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 | 未設定必要的簽署器後端或憑證路徑驗證器時拋出 |
TPadesPaddingScheme | psRsaPss、psRsaPkcs1v15 或 psEcdsa |
TPadesSignerOptions | CertificateThumbprint 選擇憑證,PaddingScheme 選擇簽章方案;Default 使用空指紋與 psRsaPss |
TPadesChainCertArray | DER 編碼鏈憑證的動態陣列 |
TPadesResolvedSigner | Signer、SignerCertDer 與 ChainCertDer 捆綁已解析的簽署器與憑證材料 |
TPdfRevocationMode | prmNone、prmOffline、prmOnlineAllowed 或 prmOnlineRequired |
TPdfStringArray | 用於政策 OID 與提供者機制名稱的動態字串陣列 |
TPdfCertificatePathOptions | ValidationTime、RevocationMode、RequiredPolicyOids、MaxCertificates、MaxCertificateBytes、MaxFetchBytes 與 MaxPathDepth 控制驗證與資源額度;Default 選擇離線撤銷檢查,限制為 64 張憑證、每張憑證 4 MiB、擷取資料 16 MiB 與路徑深度 16 |
TPdfCertificatePathReport | Trusted、PathBuilt、PolicyValid、RevocationChecked、PathCertificateCount、ErrorCode 與 ErrorMessage 回報驗證結果 |
TPdfPkcs11Slot | SlotID、Description、TokenLabel 與 TokenPresent 描述單一 PKCS#11 插槽 |
TPdfPkcs11Slots | TPdfPkcs11Slot 記錄的動態陣列 |
TPdfPkcs11Certificate | SlotID、ObjectID、LabelText、CertificateDer 與 Mechanisms 描述單一權杖憑證 |
TPdfPkcs11Certificates | TPdfPkcs11Certificate 記錄的動態陣列 |
TPadesSignerResolverProc | 供 PadesSignerResolverOverride 注入變數使用的函式指標型別 |
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 | 物件方法形式的回呼,隨驗證推進逐一接收 TPdfCmsVerifyStage |
TPdfCmsVerifyOptions | OnlineRetrieval、CheckRevocation、CollectChainCertificates、UrlRetrievalTimeoutMs 及 OnCheckpoint 控制驗證;CollectSignerDiagnostics 要求個別簽署者快照,MaxSignerCount 限制快照數。Default 停用擷取、撤銷檢查與簽署者診斷,將擷取預算設為 15 秒,簽署者快照上限設為 64 |
TPdfCmsSignerVerifyResult | SignerIndex 表示編碼中的 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 指派 |