{"version":3,"file":"extensions.mjs","names":["X509Name","AsnName"],"sources":["../../../../src/modules/x509/utils/extensions.ts"],"sourcesContent":["import { AsnConvert } from '@peculiar/asn1-schema'\nimport {\n  Name as AsnName,\n  BaseCRLNumber,\n  CertificateIssuer,\n  CRLNumber,\n  DistributionPoint,\n  DistributionPointName,\n  GeneralName,\n  IssuingDistributionPoint,\n  id_ce_certificateIssuer,\n  id_ce_cRLNumber,\n  id_ce_deltaCRLIndicator,\n  id_ce_issuingDistributionPoint,\n  Reason,\n} from '@peculiar/asn1-x509'\nimport {\n  AuthorityKeyIdentifierExtension,\n  BasicConstraintsExtension,\n  CRLDistributionPointsExtension,\n  ExtendedKeyUsageExtension,\n  Extension,\n  IssuerAlternativeNameExtension,\n  KeyUsagesExtension,\n  SubjectAlternativeNameExtension,\n  SubjectKeyIdentifierExtension,\n  Name as X509Name,\n} from '@peculiar/x509'\nimport { Hasher } from '../../../crypto/hashes/Hasher'\nimport { publicJwkToSpki } from '../../../crypto/webcrypto/utils'\nimport { TypedArrayEncoder } from '../../../utils'\nimport { PublicJwk } from '../../kms'\nimport type {\n  X509CertificateExtensionsOptions,\n  X509CertificateIssuerAndSubjectOptions,\n  X509CertificateRevocationListExtensionsOptions,\n} from '../X509ServiceOptions'\nimport { convertName } from './nameConversion'\n\n/**\n * X.509 extension OIDs defined in RFC 5280\n */\nexport enum X509ExtensionIdentifier {\n  /** Basic Constraints (RFC 5280 Section 4.2.1.9) */\n  BasicConstraints = '2.5.29.19',\n  /** Key Usage (RFC 5280 Section 4.2.1.3) */\n  KeyUsage = '2.5.29.15',\n  /** Extended Key Usage (RFC 5280 Section 4.2.1.12) */\n  ExtendedKeyUsage = '2.5.29.37',\n  /** Subject Alternative Name (RFC 5280 Section 4.2.1.6) */\n  SubjectAltName = '2.5.29.17',\n  /** Issuer Alternative Name (RFC 5280 Section 4.2.1.7) */\n  IssuerAltName = '2.5.29.18',\n  /** Subject Key Identifier (RFC 5280 Section 4.2.1.2) */\n  SubjectKeyIdentifier = '2.5.29.14',\n  /** Authority Key Identifier (RFC 5280 Section 4.2.1.1) */\n  AuthorityKeyIdentifier = '2.5.29.35',\n  /** CRL Distribution Points (RFC 5280 Section 4.2.1.13) */\n  CrlDistributionPoints = '2.5.29.31',\n  /** Name Constraints (RFC 5280 Section 4.2.1.10) */\n  NameConstraints = '2.5.29.30',\n  /** Policy Constraints (RFC 5280 Section 4.2.1.11) */\n  PolicyConstraints = '2.5.29.36',\n}\n\n/**\n * X.509 CRL extension OIDs defined in RFC 5280 Section 5.2.\n *\n * These are the extensions that may appear on a CRL itself. They are distinct from the per-entry\n * CRL extensions of RFC 5280 Section 5.3 (such as `reasonCode`, `invalidityDate` and\n * `certificateIssuer`), which are carried on individual revoked entries rather than the CRL.\n */\nexport enum X509CrlExtensionIdentifier {\n  /** Authority Key Identifier (RFC 5280 Section 5.2.1) */\n  AuthorityKeyIdentifier = '2.5.29.35',\n  /** Issuer Alternative Name (RFC 5280 Section 5.2.2) */\n  IssuerAltName = '2.5.29.18',\n  /** CRL Number (RFC 5280 Section 5.2.3) */\n  CrlNumber = '2.5.29.20',\n  /** Delta CRL Indicator (RFC 5280 Section 5.2.4) */\n  DeltaCrlIndicator = '2.5.29.27',\n  /** Issuing Distribution Point (RFC 5280 Section 5.2.5) */\n  IssuingDistributionPoint = '2.5.29.28',\n  /** Freshest CRL, a.k.a. Delta CRL Distribution Point (RFC 5280 Section 5.2.6) */\n  FreshestCrl = '2.5.29.46',\n  /** Authority Information Access (RFC 5280 Section 5.2.7) */\n  AuthorityInformationAccess = '1.3.6.1.5.5.7.1.1',\n}\n\nexport const createSubjectKeyIdentifierExtension = (\n  options: X509CertificateExtensionsOptions['subjectKeyIdentifier'],\n  additionalOptions: { publicJwk: PublicJwk }\n) => {\n  if (!options?.include) return\n\n  const spki = publicJwkToSpki(additionalOptions.publicJwk)\n  const hash = Hasher.hash(new Uint8Array(spki.subjectPublicKey), 'SHA-1')\n\n  return new SubjectKeyIdentifierExtension(TypedArrayEncoder.toHex(hash))\n}\n\nexport const createKeyUsagesExtension = (options: X509CertificateExtensionsOptions['keyUsage']) => {\n  if (!options) return\n\n  const flags = options.usages.reduce((prev, curr) => prev | curr, 0)\n\n  return new KeyUsagesExtension(flags, options.markAsCritical)\n}\n\nexport const createExtendedKeyUsagesExtension = (options: X509CertificateExtensionsOptions['extendedKeyUsage']) => {\n  if (!options) return\n\n  return new ExtendedKeyUsageExtension(options.usages, options.markAsCritical)\n}\n\nexport const createAuthorityKeyIdentifierExtension = (\n  options: X509CertificateExtensionsOptions['authorityKeyIdentifier'],\n  additionalOptions: { publicJwk: PublicJwk }\n) => {\n  if (!options) return\n\n  const spki = publicJwkToSpki(additionalOptions.publicJwk)\n  const hash = Hasher.hash(new Uint8Array(spki.subjectPublicKey), 'SHA-1')\n\n  return new AuthorityKeyIdentifierExtension(TypedArrayEncoder.toHex(hash), options.markAsCritical)\n}\n\nexport const createIssuerAlternativeNameExtension = (\n  options: X509CertificateExtensionsOptions['issuerAlternativeName']\n) => {\n  if (!options) return\n\n  return new IssuerAlternativeNameExtension(options.name, options.markAsCritical)\n}\n\nexport const createSubjectAlternativeNameExtension = (\n  options: X509CertificateExtensionsOptions['subjectAlternativeName']\n) => {\n  if (!options) return\n\n  return new SubjectAlternativeNameExtension(options.name, options.markAsCritical)\n}\n\nexport const createBasicConstraintsExtension = (options: X509CertificateExtensionsOptions['basicConstraints']) => {\n  if (!options) return\n\n  return new BasicConstraintsExtension(options.ca, options.pathLenConstraint, options.markAsCritical)\n}\n\nexport const createCrlDistributionPointsExtension = (\n  options: X509CertificateExtensionsOptions['crlDistributionPoints']\n) => {\n  if (!options) return\n\n  // Build a single distribution point whose `fullName` holds all URLs as alternate locations\n  // (mirrors). This mirrors how {@link X509Certificate.crlDistributionPoints} parses the\n  // extension (one distribution point with multiple URLs), so creation and parsing round-trip.\n  const distributionPoint = new DistributionPoint({\n    distributionPoint: new DistributionPointName({\n      fullName: options.urls.map((url) => new GeneralName({ uniformResourceIdentifier: url })),\n    }),\n  })\n\n  if (options.reasons && options.reasons.length > 0) {\n    // The ASN.1 BIT STRING uses bit `i` for revocation reason code `i` (e.g. keyCompromise = bit 1).\n    const reasonBits = options.reasons.reduce((mask, reason) => mask | (1 << reason), 0)\n    const reason = new Reason()\n    reason.fromNumber(reasonBits)\n    distributionPoint.reasons = reason\n  }\n\n  if (options.crlIssuer) {\n    distributionPoint.cRLIssuer = [new GeneralName({ uniformResourceIdentifier: options.crlIssuer })]\n  }\n\n  return new CRLDistributionPointsExtension([distributionPoint], options.markAsCritical)\n}\n\nexport const createCrlNumberExtension = (options: X509CertificateRevocationListExtensionsOptions['crlNumber']) => {\n  if (!options) return\n\n  // There is no high-level CRL Number extension in @peculiar/x509, so build it from the ASN.1 type.\n  const value = AsnConvert.serialize(new CRLNumber(options.value))\n\n  return new Extension(id_ce_cRLNumber, options.markAsCritical ?? false, value)\n}\n\nexport const createDeltaCrlIndicatorExtension = (\n  options: X509CertificateRevocationListExtensionsOptions['deltaCrlIndicator']\n) => {\n  if (!options) return\n\n  // There is no high-level Delta CRL Indicator extension in @peculiar/x509, so build it from the\n  // ASN.1 type. The value is the CRL Number of the base (complete) CRL this delta CRL is relative to.\n  const value = AsnConvert.serialize(new BaseCRLNumber(options.value))\n\n  // RFC 5280 §5.2.4: the delta CRL indicator extension MUST be critical.\n  return new Extension(id_ce_deltaCRLIndicator, options.markAsCritical ?? true, value)\n}\n\nexport const createIssuingDistributionPointExtension = (\n  options: X509CertificateRevocationListExtensionsOptions['issuingDistributionPoint']\n) => {\n  if (!options) return\n\n  const issuingDistributionPoint = new IssuingDistributionPoint({\n    onlyContainsUserCerts: options.onlyContainsUserCerts ?? false,\n    onlyContainsCACerts: options.onlyContainsCACerts ?? false,\n    indirectCRL: options.indirectCRL ?? false,\n    onlyContainsAttributeCerts: options.onlyContainsAttributeCerts ?? false,\n  })\n\n  if (options.fullName && options.fullName.length > 0) {\n    issuingDistributionPoint.distributionPoint = new DistributionPointName({\n      fullName: options.fullName.map((url) => new GeneralName({ uniformResourceIdentifier: url })),\n    })\n  }\n\n  if (options.onlySomeReasons && options.onlySomeReasons.length > 0) {\n    const reason = new Reason()\n    reason.fromNumber(options.onlySomeReasons.reduce((mask, value) => mask | (1 << value), 0))\n    issuingDistributionPoint.onlySomeReasons = reason\n  }\n\n  // RFC 5280 §5.2.5: the issuing distribution point extension MUST be critical.\n  return new Extension(\n    id_ce_issuingDistributionPoint,\n    options.markAsCritical ?? true,\n    AsnConvert.serialize(issuingDistributionPoint)\n  )\n}\n\n/**\n * Build the `certificateIssuer` CRL entry extension (RFC 5280 §5.3.3) used by indirect CRLs to\n * indicate the issuer of the revoked certificate. This extension is always critical.\n */\nexport const createCrlEntryCertificateIssuerExtension = (issuer: string | X509CertificateIssuerAndSubjectOptions) => {\n  const name = AsnConvert.parse(new X509Name(convertName(issuer)).toArrayBuffer(), AsnName)\n  const certificateIssuer = new CertificateIssuer([new GeneralName({ directoryName: name })])\n\n  return new Extension(id_ce_certificateIssuer, true, AsnConvert.serialize(certificateIssuer))\n}\n"],"mappings":"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"}