PDFium Delphi Component Docs

FPdfPkcs11 unit

Unit: FPdfPkcs11
PKCS#11 signing backend for PAdES, resolving a signer certificate and its private key from a token and producing the SignerInfo signature inside the token

Syntax

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;

Description

FPdfPkcs11 is the portable PAdES signing backend and the counterpart of the Windows CNG backend. It resolves a signer certificate and its private key from a PKCS#11 token, then returns a TPadesResolvedSigner whose ICmsSigner produces the SignerInfo signature through the token, so the key never leaves it

The module is loaded at run time by path - opensc-pkcs11.so, libsofthsm2.so, a vendor DLL - so nothing is linked at build time and an absent module is reported rather than fatal. Only C_GetFunctionList is resolved by name; every other entry point comes out of the function table it returns, which is how the standard intends a module to be reached

ConfigurePkcs11SignerProvider builds a TPdfPkcs11SignerProvider from a TPdfPkcs11Options value and installs it as the active PAdES signer backend, returning the IPdfPkcs11SignerProvider interface that also carries the token enumeration methods

Pkcs11ModuleAvailable and Pkcs11ModuleVersion report whether a given module loads and exposes a usable function table, so an application can decide at startup whether token signing is possible on this machine. Loaded modules are cached by path, because the standard allows only one initialisation per process per module

Resolve selects the certificate by TPadesSignerOptions.CertificateThumbprint when one is supplied and by CertificateLabel otherwise, then locates the private key object that carries the same token identifier as the certificate. The certificate key algorithm decides the algorithm family: an EC key signs with ECDSA and its raw signature is re-encoded as the DER SEQUENCE that CMS expects, whilst an RSA key follows the requested padding scheme

EnumerateSlots and EnumerateCertificates serve selection user interfaces, letting an application list the slots a module reports and the certificates a chosen slot holds before any signing option is fixed

Functions

FunctionDescription
Pkcs11ModuleAvailableReturns True when the module at the given path loads and exposes a usable function table
Pkcs11ModuleVersionReturns the version string the module reports, or an empty string when the module does not load
Pkcs11AbiLayoutReturns the ABI layout this build resolved, as ulong=<n> attr=<n> pss=<n> table=<n>
ConfigurePkcs11SignerProviderBuilds a provider from the supplied options, installs it as the PAdES signer backend and returns it as IPdfPkcs11SignerProvider

Types

TypePurpose
EPdfPkcs11ErrorException raised when no module path is configured, the module cannot be loaded, a token call fails, or no matching certificate or private key is found
TPdfPkcs11OptionsRecord naming the module, slot, PIN and certificate the provider works with
TPdfPkcs11SignerProviderProvider class implementing IPadesSignerProvider and IPdfPkcs11SignerProvider on top of a PKCS#11 module

TPdfPkcs11Options fields

FieldDescription
ModulePathPath to the PKCS#11 module; required, because which module serves a token is a deployment decision and there is no useful default
SlotIdToken slot to open, honoured only when UseSpecificSlot is True
UseSpecificSlotLeave False to take the first slot that reports a token present
PinUser PIN; the provider clears its own copy once the token has consumed it, and the caller stays responsible for the lifetime of the string it passes in
CertificateLabelOptional object label of the certificate to sign with, used only when TPadesSignerOptions.CertificateThumbprint is empty
DefaultStatic factory returning options with an empty module path, slot 0, automatic slot selection and no PIN or label

TPdfPkcs11SignerProvider members

MemberDescription
CreateConstructs the provider from a TPdfPkcs11Options value; the module itself is opened on first use
DestroyCloses any open token session before the instance is released
BackendNameReturns the backend name, with the module file name appended when a module path is configured
ResolveResolves TPadesSignerOptions into a TPadesResolvedSigner holding the token signer and the signer certificate DER
EnumerateSlotsReturns every slot the module reports as TPdfPkcs11Slots, including slots with no token present
EnumerateCertificatesReturns the certificates held in one slot as TPdfPkcs11Certificates, opening a session on that slot first
CloseProtectedSessionsLogs out where a login took place and closes the open session, releasing the token for other consumers

Remarks

See Also

FPdfCrypto, FPdfCryptoWin, FPdfCms