UNPKG

@ldclabs/cose-ts

Version:

Implemented Keys, Algorithms (RFC9053), COSE (RFC9052) and CWT (RFC8392) in TypeScript.

80 lines 3.37 kB
// (c) 2023-present, LDC Labs. All rights reserved. // See the file LICENSE for licensing terms. import { Header } from './header'; import * as iana from './iana'; import { decodeCBOR, encodeCBOR, compareBytes } from './utils'; import { skipTag, withTag, CwtPrefix, Mac0MessagePrefix, CBORSelfPrefix } from './tag'; // Mac0Message represents a COSE_Mac0 object. // // Reference https://datatracker.ietf.org/doc/html/rfc9052#name-signing-with-one-signer. export class Mac0Message { payload; // protected header parameters: iana.HeaderParameterAlg, iana.HeaderParameterCrit. protected = null; // Other header parameters. unprotected = null; static macBytes(payload, protectedHeader, externalData) { return encodeCBOR([ 'MAC0', protectedHeader, externalData ?? new Uint8Array(), payload ]); } static fromBytes(key, coseData, externalData) { const data = skipTag(Mac0MessagePrefix, skipTag(CwtPrefix, skipTag(CBORSelfPrefix, coseData))); const [protectedBytes, unprotected, payload, tag] = decodeCBOR(data); const protectedHeader = Header.fromBytes(protectedBytes); const unprotectedHeader = new Header(unprotected); if (protectedHeader.has(iana.HeaderParameterAlg)) { const alg = protectedHeader.getInt(iana.HeaderParameterAlg); if (alg !== key.alg) { throw new Error(`cose-ts: Mac0Message.fromBytes: alg mismatch, expected ${alg}, got ${key.alg}`); } } const t = key.mac(Mac0Message.macBytes(payload, protectedBytes, externalData)); if (compareBytes(tag, t) !== 0) { throw new Error('cose-ts: Mac0Message.fromBytes: tag mismatch'); } return new Mac0Message(payload, protectedHeader, unprotectedHeader); } static withTag(coseData) { return withTag(Mac0MessagePrefix, coseData); } constructor(payload, protectedHeader, unprotected) { this.payload = payload; this.protected = protectedHeader ? new Header(protectedHeader.toRaw()) : null; this.unprotected = unprotected ? new Header(unprotected.toRaw()) : null; } toBytes(key, externalData) { if (this.protected == null) { this.protected = new Header(); if (key.has(iana.KeyParameterAlg)) { this.protected.setParam(iana.HeaderParameterAlg, key.alg); } } else if (this.protected.has(iana.HeaderParameterAlg)) { const alg = this.protected.getInt(iana.HeaderParameterAlg); if (alg !== key.alg) { throw new Error(`cose-ts: Mac0Message.toBytes: alg mismatch, expected ${alg}, got ${key.alg}`); } } if (this.unprotected == null) { this.unprotected = new Header(); if (key.has(iana.KeyParameterKid)) { this.unprotected.setParam(iana.HeaderParameterKid, key.kid); } } const protectedBytes = this.protected.toBytes(); const tag = key.mac(Mac0Message.macBytes(this.payload, protectedBytes, externalData)); return encodeCBOR([ protectedBytes, this.unprotected.toRaw(), this.payload, tag ]); } } //# sourceMappingURL=mac0.js.map