Skip to content

Commit de1338d

Browse files
panvaMoLow
authored andcommitted
crypto: fix webcrypto private/secret import with empty usages
Refs: #47864 PR-URL: #47877 Refs: #47864 Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 81d8d95 commit de1338d

9 files changed

Lines changed: 101 additions & 47 deletions

‎lib/internal/crypto/webcrypto.js‎

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -600,52 +600,67 @@ async function importKey(
600600
});
601601

602602
algorithm=normalizeAlgorithm(algorithm,'importKey');
603+
letresult;
603604
switch(algorithm.name){
604605
case'RSASSA-PKCS1-v1_5':
605606
// Fall through
606607
case'RSA-PSS':
607608
// Fall through
608609
case'RSA-OAEP':
609-
returnrequire('internal/crypto/rsa')
610+
result=awaitrequire('internal/crypto/rsa')
610611
.rsaImportKey(format,keyData,algorithm,extractable,keyUsages);
612+
break;
611613
case'ECDSA':
612614
// Fall through
613615
case'ECDH':
614-
returnrequire('internal/crypto/ec')
616+
result=awaitrequire('internal/crypto/ec')
615617
.ecImportKey(format,keyData,algorithm,extractable,keyUsages);
618+
break;
616619
case'Ed25519':
617620
// Fall through
618621
case'Ed448':
619622
// Fall through
620623
case'X25519':
621624
// Fall through
622625
case'X448':
623-
returnrequire('internal/crypto/cfrg')
626+
result=awaitrequire('internal/crypto/cfrg')
624627
.cfrgImportKey(format,keyData,algorithm,extractable,keyUsages);
628+
break;
625629
case'HMAC':
626-
returnrequire('internal/crypto/mac')
630+
result=awaitrequire('internal/crypto/mac')
627631
.hmacImportKey(format,keyData,algorithm,extractable,keyUsages);
632+
break;
628633
case'AES-CTR':
629634
// Fall through
630635
case'AES-CBC':
631636
// Fall through
632637
case'AES-GCM':
633638
// Fall through
634639
case'AES-KW':
635-
returnrequire('internal/crypto/aes')
640+
result=awaitrequire('internal/crypto/aes')
636641
.aesImportKey(algorithm,format,keyData,extractable,keyUsages);
642+
break;
637643
case'HKDF':
638644
// Fall through
639645
case'PBKDF2':
640-
returnimportGenericSecretKey(
646+
result=awaitimportGenericSecretKey(
641647
algorithm,
642648
format,
643649
keyData,
644650
extractable,
645651
keyUsages);
652+
break;
653+
default:
654+
throwlazyDOMException('Unrecognized algorithm name','NotSupportedError');
646655
}
647656

648-
throwlazyDOMException('Unrecognized algorithm name','NotSupportedError');
657+
if((result.type==='secret'||result.type==='private')&&result.usages.length===0){
658+
throwlazyDOMException(
659+
`Usages cannot be empty when importing a ${result.type} key.`,
660+
'SyntaxError');
661+
}
662+
663+
returnresult;
649664
}
650665

651666
// subtle.wrapKey() is essentially a subtle.exportKey() followed

‎test/parallel/test-webcrypto-export-import-cfrg.js‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,15 @@ async function testImportPkcs8({ name, privateUsages }, extractable) {
164164
message: /keyisnotextractable/
165165
});
166166
}
167+
168+
awaitassert.rejects(
169+
subtle.importKey(
170+
'pkcs8',
171+
keyData[name].pkcs8,
172+
{ name },
173+
extractable,
174+
[/* empty usages */]),
175+
{name: 'SyntaxError',message: 'Usages cannot be empty when importing a private key.'});
167176
}
168177

