jose 5.2.2 → 5.2.3
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/browser/jwe/flattened/encrypt.js +9 -14
- package/dist/browser/jwks/remote.js +1 -1
- package/dist/browser/lib/aesgcmkw.js +6 -4
- package/dist/browser/lib/validate_crit.js +1 -1
- package/dist/browser/runtime/encrypt.js +13 -5
- package/dist/node/cjs/jwe/flattened/encrypt.js +9 -14
- package/dist/node/cjs/jwks/remote.js +1 -1
- package/dist/node/cjs/lib/aesgcmkw.js +6 -4
- package/dist/node/cjs/lib/validate_crit.js +1 -1
- package/dist/node/cjs/runtime/encrypt.js +9 -3
- package/dist/node/esm/jwe/flattened/encrypt.js +9 -14
- package/dist/node/esm/jwks/remote.js +1 -1
- package/dist/node/esm/lib/aesgcmkw.js +6 -4
- package/dist/node/esm/lib/validate_crit.js +1 -1
- package/dist/node/esm/runtime/encrypt.js +9 -3
- package/package.json +1 -1
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { encode as base64url } from '../../runtime/base64url.js';
|
|
2
2
|
import encrypt from '../../runtime/encrypt.js';
|
|
3
|
-
import generateIv from '../../lib/iv.js';
|
|
4
3
|
import encryptKeyManagement from '../../lib/encrypt_key_management.js';
|
|
5
4
|
import { JOSENotSupported, JWEInvalid } from '../../util/errors.js';
|
|
6
5
|
import isDisjoint from '../../lib/is_disjoint.js';
|
|
@@ -84,15 +83,8 @@ export class FlattenedEncrypt {
|
|
|
84
83
|
throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing or invalid');
|
|
85
84
|
}
|
|
86
85
|
let encryptedKey;
|
|
87
|
-
if (alg === 'dir') {
|
|
88
|
-
|
|
89
|
-
throw new TypeError('setContentEncryptionKey cannot be called when using Direct Encryption');
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
else if (alg === 'ECDH-ES') {
|
|
93
|
-
if (this._cek) {
|
|
94
|
-
throw new TypeError('setContentEncryptionKey cannot be called when using Direct Key Agreement');
|
|
95
|
-
}
|
|
86
|
+
if (this._cek && (alg === 'dir' || alg === 'ECDH-ES')) {
|
|
87
|
+
throw new TypeError(`setContentEncryptionKey cannot be called with JWE "alg" (Algorithm) Header ${alg}`);
|
|
96
88
|
}
|
|
97
89
|
let cek;
|
|
98
90
|
{
|
|
@@ -117,7 +109,6 @@ export class FlattenedEncrypt {
|
|
|
117
109
|
}
|
|
118
110
|
}
|
|
119
111
|
}
|
|
120
|
-
this._iv || (this._iv = generateIv(enc));
|
|
121
112
|
let additionalData;
|
|
122
113
|
let protectedHeader;
|
|
123
114
|
let aadMember;
|
|
@@ -134,12 +125,16 @@ export class FlattenedEncrypt {
|
|
|
134
125
|
else {
|
|
135
126
|
additionalData = protectedHeader;
|
|
136
127
|
}
|
|
137
|
-
const { ciphertext, tag } = await encrypt(enc, this._plaintext, cek, this._iv, additionalData);
|
|
128
|
+
const { ciphertext, tag, iv } = await encrypt(enc, this._plaintext, cek, this._iv, additionalData);
|
|
138
129
|
const jwe = {
|
|
139
130
|
ciphertext: base64url(ciphertext),
|
|
140
|
-
iv: base64url(this._iv),
|
|
141
|
-
tag: base64url(tag),
|
|
142
131
|
};
|
|
132
|
+
if (iv) {
|
|
133
|
+
jwe.iv = base64url(iv);
|
|
134
|
+
}
|
|
135
|
+
if (tag) {
|
|
136
|
+
jwe.tag = base64url(tag);
|
|
137
|
+
}
|
|
143
138
|
if (encryptedKey) {
|
|
144
139
|
jwe.encrypted_key = base64url(encryptedKey);
|
|
145
140
|
}
|
|
@@ -9,7 +9,7 @@ function isCloudflareWorkers() {
|
|
|
9
9
|
let USER_AGENT;
|
|
10
10
|
if (typeof navigator === 'undefined' || !navigator.userAgent?.startsWith?.('Mozilla/5.0 ')) {
|
|
11
11
|
const NAME = 'jose';
|
|
12
|
-
const VERSION = 'v5.2.
|
|
12
|
+
const VERSION = 'v5.2.3';
|
|
13
13
|
USER_AGENT = `${NAME}/${VERSION}`;
|
|
14
14
|
}
|
|
15
15
|
class RemoteJWKSet extends LocalJWKSet {
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import encrypt from '../runtime/encrypt.js';
|
|
2
2
|
import decrypt from '../runtime/decrypt.js';
|
|
3
|
-
import generateIv from './iv.js';
|
|
4
3
|
import { encode as base64url } from '../runtime/base64url.js';
|
|
5
4
|
export async function wrap(alg, key, cek, iv) {
|
|
6
5
|
const jweAlgorithm = alg.slice(0, 7);
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
const wrapped = await encrypt(jweAlgorithm, cek, key, iv, new Uint8Array(0));
|
|
7
|
+
return {
|
|
8
|
+
encryptedKey: wrapped.ciphertext,
|
|
9
|
+
iv: base64url(wrapped.iv),
|
|
10
|
+
tag: base64url(wrapped.tag),
|
|
11
|
+
};
|
|
10
12
|
}
|
|
11
13
|
export async function unwrap(alg, key, encryptedKey, iv, tag) {
|
|
12
14
|
const jweAlgorithm = alg.slice(0, 7);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { JOSENotSupported } from '../util/errors.js';
|
|
2
2
|
function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader, joseHeader) {
|
|
3
|
-
if (joseHeader.crit !== undefined && protectedHeader
|
|
3
|
+
if (joseHeader.crit !== undefined && protectedHeader?.crit === undefined) {
|
|
4
4
|
throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
|
|
5
5
|
}
|
|
6
6
|
if (!protectedHeader || protectedHeader.crit === undefined) {
|
|
@@ -4,6 +4,7 @@ import checkCekLength from './check_cek_length.js';
|
|
|
4
4
|
import crypto, { isCryptoKey } from './webcrypto.js';
|
|
5
5
|
import { checkEncCryptoKey } from '../lib/crypto_key.js';
|
|
6
6
|
import invalidKeyInput from '../lib/invalid_key_input.js';
|
|
7
|
+
import generateIv from '../lib/iv.js';
|
|
7
8
|
import { JOSENotSupported } from '../util/errors.js';
|
|
8
9
|
import { types } from './is_key_like.js';
|
|
9
10
|
async function cbcEncrypt(enc, plaintext, cek, iv, aad) {
|
|
@@ -22,7 +23,7 @@ async function cbcEncrypt(enc, plaintext, cek, iv, aad) {
|
|
|
22
23
|
}, encKey, plaintext));
|
|
23
24
|
const macData = concat(aad, iv, ciphertext, uint64be(aad.length << 3));
|
|
24
25
|
const tag = new Uint8Array((await crypto.subtle.sign('HMAC', macKey, macData)).slice(0, keySize >> 3));
|
|
25
|
-
return { ciphertext, tag };
|
|
26
|
+
return { ciphertext, tag, iv };
|
|
26
27
|
}
|
|
27
28
|
async function gcmEncrypt(enc, plaintext, cek, iv, aad) {
|
|
28
29
|
let encKey;
|
|
@@ -41,25 +42,32 @@ async function gcmEncrypt(enc, plaintext, cek, iv, aad) {
|
|
|
41
42
|
}, encKey, plaintext));
|
|
42
43
|
const tag = encrypted.slice(-16);
|
|
43
44
|
const ciphertext = encrypted.slice(0, -16);
|
|
44
|
-
return { ciphertext, tag };
|
|
45
|
+
return { ciphertext, tag, iv };
|
|
45
46
|
}
|
|
46
47
|
const encrypt = async (enc, plaintext, cek, iv, aad) => {
|
|
47
48
|
if (!isCryptoKey(cek) && !(cek instanceof Uint8Array)) {
|
|
48
49
|
throw new TypeError(invalidKeyInput(cek, ...types, 'Uint8Array'));
|
|
49
50
|
}
|
|
50
|
-
|
|
51
|
+
if (iv) {
|
|
52
|
+
checkIvLength(enc, iv);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
iv = generateIv(enc);
|
|
56
|
+
}
|
|
51
57
|
switch (enc) {
|
|
52
58
|
case 'A128CBC-HS256':
|
|
53
59
|
case 'A192CBC-HS384':
|
|
54
60
|
case 'A256CBC-HS512':
|
|
55
|
-
if (cek instanceof Uint8Array)
|
|
61
|
+
if (cek instanceof Uint8Array) {
|
|
56
62
|
checkCekLength(cek, parseInt(enc.slice(-3), 10));
|
|
63
|
+
}
|
|
57
64
|
return cbcEncrypt(enc, plaintext, cek, iv, aad);
|
|
58
65
|
case 'A128GCM':
|
|
59
66
|
case 'A192GCM':
|
|
60
67
|
case 'A256GCM':
|
|
61
|
-
if (cek instanceof Uint8Array)
|
|
68
|
+
if (cek instanceof Uint8Array) {
|
|
62
69
|
checkCekLength(cek, parseInt(enc.slice(1, 4), 10));
|
|
70
|
+
}
|
|
63
71
|
return gcmEncrypt(enc, plaintext, cek, iv, aad);
|
|
64
72
|
default:
|
|
65
73
|
throw new JOSENotSupported('Unsupported JWE Content Encryption Algorithm');
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.FlattenedEncrypt = exports.unprotected = void 0;
|
|
4
4
|
const base64url_js_1 = require("../../runtime/base64url.js");
|
|
5
5
|
const encrypt_js_1 = require("../../runtime/encrypt.js");
|
|
6
|
-
const iv_js_1 = require("../../lib/iv.js");
|
|
7
6
|
const encrypt_key_management_js_1 = require("../../lib/encrypt_key_management.js");
|
|
8
7
|
const errors_js_1 = require("../../util/errors.js");
|
|
9
8
|
const is_disjoint_js_1 = require("../../lib/is_disjoint.js");
|
|
@@ -95,15 +94,8 @@ class FlattenedEncrypt {
|
|
|
95
94
|
throw new errors_js_1.JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing or invalid');
|
|
96
95
|
}
|
|
97
96
|
let encryptedKey;
|
|
98
|
-
if (alg === 'dir') {
|
|
99
|
-
|
|
100
|
-
throw new TypeError('setContentEncryptionKey cannot be called when using Direct Encryption');
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
else if (alg === 'ECDH-ES') {
|
|
104
|
-
if (this._cek) {
|
|
105
|
-
throw new TypeError('setContentEncryptionKey cannot be called when using Direct Key Agreement');
|
|
106
|
-
}
|
|
97
|
+
if (this._cek && (alg === 'dir' || alg === 'ECDH-ES')) {
|
|
98
|
+
throw new TypeError(`setContentEncryptionKey cannot be called with JWE "alg" (Algorithm) Header ${alg}`);
|
|
107
99
|
}
|
|
108
100
|
let cek;
|
|
109
101
|
{
|
|
@@ -128,7 +120,6 @@ class FlattenedEncrypt {
|
|
|
128
120
|
}
|
|
129
121
|
}
|
|
130
122
|
}
|
|
131
|
-
this._iv ||= (0, iv_js_1.default)(enc);
|
|
132
123
|
let additionalData;
|
|
133
124
|
let protectedHeader;
|
|
134
125
|
let aadMember;
|
|
@@ -145,12 +136,16 @@ class FlattenedEncrypt {
|
|
|
145
136
|
else {
|
|
146
137
|
additionalData = protectedHeader;
|
|
147
138
|
}
|
|
148
|
-
const { ciphertext, tag } = await (0, encrypt_js_1.default)(enc, this._plaintext, cek, this._iv, additionalData);
|
|
139
|
+
const { ciphertext, tag, iv } = await (0, encrypt_js_1.default)(enc, this._plaintext, cek, this._iv, additionalData);
|
|
149
140
|
const jwe = {
|
|
150
141
|
ciphertext: (0, base64url_js_1.encode)(ciphertext),
|
|
151
|
-
iv: (0, base64url_js_1.encode)(this._iv),
|
|
152
|
-
tag: (0, base64url_js_1.encode)(tag),
|
|
153
142
|
};
|
|
143
|
+
if (iv) {
|
|
144
|
+
jwe.iv = (0, base64url_js_1.encode)(iv);
|
|
145
|
+
}
|
|
146
|
+
if (tag) {
|
|
147
|
+
jwe.tag = (0, base64url_js_1.encode)(tag);
|
|
148
|
+
}
|
|
154
149
|
if (encryptedKey) {
|
|
155
150
|
jwe.encrypted_key = (0, base64url_js_1.encode)(encryptedKey);
|
|
156
151
|
}
|
|
@@ -12,7 +12,7 @@ function isCloudflareWorkers() {
|
|
|
12
12
|
let USER_AGENT;
|
|
13
13
|
if (typeof navigator === 'undefined' || !navigator.userAgent?.startsWith?.('Mozilla/5.0 ')) {
|
|
14
14
|
const NAME = 'jose';
|
|
15
|
-
const VERSION = 'v5.2.
|
|
15
|
+
const VERSION = 'v5.2.3';
|
|
16
16
|
USER_AGENT = `${NAME}/${VERSION}`;
|
|
17
17
|
}
|
|
18
18
|
class RemoteJWKSet extends local_js_1.LocalJWKSet {
|
|
@@ -3,13 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.unwrap = exports.wrap = void 0;
|
|
4
4
|
const encrypt_js_1 = require("../runtime/encrypt.js");
|
|
5
5
|
const decrypt_js_1 = require("../runtime/decrypt.js");
|
|
6
|
-
const iv_js_1 = require("./iv.js");
|
|
7
6
|
const base64url_js_1 = require("../runtime/base64url.js");
|
|
8
7
|
async function wrap(alg, key, cek, iv) {
|
|
9
8
|
const jweAlgorithm = alg.slice(0, 7);
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
const wrapped = await (0, encrypt_js_1.default)(jweAlgorithm, cek, key, iv, new Uint8Array(0));
|
|
10
|
+
return {
|
|
11
|
+
encryptedKey: wrapped.ciphertext,
|
|
12
|
+
iv: (0, base64url_js_1.encode)(wrapped.iv),
|
|
13
|
+
tag: (0, base64url_js_1.encode)(wrapped.tag),
|
|
14
|
+
};
|
|
13
15
|
}
|
|
14
16
|
exports.wrap = wrap;
|
|
15
17
|
async function unwrap(alg, key, encryptedKey, iv, tag) {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const errors_js_1 = require("../util/errors.js");
|
|
4
4
|
function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader, joseHeader) {
|
|
5
|
-
if (joseHeader.crit !== undefined && protectedHeader
|
|
5
|
+
if (joseHeader.crit !== undefined && protectedHeader?.crit === undefined) {
|
|
6
6
|
throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
|
|
7
7
|
}
|
|
8
8
|
if (!protectedHeader || protectedHeader.crit === undefined) {
|
|
@@ -9,6 +9,7 @@ const webcrypto_js_1 = require("./webcrypto.js");
|
|
|
9
9
|
const crypto_key_js_1 = require("../lib/crypto_key.js");
|
|
10
10
|
const is_key_object_js_1 = require("./is_key_object.js");
|
|
11
11
|
const invalid_key_input_js_1 = require("../lib/invalid_key_input.js");
|
|
12
|
+
const iv_js_1 = require("../lib/iv.js");
|
|
12
13
|
const errors_js_1 = require("../util/errors.js");
|
|
13
14
|
const ciphers_js_1 = require("./ciphers.js");
|
|
14
15
|
const is_key_like_js_1 = require("./is_key_like.js");
|
|
@@ -27,7 +28,7 @@ function cbcEncrypt(enc, plaintext, cek, iv, aad) {
|
|
|
27
28
|
const ciphertext = (0, buffer_utils_js_1.concat)(cipher.update(plaintext), cipher.final());
|
|
28
29
|
const macSize = parseInt(enc.slice(-3), 10);
|
|
29
30
|
const tag = (0, cbc_tag_js_1.default)(aad, iv, ciphertext, macSize, macKey, keySize);
|
|
30
|
-
return { ciphertext, tag };
|
|
31
|
+
return { ciphertext, tag, iv };
|
|
31
32
|
}
|
|
32
33
|
function gcmEncrypt(enc, plaintext, cek, iv, aad) {
|
|
33
34
|
const keySize = parseInt(enc.slice(1, 4), 10);
|
|
@@ -42,7 +43,7 @@ function gcmEncrypt(enc, plaintext, cek, iv, aad) {
|
|
|
42
43
|
const ciphertext = cipher.update(plaintext);
|
|
43
44
|
cipher.final();
|
|
44
45
|
const tag = cipher.getAuthTag();
|
|
45
|
-
return { ciphertext, tag };
|
|
46
|
+
return { ciphertext, tag, iv };
|
|
46
47
|
}
|
|
47
48
|
const encrypt = (enc, plaintext, cek, iv, aad) => {
|
|
48
49
|
let key;
|
|
@@ -57,7 +58,12 @@ const encrypt = (enc, plaintext, cek, iv, aad) => {
|
|
|
57
58
|
throw new TypeError((0, invalid_key_input_js_1.default)(cek, ...is_key_like_js_1.types, 'Uint8Array'));
|
|
58
59
|
}
|
|
59
60
|
(0, check_cek_length_js_1.default)(enc, key);
|
|
60
|
-
|
|
61
|
+
if (iv) {
|
|
62
|
+
(0, check_iv_length_js_1.default)(enc, iv);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
iv = (0, iv_js_1.default)(enc);
|
|
66
|
+
}
|
|
61
67
|
switch (enc) {
|
|
62
68
|
case 'A128CBC-HS256':
|
|
63
69
|
case 'A192CBC-HS384':
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { encode as base64url } from '../../runtime/base64url.js';
|
|
2
2
|
import encrypt from '../../runtime/encrypt.js';
|
|
3
|
-
import generateIv from '../../lib/iv.js';
|
|
4
3
|
import encryptKeyManagement from '../../lib/encrypt_key_management.js';
|
|
5
4
|
import { JOSENotSupported, JWEInvalid } from '../../util/errors.js';
|
|
6
5
|
import isDisjoint from '../../lib/is_disjoint.js';
|
|
@@ -92,15 +91,8 @@ export class FlattenedEncrypt {
|
|
|
92
91
|
throw new JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing or invalid');
|
|
93
92
|
}
|
|
94
93
|
let encryptedKey;
|
|
95
|
-
if (alg === 'dir') {
|
|
96
|
-
|
|
97
|
-
throw new TypeError('setContentEncryptionKey cannot be called when using Direct Encryption');
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
else if (alg === 'ECDH-ES') {
|
|
101
|
-
if (this._cek) {
|
|
102
|
-
throw new TypeError('setContentEncryptionKey cannot be called when using Direct Key Agreement');
|
|
103
|
-
}
|
|
94
|
+
if (this._cek && (alg === 'dir' || alg === 'ECDH-ES')) {
|
|
95
|
+
throw new TypeError(`setContentEncryptionKey cannot be called with JWE "alg" (Algorithm) Header ${alg}`);
|
|
104
96
|
}
|
|
105
97
|
let cek;
|
|
106
98
|
{
|
|
@@ -125,7 +117,6 @@ export class FlattenedEncrypt {
|
|
|
125
117
|
}
|
|
126
118
|
}
|
|
127
119
|
}
|
|
128
|
-
this._iv ||= generateIv(enc);
|
|
129
120
|
let additionalData;
|
|
130
121
|
let protectedHeader;
|
|
131
122
|
let aadMember;
|
|
@@ -142,12 +133,16 @@ export class FlattenedEncrypt {
|
|
|
142
133
|
else {
|
|
143
134
|
additionalData = protectedHeader;
|
|
144
135
|
}
|
|
145
|
-
const { ciphertext, tag } = await encrypt(enc, this._plaintext, cek, this._iv, additionalData);
|
|
136
|
+
const { ciphertext, tag, iv } = await encrypt(enc, this._plaintext, cek, this._iv, additionalData);
|
|
146
137
|
const jwe = {
|
|
147
138
|
ciphertext: base64url(ciphertext),
|
|
148
|
-
iv: base64url(this._iv),
|
|
149
|
-
tag: base64url(tag),
|
|
150
139
|
};
|
|
140
|
+
if (iv) {
|
|
141
|
+
jwe.iv = base64url(iv);
|
|
142
|
+
}
|
|
143
|
+
if (tag) {
|
|
144
|
+
jwe.tag = base64url(tag);
|
|
145
|
+
}
|
|
151
146
|
if (encryptedKey) {
|
|
152
147
|
jwe.encrypted_key = base64url(encryptedKey);
|
|
153
148
|
}
|
|
@@ -9,7 +9,7 @@ function isCloudflareWorkers() {
|
|
|
9
9
|
let USER_AGENT;
|
|
10
10
|
if (typeof navigator === 'undefined' || !navigator.userAgent?.startsWith?.('Mozilla/5.0 ')) {
|
|
11
11
|
const NAME = 'jose';
|
|
12
|
-
const VERSION = 'v5.2.
|
|
12
|
+
const VERSION = 'v5.2.3';
|
|
13
13
|
USER_AGENT = `${NAME}/${VERSION}`;
|
|
14
14
|
}
|
|
15
15
|
class RemoteJWKSet extends LocalJWKSet {
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import encrypt from '../runtime/encrypt.js';
|
|
2
2
|
import decrypt from '../runtime/decrypt.js';
|
|
3
|
-
import generateIv from './iv.js';
|
|
4
3
|
import { encode as base64url } from '../runtime/base64url.js';
|
|
5
4
|
export async function wrap(alg, key, cek, iv) {
|
|
6
5
|
const jweAlgorithm = alg.slice(0, 7);
|
|
7
|
-
iv
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
const wrapped = await encrypt(jweAlgorithm, cek, key, iv, new Uint8Array(0));
|
|
7
|
+
return {
|
|
8
|
+
encryptedKey: wrapped.ciphertext,
|
|
9
|
+
iv: base64url(wrapped.iv),
|
|
10
|
+
tag: base64url(wrapped.tag),
|
|
11
|
+
};
|
|
10
12
|
}
|
|
11
13
|
export async function unwrap(alg, key, encryptedKey, iv, tag) {
|
|
12
14
|
const jweAlgorithm = alg.slice(0, 7);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { JOSENotSupported } from '../util/errors.js';
|
|
2
2
|
function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader, joseHeader) {
|
|
3
|
-
if (joseHeader.crit !== undefined && protectedHeader
|
|
3
|
+
if (joseHeader.crit !== undefined && protectedHeader?.crit === undefined) {
|
|
4
4
|
throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
|
|
5
5
|
}
|
|
6
6
|
if (!protectedHeader || protectedHeader.crit === undefined) {
|
|
@@ -7,6 +7,7 @@ import { isCryptoKey } from './webcrypto.js';
|
|
|
7
7
|
import { checkEncCryptoKey } from '../lib/crypto_key.js';
|
|
8
8
|
import isKeyObject from './is_key_object.js';
|
|
9
9
|
import invalidKeyInput from '../lib/invalid_key_input.js';
|
|
10
|
+
import generateIv from '../lib/iv.js';
|
|
10
11
|
import { JOSENotSupported } from '../util/errors.js';
|
|
11
12
|
import supported from './ciphers.js';
|
|
12
13
|
import { types } from './is_key_like.js';
|
|
@@ -25,7 +26,7 @@ function cbcEncrypt(enc, plaintext, cek, iv, aad) {
|
|
|
25
26
|
const ciphertext = concat(cipher.update(plaintext), cipher.final());
|
|
26
27
|
const macSize = parseInt(enc.slice(-3), 10);
|
|
27
28
|
const tag = cbcTag(aad, iv, ciphertext, macSize, macKey, keySize);
|
|
28
|
-
return { ciphertext, tag };
|
|
29
|
+
return { ciphertext, tag, iv };
|
|
29
30
|
}
|
|
30
31
|
function gcmEncrypt(enc, plaintext, cek, iv, aad) {
|
|
31
32
|
const keySize = parseInt(enc.slice(1, 4), 10);
|
|
@@ -40,7 +41,7 @@ function gcmEncrypt(enc, plaintext, cek, iv, aad) {
|
|
|
40
41
|
const ciphertext = cipher.update(plaintext);
|
|
41
42
|
cipher.final();
|
|
42
43
|
const tag = cipher.getAuthTag();
|
|
43
|
-
return { ciphertext, tag };
|
|
44
|
+
return { ciphertext, tag, iv };
|
|
44
45
|
}
|
|
45
46
|
const encrypt = (enc, plaintext, cek, iv, aad) => {
|
|
46
47
|
let key;
|
|
@@ -55,7 +56,12 @@ const encrypt = (enc, plaintext, cek, iv, aad) => {
|
|
|
55
56
|
throw new TypeError(invalidKeyInput(cek, ...types, 'Uint8Array'));
|
|
56
57
|
}
|
|
57
58
|
checkCekLength(enc, key);
|
|
58
|
-
|
|
59
|
+
if (iv) {
|
|
60
|
+
checkIvLength(enc, iv);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
iv = generateIv(enc);
|
|
64
|
+
}
|
|
59
65
|
switch (enc) {
|
|
60
66
|
case 'A128CBC-HS256':
|
|
61
67
|
case 'A192CBC-HS384':
|