jose-browser-runtime
Advanced tools
Comparing version 4.0.3 to 4.0.4
import { JOSENotSupported } from '../util/errors.js'; | ||
import random from '../runtime/random.js'; | ||
const bitLengths = new Map([ | ||
['A128CBC-HS256', 256], | ||
['A128GCM', 128], | ||
['A192CBC-HS384', 384], | ||
['A192GCM', 192], | ||
['A256CBC-HS512', 512], | ||
['A256GCM', 256], | ||
]); | ||
const generateCek = (alg) => { | ||
const bitLength = bitLengths.get(alg); | ||
if (!bitLength) { | ||
throw new JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`); | ||
export function bitLength(alg) { | ||
switch (alg) { | ||
case 'A128CBC-HS256': | ||
return 256; | ||
case 'A192CBC-HS384': | ||
return 384; | ||
case 'A256CBC-HS512': | ||
return 512; | ||
case 'A128GCM': | ||
return 128; | ||
case 'A192GCM': | ||
return 192; | ||
case 'A256GCM': | ||
return 256; | ||
default: | ||
throw new JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`); | ||
} | ||
return random(new Uint8Array(bitLength >> 3)); | ||
}; | ||
export default generateCek; | ||
export { bitLengths }; | ||
} | ||
export default (alg) => random(new Uint8Array(bitLength(alg) >> 3)); |
import { JWEInvalid } from '../util/errors.js'; | ||
import { bitLengths } from './iv.js'; | ||
import { bitLength } from './iv.js'; | ||
const checkIvLength = (enc, iv) => { | ||
if (iv.length << 3 !== bitLengths.get(enc)) { | ||
if (iv.length << 3 !== bitLength(enc)) { | ||
throw new JWEInvalid('Invalid Initialization Vector length'); | ||
@@ -6,0 +6,0 @@ } |
@@ -8,3 +8,3 @@ import { unwrap as aesKw } from '../runtime/aeskw.js'; | ||
import { JOSENotSupported, JWEInvalid } from '../util/errors.js'; | ||
import { bitLengths as cekLengths } from '../lib/cek.js'; | ||
import { bitLength as cekLength } from '../lib/cek.js'; | ||
import { importJWK } from '../key/import.js'; | ||
@@ -44,3 +44,3 @@ import checkKeyType from './check_key_type.js'; | ||
} | ||
const sharedSecret = await ECDH.deriveKey(epk, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, parseInt(alg.substr(-5, 3), 10) || cekLengths.get(joseHeader.enc), partyUInfo, partyVInfo); | ||
const sharedSecret = await ECDH.deriveKey(epk, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, parseInt(alg.substr(-5, 3), 10) || cekLength(joseHeader.enc), partyUInfo, partyVInfo); | ||
if (alg === 'ECDH-ES') | ||
@@ -47,0 +47,0 @@ return sharedSecret; |
@@ -7,3 +7,3 @@ import { wrap as aesKw } from '../runtime/aeskw.js'; | ||
import { encode as base64url } from '../runtime/base64url.js'; | ||
import generateCek, { bitLengths as cekLengths } from '../lib/cek.js'; | ||
import generateCek, { bitLength as cekLength } from '../lib/cek.js'; | ||
import { JOSENotSupported } from '../util/errors.js'; | ||
@@ -33,3 +33,3 @@ import { exportJWK } from '../key/export.js'; | ||
const { x, y, crv, kty } = await exportJWK(ephemeralKey); | ||
const sharedSecret = await ECDH.deriveKey(key, ephemeralKey, alg === 'ECDH-ES' ? enc : alg, parseInt(alg.substr(-5, 3), 10) || cekLengths.get(enc), apu, apv); | ||
const sharedSecret = await ECDH.deriveKey(key, ephemeralKey, alg === 'ECDH-ES' ? enc : alg, parseInt(alg.substr(-5, 3), 10) || cekLength(enc), apu, apv); | ||
parameters = { epk: { x, y, crv, kty } }; | ||
@@ -36,0 +36,0 @@ if (apu) |
import { JOSENotSupported } from '../util/errors.js'; | ||
import random from '../runtime/random.js'; | ||
const bitLengths = new Map([ | ||
['A128CBC-HS256', 128], | ||
['A128GCM', 96], | ||
['A128GCMKW', 96], | ||
['A192CBC-HS384', 128], | ||
['A192GCM', 96], | ||
['A192GCMKW', 96], | ||
['A256CBC-HS512', 128], | ||
['A256GCM', 96], | ||
['A256GCMKW', 96], | ||
]); | ||
const generateIv = (alg) => { | ||
const bitLength = bitLengths.get(alg); | ||
if (!bitLength) { | ||
throw new JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`); | ||
export function bitLength(alg) { | ||
switch (alg) { | ||
case 'A128CBC-HS256': | ||
return 128; | ||
case 'A128GCM': | ||
return 96; | ||
case 'A128GCMKW': | ||
return 96; | ||
case 'A192CBC-HS384': | ||
return 128; | ||
case 'A192GCM': | ||
return 96; | ||
case 'A192GCMKW': | ||
return 96; | ||
case 'A256CBC-HS512': | ||
return 128; | ||
case 'A256GCM': | ||
return 96; | ||
case 'A256GCMKW': | ||
return 96; | ||
default: | ||
throw new JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`); | ||
} | ||
return random(new Uint8Array(bitLength >> 3)); | ||
}; | ||
export default generateIv; | ||
export { bitLengths }; | ||
} | ||
export default (alg) => random(new Uint8Array(bitLength(alg) >> 3)); |
import bogusWebCrypto from './bogus.js'; | ||
import crypto, { checkCryptoKey, isCryptoKey } from './webcrypto.js'; | ||
import crypto, { isCryptoKey } from './webcrypto.js'; | ||
import { checkEncCryptoKey } from '../lib/crypto_key.js'; | ||
import invalidKeyInput from './invalid_key_input.js'; | ||
@@ -11,3 +12,3 @@ function checkKeySize(key, alg) { | ||
if (isCryptoKey(key)) { | ||
checkCryptoKey(key, alg, usage); | ||
checkEncCryptoKey(key, alg, usage); | ||
return key; | ||
@@ -14,0 +15,0 @@ } |
import { concat, uint64be } from '../lib/buffer_utils.js'; | ||
import checkIvLength from '../lib/check_iv_length.js'; | ||
import checkCekLength from './check_cek_length.js'; | ||
import timingSafeEqual from './timing_safe_equal.js'; | ||
import { JOSENotSupported, JWEDecryptionFailed } from '../util/errors.js'; | ||
import crypto, { checkCryptoKey, isCryptoKey } from './webcrypto.js'; | ||
import crypto, { isCryptoKey } from './webcrypto.js'; | ||
import { checkEncCryptoKey } from '../lib/crypto_key.js'; | ||
import invalidKeyInput from './invalid_key_input.js'; | ||
@@ -45,3 +47,3 @@ async function cbcDecrypt(enc, cek, ciphertext, iv, tag, aad) { | ||
else { | ||
checkCryptoKey(cek, enc, 'decrypt'); | ||
checkEncCryptoKey(cek, enc, 'decrypt'); | ||
encKey = cek; | ||
@@ -70,2 +72,4 @@ } | ||
case 'A256CBC-HS512': | ||
if (cek instanceof Uint8Array) | ||
checkCekLength(cek, parseInt(enc.substr(-3), 10)); | ||
return cbcDecrypt(enc, cek, ciphertext, iv, tag, aad); | ||
@@ -75,2 +79,4 @@ case 'A128GCM': | ||
case 'A256GCM': | ||
if (cek instanceof Uint8Array) | ||
checkCekLength(cek, parseInt(enc.substr(1, 3), 10)); | ||
return gcmDecrypt(enc, cek, ciphertext, iv, tag, aad); | ||
@@ -77,0 +83,0 @@ default: |
import { encoder, concat, uint32be, lengthAndInput, concatKdf } from '../lib/buffer_utils.js'; | ||
import crypto, { checkCryptoKey, isCryptoKey } from './webcrypto.js'; | ||
import crypto, { isCryptoKey } from './webcrypto.js'; | ||
import { checkEncCryptoKey } from '../lib/crypto_key.js'; | ||
import digest from './digest.js'; | ||
@@ -9,7 +10,7 @@ import invalidKeyInput from './invalid_key_input.js'; | ||
} | ||
checkCryptoKey(publicKey, 'ECDH-ES'); | ||
checkEncCryptoKey(publicKey, 'ECDH-ES'); | ||
if (!isCryptoKey(privateKey)) { | ||
throw new TypeError(invalidKeyInput(privateKey, 'CryptoKey')); | ||
} | ||
checkCryptoKey(privateKey, 'ECDH-ES', 'deriveBits', 'deriveKey'); | ||
checkEncCryptoKey(privateKey, 'ECDH-ES', 'deriveBits', 'deriveKey'); | ||
const value = concat(lengthAndInput(encoder.encode(algorithm)), lengthAndInput(apu), lengthAndInput(apv), uint32be(keyLength)); | ||
@@ -16,0 +17,0 @@ if (!privateKey.usages.includes('deriveBits')) { |
import { concat, uint64be } from '../lib/buffer_utils.js'; | ||
import checkIvLength from '../lib/check_iv_length.js'; | ||
import crypto, { checkCryptoKey, isCryptoKey } from './webcrypto.js'; | ||
import checkCekLength from './check_cek_length.js'; | ||
import crypto, { isCryptoKey } from './webcrypto.js'; | ||
import { checkEncCryptoKey } from '../lib/crypto_key.js'; | ||
import invalidKeyInput from './invalid_key_input.js'; | ||
@@ -30,3 +32,3 @@ import { JOSENotSupported } from '../util/errors.js'; | ||
else { | ||
checkCryptoKey(cek, enc, 'encrypt'); | ||
checkEncCryptoKey(cek, enc, 'encrypt'); | ||
encKey = cek; | ||
@@ -53,2 +55,4 @@ } | ||
case 'A256CBC-HS512': | ||
if (cek instanceof Uint8Array) | ||
checkCekLength(cek, parseInt(enc.substr(-3), 10)); | ||
return cbcEncrypt(enc, plaintext, cek, iv, aad); | ||
@@ -58,2 +62,4 @@ case 'A128GCM': | ||
case 'A256GCM': | ||
if (cek instanceof Uint8Array) | ||
checkCekLength(cek, parseInt(enc.substr(1, 3), 10)); | ||
return gcmEncrypt(enc, plaintext, cek, iv, aad); | ||
@@ -60,0 +66,0 @@ default: |
@@ -1,6 +0,7 @@ | ||
import crypto, { checkCryptoKey, isCryptoKey } from './webcrypto.js'; | ||
import crypto, { isCryptoKey } from './webcrypto.js'; | ||
import { checkSigCryptoKey } from '../lib/crypto_key.js'; | ||
import invalidKeyInput from './invalid_key_input.js'; | ||
export default function getCryptoKey(alg, key, usage) { | ||
if (isCryptoKey(key)) { | ||
checkCryptoKey(key, alg, usage); | ||
checkSigCryptoKey(key, alg, usage); | ||
return key; | ||
@@ -7,0 +8,0 @@ } |
@@ -6,3 +6,4 @@ import random from './random.js'; | ||
import checkP2s from '../lib/check_p2s.js'; | ||
import crypto, { checkCryptoKey, isCryptoKey } from './webcrypto.js'; | ||
import crypto, { isCryptoKey } from './webcrypto.js'; | ||
import { checkEncCryptoKey } from '../lib/crypto_key.js'; | ||
import invalidKeyInput from './invalid_key_input.js'; | ||
@@ -14,3 +15,3 @@ function getCryptoKey(key, alg) { | ||
if (isCryptoKey(key)) { | ||
checkCryptoKey(key, alg, 'deriveBits', 'deriveKey'); | ||
checkEncCryptoKey(key, alg, 'deriveBits', 'deriveKey'); | ||
return key; | ||
@@ -17,0 +18,0 @@ } |
import subtleAlgorithm from './subtle_rsaes.js'; | ||
import bogusWebCrypto from './bogus.js'; | ||
import crypto, { checkCryptoKey, isCryptoKey } from './webcrypto.js'; | ||
import crypto, { isCryptoKey } from './webcrypto.js'; | ||
import { checkEncCryptoKey } from '../lib/crypto_key.js'; | ||
import checkKeyLength from './check_key_length.js'; | ||
@@ -10,3 +11,3 @@ import invalidKeyInput from './invalid_key_input.js'; | ||
} | ||
checkCryptoKey(key, alg, 'encrypt', 'wrapKey'); | ||
checkEncCryptoKey(key, alg, 'encrypt', 'wrapKey'); | ||
checkKeyLength(alg, key); | ||
@@ -26,3 +27,3 @@ if (key.usages.includes('encrypt')) { | ||
} | ||
checkCryptoKey(key, alg, 'decrypt', 'unwrapKey'); | ||
checkEncCryptoKey(key, alg, 'decrypt', 'unwrapKey'); | ||
checkKeyLength(alg, key); | ||
@@ -29,0 +30,0 @@ if (key.usages.includes('decrypt')) { |
@@ -9,146 +9,1 @@ import globalThis from './global.js'; | ||
} | ||
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'; | ||
} | ||
} | ||
export function checkCryptoKey(key, alg, ...usages) { | ||
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 (usages.length && !usages.some((expected) => key.usages.includes(expected))) { | ||
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); | ||
} | ||
} |
{ | ||
"name": "jose-browser-runtime", | ||
"version": "4.0.3", | ||
"version": "4.0.4", | ||
"description": "(Browser Runtime) 'JSON Web Almost Everything' - JWA, JWS, JWE, JWT, JWK, JWKS with no dependencies using runtime's native crypto", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
155434
106
3829