UNPKG

cose-kit

Version:

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

103 lines (102 loc) 4.45 kB
import { SignatureBase } from './SignatureBase.js'; import { COSEBase } from './COSEBase.js'; import { UnprotectedHeaders, ProtectedHeaders, AlgorithmNames, Headers } from '../headers.js'; import sign from '#runtime/sign.js'; import { encoder, addExtension } from '../cbor.js'; import { decode } from './decode.js'; import * as errors from "../util/errors.js"; export class Sign extends COSEBase { constructor(protectedHeaders, unprotectedHeaders, payload, signatures) { super(protectedHeaders, unprotectedHeaders); this.payload = payload; this.signatures = signatures; } getContentForEncoding() { return [ this.encodedProtectedHeaders, this.unprotectedHeaders, this.payload, this.signatures.map((signature) => [ signature.protectedHeaders, signature.unprotectedHeaders, signature.signature ]), ]; } async verify(key, options) { for (const signature of this.signatures) { try { await signature.verify(key, this.encodedProtectedHeaders, this.payload, options); return; } catch (err) { } } throw new errors.COSESignatureVerificationFailed(); } async verifyX509(roots, options) { for (const signature of this.signatures) { try { const { publicKey } = await signature.verifyX509Chain(roots); await signature.verify(publicKey, this.encodedProtectedHeaders, this.payload, options); return; } catch (err) { } } throw new errors.COSESignatureVerificationFailed(); } static async sign(bodyProtectedHeader, unprotectedHeaders, payload, signers) { const encodedProtectedHeaders = ProtectedHeaders.from(bodyProtectedHeader).encode(); const unprotectedHeadersMap = UnprotectedHeaders.from(unprotectedHeaders).esMap; const signatures = await Promise.all(signers.map(async ({ key, protectedHeaders, unprotectedHeaders }) => { return Signature.sign(encodedProtectedHeaders, protectedHeaders, unprotectedHeaders, payload, key); })); return new Sign(encodedProtectedHeaders, unprotectedHeadersMap, payload, signatures); } static decode(cose) { return decode(cose, Sign); } } Sign.tag = 98; export class Signature extends SignatureBase { constructor(protectedHeaders, unprotectedHeaders, signature) { super(protectedHeaders, unprotectedHeaders, signature); this.unprotectedHeaders = unprotectedHeaders; this.signature = signature; } static Signature(bodyProtectedHeaders, protectedHeaders, applicationHeaders, payload) { return encoder.encode([ 'Signature', bodyProtectedHeaders || new Uint8Array(), protectedHeaders || new Uint8Array(), applicationHeaders || new Uint8Array(), payload, ]); } async verify(key, bodyProtectedHeaders, payload, options) { const toBeSigned = Signature.Signature(bodyProtectedHeaders, this.encodedProtectedHeaders, new Uint8Array(), payload); await this.internalVerify(toBeSigned, key, options); } static async sign(bodyProtectedHeaders, protectedHeaders, unprotectedHeaders, payload, key) { const wProtectedHeaders = ProtectedHeaders.from(protectedHeaders); const alg = AlgorithmNames.get(wProtectedHeaders.get(Headers.Algorithm)); const encodedProtectedHeaders = wProtectedHeaders.encode(); const unprotectedHeadersMapped = UnprotectedHeaders.from(unprotectedHeaders).esMap; const toBeSigned = Signature.Signature(bodyProtectedHeaders, encodedProtectedHeaders, new Uint8Array(), payload); if (!alg) { throw new Error('The alg header must be set.'); } const signature = await sign(alg, key, toBeSigned); return new Signature(encodedProtectedHeaders, unprotectedHeadersMapped, signature); } } addExtension({ Class: Sign, tag: Sign.tag, encode(instance, encode) { return encode(instance.getContentForEncoding()); }, decode: (data) => { const signatures = data[3].map(signature => new Signature(signature[0], signature[1], signature[2])); return new Sign(data[0], data[1], data[2], signatures); } });