PDFium Delphi Component Docs

FPdfCrypto 單元

單元: FPdfCrypto
供平台後端、PKCS#11 整合、信任存放區、撤銷擷取器與有界路徑驗證使用的 PAdES 簽署器提供者與憑證驗證外觀

語法

TPadesPaddingScheme = (psRsaPss, psRsaPkcs1v15, psEcdsa);

TPadesSignerOptions = record
  CertificateThumbprint: string;
  PaddingScheme: TPadesPaddingScheme;
  class function Default: TPadesSignerOptions; static;
end;

TPadesChainCertArray = array of TBytes;

TPadesResolvedSigner = record
  Signer: ICmsSigner;
  SignerCertDer: TBytes;
  ChainCertDer: TPadesChainCertArray;
end;

TPdfRevocationMode = (prmNone, prmOffline, prmOnlineAllowed,
  prmOnlineRequired);
TPdfStringArray = array of string;

TPdfCertificatePathOptions = record
  ValidationTime: TDateTime;
  RevocationMode: TPdfRevocationMode;
  RequiredPolicyOids: TPdfStringArray;
  MaxCertificates: Integer;
  MaxCertificateBytes: Integer;
  MaxFetchBytes: Integer;
  MaxPathDepth: Integer;
  class function Default: TPdfCertificatePathOptions; static;
end;

TPdfCertificatePathReport = record
  Trusted: Boolean;
  PathBuilt: Boolean;
  PolicyValid: Boolean;
  RevocationChecked: Boolean;
  PathCertificateCount: Integer;
  ErrorCode: Integer;
  ErrorMessage: string;
end;

IPdfTrustStore = interface
  function LoadTrustAnchors: TPadesChainCertArray;
end;

IPdfValidationFetcher = interface
  function Fetch(const Uri: string; MaxBytes: Integer;
    out Data: TBytes): Boolean;
end;

IPdfCertificatePathValidator = interface
  function Validate(const LeafCertificate: TBytes;
    const Intermediates, TrustAnchors: TPadesChainCertArray;
    TrustStore: IPdfTrustStore; Fetcher: IPdfValidationFetcher;
    const Options: TPdfCertificatePathOptions;
    out Report: TPdfCertificatePathReport): Boolean;
end;

IPadesSignerProvider = interface
  function BackendName: string;
  function Resolve(const Options: TPadesSignerOptions): TPadesResolvedSigner;
end;

TPdfPkcs11Slot = record
  SlotID: UInt64;
  Description: string;
  TokenLabel: string;
  TokenPresent: Boolean;
end;
TPdfPkcs11Slots = array of TPdfPkcs11Slot;

TPdfPkcs11Certificate = record
  SlotID: UInt64;
  ObjectID: TBytes;
  LabelText: string;
  CertificateDer: TBytes;
  Mechanisms: TPdfStringArray;
end;
TPdfPkcs11Certificates = array of TPdfPkcs11Certificate;

IPdfPkcs11SignerProvider = interface(IPadesSignerProvider)
  function EnumerateSlots: TPdfPkcs11Slots;
  function EnumerateCertificates(SlotID: UInt64): TPdfPkcs11Certificates;
  procedure CloseProtectedSessions;
end;

TPdfCmsVerifyStatus = (pcvsUnavailable, pcvsValid, pcvsInvalid,
  pcvsUnsupported, pcvsIndeterminate);
TPdfCmsRevocationReason = (pcrrNone, pcrrCertificateRevoked, pcrrCrlExpired,
  pcrrCrlNotYetValid, pcrrCrlUnavailable, pcrrCrlSignatureInvalid,
  pcrrCrlInvalid, pcrrChainUntrusted, pcrrUnknown, pcrrOcspUnavailable,
  pcrrOcspInvalid, pcrrOcspStatusUnknown);
TPdfCmsVerifyStage = (pcvstCryptographicSignature, pcvstChainBuild,
  pcvstOnlineRetrieval, pcvstRevocationCheck);
