jose 6.2.10 → 6.2.12
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/dist/types/index.d.ts +1 -2
- package/dist/types/jwe/compact/decrypt.d.ts +12 -25
- package/dist/types/jwe/compact/encrypt.d.ts +18 -32
- package/dist/types/jwe/flattened/decrypt.d.ts +12 -25
- package/dist/types/jwe/flattened/encrypt.d.ts +24 -50
- package/dist/types/jwe/general/decrypt.d.ts +15 -30
- package/dist/types/jwe/general/encrypt.d.ts +29 -52
- package/dist/types/jwk/embedded.d.ts +5 -8
- package/dist/types/jwk/thumbprint.d.ts +7 -9
- package/dist/types/jwks/local.d.ts +10 -13
- package/dist/types/jwks/remote.d.ts +29 -41
- package/dist/types/jws/compact/sign.d.ts +8 -13
- package/dist/types/jws/compact/verify.d.ts +14 -26
- package/dist/types/jws/flattened/sign.d.ts +10 -19
- package/dist/types/jws/flattened/verify.d.ts +14 -26
- package/dist/types/jws/general/sign.d.ts +19 -33
- package/dist/types/jws/general/verify.d.ts +17 -32
- package/dist/types/jwt/decrypt.d.ts +20 -27
- package/dist/types/jwt/encrypt.d.ts +30 -35
- package/dist/types/jwt/sign.d.ts +8 -13
- package/dist/types/jwt/unsecured.d.ts +10 -19
- package/dist/types/jwt/verify.d.ts +19 -22
- package/dist/types/key/export.d.ts +10 -10
- package/dist/types/key/generate_key_pair.d.ts +15 -22
- package/dist/types/key/generate_secret.d.ts +12 -19
- package/dist/types/key/import.d.ts +25 -31
- package/dist/types/types.d.ts +184 -319
- package/dist/types/util/base64url.d.ts +7 -7
- package/dist/types/util/decode_jwt.d.ts +5 -7
- package/dist/types/util/decode_protected_header.d.ts +6 -5
- package/dist/types/util/errors.d.ts +50 -88
- package/dist/webapi/index.js +70 -32
- package/dist/webapi/jwe/compact/decrypt.js +6 -8
- package/dist/webapi/jwe/compact/encrypt.js +25 -48
- package/dist/webapi/jwe/flattened/decrypt.js +14 -14
- package/dist/webapi/jwe/flattened/encrypt.js +34 -64
- package/dist/webapi/jwe/general/decrypt.js +38 -49
- package/dist/webapi/jwe/general/encrypt.js +100 -172
- package/dist/webapi/jwk/embedded.js +29 -32
- package/dist/webapi/jwk/thumbprint.js +51 -70
- package/dist/webapi/jwks/local.js +53 -64
- package/dist/webapi/jwks/remote.js +88 -136
- package/dist/webapi/jws/compact/sign.js +19 -21
- package/dist/webapi/jws/compact/verify.js +7 -8
- package/dist/webapi/jws/flattened/sign.js +22 -31
- package/dist/webapi/jws/flattened/verify.js +11 -24
- package/dist/webapi/jws/general/sign.js +55 -73
- package/dist/webapi/jws/general/verify.js +43 -69
- package/dist/webapi/jwt/decrypt.js +12 -20
- package/dist/webapi/jwt/encrypt.js +43 -70
- package/dist/webapi/jwt/sign.js +17 -16
- package/dist/webapi/jwt/unsecured.js +31 -40
- package/dist/webapi/jwt/verify.js +12 -14
- package/dist/webapi/key/export.js +32 -41
- package/dist/webapi/key/generate_key_pair.js +32 -49
- package/dist/webapi/key/generate_secret.js +35 -40
- package/dist/webapi/key/import.js +48 -56
- package/dist/webapi/lib/asn1.js +128 -169
- package/dist/webapi/lib/buffer_utils.js +72 -41
- package/dist/webapi/lib/content_encryption.js +75 -119
- package/dist/webapi/lib/deflate.js +35 -47
- package/dist/webapi/lib/jwe_algorithms.js +102 -93
- package/dist/webapi/lib/jwe_decrypt.js +178 -234
- package/dist/webapi/lib/jwe_encrypt.js +71 -138
- package/dist/webapi/lib/jws_algorithms.js +62 -61
- package/dist/webapi/lib/jws_sign.js +43 -82
- package/dist/webapi/lib/jws_verify.js +78 -131
- package/dist/webapi/lib/jwt_claims_set.js +123 -209
- package/dist/webapi/lib/key.js +147 -139
- package/dist/webapi/lib/key_algorithm.js +13 -8
- package/dist/webapi/lib/key_descriptor.js +8 -6
- package/dist/webapi/lib/key_management.js +169 -235
- package/dist/webapi/lib/validate.js +122 -0
- package/dist/webapi/util/base64url.js +14 -37
- package/dist/webapi/util/decode_jwt.js +32 -31
- package/dist/webapi/util/decode_protected_header.js +18 -23
- package/dist/webapi/util/errors.js +94 -84
- package/package.json +17 -81
- package/dist/webapi/lib/base64.js +0 -22
- package/dist/webapi/lib/crypto_key.js +0 -28
- package/dist/webapi/lib/helpers.js +0 -42
- package/dist/webapi/lib/invalid_key_input.js +0 -26
- package/dist/webapi/lib/is_key_like.js +0 -17
- package/dist/webapi/lib/jwk_metadata.js +0 -20
- package/dist/webapi/lib/jwk_to_key.js +0 -17
- package/dist/webapi/lib/key_options.js +0 -6
- package/dist/webapi/lib/options.js +0 -74
- package/dist/webapi/lib/signing.js +0 -26
- package/dist/webapi/lib/type_checks.js +0 -33
|
@@ -1,74 +1,48 @@
|
|
|
1
|
-
import { encodeJsonUnencodedPayload, parseProtectedHeader, prepareVerify, snapshotJws, verifySignature
|
|
2
|
-
import { JWSInvalid, JWSSignatureVerificationFailed } from
|
|
3
|
-
import { isObject } from
|
|
1
|
+
import { encodeJsonUnencodedPayload, parseProtectedHeader, prepareVerify, snapshotJws, verifySignature } from "../../lib/jws_verify.js";
|
|
2
|
+
import { JWSInvalid, JWSSignatureVerificationFailed } from "../../util/errors.js";
|
|
3
|
+
import { isObject } from "../../lib/validate.js";
|
|
4
4
|
function snapshotSignature(signature, payload) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return undefined;
|
|
16
|
-
const protectedHeader = parseProtectedHeader(encodedProtected);
|
|
17
|
-
const { b64, crit } = protectedHeader;
|
|
18
|
-
return [
|
|
19
|
-
jws,
|
|
20
|
-
protectedHeader,
|
|
21
|
-
Array.isArray(crit) && crit.includes('b64')
|
|
22
|
-
? typeof b64 === 'boolean'
|
|
23
|
-
? b64
|
|
24
|
-
? 1
|
|
25
|
-
: 2
|
|
26
|
-
: 0
|
|
27
|
-
: 1,
|
|
28
|
-
];
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
return undefined;
|
|
32
|
-
}
|
|
5
|
+
try {
|
|
6
|
+
const jws = snapshotJws(signature, [payload]), protectedHeader = parseProtectedHeader(jws.protected), { b64, crit } = protectedHeader;
|
|
7
|
+
return [
|
|
8
|
+
jws,
|
|
9
|
+
protectedHeader,
|
|
10
|
+
Array.isArray(crit) && crit.includes("b64") ? typeof b64 == "boolean" ? b64 ? 1 : 2 : 0 : 1
|
|
11
|
+
];
|
|
12
|
+
} catch {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
33
15
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
16
|
+
async function generalVerify(jws, key, options) {
|
|
17
|
+
if (!isObject(jws))
|
|
18
|
+
throw new JWSInvalid("General JWS must be an object");
|
|
19
|
+
const { signatures, payload: inputPayload } = jws;
|
|
20
|
+
if (!Array.isArray(signatures))
|
|
21
|
+
throw new JWSInvalid("JWS Signatures missing or incorrect type");
|
|
22
|
+
const signatureEntries = Array.from(signatures);
|
|
23
|
+
if (!signatureEntries.every(isObject))
|
|
24
|
+
throw new JWSInvalid("JWS Signatures missing or incorrect type");
|
|
25
|
+
let shared;
|
|
26
|
+
try {
|
|
27
|
+
if (inputPayload === void 0)
|
|
28
|
+
throw new Error();
|
|
29
|
+
shared = prepareVerify(options);
|
|
30
|
+
} catch {
|
|
31
|
+
throw new JWSSignatureVerificationFailed();
|
|
32
|
+
}
|
|
33
|
+
const payload = inputPayload instanceof Uint8Array ? new Uint8Array(inputPayload) : inputPayload, candidates = signatureEntries.map((signature) => snapshotSignature(signature, payload)).filter((candidate) => candidate !== void 0);
|
|
34
|
+
let modes = 0;
|
|
35
|
+
for (const [, , mode] of candidates)
|
|
36
|
+
if (modes |= mode, modes === 3)
|
|
37
|
+
throw new JWSInvalid("inconsistent use of JWS Unencoded Payload (RFC7797)");
|
|
38
|
+
for (const candidate of candidates)
|
|
47
39
|
try {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
catch {
|
|
53
|
-
throw new JWSSignatureVerificationFailed();
|
|
54
|
-
}
|
|
55
|
-
const payload = inputPayload instanceof Uint8Array ? new Uint8Array(inputPayload) : inputPayload;
|
|
56
|
-
const candidates = signatureEntries
|
|
57
|
-
.map((signature) => snapshotSignature(signature, payload))
|
|
58
|
-
.filter((candidate) => candidate !== undefined);
|
|
59
|
-
let modes = 0;
|
|
60
|
-
for (const [, , mode] of candidates) {
|
|
61
|
-
modes |= mode;
|
|
62
|
-
if (modes === 3) {
|
|
63
|
-
throw new JWSInvalid('inconsistent use of JWS Unencoded Payload (RFC7797)');
|
|
64
|
-
}
|
|
40
|
+
const [result] = await verifySignature(candidate[0], shared, key, encodeJsonUnencodedPayload, candidate[1]);
|
|
41
|
+
return result;
|
|
42
|
+
} catch {
|
|
65
43
|
}
|
|
66
|
-
|
|
67
|
-
try {
|
|
68
|
-
return verifyResult(candidate[0], await verifySignature(candidate[0], shared, key, encodeJsonUnencodedPayload, candidate[1]));
|
|
69
|
-
}
|
|
70
|
-
catch {
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
throw new JWSSignatureVerificationFailed();
|
|
44
|
+
throw new JWSSignatureVerificationFailed();
|
|
74
45
|
}
|
|
46
|
+
export {
|
|
47
|
+
generalVerify
|
|
48
|
+
};
|
|
@@ -1,21 +1,13 @@
|
|
|
1
|
-
import { prepareDecrypt, decryptCompact } from
|
|
2
|
-
import { validateClaimsSet } from
|
|
3
|
-
import { JWTClaimValidationFailed } from
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
(claim === 'aud'
|
|
11
|
-
? JSON.stringify(protectedHeader.aud) !== JSON.stringify(payload.aud)
|
|
12
|
-
: protectedHeader[claim] !== payload[claim])) {
|
|
13
|
-
throw new JWTClaimValidationFailed(`replicated "${claim}" claim header parameter mismatch`, payload, claim, 'mismatch');
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
const result = { payload, protectedHeader };
|
|
17
|
-
if (typeof key === 'function') {
|
|
18
|
-
return { ...result, key: decrypted[2] };
|
|
19
|
-
}
|
|
20
|
-
return result;
|
|
1
|
+
import { prepareDecrypt, decryptCompact } from "../lib/jwe_decrypt.js";
|
|
2
|
+
import { validateClaimsSet } from "../lib/jwt_claims_set.js";
|
|
3
|
+
import { JWTClaimValidationFailed } from "../util/errors.js";
|
|
4
|
+
async function jwtDecrypt(jwt, key, options) {
|
|
5
|
+
const { plaintext, ...result } = await decryptCompact(jwt, prepareDecrypt(options), key), { protectedHeader } = result, payload = validateClaimsSet(protectedHeader, plaintext, options);
|
|
6
|
+
for (const claim of ["iss", "sub", "aud"])
|
|
7
|
+
if (protectedHeader[claim] !== void 0 && (claim === "aud" ? JSON.stringify(protectedHeader.aud) !== JSON.stringify(payload.aud) : protectedHeader[claim] !== payload[claim]))
|
|
8
|
+
throw new JWTClaimValidationFailed(`replicated "${claim}" claim header parameter mismatch`, payload, claim, "mismatch");
|
|
9
|
+
return { payload, ...result };
|
|
21
10
|
}
|
|
11
|
+
export {
|
|
12
|
+
jwtDecrypt
|
|
13
|
+
};
|
|
@@ -1,72 +1,45 @@
|
|
|
1
|
-
import { createJWE } from
|
|
2
|
-
import { JWTClaimsBuilder, jwtClaim, jwtData } from
|
|
3
|
-
import { assertNotSet } from
|
|
1
|
+
import { compactJWE, createJWE } from "../lib/jwe_encrypt.js";
|
|
2
|
+
import { JWTClaimsBuilder, jwtClaim, jwtData } from "../lib/jwt_claims_set.js";
|
|
3
|
+
import { assertNotSet } from "../lib/validate.js";
|
|
4
4
|
const EncryptJWT_base = JWTClaimsBuilder;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
replicateIssuerAsHeader
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
this.#replicateAudienceAsHeader = true;
|
|
43
|
-
return this;
|
|
44
|
-
}
|
|
45
|
-
async encrypt(key, options) {
|
|
46
|
-
const plaintext = jwtData(this);
|
|
47
|
-
if (this.#protectedHeader &&
|
|
48
|
-
(this.#replicateIssuerAsHeader ||
|
|
49
|
-
this.#replicateSubjectAsHeader ||
|
|
50
|
-
this.#replicateAudienceAsHeader)) {
|
|
51
|
-
this.#protectedHeader = {
|
|
52
|
-
...this.#protectedHeader,
|
|
53
|
-
iss: this.#replicateIssuerAsHeader ? jwtClaim(this, 'iss') : undefined,
|
|
54
|
-
sub: this.#replicateSubjectAsHeader ? jwtClaim(this, 'sub') : undefined,
|
|
55
|
-
aud: this.#replicateAudienceAsHeader ? jwtClaim(this, 'aud') : undefined,
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
const jwe = await createJWE([
|
|
59
|
-
plaintext,
|
|
60
|
-
this.#protectedHeader,
|
|
61
|
-
undefined,
|
|
62
|
-
undefined,
|
|
63
|
-
undefined,
|
|
64
|
-
this.#cek,
|
|
65
|
-
this.#iv,
|
|
66
|
-
this.#keyManagementParameters,
|
|
67
|
-
undefined,
|
|
68
|
-
false,
|
|
69
|
-
], key, options);
|
|
70
|
-
return [jwe.protected, jwe.encrypted_key, jwe.iv, jwe.ciphertext, jwe.tag].join('.');
|
|
71
|
-
}
|
|
5
|
+
class EncryptJWT extends EncryptJWT_base {
|
|
6
|
+
#input = [void 0];
|
|
7
|
+
#replicateIssuerAsHeader;
|
|
8
|
+
#replicateSubjectAsHeader;
|
|
9
|
+
#replicateAudienceAsHeader;
|
|
10
|
+
setProtectedHeader(protectedHeader) {
|
|
11
|
+
return assertNotSet(this.#input[1], "setProtectedHeader"), this.#input[1] = protectedHeader, this;
|
|
12
|
+
}
|
|
13
|
+
setKeyManagementParameters(parameters) {
|
|
14
|
+
return assertNotSet(this.#input[7], "setKeyManagementParameters"), this.#input[7] = parameters, this;
|
|
15
|
+
}
|
|
16
|
+
setContentEncryptionKey(cek) {
|
|
17
|
+
return assertNotSet(this.#input[5], "setContentEncryptionKey"), this.#input[5] = cek, this;
|
|
18
|
+
}
|
|
19
|
+
setInitializationVector(iv) {
|
|
20
|
+
return assertNotSet(this.#input[6], "setInitializationVector"), this.#input[6] = iv, this;
|
|
21
|
+
}
|
|
22
|
+
replicateIssuerAsHeader() {
|
|
23
|
+
return this.#replicateIssuerAsHeader = !0, this;
|
|
24
|
+
}
|
|
25
|
+
replicateSubjectAsHeader() {
|
|
26
|
+
return this.#replicateSubjectAsHeader = !0, this;
|
|
27
|
+
}
|
|
28
|
+
replicateAudienceAsHeader() {
|
|
29
|
+
return this.#replicateAudienceAsHeader = !0, this;
|
|
30
|
+
}
|
|
31
|
+
async encrypt(key, options) {
|
|
32
|
+
const plaintext = jwtData(this);
|
|
33
|
+
this.#input[1] && (this.#replicateIssuerAsHeader || this.#replicateSubjectAsHeader || this.#replicateAudienceAsHeader) && (this.#input[1] = {
|
|
34
|
+
...this.#input[1],
|
|
35
|
+
iss: this.#replicateIssuerAsHeader ? jwtClaim(this, "iss") : void 0,
|
|
36
|
+
sub: this.#replicateSubjectAsHeader ? jwtClaim(this, "sub") : void 0,
|
|
37
|
+
aud: this.#replicateAudienceAsHeader ? jwtClaim(this, "aud") : void 0
|
|
38
|
+
});
|
|
39
|
+
const input = [...this.#input];
|
|
40
|
+
return input[0] = plaintext, compactJWE(await createJWE(input, key, options));
|
|
41
|
+
}
|
|
72
42
|
}
|
|
43
|
+
export {
|
|
44
|
+
EncryptJWT
|
|
45
|
+
};
|
package/dist/webapi/jwt/sign.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import { createCompactSignature } from
|
|
2
|
-
import { JWTInvalid } from
|
|
3
|
-
import { JWTClaimsBuilder, jwtData } from
|
|
4
|
-
import { assertNotSet } from
|
|
1
|
+
import { createCompactSignature } from "../lib/jws_sign.js";
|
|
2
|
+
import { JWTInvalid } from "../util/errors.js";
|
|
3
|
+
import { JWTClaimsBuilder, jwtData } from "../lib/jwt_claims_set.js";
|
|
4
|
+
import { assertNotSet } from "../lib/validate.js";
|
|
5
5
|
const SignJWT_base = JWTClaimsBuilder;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
});
|
|
17
|
-
}
|
|
6
|
+
class SignJWT extends SignJWT_base {
|
|
7
|
+
#protectedHeader;
|
|
8
|
+
setProtectedHeader(protectedHeader) {
|
|
9
|
+
return assertNotSet(this.#protectedHeader, "setProtectedHeader"), this.#protectedHeader = protectedHeader, this;
|
|
10
|
+
}
|
|
11
|
+
async sign(key, options) {
|
|
12
|
+
return createCompactSignature(jwtData(this), this.#protectedHeader, options?.crit, key, () => {
|
|
13
|
+
throw new JWTInvalid("JWTs MUST NOT use unencoded payload");
|
|
14
|
+
});
|
|
15
|
+
}
|
|
18
16
|
}
|
|
17
|
+
export {
|
|
18
|
+
SignJWT
|
|
19
|
+
};
|
|
@@ -1,43 +1,34 @@
|
|
|
1
|
-
import * as b64u from
|
|
2
|
-
import { decodeBase64url, parseJoseHeader } from
|
|
3
|
-
import { JWSInvalid, JWTInvalid } from
|
|
4
|
-
import { validateClaimsSet, JWTClaimsBuilder, jwtData } from
|
|
5
|
-
import { JWS_RECOGNIZED, validateB64, validateCrit } from '../lib/options.js';
|
|
1
|
+
import * as b64u from "../util/base64url.js";
|
|
2
|
+
import { decodeBase64url, parseJoseHeader, JWS_RECOGNIZED, validateB64, validateCrit } from "../lib/validate.js";
|
|
3
|
+
import { JWSInvalid, JWTInvalid } from "../util/errors.js";
|
|
4
|
+
import { validateClaimsSet, JWTClaimsBuilder, jwtData } from "../lib/jwt_claims_set.js";
|
|
6
5
|
const UnsecuredJWT_base = JWTClaimsBuilder;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const extensions = validateCrit(JWSInvalid, JWS_RECOGNIZED, undefined, header, header);
|
|
26
|
-
b64 = validateB64(header, extensions);
|
|
27
|
-
}
|
|
28
|
-
catch (cause) {
|
|
29
|
-
if (!(cause instanceof JWSInvalid)) {
|
|
30
|
-
throw cause;
|
|
31
|
-
}
|
|
32
|
-
throw new JWTInvalid('Invalid Unsecured JWT', { cause });
|
|
33
|
-
}
|
|
34
|
-
if (header.alg !== 'none') {
|
|
35
|
-
throw new JWTInvalid('Invalid Unsecured JWT');
|
|
36
|
-
}
|
|
37
|
-
if (!b64) {
|
|
38
|
-
throw new JWTInvalid('JWTs MUST NOT use unencoded payload');
|
|
39
|
-
}
|
|
40
|
-
const payload = validateClaimsSet(header, decodeBase64url(encodedPayload, 'payload', JWTInvalid), options);
|
|
41
|
-
return { payload, header };
|
|
6
|
+
class UnsecuredJWT extends UnsecuredJWT_base {
|
|
7
|
+
encode() {
|
|
8
|
+
const header = b64u.encode(JSON.stringify({ alg: "none" })), payload = b64u.encode(jwtData(this));
|
|
9
|
+
return `${header}.${payload}.`;
|
|
10
|
+
}
|
|
11
|
+
static decode(jwt, options) {
|
|
12
|
+
if (typeof jwt != "string")
|
|
13
|
+
throw new JWTInvalid("Unsecured JWT must be a string");
|
|
14
|
+
const { 0: encodedHeader, 1: encodedPayload, 2: signature, length } = jwt.split(".");
|
|
15
|
+
if (length !== 3 || signature !== "")
|
|
16
|
+
throw new JWTInvalid("Invalid Unsecured JWT");
|
|
17
|
+
let header, b64;
|
|
18
|
+
try {
|
|
19
|
+
header = parseJoseHeader(encodedHeader, JWSInvalid, "JWS Protected Header is invalid");
|
|
20
|
+
const extensions = validateCrit(JWSInvalid, JWS_RECOGNIZED, void 0, header, header);
|
|
21
|
+
b64 = validateB64(header, extensions);
|
|
22
|
+
} catch (cause) {
|
|
23
|
+
throw cause instanceof JWSInvalid ? new JWTInvalid("Invalid Unsecured JWT", { cause }) : cause;
|
|
42
24
|
}
|
|
25
|
+
if (header.alg !== "none")
|
|
26
|
+
throw new JWTInvalid("Invalid Unsecured JWT");
|
|
27
|
+
if (!b64)
|
|
28
|
+
throw new JWTInvalid("JWTs MUST NOT use unencoded payload");
|
|
29
|
+
return { payload: validateClaimsSet(header, decodeBase64url(encodedPayload, "payload", JWTInvalid), options), header };
|
|
30
|
+
}
|
|
43
31
|
}
|
|
32
|
+
export {
|
|
33
|
+
UnsecuredJWT
|
|
34
|
+
};
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import { prepareVerify, verifyCompact } from
|
|
2
|
-
import { validateClaimsSet } from
|
|
3
|
-
import { JWTInvalid } from
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const result = { payload, protectedHeader: verified[1] };
|
|
11
|
-
if (typeof key === 'function') {
|
|
12
|
-
return { ...result, key: verified[3] };
|
|
13
|
-
}
|
|
14
|
-
return result;
|
|
1
|
+
import { prepareVerify, verifyCompact } from "../lib/jws_verify.js";
|
|
2
|
+
import { validateClaimsSet } from "../lib/jwt_claims_set.js";
|
|
3
|
+
import { JWTInvalid } from "../util/errors.js";
|
|
4
|
+
async function jwtVerify(jwt, key, options) {
|
|
5
|
+
const [verified, b64] = await verifyCompact(jwt, prepareVerify(options), key);
|
|
6
|
+
if (!b64)
|
|
7
|
+
throw new JWTInvalid("JWTs MUST NOT use unencoded payload");
|
|
8
|
+
const payload = validateClaimsSet(verified.protectedHeader, verified.payload, options);
|
|
9
|
+
return { ...verified, payload };
|
|
15
10
|
}
|
|
11
|
+
export {
|
|
12
|
+
jwtVerify
|
|
13
|
+
};
|
|
@@ -1,44 +1,35 @@
|
|
|
1
|
-
import { toSPKI as exportPublic, toPKCS8 as exportPrivate } from
|
|
2
|
-
import { invalidKeyInput } from
|
|
3
|
-
import { encode as b64u } from
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
return Object.fromEntries(Object.entries(jwk).filter(([, value]) => value !== undefined));
|
|
1
|
+
import { toSPKI as exportPublic, toPKCS8 as exportPrivate } from "../lib/asn1.js";
|
|
2
|
+
import { invalidKeyInput, isCryptoKey, isKeyObject } from "../lib/key.js";
|
|
3
|
+
import { encode as b64u } from "../util/base64url.js";
|
|
4
|
+
function exportSPKI(key) {
|
|
5
|
+
return exportPublic(key);
|
|
7
6
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (key.type === 'secret') {
|
|
11
|
-
key = key.export();
|
|
12
|
-
}
|
|
13
|
-
else {
|
|
14
|
-
return key.export({ format: 'jwk' });
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
if (key instanceof Uint8Array) {
|
|
18
|
-
return {
|
|
19
|
-
kty: 'oct',
|
|
20
|
-
k: b64u(key),
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
if (!isCryptoKey(key)) {
|
|
24
|
-
throw new TypeError(invalidKeyInput(key, 'CryptoKey', 'KeyObject', 'Uint8Array'));
|
|
25
|
-
}
|
|
26
|
-
if (!key.extractable) {
|
|
27
|
-
throw new TypeError('non-extractable CryptoKey cannot be exported as a JWK');
|
|
28
|
-
}
|
|
29
|
-
const { ext, key_ops, alg, use, ...jwk } = omitUndefinedProperties(await crypto.subtle.exportKey('jwk', key));
|
|
30
|
-
if (jwk.kty === 'AKP') {
|
|
31
|
-
;
|
|
32
|
-
jwk.alg = alg;
|
|
33
|
-
}
|
|
34
|
-
return jwk;
|
|
7
|
+
function exportPKCS8(key) {
|
|
8
|
+
return exportPrivate(key);
|
|
35
9
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return
|
|
10
|
+
async function exportJWK(key) {
|
|
11
|
+
if (isKeyObject(key))
|
|
12
|
+
if (key.type === "secret")
|
|
13
|
+
key = key.export();
|
|
14
|
+
else
|
|
15
|
+
return key.export({ format: "jwk" });
|
|
16
|
+
if (key instanceof Uint8Array)
|
|
17
|
+
return {
|
|
18
|
+
kty: "oct",
|
|
19
|
+
k: b64u(key)
|
|
20
|
+
};
|
|
21
|
+
if (!isCryptoKey(key))
|
|
22
|
+
throw new TypeError(invalidKeyInput(key, "CryptoKey", "KeyObject", "Uint8Array"));
|
|
23
|
+
if (!key.extractable)
|
|
24
|
+
throw new TypeError("non-extractable CryptoKey cannot be exported as a JWK");
|
|
25
|
+
const jwk = await crypto.subtle.exportKey("jwk", key);
|
|
26
|
+
delete jwk.ext, delete jwk.key_ops, delete jwk.use, jwk.kty !== "AKP" && delete jwk.alg;
|
|
27
|
+
for (const parameter of Object.keys(jwk))
|
|
28
|
+
jwk[parameter] === void 0 && delete jwk[parameter];
|
|
29
|
+
return jwk;
|
|
44
30
|
}
|
|
31
|
+
export {
|
|
32
|
+
exportJWK,
|
|
33
|
+
exportPKCS8,
|
|
34
|
+
exportSPKI
|
|
35
|
+
};
|
|
@@ -1,52 +1,35 @@
|
|
|
1
|
-
import { JOSENotSupported } from
|
|
2
|
-
import { validateExtractableOption } from
|
|
3
|
-
import { keyAlgorithm, unsupportedAlg, algArgument } from
|
|
1
|
+
import { JOSENotSupported } from "../util/errors.js";
|
|
2
|
+
import { validateExtractableOption } from "../lib/key.js";
|
|
3
|
+
import { keyAlgorithm, unsupportedAlg, algArgument } from "../lib/key_algorithm.js";
|
|
4
4
|
function getModulusLengthOption(options) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
throw new JOSENotSupported('Invalid or unsupported modulusLength option provided, 2048 bits or larger keys must be used');
|
|
10
|
-
}
|
|
11
|
-
return modulusLength;
|
|
5
|
+
const modulusLength = options?.modulusLength ?? 2048;
|
|
6
|
+
if (typeof modulusLength != "number" || !Number.isInteger(modulusLength) || modulusLength < 2048)
|
|
7
|
+
throw new JOSENotSupported("Invalid or unsupported modulusLength option provided, 2048 bits or larger keys must be used");
|
|
8
|
+
return modulusLength;
|
|
12
9
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
else {
|
|
36
|
-
if (entry.crv !== undefined && options?.crv !== undefined && options.crv !== entry.crv) {
|
|
37
|
-
throw new JOSENotSupported(`Invalid or unsupported crv option provided, the only supported value for ${alg} is ${entry.crv}`);
|
|
38
|
-
}
|
|
39
|
-
algorithm =
|
|
40
|
-
entry.kty[0] === 'RSA'
|
|
41
|
-
? {
|
|
42
|
-
...entry.subtle,
|
|
43
|
-
publicExponent: Uint8Array.of(0x01, 0x00, 0x01),
|
|
44
|
-
modulusLength: getModulusLengthOption(options),
|
|
45
|
-
}
|
|
46
|
-
: entry.subtle;
|
|
47
|
-
}
|
|
48
|
-
return crypto.subtle.generateKey(algorithm, extractable ?? false, [
|
|
49
|
-
...entry.usages[1],
|
|
50
|
-
...entry.usages[0],
|
|
51
|
-
]);
|
|
10
|
+
async function generateKeyPair(alg, options) {
|
|
11
|
+
const extractable = validateExtractableOption(options?.extractable), entry = keyAlgorithm(alg, algArgument);
|
|
12
|
+
entry.secret && unsupportedAlg(algArgument);
|
|
13
|
+
let algorithm;
|
|
14
|
+
if (entry.resolve) {
|
|
15
|
+
const crv = options?.crv ?? "P-256";
|
|
16
|
+
if (!["P-256", "P-384", "P-521", "X25519"].includes(crv))
|
|
17
|
+
throw new JOSENotSupported("Invalid or unsupported crv option provided, supported values are P-256, P-384, P-521, and X25519");
|
|
18
|
+
algorithm = entry.resolve({ crv });
|
|
19
|
+
} else {
|
|
20
|
+
if (entry.crv !== void 0 && options?.crv !== void 0 && options.crv !== entry.crv)
|
|
21
|
+
throw new JOSENotSupported(`Invalid or unsupported crv option provided, the only supported value for ${alg} is ${entry.crv}`);
|
|
22
|
+
algorithm = entry.kty[0] === "RSA" ? {
|
|
23
|
+
...entry.subtle,
|
|
24
|
+
publicExponent: Uint8Array.of(1, 0, 1),
|
|
25
|
+
modulusLength: getModulusLengthOption(options)
|
|
26
|
+
} : entry.subtle;
|
|
27
|
+
}
|
|
28
|
+
return crypto.subtle.generateKey(algorithm, extractable ?? !1, [
|
|
29
|
+
...entry.usages[1],
|
|
30
|
+
...entry.usages[0]
|
|
31
|
+
]);
|
|
52
32
|
}
|
|
33
|
+
export {
|
|
34
|
+
generateKeyPair
|
|
35
|
+
};
|