@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
121 lines (117 loc) • 4.31 kB
JavaScript
import { TypedArrayEncoder } from "../../utils/TypedArrayEncoder.mjs";
import { Hasher } from "../../crypto/hashes/Hasher.mjs";
import "../../utils/index.mjs";
import { knownJwaFromCoseSignatureAlgorithm } from "../kms/cose/algorithm.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 { MdocError } from "./MdocError.mjs";
import { sha256 } from "@noble/hashes/sha2.js";
import { p256 } from "@noble/curves/nist.js";
import { CoseKey, coseKeyToJwk } from "@owf/mdoc";
import { hkdf } from "@noble/hashes/hkdf.js";
//#region src/modules/mdoc/MdocContext.ts
const getMdocContext = (agentContext, { now } = {}) => {
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, new Uint8Array(bytes).buffer));
},
random: (length) => {
return crypto.getRandomValues(new Uint8Array(length));
},
calculateEphemeralMacKey: async (input) => {
const { privateKey, publicKey, sessionTranscriptBytes } = input;
const hk1 = hkdf(sha256, p256.getSharedSecret(privateKey, publicKey, true).slice(1), Hasher.hash(sessionTranscriptBytes, "sha-256"), TypedArrayEncoder.fromUtf8String("EMacKey"), 32);
return CoseKey.fromJwk({
key_ops: ["sign", "verify"],
ext: true,
kty: "oct",
k: TypedArrayEncoder.toBase64Url(hk1),
alg: "HS256"
});
}
},
cose: {
mac0: {
sign: async (input) => {
if (!input.key.keyId) throw new MdocError("Missing required keyId on CoseKey for signing mdoc");
const { signature } = await kms.sign({
data: input.toBeAuthenticated,
algorithm: input.key.algorithm,
keyId: input.key.keyId
});
return signature;
},
verify: async (input) => {
const { mac0, key } = input;
const algorithm = knownJwaFromCoseSignatureAlgorithm(mac0.signatureAlgorithmName);
const { verified } = await kms.verify({
key: { publicJwk: key.jwk },
data: mac0.toBeAuthenticated,
algorithm,
signature: mac0.tag
});
return verified;
}
},
sign1: {
sign: async (input) => {
if (!input.key.keyId) throw new MdocError("Missing required keyId on CoseKey for signing mdoc");
const { signature } = await kms.sign({
data: input.toBeSigned,
algorithm: coseKeyToJwk.algorithm(input.algorithm),
keyId: input.key.keyId
});
return signature;
},
verify: async (input) => {
const { verified } = await kms.verify({
key: { publicJwk: input.key.jwk },
data: input.sign1.toBeSigned,
algorithm: input.sign1.signatureAlgorithmName,
signature: input.sign1.signature
});
return verified;
}
}
},
x509: {
getIssuerNameField: (input) => {
const { certificate, field } = input;
return X509Certificate.fromRawCertificate(certificate).getIssuerNameField(field);
},
getPublicKey: async (input) => {
const certificate = X509Certificate.fromRawCertificate(input.certificate);
return CoseKey.fromJwk(certificate.publicJwk.toJson());
},
verifyCertificateChain: 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,
verificationDate: input.now ?? now
});
},
getCertificateData: async (input) => {
const { certificate } = input;
const x509Certificate = X509Certificate.fromRawCertificate(certificate);
return {
...x509Certificate.data,
thumbprint: await x509Certificate.getThumbprintInHex(agentContext)
};
}
}
};
};
//#endregion
export { getMdocContext };
//# sourceMappingURL=MdocContext.mjs.map