TPdfCmsVerifyCheckpoint = procedure(Stage: TPdfCmsVerifyStage) of object;

TPdfCmsVerifyOptions = record
  OnlineRetrieval: Boolean;
  CheckRevocation: Boolean;
  CollectChainCertificates: Boolean;
  UrlRetrievalTimeoutMs: Cardinal;
  OnCheckpoint: TPdfCmsVerifyCheckpoint;
  CollectSignerDiagnostics: Boolean;
  MaxSignerCount: Integer;
  class function Default: TPdfCmsVerifyOptions; static;
end;

TPdfCmsSignerVerifyResult = record
  SignerIndex: Integer;
  SignatureStatus, TrustStatus, RevocationStatus: TPdfCmsVerifyStatus;
  SignatureError, TrustError: Cardinal;
  SignerCertificate: TBytes;
  RevocationReason: TPdfCmsRevocationReason;
  RevocationError: Cardinal;
  RevocationCertificate: TBytes;
end;
TPdfCmsSignerVerifyResults = array of TPdfCmsSignerVerifyResult;

TPdfCmsVerifyResult = record
  SignatureStatus: TPdfCmsVerifyStatus;
  TrustStatus: TPdfCmsVerifyStatus;
  RevocationStatus: TPdfCmsVerifyStatus;
  SignatureError: Cardinal;
  TrustError: Cardinal;
  SignerCertificate: TBytes;
  ChainCertificates: TPadesChainCertArray;
  RevocationReason: TPdfCmsRevocationReason;
  RevocationError: Cardinal;
  RevocationCertificate: TBytes;
  SignerResults: TPdfCmsSignerVerifyResults;
  SignerDiagnosticsStatus: TPdfCmsVerifyStatus;
  SignerCount: Integer;
end;

IPdfCmsVerifier = interface
  function BackendName: string;
  function VerifyDetached(const CmsDer: TBytes;
    Segment1: Pointer; Segment1Length: Cardinal;
    Segment2: Pointer; Segment2Length: Cardinal;
    const Options: TPdfCmsVerifyOptions): TPdfCmsVerifyResult;
  function VerifyAttached(const CmsDer: TBytes;
    const Options: TPdfCmsVerifyOptions): TPdfCmsVerifyResult;
end;

procedure ConfigurePadesCmsVerifier(const Verifier: IPdfCmsVerifier);
function PadesCmsVerificationAvailable: Boolean;
function PadesCmsVerificationBackendName: string;
function PadesCryptoAvailable: Boolean;
function PadesCryptoBackendName: string;
function ResolvePadesSigner(const Options: TPadesSignerOptions): TPadesResolvedSigner;
procedure ConfigurePdfCertificatePathValidator(
  const Validator: IPdfCertificatePathValidator);
function ValidatePdfCertificatePath(const LeafCertificate: TBytes;
  const Intermediates, TrustAnchors: TPadesChainCertArray;
  TrustStore: IPdfTrustStore; Fetcher: IPdfValidationFetcher;
  const Options: TPdfCertificatePathOptions;
  out Report: TPdfCertificatePathReport): Boolean;
procedure ConfigurePadesSignerProvider(const Provider: IPadesSignerProvider);

TPadesSignerResolverProc = function(const Options: TPadesSignerOptions): TPadesResolvedSigner;

PadesSignerResolverOverride: TPadesSignerResolverProc;
PdfCertificatePathValidator: IPdfCertificatePathValidator;
PadesSignerProvider: IPadesSignerProvider;
PadesCmsVerifier: IPdfCmsVerifier;

說明

FPdfCrypto 是 PAdES 簽署堆疊的入口。PadesCryptoAvailable 回報簽署資料及其後端是否可用,PadesCryptoBackendName 識別選定後端;Windows 預設使用 Cryptography Next Generation,其他平台則從 FPdfCryptoSsl 解析明確設定的 OpenSSL 私鑰與憑證

