import { ErrorResult, Micro509Error } from "../result/result.js"; import { SignatureProfileInput } from "../internal/crypto/signing.js"; import { ParsedCertificate, ParsedName } from "../x509/parse.js"; //#region src/pkcs/pkcs7.d.ts /** PEM text (may contain multiple CERTIFICATE blocks), raw DER bytes, or an already-parsed certificate. */ type Pkcs7CertificateSource = string | Uint8Array | ParsedCertificate; /** DER, PEM, and base64 encodings of a PKCS#7 certificate bag. */ interface Pkcs7CertBagMaterial { /** Raw DER-encoded PKCS#7 structure. */ readonly der: Uint8Array; /** PEM-armored PKCS#7 (`-----BEGIN PKCS7-----`). */ readonly pem: string; /** Base64-encoded DER (no PEM armor). */ readonly base64: string; } /** * RFC 5652 §5.3 `SignerIdentifier ::= CHOICE { issuerAndSerialNumber, * subjectKeyIdentifier [0] }`, which locates the signer's certificate. */ type ParsedSignerIdentifier = { /** Issuer name plus serial number. */ readonly type: "issuerAndSerialNumber"; /** Parsed issuer distinguished name. */ readonly issuer: ParsedName; /** Hex-encoded certificate serial number. */ readonly serialNumberHex: string; } | { /** SubjectKeyIdentifier (`[0]`). */ readonly type: "subjectKeyIdentifier"; /** Hex-encoded SubjectKeyIdentifier of the signer certificate. */ readonly subjectKeyIdentifier: string; }; /** Fields shared by every decoded SignerInfo, regardless of signed-attribute presence. */ interface ParsedPkcs7SignerInfoBase { /** CMS SignerInfo version (typically 1 for issuerAndSerialNumber). */ readonly version: number; /** Which of the two RFC 5652 §5.3 SignerIdentifier alternatives this SignerInfo uses. */ readonly signerIdentifier: ParsedSignerIdentifier; /** OID of the digest algorithm used to hash the content. */ readonly digestAlgorithmOid: string; /** Human-readable digest algorithm name (e.g. `"SHA-256"`). */ readonly digestAlgorithmName: string; /** OID of the algorithm used to produce the signature. */ readonly signatureAlgorithmOid: string; /** Human-readable signature algorithm name. */ readonly signatureAlgorithmName: string; /** Raw DER of the signature AlgorithmIdentifier parameters, if present. */ readonly signatureAlgorithmParametersDer?: Uint8Array; /** Hex-encoded raw signature bytes. */ readonly signatureHex: string; /** Raw signature bytes. */ readonly signature: Uint8Array; } /** * A single SignerInfo decoded from a PKCS#7 SignedData structure. * * Discriminated on `hasSignedAttrs`: when `true`, `signedAttrsDer` is always * present; when `false`, it cannot exist. */ type ParsedPkcs7SignerInfo = (ParsedPkcs7SignerInfoBase & { /** This SignerInfo includes authenticated (signed) attributes. */ readonly hasSignedAttrs: true; /** Raw DER of signedAttrs with original IMPLICIT [0] tag (0xa0). */ readonly signedAttrsDer: Uint8Array; }) | (ParsedPkcs7SignerInfoBase & { /** This SignerInfo has no authenticated attributes. */ readonly hasSignedAttrs: false; /** Never present without signed attributes. */ readonly signedAttrsDer?: undefined; }); /** * One RFC 5652 §10.2.2 CertificateChoices alternative. * * X.509 is the only alternative this library decodes. The rest keep their DER, * including the context tag, so a CertificateSet round-trips and a caller can * tell an X.509-only bag from one carrying attribute certificates. RFC 5652 * marks `extendedCertificate` and `attributeCertificateV1` obsolete. */ type ParsedCertificateChoice = { /** X.509 certificate (untagged `Certificate`). */ readonly type: "certificate"; /** The decoded certificate. */ readonly certificate: ParsedCertificate; } | { /** PKCS #6 extended certificate (`[0]`), obsolete. */ readonly type: "extendedCertificate"; /** Raw DER of the element, including its context tag. */ readonly der: Uint8Array; } | { /** Version 1 X.509 attribute certificate (`[1]`), obsolete. */ readonly type: "attributeCertificateV1"; /** Raw DER of the element, including its context tag. */ readonly der: Uint8Array; } | { /** Version 2 X.509 attribute certificate (`[2]`). */ readonly type: "attributeCertificateV2"; /** Raw DER of the element, including its context tag. */ readonly der: Uint8Array; } | { /** Any other certificate format (`[3] OtherCertificateFormat`). */ readonly type: "other"; /** `otherCertFormat` OID identifying the format. */ readonly formatOid: string; /** Raw DER of the element, including its context tag. */ readonly der: Uint8Array; }; /** Decoded PKCS#7 SignedData content, including certificates and signer info. */ interface ParsedPkcs7SignedData { /** Original DER bytes when this object came from {@linkcode parsePkcs7SignedDataDer} or PEM parsing. */ readonly der?: Uint8Array; /** Outer ContentInfo type OID (always `pkcs7-signedData`). */ readonly contentTypeOid: string; /** SignedData version number. */ readonly version: number; /** OIDs of digest algorithms declared in `digestAlgorithms`. */ readonly digestAlgorithmOids: readonly string[]; /** Human-readable digest algorithm names declared in `digestAlgorithms`. */ readonly digestAlgorithmNames: readonly string[]; /** OID of the encapsulated content type (e.g. `pkcs7-data`). */ readonly encapsulatedContentTypeOid: string; /** Raw encapsulated content bytes. Absent in degenerate (certs-only) bags. */ readonly encapsulatedContent?: Uint8Array; /** RFC 5652 §10.2.2 CertificateChoices entries from the SignedData certificate set. */ readonly certificateChoices: readonly ParsedCertificateChoice[]; /** Decoded signer info entries. Empty for degenerate cert bags. */ readonly signerInfos: readonly ParsedPkcs7SignerInfo[]; } /** Error codes for PKCS#7 parse failures. */ type ParsePkcs7ErrorCode = "malformed" | "not_signed_data"; /** Error payload for a failed PKCS#7 parse. */ interface ParsePkcs7Failure extends Micro509Error { /** Always `false` for failures. */ readonly ok: false; } /** Success-or-failure result from {@linkcode parsePkcs7SignedDataDer} / {@linkcode parsePkcs7SignedDataPem}. */ type ParsePkcs7SignedDataResult = { /** Parse succeeded. */ readonly ok: true; /** Decoded SignedData. */ readonly value: ParsedPkcs7SignedData; } | ErrorResult, ParsePkcs7Failure>; /** Success-or-failure result from {@linkcode parsePkcs7CertBagDer} / {@linkcode parsePkcs7CertBagPem}. */ type ParsePkcs7CertBagResult = { /** Parse succeeded. */ readonly ok: true; /** Parsed certificates from the cert bag. */ readonly value: readonly ParsedCertificate[]; } | ErrorResult, ParsePkcs7Failure>; /** * Error codes for {@linkcode verifyPkcs7SignedData} failures. * * `detached_content_required` means the SignedData carries no `eContent` * (detached signature or degenerate cert bag) and no external content was * supplied via {@linkcode VerifyPkcs7SignedDataOptions}. */ type VerifyPkcs7SignedDataErrorCode = "signer_not_found" | "signature_invalid" | "message_digest_mismatch" | "detached_content_required" | ParsePkcs7ErrorCode; /** Error payload for a failed {@linkcode verifyPkcs7SignedData} call. */ interface VerifyPkcs7SignedDataFailure extends Micro509Error { /** Always `false` for failures. */ readonly ok: false; } /** Options for {@linkcode verifyPkcs7SignedData}. */ interface VerifyPkcs7SignedDataOptions { /** * External content for a detached SignedData (RFC 5652 Section 5.2, absent `eContent`). * Required to verify a detached signature; ignored when the SignedData embeds its own content. */ readonly content?: Uint8Array; } /** A SignerInfo paired with the certificate that verified its signature. */ interface VerifiedPkcs7Signer { /** The SignerInfo whose signature verified. */ readonly signerInfo: ParsedPkcs7SignerInfo; /** The certificate from the SignedData certificate set that verified it. */ readonly certificate: ParsedCertificate; } /** Success-or-failure result from {@linkcode verifyPkcs7SignedData}. */ type VerifyPkcs7SignedDataResult = { /** Verification succeeded. */ readonly ok: true; /** The verified SignedData structure. */ readonly value: ParsedPkcs7SignedData; /** One entry per SignerInfo, in SignedData order. */ readonly signers: readonly VerifiedPkcs7Signer[]; } | ErrorResult, VerifyPkcs7SignedDataFailure>; /** Caller-correctable failure code from {@linkcode createPkcs7CertBag}. */ type CreatePkcs7CertBagErrorCode = "invalid_certificate"; /** Error payload for a failed PKCS#7 certificate bag creation. */ interface CreatePkcs7CertBagFailure extends Micro509Error { /** Always `false` for failures. */ readonly ok: false; } /** Success-or-failure result from {@linkcode createPkcs7CertBag}. */ type CreatePkcs7CertBagResult = { /** Creation succeeded. */ readonly ok: true; /** DER, PEM, and base64 forms of the certificate bag. */ readonly value: Pkcs7CertBagMaterial; } | ErrorResult, CreatePkcs7CertBagFailure>; /** * Creates a degenerate PKCS#7 SignedData structure containing only * certificates (no signers), returning DER, PEM, and base64 forms, or a * typed `invalid_certificate` failure when a certificate source is not * valid PEM/DER. */ declare function createPkcs7CertBag(certificates: readonly Pkcs7CertificateSource[]): CreatePkcs7CertBagResult; /** A single signer for {@linkcode createPkcs7SignedData}. */ interface Pkcs7Signer { /** * Signer certificate (PEM text with one CERTIFICATE block, or raw DER). * Embedded in the SignedData certificate set and referenced by the * SignerInfo via issuerAndSerialNumber. */ readonly certificate: Pkcs7CertificateSource; /** Private key matching the certificate's public key, used to sign. */ readonly privateKey: CryptoKey; /** * Signature profile. Defaults to inferring the algorithm from the key * (e.g. ECDSA→ecdsa-with-SHA*, RSA→sha*WithRSAEncryption, Ed25519). * Pass `{ kind: 'rsa-pss' }` to force RSA-PSS padding for an RSA-PSS key. */ readonly signature?: SignatureProfileInput; } /** Input for {@linkcode createPkcs7SignedData}. */ interface CreatePkcs7SignedDataInput { /** Content to encapsulate and sign (the eContent). */ readonly content: Uint8Array; /** One or more signers. Each produces a SignerInfo with signed attributes. */ readonly signers: readonly Pkcs7Signer[]; /** * Additional certificates to embed (e.g. intermediates). Signer * certificates are always embedded; duplicate DER is removed. */ readonly additionalCertificates?: readonly Pkcs7CertificateSource[]; /** * Encapsulated content type OID. * @default `'1.2.840.113549.1.7.1'` (pkcs7-data) */ readonly encapsulatedContentTypeOid?: string; /** * Omit `eContent` from `encapContentInfo` (RFC 5652 Section 5.2 detached * form). The signature still covers `content` via the messageDigest signed * attribute, but the bytes are not embedded — the verifier must supply them * externally (e.g. git x509 commit signing, S/MIME detached signatures). * @default false */ readonly detached?: boolean; } /** DER, PEM, and base64 encodings of a PKCS#7/CMS SignedData structure. */ interface Pkcs7SignedDataMaterial { /** Raw DER-encoded SignedData ContentInfo. */ readonly der: Uint8Array; /** * PEM-armored ContentInfo. A version 1 SignedData carries the `PKCS7` * label; a version 3 one is outside RFC 2315, whose SignedData version * "shall be 1", so it carries the RFC 7468 Section 9 `CMS` label. */ readonly pem: string; /** Base64-encoded DER (no PEM armor). */ readonly base64: string; } /** Caller-correctable failure codes from {@linkcode createPkcs7SignedData}. */ type CreatePkcs7SignedDataErrorCode = "no_signers" | "invalid_signer_certificate" | "invalid_certificate" | "signer_certificate_key_mismatch" | "unsupported_signer_key"; /** Error payload for a failed PKCS#7 SignedData creation. */ interface CreatePkcs7SignedDataFailure extends Micro509Error { /** Always `false` for failures. */ readonly ok: false; } /** Success-or-failure result from {@linkcode createPkcs7SignedData}. */ type CreatePkcs7SignedDataResult = { /** Creation succeeded. */ readonly ok: true; /** DER, PEM, and base64 forms of the SignedData. */ readonly value: Pkcs7SignedDataMaterial; } | ErrorResult, CreatePkcs7SignedDataFailure>; /** * Creates a PKCS#7/CMS SignedData with one or more signers over `content`. * * Each signer uses the RFC 5652 Section 5.4 signed-attributes flow: the * signature covers a `SET OF` authenticated attributes carrying `contentType` * and `messageDigest` (the digest of the encapsulated content). By default the * content is embedded (attached signature), so the result verifies with * {@linkcode verifyPkcs7SignedData} without any external data. With * `detached: true` the `eContent` is omitted (RFC 5652 Section 5.2) and the * verifier must supply the content externally. * * The content digest is derived from each signer's key (P-256/RSA-SHA256 → * SHA-256, P-384 → SHA-384, P-521 → SHA-512, Ed25519 → SHA-512 per RFC 8419). * * Returns a {@linkcode CreatePkcs7SignedDataResult}: DER, PEM, and base64 * forms on success, or a typed failure for caller-correctable input (no * signers, a signer source that is not exactly one certificate, a signer * certificate whose public key cannot verify the signer key's algorithm, or an * unsupported signer key). */ declare function createPkcs7SignedData(input: CreatePkcs7SignedDataInput): Promise; /** Parses a DER-encoded PKCS#7 cert bag, returning the contained certificates. */ declare function parsePkcs7CertBagDer(der: Uint8Array): ParsePkcs7CertBagResult; /** Parses a PEM-armored PKCS#7/CMS cert bag. Expects exactly one `PKCS7` or `CMS` PEM block. */ declare function parsePkcs7CertBagPem(pem: string): ParsePkcs7CertBagResult; /** Decodes a DER-encoded PKCS#7 ContentInfo expecting `signedData` content type. */ declare function parsePkcs7SignedDataDer(der: Uint8Array): ParsePkcs7SignedDataResult; /** Decodes a PEM-armored PKCS#7/CMS SignedData. Expects exactly one `PKCS7` or `CMS` PEM block. */ declare function parsePkcs7SignedDataPem(pem: string): ParsePkcs7SignedDataResult; /** * Verifies all signer signatures in a PKCS#7 SignedData structure. * * Accepts PEM text, raw DER, or an already-parsed {@linkcode ParsedPkcs7SignedData}. * For each signer, locates the matching certificate in the embedded set and * verifies the signature (including signed-attribute digest checks per RFC 5652 Section 5.4). * * For a detached SignedData (absent `eContent`), pass the externally-held * content via `options.content`; without it, verification fails with the * typed `detached_content_required` code. When the SignedData embeds its own * content, that embedded content is verified and `options.content` is ignored. * * @example * ```ts * import { verifyPkcs7SignedData } from 'micro509'; * * const result = await verifyPkcs7SignedData(pkcs7Pem); * if (result.ok) { * for (const { signerInfo, certificate } of result.signers) { * console.log(signerInfo.digestAlgorithmOid, certificate.subject); * } * } * * // Detached signature: supply the content externally * const detached = await verifyPkcs7SignedData(cmsBlob, { content: signedBytes }); * ``` */ declare function verifyPkcs7SignedData(input: string | Uint8Array | ParsedPkcs7SignedData, options?: VerifyPkcs7SignedDataOptions): Promise; //#endregion export { CreatePkcs7CertBagErrorCode, CreatePkcs7CertBagFailure, CreatePkcs7CertBagResult, CreatePkcs7SignedDataErrorCode, CreatePkcs7SignedDataFailure, CreatePkcs7SignedDataInput, CreatePkcs7SignedDataResult, ParsePkcs7CertBagResult, ParsePkcs7ErrorCode, ParsePkcs7Failure, ParsePkcs7SignedDataResult, ParsedCertificateChoice, ParsedPkcs7SignedData, ParsedPkcs7SignerInfo, ParsedPkcs7SignerInfoBase, ParsedSignerIdentifier, Pkcs7CertBagMaterial, Pkcs7CertificateSource, Pkcs7SignedDataMaterial, Pkcs7Signer, VerifiedPkcs7Signer, VerifyPkcs7SignedDataErrorCode, VerifyPkcs7SignedDataFailure, VerifyPkcs7SignedDataOptions, VerifyPkcs7SignedDataResult, createPkcs7CertBag, createPkcs7SignedData, parsePkcs7CertBagDer, parsePkcs7CertBagPem, parsePkcs7SignedDataDer, parsePkcs7SignedDataPem, verifyPkcs7SignedData }; //# sourceMappingURL=pkcs7.d.ts.map