UNPKG

cose-kit

Version:

This is an early prototype of a RFC8152 COSE library for node.js.

83 lines (82 loc) 2.94 kB
import verify from "#runtime/verify.js"; import { algsToValue, headers } from '../headers.js'; import sign from '#runtime/sign.js'; import { fromUTF8 } from '../lib/buffer_utils.js'; import { SignatureBase } from './SignatureBase.js'; import { encoder, addExtension } from '../cbor.js'; export class Sign1 extends SignatureBase { constructor(protectedHeaders, unprotectedHeaders, payload, signature) { super(protectedHeaders, unprotectedHeaders, signature); this.payload = payload; } getContentForEncoding() { return [ this.encodedProtectedHeaders, this.unprotectedHeaders, this.payload, this.signature, ]; } encode() { return encoder.encode(this); } static Signature1(protectedHeaders, applicationHeaders, payload) { return encoder.encode([ 'Signature1', protectedHeaders, applicationHeaders, payload, ]); } async verify(key, externalAAD = new Uint8Array()) { if (typeof key === 'function') { key = await key(this); } if (!key) { throw new Error('key not found'); } const toBeSigned = Sign1.Signature1(this.encodedProtectedHeaders || new Uint8Array(), externalAAD, this.payload); if (!this.algName) { throw new Error('unknown algorithm: ' + this.alg); } return verify(this.algName, key, this.signature, toBeSigned); } async verifyX509(roots) { const { publicKey } = await this.verifyX509Chain(roots); return this.verify(publicKey); } static async sign(protectedHeaders, unprotectedHeaders, payload, key) { const { alg } = protectedHeaders; const encodedProtectedHeaders = encoder.encode(new Map(Object.entries(protectedHeaders).map(([k, v]) => { if (k === 'alg') { v = algsToValue.get(v); } else if (typeof v === 'string') { v = fromUTF8(v); } return [headers[k], v]; }))); const unprotectedHeadersMap = new Map(Object.entries(unprotectedHeaders || {}).map(([k, v]) => { if (typeof v === 'string') { v = fromUTF8(v); } return [headers[k], v]; })); const toBeSigned = Sign1.Signature1(encodedProtectedHeaders, new Uint8Array(), payload); if (!alg) { throw new Error('The alg header must be set.'); } const signature = await sign(alg, key, toBeSigned); return new Sign1(encodedProtectedHeaders, unprotectedHeadersMap, payload, signature); } } addExtension({ Class: Sign1, tag: 18, encode(instance, encodeFn) { return encodeFn(instance.getContentForEncoding()); }, decode: (data) => { return new Sign1(data[0], data[1], data[2], data[3]); } });