UNPKG

digital-covid-certificate-lib

Version:

A library to parse and verify Digital Covid Certificates (DCC)

82 lines 3.74 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ChKeyStore = void 0; const pvtsutils_1 = require("pvtsutils"); const x509_1 = require("@peculiar/x509"); class ChKeyStore { constructor() { } verifyCertificateChain(args) { return __awaiter(this, void 0, void 0, function* () { const { jwt, rootCertificate } = args; const trustChain = jwt.header.x5c.map(cert => new x509_1.X509Certificate(cert)); if (rootCertificate) { trustChain.push(new x509_1.X509Certificate(rootCertificate)); } for (let i = 0; i < trustChain.length; i++) { const valid = yield trustChain[i].verify({ date: new Date(), publicKey: trustChain[i + 1] }); if (!valid) { throw new Error("Invalid certificate."); } } }); } getKey(keyId) { const keyData = this.keys.filter(key => key.keyId === keyId).pop(); return this.mapToCryptoKey(keyData); } loadKeys(loadingArgs) { return __awaiter(this, void 0, void 0, function* () { if (loadingArgs.verifySignature) { yield this.verifyCertificateChain(loadingArgs); yield this.verifyJwtSignature(loadingArgs); } this.keys = loadingArgs.jwt.payload.certs; }); } mapToCryptoKey(keyData) { const format = "jwk"; keyData.kty = "RSA"; keyData.ext = true; keyData.alg = keyData.alg === 'RS256' ? "PS256" : keyData.alg; // RS256 is not known to WebCrypto Api const toBase64Url = (str) => pvtsutils_1.Convert.ToBase64Url(pvtsutils_1.Convert.FromBase64(str)); keyData.e = toBase64Url(keyData.e); keyData.n = toBase64Url(keyData.n); const algorithm = { name: "RSA-PSS", // can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512" hash: { name: "SHA-256" }, }; // whether the key is extractable (i.e. can be used in exportKey) const extractable = false; // "verify" for public key import, "sign" for private key imports const keyUsages = ["verify"]; return crypto.subtle.importKey(format, keyData, algorithm, extractable, keyUsages); } verifyJwtSignature(arg) { return __awaiter(this, void 0, void 0, function* () { const { jwt } = arg; const certificate = jwt.header.x5c.map(cert => new x509_1.X509Certificate(cert))[0]; const public_key = yield certificate.publicKey.export(crypto); const valid = yield crypto.subtle.verify(public_key.algorithm, public_key, //from generateKey or importKey above jwt.signature, //ArrayBuffer of the signature jwt.toBeSigned //ArrayBuffer of the data ); if (!valid) { throw new Error("Invalid JWT."); } }); } } exports.ChKeyStore = ChKeyStore; //# sourceMappingURL=ChKeyStore.js.map