TPDFlibPKCS11Client

Seguridad y firmas

Descripción

Carga en tiempo de ejecución un módulo PKCS #11 del fabricante y expone certificados y claves privadas que no están registrados con los proveedores CSP o KSP de WindowsEl cliente enumera los tokens presentes, abre una sesión persistente, autentica al usuario, empareja un certificado X.509 con una clave de firma por

CKA_ID binario y firma resúmenes ya calculados a través de CKM_RSA_PKCS o CKM_ECDSAEl descubrimiento explícito con certificado opcional puede seleccionar una clave privada ML-DSA por etiqueta o identificador binario, validar su

CKA_PARAMETER_SETCKM_ML_DSA

SignDigest y firmar mensajes originales a través de TPDFlibExternalDigestSignEventTPDFlib.OnExternalDigestSign implementa

Unidad

PDFlibPKCS11

Construcción y ciclo de vida del módulo

Constructor TPDFlibPKCS11Client.Create;
Destructor TPDFlibPKCS11Client.Destroy;
Function TPDFlibPKCS11Client.LoadModule: Boolean;
Procedure TPDFlibPKCS11Client.UnloadModule;
Function TPDFlibPKCS11Client.UseFunctionList(FunctionList: PPLPKCS11FunctionList; AlreadyInitialized: Boolean): Boolean;

ModulePath identifica una DLL PKCS #11 Win32 o Win64 que exporta C_GetFunctionListLos clientes que usan la misma ruta comparten un módulo cargado y un ciclo de vida equilibrado

C_Initialize/C_FinalizeEl cargador solicita primero

CKF_OS_LOCKING_OK

UseFunctionList; los módulos que no pueden proporcionar bloqueo interno quedan protegidos por un bloqueo compartido de llamadas, mientras que los módulos conformes permiten que sesiones de clientes separadas se ejecuten concurrentementeUnloadModule admite proveedores enlazados estáticamente, incrustados o gestionados por la aplicación; el llamador debe mantener viva la tabla suministrada hasta

Detección y conexión de tokens

Function TPDFlibPKCS11Client.RefreshTokens: Boolean;
Function TPDFlibPKCS11Client.GetToken(Index: Integer; Out Token: TPDFlibPKCS11Token): Boolean;
Function TPDFlibPKCS11Client.Connect: Boolean;
Procedure TPDFlibPKCS11Client.Disconnect;
Function TPDFlibPKCS11Client.GetSelectedToken(Out Token: TPDFlibPKCS11Token): Boolean;
Property TPDFlibPKCS11Client.TokenCount: Integer;

RefreshTokens enumera las ranuras presentes con reintento acotado cuando un evento de conexión en caliente cambia el recuento, y TokenCount informa de cuántos tokens encontró la última actualizaciónSeleccione un token con

SlotID, TokenLabel, TokenSerial o una combinación; una selección vacía solo tiene éxito cuando existe exactamente un token presente

TPDFlibPKCS11Token informa de la descripción de la ranura, el fabricante, la etiqueta del token, el modelo, el número de serie, las marcas y los límites de longitud del PIN

Parámetros

CertificateLabelFiltro opcional CKA_LABEL UTF-8 para el objeto de certificado X.509
CertificateIDFiltro opcional CKA_ID binario almacenado en un AnsiString
PrivateKeyLabelFiltro opcional CKA_LABEL UTF-8 para la clave privada de firma
PrivateKeyIDCKA_ID binario opcional de la clave privada; cuando está vacío, se reutiliza el identificador del certificado
CertificateOptionalToma False como valor predeterminado; cuando es True, se requiere una etiqueta o un identificador de clave privada y el descubrimiento solo acepta claves ML-DSA sin certificado X.509

CKA_SIGN=True

MLDSAParameterSet

CertificateDER, valida el DER del certificado y rechaza los desajustes de tipo RSA/EC; el descubrimiento con certificado opcional exige una clave ML-DSA inequívoca y valida el conjunto de parámetros 44, 65 o 87El conjunto de parámetros ML-DSA resuelto se expone a través de ResolvedPrivateKeyIDEl certificado resuelto se expone a través de

Autenticación

UserPINPIN de usuario de solo escritura codificado en UTF-8, comprobado contra los límites del token y borrado cuando se reemplaza o destruye
UseProtectedAuthenticationPathPasa un PIN nulo cuando el token anuncia CKF_PROTECTED_AUTHENTICATION_PATH
ReadWriteSessionAñade CKF_RW_SESSION; la firma normalmente solo necesita la sesión serie de solo lectura predeterminada

