@credo-ts/core
Version:
<p align="center"> <br /> <img alt="Credo Logo" src="https://github.com/openwallet-foundation/credo-ts/blob/c7886cb8377ceb8ee4efe8d264211e561a75072d/images/credo-logo.png" height="250px" /> </p> <h1 align="center"><b>Credo - Core</b></h1
1 lines • 7.56 kB
Source Map (JSON)
{"version":3,"file":"mdocUtil.mjs","names":[],"sources":["../../../src/modules/mdoc/mdocUtil.ts"],"sourcesContent":["import { DeviceNamespaces, DeviceSignedItems } from '@owf/mdoc'\nimport type { PublicJwk } from '../kms'\nimport { convertLegacyTrustedCertificates } from '../x509/utils/convertLegacyTrustedCertificates'\nimport { X509Certificate } from '../x509/X509Certificate'\nimport type { X509VerificationTrustedCertificates } from '../x509/X509ModuleConfig'\nimport { MdocError } from './MdocError'\nimport type { MdocNameSpaces } from './MdocOptions'\nimport { isMdocSupportedSignatureAlgorithm, mdocSupportedSignatureAlgorithms } from './mdocSupportedAlgs'\n\n/**\n * mdoc COSE structures require an explicit `alg`, but credo public JWKs generally don't carry one.\n */\nexport function getMdocSignatureAlgForJwk(publicJwk: PublicJwk) {\n const signatureAlgorithm = publicJwk.supportedSignatureAlgorithms.find(isMdocSupportedSignatureAlgorithm)\n if (!signatureAlgorithm) {\n throw new MdocError(\n `No supported signature algorithm found for jwk ${\n publicJwk.jwkTypeHumanDescription\n }. Key supports algs ${publicJwk.supportedSignatureAlgorithms.join(\n ', '\n )}. mdoc supports algs ${mdocSupportedSignatureAlgorithms.join(', ')}`\n )\n }\n\n return signatureAlgorithm\n}\n\n/**\n * The JSON representation of a public JWK, with `alg` filled in as the mdoc COSE structures require\n * it. The `kid` (needed to resolve the key for signing) is taken from the jwk as-is; it's up to the\n * caller to make sure the key id is set.\n */\nexport function mdocSigningJwk(publicJwk: PublicJwk) {\n const jwk = publicJwk.toJson()\n\n return {\n ...jwk,\n alg: jwk.alg ?? getMdocSignatureAlgForJwk(publicJwk),\n }\n}\n\nexport interface MdocTrustedCertificate {\n issuance: string[]\n status: string[]\n hasDedicatedStatusCertificates: boolean\n}\n\n/**\n * Falls back to the `issuance` certs when no `status` certs are configured (`status: undefined`); an\n * explicit `status: []` is passed through. {@link assertMdocStatusListChainsMatchIssuanceChain} then\n * keeps the fallback from widening the trust set.\n */\nexport function convertMdocTrustedCertificates(\n trustedCertificates: string[] | X509VerificationTrustedCertificates[]\n): MdocTrustedCertificate[] {\n return convertLegacyTrustedCertificates(trustedCertificates).map(({ issuance, status }) => ({\n issuance,\n status: status ?? issuance,\n hasDedicatedStatusCertificates: status !== undefined,\n }))\n}\n\n/**\n * Maps the converted trusted certificates to the raw representation the `@owf/mdoc` library expects.\n */\nexport function mdocTrustedCertificatesToRaw(trustedCertificates: MdocTrustedCertificate[]) {\n return trustedCertificates.map(({ issuance, status }) => ({\n issuance: issuance.map((cert) => X509Certificate.fromEncodedCertificate(cert).rawCertificate),\n status: status.map((cert) => X509Certificate.fromEncodedCertificate(cert).rawCertificate),\n }))\n}\n\n/**\n * Without dedicated status certs, requires the status/identifier list chains to equal the issuance\n * chain, so the fallback can't accept a list signed by a different chain under the same trust anchor.\n */\nexport function assertMdocStatusListChainsMatchIssuanceChain(\n trustedCertificates: MdocTrustedCertificate[],\n chains: {\n trustedIssuanceChain: Uint8Array[]\n trustedStatusListChain?: Uint8Array[]\n trustedIdentifierListChain?: Uint8Array[]\n }\n) {\n const issuanceChain = chains.trustedIssuanceChain.map((cert) => X509Certificate.fromRawCertificate(cert))\n const issuanceTrustAnchor = issuanceChain[issuanceChain.length - 1]\n\n const matchedTrustedCertificate = trustedCertificates.find(({ issuance }) =>\n issuance.some((cert) => X509Certificate.fromEncodedCertificate(cert).equal(issuanceTrustAnchor))\n )\n\n // With dedicated status certs the library already validated the lists against them.\n if (matchedTrustedCertificate?.hasDedicatedStatusCertificates) return\n\n const chainMatchesIssuanceChain = (chain: Uint8Array[]) => {\n const resolvedChain = chain.map((cert) => X509Certificate.fromRawCertificate(cert))\n return (\n resolvedChain.length === issuanceChain.length && resolvedChain.every((cert, i) => cert.equal(issuanceChain[i]))\n )\n }\n\n if (chains.trustedIdentifierListChain && !chainMatchesIssuanceChain(chains.trustedIdentifierListChain)) {\n throw new MdocError(\n 'Trusted identifier list chain does not match the trusted issuance chain, and no trusted status certificates were provided for the trusted issuance certificate'\n )\n }\n\n if (chains.trustedStatusListChain && !chainMatchesIssuanceChain(chains.trustedStatusListChain)) {\n throw new MdocError(\n 'Trusted status list chain does not match the trusted issuance chain, and no trusted status certificates were provided for the trusted issuance certificate'\n )\n }\n}\n\nexport function nameSpacesRecordToMap<\n NamespaceValue,\n NameSpaces extends Record<string, Record<string, NamespaceValue>>,\n>(nameSpaces: NameSpaces): Map<string, Map<string, NamespaceValue>> {\n return new Map(Object.entries(nameSpaces).map(([key, value]) => [key, new Map(Object.entries(value))] as const))\n}\n\nexport function nameSpacesRecordToDeviceNamespaces(nameSpaces: MdocNameSpaces) {\n return DeviceNamespaces.create({\n deviceNamespaces: new Map(\n Array.from(nameSpacesRecordToMap(nameSpaces), ([nameSpace, items]) => [\n nameSpace,\n DeviceSignedItems.create({ deviceSignedItems: items }),\n ])\n ),\n })\n}\n\nexport function namespacesMapToRecord<NamespaceValue, NameSpaces extends Map<string, Map<string, NamespaceValue>>>(\n nameSpaces: NameSpaces\n): Record<string, Record<string, NamespaceValue>> {\n return Object.fromEntries(\n Array.from(nameSpaces.entries()).map(([key, value]) => [key, Object.fromEntries(Array.from(value.entries()))])\n )\n}\n"],"mappings":";;;;;;;;;AAYA,SAAgB,0BAA0B,WAAsB;CAC9D,MAAM,qBAAqB,UAAU,6BAA6B,KAAK,iCAAiC;CACxG,IAAI,CAAC,oBACH,MAAM,IAAI,UACR,kDACE,UAAU,wBACX,sBAAsB,UAAU,6BAA6B,KAC5D,IACF,EAAE,uBAAuB,iCAAiC,KAAK,IAAI,GACrE;CAGF,OAAO;AACT;;;;;;AAOA,SAAgB,eAAe,WAAsB;CACnD,MAAM,MAAM,UAAU,OAAO;CAE7B,OAAO;EACL,GAAG;EACH,KAAK,IAAI,OAAO,0BAA0B,SAAS;CACrD;AACF;;;;;;AAaA,SAAgB,+BACd,qBAC0B;CAC1B,OAAO,iCAAiC,mBAAmB,CAAC,CAAC,KAAK,EAAE,UAAU,cAAc;EAC1F;EACA,QAAQ,UAAU;EAClB,gCAAgC,WAAW,KAAA;CAC7C,EAAE;AACJ;;;;AAKA,SAAgB,6BAA6B,qBAA+C;CAC1F,OAAO,oBAAoB,KAAK,EAAE,UAAU,cAAc;EACxD,UAAU,SAAS,KAAK,SAAS,gBAAgB,uBAAuB,IAAI,CAAC,CAAC,cAAc;EAC5F,QAAQ,OAAO,KAAK,SAAS,gBAAgB,uBAAuB,IAAI,CAAC,CAAC,cAAc;CAC1F,EAAE;AACJ;;;;;AAMA,SAAgB,6CACd,qBACA,QAKA;CACA,MAAM,gBAAgB,OAAO,qBAAqB,KAAK,SAAS,gBAAgB,mBAAmB,IAAI,CAAC;CACxG,MAAM,sBAAsB,cAAc,cAAc,SAAS;CAOjE,IALkC,oBAAoB,MAAM,EAAE,eAC5D,SAAS,MAAM,SAAS,gBAAgB,uBAAuB,IAAI,CAAC,CAAC,MAAM,mBAAmB,CAAC,CAIrE,CAAC,EAAE,gCAAgC;CAE/D,MAAM,6BAA6B,UAAwB;EACzD,MAAM,gBAAgB,MAAM,KAAK,SAAS,gBAAgB,mBAAmB,IAAI,CAAC;EAClF,OACE,cAAc,WAAW,cAAc,UAAU,cAAc,OAAO,MAAM,MAAM,KAAK,MAAM,cAAc,EAAE,CAAC;CAElH;CAEA,IAAI,OAAO,8BAA8B,CAAC,0BAA0B,OAAO,0BAA0B,GACnG,MAAM,IAAI,UACR,gKACF;CAGF,IAAI,OAAO,0BAA0B,CAAC,0BAA0B,OAAO,sBAAsB,GAC3F,MAAM,IAAI,UACR,4JACF;AAEJ;AAEA,SAAgB,sBAGd,YAAkE;CAClE,OAAO,IAAI,IAAI,OAAO,QAAQ,UAAU,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CAAC,KAAK,IAAI,IAAI,OAAO,QAAQ,KAAK,CAAC,CAAC,CAAU,CAAC;AACjH;AAEA,SAAgB,mCAAmC,YAA4B;CAC7E,OAAO,iBAAiB,OAAO,EAC7B,kBAAkB,IAAI,IACpB,MAAM,KAAK,sBAAsB,UAAU,IAAI,CAAC,WAAW,WAAW,CACpE,WACA,kBAAkB,OAAO,EAAE,mBAAmB,MAAM,CAAC,CACvD,CAAC,CACH,EACF,CAAC;AACH"}