cose-kit
Version:
**DEPRECATED:** Use [@auth0/cose](https://www.npmjs.com/package/@auth0/cose).
88 lines (87 loc) • 3.91 kB
JavaScript
import decrypt from "#runtime/decrypt.js";
import encrypt from "#runtime/encrypt.js";
import { concat } from '../lib/buffer_utils.js';
import { addExtension, encoder } from '../cbor.js';
import { COSEBase } from './COSEBase.js';
import * as errors from "../util/errors.js";
import validateAlgorithms from "../lib/validate_algorithms.js";
import generateIv from '../lib/iv.js';
import { Headers, EncryptionAlgorithmNames, EncryptProtectedHeaders, UnprotectedHeaders } from '../headers.js';
import { decode } from "./decode.js";
export class Encrypt0 extends COSEBase {
constructor(protectedHeaders, unprotectedHeaders, ciphertext) {
super(protectedHeaders, unprotectedHeaders);
this.ciphertext = ciphertext;
}
static createEncrypt0AAD(protectedHeaders, externalAAD) {
return encoder.encode([
'Encrypt0',
protectedHeaders,
externalAAD
]);
}
getContentForEncoding() {
return [
this.encodedProtectedHeaders,
this.unprotectedHeaders,
this.ciphertext,
];
}
static decode(cose) {
return decode(cose, Encrypt0);
}
async decrypt(key, options) {
var _a, _b, _c;
const ciphertextWithTag = (_a = options === null || options === void 0 ? void 0 : options.detachedPayload) !== null && _a !== void 0 ? _a : this.ciphertext;
const aad = Encrypt0.createEncrypt0AAD((_b = this.encodedProtectedHeaders) !== null && _b !== void 0 ? _b : new Uint8Array(), (_c = options === null || options === void 0 ? void 0 : options.externalAAD) !== null && _c !== void 0 ? _c : new Uint8Array());
if (!this.alg || !this.algName || !EncryptionAlgorithmNames.has(this.alg)) {
throw new errors.COSEInvalid(`Unsupported encryption 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`);
}
const iv = this.unprotectedHeaders.get(Headers.IV);
const tag = ciphertextWithTag.slice(-16);
const ciphertext = ciphertextWithTag.slice(0, -16);
return decrypt(this.algName, key, ciphertext, iv, tag, aad);
}
get alg() {
return this.protectedHeaders.get(Headers.Algorithm) ||
this.unprotectedHeaders.get(Headers.Algorithm);
}
get algName() {
return this.alg ? EncryptionAlgorithmNames.get(this.alg) : undefined;
}
hasSupportedAlg() {
return !!this.algName;
}
static async encrypt(protectedHeaders, unprotectedHeaders, content, key, externalAAD = new Uint8Array()) {
const wProtectedHeaders = EncryptProtectedHeaders.wrap(protectedHeaders);
const alg = EncryptionAlgorithmNames.get(wProtectedHeaders.get(Headers.Algorithm));
if (!alg) {
throw new Error(`The protected header [${Headers.Algorithm}] (Algorithm) must be valid.`);
}
const wUnprotectedHeaders = UnprotectedHeaders.wrap([...(unprotectedHeaders || [])]);
let iv = wUnprotectedHeaders.get(Headers.IV);
if (!iv) {
iv = generateIv(alg);
wUnprotectedHeaders.set(Headers.IV, iv);
}
const aad = Encrypt0.createEncrypt0AAD(encoder.encode(wProtectedHeaders.esMap), externalAAD);
const { ciphertext, tag } = await encrypt(alg, content, key, iv, aad);
const r = concat(ciphertext, tag);
return new Encrypt0(wProtectedHeaders.esMap, wUnprotectedHeaders.esMap, r);
}
}
Encrypt0.tag = 16;
addExtension({
Class: Encrypt0,
tag: Encrypt0.tag,
encode(instance, encodeFn) {
return encodeFn(instance.getContentForEncoding());
},
decode: (data) => {
return new Encrypt0(...data);
}
});