Las claves con CKA_ALWAYS_AUTHENTICATE=True reciben un inicio de sesión específico del contexto después de cada C_SignInit con éxito

ClearPIN sobrescribe y libera el PIN configurado

Firma

Function TPDFlibPKCS11Client.SupportsMechanism(MechanismType: Cardinal): Boolean;
Function TPDFlibPKCS11Client.SupportsAlgorithm(DigestAlgorithm, SignatureAlgorithm: Integer): Boolean;
Function TPDFlibPKCS11Client.SignMLDSA(Const Message: AnsiString; Out Signature: AnsiString): Boolean;
Function TPDFlibPKCS11Client.SignHash(Const Digest: AnsiString; DigestAlgorithm, SignatureAlgorithm: Integer; Out Signature: AnsiString): Boolean;
Function TPDFlibPKCS11Client.SignDigest(Sender: TObject; SignProcessID: Integer; Const Digest: AnsiString; DigestAlgorithm, SignatureAlgorithm: Integer; Var Signature: AnsiString): Boolean;

Las firmas RSA usan CKM_RSA_PKCS bruto con un DigestInfo DER construido localmente, de modo que el token no aplica hash al resumen PDF una segunda vezLas firmas ECDSA usan

CKM_ECDSA bruto; la salida P1363 del token se devuelve sin cambios para PDF_EXTERNAL_SIGNATURE_ECDSA_P1363 o se convierte a DER estricto para PDF_EXTERNAL_SIGNATURE_ECDSA_DER

SignMLDSA pasa el mensaje original a CKM_ML_DSA de una sola parte con parámetros de mecanismo vacíos, seleccionando el contexto vacío por defecto; es independiente de SignHash y de la retrollamada de resumen CMS

Las longitudes de resumen SHA-1, SHA-256, SHA-384, SHA-512, SHA3-256, SHA3-384 y SHA3-512 se validan antes de cualquier operación de clave privada

C_SignInit falla antes de que comience la firma, evitando operaciones duplicadas de clave privada tras un fallo ambiguo de C_Sign

Ejemplo

var
  Token: TPDFlibPKCS11Client;
  ProcessID: Integer;
begin
  Token:= TPDFlibPKCS11Client.Create;
  try
    Token.ModulePath:= 'C:\Program Files\Vendor\pkcs11.dll';
    Token.TokenLabel:= 'Signing token';
    Token.CertificateLabel:= 'Document signer';
    Token.UserPIN:= UserPIN;
    if not Token.Connect then
      raise Exception.Create(String(Token.LastError));

    PDF.OnExternalDigestSign:= Token.SignDigest;
    ProcessID:= PDF.NewSignProcessFromFile(InputFile, '');
    PDF.SetSignProcessField(ProcessID, 'Approval');
    PDF.SetSignProcessDigestAlgorithm(ProcessID, 2);
    PDF.SetSignProcessExternalDigestSigner(ProcessID,
      Token.CertificateDER, PDF_EXTERNAL_SIGNATURE_RSA_PKCS1, 512);
    PDF.EndSignProcessToFile(ProcessID, OutputFile);
  finally
    Token.Free;
  end;
end;

Estado y comportamiento en caso de error

Connected, KeyType, MLDSAParameterSet, AlwaysAuthenticate, FunctionListMajor y FunctionListMinor exponen el estado activo del proveedorLos métodos devuelven

False y establecen tanto LastReturnValue como LastError cuando fallan la carga del módulo, la selección del token, la autenticación, el descubrimiento de objetos, los límites de atributos, las comprobaciones de mecanismo o la firma

Véase también

OnExternalDigestSign, SetSignProcessExternalDigestSigner, SetSignProcessDigestAlgorithm, TPDFlibCSCClient

Administración del PIN

Function TPDFlibPKCS11Client.InitializeUserPIN(Const SecurityOfficerPIN, NewUserPIN: WideString): Boolean;
Function TPDFlibPKCS11Client.ChangeUserPIN(Const OldPIN, NewPIN: WideString): Boolean;

Ambas operaciones abren su propia sesión de lectura/escritura en el token configurado y dejan intacta la sesión de firma; InitializeUserPIN inicia sesión como oficial de seguridad antes de llamar a C_InitPIN, y ChangeUserPIN inicia sesión como usuario antes de llamar a C_SetPIN

Los búferes de PIN se borran después del uso; un módulo sin el punto de entrada requerido informa de un error en lugar de fallar en silencio