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 to przenośne zaplecze podpisywania PAdES i odpowiednik zaplecza CNG z Windows. Rozwiązuje certyfikat podpisującego i jego klucz prywatny z tokena PKCS#11, po czym zwraca TPadesResolvedSigner, którego ICmsSigner produkuje podpis SignerInfo przez token, więc klucz nigdy go nie opuszcza
Moduł jest ładowany w czasie działania po ścieżce - opensc-pkcs11.so, libsofthsm2.so, DLL dostawcy - więc nic nie jest konsolidowane w czasie budowania, a nieobecny moduł jest raportowany zamiast kończyć się katastrofą. Tylko C_GetFunctionList jest rozwiązywane po nazwie; każdy pozostały punkt wejścia pochodzi z tabeli funkcji, którą on zwraca, i dokładnie tak standard przewiduje dostęp do modułu
ConfigurePkcs11SignerProvider buduje TPdfPkcs11SignerProvider z wartości TPdfPkcs11Options i instaluje go jako aktywne zaplecze podpisującego PAdES, zwracając interfejs IPdfPkcs11SignerProvider, który dodatkowo niesie metody wyliczania tokena
Pkcs11ModuleAvailable i Pkcs11ModuleVersion raportują, czy dany moduł się ładuje i udostępnia użyteczną tabelę funkcji, więc aplikacja może przy starcie zdecydować, czy podpisywanie tokenem jest na tej maszynie możliwe. Załadowane moduły są cache'owane po ścieżce, ponieważ standard dopuszcza tylko jedną inicjalizację na moduł w obrębie procesu
Resolve wybiera certyfikat po TPadesSignerOptions.CertificateThumbprint, gdy ten jest podany, a w przeciwnym razie po CertificateLabel, po czym odnajduje obiekt klucza prywatnego niosący ten sam identyfikator tokena co certyfikat. Algorytm klucza certyfikatu rozstrzyga rodzinę algorytmu: klucz EC podpisuje ECDSA, a jego surowy podpis jest przekodowywany na strukturę SEQUENCE w DER, której oczekuje CMS, podczas gdy klucz RSA stosuje żądany schemat dopełnienia
EnumerateSlots i EnumerateCertificates obsługują graficzne interfejsy wyboru, pozwalając aplikacji wypisać gniazda raportowane przez moduł i certyfikaty przechowywane w wybranym gnieździe, zanim jakakolwiek opcja podpisywania zostanie ustalona
| Function | Description |
|---|---|
Pkcs11ModuleAvailable | Zwraca True, gdy moduł pod podaną ścieżką się ładuje i udostępnia użyteczną tabelę funkcji |
Pkcs11ModuleVersion | Zwraca ciąg wersji zgłaszany przez moduł albo pusty ciąg, gdy moduł się nie ładuje |
Pkcs11AbiLayout | Zwraca układ ABI rozstrzygnięty przez tę kompilację, jako ulong=<n> attr=<n> pss=<n> table=<n> |
ConfigurePkcs11SignerProvider | Buduje dostawcę z przekazanych opcji, instaluje go jako zaplecze podpisującego PAdES i zwraca jako IPdfPkcs11SignerProvider |
| Type | Purpose |
|---|---|
EPdfPkcs11Error | Wyjątek zgłaszany, gdy nie skonfigurowano ścieżki modułu, gdy modułu nie da się załadować, gdy wywołanie tokena zawodzi albo gdy nie znajduje się pasującego certyfikatu lub klucza prywatnego |
TPdfPkcs11Options | Rekord nazywający moduł, gniazdo, PIN i certyfikat, z którymi pracuje dostawca |
TPdfPkcs11SignerProvider | Klasa dostawcy implementująca IPadesSignerProvider i IPdfPkcs11SignerProvider na bazie modułu PKCS#11 |
| Field | Description |
|---|---|
ModulePath | Ścieżka do modułu PKCS#11; wymagana, ponieważ o tym, który moduł obsługuje token, decyduje wdrożenie, a użyteczna wartość domyślna nie istnieje |
SlotId | Gniazdo tokena do otwarcia, respektowane tylko gdy UseSpecificSlot jest True |
UseSpecificSlot | Pozostaw False, aby wziąć pierwsze gniazdo zgłaszające obecność tokena |
Pin | PIN użytkownika; dostawca czyści własną kopię, gdy token go skonsumuje, a odpowiedzialność za czas życia przekazanego ciągu pozostaje po stronie wywołującego |
CertificateLabel | Opcjonalna etykieta obiektu certyfikatu do podpisywania, używana tylko gdy TPadesSignerOptions.CertificateThumbprint jest pusty |
Default | Statyczna fabryka zwracająca opcje z pustą ścieżką modułu, gniazdem 0, automatycznym wyborem gniazda oraz bez PIN-u i etykiety |
| Member | Description |
|---|---|
Create | Konstruuje dostawcę z wartości TPdfPkcs11Options; sam moduł jest otwierany przy pierwszym użyciu |
Destroy | Zamyka wszelkie otwarte sesje tokena, zanim instancja zostanie zwolniona |
BackendName | Zwraca nazwę zaplecza z dołączoną nazwą pliku modułu, gdy ścieżka modułu jest skonfigurowana |
Resolve | Rozwiązuje TPadesSignerOptions w TPadesResolvedSigner z podpisującym tokena i certyfikatem DER podpisującego |
EnumerateSlots | Zwraca każde gniazdo raportowane przez moduł jako TPdfPkcs11Slots, łącznie z gniazdami bez tokena |
EnumerateCertificates | Zwraca certyfikaty przechowywane w jednym gnieździe jako TPdfPkcs11Certificates, otwierając najpierw sesję na tym gnieździe |
CloseProtectedSessions | Wylogowuje tam, gdzie doszło do logowania, i zamyka otwartą sesję, uwalniając token dla pozostałych konsumentów |
CK_ULONG podąża za C-owym unsigned long, więc ma 4 bajty na Windows (LLP64) i 8 bajtów na Linux i macOS (LP64); każdy uchwyt, licznik i typ atrybutu to CK_ULONGPkcs11AbiLayout raportuje układ rozstrzygnięty przez tę kompilację, więc niezgodność daje się zdiagnozować zamiast kończyć się cichym crashem: Win32 zgłasza ulong=4 attr=12 pss=12 table=2, Win64 zgłasza ulong=4 attr=16 pss=12 table=2, a cel LP64 zgłasza ulong=8 attr=24 pss=24 table=8CertificateLabel, wygrywa pierwszy certyfikat na tokenie, co pasuje do tokena z jednym certyfikatem i do żadnego wdrożenia produkcyjnego