

import { Hasher } from "../../crypto/hashes/Hasher.mjs";
import { Buffer } from "../../utils/buffer.mjs";
import { TypedArrayEncoder } from "../../utils/TypedArrayEncoder.mjs";
import "../../utils/index.mjs";
import { PublicJwk } from "../kms/jwk/PublicJwk.mjs";
import { KeyManagementApi } from "../kms/KeyManagementApi.mjs";
import "../kms/index.mjs";
import { CredoWebCrypto } from "../../crypto/webcrypto/CredoWebCrypto.mjs";
import { X509Certificate } from "../x509/X509Certificate.mjs";
import { X509Service } from "../x509/X509Service.mjs";
import "../x509/index.mjs";
import "../../crypto/index.mjs";
import { sha256 } from "@noble/hashes/sha2";
import { p256 } from "@noble/curves/p256";
import { hkdf } from "@noble/hashes/hkdf";

//#region src/modules/mdoc/MdocContext.ts
const getMdocContext = (agentContext) => {
	const crypto = new CredoWebCrypto(agentContext);
	const kms = agentContext.resolve(KeyManagementApi);
	return {
		crypto: {
			digest: async (input) => {
				const { bytes, digestAlgorithm } = input;
				return new Uint8Array(crypto.digest(digestAlgorithm, bytes));
			},
			random: (length) => {
				return crypto.getRandomValues(new Uint8Array(length));
			},
			calculateEphemeralMacKeyJwk: async (input) => {
				const { privateKey, publicKey, sessionTranscriptBytes } = input;
				const hk1 = hkdf(sha256, p256.getSharedSecret(TypedArrayEncoder.toHex(privateKey), TypedArrayEncoder.toHex(publicKey), true).slice(1), Hasher.hash(sessionTranscriptBytes, "sha-256"), Buffer.from("EMacKey", "utf-8"), 32);
				return {
					key_ops: ["sign", "verify"],
					ext: true,
					kty: "oct",
					k: TypedArrayEncoder.toBase64URL(hk1),
					alg: "HS256"
				};
			}
		},
		cose: {
			mac0: {
				sign: async (input) => {
					const { jwk, mac0 } = input;
					const { data } = mac0.getRawSigningData();
					const publicJwk = PublicJwk.fromUnknown(jwk);
					const algorithm = mac0.algName ?? publicJwk.signatureAlgorithm;
					const { signature } = await kms.sign({
						data,
						algorithm,
						keyId: publicJwk.keyId
					});
					return signature;
				},
				verify: async (input) => {
					const { mac0, jwk, options } = input;
					const { data, signature } = mac0.getRawVerificationData(options);
					const publicJwk = PublicJwk.fromUnknown(jwk);
					const algorithm = mac0.algName ?? publicJwk.signatureAlgorithm;
					const { verified } = await kms.verify({
						key: { publicJwk: jwk },
						data,
						algorithm,
						signature
					});
					return verified;
				}
			},
			sign1: {
				sign: async (input) => {
					const { jwk, sign1 } = input;
					const { data } = sign1.getRawSigningData();
					const publicJwk = PublicJwk.fromUnknown(jwk);
					const algorithm = sign1.algName ?? publicJwk.signatureAlgorithm;
					const { signature } = await kms.sign({
						data,
						algorithm,
						keyId: publicJwk.keyId
					});
					return signature;
				},
				verify: async (input) => {
					const { sign1, jwk, options } = input;
					const { data, signature } = sign1.getRawVerificationData(options);
					const publicJwk = PublicJwk.fromUnknown(jwk);
					const algorithm = sign1.algName ?? publicJwk.signatureAlgorithm;
					const { verified } = await kms.verify({
						key: { publicJwk: jwk },
						data,
						algorithm,
						signature
					});
					return verified;
				}
			}
		},
		x509: {
			getIssuerNameField: (input) => {
				const { certificate, field } = input;
				return X509Certificate.fromRawCertificate(certificate).getIssuerNameField(field);
			},
			getPublicKey: async (input) => {
				return X509Certificate.fromRawCertificate(input.certificate).publicJwk.toJson();
			},
			validateCertificateChain: async (input) => {
				const certificateChain = input.x5chain.map((cert) => X509Certificate.fromRawCertificate(cert).toString("pem"));
				const trustedCertificates = input.trustedCertificates.map((cert) => X509Certificate.fromRawCertificate(cert).toString("pem"));
				await X509Service.validateCertificateChain(agentContext, {
					certificateChain,
					trustedCertificates
				});
			},
			getCertificateData: async (input) => {
				const { certificate } = input;
				const x509Certificate = X509Certificate.fromRawCertificate(certificate);
				return {
					...x509Certificate.data,
					thumbprint: await x509Certificate.getThumprintInHex(agentContext)
				};
			}
		}
	};
};

//#endregion
export { getMdocContext };
//# sourceMappingURL=MdocContext.mjs.map