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);
TPdfCmsVerifyStage = (pcvstCryptographicSignature, pcvstChainBuild,
pcvstOnlineRetrieval, pcvstRevocationCheck);
TPdfCmsVerifyCheckpoint = procedure(Stage: TPdfCmsVerifyStage) of object;
TPdfCmsVerifyOptions = record
OnlineRetrieval: Boolean;
CheckRevocation: Boolean;
CollectChainCertificates: Boolean;
UrlRetrievalTimeoutMs: Cardinal;
OnCheckpoint: TPdfCmsVerifyCheckpoint;
class function Default: TPdfCmsVerifyOptions; static;
end;
TPdfCmsVerifyResult = record
SignatureStatus: TPdfCmsVerifyStatus;
TrustStatus: TPdfCmsVerifyStatus;
RevocationStatus: TPdfCmsVerifyStatus;
SignatureError: Cardinal;
TrustError: Cardinal;
SignerCertificate: TBytes;
ChainCertificates: TPadesChainCertArray;
RevocationReason: TPdfCmsRevocationReason;
RevocationError: Cardinal;
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;
FPdfCrypto — входная точка стека подписи PAdES. PadesCryptoAvailable сообщает, подключён ли криптографический бэкенд на текущей платформе, а PadesCryptoBackendName идентифицирует его; в Windows бэкенд Cryptography Next Generation из FPdfCryptoWin привязывается автоматически
ResolvePadesSigner принимает отпечаток сертификата и схему дополнения и возвращает полностью заполненный TPadesResolvedSigner: реализацию ICmsSigner, выполняющую операцию с закрытым ключом, сертификат подписанта в DER и сертификаты выпускающей цепочки. Результат передаётся напрямую в FPdfCms.BuildSignedData
Пользовательские интеграции могут зарегистрировать IPadesSignerProvider, включая IPdfPkcs11SignerProvider, перечисляющий слоты токенов и сертификаты, либо использовать PadesSignerResolverOverride как детерминированный шов распознавателя
Проверка цепочки сертификатов строится на провайдерах и бюджетах: вызывающий код настраивает IPdfCertificatePathValidator, при необходимости передаёт явные якоря доверия, IPdfTrustStore и IPdfValidationFetcher, а затем изучает TPdfCertificatePathReport
| Function | Description |
|---|---|
PadesCryptoAvailable | Возвращает True, когда криптографический бэкенд для подписи PAdES доступен на текущей платформе |
PadesCryptoBackendName | Возвращает отображаемое имя активного криптографического бэкенда |
ResolvePadesSigner | Превращает отпечаток сертификата и схему дополнения в подписанта, сертификат подписанта и цепочку |
ConfigurePdfCertificatePathValidator | Устанавливает или очищает глобальный для процесса IPdfCertificatePathValidator, используемый ValidatePdfCertificatePath |
ValidatePdfCertificatePath | Проверяет листовой сертификат относительно промежуточных и объединённых явных якорей доверия из хранилища после применения бюджетов количества сертификатов, размера, загрузки и глубины цепочки |
ConfigurePadesSignerProvider | Устанавливает или очищает глобальный для процесса провайдер подписанта, используемый перед платформенным бэкендом |
ConfigurePadesCmsVerifier | Устанавливает бэкенд проверки CMS, используемый валидатором PAdES; его очистка восстанавливает Windows CryptoAPI в Windows. Другие платформы требуют явного вызова ConfigureSslCmsVerifier или ConfigureKeychainCmsVerifier |
PadesCmsVerificationAvailable | Возвращает True, если в этой сборке есть хоть какой-нибудь бэкенд, умеющий проверять CMS — зарегистрированный или встроенный |
PadesCmsVerificationBackendName | Возвращает отображаемое имя активного бэкенда проверки или пустую строку, если его нет |
| Interface member | Description |
|---|---|
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 | Проверяет токен метки времени: он несёт своё содержимое и не требует отдельных сегментов |
| Type | Description |
|---|---|
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; evidence-отчёты включают обе пары
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 МиБ, а суммарную работу диагностики на ввод/вывод — 64 МиБ; macOS ограничивает возвращаемые данные сертификатов 4 МиБ на сертификат и 64 МиБ суммарно. Меньшее MaxSignerCount дополнительно снижает запрошенное вызывающим количество
Снимки подписантов переиспользуют настроенные свидетельства и свидетельства, полученные во время агрегированной проверки. OpenSSL не выполняет повторное сетевое извлечение для каждого диагностического снимка, а неполное агрегированное извлечение не может стать успешным автономным снимком отзыва
PadesSignerResolverOverride имеет приоритет, затем явно зарегистрированный IPadesSignerProvider, затем платформенное значение по умолчанию. Стандартные значения вне Windows требуют ConfigureSslSigningCredentials; одной доступности libcrypto недостаточно, чтобы предоставить закрытый ключ или сертификат
Стандартный бэкенд OpenSSL отклоняет непустой CertificateThumbprint, потому что его сертификат выбран явной конфигурацией. Подпись через Keychain остаётся доступной через ConfigureKeychainSignerProvider, когда приложение выбирает этот провайдер
| Variable | Description |
|---|---|
PadesSignerResolverOverride | Необязательный обратный вызов распознавателя, вычисляемый перед зарегистрированными и платформенными провайдерами |
PadesCmsVerifier | Текущий бэкенд проверки CMS, обычно назначаемый через ConfigurePadesCmsVerifier |
PdfCertificatePathValidator | Текущий валидатор цепочки сертификатов, обычно назначаемый через ConfigurePdfCertificatePathValidator |
PadesSignerProvider | Текущий провайдер подписанта, обычно назначаемый через ConfigurePadesSignerProvider |