import { type TArg, type TRet } from '@noble/hashes/utils.js'; import * as P from 'micro-packed'; import { ASN1, BER } from './asn1.ts'; import { RSAPrivateKey as DERRSAPrivateKey, type PKCS8Key as DERPKCS8Key } from './convert.ts'; /** Supported certificate/key curves. */ export type Curve = 'P-256' | 'P-384' | 'P-521' | 'brainpoolP256r1' | 'brainpoolP384r1' | 'brainpoolP512r1'; /** Supported signing or key-agreement curve name. */ export type CertCurve = Curve | string; /** Parsed PEM block with decoded DER bytes. */ export type PemBlock = { /** PEM block tag between `BEGIN` and `END`. */ tag: string; /** Base64 payload exactly as it appeared in the PEM block. */ b64: string; /** Decoded DER bytes for the PEM payload. */ der: Uint8Array; }; /** Parsed PKCS#8 attribute entry. */ export type Pkcs8Attr = { /** Attribute OID. */ oid: string; /** Raw ASN.1 values carried by the attribute. */ values: Uint8Array[]; }; type RSAPrivateKey = P.UnwrapCoder; type StrictBytes = P.UnwrapCoder; type ASN1StringOrRaw = P.UnwrapCoder; type BERDoc = ReturnType; type BEROpts = { allowBER?: boolean; }; type TLVNode = P.UnwrapCoder; /** Decoded X.509 certificate. */ export type Cert = P.UnwrapCoder; type KeyBase = { pem: string; der: Uint8Array; attributes?: Pkcs8Attr[]; }; /** Parsed private-key PEM/DER bundle. */ export type PrivateKey = KeyBase & { key: DERPKCS8Key; rsa?: RSAPrivateKey; }; /** Leaf certificate, private key, and optional chain used for signing. */ export type SigningPem = { /** Leaf certificate used as the signer. */ leaf: Cert; /** Private key matching the leaf certificate. */ key: PrivateKey; /** Optional issuer chain sent alongside the leaf. */ chain: Cert[]; }; /** CMS verification options. */ export type CmsVerifyOpts = { /** Validation time in UNIX milliseconds. */ time?: number; /** Allow BER normalization before decoding. */ allowBER?: boolean; /** * Whether to verify CMS and certificate signatures for supported algorithms. * When `false`, structure, path, and attribute validation still runs. */ checkSignatures?: boolean; /** * Permit signature verification without a path to a supplied trust anchor. * The result then reports `trusted: false`. Defaults to `false`. */ allowUntrusted?: boolean; /** Intended verification purpose such as S/MIME or code signing. */ purpose?: 'any' | 'smime' | 'codeSigning'; /** Signer/path certificates; successful normal verification must terminate at one of them. */ chain?: (string | Uint8Array | Cert)[]; }; /** Result of CMS verification. */ export type CmsVerify = { /** Signature algorithm OID from the CMS SignerInfo. */ signatureOid: string; /** Parsed signer certificate. */ signer: Cert; /** Whether signed attributes were present and validated. */ signedAttrs: boolean; /** Parsed certificate path from signer toward issuer or root candidates. */ chain: Cert[]; /** Whether the verified path terminates at a certificate supplied in `opts.chain`. */ trusted: boolean; }; /** Detached CMS payload and signature pair. */ export type CmsDetached = { /** Original detached content bytes. */ content: Uint8Array; /** Detached CMS SignedData blob. */ signature: Uint8Array; /** Certificates bundled with the signature. */ certs: Cert[]; }; /** CMS signing options. */ export type CmsSignOpts = BEROpts & { createdTs?: number; extraEntropy?: boolean | Uint8Array; smimeCapabilities?: string[]; messageDigest?: Uint8Array; digestAlgorithm?: string; digestAlgorithmParams?: 'absent' | 'null'; signatureAlgorithm?: string; }; /** Decoded certificate extension data. */ export type CertExt = { /** Extension OID. */ oid: string; /** Whether the extension is marked critical. */ critical: boolean; /** Subject Key Identifier extension. */ ski?: Uint8Array; /** Basic Constraints extension. */ basic?: { ca?: boolean; pathLen?: bigint; }; /** Key Usage extension bit string. */ keyUsage?: { unused: number; bytes: Uint8Array; }; /** Extended Key Usage extension. */ eku?: { list: string[]; }; /** Subject Alternative Name extension. */ san?: { list: CertGeneralName[]; }; /** Authority Key Identifier extension. */ aki?: { keyIdentifier?: Uint8Array; authorityCertIssuer?: { list: CertGeneralName[]; }; authorityCertSerialNumber?: bigint; }; /** Authority Information Access extension. */ aia?: { list: { method: string; location: CertGeneralName; }[]; }; /** Proxy Certificate Information extension. */ proxyCertInfo?: { pathLen?: bigint; policy: { language: string; policy?: string; }; }; /** TLS Feature extension. */ tlsFeature?: { list: bigint[]; }; /** Signed Certificate Timestamps extension. */ sct?: { version: number; logID: Uint8Array; timestamp: bigint; extensions: string; hash: number; signatureAlgorithm: number; signature: Uint8Array; }[]; /** CRL Distribution Points extension. */ crlDistributionPoints?: { list: { distributionPoint?: CertDistributionPointName; reasons?: { unused: number; bytes: Uint8Array; }; cRLIssuer?: { list: CertGeneralName[]; }; }[]; }; /** Certificate Policies extension. */ policies?: { list: { policy: string; qualifiers?: { list: CertPolicyQualifier[]; }; }[]; }; /** Name Constraints extension. */ nameConstraints?: { permitted?: { list: CertGeneralSubtree[]; }; excluded?: { list: CertGeneralSubtree[]; }; }; /** Subject Directory Attributes extension. */ subjectDirectoryAttributes?: { list: { type: string; values: CertAny[]; }[]; }; /** Private Key Usage Period extension. */ privateKeyUsagePeriod?: { notBefore?: string; notAfter?: string; }; /** Issuer Alternative Name extension. */ issuerAltName?: { list: CertGeneralName[]; }; /** Issuing Distribution Point extension. */ issuingDistributionPoint?: { distributionPoint?: CertDistributionPointName; onlyContainsUserCerts?: boolean; onlyContainsCACerts?: boolean; onlySomeReasons?: { unused: number; bytes: Uint8Array; }; indirectCRL?: boolean; onlyContainsAttributeCerts?: boolean; }; /** Certificate Issuer extension. */ certificateIssuer?: { list: CertGeneralName[]; }; /** Policy Mappings extension. */ policyMappings?: { list: { issuerDomainPolicy: string; subjectDomainPolicy: string; }[]; }; /** Freshest CRL extension. */ freshestCRL?: { list: { distributionPoint?: CertDistributionPointName; reasons?: { unused: number; bytes: Uint8Array; }; cRLIssuer?: { list: CertGeneralName[]; }; }[]; }; /** Policy Constraints extension. */ policyConstraints?: { requireExplicitPolicy?: bigint; inhibitPolicyMapping?: bigint; }; /** Inhibit Any Policy extension. */ inhibitAnyPolicy?: bigint; /** QC Statements extension. */ qcStatements?: { list: { statementId: string; statementInfo: CertAny | undefined; }[]; }; /** Subject Information Access extension. */ subjectInfoAccess?: { list: { method: string; location: CertGeneralName; }[]; }; /** Microsoft certificate type extension. */ msCertType?: CertAny; }; /** Parsed GeneralName value. */ export type CertGeneralName = { TAG: 'otherName'; data: { type: string; value: Uint8Array; }; } | { TAG: 'rfc822Name'; data: string; } | { TAG: 'dNSName'; data: string; } | { TAG: 'x400Address'; data: Uint8Array; } | { TAG: 'directoryName'; data: NameCodec; } | { TAG: 'ediPartyName'; data: Uint8Array; } | { TAG: 'uniformResourceIdentifier'; data: string; } | { TAG: 'iPAddress'; data: string; } | { TAG: 'registeredID'; data: string; }; /** Parsed CRL distribution-point name. */ export type CertDistributionPointName = { TAG: 'fullName'; data: { list: CertGeneralName[]; }; } | { TAG: 'nameRelativeToCRLIssuer'; data: Array<{ oid: string; value: ASN1StringOrRaw; }>; }; /** Parsed reason flags from CRL-related extensions. */ export type CertReasonFlags = { /** End-entity private key was compromised. */ keyCompromise: boolean; /** CA private key was compromised. */ cACompromise: boolean; /** Subject affiliation changed. */ affiliationChanged: boolean; /** Certificate was superseded. */ superseded: boolean; /** Subject ceased operation. */ cessationOfOperation: boolean; /** Certificate was placed on hold. */ certificateHold: boolean; /** Privileges were withdrawn. */ privilegeWithdrawn: boolean; /** Attribute authority key was compromised. */ aACompromise: boolean; }; /** Parsed GeneralSubtree value. */ export type CertGeneralSubtree = { /** Base GeneralName covered by the subtree. */ base: CertGeneralName; /** Minimum subtree depth, when explicitly present. */ minimum?: bigint; /** Maximum subtree depth, when explicitly present. */ maximum?: bigint; }; /** Parsed certificate-policy qualifier. */ export type CertPolicyQualifier = { TAG: 'cps'; data: string; } | { TAG: 'userNotice'; data: { noticeRef?: { organization: CertText; numbers: (number | bigint)[]; }; explicitText?: CertText; }; } | { TAG: 'unknown'; data: { oid: string; value: TLVNode; }; }; /** Decoded text value from certificate fields. */ export type CertText = { /** Underlying ASN.1 string tag used by the source field. */ tag: 'utf8' | 'ia5' | 'visible' | 'bmp'; /** Decoded text content. */ text: string; }; /** Best-effort decoded arbitrary ASN.1 value. */ export type CertAny = P.UnwrapCoder; /** * Extracts all PEM blocks from a text blob. * @param text - Text containing one or more PEM blocks. * @returns Parsed PEM blocks with decoded DER bytes. * @example * Extract all PEM blocks from a text blob. * ```ts * import { pemBlocks } from 'micro-key-producer/x509.js'; * pemBlocks(`-----BEGIN DATA----- * AA== * -----END DATA-----`); * ``` */ export declare const pemBlocks: (text: string) => TRet; type EdKind = 'Ed25519' | 'Ed448'; declare const X509Time: { decode: (der: TArg) => number; encode: (ts: number) => TRet; }; type NameCodec = { rdns: Array>; }; type ValidityCodec = { notBefore: P.UnwrapCoder; notAfter: P.UnwrapCoder; }; type ExtCodec = { oid: string; rest: StrictBytes; }; type AlgorithmIdentifierCodec = P.UnwrapCoder; type TBSCertificateCodec = { version: bigint | undefined; serial: bigint; signature: AlgorithmIdentifierCodec; issuer: NameCodec; validity: ValidityCodec; subject: NameCodec; spki: { algorithm: AlgorithmIdentifierCodec; publicKey: StrictBytes; }; issuerUniqueID: P.UnwrapCoder | undefined; subjectUniqueID: P.UnwrapCoder | undefined; extensions: { list: ExtCodec[]; } | undefined; }; type CertificateCodec = { tbs: TBSCertificateCodec; sigAlg: AlgorithmIdentifierCodec; sig: StrictBytes; }; declare const X509C: { Name: P.CoderType; TBSCertificate: P.CoderType; Certificate: P.CoderType; }; type AttributeCodec = { oid: string; values: StrictBytes[]; }; type SignerIdentifierCodec = { TAG: 'issuerSerial'; data: { issuer: NameCodec; serial: bigint; }; } | { TAG: 'subjectKeyIdentifier'; data: StrictBytes; }; type SignerInfoCodec = { version: bigint; sid: SignerIdentifierCodec; digestAlg: AlgorithmIdentifierCodec; signedAttrs: AttributeCodec[] | undefined; signatureAlg: AlgorithmIdentifierCodec; signature: StrictBytes; unsignedAttrs: AttributeCodec[] | undefined; }; type SignedDataCodec = { version: bigint; digestAlgorithms: AlgorithmIdentifierCodec[]; encapContentInfo: { eContentType: string; eContent: StrictBytes | undefined; }; certificates: CMSCertificateChoiceCodec[] | undefined; crls: CMSRevocationInfoChoiceCodec[] | undefined; signerInfos: SignerInfoCodec[]; }; type ContentInfoCodec = { contentType: string; content: StrictBytes; }; type CMSCertificateChoiceCodec = { TAG: 'certificate'; data: P.UnwrapCoder; } | { TAG: 'extendedCertificate'; data: StrictBytes; } | { TAG: 'v1AttrCert'; data: StrictBytes; } | { TAG: 'v2AttrCert'; data: StrictBytes; } | { TAG: 'other'; data: StrictBytes; }; type CMSRevocationInfoChoiceCodec = { TAG: 'crl'; data: { tbsCertList: StrictBytes; signatureAlgorithm: AlgorithmIdentifierCodec; signatureValue: StrictBytes; }; } | { TAG: 'other'; data: { format: string; info: StrictBytes; }; }; declare const CMSCertificateChoices: P.CoderType; declare const CMSRevocationInfoChoice: P.CoderType; declare const CMSSignedData: P.CoderType; declare const CMSX: { AlgorithmIdentifier: typeof ASN1.AlgorithmIdentifier; Attribute: P.CoderType; SignerInfo: P.CoderType; SignedData: P.CoderType; ContentInfo: P.CoderType; }; /** * Low-level X.509 coders used by the higher-level APIs. * @example * Use the low-level coders when you need to encode or decode individual X.509 structures. * ```ts * import { CERTUtils } from 'micro-key-producer/x509.js'; * CERTUtils.Name.encode({ * rdns: [[{ oid: 'commonName', value: { TAG: 'utf8', data: 'example.com' } }]], * }); * ``` */ export declare const CERTUtils: { Name: typeof X509C.Name; TBSCertificate: typeof X509C.TBSCertificate; Certificate: typeof X509C.Certificate; }; declare const IPv4: P.CoderType; declare const IPv6: P.CoderType; type X509Api = { decode: (der: Uint8Array, opts?: BEROpts) => Cert; encode: (cert: Cert) => Uint8Array; extensions: (cert: Cert) => CertExt[]; }; declare const X509Api: X509Api; /** X.509 certificate DER helpers. */ export declare const X509: TRet; type CMSApi = { decode: (der: Uint8Array, opts?: BEROpts) => P.UnwrapCoder & { ber?: BERDoc; }; encode: (contentInfo: P.UnwrapCoder & { ber?: BERDoc; }) => Uint8Array; contentType: (der: Uint8Array, opts?: BEROpts) => string; signed: (der: Uint8Array, opts?: BEROpts) => P.UnwrapCoder; verify: (der: Uint8Array, opts?: CmsVerifyOpts) => CmsVerify; detach: (der: Uint8Array, opts?: BEROpts) => CmsDetached; attach: (signature: Uint8Array, content: Uint8Array, opts?: BEROpts) => Uint8Array; verifyDetached: (signature: Uint8Array, content: Uint8Array, opts?: CmsVerifyOpts) => CmsVerify; sign: (content: string | Uint8Array, signingCertPem: string, privateKeyPem: string, chainPem?: string, opts?: CmsSignOpts) => Uint8Array; signDetached: (content: string | Uint8Array, signingCertPem: string, privateKeyPem: string, chainPem?: string, opts?: CmsSignOpts) => Uint8Array; compact: { sign: (content: string | Uint8Array, signingCertPem: string, privateKeyPem: string, opts?: Pick) => Uint8Array; build: (content: string | Uint8Array, signature: Uint8Array, signingCertPem: string, chainPem?: string, opts?: CmsCompactBuildOpts) => Uint8Array; }; }; type CmsCompactBuildOpts = Pick; /** CMS SignedData helpers for X.509 certificates. */ export declare const CMS: TRet; export declare const __TEST: { IPv4: typeof IPv4; IPv6: typeof IPv6; X509Time: typeof X509Time; CMSCertificateChoices: typeof CMSCertificateChoices; CMSRevocationInfoChoice: typeof CMSRevocationInfoChoice; CMSSignedData: typeof CMSSignedData; keyCurve: (privateKeyPem: string) => CertCurve | EdKind; }; export {};