import { decodeAsn1, isConstructed, UNIVERSAL_TAGS } from "../asn1/index.js"; import { decodeOid } from "../asn1/oid.js"; import { X509_CODES, X509Error } from "../errors/error-codes.js"; import type { ExtendedKeyUsage } from "./extension.types.js"; export const OID_EXTENDED_KEY_USAGE = "2.5.29.37"; export const EKU_OID_TO_NAME: Readonly> = { "2.5.29.37.0": "anyExtendedKeyUsage", "1.3.6.1.5.5.7.3.1": "serverAuth", "1.3.6.1.5.5.7.3.2": "clientAuth", "1.3.6.1.5.5.7.3.3": "codeSigning", "1.3.6.1.5.5.7.3.4": "emailProtection", "1.3.6.1.5.5.7.3.8": "timeStamping", "1.3.6.1.5.5.7.3.9": "OCSPSigning", }; function bad(reason: string): X509Error { return new X509Error( X509_CODES.EXTENSION_MALFORMED, "error.x509.eku-malformed", { context: { reason } } ); } export function decodeExtendedKeyUsage(value: Uint8Array): ExtendedKeyUsage { const node = decodeAsn1(value); if ( !isConstructed(node) || node.tag.tagNumber !== UNIVERSAL_TAGS.SEQUENCE ) { throw bad("not-sequence"); } const purposes: string[] = node.children.map((c) => { if ( isConstructed(c) || c.tag.tagNumber !== UNIVERSAL_TAGS.OBJECT_IDENTIFIER ) { throw bad("child-not-oid"); } const oid = decodeOid(c.content); return EKU_OID_TO_NAME[oid] ?? oid; }); return { purposes }; }