{"version":3,"file":"MdocContext.mjs","names":[],"sources":["../../../src/modules/mdoc/MdocContext.ts"],"sourcesContent":["import { p256 } from '@noble/curves/nist.js'\nimport { hkdf } from '@noble/hashes/hkdf.js'\nimport { sha256 } from '@noble/hashes/sha2.js'\nimport { CoseKey, coseKeyToJwk, type MdocContext } from '@owf/mdoc'\nimport type { AgentContext } from '../../agent'\nimport { CredoWebCrypto, Hasher } from '../../crypto'\nimport { TypedArrayEncoder } from '../../utils'\nimport {\n  KeyManagementApi,\n  type KmsJwkPublicAsymmetric,\n  type KnownJwaSignatureAlgorithm,\n  knownJwaFromCoseSignatureAlgorithm,\n} from '../kms'\nimport { X509Certificate, X509Service } from '../x509'\nimport { MdocError } from './MdocError'\n\nexport const getMdocContext = (agentContext: AgentContext, { now }: { now?: Date } = {}): MdocContext => {\n  const crypto = new CredoWebCrypto(agentContext)\n  const kms = agentContext.resolve(KeyManagementApi)\n\n  return {\n    crypto: {\n      digest: async (input) => {\n        const { bytes, digestAlgorithm } = input\n\n        return new Uint8Array(\n          crypto.digest(\n            digestAlgorithm,\n            // NOTE: extra Uint8Array wrapping is needed here, somehow if we use `bytes.buffer` directly\n            // it's not working. Maybe due to Uint8array length\n            new Uint8Array(bytes).buffer\n          )\n        )\n      },\n      random: (length) => {\n        return crypto.getRandomValues(new Uint8Array(length))\n      },\n      calculateEphemeralMacKey: async (input) => {\n        const { privateKey, publicKey, sessionTranscriptBytes } = input\n        const ikm = p256.getSharedSecret(privateKey, publicKey, true).slice(1)\n        const salt = Hasher.hash(sessionTranscriptBytes, 'sha-256')\n        const info = TypedArrayEncoder.fromUtf8String('EMacKey')\n        const hk1 = hkdf(sha256, ikm, salt, info, 32)\n\n        return CoseKey.fromJwk({\n          key_ops: ['sign', 'verify'],\n          ext: true,\n          kty: 'oct',\n          k: TypedArrayEncoder.toBase64Url(hk1),\n          alg: 'HS256',\n        })\n      },\n    },\n\n    cose: {\n      mac0: {\n        sign: async (input) => {\n          if (!input.key.keyId) {\n            throw new MdocError('Missing required keyId on CoseKey for signing mdoc')\n          }\n\n          const { signature } = await kms.sign({\n            data: input.toBeAuthenticated,\n            // FIXME: input needs to provide the algorithm\n            algorithm: input.key.algorithm as unknown as KnownJwaSignatureAlgorithm,\n            keyId: input.key.keyId,\n          })\n\n          return signature\n        },\n        verify: async (input) => {\n          const { mac0, key } = input\n\n          const algorithm = knownJwaFromCoseSignatureAlgorithm(mac0.signatureAlgorithmName)\n\n          const { verified } = await kms.verify({\n            key: {\n              publicJwk: key.jwk as KmsJwkPublicAsymmetric,\n            },\n            data: mac0.toBeAuthenticated,\n            algorithm,\n            signature: mac0.tag,\n          })\n\n          return verified\n        },\n      },\n      sign1: {\n        sign: async (input) => {\n          if (!input.key.keyId) {\n            throw new MdocError('Missing required keyId on CoseKey for signing mdoc')\n          }\n\n          const { signature } = await kms.sign({\n            data: input.toBeSigned,\n            algorithm: coseKeyToJwk.algorithm(input.algorithm),\n            keyId: input.key.keyId,\n          })\n\n          return signature\n        },\n        verify: async (input) => {\n          const { verified } = await kms.verify({\n            key: {\n              publicJwk: input.key.jwk as KmsJwkPublicAsymmetric,\n            },\n            data: input.sign1.toBeSigned,\n            algorithm: input.sign1.signatureAlgorithmName as KnownJwaSignatureAlgorithm,\n            signature: input.sign1.signature,\n          })\n\n          return verified\n        },\n      },\n    },\n\n    x509: {\n      getIssuerNameField: (input) => {\n        const { certificate, field } = input\n        const x509Certificate = X509Certificate.fromRawCertificate(certificate)\n        return x509Certificate.getIssuerNameField(field)\n      },\n      getPublicKey: async (input) => {\n        const certificate = X509Certificate.fromRawCertificate(input.certificate)\n        return CoseKey.fromJwk(certificate.publicJwk.toJson())\n      },\n      verifyCertificateChain: async (input) => {\n        const certificateChain = input.x5chain.map((cert) => X509Certificate.fromRawCertificate(cert).toString('pem'))\n        const trustedCertificates = input.trustedCertificates.map((cert) =>\n          X509Certificate.fromRawCertificate(cert).toString('pem')\n        ) as [string, ...string[]]\n\n        await X509Service.validateCertificateChain(agentContext, {\n          certificateChain,\n          trustedCertificates,\n          verificationDate: input.now ?? now,\n        })\n      },\n      getCertificateData: async (input) => {\n        const { certificate } = input\n        const x509Certificate = X509Certificate.fromRawCertificate(certificate)\n        return {\n          ...x509Certificate.data,\n          thumbprint: await x509Certificate.getThumbprintInHex(agentContext),\n        }\n      },\n    },\n  } satisfies MdocContext\n}\n"],"mappings":"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"}