TCmsSignerIdKind = (sidIssuerAndSerial, sidSubjectKeyIdentifier);
TCmsSignerId = record
Kind: TCmsSignerIdKind;
IssuerDer: TBytes;
SerialDer: TBytes;
SubjectKeyId: TBytes;
end;
ICmsSigner = interface
function GetDigestAlgorithmOid: AnsiString;
function GetSignatureAlgorithmOid: AnsiString;
function GetSignatureAlgorithmParams: TBytes;
function GetSignerId: TCmsSignerId;
function SignSignedAttrsDigest(const Digest: TSHA256Digest): TBytes;
end;
TCmsBuildOptions = record
SigningTimeUtc: TDateTime;
CommitmentTypeOid: AnsiString;
SignaturePolicyOid: AnsiString;
SignaturePolicyHash: TBytes;
SignaturePolicyUri: AnsiString;
SignaturePolicyDocument: TBytes;
class function Default: TCmsBuildOptions; static;
end;
function VerifyCmsSignaturePolicyDocument(const Options: TCmsBuildOptions;
const PolicyDocument: TBytes; out ErrorText: string): Boolean;
function BuildSignedData(const DetachedDigest: TSHA256Digest;
const Signer: ICmsSigner; const SignerCertDer: TBytes;
const ChainCertDer: array of TBytes;
const Options: TCmsBuildOptions): TBytes;
function ExtractSignatureValue(const CmsDer: TBytes;
out SignatureValueOctets: TBytes): Boolean;
procedure AddSignatureTimestampToCms(var CmsDer: TBytes;
const TimestampTokenDer: TBytes);
FPdfCms — низкоуровневый построитель CMS, используемый внутри пути подписи PAdES. Он позволяет опытному пользователю собрать значение CMS SignedData из дайджеста SHA-256 подписанных атрибутов, абстракции подписанта, сертификата подписанта и необязательной цепочки сертификатов
Интерфейс ICmsSigner — контракт криптографического бэкенда: вызывающий код предоставляет OID алгоритмов дайджеста и подписи, идентификатор подписанта и выполняет фактическую операцию с закрытым ключом над дайджестом подписанных атрибутов. Это отделяет кодирование CMS от конкретного криптопровайдера
TCmsBuildOptions может добавить время подписи, тип обязательства и явный идентификатор политики подписи с хешем политики SHA-256, URI и необязательным документом политики в памяти
ExtractSignatureValue извлекает исходные октеты подписи из готового значения CMS, чтобы их можно было отправить в службу отметок времени; AddSignatureTimestampToCms затем встраивает возвращённый токен отметки времени как неподписанный атрибут, образуя форму, соответствующую B-T/B-LTA
| Method | Description |
|---|---|
GetDigestAlgorithmOid | Возвращает OID хеш-алгоритма, применённого к подписанным атрибутам (например 2.16.840.1.101.3.4.2.1 для SHA-256) |
GetSignatureAlgorithmOid | Возвращает OID алгоритма подписи, применяемого к дайджесту |
GetSignatureAlgorithmParams | Возвращает параметры алгоритма (часто пустые для ECDSA; содержит блоб параметров RSA-PSS для PSS) |
GetSignerId | Возвращает TCmsSignerId, идентифицирующий подписанта по издателю и серийному номеру либо по идентификатору ключа субъекта |
SignSignedAttrsDigest | Выполняет подпись закрытым ключом по переданному дайджесту и возвращает октеты подписи |
| Routine | Description |
|---|---|
CertKeyAlgorithmOid | Читает OID алгоритма SubjectPublicKeyInfo из сертификата — именно он определяет, что используется: RSA или ECDSA; этот OID нужен каждому бэкенду подписи, поэтому он живёт здесь, а не внутри одного из них |
ExtractIssuerAndSerial | Извлекает исходные TLV issuer и serialNumber, которые содержит SignerIdentifier, в IssuerTlv и SerialTlv |
EcDsaP1363ToDer | Упаковывает «сырую» подпись ECDSA в формате P1363 r||s в DER-последовательность из двух INTEGER, которую ожидает CMS; токены и криптографические API платформ возвращают подпись именно в таком виде |
VerifyCmsSignaturePolicyDocument | Требует непустой SignaturePolicyOid и 32-байтовый SignaturePolicyHash, затем проверяет переданный документ политики по SHA-256 и возвращает диагностический текст при сбое |
BuildSignedData | Строит полный отсоединённый CMS ContentInfo по RFC 5652 с одним CAdES SignerInfo, сертификатом подписанта, необязательной цепочкой и настроенными подписанными атрибутами |
ExtractSignatureValue | Извлекает исходные октеты подписи SignerInfo, используемые как вход сообщения для отметки времени RFC 3161 |
AddSignatureTimestampToCms | Добавляет полный TimeStampToken RFC 3161 как неподписанный атрибут signature-time-stamp и перекодирует объемлющие длины |
| Type | Description |
|---|---|
TCmsSignerIdKind | sidIssuerAndSerial выбирает Name издателя плюс TLV серийного номера, а sidSubjectKeyIdentifier — исходные октеты идентификатора ключа субъекта |
TCmsSignerId | Kind, IssuerDer, SerialDer и SubjectKeyId несут выбранную форму идентификатора SignerInfo |
TCmsBuildOptions | SigningTimeUtc, CommitmentTypeOid, SignaturePolicyOid, SignaturePolicyHash, SignaturePolicyUri и SignaturePolicyDocument настраивают подписанные атрибуты; Default очищает все необязательные значения |
TSHA256Digest предоставляется модулем FPdfSha256BuildSignedData принимает цепочку сертификатов как открытый массив сертификатов в кодировке DER; первым идти подписант не обязательно — порядок следует CMS EncapsulatedCertificateSet