UNPKG

cose-kit

Version:

**DEPRECATED:** Use [@auth0/cose](https://www.npmjs.com/package/@auth0/cose).

77 lines (76 loc) 3.16 kB
import verify from "#runtime/verify.js"; import { importX509 } from 'jose'; import { pkijs } from '#runtime/pkijs.js'; import { decodeBase64 } from '#runtime/base64.js'; import { X509InvalidCertificateChain, X509NoMatchingCertificate } from '../util/errors.js'; import { certToPEM, pemToCert } from '../util/cert.js'; import { AlgorithmNames, Headers } from '../headers.js'; import { COSEBase } from './COSEBase.js'; import * as errors from "../util/errors.js"; import validateAlgorithms from '../lib/validate_algorithms.js'; export class SignatureBase extends COSEBase { constructor(protectedHeaders, unprotectedHeaders, signature) { super(protectedHeaders, unprotectedHeaders); this.signature = signature; } get alg() { return this.protectedHeaders.get(Headers.Algorithm) || this.unprotectedHeaders.get(Headers.Algorithm); } get algName() { return this.alg ? AlgorithmNames.get(this.alg) : undefined; } get kid() { return this.protectedHeaders.get(Headers.KeyID) || this.unprotectedHeaders.get(Headers.KeyID); } get x5bag() { const x5bag = this.protectedHeaders.get(Headers.X5Bag) || this.unprotectedHeaders.get(Headers.X5Bag); if (!x5bag) { return; } return Array.isArray(x5bag) ? x5bag : [x5bag]; } get x5chain() { const x5chain = this.protectedHeaders.get(Headers.X5Chain) || this.unprotectedHeaders.get(Headers.X5Chain); if (!x5chain) { return; } return Array.isArray(x5chain) ? x5chain : [x5chain]; } async verifyX509Chain(caRoots) { const { x5chain } = this; if (!x5chain || x5chain.length === 0) { throw new X509NoMatchingCertificate(); } const chainEngine = new pkijs.CertificateChainValidationEngine({ certs: x5chain.map((c) => pkijs.Certificate.fromBER(c)), trustedCerts: caRoots.map((c) => pkijs.Certificate.fromBER(decodeBase64(pemToCert(c)))), }); const chain = await chainEngine.verify(); if (!chain.result) { throw new X509InvalidCertificateChain(chain.resultMessage); } const x509Cert = certToPEM(x5chain[0]); const publicKey = await importX509(x509Cert, this.algName); return { publicKey, raw: x5chain[0] }; } async internalVerify(payload, key, options) { if (!this.alg || !this.algName || !AlgorithmNames.has(this.alg)) { throw new errors.COSEInvalid(`Unsupported algorithm ${this.alg}`); } const algorithms = options && validateAlgorithms('algorithms', options.algorithms); if (algorithms && !algorithms.has(this.alg)) { throw new errors.COSEAlgNotAllowed(`[${Headers.Algorithm}] (algorithm) Header Parameter not allowed`); } if (typeof key === 'function') { key = await key(this); } const isValid = await verify(this.algName, key, this.signature, payload); if (!isValid) { throw new errors.COSESignatureVerificationFailed(); } } }