EPdfKeychainError = class(Exception);
TPdfKeychainSignerProvider = class(TInterfacedObject, IPadesSignerProvider)
constructor Create(const KeychainPath: string = '');
function BackendName: string;
function Resolve(const Options: TPadesSignerOptions): TPadesResolvedSigner;
end;
TPdfKeychainCmsVerifier = class(TInterfacedObject, IPdfCmsVerifier)
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;
function KeychainAvailable: Boolean;
function KeychainMissingSymbols: string;
function KeychainVerificationAvailable: Boolean;
function ConfigureKeychainSignerProvider: IPadesSignerProvider;
function ConfigureKeychainCmsVerifier: IPdfCmsVerifier;
procedure ConfigureKeychainTrustAnchors(const Anchors: TPadesChainCertArray);
procedure ConfigureKeychainOcspResponses(const Responses: TPadesChainCertArray);
FPdfCryptoMac は、FPdfCrypto と FPdfCms が利用する macOS 向け暗号バックエンドで、プラットフォーム統合の両側面を担います。Keychain のアイデンティティによる PAdES 署名と、システムの CMS デコーダと信頼評価による CMS 検証です。Security.framework と CoreFoundation はリンクではなく実行時に名前で読み込まれ解決されるため、このユニットはすべてのターゲットでコンパイルでき、プラットフォームのサービスが実際に到達可能かを実行時に報告します
署名側では、TPdfKeychainSignerProvider が IPadesSignerProvider を実装します。その Resolve メソッドは Keychain のアイデンティティを列挙し、TPadesSignerOptions が運ぶ SHA-1 サムプリントに証明書が一致するものを選び、証明書の DER と対応する秘密鍵の参照を読み取り、ICmsSigner が Security.framework を通じて CMS の signed attributes に署名する TPadesResolvedSigner を返します。秘密鍵が Keychain の外に出ることはありません。オプションで要求されたパディング方式は鍵が実際に対応できるものと調整され、RSASSA-PSS のパラメータは他のバックエンドが発行するものと同一です。そのため macOS で署名された文書は同じ AlgorithmIdentifier を持ちます。ConfigureKeychainSignerProvider はプロバイダを構築してアクティブな PAdES 署名バックエンドとして登録し、登録したインターフェイスを返します
検証側では TPdfKeychainCmsVerifier が CMSDecoder と SecTrust 上に IPdfCmsVerifier を実装します。VerifyDetached は署名の穴の両側にある 2 つの署名対象バイト範囲を decoder の detached content に連結し、CMS を検証します。VerifyAttached は自身の内容を持つ CMS を検証し、timestamp token に使います。どちらも署名、信頼、失効を分けた TPdfCmsVerifyResult を返し、必要に応じて署名者証明書と評価済みチェーンを収集します。TPdfCmsVerifyOptions の失効、online retrieval、checkpoint 設定にも従います。ConfigureKeychainCmsVerifier は verifier を作り、有効な CMS 検証バックエンドとして登録します
署名の有効性と証明書の信頼は独立した結果として保たれます。そのため、信頼されていないチェーンや自己署名チェーンの下での正真の署名は、改ざんされたコンテンツと区別できます
attached RFC 3161 token では、上限付き DER 解析により元のカプセル化された TSTInfo octet を native decoder に渡し、content type と署名属性は変更しません。通常の CMS 検証では unsigned attribute を native 入力から除き、自動 timestamp 処理が外側の署名自身の完全性やチェーン結果を置き換えるのを防ぎます。この検証は countersignature や他の unsigned attribute を検証しません。ValidatePadesTrust が元の各 timestamp token、message imprint、TSA 証明書の役割、信頼、失効を別途検証します
TPdfKeychainSignerProvider.Create に Keychain ファイルのパスを渡すと、その query だけの search list で identity 検索を選択した Keychain に限定できます。その後 ConfigurePadesSignerProvider で登録します。空のパスは現在のユーザー検索範囲を使います。選んだ Keychain を開いたり検索したりしても、既定 Keychain、ユーザーの search list、システムの信頼設定は変わりません。不正なパスや範囲限定検索の symbol 不足は EPdfKeychainError になります
Resolve は offline かつ query 内だけの証明書検索とネイティブのチェーン構築で、署名証明書の取得可能な発行者チェーンも export します。候補は 4096 証明書、各 1 MiB、合計 16 MiB までです。構築するチェーンは leaf を含め 32 証明書までで、leaf は ChainCertDer と別に返します。証明書材料を export しても信頼は成立せず、trust anchor も登録しません。取得できない発行者を合成することもありません
| 関数 | 説明 |
|---|---|
KeychainAvailable | Security.framework と CoreFoundation が読み込まれ、署名に必要なすべてのシンボルが解決されているときに True を返します |
KeychainMissingSymbols | 解決に失敗した名前を空白区切りで返します。すべてがバインドされていれば空文字列を返します |
ConfigureKeychainSignerProvider | TPdfKeychainSignerProvider を構築して PAdES 署名バックエンドとして登録し、IPadesSignerProvider として返します |
TPdfKeychainSignerProvider.Create | identity 検索を限定する既存の Keychain ファイルを任意で選びます。埋め込み NUL と、文字列のコード単位 4096 を超えるパスは拒否します |
TPdfKeychainSignerProvider.BackendName | 署名プロバイダが報告するバックエンド識別子を返します |
TPdfKeychainSignerProvider.Resolve | TPadesSignerOptions を Keychain のアイデンティティと照合し、署名者、証明書の DER、チェーンを含む TPadesResolvedSigner を返します |
| 関数 | 説明 |
|---|---|
KeychainVerificationAvailable | CMS デコーダ、信頼ポリシー、信頼評価のシンボルが解決されているときに True を返します |
ConfigureKeychainCmsVerifier | TPdfKeychainCmsVerifier を構築して CMS 検証バックエンドとして登録し、IPdfCmsVerifier として返します |
ConfigureKeychainTrustAnchors | 後の各信頼評価に使う明示 DER anchor を複製し、Keychain を変更せず system anchor を補います。上限は 64 証明書、各 4 MiB、合計 16 MiB で、空配列は解除します |
ConfigureKeychainOcspResponses | Security.framework の native 評価用に明示 DER OCSP 証拠を複製します。上限は 8 応答、各 1 MiB、合計 4 MiB で、空配列は解除します |
TPdfKeychainCmsVerifier.BackendName | 検証バックエンドが報告するバックエンド識別子を返します |
TPdfKeychainCmsVerifier.VerifyDetached | Segment1、Segment1Length、Segment2、Segment2Length が示す 2 つの呼び出し側所有コンテンツセグメントに対して detached CMS 値を検証します。指定された TPdfCmsVerifyOptions を使用します |
TPdfKeychainCmsVerifier.VerifyAttached | 署名済みコンテンツを自身で運ぶ attached CMS 値を検証します。指定された TPdfCmsVerifyOptions を使用します |
| 型 | メンバーと目的 |
|---|---|
EPdfKeychainError | Security.framework が利用できない場合、要求された署名者に一致する Keychain アイデンティティがない場合、またはプラットフォームの署名呼び出しが失敗した場合に発生する例外です |
TPdfKeychainSignerProvider | IPadesSignerProvider を実装する PAdES 署名バックエンドです。BackendName と Resolve を持ちます |
TPdfKeychainCmsVerifier | IPdfCmsVerifier を実装する CMS 検証バックエンドです。BackendName、VerifyDetached、VerifyAttached を持ちます |
KeychainAvailable と KeychainVerificationAvailable は署名と検証を別々に報告します。両者は異なる framework シンボルを必要とするため、片方だけがバインドされて片方はされていないという状態があり得ますKeychainMissingSymbols は解決に失敗したすべてのシンボルを名前挙げします。これにより、framework が存在しないこととバインドの問題とを区別できます。結果が空ならすべてがバインドされており、framework のパスが挙げられていれば framework が読み込めておらず、個々のエントリポイントが挙げられていれば framework は読み込めたものの名前が解決できなかったことを意味しますKeychainAvailable と KeychainVerificationAvailable が False、KeychainMissingSymbols が空となり、設定関数は EPdfKeychainError を送出しますTPadesSignerOptions が証明書サムプリントを運ばない場合、Keychain の中で最初に使えるアイデンティティが選ばれます。これはテストには向きますが、実運用の署名には向きませんpcvsUnsupported となり、完全性を valid/invalid とは報告しません。この形式には OpenSSL CMS verifier を使ってください。複数アルゴリズムの署名者診断でも、各署名者の結果を個別に維持しますFreshOcspResponse の時刻/DER 事前フィルターを通り、続いて native の responder 署名、権限、証明書を確認します。許容時刻差は 300 秒、producedAt と thisUpdate の古さは最大 1 日ですOnlineRetrieval=False は native の trust-network 取得を無効にします。Security.framework の online 評価は platform の動作に従い、UrlRetrievalTimeoutMs はこのバックエンドに OpenSSL の制限付き通信期限を与えませんCollectSignerDiagnostics=True は個別の署名者 snapshot を返し、MaxSignerCount とハード上限 64 を適用します。返す証明書材料は各 4 MiB、合計 64 MiB までで、未完了の収集は pcvsIndeterminate ですSignerDiagnosticsStatus=pcvsValid は失敗した署名者判定も含む収集完了を示します。RevocationError は Security.framework の native status で、このバックエンドの RevocationCertificate は空のままです