@@ -7,6 +7,7 @@ if (!common.hasCrypto)
77 common . skip ( 'missing crypto' ) ;
88
99const assert = require ( 'assert' ) ;
10+ const { hasOpenSSL } = require ( '../common/crypto' ) ;
1011const { types : { isCryptoKey } } = require ( 'util' ) ;
1112const { internalBinding } = require ( 'internal/test/binding' ) ;
1213const {
@@ -31,6 +32,34 @@ const {
3132
3233const { subtle } = globalThis . crypto ;
3334
35+ // Defines Object.prototype setters that fail the test if native result object
36+ // creation uses [[Set]] instead of creating own data properties.
37+ async function withObjectPrototypeSetters ( names , fn ) {
38+ const descriptors = new Map ( ) ;
39+ for ( const name of names ) {
40+ descriptors . set ( name , Object . getOwnPropertyDescriptor ( Object . prototype , name ) ) ;
41+ Object . defineProperty ( Object . prototype , name , {
42+ __proto__ : null ,
43+ configurable : true ,
44+ get : common . mustNotCall ( `Object.prototype.${ name } getter` ) ,
45+ set : common . mustNotCall ( `Object.prototype.${ name } setter` ) ,
46+ } ) ;
47+ }
48+
49+ try {
50+ return await fn ( ) ;
51+ } finally {
52+ for ( const name of names ) {
53+ const descriptor = descriptors . get ( name ) ;
54+ if ( descriptor === undefined ) {
55+ delete Object . prototype [ name ] ;
56+ } else {
57+ Object . defineProperty ( Object . prototype , name , descriptor ) ;
58+ }
59+ }
60+ }
61+ }
62+
3463( async function ( ) {
3564 {
3665 const promise = new HashJob (
@@ -67,14 +96,16 @@ const { subtle } = globalThis.crypto;
6796 }
6897
6998 {
70- const pair = await new EcKeyPairGenJob (
71- kCryptoJobWebCrypto ,
72- 'P-256' ,
73- undefined ,
74- { name : 'ECDSA' , namedCurve : 'P-256' } ,
75- getUsagesMask ( new Set ( [ 'verify' ] ) ) ,
76- getUsagesMask ( new Set ( [ 'sign' ] ) ) ,
77- true ) . run ( ) ;
99+ const pair = await withObjectPrototypeSetters (
100+ [ 'publicKey' , 'privateKey' ] ,
101+ ( ) => new EcKeyPairGenJob (
102+ kCryptoJobWebCrypto ,
103+ 'P-256' ,
104+ undefined ,
105+ { name : 'ECDSA' , namedCurve : 'P-256' } ,
106+ getUsagesMask ( new Set ( [ 'verify' ] ) ) ,
107+ getUsagesMask ( new Set ( [ 'sign' ] ) ) ,
108+ true ) . run ( ) ) ;
78109
79110 assert . strictEqual ( Object . getPrototypeOf ( pair ) , Object . prototype ) ;
80111 assert ( isCryptoKey ( pair . publicKey ) ) ;
@@ -120,6 +151,33 @@ const { subtle } = globalThis.crypto;
120151 } ) ;
121152 }
122153
154+ {
155+ const key = await subtle . generateKey (
156+ { name : 'AES-CBC' , length : 128 } ,
157+ false ,
158+ [ 'encrypt' , 'decrypt' ] ) ;
159+ const iv = crypto . getRandomValues ( new Uint8Array ( 16 ) ) ;
160+ const ciphertext = new Uint8Array ( await subtle . encrypt (
161+ { name : 'AES-CBC' , iv } ,
162+ key ,
163+ Buffer . alloc ( 16 ) ) ) ;
164+ ciphertext [ ciphertext . length - 1 ] ^= 0xff ;
165+
166+ await assert . rejects (
167+ withObjectPrototypeSetters ( [ 'cause' ] , ( ) =>
168+ subtle . decrypt ( { name : 'AES-CBC' , iv } , key , ciphertext ) ) ,
169+ ( err ) => {
170+ assert . strictEqual ( err . name , 'OperationError' ) ;
171+ assert . strictEqual (
172+ err . message ,
173+ 'The operation failed for an operation-specific reason' ) ;
174+ assert ( err . cause ) ;
175+ assert . strictEqual ( typeof err . cause . message , 'string' ) ;
176+ assert . notStrictEqual ( err . cause . message , '' ) ;
177+ return true ;
178+ } ) ;
179+ }
180+
123181 {
124182 const key = await subtle . generateKey (
125183 { name : 'HMAC' , hash : 'SHA-256' } ,
@@ -151,4 +209,18 @@ const { subtle } = globalThis.crypto;
151209 delete CryptoKey . prototype . then ;
152210 }
153211 }
212+
213+ if ( hasOpenSSL ( 3 , 5 ) ) {
214+ const pair = await subtle . generateKey (
215+ { name : 'ML-KEM-768' } ,
216+ true ,
217+ [ 'encapsulateBits' , 'decapsulateBits' ] ) ;
218+ const result = await withObjectPrototypeSetters (
219+ [ 'sharedKey' , 'ciphertext' ] ,
220+ ( ) => subtle . encapsulateBits ( { name : 'ML-KEM-768' } , pair . publicKey ) ) ;
221+
222+ assert . strictEqual ( Object . getPrototypeOf ( result ) , Object . prototype ) ;
223+ assert ( result . sharedKey instanceof ArrayBuffer ) ;
224+ assert ( result . ciphertext instanceof ArrayBuffer ) ;
225+ }
154226} ) ( ) . then ( common . mustCall ( ) ) ;
0 commit comments