jose 5.10.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -15
- package/dist/types/index.d.ts +5 -5
- package/dist/types/jwe/compact/decrypt.d.ts +4 -4
- package/dist/types/jwe/compact/encrypt.d.ts +4 -4
- package/dist/types/jwe/flattened/decrypt.d.ts +4 -4
- package/dist/types/jwe/flattened/encrypt.d.ts +6 -6
- package/dist/types/jwe/general/decrypt.d.ts +4 -4
- package/dist/types/jwe/general/encrypt.d.ts +7 -7
- package/dist/types/jwk/embedded.d.ts +2 -2
- package/dist/types/jwk/thumbprint.d.ts +5 -5
- package/dist/types/jwks/local.d.ts +2 -2
- package/dist/types/jwks/remote.d.ts +104 -25
- package/dist/types/jws/compact/sign.d.ts +4 -4
- package/dist/types/jws/compact/verify.d.ts +4 -4
- package/dist/types/jws/flattened/sign.d.ts +4 -4
- package/dist/types/jws/flattened/verify.d.ts +4 -4
- package/dist/types/jws/general/sign.d.ts +6 -6
- package/dist/types/jws/general/verify.d.ts +4 -4
- package/dist/types/jwt/decrypt.d.ts +5 -5
- package/dist/types/jwt/encrypt.d.ts +4 -4
- package/dist/types/jwt/produce.d.ts +3 -3
- package/dist/types/jwt/sign.d.ts +3 -3
- package/dist/types/jwt/unsecured.d.ts +5 -5
- package/dist/types/jwt/verify.d.ts +5 -5
- package/dist/types/key/export.d.ts +10 -12
- package/dist/types/key/generate_key_pair.d.ts +10 -11
- package/dist/types/key/generate_secret.d.ts +6 -9
- package/dist/types/key/import.d.ts +20 -27
- package/dist/types/types.d.ts +27 -29
- package/dist/types/util/decode_jwt.d.ts +2 -2
- package/dist/types/util/decode_protected_header.d.ts +2 -2
- package/dist/types/util/errors.d.ts +6 -6
- package/dist/{browser → webapi}/index.js +2 -2
- package/dist/{node/esm → webapi}/jwe/flattened/decrypt.js +8 -4
- package/dist/{node/esm → webapi}/jwe/flattened/encrypt.js +7 -3
- package/dist/{node/esm → webapi}/jwe/general/encrypt.js +8 -3
- package/dist/{node/esm → webapi}/jwk/thumbprint.js +18 -8
- package/dist/{node/esm → webapi}/jwks/local.js +1 -6
- package/dist/{node/esm → webapi}/jwks/remote.js +34 -6
- package/dist/{node/esm → webapi}/jws/flattened/sign.js +7 -5
- package/dist/{browser → webapi}/jws/flattened/verify.js +8 -14
- package/dist/{browser → webapi}/jwt/unsecured.js +1 -1
- package/dist/{node/esm → webapi}/key/export.js +2 -3
- package/dist/{browser/runtime/generate.js → webapi/key/generate_key_pair.js} +4 -57
- package/dist/webapi/key/generate_secret.js +40 -0
- package/dist/{browser → webapi}/key/import.js +8 -6
- package/dist/{node/esm → webapi}/lib/aesgcmkw.js +3 -3
- package/dist/{browser/runtime → webapi/lib}/aeskw.js +9 -16
- package/dist/{browser/runtime → webapi/lib}/asn1.js +24 -20
- package/dist/{browser/runtime → webapi/lib}/base64url.js +17 -9
- package/dist/{browser → webapi}/lib/buffer_utils.js +4 -19
- package/dist/{browser → webapi}/lib/cek.js +1 -2
- package/dist/{browser/runtime → webapi/lib}/check_cek_length.js +1 -2
- package/dist/{browser → webapi}/lib/check_iv_length.js +1 -2
- package/dist/webapi/lib/check_key_type.js +126 -0
- package/dist/{node/esm → webapi}/lib/crypto_key.js +9 -26
- package/dist/{browser/runtime → webapi/lib}/decrypt.js +26 -10
- package/dist/{node/esm → webapi}/lib/decrypt_key_management.js +22 -24
- package/dist/{browser/runtime → webapi/lib}/digest.js +1 -3
- package/dist/webapi/lib/ecdhes.js +46 -0
- package/dist/{browser/runtime → webapi/lib}/encrypt.js +8 -10
- package/dist/{node/esm → webapi}/lib/encrypt_key_management.js +26 -23
- package/dist/webapi/lib/get_sign_verify_key.js +12 -0
- package/dist/{node/esm → webapi}/lib/is_disjoint.js +1 -2
- package/dist/{browser → webapi}/lib/is_jwk.js +1 -1
- package/dist/webapi/lib/is_key_like.js +14 -0
- package/dist/{browser → webapi}/lib/is_object.js +2 -2
- package/dist/{node/esm → webapi}/lib/iv.js +1 -2
- package/dist/{browser/runtime → webapi/lib}/jwk_to_key.js +3 -13
- package/dist/webapi/lib/key_to_jwk.js +27 -0
- package/dist/webapi/lib/normalize_key.js +164 -0
- package/dist/webapi/lib/pbes2kw.js +37 -0
- package/dist/webapi/lib/rsaes.js +24 -0
- package/dist/{browser/runtime → webapi/lib}/sign.js +1 -3
- package/dist/{browser/runtime → webapi/lib}/subtle_dsa.js +4 -5
- package/dist/{browser → webapi}/lib/validate_algorithms.js +1 -2
- package/dist/{node/esm → webapi}/lib/validate_crit.js +3 -4
- package/dist/{browser/runtime → webapi/lib}/verify.js +1 -3
- package/dist/{node/esm → webapi}/util/base64url.js +1 -1
- package/package.json +36 -219
- package/dist/browser/jwe/compact/encrypt.js +0 -26
- package/dist/browser/jwe/flattened/decrypt.js +0 -161
- package/dist/browser/jwe/flattened/encrypt.js +0 -153
- package/dist/browser/jwe/general/encrypt.js +0 -174
- package/dist/browser/jwk/thumbprint.js +0 -53
- package/dist/browser/jwks/local.js +0 -124
- package/dist/browser/jwks/remote.js +0 -139
- package/dist/browser/jws/compact/sign.js +0 -17
- package/dist/browser/jws/flattened/sign.js +0 -81
- package/dist/browser/jws/general/sign.js +0 -67
- package/dist/browser/jwt/encrypt.js +0 -68
- package/dist/browser/jwt/produce.js +0 -75
- package/dist/browser/jwt/sign.js +0 -20
- package/dist/browser/key/export.js +0 -12
- package/dist/browser/key/generate_key_pair.js +0 -4
- package/dist/browser/key/generate_secret.js +0 -4
- package/dist/browser/lib/aesgcmkw.js +0 -16
- package/dist/browser/lib/check_key_type.js +0 -77
- package/dist/browser/lib/check_p2s.js +0 -6
- package/dist/browser/lib/crypto_key.js +0 -157
- package/dist/browser/lib/decrypt_key_management.js +0 -129
- package/dist/browser/lib/encrypt_key_management.js +0 -89
- package/dist/browser/lib/format_pem.js +0 -4
- package/dist/browser/lib/is_disjoint.js +0 -22
- package/dist/browser/lib/iv.js +0 -20
- package/dist/browser/lib/validate_crit.js +0 -34
- package/dist/browser/package.json +0 -1
- package/dist/browser/runtime/bogus.js +0 -6
- package/dist/browser/runtime/ecdhes.js +0 -47
- package/dist/browser/runtime/fetch_jwks.js +0 -34
- package/dist/browser/runtime/get_sign_verify_key.js +0 -24
- package/dist/browser/runtime/is_key_like.js +0 -8
- package/dist/browser/runtime/key_to_jwk.js +0 -21
- package/dist/browser/runtime/normalize_key.js +0 -68
- package/dist/browser/runtime/pbes2kw.js +0 -51
- package/dist/browser/runtime/random.js +0 -2
- package/dist/browser/runtime/rsaes.js +0 -37
- package/dist/browser/runtime/runtime.js +0 -1
- package/dist/browser/runtime/subtle_rsaes.js +0 -12
- package/dist/browser/runtime/timing_safe_equal.js +0 -19
- package/dist/browser/runtime/webcrypto.js +0 -2
- package/dist/browser/util/base64url.js +0 -3
- package/dist/browser/util/errors.js +0 -114
- package/dist/browser/util/runtime.js +0 -2
- package/dist/node/cjs/index.js +0 -69
- package/dist/node/cjs/jwe/compact/decrypt.js +0 -30
- package/dist/node/cjs/jwe/compact/encrypt.js +0 -31
- package/dist/node/cjs/jwe/flattened/decrypt.js +0 -164
- package/dist/node/cjs/jwe/flattened/encrypt.js +0 -165
- package/dist/node/cjs/jwe/general/decrypt.js +0 -34
- package/dist/node/cjs/jwe/general/encrypt.js +0 -186
- package/dist/node/cjs/jwk/embedded.js +0 -20
- package/dist/node/cjs/jwk/thumbprint.js +0 -57
- package/dist/node/cjs/jwks/local.js +0 -128
- package/dist/node/cjs/jwks/remote.js +0 -152
- package/dist/node/cjs/jws/compact/sign.js +0 -22
- package/dist/node/cjs/jws/compact/verify.js +0 -24
- package/dist/node/cjs/jws/flattened/sign.js +0 -88
- package/dist/node/cjs/jws/flattened/verify.js +0 -125
- package/dist/node/cjs/jws/general/sign.js +0 -77
- package/dist/node/cjs/jws/general/verify.js +0 -27
- package/dist/node/cjs/jwt/decrypt.js +0 -26
- package/dist/node/cjs/jwt/encrypt.js +0 -79
- package/dist/node/cjs/jwt/produce.js +0 -80
- package/dist/node/cjs/jwt/sign.js +0 -25
- package/dist/node/cjs/jwt/unsecured.js +0 -36
- package/dist/node/cjs/jwt/verify.js +0 -18
- package/dist/node/cjs/key/export.js +0 -17
- package/dist/node/cjs/key/generate_key_pair.js +0 -7
- package/dist/node/cjs/key/generate_secret.js +0 -7
- package/dist/node/cjs/key/import.js +0 -51
- package/dist/node/cjs/lib/aesgcmkw.js +0 -20
- package/dist/node/cjs/lib/buffer_utils.js +0 -60
- package/dist/node/cjs/lib/cek.js +0 -23
- package/dist/node/cjs/lib/check_iv_length.js +0 -10
- package/dist/node/cjs/lib/check_key_type.js +0 -80
- package/dist/node/cjs/lib/check_p2s.js +0 -9
- package/dist/node/cjs/lib/crypto_key.js +0 -161
- package/dist/node/cjs/lib/decrypt_key_management.js +0 -131
- package/dist/node/cjs/lib/encrypt_key_management.js +0 -91
- package/dist/node/cjs/lib/epoch.js +0 -3
- package/dist/node/cjs/lib/invalid_key_input.js +0 -34
- package/dist/node/cjs/lib/is_disjoint.js +0 -24
- package/dist/node/cjs/lib/is_jwk.js +0 -19
- package/dist/node/cjs/lib/is_object.js +0 -19
- package/dist/node/cjs/lib/iv.js +0 -23
- package/dist/node/cjs/lib/jwt_claims_set.js +0 -106
- package/dist/node/cjs/lib/private_symbols.js +0 -4
- package/dist/node/cjs/lib/secs.js +0 -57
- package/dist/node/cjs/lib/validate_algorithms.js +0 -13
- package/dist/node/cjs/lib/validate_crit.js +0 -36
- package/dist/node/cjs/runtime/aeskw.js +0 -55
- package/dist/node/cjs/runtime/asn1.js +0 -54
- package/dist/node/cjs/runtime/base64url.js +0 -20
- package/dist/node/cjs/runtime/cbc_tag.js +0 -11
- package/dist/node/cjs/runtime/check_cek_length.js +0 -37
- package/dist/node/cjs/runtime/check_key_length.js +0 -18
- package/dist/node/cjs/runtime/ciphers.js +0 -8
- package/dist/node/cjs/runtime/decrypt.js +0 -103
- package/dist/node/cjs/runtime/digest.js +0 -5
- package/dist/node/cjs/runtime/dsa_digest.js +0 -26
- package/dist/node/cjs/runtime/ecdhes.js +0 -70
- package/dist/node/cjs/runtime/encrypt.js +0 -80
- package/dist/node/cjs/runtime/fetch_jwks.js +0 -45
- package/dist/node/cjs/runtime/generate.js +0 -103
- package/dist/node/cjs/runtime/get_named_curve.js +0 -61
- package/dist/node/cjs/runtime/get_sign_verify_key.js +0 -31
- package/dist/node/cjs/runtime/hmac_digest.js +0 -16
- package/dist/node/cjs/runtime/is_key_like.js +0 -11
- package/dist/node/cjs/runtime/is_key_object.js +0 -4
- package/dist/node/cjs/runtime/jwk_to_key.js +0 -10
- package/dist/node/cjs/runtime/key_to_jwk.js +0 -36
- package/dist/node/cjs/runtime/node_key.js +0 -111
- package/dist/node/cjs/runtime/normalize_key.js +0 -3
- package/dist/node/cjs/runtime/pbes2kw.js +0 -48
- package/dist/node/cjs/runtime/random.js +0 -5
- package/dist/node/cjs/runtime/rsaes.js +0 -71
- package/dist/node/cjs/runtime/runtime.js +0 -3
- package/dist/node/cjs/runtime/sign.js +0 -19
- package/dist/node/cjs/runtime/timing_safe_equal.js +0 -5
- package/dist/node/cjs/runtime/verify.js +0 -31
- package/dist/node/cjs/runtime/webcrypto.js +0 -9
- package/dist/node/cjs/util/base64url.js +0 -6
- package/dist/node/cjs/util/decode_jwt.js +0 -35
- package/dist/node/cjs/util/decode_protected_header.js +0 -37
- package/dist/node/cjs/util/errors.js +0 -117
- package/dist/node/cjs/util/runtime.js +0 -4
- package/dist/node/esm/index.js +0 -30
- package/dist/node/esm/jwe/compact/decrypt.js +0 -27
- package/dist/node/esm/jwe/general/decrypt.js +0 -31
- package/dist/node/esm/jwk/embedded.js +0 -17
- package/dist/node/esm/jws/compact/verify.js +0 -21
- package/dist/node/esm/jws/flattened/verify.js +0 -122
- package/dist/node/esm/jws/general/verify.js +0 -24
- package/dist/node/esm/jwt/decrypt.js +0 -23
- package/dist/node/esm/jwt/unsecured.js +0 -32
- package/dist/node/esm/jwt/verify.js +0 -15
- package/dist/node/esm/key/generate_key_pair.js +0 -4
- package/dist/node/esm/key/generate_secret.js +0 -4
- package/dist/node/esm/key/import.js +0 -45
- package/dist/node/esm/lib/buffer_utils.js +0 -51
- package/dist/node/esm/lib/cek.js +0 -20
- package/dist/node/esm/lib/check_iv_length.js +0 -8
- package/dist/node/esm/lib/check_key_type.js +0 -77
- package/dist/node/esm/lib/check_p2s.js +0 -6
- package/dist/node/esm/lib/epoch.js +0 -1
- package/dist/node/esm/lib/invalid_key_input.js +0 -31
- package/dist/node/esm/lib/is_jwk.js +0 -13
- package/dist/node/esm/lib/is_object.js +0 -16
- package/dist/node/esm/lib/jwt_claims_set.js +0 -104
- package/dist/node/esm/lib/private_symbols.js +0 -1
- package/dist/node/esm/lib/secs.js +0 -55
- package/dist/node/esm/lib/validate_algorithms.js +0 -11
- package/dist/node/esm/package.json +0 -1
- package/dist/node/esm/runtime/aeskw.js +0 -50
- package/dist/node/esm/runtime/asn1.js +0 -46
- package/dist/node/esm/runtime/base64url.js +0 -14
- package/dist/node/esm/runtime/cbc_tag.js +0 -8
- package/dist/node/esm/runtime/check_cek_length.js +0 -35
- package/dist/node/esm/runtime/check_key_length.js +0 -16
- package/dist/node/esm/runtime/ciphers.js +0 -6
- package/dist/node/esm/runtime/decrypt.js +0 -101
- package/dist/node/esm/runtime/digest.js +0 -3
- package/dist/node/esm/runtime/dsa_digest.js +0 -23
- package/dist/node/esm/runtime/ecdhes.js +0 -64
- package/dist/node/esm/runtime/encrypt.js +0 -78
- package/dist/node/esm/runtime/fetch_jwks.js +0 -43
- package/dist/node/esm/runtime/generate.js +0 -99
- package/dist/node/esm/runtime/get_named_curve.js +0 -58
- package/dist/node/esm/runtime/get_sign_verify_key.js +0 -28
- package/dist/node/esm/runtime/hmac_digest.js +0 -13
- package/dist/node/esm/runtime/is_key_like.js +0 -8
- package/dist/node/esm/runtime/is_key_object.js +0 -2
- package/dist/node/esm/runtime/jwk_to_key.js +0 -8
- package/dist/node/esm/runtime/key_to_jwk.js +0 -34
- package/dist/node/esm/runtime/node_key.js +0 -108
- package/dist/node/esm/runtime/normalize_key.js +0 -1
- package/dist/node/esm/runtime/pbes2kw.js +0 -43
- package/dist/node/esm/runtime/random.js +0 -1
- package/dist/node/esm/runtime/rsaes.js +0 -66
- package/dist/node/esm/runtime/runtime.js +0 -1
- package/dist/node/esm/runtime/sign.js +0 -17
- package/dist/node/esm/runtime/timing_safe_equal.js +0 -3
- package/dist/node/esm/runtime/verify.js +0 -29
- package/dist/node/esm/runtime/webcrypto.js +0 -5
- package/dist/node/esm/util/decode_jwt.js +0 -32
- package/dist/node/esm/util/decode_protected_header.js +0 -34
- package/dist/node/esm/util/runtime.js +0 -2
- package/dist/types/util/runtime.d.ts +0 -3
- /package/dist/{browser → webapi}/jwe/compact/decrypt.js +0 -0
- /package/dist/{node/esm → webapi}/jwe/compact/encrypt.js +0 -0
- /package/dist/{browser → webapi}/jwe/general/decrypt.js +0 -0
- /package/dist/{browser → webapi}/jwk/embedded.js +0 -0
- /package/dist/{node/esm → webapi}/jws/compact/sign.js +0 -0
- /package/dist/{browser → webapi}/jws/compact/verify.js +0 -0
- /package/dist/{node/esm → webapi}/jws/general/sign.js +0 -0
- /package/dist/{browser → webapi}/jws/general/verify.js +0 -0
- /package/dist/{browser → webapi}/jwt/decrypt.js +0 -0
- /package/dist/{node/esm → webapi}/jwt/encrypt.js +0 -0
- /package/dist/{node/esm → webapi}/jwt/produce.js +0 -0
- /package/dist/{node/esm → webapi}/jwt/sign.js +0 -0
- /package/dist/{browser → webapi}/jwt/verify.js +0 -0
- /package/dist/{browser/runtime → webapi/lib}/check_key_length.js +0 -0
- /package/dist/{browser → webapi}/lib/epoch.js +0 -0
- /package/dist/{browser → webapi}/lib/invalid_key_input.js +0 -0
- /package/dist/{browser → webapi}/lib/jwt_claims_set.js +0 -0
- /package/dist/{browser → webapi}/lib/private_symbols.js +0 -0
- /package/dist/{browser → webapi}/lib/secs.js +0 -0
- /package/dist/{browser → webapi}/util/decode_jwt.js +0 -0
- /package/dist/{browser → webapi}/util/decode_protected_header.js +0 -0
- /package/dist/{node/esm → webapi}/util/errors.js +0 -0
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { encode as base64url } from '../../
|
|
1
|
+
import { encode as base64url } from '../../lib/base64url.js';
|
|
2
2
|
import { unprotected } from '../../lib/private_symbols.js';
|
|
3
|
-
import encrypt from '../../
|
|
3
|
+
import encrypt from '../../lib/encrypt.js';
|
|
4
4
|
import encryptKeyManagement from '../../lib/encrypt_key_management.js';
|
|
5
5
|
import { JOSENotSupported, JWEInvalid } from '../../util/errors.js';
|
|
6
6
|
import isDisjoint from '../../lib/is_disjoint.js';
|
|
7
7
|
import { encoder, decoder, concat } from '../../lib/buffer_utils.js';
|
|
8
8
|
import validateCrit from '../../lib/validate_crit.js';
|
|
9
|
+
import normalizeKey from '../../lib/normalize_key.js';
|
|
10
|
+
import checkKeyType from '../../lib/check_key_type.js';
|
|
9
11
|
export class FlattenedEncrypt {
|
|
10
12
|
_plaintext;
|
|
11
13
|
_protectedHeader;
|
|
@@ -94,10 +96,12 @@ export class FlattenedEncrypt {
|
|
|
94
96
|
if (this._cek && (alg === 'dir' || alg === 'ECDH-ES')) {
|
|
95
97
|
throw new TypeError(`setContentEncryptionKey cannot be called with JWE "alg" (Algorithm) Header ${alg}`);
|
|
96
98
|
}
|
|
99
|
+
checkKeyType(alg === 'dir' ? enc : alg, key, 'encrypt');
|
|
97
100
|
let cek;
|
|
98
101
|
{
|
|
99
102
|
let parameters;
|
|
100
|
-
|
|
103
|
+
const k = await normalizeKey(key, alg);
|
|
104
|
+
({ cek, encryptedKey, parameters } = await encryptKeyManagement(alg, enc, k, this._cek, this._keyManagementParameters));
|
|
101
105
|
if (parameters) {
|
|
102
106
|
if (options && unprotected in options) {
|
|
103
107
|
if (!this._unprotectedHeader) {
|
|
@@ -4,8 +4,10 @@ import { JOSENotSupported, JWEInvalid } from '../../util/errors.js';
|
|
|
4
4
|
import generateCek from '../../lib/cek.js';
|
|
5
5
|
import isDisjoint from '../../lib/is_disjoint.js';
|
|
6
6
|
import encryptKeyManagement from '../../lib/encrypt_key_management.js';
|
|
7
|
-
import { encode as base64url } from '../../
|
|
7
|
+
import { encode as base64url } from '../../lib/base64url.js';
|
|
8
8
|
import validateCrit from '../../lib/validate_crit.js';
|
|
9
|
+
import normalizeKey from '../../lib/normalize_key.js';
|
|
10
|
+
import checkKeyType from '../../lib/check_key_type.js';
|
|
9
11
|
class IndividualRecipient {
|
|
10
12
|
parent;
|
|
11
13
|
unprotectedHeader;
|
|
@@ -170,9 +172,12 @@ export class GeneralEncrypt {
|
|
|
170
172
|
target.header = flattened.header;
|
|
171
173
|
continue;
|
|
172
174
|
}
|
|
173
|
-
const
|
|
175
|
+
const alg = recipient.unprotectedHeader?.alg ||
|
|
174
176
|
this._protectedHeader?.alg ||
|
|
175
|
-
this._unprotectedHeader?.alg
|
|
177
|
+
this._unprotectedHeader?.alg;
|
|
178
|
+
checkKeyType(alg === 'dir' ? enc : alg, recipient.key, 'encrypt');
|
|
179
|
+
const k = await normalizeKey(recipient.key, alg);
|
|
180
|
+
const { encryptedKey, parameters } = await encryptKeyManagement(alg, enc, k, cek, { p2c });
|
|
176
181
|
target.encrypted_key = base64url(encryptedKey);
|
|
177
182
|
if (recipient.unprotectedHeader || parameters)
|
|
178
183
|
target.header = { ...recipient.unprotectedHeader, ...parameters };
|
|
@@ -1,16 +1,26 @@
|
|
|
1
|
-
import digest from '../
|
|
2
|
-
import { encode as base64url } from '../
|
|
1
|
+
import digest from '../lib/digest.js';
|
|
2
|
+
import { encode as base64url } from '../lib/base64url.js';
|
|
3
3
|
import { JOSENotSupported, JWKInvalid } from '../util/errors.js';
|
|
4
4
|
import { encoder } from '../lib/buffer_utils.js';
|
|
5
|
-
import
|
|
5
|
+
import isKeyLike from '../lib/is_key_like.js';
|
|
6
|
+
import { isJWK } from '../lib/is_jwk.js';
|
|
7
|
+
import { exportJWK } from '../key/export.js';
|
|
8
|
+
import invalidKeyInput from '../lib/invalid_key_input.js';
|
|
6
9
|
const check = (value, description) => {
|
|
7
10
|
if (typeof value !== 'string' || !value) {
|
|
8
11
|
throw new JWKInvalid(`${description} missing or invalid`);
|
|
9
12
|
}
|
|
10
13
|
};
|
|
11
|
-
export async function calculateJwkThumbprint(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
export async function calculateJwkThumbprint(key, digestAlgorithm) {
|
|
15
|
+
let jwk;
|
|
16
|
+
if (isJWK(key)) {
|
|
17
|
+
jwk = key;
|
|
18
|
+
}
|
|
19
|
+
else if (isKeyLike(key)) {
|
|
20
|
+
jwk = await exportJWK(key);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
throw new TypeError(invalidKeyInput(key, 'CryptoKey', 'KeyObject', 'JSON Web Key'));
|
|
14
24
|
}
|
|
15
25
|
digestAlgorithm ??= 'sha256';
|
|
16
26
|
if (digestAlgorithm !== 'sha256' &&
|
|
@@ -46,8 +56,8 @@ export async function calculateJwkThumbprint(jwk, digestAlgorithm) {
|
|
|
46
56
|
const data = encoder.encode(JSON.stringify(components));
|
|
47
57
|
return base64url(await digest(digestAlgorithm, data));
|
|
48
58
|
}
|
|
49
|
-
export async function calculateJwkThumbprintUri(
|
|
59
|
+
export async function calculateJwkThumbprintUri(key, digestAlgorithm) {
|
|
50
60
|
digestAlgorithm ??= 'sha256';
|
|
51
|
-
const thumbprint = await calculateJwkThumbprint(
|
|
61
|
+
const thumbprint = await calculateJwkThumbprint(key, digestAlgorithm);
|
|
52
62
|
return `urn:ietf:params:oauth:jwk-thumbprint:sha-${digestAlgorithm.slice(-3)}:${thumbprint}`;
|
|
53
63
|
}
|
|
@@ -60,9 +60,6 @@ class LocalJWKSet {
|
|
|
60
60
|
case 'ES256':
|
|
61
61
|
candidate = jwk.crv === 'P-256';
|
|
62
62
|
break;
|
|
63
|
-
case 'ES256K':
|
|
64
|
-
candidate = jwk.crv === 'secp256k1';
|
|
65
|
-
break;
|
|
66
63
|
case 'ES384':
|
|
67
64
|
candidate = jwk.crv === 'P-384';
|
|
68
65
|
break;
|
|
@@ -70,10 +67,8 @@ class LocalJWKSet {
|
|
|
70
67
|
candidate = jwk.crv === 'P-521';
|
|
71
68
|
break;
|
|
72
69
|
case 'Ed25519':
|
|
73
|
-
candidate = jwk.crv === 'Ed25519';
|
|
74
|
-
break;
|
|
75
70
|
case 'EdDSA':
|
|
76
|
-
candidate = jwk.crv === 'Ed25519'
|
|
71
|
+
candidate = jwk.crv === 'Ed25519';
|
|
77
72
|
break;
|
|
78
73
|
}
|
|
79
74
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { JWKSNoMatchingKey } from '../util/errors.js';
|
|
1
|
+
import { JOSEError, JWKSNoMatchingKey, JWKSTimeout } from '../util/errors.js';
|
|
3
2
|
import { createLocalJWKSet } from './local.js';
|
|
4
3
|
import isObject from '../lib/is_object.js';
|
|
5
4
|
function isCloudflareWorkers() {
|
|
@@ -10,9 +9,32 @@ function isCloudflareWorkers() {
|
|
|
10
9
|
let USER_AGENT;
|
|
11
10
|
if (typeof navigator === 'undefined' || !navigator.userAgent?.startsWith?.('Mozilla/5.0 ')) {
|
|
12
11
|
const NAME = 'jose';
|
|
13
|
-
const VERSION = '
|
|
12
|
+
const VERSION = 'v6.0.0';
|
|
14
13
|
USER_AGENT = `${NAME}/${VERSION}`;
|
|
15
14
|
}
|
|
15
|
+
export const customFetch = Symbol();
|
|
16
|
+
async function fetchJwks(url, options) {
|
|
17
|
+
const response = await (options?.[customFetch] || fetch)(url, {
|
|
18
|
+
method: 'GET',
|
|
19
|
+
signal: options.signal,
|
|
20
|
+
redirect: 'manual',
|
|
21
|
+
headers: options.headers,
|
|
22
|
+
}).catch((err) => {
|
|
23
|
+
if (err.name === 'TimeoutError') {
|
|
24
|
+
throw new JWKSTimeout();
|
|
25
|
+
}
|
|
26
|
+
throw err;
|
|
27
|
+
});
|
|
28
|
+
if (response.status !== 200) {
|
|
29
|
+
throw new JOSEError('Expected 200 OK from the JSON Web Key Set HTTP response');
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
return await response.json();
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
throw new JOSEError('Failed to parse the JSON Web Key Set HTTP response as JSON');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
16
38
|
export const jwksCache = Symbol();
|
|
17
39
|
function isFreshJwksCache(input, cacheMaxAge) {
|
|
18
40
|
if (typeof input !== 'object' || input === null) {
|
|
@@ -44,7 +66,7 @@ class RemoteJWKSet {
|
|
|
44
66
|
throw new TypeError('url must be an instance of URL');
|
|
45
67
|
}
|
|
46
68
|
this._url = new URL(url.href);
|
|
47
|
-
this._options = {
|
|
69
|
+
this._options = { headers: options?.headers };
|
|
48
70
|
this._timeoutDuration =
|
|
49
71
|
typeof options?.timeoutDuration === 'number' ? options?.timeoutDuration : 5000;
|
|
50
72
|
this._cooldownDuration =
|
|
@@ -94,7 +116,14 @@ class RemoteJWKSet {
|
|
|
94
116
|
headers.set('User-Agent', USER_AGENT);
|
|
95
117
|
this._options.headers = Object.fromEntries(headers.entries());
|
|
96
118
|
}
|
|
97
|
-
|
|
119
|
+
if (!headers.has('accept')) {
|
|
120
|
+
headers.set('accept', 'application/json');
|
|
121
|
+
headers.append('accept', 'application/jwk-set+json');
|
|
122
|
+
}
|
|
123
|
+
this._pendingFetch ||= fetchJwks(this._url.href, {
|
|
124
|
+
headers,
|
|
125
|
+
signal: AbortSignal.timeout(this._timeoutDuration),
|
|
126
|
+
})
|
|
98
127
|
.then((json) => {
|
|
99
128
|
this._local = createLocalJWKSet(json);
|
|
100
129
|
if (this._cache) {
|
|
@@ -145,4 +174,3 @@ export function createRemoteJWKSet(url, options) {
|
|
|
145
174
|
});
|
|
146
175
|
return remoteJWKSet;
|
|
147
176
|
}
|
|
148
|
-
export const experimental_jwksCache = jwksCache;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { encode as base64url } from '../../
|
|
2
|
-
import sign from '../../
|
|
1
|
+
import { encode as base64url } from '../../lib/base64url.js';
|
|
2
|
+
import sign from '../../lib/sign.js';
|
|
3
3
|
import isDisjoint from '../../lib/is_disjoint.js';
|
|
4
4
|
import { JWSInvalid } from '../../util/errors.js';
|
|
5
5
|
import { encoder, decoder, concat } from '../../lib/buffer_utils.js';
|
|
6
|
-
import
|
|
6
|
+
import checkKeyType from '../../lib/check_key_type.js';
|
|
7
7
|
import validateCrit from '../../lib/validate_crit.js';
|
|
8
|
+
import normalizeKey from '../../lib/normalize_key.js';
|
|
8
9
|
export class FlattenedSign {
|
|
9
10
|
_payload;
|
|
10
11
|
_protectedHeader;
|
|
@@ -52,7 +53,7 @@ export class FlattenedSign {
|
|
|
52
53
|
if (typeof alg !== 'string' || !alg) {
|
|
53
54
|
throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
|
|
54
55
|
}
|
|
55
|
-
|
|
56
|
+
checkKeyType(alg, key, 'sign');
|
|
56
57
|
let payload = this._payload;
|
|
57
58
|
if (b64) {
|
|
58
59
|
payload = encoder.encode(base64url(payload));
|
|
@@ -65,7 +66,8 @@ export class FlattenedSign {
|
|
|
65
66
|
protectedHeader = encoder.encode('');
|
|
66
67
|
}
|
|
67
68
|
const data = concat(protectedHeader, encoder.encode('.'), payload);
|
|
68
|
-
const
|
|
69
|
+
const k = await normalizeKey(key, alg);
|
|
70
|
+
const signature = await sign(alg, k, data);
|
|
69
71
|
const jws = {
|
|
70
72
|
signature: base64url(signature),
|
|
71
73
|
payload: '',
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { decode as base64url } from '../../
|
|
2
|
-
import verify from '../../
|
|
1
|
+
import { decode as base64url } from '../../lib/base64url.js';
|
|
2
|
+
import verify from '../../lib/verify.js';
|
|
3
3
|
import { JOSEAlgNotAllowed, JWSInvalid, JWSSignatureVerificationFailed } from '../../util/errors.js';
|
|
4
4
|
import { concat, encoder, decoder } from '../../lib/buffer_utils.js';
|
|
5
5
|
import isDisjoint from '../../lib/is_disjoint.js';
|
|
6
6
|
import isObject from '../../lib/is_object.js';
|
|
7
|
-
import
|
|
7
|
+
import checkKeyType from '../../lib/check_key_type.js';
|
|
8
8
|
import validateCrit from '../../lib/validate_crit.js';
|
|
9
9
|
import validateAlgorithms from '../../lib/validate_algorithms.js';
|
|
10
|
-
import
|
|
11
|
-
import { importJWK } from '../../key/import.js';
|
|
10
|
+
import normalizeKey from '../../lib/normalize_key.js';
|
|
12
11
|
export async function flattenedVerify(jws, key, options) {
|
|
13
12
|
if (!isObject(jws)) {
|
|
14
13
|
throw new JWSInvalid('Flattened JWS must be an object');
|
|
@@ -73,14 +72,8 @@ export async function flattenedVerify(jws, key, options) {
|
|
|
73
72
|
if (typeof key === 'function') {
|
|
74
73
|
key = await key(parsedProt, jws);
|
|
75
74
|
resolvedKey = true;
|
|
76
|
-
checkKeyTypeWithJwk(alg, key, 'verify');
|
|
77
|
-
if (isJWK(key)) {
|
|
78
|
-
key = await importJWK(key, alg);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
checkKeyTypeWithJwk(alg, key, 'verify');
|
|
83
75
|
}
|
|
76
|
+
checkKeyType(alg, key, 'verify');
|
|
84
77
|
const data = concat(encoder.encode(jws.protected ?? ''), encoder.encode('.'), typeof jws.payload === 'string' ? encoder.encode(jws.payload) : jws.payload);
|
|
85
78
|
let signature;
|
|
86
79
|
try {
|
|
@@ -89,7 +82,8 @@ export async function flattenedVerify(jws, key, options) {
|
|
|
89
82
|
catch {
|
|
90
83
|
throw new JWSInvalid('Failed to base64url decode the signature');
|
|
91
84
|
}
|
|
92
|
-
const
|
|
85
|
+
const k = await normalizeKey(key, alg);
|
|
86
|
+
const verified = await verify(alg, k, signature, data);
|
|
93
87
|
if (!verified) {
|
|
94
88
|
throw new JWSSignatureVerificationFailed();
|
|
95
89
|
}
|
|
@@ -116,7 +110,7 @@ export async function flattenedVerify(jws, key, options) {
|
|
|
116
110
|
result.unprotectedHeader = jws.header;
|
|
117
111
|
}
|
|
118
112
|
if (resolvedKey) {
|
|
119
|
-
return { ...result, key };
|
|
113
|
+
return { ...result, key: k };
|
|
120
114
|
}
|
|
121
115
|
return result;
|
|
122
116
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { toSPKI as exportPublic } from '../
|
|
2
|
-
import
|
|
3
|
-
import keyToJWK from '../runtime/key_to_jwk.js';
|
|
1
|
+
import { toSPKI as exportPublic, toPKCS8 as exportPrivate } from '../lib/asn1.js';
|
|
2
|
+
import keyToJWK from '../lib/key_to_jwk.js';
|
|
4
3
|
export async function exportSPKI(key) {
|
|
5
4
|
return exportPublic(key);
|
|
6
5
|
}
|
|
@@ -1,45 +1,4 @@
|
|
|
1
|
-
import crypto from './webcrypto.js';
|
|
2
1
|
import { JOSENotSupported } from '../util/errors.js';
|
|
3
|
-
import random from './random.js';
|
|
4
|
-
export async function generateSecret(alg, options) {
|
|
5
|
-
let length;
|
|
6
|
-
let algorithm;
|
|
7
|
-
let keyUsages;
|
|
8
|
-
switch (alg) {
|
|
9
|
-
case 'HS256':
|
|
10
|
-
case 'HS384':
|
|
11
|
-
case 'HS512':
|
|
12
|
-
length = parseInt(alg.slice(-3), 10);
|
|
13
|
-
algorithm = { name: 'HMAC', hash: `SHA-${length}`, length };
|
|
14
|
-
keyUsages = ['sign', 'verify'];
|
|
15
|
-
break;
|
|
16
|
-
case 'A128CBC-HS256':
|
|
17
|
-
case 'A192CBC-HS384':
|
|
18
|
-
case 'A256CBC-HS512':
|
|
19
|
-
length = parseInt(alg.slice(-3), 10);
|
|
20
|
-
return random(new Uint8Array(length >> 3));
|
|
21
|
-
case 'A128KW':
|
|
22
|
-
case 'A192KW':
|
|
23
|
-
case 'A256KW':
|
|
24
|
-
length = parseInt(alg.slice(1, 4), 10);
|
|
25
|
-
algorithm = { name: 'AES-KW', length };
|
|
26
|
-
keyUsages = ['wrapKey', 'unwrapKey'];
|
|
27
|
-
break;
|
|
28
|
-
case 'A128GCMKW':
|
|
29
|
-
case 'A192GCMKW':
|
|
30
|
-
case 'A256GCMKW':
|
|
31
|
-
case 'A128GCM':
|
|
32
|
-
case 'A192GCM':
|
|
33
|
-
case 'A256GCM':
|
|
34
|
-
length = parseInt(alg.slice(1, 4), 10);
|
|
35
|
-
algorithm = { name: 'AES-GCM', length };
|
|
36
|
-
keyUsages = ['encrypt', 'decrypt'];
|
|
37
|
-
break;
|
|
38
|
-
default:
|
|
39
|
-
throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
|
|
40
|
-
}
|
|
41
|
-
return crypto.subtle.generateKey(algorithm, options?.extractable ?? false, keyUsages);
|
|
42
|
-
}
|
|
43
2
|
function getModulusLengthOption(options) {
|
|
44
3
|
const modulusLength = options?.modulusLength ?? 2048;
|
|
45
4
|
if (typeof modulusLength !== 'number' || modulusLength < 2048) {
|
|
@@ -98,27 +57,16 @@ export async function generateKeyPair(alg, options) {
|
|
|
98
57
|
keyUsages = ['sign', 'verify'];
|
|
99
58
|
break;
|
|
100
59
|
case 'Ed25519':
|
|
101
|
-
algorithm = { name: 'Ed25519' };
|
|
102
|
-
keyUsages = ['sign', 'verify'];
|
|
103
|
-
break;
|
|
104
60
|
case 'EdDSA': {
|
|
105
61
|
keyUsages = ['sign', 'verify'];
|
|
106
|
-
|
|
107
|
-
switch (crv) {
|
|
108
|
-
case 'Ed25519':
|
|
109
|
-
case 'Ed448':
|
|
110
|
-
algorithm = { name: crv };
|
|
111
|
-
break;
|
|
112
|
-
default:
|
|
113
|
-
throw new JOSENotSupported('Invalid or unsupported crv option provided');
|
|
114
|
-
}
|
|
62
|
+
algorithm = { name: 'Ed25519' };
|
|
115
63
|
break;
|
|
116
64
|
}
|
|
117
65
|
case 'ECDH-ES':
|
|
118
66
|
case 'ECDH-ES+A128KW':
|
|
119
67
|
case 'ECDH-ES+A192KW':
|
|
120
68
|
case 'ECDH-ES+A256KW': {
|
|
121
|
-
keyUsages = ['
|
|
69
|
+
keyUsages = ['deriveBits'];
|
|
122
70
|
const crv = options?.crv ?? 'P-256';
|
|
123
71
|
switch (crv) {
|
|
124
72
|
case 'P-256':
|
|
@@ -128,11 +76,10 @@ export async function generateKeyPair(alg, options) {
|
|
|
128
76
|
break;
|
|
129
77
|
}
|
|
130
78
|
case 'X25519':
|
|
131
|
-
|
|
132
|
-
algorithm = { name: crv };
|
|
79
|
+
algorithm = { name: 'X25519' };
|
|
133
80
|
break;
|
|
134
81
|
default:
|
|
135
|
-
throw new JOSENotSupported('Invalid or unsupported crv option provided, supported values are P-256, P-384, P-521,
|
|
82
|
+
throw new JOSENotSupported('Invalid or unsupported crv option provided, supported values are P-256, P-384, P-521, and X25519');
|
|
136
83
|
}
|
|
137
84
|
break;
|
|
138
85
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { JOSENotSupported } from '../util/errors.js';
|
|
2
|
+
export async function generateSecret(alg, options) {
|
|
3
|
+
let length;
|
|
4
|
+
let algorithm;
|
|
5
|
+
let keyUsages;
|
|
6
|
+
switch (alg) {
|
|
7
|
+
case 'HS256':
|
|
8
|
+
case 'HS384':
|
|
9
|
+
case 'HS512':
|
|
10
|
+
length = parseInt(alg.slice(-3), 10);
|
|
11
|
+
algorithm = { name: 'HMAC', hash: `SHA-${length}`, length };
|
|
12
|
+
keyUsages = ['sign', 'verify'];
|
|
13
|
+
break;
|
|
14
|
+
case 'A128CBC-HS256':
|
|
15
|
+
case 'A192CBC-HS384':
|
|
16
|
+
case 'A256CBC-HS512':
|
|
17
|
+
length = parseInt(alg.slice(-3), 10);
|
|
18
|
+
return crypto.getRandomValues(new Uint8Array(length >> 3));
|
|
19
|
+
case 'A128KW':
|
|
20
|
+
case 'A192KW':
|
|
21
|
+
case 'A256KW':
|
|
22
|
+
length = parseInt(alg.slice(1, 4), 10);
|
|
23
|
+
algorithm = { name: 'AES-KW', length };
|
|
24
|
+
keyUsages = ['wrapKey', 'unwrapKey'];
|
|
25
|
+
break;
|
|
26
|
+
case 'A128GCMKW':
|
|
27
|
+
case 'A192GCMKW':
|
|
28
|
+
case 'A256GCMKW':
|
|
29
|
+
case 'A128GCM':
|
|
30
|
+
case 'A192GCM':
|
|
31
|
+
case 'A256GCM':
|
|
32
|
+
length = parseInt(alg.slice(1, 4), 10);
|
|
33
|
+
algorithm = { name: 'AES-GCM', length };
|
|
34
|
+
keyUsages = ['encrypt', 'decrypt'];
|
|
35
|
+
break;
|
|
36
|
+
default:
|
|
37
|
+
throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
|
|
38
|
+
}
|
|
39
|
+
return crypto.subtle.generateKey(algorithm, options?.extractable ?? false, keyUsages);
|
|
40
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { decode as decodeBase64URL } from '../
|
|
2
|
-
import { fromSPKI, fromPKCS8, fromX509 } from '../
|
|
3
|
-
import
|
|
1
|
+
import { decode as decodeBase64URL } from '../lib/base64url.js';
|
|
2
|
+
import { fromSPKI, fromPKCS8, fromX509 } from '../lib/asn1.js';
|
|
3
|
+
import toCryptoKey from '../lib/jwk_to_key.js';
|
|
4
4
|
import { JOSENotSupported } from '../util/errors.js';
|
|
5
5
|
import isObject from '../lib/is_object.js';
|
|
6
6
|
export async function importSPKI(spki, alg, options) {
|
|
@@ -21,11 +21,13 @@ export async function importPKCS8(pkcs8, alg, options) {
|
|
|
21
21
|
}
|
|
22
22
|
return fromPKCS8(pkcs8, alg, options);
|
|
23
23
|
}
|
|
24
|
-
export async function importJWK(jwk, alg) {
|
|
24
|
+
export async function importJWK(jwk, alg, options) {
|
|
25
25
|
if (!isObject(jwk)) {
|
|
26
26
|
throw new TypeError('JWK must be an object');
|
|
27
27
|
}
|
|
28
|
-
|
|
28
|
+
let ext;
|
|
29
|
+
alg ??= jwk.alg;
|
|
30
|
+
ext ??= options?.extractable ?? jwk.ext;
|
|
29
31
|
switch (jwk.kty) {
|
|
30
32
|
case 'oct':
|
|
31
33
|
if (typeof jwk.k !== 'string' || !jwk.k) {
|
|
@@ -38,7 +40,7 @@ export async function importJWK(jwk, alg) {
|
|
|
38
40
|
}
|
|
39
41
|
case 'EC':
|
|
40
42
|
case 'OKP':
|
|
41
|
-
return
|
|
43
|
+
return toCryptoKey({ ...jwk, alg, ext });
|
|
42
44
|
default:
|
|
43
45
|
throw new JOSENotSupported('Unsupported "kty" (Key Type) Parameter value');
|
|
44
46
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import encrypt from '
|
|
2
|
-
import decrypt from '
|
|
3
|
-
import { encode as base64url } from '../
|
|
1
|
+
import encrypt from './encrypt.js';
|
|
2
|
+
import decrypt from './decrypt.js';
|
|
3
|
+
import { encode as base64url } from '../lib/base64url.js';
|
|
4
4
|
export async function wrap(alg, key, cek, iv) {
|
|
5
5
|
const jweAlgorithm = alg.slice(0, 7);
|
|
6
6
|
const wrapped = await encrypt(jweAlgorithm, cek, key, iv, new Uint8Array(0));
|
|
@@ -1,32 +1,25 @@
|
|
|
1
|
-
import
|
|
2
|
-
import crypto, { isCryptoKey } from './webcrypto.js';
|
|
3
|
-
import { checkEncCryptoKey } from '../lib/crypto_key.js';
|
|
4
|
-
import invalidKeyInput from '../lib/invalid_key_input.js';
|
|
5
|
-
import { types } from './is_key_like.js';
|
|
1
|
+
import { checkEncCryptoKey } from './crypto_key.js';
|
|
6
2
|
function checkKeySize(key, alg) {
|
|
7
3
|
if (key.algorithm.length !== parseInt(alg.slice(1, 4), 10)) {
|
|
8
4
|
throw new TypeError(`Invalid key size for alg: ${alg}`);
|
|
9
5
|
}
|
|
10
6
|
}
|
|
11
7
|
function getCryptoKey(key, alg, usage) {
|
|
12
|
-
if (isCryptoKey(key)) {
|
|
13
|
-
checkEncCryptoKey(key, alg, usage);
|
|
14
|
-
return key;
|
|
15
|
-
}
|
|
16
8
|
if (key instanceof Uint8Array) {
|
|
17
9
|
return crypto.subtle.importKey('raw', key, 'AES-KW', true, [usage]);
|
|
18
10
|
}
|
|
19
|
-
|
|
11
|
+
checkEncCryptoKey(key, alg, usage);
|
|
12
|
+
return key;
|
|
20
13
|
}
|
|
21
|
-
export
|
|
14
|
+
export async function wrap(alg, key, cek) {
|
|
22
15
|
const cryptoKey = await getCryptoKey(key, alg, 'wrapKey');
|
|
23
16
|
checkKeySize(cryptoKey, alg);
|
|
24
|
-
const cryptoKeyCek = await crypto.subtle.importKey('raw', cek,
|
|
17
|
+
const cryptoKeyCek = await crypto.subtle.importKey('raw', cek, { hash: 'SHA-256', name: 'HMAC' }, true, ['sign']);
|
|
25
18
|
return new Uint8Array(await crypto.subtle.wrapKey('raw', cryptoKeyCek, cryptoKey, 'AES-KW'));
|
|
26
|
-
}
|
|
27
|
-
export
|
|
19
|
+
}
|
|
20
|
+
export async function unwrap(alg, key, encryptedKey) {
|
|
28
21
|
const cryptoKey = await getCryptoKey(key, alg, 'unwrapKey');
|
|
29
22
|
checkKeySize(cryptoKey, alg);
|
|
30
|
-
const cryptoKeyCek = await crypto.subtle.unwrapKey('raw', encryptedKey, cryptoKey, 'AES-KW',
|
|
23
|
+
const cryptoKeyCek = await crypto.subtle.unwrapKey('raw', encryptedKey, cryptoKey, 'AES-KW', { hash: 'SHA-256', name: 'HMAC' }, true, ['sign']);
|
|
31
24
|
return new Uint8Array(await crypto.subtle.exportKey('raw', cryptoKeyCek));
|
|
32
|
-
}
|
|
25
|
+
}
|
|
@@ -1,12 +1,20 @@
|
|
|
1
|
-
import
|
|
2
|
-
import invalidKeyInput from '../lib/invalid_key_input.js';
|
|
1
|
+
import invalidKeyInput from './invalid_key_input.js';
|
|
3
2
|
import { encodeBase64, decodeBase64 } from './base64url.js';
|
|
4
|
-
import formatPEM from '../lib/format_pem.js';
|
|
5
3
|
import { JOSENotSupported } from '../util/errors.js';
|
|
6
|
-
import {
|
|
4
|
+
import { isCryptoKey, isKeyObject } from './is_key_like.js';
|
|
5
|
+
const formatPEM = (b64, descriptor) => {
|
|
6
|
+
const newlined = (b64.match(/.{1,64}/g) || []).join('\n');
|
|
7
|
+
return `-----BEGIN ${descriptor}-----\n${newlined}\n-----END ${descriptor}-----`;
|
|
8
|
+
};
|
|
7
9
|
const genericExport = async (keyType, keyFormat, key) => {
|
|
10
|
+
if (isKeyObject(key)) {
|
|
11
|
+
if (key.type !== keyType) {
|
|
12
|
+
throw new TypeError(`key is not a ${keyType} key`);
|
|
13
|
+
}
|
|
14
|
+
return key.export({ format: 'pem', type: keyFormat });
|
|
15
|
+
}
|
|
8
16
|
if (!isCryptoKey(key)) {
|
|
9
|
-
throw new TypeError(invalidKeyInput(key,
|
|
17
|
+
throw new TypeError(invalidKeyInput(key, 'CryptoKey', 'KeyObject'));
|
|
10
18
|
}
|
|
11
19
|
if (!key.extractable) {
|
|
12
20
|
throw new TypeError('CryptoKey is not extractable');
|
|
@@ -43,16 +51,8 @@ const getNamedCurve = (keyData) => {
|
|
|
43
51
|
return 'P-384';
|
|
44
52
|
case findOid(keyData, [0x2b, 0x81, 0x04, 0x00, 0x23]):
|
|
45
53
|
return 'P-521';
|
|
46
|
-
case findOid(keyData, [0x2b, 0x65, 0x6e]):
|
|
47
|
-
return 'X25519';
|
|
48
|
-
case findOid(keyData, [0x2b, 0x65, 0x6f]):
|
|
49
|
-
return 'X448';
|
|
50
|
-
case findOid(keyData, [0x2b, 0x65, 0x70]):
|
|
51
|
-
return 'Ed25519';
|
|
52
|
-
case findOid(keyData, [0x2b, 0x65, 0x71]):
|
|
53
|
-
return 'Ed448';
|
|
54
54
|
default:
|
|
55
|
-
|
|
55
|
+
return undefined;
|
|
56
56
|
}
|
|
57
57
|
};
|
|
58
58
|
const genericImport = async (replace, keyFormat, pem, alg, options) => {
|
|
@@ -102,22 +102,19 @@ const genericImport = async (replace, keyFormat, pem, alg, options) => {
|
|
|
102
102
|
case 'ECDH-ES+A192KW':
|
|
103
103
|
case 'ECDH-ES+A256KW': {
|
|
104
104
|
const namedCurve = getNamedCurve(keyData);
|
|
105
|
-
algorithm = namedCurve
|
|
105
|
+
algorithm = namedCurve?.startsWith('P-') ? { name: 'ECDH', namedCurve } : { name: 'X25519' };
|
|
106
106
|
keyUsages = isPublic ? [] : ['deriveBits'];
|
|
107
107
|
break;
|
|
108
108
|
}
|
|
109
109
|
case 'Ed25519':
|
|
110
|
-
algorithm = { name: 'Ed25519' };
|
|
111
|
-
keyUsages = isPublic ? ['verify'] : ['sign'];
|
|
112
|
-
break;
|
|
113
110
|
case 'EdDSA':
|
|
114
|
-
algorithm = { name:
|
|
111
|
+
algorithm = { name: 'Ed25519' };
|
|
115
112
|
keyUsages = isPublic ? ['verify'] : ['sign'];
|
|
116
113
|
break;
|
|
117
114
|
default:
|
|
118
115
|
throw new JOSENotSupported('Invalid or unsupported "alg" (Algorithm) value');
|
|
119
116
|
}
|
|
120
|
-
return crypto.subtle.importKey(keyFormat, keyData, algorithm, options?.extractable ?? false, keyUsages);
|
|
117
|
+
return crypto.subtle.importKey(keyFormat, keyData, algorithm, options?.extractable ?? (isPublic ? true : false), keyUsages);
|
|
121
118
|
};
|
|
122
119
|
export const fromPKCS8 = (pem, alg, options) => {
|
|
123
120
|
return genericImport(/(?:-----(?:BEGIN|END) PRIVATE KEY-----|\s)/g, 'pkcs8', pem, alg, options);
|
|
@@ -188,7 +185,14 @@ function spkiFromX509(buf) {
|
|
|
188
185
|
const tbsCertificate = getElement(getElement(parseElement(buf).contents)[0].contents);
|
|
189
186
|
return encodeBase64(tbsCertificate[tbsCertificate[0].raw[0] === 0xa0 ? 6 : 5].raw);
|
|
190
187
|
}
|
|
188
|
+
let X509Certificate;
|
|
191
189
|
function getSPKI(x509) {
|
|
190
|
+
if ((X509Certificate ||= globalThis.process?.getBuiltinModule?.('node:crypto')?.X509Certificate)) {
|
|
191
|
+
try {
|
|
192
|
+
return new X509Certificate(x509).publicKey.export({ format: 'pem', type: 'spki' });
|
|
193
|
+
}
|
|
194
|
+
catch { }
|
|
195
|
+
}
|
|
192
196
|
const pem = x509.replace(/(?:-----(?:BEGIN|END) CERTIFICATE-----|\s)/g, '');
|
|
193
197
|
const raw = decodeBase64(pem);
|
|
194
198
|
return formatPEM(spkiFromX509(raw), 'PUBLIC KEY');
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { encoder, decoder } from '../lib/buffer_utils.js';
|
|
2
|
-
export
|
|
1
|
+
import { encoder, decoder, Buffer } from '../lib/buffer_utils.js';
|
|
2
|
+
export function encodeBase64(input) {
|
|
3
|
+
if (Buffer)
|
|
4
|
+
return Buffer.from(input).toString('base64');
|
|
3
5
|
let unencoded = input;
|
|
4
6
|
if (typeof unencoded === 'string') {
|
|
5
7
|
unencoded = encoder.encode(unencoded);
|
|
@@ -10,23 +12,29 @@ export const encodeBase64 = (input) => {
|
|
|
10
12
|
arr.push(String.fromCharCode.apply(null, unencoded.subarray(i, i + CHUNK_SIZE)));
|
|
11
13
|
}
|
|
12
14
|
return btoa(arr.join(''));
|
|
13
|
-
}
|
|
14
|
-
export
|
|
15
|
+
}
|
|
16
|
+
export function encode(input) {
|
|
17
|
+
if (Buffer)
|
|
18
|
+
return Buffer.from(input).toString('base64url');
|
|
15
19
|
return encodeBase64(input).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
|
|
16
|
-
}
|
|
17
|
-
export
|
|
20
|
+
}
|
|
21
|
+
export function decodeBase64(encoded) {
|
|
22
|
+
if (Buffer)
|
|
23
|
+
return Buffer.from(encoded, 'base64');
|
|
18
24
|
const binary = atob(encoded);
|
|
19
25
|
const bytes = new Uint8Array(binary.length);
|
|
20
26
|
for (let i = 0; i < binary.length; i++) {
|
|
21
27
|
bytes[i] = binary.charCodeAt(i);
|
|
22
28
|
}
|
|
23
29
|
return bytes;
|
|
24
|
-
}
|
|
25
|
-
export
|
|
30
|
+
}
|
|
31
|
+
export function decode(input) {
|
|
26
32
|
let encoded = input;
|
|
27
33
|
if (encoded instanceof Uint8Array) {
|
|
28
34
|
encoded = decoder.decode(encoded);
|
|
29
35
|
}
|
|
36
|
+
if (Buffer)
|
|
37
|
+
return Buffer.from(encoded, 'base64url');
|
|
30
38
|
encoded = encoded.replace(/-/g, '+').replace(/_/g, '/').replace(/\s/g, '');
|
|
31
39
|
try {
|
|
32
40
|
return decodeBase64(encoded);
|
|
@@ -34,4 +42,4 @@ export const decode = (input) => {
|
|
|
34
42
|
catch {
|
|
35
43
|
throw new TypeError('The input to be decoded is not correctly encoded.');
|
|
36
44
|
}
|
|
37
|
-
}
|
|
45
|
+
}
|