Skip to content

Commit 9d0fdf7

Browse files
committed
crypto: re-add padding for AES-KW wrapped JWKs
PR-URL: #46563 Reviewed-By: James M Snell <[email protected]>
1 parent 9634bf8 commit 9d0fdf7

File tree

2 files changed

+17
-8
lines changed

2 files changed

+17
-8
lines changed

lib/internal/crypto/webcrypto.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const {
88
ReflectApply,
99
ReflectConstruct,
1010
SafeSet,
11+
StringPrototypeRepeat,
1112
SymbolToStringTag,
1213
} = primordials;
1314

@@ -681,7 +682,16 @@ async function wrapKey(format, key, wrappingKey, algorithm) {
681682
let keyData = await ReflectApply(exportKey, this, [format, key]);
682683

683684
if (format === 'jwk') {
684-
keyData = new TextEncoder().encode(JSONStringify(keyData));
685+
const ec = new TextEncoder();
686+
const raw = JSONStringify(keyData);
687+
// As per the NOTE in step 13 https://w3c.github.io/webcrypto/#SubtleCrypto-method-wrapKey
688+
// we're padding AES-KW wrapped JWK to make sure it is always a multiple of 8 bytes
689+
// in length
690+
if (algorithm.name === 'AES-KW' && raw.length % 8 !== 0) {
691+
keyData = ec.encode(raw + StringPrototypeRepeat(' ', 8 - (raw.length % 8)));
692+
} else {
693+
keyData = ec.encode(raw);
694+
}
685695
}
686696

687697
return cipherOrWrap(

test/parallel/test-webcrypto-wrap-unwrap.js

+6-7
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@ function getFormats(key) {
199199
// material length must be a multiple of 8.
200200
// If the wrapping algorithm is RSA-OAEP, the exported key
201201
// material maximum length is a factor of the modulusLength
202+
//
203+
// As per the NOTE in step 13 https://w3c.github.io/webcrypto/#SubtleCrypto-method-wrapKey
204+
// we're padding AES-KW wrapped JWK to make sure it is always a multiple of 8 bytes
205+
// in length
202206
async function wrappingIsPossible(name, exported) {
203207
if ('byteLength' in exported) {
204208
switch (name) {
@@ -207,13 +211,8 @@ async function wrappingIsPossible(name, exported) {
207211
case 'RSA-OAEP':
208212
return exported.byteLength <= 446;
209213
}
210-
} else if ('kty' in exported) {
211-
switch (name) {
212-
case 'AES-KW':
213-
return JSON.stringify(exported).length % 8 === 0;
214-
case 'RSA-OAEP':
215-
return JSON.stringify(exported).length <= 478;
216-
}
214+
} else if ('kty' in exported && name === 'RSA-OAEP') {
215+
return JSON.stringify(exported).length <= 478;
217216
}
218217
return true;
219218
}

0 commit comments

Comments
 (0)