@@ -12,6 +12,7 @@ if (!hasOpenSSL(3, 5))
1212
1313const assert = require ( 'assert' ) ;
1414const { subtle } = globalThis . crypto ;
15+ const { createPrivateKey } = require ( 'crypto' ) ;
1516
1617const fixtures = require ( '../common/fixtures' ) ;
1718
@@ -196,41 +197,32 @@ async function testImportPkcs8SeedOnly({ name, privateUsages }, extractable) {
196197}
197198
198199async function testImportPkcs8PrivOnly ( { name, privateUsages } , extractable ) {
199- const key = await subtle . importKey (
200- 'pkcs8' ,
201- keyData [ name ] . pkcs8_priv_only ,
202- { name } ,
203- extractable ,
204- privateUsages ) ;
205- assert . strictEqual ( key . type , 'private' ) ;
206- assert . strictEqual ( key . extractable , extractable ) ;
207- assert . deepStrictEqual ( key . usages , privateUsages ) ;
208- assert . deepStrictEqual ( key . algorithm . name , name ) ;
209- assert . strictEqual ( key . algorithm , key . algorithm ) ;
210- assert . strictEqual ( key . usages , key . usages ) ;
211-
212- if ( extractable ) {
213- await assert . rejects ( subtle . exportKey ( 'pkcs8' , key ) , ( err ) => {
214- assert . strictEqual ( err . name , 'OperationError' ) ;
215- assert . strictEqual ( err . cause . code , 'ERR_CRYPTO_OPERATION_FAILED' ) ;
216- assert . strictEqual ( err . cause . message , 'Failed to get raw seed' ) ;
217- return true ;
200+ await assert . rejects (
201+ subtle . importKey (
202+ 'pkcs8' ,
203+ keyData [ name ] . pkcs8_priv_only ,
204+ { name } ,
205+ extractable ,
206+ privateUsages ) ,
207+ {
208+ name : 'NotSupportedError' ,
209+ message : 'Importing an ML-DSA PKCS#8 key without a seed is not supported' ,
218210 } ) ;
219- } else {
220- await assert . rejects (
221- subtle . exportKey ( 'pkcs8' , key ) , {
222- message : / k e y i s n o t e x t r a c t a b l e /
223- } ) ;
224- }
211+ }
225212
213+ async function testImportPkcs8MismatchedSeed ( { name, privateUsages } , extractable ) {
214+ const modified = Buffer . from ( keyData [ name ] . pkcs8 ) ;
215+ modified [ 30 ] ^= 0xff ;
226216 await assert . rejects (
227217 subtle . importKey (
228218 'pkcs8' ,
229- keyData [ name ] . pkcs8_seed_only ,
219+ modified ,
230220 { name } ,
231221 extractable ,
232- [ /* empty usages */ ] ) ,
233- { name : 'SyntaxError' , message : 'Usages cannot be empty when importing a private key.' } ) ;
222+ privateUsages ) ,
223+ {
224+ name : 'DataError' ,
225+ } ) ;
234226}
235227
236228async function testImportJwk ( { name, publicUsages, privateUsages } , extractable ) {
@@ -493,6 +485,7 @@ async function testImportRawSeed({ name, privateUsages }, extractable) {
493485 tests . push ( testImportPkcs8 ( vector , extractable ) ) ;
494486 tests . push ( testImportPkcs8SeedOnly ( vector , extractable ) ) ;
495487 tests . push ( testImportPkcs8PrivOnly ( vector , extractable ) ) ;
488+ tests . push ( testImportPkcs8MismatchedSeed ( vector , extractable ) ) ;
496489 tests . push ( testImportJwk ( vector , extractable ) ) ;
497490 tests . push ( testImportRawSeed ( vector , extractable ) ) ;
498491 tests . push ( testImportRawPublic ( vector , extractable ) ) ;
@@ -509,3 +502,17 @@ async function testImportRawSeed({ name, privateUsages }, extractable) {
509502 message : 'Unable to import ML-DSA-44 using raw format' ,
510503 } ) ;
511504} ) ( ) . then ( common . mustCall ( ) ) ;
505+
506+ ( async function ( ) {
507+ for ( const { name, privateUsages } of testVectors ) {
508+ const pem = fixtures . readKey ( getKeyFileName ( name . toLowerCase ( ) , 'private_priv_only' ) , 'ascii' ) ;
509+ const keyObject = createPrivateKey ( pem ) ;
510+ const key = keyObject . toCryptoKey ( { name } , true , privateUsages ) ;
511+ await assert . rejects ( subtle . exportKey ( 'pkcs8' , key ) , ( err ) => {
512+ assert . strictEqual ( err . name , 'OperationError' ) ;
513+ assert . strictEqual ( err . cause . code , 'ERR_CRYPTO_OPERATION_FAILED' ) ;
514+ assert . strictEqual ( err . cause . message , 'Failed to get raw seed' ) ;
515+ return true ;
516+ } ) ;
517+ }
518+ } ) ( ) . then ( common . mustCall ( ) ) ;
0 commit comments