deno.land / x / jose@v5.2.4 / lib / crypto_key.ts
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149function unusable(name: string | number, prop = 'algorithm.name') { return new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`)}
function isAlgorithm<T extends KeyAlgorithm>( algorithm: KeyAlgorithm, name: string,): algorithm is T { return algorithm.name === name}
function getHashLength(hash: KeyAlgorithm) { return parseInt(hash.name.slice(4), 10)}
function getNamedCurve(alg: string) { switch (alg) { case 'ES256': return 'P-256' case 'ES384': return 'P-384' case 'ES512': return 'P-521' default: throw new Error('unreachable') }}
function checkUsage(key: CryptoKey, usages: KeyUsage[]) { 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) }}
export function checkSigCryptoKey(key: CryptoKey, alg: string, ...usages: KeyUsage[]) { switch (alg) { case 'HS256': case 'HS384': case 'HS512': { if (!isAlgorithm<HmacKeyAlgorithm>(key.algorithm, 'HMAC')) throw unusable('HMAC') const expected = parseInt(alg.slice(2), 10) const actual = getHashLength(key.algorithm.hash) if (actual !== expected) throw unusable(`SHA-${expected}`, 'algorithm.hash') break } case 'RS256': case 'RS384': case 'RS512': { if (!isAlgorithm<RsaHashedKeyAlgorithm>(key.algorithm, 'RSASSA-PKCS1-v1_5')) throw unusable('RSASSA-PKCS1-v1_5') const expected = parseInt(alg.slice(2), 10) const actual = getHashLength(key.algorithm.hash) if (actual !== expected) throw unusable(`SHA-${expected}`, 'algorithm.hash') break } case 'PS256': case 'PS384': case 'PS512': { if (!isAlgorithm<RsaHashedKeyAlgorithm>(key.algorithm, 'RSA-PSS')) throw unusable('RSA-PSS') const expected = parseInt(alg.slice(2), 10) const actual = getHashLength(key.algorithm.hash) if (actual !== expected) throw unusable(`SHA-${expected}`, 'algorithm.hash') break } case 'EdDSA': { if (key.algorithm.name !== 'Ed25519' && key.algorithm.name !== 'Ed448') { throw unusable('Ed25519 or Ed448') } break } case 'ES256': case 'ES384': case 'ES512': { if (!isAlgorithm<EcKeyAlgorithm>(key.algorithm, 'ECDSA')) throw unusable('ECDSA') const expected = getNamedCurve(alg) const actual = key.algorithm.namedCurve if (actual !== expected) throw unusable(expected, 'algorithm.namedCurve') break } default: throw new TypeError('CryptoKey does not support this operation') }
checkUsage(key, usages)}
export function checkEncCryptoKey(key: CryptoKey, alg: string, ...usages: KeyUsage[]) { switch (alg) { case 'A128GCM': case 'A192GCM': case 'A256GCM': { if (!isAlgorithm<AesKeyAlgorithm>(key.algorithm, 'AES-GCM')) throw unusable('AES-GCM') const expected = parseInt(alg.slice(1, 4), 10) const actual = key.algorithm.length if (actual !== expected) throw unusable(expected, 'algorithm.length') break } case 'A128KW': case 'A192KW': case 'A256KW': { if (!isAlgorithm<AesKeyAlgorithm>(key.algorithm, 'AES-KW')) throw unusable('AES-KW') const expected = parseInt(alg.slice(1, 4), 10) const actual = key.algorithm.length if (actual !== expected) throw unusable(expected, 'algorithm.length') break } case 'ECDH': { switch (key.algorithm.name) { case 'ECDH': case 'X25519': case 'X448': break default: throw unusable('ECDH, X25519, or X448') } break } case 'PBES2-HS256+A128KW': case 'PBES2-HS384+A192KW': case 'PBES2-HS512+A256KW': if (!isAlgorithm(key.algorithm, 'PBKDF2')) throw unusable('PBKDF2') break case 'RSA-OAEP': case 'RSA-OAEP-256': case 'RSA-OAEP-384': case 'RSA-OAEP-512': { if (!isAlgorithm<RsaHashedKeyAlgorithm>(key.algorithm, 'RSA-OAEP')) throw unusable('RSA-OAEP') const expected = parseInt(alg.slice(9), 10) || 1 const actual = getHashLength(key.algorithm.hash) if (actual !== expected) throw unusable(`SHA-${expected}`, 'algorithm.hash') break } default: throw new TypeError('CryptoKey does not support this operation') }
checkUsage(key, usages)}
Version Info