ResolvePadesSigner 接受憑證指紋與填充方案,傳回完整填妥的 TPadesResolvedSigner:執行私鑰操作的 ICmsSigner 實作、簽署者憑證 DER,以及簽發鏈憑證。結果可直接傳給 FPdfCms.BuildSignedData

自訂整合可以註冊 IPadesSignerProvider(包括可列舉權杖插槽與憑證的 IPdfPkcs11SignerProvider),或使用 PadesSignerResolverOverride 作為確定性的解析器接縫

憑證路徑驗證以提供者為基礎並受額度限制:呼叫端設定 IPdfCertificatePathValidator,可選擇提供明確的信任錨點、IPdfTrustStore 與 IPdfValidationFetcher,再檢視 TPdfCertificatePathReport

函式

函式說明
PadesCryptoAvailable目前平台上有可用於 PAdES 簽署的密碼學後端時傳回 True
PadesCryptoBackendName傳回作用中密碼學後端的顯示名稱
ResolvePadesSigner將憑證指紋與填充方案解析為簽署器、簽署者憑證與鏈
ConfigurePdfCertificatePathValidator設定或清除處理序級的 IPdfCertificatePathValidator,供 ValidatePdfCertificatePath 使用
ValidatePdfCertificatePath在強制執行憑證數量、大小、擷取與路徑深度額度後,對照中繼憑證與合併的明確及信任存放區錨點驗證葉憑證
ConfigurePadesSignerProvider設定或清除在平台後端之前使用的處理序級簽署器提供者
ConfigurePadesCmsVerifier安裝 PAdES 驗證器使用的 CMS 驗證後端;在 Windows 上清除後端會恢復使用 Windows CryptoAPI。其他平台必須明確呼叫 ConfigureSslCmsVerifier 或 ConfigureKeychainCmsVerifier
PadesCmsVerificationAvailable當此組建中存在能驗證 CMS 的後端(無論是註冊的還是內建的)時傳回 True
PadesCmsVerificationBackendName傳回目前作用中驗證後端的顯示名稱,沒有則傳回空字串

提供者介面

介面成員說明
IPdfTrustStore.LoadTrustAnchors傳回額外的 DER 編碼信任錨點,受設定的憑證額度約束
IPdfValidationFetcher.Fetch從 Uri 擷取驗證資料,不超過 MaxBytes
IPdfCertificatePathValidator.Validate建置並評估憑證路徑,並填入 TPdfCertificatePathReport
IPadesSignerProvider.BackendName傳回由 PadesCryptoBackendName 公開的提供者顯示名稱
IPadesSignerProvider.Resolve為提供的 TPadesSignerOptions 傳回完整的簽署器材料
IPdfPkcs11SignerProvider.EnumerateSlots傳回可用的 PKCS#11 插槽與權杖存在中繼資料
IPdfPkcs11SignerProvider.EnumerateCertificates傳回單一 PKCS#11 插槽中可見的憑證與簽署機制
IPdfPkcs11SignerProvider.CloseProtectedSessions關閉提供者擁有的受保護或已驗證 PKCS#11 連線
IPdfCmsVerifier.BackendName傳回 PadesCmsVerificationBackendName 所回報的驗證後端顯示名稱
IPdfCmsVerifier.VerifyDetached驗證 PDF 簽章;簽章的實際內容是 /Contents 缺口兩側的兩段位元組範圍
IPdfCmsVerifier.VerifyAttached驗證時間戳權杖;權杖自帶內容,不需要分離的內容段

類型

