@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
142 lines (138 loc) • 5.96 kB
JavaScript
import { isKnownJwaSignatureAlgorithm } from "../kms/jwk/jwa.mjs";
import { PublicJwk } from "../kms/jwk/PublicJwk.mjs";
import { _classPrivateFieldInitSpec } from "../../_virtual/_@oxc-project_runtime@0.112.0/helpers/classPrivateFieldInitSpec.mjs";
import { _classPrivateFieldSet2 } from "../../_virtual/_@oxc-project_runtime@0.112.0/helpers/classPrivateFieldSet2.mjs";
import { _classPrivateFieldGet2 } from "../../_virtual/_@oxc-project_runtime@0.112.0/helpers/classPrivateFieldGet2.mjs";
import "../kms/index.mjs";
import { X509Certificate } from "../x509/X509Certificate.mjs";
import { X509ModuleConfig } from "../x509/X509ModuleConfig.mjs";
import "../x509/index.mjs";
import { ClaimFormat } from "../vc/models/ClaimFormat.mjs";
import "../vc/index.mjs";
import { MdocError } from "./MdocError.mjs";
import { getMdocContext } from "./MdocContext.mjs";
import { isMdocSupportedSignatureAlgorithm, mdocSupportedSignatureAlgorithms } from "./mdocSupportedAlgs.mjs";
import { DeviceKey, DeviceKeyInfo, Holder, Issuer, IssuerSigned, SignatureAlgorithm } from "@owf/mdoc";
//#region src/modules/mdoc/Mdoc.ts
var _deviceKeyId = /* @__PURE__ */ new WeakMap();
/**
* This class represents a IssuerSigned Mdoc Document,
* which are the actual credentials being issued to holders.
*/
var Mdoc = class Mdoc {
get base64Url() {
return this.issuerSigned.encodedForOid4Vci;
}
constructor(issuerSigned) {
this.issuerSigned = issuerSigned;
_classPrivateFieldInitSpec(this, _deviceKeyId, void 0);
}
/**
* claim format is convenience method added to all credential instances
*/
get claimFormat() {
return ClaimFormat.MsoMdoc;
}
/**
* Encoded is convenience method added to all credential instances
*/
get encoded() {
return this.issuerSigned.encodedForOid4Vci;
}
/**
* Get the device key to which the mdoc is bound
*/
get deviceKey() {
const publicJwk = PublicJwk.fromUnknown(this.issuerSigned.issuerAuth.mobileSecurityObject.deviceKeyInfo.deviceKey.jwk);
if (_classPrivateFieldGet2(_deviceKeyId, this)) publicJwk.keyId = _classPrivateFieldGet2(_deviceKeyId, this);
return publicJwk;
}
set deviceKeyId(keyId) {
_classPrivateFieldSet2(_deviceKeyId, this, keyId);
}
get deviceKeyId() {
const deviceKey = this.deviceKey;
if (deviceKey.hasKeyId) return deviceKey.keyId;
}
static fromBase64Url(mdocBase64Url) {
return new Mdoc(IssuerSigned.fromEncodedForOid4Vci(mdocBase64Url));
}
get docType() {
return this.issuerSigned.issuerAuth.mobileSecurityObject.docType;
}
get alg() {
const algName = this.issuerSigned.issuerAuth.signatureAlgorithmName;
if (isKnownJwaSignatureAlgorithm(algName)) return algName;
throw new MdocError(`Cannot parse mdoc. The signature algorithm '${algName}' is not supported.`);
}
get validityInfo() {
const { signed, validFrom, validUntil } = this.issuerSigned.issuerAuth.mobileSecurityObject.validityInfo;
return {
signed,
validFrom,
validUntil
};
}
get issuerSignedCertificateChain() {
return this.issuerSigned.issuerAuth.certificateChain;
}
get signingCertificate() {
return this.issuerSigned.issuerAuth.certificate;
}
get issuerSignedNamespaces() {
if (!this.issuerSigned.issuerNamespaces?.issuerNamespaces) return {};
return Object.fromEntries(Array.from(this.issuerSigned.issuerNamespaces.issuerNamespaces.entries()).map(([namespace, value]) => [namespace, Object.fromEntries(Array.from(value.values()).map((v) => [v.elementIdentifier, v.elementValue]))]));
}
static async sign(agentContext, options) {
const { docType, validityInfo, namespaces, holderKey, issuerCertificate } = options;
const issuer = new Issuer(docType, getMdocContext(agentContext));
for (const [namespace, namespaceRecord] of Object.entries(namespaces)) issuer.addIssuerNamespace(namespace, namespaceRecord);
const issuerKey = issuerCertificate.publicJwk;
const alg = issuerKey.supportedSignatureAlgorithms.find(isMdocSupportedSignatureAlgorithm);
if (!alg) throw new MdocError(`Unable to create sign mdoc. No supported signature algorithm found to sign mdoc for jwk with key ${issuerKey.jwkTypeHumanDescription}. Key supports algs ${issuerKey.supportedSignatureAlgorithms.join(", ")}. mdoc supports algs ${mdocSupportedSignatureAlgorithms.join(", ")}`);
const now = /* @__PURE__ */ new Date();
return new Mdoc(await issuer.sign({
digestAlgorithm: "SHA-256",
validityInfo: {
...validityInfo,
signed: validityInfo.signed ?? now,
validFrom: validityInfo.validFrom ?? now
},
algorithm: SignatureAlgorithm[alg],
certificates: [issuerCertificate.rawCertificate],
deviceKeyInfo: DeviceKeyInfo.create({ deviceKey: DeviceKey.fromJwk(holderKey.toJson()) }),
signingKey: issuerKey.toJson()
}));
}
async verify(agentContext, options) {
const x509ModuleConfig = agentContext.dependencyManager.resolve(X509ModuleConfig);
const certificateChain = this.issuerSigned.issuerAuth.certificateChain.map((certificate) => X509Certificate.fromRawCertificate(certificate));
let trustedCertificates = options?.trustedCertificates;
if (!trustedCertificates) trustedCertificates = await x509ModuleConfig.getTrustedCertificatesForVerification?.(agentContext, {
verification: {
type: "credential",
credential: this
},
certificateChain
}) ?? x509ModuleConfig.trustedCertificates;
if (!trustedCertificates) throw new MdocError("No trusted certificates found. Cannot verify mdoc.");
const mdocContext = getMdocContext(agentContext, { now: options?.now });
try {
await Holder.verifyIssuerSigned({
trustedCertificates: trustedCertificates.map((cert) => X509Certificate.fromEncodedCertificate(cert).rawCertificate),
issuerSigned: this.issuerSigned,
disableCertificateChainValidation: false,
now: options?.now
}, mdocContext);
return { isValid: true };
} catch (error) {
return {
isValid: false,
error: error.message
};
}
}
};
//#endregion
export { Mdoc };
//# sourceMappingURL=Mdoc.mjs.map