jose/dist/node/cjs/runtime/webcrypto.js
2021-10-14 12:24:49 +02:00

159 lines
6.3 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getKeyObject = exports.isCryptoKey = void 0;
const crypto = require("crypto");
const util = require("util");
const webcrypto = crypto.webcrypto;
exports.default = webcrypto;
exports.isCryptoKey = util.types.isCryptoKey
? (obj) => util.types.isCryptoKey(obj)
:
(obj) => false;
function getHashLength(hash) {
return parseInt(hash === null || hash === void 0 ? void 0 : hash.name.substr(4), 10);
}
function getNamedCurve(alg) {
switch (alg) {
case 'ES256':
return 'P-256';
case 'ES384':
return 'P-384';
case 'ES512':
return 'P-521';
}
}
function getKeyObject(key, alg, usage) {
switch (alg) {
case undefined:
break;
case 'HS256':
case 'HS384':
case 'HS512': {
if (key.algorithm.name !== 'HMAC') {
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be HMAC.`);
}
const expected = parseInt(alg.substr(2), 10);
const actual = getHashLength(key.algorithm.hash);
if (actual !== expected) {
throw new TypeError(`CryptoKey does not support this operation, its algorithm.hash must be SHA-${expected}.`);
}
break;
}
case 'RS256':
case 'RS384':
case 'RS512': {
if (key.algorithm.name !== 'RSASSA-PKCS1-v1_5') {
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be RSASSA-PKCS1-v1_5.`);
}
const expected = parseInt(alg.substr(2), 10);
const actual = getHashLength(key.algorithm.hash);
if (actual !== expected) {
throw new TypeError(`CryptoKey does not support this operation, its algorithm.hash must be SHA-${expected}.`);
}
break;
}
case 'PS256':
case 'PS384':
case 'PS512': {
if (key.algorithm.name !== 'RSA-PSS') {
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be RSA-PSS.`);
}
const expected = parseInt(alg.substr(2), 10);
const actual = getHashLength(key.algorithm.hash);
if (actual !== expected) {
throw new TypeError(`CryptoKey does not support this operation, its algorithm.hash must be SHA-${expected}.`);
}
break;
}
case 'EdDSA': {
if (key.algorithm.name !== 'NODE-ED25519' && key.algorithm.name !== 'NODE-ED448') {
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be NODE-ED25519 or NODE-ED448.`);
}
break;
}
case 'ES256':
case 'ES384':
case 'ES512': {
if (key.algorithm.name !== 'ECDSA') {
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be ECDSA.`);
}
const expected = getNamedCurve(alg);
const actual = key.algorithm.namedCurve;
if (actual !== expected) {
throw new TypeError(`CryptoKey does not support this operation, its algorithm.namedCurve must be ${expected}.`);
}
break;
}
case 'A128GCM':
case 'A192GCM':
case 'A256GCM': {
if (key.algorithm.name !== 'AES-GCM') {
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be AES-GCM.`);
}
const expected = parseInt(alg.substr(1, 3), 10);
const actual = key.algorithm.length;
if (actual !== expected) {
throw new TypeError(`CryptoKey does not support this operation, its algorithm.length must be ${expected}.`);
}
break;
}
case 'A128KW':
case 'A192KW':
case 'A256KW': {
if (key.algorithm.name !== 'AES-KW') {
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be AES-KW.`);
}
const expected = parseInt(alg.substr(1, 3), 10);
const actual = key.algorithm.length;
if (actual !== expected) {
throw new TypeError(`CryptoKey does not support this operation, its algorithm.length must be ${expected}.`);
}
break;
}
case 'ECDH-ES':
if (key.algorithm.name !== 'ECDH') {
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be ECDH.`);
}
break;
case 'PBES2-HS256+A128KW':
case 'PBES2-HS384+A192KW':
case 'PBES2-HS512+A256KW':
if (key.algorithm.name !== 'PBKDF2') {
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be PBKDF2.`);
}
break;
case 'RSA-OAEP':
case 'RSA-OAEP-256':
case 'RSA-OAEP-384':
case 'RSA-OAEP-512': {
if (key.algorithm.name !== 'RSA-OAEP') {
throw new TypeError(`CryptoKey does not support this operation, its algorithm.name must be RSA-OAEP.`);
}
const expected = parseInt(alg.substr(9), 10) || 1;
const actual = getHashLength(key.algorithm.hash);
if (actual !== expected) {
throw new TypeError(`CryptoKey does not support this operation, its algorithm.hash must be SHA-${expected}.`);
}
break;
}
default:
throw new TypeError('CryptoKey does not support this operation');
}
if (usage && !key.usages.find(Set.prototype.has.bind(usage))) {
const usages = [...usage];
let msg = 'CryptoKey does not support this operation, its usages must include ';
if (usages.length > 2) {
const last = usages.pop();
msg += `one of ${usages.join(', ')}, or ${last}.`;
}
else if (usages.length === 2) {
msg += `one of ${usages[0]} or ${usages[1]}.`;
}
else {
msg += ` ${usages[0]}.`;
}
throw new TypeError(msg);
}
return crypto.KeyObject.from(key);
}
exports.getKeyObject = getKeyObject;