169178
asyncfunctiontestImportJwk({ name, publicUsages, privateUsages },extractable){
@@ -311,6 +320,15 @@ async function testImportJwk({ name, publicUsages, privateUsages }, extractable)
311320
publicUsages),
312321
{message: 'JWK "crv" Parameter and algorithm name mismatch'});
313322
}
323+
324+
awaitassert.rejects(
325+
subtle.importKey(
326+
'jwk',
327+
{ ...jwk},
328+
{ name },
329+
extractable,
330+
[/* empty usages */]),
331+
{name: 'SyntaxError',message: 'Usages cannot be empty when importing a private key.'});
314332
}
315333

316334
asyncfunctiontestImportRaw({ name, publicUsages }){

‎test/parallel/test-webcrypto-export-import-ec.js‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,15 @@ async function testImportPkcs8(
164164
message: /keyisnotextractable/
165165
});
166166
}
167+
168+
awaitassert.rejects(
169+
subtle.importKey(
170+
'pkcs8',
171+
keyData[namedCurve].pkcs8,
172+
{ name, namedCurve },
173+
extractable,
174+
[/* empty usages */]),
175+
{name: 'SyntaxError',message: 'Usages cannot be empty when importing a private key.'});
167176
}
168177

169178
asyncfunctiontestImportJwk(
@@ -312,6 +321,15 @@ async function testImportJwk(
312321
privateUsages),
313322
{message: 'JWK "crv" does not match the requested algorithm'});
314323
}
324+
325+
awaitassert.rejects(
326+
subtle.importKey(
327+
'jwk',
328+
{ ...jwk},
329+
{ name, namedCurve },
330+
extractable,
331+
[/* empty usages */]),
332+
{name: 'SyntaxError',message: 'Usages cannot be empty when importing a private key.'});
315333
}
316334

317335
asyncfunctiontestImportRaw({ name, publicUsages },namedCurve){

‎test/parallel/test-webcrypto-export-import-rsa.js‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,15 @@ async function testImportPkcs8(
361361
message: /keyisnotextractable/
362362
});
363363
}
364+
365+
awaitassert.rejects(
366+
subtle.importKey(
367+
'pkcs8',
368+
keyData[size].pkcs8,
369+
{ name, hash },
370+
extractable,
371+
[/* empty usages */]),
372+
{name: 'SyntaxError',message: 'Usages cannot be empty when importing a private key.'});
364373
}
365374

366375
asyncfunctiontestImportJwk(
@@ -495,6 +504,15 @@ async function testImportJwk(
495504
privateUsages),
496505
{message: 'JWK "alg" does not match the requested algorithm'});
497506
}
507+
508+
awaitassert.rejects(
509+
subtle.importKey(
510+
'jwk',
511+
{ ...jwk},
512+
{ name, hash },
513+
extractable,
514+
[/* empty usages */]),
515+
{name: 'SyntaxError',message: 'Usages cannot be empty when importing a private key.'});
498516
}
499517

500518
// combinations to test

‎test/parallel/test-webcrypto-export-import.js‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,18 @@ const { subtle } = webcrypto;
9696
assert.deepStrictEqual(
9797
Buffer.from(jwk.k,'base64').toString('hex'),
9898
Buffer.from(raw).toString('hex'));
99+
100+
awaitassert.rejects(
101+
subtle.importKey(
102+
'raw',
103+
keyData,
104+
{
105+
name: 'HMAC',
106+
hash: 'SHA-256'
107+
},
108+
true,
109+
[/* empty usages */]),
110+
{name: 'SyntaxError',message: 'Usages cannot be empty when importing a secret key.'});
99111
}
100112

101113
test().then(common.mustCall());
@@ -126,6 +138,18 @@ const { subtle } = webcrypto;
126138
assert.deepStrictEqual(
127139
Buffer.from(jwk.k,'base64').toString('hex'),
128140
Buffer.from(raw).toString('hex'));
141+
142+
awaitassert.rejects(
143+
subtle.importKey(
144+
'raw',
145+
keyData,
146+
{
147+
name: 'AES-CTR',
148+
length: 256,
149+
},
150+
true,
151+
[/* empty usages */]),
152+
{name: 'SyntaxError',message: 'Usages cannot be empty when importing a secret key.'});
129153
}
130154

