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,142 +1,75 @@
|
|
|
1
|
-
import { encode as b64u } from
|
|
2
|
-
import { encrypt } from
|
|
3
|
-
import { encryptKeyManagement } from
|
|
4
|
-
import { JWEInvalid } from
|
|
5
|
-
import { assertUint8Array, isDisjoint, isObject } from
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if (!isDisjoint(protectedHeader, unprotectedHeader, sharedUnprotectedHeader)) {
|
|
14
|
-
throw new JWEInvalid('JWE Protected, JWE Shared Unprotected and JWE Per-Recipient Header Parameter names must be disjoint');
|
|
15
|
-
}
|
|
1
|
+
import { encode as b64u } from "../util/base64url.js";
|
|
2
|
+
import { encrypt } from "./content_encryption.js";
|
|
3
|
+
import { encryptKeyManagement } from "./key_management.js";
|
|
4
|
+
import { JWEInvalid } from "../util/errors.js";
|
|
5
|
+
import { assertUint8Array, isDisjoint, isObject, serializeJoseHeader, validateCrit, validateCritDuplicates, JWE_RECOGNIZED } from "./validate.js";
|
|
6
|
+
import { encode } from "./buffer_utils.js";
|
|
7
|
+
import { prepareKey } from "./key.js";
|
|
8
|
+
import { JWE, jweAlgorithm, jweEncryption } from "./jwe_algorithms.js";
|
|
9
|
+
import { compress, validateZip } from "./deflate.js";
|
|
10
|
+
function checkDisjoint(protectedHeader, unprotectedHeader, sharedUnprotectedHeader) {
|
|
11
|
+
if (!isDisjoint(protectedHeader, unprotectedHeader, sharedUnprotectedHeader))
|
|
12
|
+
throw new JWEInvalid("JWE Protected, JWE Shared Unprotected and JWE Per-Recipient Header Parameter names must be disjoint");
|
|
16
13
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
...sharedUnprotectedHeader,
|
|
48
|
-
};
|
|
49
|
-
validateCritDuplicates(JWEInvalid, protectedHeader);
|
|
50
|
-
validateCrit(JWEInvalid, JWE_RECOGNIZED, crit, protectedHeader, joseHeader);
|
|
51
|
-
validateZip(joseHeader, protectedHeader);
|
|
52
|
-
const { alg, enc } = joseHeader;
|
|
53
|
-
if (typeof alg !== 'string' || !alg) {
|
|
54
|
-
throw new JWEInvalid('JWE "alg" (Algorithm) Header Parameter missing or invalid');
|
|
55
|
-
}
|
|
56
|
-
if (typeof enc !== 'string' || !enc) {
|
|
57
|
-
throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing or invalid');
|
|
58
|
-
}
|
|
59
|
-
return [joseHeader, alg, enc, jweEncryption(enc)];
|
|
14
|
+
function checkEncryptHeaders(input, options, sharedHeadersNormalized = !1) {
|
|
15
|
+
if (!input[1] && !input[2] && !input[3])
|
|
16
|
+
throw new JWEInvalid("either setProtectedHeader, setUnprotectedHeader, or sharedUnprotectedHeader must be called before #encrypt()");
|
|
17
|
+
options !== void 0 && (input[8] = options?.crit);
|
|
18
|
+
let [, protectedHeader, unprotectedHeader, sharedUnprotectedHeader, aad, cek, iv, keyManagementParameters, crit] = input;
|
|
19
|
+
if (aad !== void 0 && assertUint8Array(aad, "JWE Additional Authenticated Data"), cek !== void 0 && assertUint8Array(cek, "JWE Content Encryption Key"), iv !== void 0 && assertUint8Array(iv, "JWE Initialization Vector"), !sharedHeadersNormalized && protectedHeader !== void 0 && (protectedHeader = serializeJoseHeader(JWEInvalid, protectedHeader)[0], input[1] = protectedHeader), unprotectedHeader !== void 0 && (unprotectedHeader = serializeJoseHeader(JWEInvalid, unprotectedHeader)[0], input[2] = unprotectedHeader), !sharedHeadersNormalized && sharedUnprotectedHeader !== void 0 && (sharedUnprotectedHeader = serializeJoseHeader(JWEInvalid, sharedUnprotectedHeader)[0], input[3] = sharedUnprotectedHeader), keyManagementParameters !== void 0 && !isObject(keyManagementParameters))
|
|
20
|
+
throw new TypeError("JWE Key Management Parameters must be an object");
|
|
21
|
+
checkDisjoint(protectedHeader, unprotectedHeader, sharedUnprotectedHeader);
|
|
22
|
+
const joseHeader = {
|
|
23
|
+
...protectedHeader,
|
|
24
|
+
...unprotectedHeader,
|
|
25
|
+
...sharedUnprotectedHeader
|
|
26
|
+
};
|
|
27
|
+
validateCritDuplicates(JWEInvalid, protectedHeader), validateCrit(JWEInvalid, JWE_RECOGNIZED, crit, protectedHeader, joseHeader), validateZip(joseHeader, protectedHeader);
|
|
28
|
+
const { alg, enc } = joseHeader;
|
|
29
|
+
if (typeof alg != "string" || !alg)
|
|
30
|
+
throw new JWEInvalid('JWE "alg" (Algorithm) Header Parameter missing or invalid');
|
|
31
|
+
const algEntry = JWE[alg];
|
|
32
|
+
if (algEntry?.mode === "integrated-encryption") {
|
|
33
|
+
if (enc !== void 0)
|
|
34
|
+
throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter must not be present for integrated encryption');
|
|
35
|
+
if (cek !== void 0)
|
|
36
|
+
throw new TypeError(`setContentEncryptionKey cannot be called with JWE "alg" (Algorithm) Header ${alg}`);
|
|
37
|
+
if (iv !== void 0)
|
|
38
|
+
throw new TypeError(`setInitializationVector cannot be called with JWE "alg" (Algorithm) Header ${alg}`);
|
|
39
|
+
return [joseHeader, void 0, algEntry];
|
|
40
|
+
}
|
|
41
|
+
if (typeof enc != "string" || !enc)
|
|
42
|
+
throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing or invalid');
|
|
43
|
+
return [joseHeader, jweEncryption(enc), algEntry];
|
|
60
44
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
checkDisjoint(protectedHeader, unprotectedHeader, sharedUnprotectedHeader);
|
|
80
|
-
}
|
|
81
|
-
let protectedHeaderS;
|
|
82
|
-
let protectedHeaderB;
|
|
83
|
-
if (protectedHeader) {
|
|
84
|
-
protectedHeaderS = b64u(JSON.stringify(protectedHeader));
|
|
85
|
-
protectedHeaderB = encode(protectedHeaderS);
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
protectedHeaderS = '';
|
|
89
|
-
protectedHeaderB = new Uint8Array();
|
|
90
|
-
}
|
|
91
|
-
let additionalData;
|
|
92
|
-
let aadMember;
|
|
93
|
-
if (aad?.byteLength) {
|
|
94
|
-
aadMember = b64u(aad);
|
|
95
|
-
additionalData = concat(protectedHeaderB, encode('.'), encode(aadMember));
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
additionalData = protectedHeaderB;
|
|
99
|
-
}
|
|
100
|
-
let plaintext = inputPlaintext;
|
|
101
|
-
if (joseHeader.zip === 'DEF') {
|
|
102
|
-
plaintext = await compress(plaintext).catch((cause) => {
|
|
103
|
-
throw new JWEInvalid('Failed to compress plaintext', { cause });
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
const { ciphertext, tag, iv } = await encrypt(encEntry, plaintext, cek, inputIv, additionalData);
|
|
107
|
-
const jwe = {
|
|
108
|
-
ciphertext: b64u(ciphertext),
|
|
109
|
-
};
|
|
110
|
-
if (iv) {
|
|
111
|
-
jwe.iv = b64u(iv);
|
|
112
|
-
}
|
|
113
|
-
if (tag) {
|
|
114
|
-
jwe.tag = b64u(tag);
|
|
115
|
-
}
|
|
116
|
-
if (encryptedKey) {
|
|
117
|
-
jwe.encrypted_key = b64u(encryptedKey);
|
|
118
|
-
}
|
|
119
|
-
if (aadMember) {
|
|
120
|
-
jwe.aad = aadMember;
|
|
121
|
-
}
|
|
122
|
-
if (protectedHeader) {
|
|
123
|
-
jwe.protected = protectedHeaderS;
|
|
124
|
-
}
|
|
125
|
-
if (sharedUnprotectedHeader) {
|
|
126
|
-
jwe.unprotected = sharedUnprotectedHeader;
|
|
127
|
-
}
|
|
128
|
-
if (unprotectedHeader) {
|
|
129
|
-
jwe.header = unprotectedHeader;
|
|
130
|
-
}
|
|
131
|
-
return jwe;
|
|
45
|
+
async function encryptJWE(input, checked, key) {
|
|
46
|
+
const [joseHeader, encEntry, selected] = checked, [inputPlaintext, inputProtectedHeader, inputUnprotectedHeader, sharedUnprotectedHeader, aad, providedCek, inputIv, keyManagementParameters, , unprotectedParameters] = input;
|
|
47
|
+
let protectedHeader = inputProtectedHeader, unprotectedHeader = inputUnprotectedHeader;
|
|
48
|
+
const algEntry = selected ?? jweAlgorithm(joseHeader.alg);
|
|
49
|
+
let encryptedKey, parameters, cek;
|
|
50
|
+
algEntry.mode === "integrated-encryption" ? cek = await prepareKey(algEntry, key, "encrypt") : [cek, encryptedKey, parameters] = await encryptKeyManagement(algEntry, encEntry, key, joseHeader, providedCek, keyManagementParameters), parameters && (unprotectedParameters ? unprotectedHeader = unprotectedHeader ? { ...unprotectedHeader, ...parameters } : parameters : protectedHeader = protectedHeader ? { ...protectedHeader, ...parameters } : parameters, checkDisjoint(protectedHeader, unprotectedHeader, sharedUnprotectedHeader));
|
|
51
|
+
const protectedHeaderS = protectedHeader ? b64u(JSON.stringify(protectedHeader)) : "", aadMember = aad?.byteLength ? b64u(aad) : void 0, additionalData = encode(aadMember ? `${protectedHeaderS}.${aadMember}` : protectedHeaderS);
|
|
52
|
+
let plaintext = inputPlaintext;
|
|
53
|
+
joseHeader.zip === "DEF" && (plaintext = await compress(plaintext).catch((cause) => {
|
|
54
|
+
throw new JWEInvalid("Failed to compress plaintext", { cause });
|
|
55
|
+
}));
|
|
56
|
+
let ciphertext, tag, iv;
|
|
57
|
+
algEntry.mode === "integrated-encryption" ? [encryptedKey, ciphertext] = await algEntry.encrypt(cek, plaintext, additionalData, protectedHeader, joseHeader, keyManagementParameters) : { ciphertext, tag, iv } = await encrypt(encEntry, plaintext, cek, inputIv, additionalData);
|
|
58
|
+
const jwe = {
|
|
59
|
+
ciphertext: b64u(ciphertext)
|
|
60
|
+
};
|
|
61
|
+
return iv && (jwe.iv = b64u(iv)), tag && (jwe.tag = b64u(tag)), encryptedKey?.byteLength && (jwe.encrypted_key = b64u(encryptedKey)), aadMember && (jwe.aad = aadMember), protectedHeader && (jwe.protected = protectedHeaderS), sharedUnprotectedHeader && (jwe.unprotected = sharedUnprotectedHeader), unprotectedHeader && (jwe.header = unprotectedHeader), jwe;
|
|
132
62
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
throw new JWEInvalid('either setProtectedHeader, setUnprotectedHeader, or sharedUnprotectedHeader must be called before #encrypt()');
|
|
136
|
-
}
|
|
137
|
-
if (options !== undefined) {
|
|
138
|
-
input[8] = options?.crit;
|
|
139
|
-
input[9] = options ? unprotected in options : false;
|
|
140
|
-
}
|
|
141
|
-
return encryptJWE(input, checkEncryptHeaders(input), key);
|
|
63
|
+
async function createJWE(input, key, options) {
|
|
64
|
+
return encryptJWE(input, checkEncryptHeaders(input, options), key);
|
|
142
65
|
}
|
|
66
|
+
function compactJWE(jwe) {
|
|
67
|
+
return [jwe.protected, jwe.encrypted_key, jwe.iv, jwe.ciphertext, jwe.tag].join(".");
|
|
68
|
+
}
|
|
69
|
+
export {
|
|
70
|
+
checkDisjoint,
|
|
71
|
+
checkEncryptHeaders,
|
|
72
|
+
compactJWE,
|
|
73
|
+
createJWE,
|
|
74
|
+
encryptJWE
|
|
75
|
+
};
|
|
@@ -1,73 +1,74 @@
|
|
|
1
|
-
import { JOSENotSupported } from
|
|
2
|
-
import { table } from
|
|
3
|
-
const sig = [[
|
|
1
|
+
import { JOSENotSupported } from "../util/errors.js";
|
|
2
|
+
import { table } from "./key_descriptor.js";
|
|
3
|
+
const sig = [["verify"], ["sign"]];
|
|
4
4
|
function hmac(bits) {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
const subtle = { name: "HMAC", hash: `SHA-${bits}` };
|
|
6
|
+
return { kty: ["oct"], secret: !0, subtle, signing: subtle, usages: sig };
|
|
7
7
|
}
|
|
8
8
|
function rsa(bits, saltLength) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
};
|
|
9
|
+
const subtle = { name: saltLength ? "RSA-PSS" : "RSASSA-PKCS1-v1_5", hash: `SHA-${bits}` };
|
|
10
|
+
return {
|
|
11
|
+
kty: ["RSA"],
|
|
12
|
+
subtle,
|
|
13
|
+
signing: saltLength ? { ...subtle, saltLength } : subtle,
|
|
14
|
+
usages: sig,
|
|
15
|
+
minRsaBits: 2048
|
|
16
|
+
};
|
|
18
17
|
}
|
|
19
18
|
function ecdsa(crv, bits) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
return {
|
|
20
|
+
kty: ["EC"],
|
|
21
|
+
crv,
|
|
22
|
+
subtle: { name: "ECDSA", namedCurve: crv },
|
|
23
|
+
signing: { name: "ECDSA", hash: `SHA-${bits}` },
|
|
24
|
+
usages: sig
|
|
25
|
+
};
|
|
27
26
|
}
|
|
28
27
|
function eddsa() {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
const subtle = { name: "Ed25519" };
|
|
29
|
+
return {
|
|
30
|
+
kty: ["OKP"],
|
|
31
|
+
crv: "Ed25519",
|
|
32
|
+
subtle,
|
|
33
|
+
signing: subtle,
|
|
34
|
+
usages: sig
|
|
35
|
+
};
|
|
37
36
|
}
|
|
38
37
|
function mldsa(bits) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
};
|
|
38
|
+
const subtle = { name: `ML-DSA-${bits}` };
|
|
39
|
+
return {
|
|
40
|
+
kty: ["AKP"],
|
|
41
|
+
subtle,
|
|
42
|
+
signing: subtle,
|
|
43
|
+
usages: sig
|
|
44
|
+
};
|
|
47
45
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
46
|
+
const JWS = table({
|
|
47
|
+
HS256: hmac(256),
|
|
48
|
+
HS384: hmac(384),
|
|
49
|
+
HS512: hmac(512),
|
|
50
|
+
RS256: rsa(256),
|
|
51
|
+
RS384: rsa(384),
|
|
52
|
+
RS512: rsa(512),
|
|
53
|
+
PS256: rsa(256, 32),
|
|
54
|
+
PS384: rsa(384, 48),
|
|
55
|
+
PS512: rsa(512, 64),
|
|
56
|
+
ES256: ecdsa("P-256", 256),
|
|
57
|
+
ES384: ecdsa("P-384", 384),
|
|
58
|
+
ES512: ecdsa("P-521", 512),
|
|
59
|
+
EdDSA: eddsa(),
|
|
60
|
+
Ed25519: eddsa(),
|
|
61
|
+
"ML-DSA-44": mldsa(44),
|
|
62
|
+
"ML-DSA-65": mldsa(65),
|
|
63
|
+
"ML-DSA-87": mldsa(87)
|
|
66
64
|
});
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
return entry;
|
|
65
|
+
function jwsAlgorithm(alg) {
|
|
66
|
+
const entry = typeof alg == "string" ? JWS[alg] : void 0;
|
|
67
|
+
if (!entry)
|
|
68
|
+
throw new JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
|
|
69
|
+
return entry;
|
|
73
70
|
}
|
|
71
|
+
export {
|
|
72
|
+
JWS,
|
|
73
|
+
jwsAlgorithm
|
|
74
|
+
};
|
|
@@ -1,85 +1,46 @@
|
|
|
1
|
-
import { encode as b64u } from
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (protectedHeader === undefined)
|
|
11
|
-
return [undefined, ''];
|
|
1
|
+
import { encode as b64u } from "../util/base64url.js";
|
|
2
|
+
import { jwsAlgorithm } from "./jws_algorithms.js";
|
|
3
|
+
import { isDisjoint, serializeJoseHeader, validateB64, validateCrit, validateCritDuplicates, JWS_RECOGNIZED } from "./validate.js";
|
|
4
|
+
import { JWSInvalid } from "../util/errors.js";
|
|
5
|
+
import { concat, encode, encoder } from "./buffer_utils.js";
|
|
6
|
+
import { prepareKey, rawKey, checkModulusLength } from "./key.js";
|
|
7
|
+
async function createSignature(input, key, rejectUnencoded) {
|
|
8
|
+
let [payload, protectedHeader, unprotectedHeader, crit] = input, protectedHeaderString = "";
|
|
9
|
+
if (protectedHeader !== void 0) {
|
|
12
10
|
const normalized = serializeJoseHeader(JWSInvalid, protectedHeader);
|
|
13
|
-
|
|
11
|
+
protectedHeader = normalized[0], protectedHeaderString = b64u(normalized[1]);
|
|
12
|
+
}
|
|
13
|
+
if (unprotectedHeader !== void 0 && (unprotectedHeader = serializeJoseHeader(JWSInvalid, unprotectedHeader)[0]), !protectedHeader && !unprotectedHeader)
|
|
14
|
+
throw new JWSInvalid("either setProtectedHeader or setUnprotectedHeader must be called before #sign()");
|
|
15
|
+
if (!isDisjoint(protectedHeader, unprotectedHeader))
|
|
16
|
+
throw new JWSInvalid("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");
|
|
17
|
+
const joseHeader = { ...protectedHeader, ...unprotectedHeader };
|
|
18
|
+
validateCritDuplicates(JWSInvalid, protectedHeader);
|
|
19
|
+
const b64 = validateB64(protectedHeader, validateCrit(JWSInvalid, JWS_RECOGNIZED, crit, protectedHeader, joseHeader));
|
|
20
|
+
b64 || rejectUnencoded?.();
|
|
21
|
+
const { alg } = joseHeader;
|
|
22
|
+
if (typeof alg != "string" || !alg)
|
|
23
|
+
throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
|
|
24
|
+
const entry = jwsAlgorithm(alg);
|
|
25
|
+
let payloadS = "", payloadB = payload, data;
|
|
26
|
+
if (b64) {
|
|
27
|
+
const encoded = input[4];
|
|
28
|
+
encoded ? (payloadS = encoded[0] ??= b64u(payload), payloadB = encoded[1] ??= encode(payloadS)) : (payloadS = b64u(payload), data = encoder.encode(`${protectedHeaderString}.${payloadS}`));
|
|
29
|
+
}
|
|
30
|
+
data ??= concat(encode(protectedHeaderString), encode("."), payloadB);
|
|
31
|
+
const k = await rawKey(await prepareKey(entry, key, "sign"), entry.subtle, "sign");
|
|
32
|
+
entry.minRsaBits && checkModulusLength(entry.alg, k);
|
|
33
|
+
const jws = {
|
|
34
|
+
signature: b64u(new Uint8Array(await crypto.subtle.sign(entry.signing, k, data))),
|
|
35
|
+
payload: payloadS
|
|
36
|
+
};
|
|
37
|
+
return protectedHeader && (jws.protected = protectedHeaderString), unprotectedHeader && (jws.header = unprotectedHeader), [jws, b64];
|
|
14
38
|
}
|
|
15
|
-
function
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
function signatureAlgorithm(joseHeader) {
|
|
20
|
-
const alg = joseHeader.alg;
|
|
21
|
-
if (typeof alg !== 'string' || !alg) {
|
|
22
|
-
throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
|
|
23
|
-
}
|
|
24
|
-
return jwsAlgorithm(alg);
|
|
25
|
-
}
|
|
26
|
-
async function signSignature(protectedHeader, payload, entry, key) {
|
|
27
|
-
const data = concat(encode(protectedHeader), encode('.'), payload);
|
|
28
|
-
const k = await prepareKey(entry, key, 'sign');
|
|
29
|
-
return b64u(await sign(entry, k, data));
|
|
30
|
-
}
|
|
31
|
-
export async function createSignature(input, key, assertB64) {
|
|
32
|
-
let { protectedHeader, unprotectedHeader } = input;
|
|
33
|
-
let protectedHeaderString;
|
|
34
|
-
[protectedHeader, protectedHeaderString] = serializeProtectedHeader(protectedHeader);
|
|
35
|
-
if (unprotectedHeader !== undefined) {
|
|
36
|
-
unprotectedHeader = serializeJoseHeader(JWSInvalid, unprotectedHeader)[0];
|
|
37
|
-
}
|
|
38
|
-
if (!protectedHeader && !unprotectedHeader) {
|
|
39
|
-
throw new JWSInvalid('either setProtectedHeader or setUnprotectedHeader must be called before #sign()');
|
|
40
|
-
}
|
|
41
|
-
if (!isDisjoint(protectedHeader, unprotectedHeader)) {
|
|
42
|
-
throw new JWSInvalid('JWS Protected and JWS Unprotected Header Parameter names must be disjoint');
|
|
43
|
-
}
|
|
44
|
-
const joseHeader = { ...protectedHeader, ...unprotectedHeader };
|
|
45
|
-
const b64 = validateSignatureHeader(protectedHeader, joseHeader, input.crit);
|
|
46
|
-
assertB64?.(b64);
|
|
47
|
-
const entry = signatureAlgorithm(joseHeader);
|
|
48
|
-
let payloadS;
|
|
49
|
-
let payloadB;
|
|
50
|
-
if (b64) {
|
|
51
|
-
const encoded = (input.encoded ??= []);
|
|
52
|
-
encoded[0] ??= b64u(input.payload);
|
|
53
|
-
encoded[1] ??= encode(encoded[0]);
|
|
54
|
-
payloadS = encoded[0];
|
|
55
|
-
payloadB = encoded[1];
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
payloadB = input.payload;
|
|
59
|
-
payloadS = '';
|
|
60
|
-
}
|
|
61
|
-
const jws = {
|
|
62
|
-
signature: await signSignature(protectedHeaderString, payloadB, entry, key),
|
|
63
|
-
payload: payloadS,
|
|
64
|
-
};
|
|
65
|
-
if (protectedHeader) {
|
|
66
|
-
jws.protected = protectedHeaderString;
|
|
67
|
-
}
|
|
68
|
-
if (unprotectedHeader) {
|
|
69
|
-
jws.header = unprotectedHeader;
|
|
70
|
-
}
|
|
71
|
-
return [jws, b64];
|
|
72
|
-
}
|
|
73
|
-
export async function createCompactSignature(payload, inputProtectedHeader, inputCrit, key, rejectUnencoded) {
|
|
74
|
-
const [protectedHeader, protectedHeaderString] = serializeProtectedHeader(inputProtectedHeader);
|
|
75
|
-
if (!protectedHeader) {
|
|
76
|
-
throw new JWSInvalid('either setProtectedHeader or setUnprotectedHeader must be called before #sign()');
|
|
77
|
-
}
|
|
78
|
-
const b64 = validateSignatureHeader(protectedHeader, protectedHeader, inputCrit);
|
|
79
|
-
if (!b64)
|
|
80
|
-
rejectUnencoded();
|
|
81
|
-
const entry = signatureAlgorithm(protectedHeader);
|
|
82
|
-
const encodedPayload = b64u(payload);
|
|
83
|
-
const signature = await signSignature(protectedHeaderString, encode(encodedPayload), entry, key);
|
|
84
|
-
return `${protectedHeaderString}.${encodedPayload}.${signature}`;
|
|
39
|
+
async function createCompactSignature(payload, protectedHeader, crit, key, rejectUnencoded) {
|
|
40
|
+
const [jws] = await createSignature([payload, protectedHeader, void 0, crit], key, rejectUnencoded);
|
|
41
|
+
return `${jws.protected}.${jws.payload}.${jws.signature}`;
|
|
85
42
|
}
|
|
43
|
+
export {
|
|
44
|
+
createCompactSignature,
|
|
45
|
+
createSignature
|
|
46
|
+
};
|