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 に渡されます
カスタム連携では、トークンスロットと証明書を列挙する IPdfPkcs11SignerProvider を含む IPadesSignerProvider を登録するか、決定論的なリゾルバの差し込み口として PadesSignerResolverOverride を使用できます
証明書パス検証はプロバイダーベースで予算管理されています。呼び出し側は IPdfCertificatePathValidator を構成し、任意で明示的なトラストアンカー、IPdfTrustStore、IPdfValidationFetcher を渡して、TPdfCertificatePathReport を検査します
| 関数 | 説明 |
|---|---|
PadesCryptoAvailable | 現在のプラットフォームで PAdES 署名に使用できる暗号バックエンドが存在する場合に True を返します |
PadesCryptoBackendName | アクティブな暗号バックエンドの表示名を返します |
ResolvePadesSigner | 証明書のサムプリントとパディング方式を、署名者、署名者証明書、チェーンに解決します |
ConfigurePdfCertificatePathValidator | ValidatePdfCertificatePath が使用するプロセス全体の IPdfCertificatePathValidator を設定またはクリアします |
ValidatePdfCertificatePath | 証明書数、サイズ、フェッチ、パス深さの予算を強制した後、リーフ証明書を中間証明書および明示的アンカーとトラストストアアンカーの結合に対して検証します |
ConfigurePadesSignerProvider | プラットフォームバックエンドより優先して使用される、プロセス全体の署名プロバイダーを設定またはクリアします |
ConfigurePadesCmsVerifier | PAdES validator が使う CMS 検証バックエンドを登録します。解除すると Windows では Windows CryptoAPI に戻ります。他のプラットフォームでは ConfigureSslCmsVerifier または ConfigureKeychainCmsVerifier を明示的に呼ぶ必要があります |
PadesCmsVerificationAvailable | このビルドで CMS を検証できるバックエンドが何かしらある場合に True を返します。登録されたものでも組み込みのものでも構いません |
PadesCmsVerificationBackendName | 有効な検証バックエンドの表示名を返します。なければ空文字列を返します |
| インターフェイスメンバー | 説明 |
|---|---|
IPdfTrustStore.LoadTrustAnchors | 構成された証明書予算の範囲内で、追加の DER エンコードされたトラストアンカーを返します |
IPdfValidationFetcher.Fetch | MaxBytes を超えずに Uri から検証マテリアルを取得します |
IPdfCertificatePathValidator.Validate | 証明書パスを構築・評価し、TPdfCertificatePathReport に値を設定します |
IPadesSignerProvider.BackendName | PadesCryptoBackendName が公開するプロバイダー表示名を返します |
IPadesSignerProvider.Resolve | 指定された TPadesSignerOptions に対する完全な署名者マテリアルを返します |
IPdfPkcs11SignerProvider.EnumerateSlots | 利用可能な PKCS#11 スロットとトークン存在メタデータを返します |
IPdfPkcs11SignerProvider.EnumerateCertificates | 1 つの PKCS#11 スロットで可視な証明書と署名メカニズムを返します |
IPdfPkcs11SignerProvider.CloseProtectedSessions | プロバイダーが所有する保護された、または認証済みの PKCS#11 セッションを閉じます |
IPdfCmsVerifier.BackendName | PadesCmsVerificationBackendName が報告する検証バックエンドの表示名を返します |
IPdfCmsVerifier.VerifyDetached | PDF 署名を検証します。署名対象のコンテンツは /Contents の抜け穴を挟む 2 つのバイト範囲です |
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 が 1 つの PKCS#11 スロットを記述します |
TPdfPkcs11Slots | TPdfPkcs11Slot レコードの動的配列です |
TPdfPkcs11Certificate | SlotID、ObjectID、LabelText、CertificateDer、Mechanisms が 1 つのトークン証明書を記述します |
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 は署名者別 snapshot を要求し、MaxSignerCount は件数を制限します。Default は取得、失効、署名者診断を無効にし、取得上限を 15 秒、署名者 snapshot を 64 件にします |
TPdfCmsSignerVerifyResult | SignerIndex はエンコードされた SignerInfo の順序です。署名、信頼、失効の状態と native error は署名者ごとに独立しています。SignerCertificate は署名者の DER 証明書、RevocationCertificate はバックエンドが取得できた場合に失効エラーに関係する証明書を示します |
TPdfCmsSignerVerifyResults | 件数を制限した署名者 snapshot の動的配列 |
TPdfCmsVerifyResult | 集約した署名、信頼、失効の状態も独立しています。レコードには SignatureError、TrustError、SignerCertificate、ChainCertificates、RevocationReason、RevocationError、RevocationCertificate、SignerResults、SignerDiagnosticsStatus、SignerCount も含まれます |
公開オプションと結果レコードが拡張されたため、更新時は利用側を再ビルドしてください。独自 verifier は管理対象の結果を Default(TPdfCmsVerifyResult) で初期化し、未対応の snapshot 項目は unavailable のままにします。文字列や動的配列を持つ生きたレコードを FillChar で消去しないでください
IPdfCmsVerifier.VerifyDetached または VerifyAttached が返す TPdfCmsVerifyResult から RevocationReason と RevocationError を読み取ります。PAdES トラスト検証はこれらを RevocationReason と NativeRevocationError として保持し、タイムスタンプトークン用には TimeStampRevocationReason と NativeTimeStampRevocationError フィールドが別に用意されます。エビデンスレポートには両方のペアが含まれます
RevocationError はバックエンド固有のネイティブ検証コードで、0 はネイティブの診断情報が取れなかったことを意味します。OpenSSL は X509_V_ERR_* のエラー空間を使います。Windows は証明書の CERT_REVOCATION_INFO.dwRevocationResult から取り出した生の DWORD を、失効チェーン呼び出しが失敗した場合はその時点の GetLastError の値を保持します。これは統一された HRESULT エラー空間でも、チェーン トラストの集約ビットマスクでもありません
OpenSSL は確認済みの失効と、期限切れ/取得不可/不正な CRL、取得不可/不正/unknown の OCSP を区別します。Windows は確認済みの失効、信頼できないチェーン、不明な native failure を報告します。macOS は署名の完全性、Basic X.509 の信頼、失効を別々に評価し、すべての platform failure を CRL/OCSP 分類に置き換えず Security.framework の native error を返します
RevocationCertificate は CMS 署名者ではなく失効した中間証明書を示す場合があります。取得できないバックエンドでは空です。OpenSSL は取得できますが、現在の macOS バックエンドは空のままです
pcrrNone もエラー 0 も、失効確認が行われたことや成功したことを証明するものではありません。判断には必ず RevocationStatus を確認してください
CollectSignerDiagnostics=True にすると、制限内の snapshot を SignerResults で確認できます。SignerCount は確定できたエンコード済み SignerInfo 数で、0 は数を確定できなかったことを示します
SignerDiagnosticsStatus=pcvsValid は、無効な署名の snapshot も含め、要求した収集が完了したことを示します。すべての署名が通ったという意味ではありません。pcvsUnavailable は収集が無効または未対応、pcvsIndeterminate は解析/リソース上限内で収集を完了できなかった状態です
OpenSSL とネイティブ macOS は収集を 64 署名者までに制限します。OpenSSL は診断 CMS 入力 4 MiB、診断の入出力作業合計 64 MiB も制限します。macOS の戻す証明書材料は各 4 MiB、合計 64 MiB です。小さい MaxSignerCount は要求件数をさらに減らします
署名者 snapshot は設定済み証拠と集約検証中に取得した証拠を再利用します。OpenSSL は snapshot ごとの再取得を行わず、不完全な集約取得が成功した offline 失効 snapshot に変わることもありません
PadesSignerResolverOverride を最優先し、次に明示登録した IPadesSignerProvider、最後に platform の既定を使います。Windows 以外の既定には ConfigureSslSigningCredentials が必要で、libcrypto があるだけでは秘密鍵や証明書は得られません
OpenSSL の既定は明示設定で証明書を選ぶため、空でない CertificateThumbprint を拒否します。アプリケーションが Keychain provider を選ぶ場合は、引き続き ConfigureKeychainSignerProvider で署名できます
| 変数 | 説明 |
|---|---|
PadesSignerResolverOverride | 登録済みプロバイダーおよびプラットフォームプロバイダーより前に評価される、任意のリゾルバコールバックです |
PadesCmsVerifier | 現在の CMS 検証バックエンドです。通常は ConfigurePadesCmsVerifier 経由で代入されます |
PdfCertificatePathValidator | 現在の証明書パスバリデーターです。通常は ConfigurePdfCertificatePathValidator 経由で代入されます |
PadesSignerProvider | 現在の署名プロバイダーです。通常は ConfigurePadesSignerProvider 経由で代入されます |