131155
test().then(common.mustCall());

‎test/parallel/test-webcrypto-sign-verify-ecdsa.js‎

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@ async function testSign({ name,
149149
plaintext }){
150150
const[
151151
publicKey,
152-
noSignPrivateKey,
153152
privateKey,
154153
hmacKey,
155154
rsaKeys,
@@ -161,12 +160,6 @@ async function testSign({ name,
161160
{ name, namedCurve },
162161
false,
163162
['verify']),
164-
subtle.importKey(
165-
'pkcs8',
166-
privateKeyBuffer,
167-
{ name, namedCurve },
168-
false,
169-
[/* No usages */]),
170163
subtle.importKey(
171164
'pkcs8',
172165
privateKeyBuffer,
@@ -214,12 +207,6 @@ async function testSign({ name,
214207
message: /Unabletousethiskeytosign/
215208
});
216209

217-
// Test failure when no sign usage
218-
awaitassert.rejects(
219-
subtle.sign({ name, hash },noSignPrivateKey,plaintext),{
220-
message: /Unabletousethiskeytosign/
221-
});
222-
223210
// Test failure when using the wrong algorithms
224211
awaitassert.rejects(
225212
subtle.sign({ name, hash },hmacKey,plaintext),{

‎test/parallel/test-webcrypto-sign-verify-eddsa.js‎

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ async function testSign({ name,
131131
data }){
132132
const[
133133
publicKey,
134-
noSignPrivateKey,
135134
privateKey,
136135
hmacKey,
137136
rsaKeys,
@@ -143,12 +142,6 @@ async function testSign({ name,
143142
{ name },
144143
false,
145144
['verify']),
146-
subtle.importKey(
147-
'pkcs8',
148-
privateKeyBuffer,
149-
{ name },
150-
false,
151-
[/* No usages */]),
152145
subtle.importKey(
153146
'pkcs8',
154147
privateKeyBuffer,
@@ -197,12 +190,6 @@ async function testSign({ name,
197190
message: /Unabletousethiskeytosign/
198191
});
199192

200-
// Test failure when no sign usage
201-
awaitassert.rejects(
202-
subtle.sign({ name },noSignPrivateKey,data),{
203-
message: /Unabletousethiskeytosign/
204-
});
205-
206193
// Test failure when using the wrong algorithms
207194
awaitassert.rejects(
208195
subtle.sign({ name },hmacKey,data),{

‎test/parallel/test-webcrypto-sign-verify-hmac.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ async function testVerify({ hash,
3131
keyBuffer,
3232
{ name, hash },
3333
false,
34-
[/* No usages */]),
34+
['sign']),
3535
subtle.generateKey(
3636
{
3737
name: 'RSA-PSS',

‎test/parallel/test-webcrypto-sign-verify-rsa.js‎

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ async function testSign({
132132
}){
133133
const[
134134
publicKey,
135-
noSignPrivateKey,
136135
privateKey,
137136
hmacKey,
138137
ecdsaKeys,
@@ -143,12 +142,6 @@ async function testSign({
143142
{name: algorithm.name, hash },
144143
false,
145144
['verify']),
146-
subtle.importKey(
147-
'pkcs8',
148-
privateKeyBuffer,
149-
{name: algorithm.name, hash },
150-
false,
151-
[/* No usages */]),
152145
subtle.importKey(
153146
'pkcs8',
154147
privateKeyBuffer,
@@ -189,12 +182,6 @@ async function testSign({
189182
message: /Unabletousethiskeytosign/
190183
});
191184

192-
// Test failure when no sign usage
193-
awaitassert.rejects(
194-
subtle.sign(algorithm,noSignPrivateKey,plaintext),{
195-
message: /Unabletousethiskeytosign/
196-
});
197-
198185
// Test failure when using the wrong algorithms
199186
awaitassert.rejects(
200187
subtle.sign(algorithm,hmacKey,plaintext),{

0 commit comments

Comments
 (0)