類型說明
EPadesCrypto密碼學後端失敗的基礎例外
EPadesCryptoUnavailable未設定必要的簽署器後端或憑證路徑驗證器時拋出
TPadesPaddingSchemepsRsaPss、psRsaPkcs1v15 或 psEcdsa
TPadesSignerOptionsCertificateThumbprint 選擇憑證,PaddingScheme 選擇簽章方案;Default 使用空指紋與 psRsaPss
TPadesChainCertArrayDER 編碼鏈憑證的動態陣列
TPadesResolvedSignerSigner、SignerCertDer 與 ChainCertDer 捆綁已解析的簽署器與憑證材料
TPdfRevocationModeprmNone、prmOffline、prmOnlineAllowed 或 prmOnlineRequired
TPdfStringArray用於政策 OID 與提供者機制名稱的動態字串陣列
TPdfCertificatePathOptionsValidationTime、RevocationMode、RequiredPolicyOids、MaxCertificates、MaxCertificateBytes、MaxFetchBytes 與 MaxPathDepth 控制驗證與資源額度;Default 選擇離線撤銷檢查,限制為 64 張憑證、每張憑證 4 MiB、擷取資料 16 MiB 與路徑深度 16
TPdfCertificatePathReportTrusted、PathBuilt、PolicyValid、RevocationChecked、PathCertificateCount、ErrorCode 與 ErrorMessage 回報驗證結果
TPdfPkcs11SlotSlotID、Description、TokenLabel 與 TokenPresent 描述單一 PKCS#11 插槽
TPdfPkcs11SlotsTPdfPkcs11Slot 記錄的動態陣列
TPdfPkcs11CertificateSlotID、ObjectID、LabelText、CertificateDer 與 Mechanisms 描述單一權杖憑證
TPdfPkcs11CertificatesTPdfPkcs11Certificate 記錄的動態陣列
TPadesSignerResolverProc供 PadesSignerResolverOverride 注入變數使用的函式指標型別
TPdfCmsVerifyStatuspcvsUnavailable、pcvsValid、pcvsInvalid、pcvsUnsupported 或 pcvsIndeterminate
TPdfCmsRevocationReasonpcrrNone、pcrrCertificateRevoked、pcrrCrlExpired、pcrrCrlNotYetValid、pcrrCrlUnavailable、pcrrCrlSignatureInvalid、pcrrCrlInvalid、pcrrChainUntrusted、pcrrUnknown、pcrrOcspUnavailable、pcrrOcspInvalid 或 pcrrOcspStatusUnknown 分別說明撤銷證據,與驗證狀態分開回報
TPdfCmsVerifyStagepcvstCryptographicSignature、pcvstChainBuild、pcvstOnlineRetrieval 或 pcvstRevocationCheck
TPdfCmsVerifyCheckpoint物件方法形式的回呼,隨驗證推進逐一接收 TPdfCmsVerifyStage
TPdfCmsVerifyOptionsOnlineRetrieval、CheckRevocation、CollectChainCertificates、UrlRetrievalTimeoutMs 及 OnCheckpoint 控制驗證;CollectSignerDiagnostics 要求個別簽署者快照,MaxSignerCount 限制快照數。Default 停用擷取、撤銷檢查與簽署者診斷,將擷取預算設為 15 秒,簽署者快照上限設為 64
TPdfCmsSignerVerifyResultSignerIndex 表示編碼中的 SignerInfo 順序;簽章、信任、撤銷狀態與原生錯誤獨立描述該簽署者。SignerCertificate 是其 DER 憑證;後端能提供時,RevocationCertificate 則識別擷取到撤銷錯誤所涉及的憑證
TPdfCmsSignerVerifyResults有數量上限的簽署者快照動態陣列
TPdfCmsVerifyResult彙總的簽章、信任與撤銷狀態彼此獨立。記錄也傳回 SignatureError、TrustError、SignerCertificate、ChainCertificates、RevocationReason、RevocationError、RevocationCertificate、SignerResults、SignerDiagnosticsStatus 及 SignerCount

撤銷診斷

公開的選項與結果記錄已擴充,升級時請重新建置使用端。自訂驗證器應以 Default(TPdfCmsVerifyResult) 初始化受管理的結果記錄,讓不支援的快照欄位維持不可用;請勿用 FillChar 清除仍持有字串或動態陣列的記錄

