EPdfPkcs11Error = class(Exception);
TPdfPkcs11Options = record
ModulePath: string;
SlotId: UInt64;
UseSpecificSlot: Boolean;
Pin: string;
CertificateLabel: string;
class function Default: TPdfPkcs11Options; static;
end;
TPdfPkcs11SignerProvider = class(TInterfacedObject, IPadesSignerProvider,
IPdfPkcs11SignerProvider)
constructor Create(const Options: TPdfPkcs11Options);
destructor Destroy; override;
function BackendName: string;
function Resolve(const Options: TPadesSignerOptions): TPadesResolvedSigner;
function EnumerateSlots: TPdfPkcs11Slots;
function EnumerateCertificates(SlotID: UInt64): TPdfPkcs11Certificates;
procedure CloseProtectedSessions;
end;
function Pkcs11ModuleAvailable(const ModulePath: string): Boolean;
function Pkcs11ModuleVersion(const ModulePath: string): string;
function Pkcs11AbiLayout: string;
function ConfigurePkcs11SignerProvider(
const Options: TPdfPkcs11Options): IPdfPkcs11SignerProvider;
FPdfPkcs11 هو خلفية توقيع PAdES المحمولة والمقابل لخلفية CNG في Windows. يحل شهادة موقِّع ومفتاحه الخاص من رمز PKCS#11، ثم يعيد TPadesResolvedSigner ينتج ICmsSigner الخاص به توقيع SignerInfo عبر الرمز، فلا يغادر المفتاح الرمز أبدًا
تُحمَّل الوحدة عند التشغيل بمسار - opensc-pkcs11.so أو libsofthsm2.so أو DLL من المورّد - فلا يُربط شيء عند البناء ويُبلَّغ عن وحدة غائبة بدل اعتبارها قاتلة. يُحل C_GetFunctionList بالاسم وحده؛ وكل نقاط الدخول الأخرى تخرج من جدول الدوال الذي يعيده، وهو ما تقصده المواصفة في بلوغ الوحدة
يبني ConfigurePkcs11SignerProvider نسخة TPdfPkcs11SignerProvider من قيمة TPdfPkcs11Options ويثبته كخلفية موقِّع PAdES النشطة، ويعيد الواجهة IPdfPkcs11SignerProvider التي تحمل أيضًا أساليب حصر الرموز
يُبلِّغ Pkcs11ModuleAvailable و Pkcs11ModuleVersion عمّا إذا كانت وحدة معطاة تُحمَّل وتكشف جدول دوال قابلًا للاستخدام، فيستطيع التطبيق أن يقرر عند الإقلاع ما إذا كان التوقيع بالرمز ممكنًا على هذه الآلة. وتُخزَّن الوحدات المحمَّلة مؤقتًا حسب المسار، لأن المواصفة تسمح بتهيئة واحدة فقط لكل عملية لكل وحدة
ينتقي Resolve الشهادة بـ TPadesSignerOptions.CertificateThumbprint عند تزويده وبـ CertificateLabel خلاف ذلك، ثم يعثر على كائن المفتاح الخاص الحامل لمعرِّف الرمز نفسه الذي تحمله الشهادة. تقرر خوارزمية مفتاح الشهادة عائلة الخوارزمية: يوقِّع مفتاح EC بـ ECDSA وتُعاد ترميز توقيعه الخام كـ SEQUENCE بترميز DER الذي يتوقعه CMS، بينما يتبع مفتاح RSA مخطط الحشو المطلوب
تخدم EnumerateSlots و EnumerateCertificates واجهات اختيار المستخدم، فتتيح للتطبيق سرد المنافذ التي تُبلِّغ عنها الوحدة والشهادات التي يحملها منفذ منتقى قبل تثبيت أي خيار توقيع
| الدالة | الوصف |
|---|---|
Pkcs11ModuleAvailable | يعيد True عندما تُحمَّل الوحدة في المسار المعطى وتكشف جدول دوال قابلًا للاستخدام |
Pkcs11ModuleVersion | يعيد سلسلة الإصدار التي تُبلِّغ عنها الوحدة، أو سلسلة فارغة عندما لا تُحمَّل الوحدة |
Pkcs11AbiLayout | يعيد تخطيط ABI الذي حله هذا البناء، بالصيغة ulong=<n> attr=<n> pss=<n> table=<n> |
ConfigurePkcs11SignerProvider | يبني مزوِّدًا من الخيارات المُزوَّدة ويثبته كخلفية موقِّع PAdES ويعيده كـ IPdfPkcs11SignerProvider |
| النوع | الغرض |
|---|---|
EPdfPkcs11Error | استثناء يُرفع عندما لا يُضبط مسار وحدة، أو تعذر تحميل الوحدة، أو فشل استدعاء رمز، أو عدم العثور على شهادة أو مفتاح خاص مطابق |
TPdfPkcs11Options | سجل يسمّي الوحدة والمنفذ و PIN والشهادة التي يعمل معها المزوِّد |
TPdfPkcs11SignerProvider | فئة مزوِّد تنفذ IPadesSignerProvider و IPdfPkcs11SignerProvider فوق وحدة PKCS#11 |
| الحقل | الوصف |
|---|---|
ModulePath | مسار وحدة PKCS#11؛ وهو مطلوب، لأن أي وحدة تخدم رمزًا قرار نشر ولا يوجد افتراض نافع |
SlotId | منفذ الرمز المطلوب فتحه، ويُراعى فقط عندما تكون UseSpecificSlot بقيمة True |
UseSpecificSlot | اتركها False لتناول أول منفذ يُبلِّغ عن رمز موجود |
Pin | PIN المستخدم؛ يمسح المزوِّد نسخته الخاصة بمجرد أن يستهلك الرمزها، ويبقى المستدعي مسؤولًا عن عمر السلسلة التي يمررها |
CertificateLabel | وسم كائن اختياري للشهادة المراد التوقيع بها، ويُستخدم فقط عندما تكون TPadesSignerOptions.CertificateThumbprint فارغة |
Default | مصنع ساكن يعيد خيارات بمسار وحدة فارغ ومنفذ 0 وانتقاء منفذ تلقائي وبلا PIN أو وسم |
| العضو | الوصف |
|---|---|
Create | يبني المزوِّد من قيمة TPdfPkcs11Options؛ وتُفتح الوحدة نفسها عند أول استخدام |
Destroy | يغلق أي جلسة رمز مفتوحة قبل تحرير النسخة |
BackendName | يعيد اسم الخلفية، مع إلحاق اسم ملف الوحدة عندما يُضبط مسار وحدة |
Resolve | يحل TPadesSignerOptions إلى TPadesResolvedSigner يحمل موقِّع الرمز و DER شهادة الموقِّع |
EnumerateSlots | يعيد كل منفذ تُبلِّغ عنه الوحدة كـ TPdfPkcs11Slots، بما في ذلك المنافذ بلا رمز موجود |
EnumerateCertificates | يعيد الشهادات المحمولة في منفذ واحد كـ TPdfPkcs11Certificates، مع فتح جلسة على ذلك المنفذ أولًا |
CloseProtectedSessions | يسجّل الخروج حيث جرى تسجيل دخول ويغلق الجلسة المفتوحة، محررًا الرمز لغير المستهلكين |
CK_ULONG قيمة unsigned long في C، فعَرضه 4 بايتات على Windows (LLP64) و8 بايتات على Linux و macOS (LP64)؛ وكل مقبض وعدّاد ونوع خاصية هي CK_ULONGPkcs11AbiLayout عن التخطيط الذي حله هذا البناء، فيصبح عدم التطابق قابلًا للتشخيص بدل انهيار صامت: يُبلِّغ Win32 عن ulong=4 attr=12 pss=12 table=2، و Win64 عن ulong=4 attr=16 pss=12 table=2، وهدف LP64 عن ulong=8 attr=24 pss=24 table=8CertificateLabel يفوز أول شهادة على الرمز، وهو ما يناسب رمزًا بشهادة واحدة ولا يناسب نشرًا إنتاجيًا