請讀取 RevocationReason 與 RevocationError,兩者取自 TPdfCmsVerifyResult;該記錄由 IPdfCmsVerifier.VerifyDetached 或 VerifyAttached 傳回。PAdES 信任驗證會把它們保留為 RevocationReason 與 NativeRevocationError,並以獨立的 TimeStampRevocationReason 與 NativeTimeStampRevocationError 欄位對應時間戳權杖;證據報告會同時包含這兩組

RevocationError 是後端專屬的原生驗證碼,零表示未擷取到原生診斷。OpenSSL 使用 X509_V_ERR_* 錯誤空間。Windows 會保留原始 DWORD,來源是憑證的 CERT_REVOCATION_INFO.dwRevocationResult,或在撤銷鏈呼叫失敗時取自 GetLastError;它既不是統一的 HRESULT 錯誤空間,也不是鏈信任的彙總位元遮罩

OpenSSL 區分已確認撤銷、過期/不可用/無效的 CRL 證據,以及不可用/無效/未知的 OCSP 證據。Windows 回報已確認撤銷、不受信任的憑證鏈或未知原生失敗。macOS 驗證器分別評估簽章完整性、Basic X.509 信任與撤銷,傳回原生 Security.framework 錯誤,不會把每種平台失敗都轉成 CRL 或 OCSP 分類

RevocationCertificate 可能識別遭撤銷的中繼憑證,而非 CMS 簽署者憑證;後端無法擷取該憑證時保持空值。OpenSSL 可收集此資訊,目前的 macOS 後端則維持空值

pcrrNone 與零值錯誤都無法證明撤銷已檢查或已通過;請一律檢視 RevocationStatus

個別簽署者診斷

設定 CollectSignerDiagnostics=True,即可檢查 SignerResults 中有上限的快照。成功確認時,SignerCount 是編碼中的 SignerInfo 數量;零表示尚未確認數量

SignerDiagnosticsStatus=pcvsValid 表示所要求的快照收集完整,包括無效簽章的快照,不代表所有簽章均通過。pcvsUnavailable 表示收集功能停用或不受支援,pcvsIndeterminate 則表示後端無法在解析或資源上限內完成收集

OpenSSL 與原生 macOS 實作將收集上限設為 64 位簽署者。OpenSSL 另將診斷 CMS 輸入限制為 4 MiB,累計診斷輸入/輸出工作限制為 64 MiB;macOS 將傳回憑證資料限制為每張 4 MiB、總計 64 MiB。較低的 MaxSignerCount 可進一步降低呼叫端要求的數量

簽署者快照重用已設定的證據及彙總驗證期間取得的證據。OpenSSL 不會為每份診斷快照再次進行網路擷取,不完整的彙總擷取也不會變成成功的離線撤銷快照

預設簽署後端

PadesSignerResolverOverride 優先,其次是明確註冊的 IPadesSignerProvider,最後才是平台預設值。非 Windows 平台的預設後端需要 ConfigureSslSigningCredentials;僅有 libcrypto 可用並不會提供私鑰或憑證

OpenSSL 預設後端拒絕非空的 CertificateThumbprint,因為憑證已由明確設定選定。應用程式選擇 Keychain 提供者時,仍可透過 ConfigureKeychainSignerProvider 簽署

全域提供者變數

變數說明
PadesSignerResolverOverride在已註冊與平台提供者之前評估的選用解析器回呼
PadesCmsVerifier目前的 CMS 驗證後端,通常透過 ConfigurePadesCmsVerifier 指派
PdfCertificatePathValidator目前的憑證路徑驗證器,通常透過 ConfigurePdfCertificatePathValidator 指派
PadesSignerProvider目前的簽署器提供者,通常透過 ConfigurePadesSignerProvider 指派

另請參閱

FPdfCms, FPdfCryptoWin, FPdfCryptoSsl, FPdfCryptoMac, FPdfCryptoOcsp, FPdfTsa, TPdf.SignPades