1'use strict'; 2 3const common = require('../common'); 4 5if (!common.hasCrypto) 6 common.skip('missing crypto'); 7 8const assert = require('assert'); 9const { webcrypto } = require('crypto'); 10const { subtle } = webcrypto; 11 12{ 13 async function test() { 14 const keyData = webcrypto.getRandomValues(new Uint8Array(32)); 15 await Promise.all([1, null, undefined, {}, []].map((format) => 16 assert.rejects( 17 subtle.importKey(format, keyData, {}, false, ['wrapKey']), { 18 code: 'ERR_INVALID_ARG_VALUE' 19 }) 20 )); 21 await assert.rejects( 22 subtle.importKey('not valid', keyData, {}, false, ['wrapKey']), { 23 code: 'ERR_INVALID_ARG_VALUE' 24 }); 25 await assert.rejects( 26 subtle.importKey('raw', 1, {}, false, ['deriveBits']), { 27 code: 'ERR_INVALID_ARG_TYPE' 28 }); 29 await assert.rejects( 30 subtle.importKey('raw', keyData, { 31 name: 'HMAC' 32 }, false, ['sign', 'verify']), { 33 code: 'ERR_MISSING_OPTION' 34 }); 35 await assert.rejects( 36 subtle.importKey('raw', keyData, { 37 name: 'HMAC', 38 hash: 'SHA-256' 39 }, false, ['deriveBits']), { 40 name: 'SyntaxError', 41 message: 'Unsupported key usage for an HMAC key' 42 }); 43 await assert.rejects( 44 subtle.importKey('raw', keyData, { 45 name: 'HMAC', 46 hash: 'SHA-256', 47 length: 0 48 }, false, ['sign', 'verify']), { 49 name: 'DataError', 50 message: 'Zero-length key is not supported' 51 }); 52 await assert.rejects( 53 subtle.importKey('raw', keyData, { 54 name: 'HMAC', 55 hash: 'SHA-256', 56 length: 1 57 }, false, ['sign', 'verify']), { 58 name: 'DataError', 59 message: 'Invalid key length' 60 }); 61 await assert.rejects( 62 subtle.importKey('jwk', null, { 63 name: 'HMAC', 64 hash: 'SHA-256', 65 }, false, ['sign', 'verify']), { 66 name: 'DataError', 67 message: 'Invalid keyData' 68 }); 69 } 70 71 test().then(common.mustCall()); 72} 73 74// Import/Export HMAC Secret Key 75{ 76 async function test() { 77 const keyData = webcrypto.getRandomValues(new Uint8Array(32)); 78 const key = await subtle.importKey( 79 'raw', 80 keyData, { 81 name: 'HMAC', 82 hash: 'SHA-256' 83 }, true, ['sign', 'verify']); 84 85 const raw = await subtle.exportKey('raw', key); 86 87 assert.deepStrictEqual( 88 Buffer.from(keyData).toString('hex'), 89 Buffer.from(raw).toString('hex')); 90 91 const jwk = await subtle.exportKey('jwk', key); 92 assert.deepStrictEqual(jwk.key_ops, ['sign', 'verify']); 93 assert(jwk.ext); 94 assert.strictEqual(jwk.kty, 'oct'); 95 96 assert.deepStrictEqual( 97 Buffer.from(jwk.k, 'base64').toString('hex'), 98 Buffer.from(raw).toString('hex')); 99 100 await assert.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.' }); 111 } 112 113 test().then(common.mustCall()); 114} 115 116// Import/Export AES Secret Key 117{ 118 async function test() { 119 const keyData = webcrypto.getRandomValues(new Uint8Array(32)); 120 const key = await subtle.importKey( 121 'raw', 122 keyData, { 123 name: 'AES-CTR', 124 length: 256, 125 }, true, ['encrypt', 'decrypt']); 126 127 const raw = await subtle.exportKey('raw', key); 128 129 assert.deepStrictEqual( 130 Buffer.from(keyData).toString('hex'), 131 Buffer.from(raw).toString('hex')); 132 133 const jwk = await subtle.exportKey('jwk', key); 134 assert.deepStrictEqual(jwk.key_ops, ['encrypt', 'decrypt']); 135 assert(jwk.ext); 136 assert.strictEqual(jwk.kty, 'oct'); 137 138 assert.deepStrictEqual( 139 Buffer.from(jwk.k, 'base64').toString('hex'), 140 Buffer.from(raw).toString('hex')); 141 142 await assert.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.' }); 153 } 154 155 test().then(common.mustCall()); 156} 157 158// Import/Export RSA Key Pairs 159{ 160 async function test() { 161 const { publicKey, privateKey } = await subtle.generateKey({ 162 name: 'RSA-PSS', 163 modulusLength: 1024, 164 publicExponent: new Uint8Array([1, 0, 1]), 165 hash: 'SHA-384' 166 }, true, ['sign', 'verify']); 167 168 const [ 169 spki, 170 pkcs8, 171 publicJwk, 172 privateJwk, 173 ] = await Promise.all([ 174 subtle.exportKey('spki', publicKey), 175 subtle.exportKey('pkcs8', privateKey), 176 subtle.exportKey('jwk', publicKey), 177 subtle.exportKey('jwk', privateKey), 178 ]); 179 180 assert(spki); 181 assert(pkcs8); 182 assert(publicJwk); 183 assert(privateJwk); 184 185 const [ 186 importedSpkiPublicKey, 187 importedPkcs8PrivateKey, 188 importedJwkPublicKey, 189 importedJwkPrivateKey, 190 ] = await Promise.all([ 191 subtle.importKey('spki', spki, { 192 name: 'RSA-PSS', 193 hash: 'SHA-384', 194 }, true, ['verify']), 195 subtle.importKey('pkcs8', pkcs8, { 196 name: 'RSA-PSS', 197 hash: 'SHA-384', 198 }, true, ['sign']), 199 subtle.importKey('jwk', publicJwk, { 200 name: 'RSA-PSS', 201 hash: 'SHA-384', 202 }, true, ['verify']), 203 subtle.importKey('jwk', privateJwk, { 204 name: 'RSA-PSS', 205 hash: 'SHA-384', 206 }, true, ['sign']), 207 ]); 208 209 assert(importedSpkiPublicKey); 210 assert(importedPkcs8PrivateKey); 211 assert(importedJwkPublicKey); 212 assert(importedJwkPrivateKey); 213 } 214 215 test().then(common.mustCall()); 216} 217 218// Import/Export EC Key Pairs 219{ 220 async function test() { 221 const { publicKey, privateKey } = await subtle.generateKey({ 222 name: 'ECDSA', 223 namedCurve: 'P-384' 224 }, true, ['sign', 'verify']); 225 226 const [ 227 spki, 228 pkcs8, 229 publicJwk, 230 privateJwk, 231 ] = await Promise.all([ 232 subtle.exportKey('spki', publicKey), 233 subtle.exportKey('pkcs8', privateKey), 234 subtle.exportKey('jwk', publicKey), 235 subtle.exportKey('jwk', privateKey), 236 ]); 237 238 assert(spki); 239 assert(pkcs8); 240 assert(publicJwk); 241 assert(privateJwk); 242 243 const [ 244 importedSpkiPublicKey, 245 importedPkcs8PrivateKey, 246 importedJwkPublicKey, 247 importedJwkPrivateKey, 248 ] = await Promise.all([ 249 subtle.importKey('spki', spki, { 250 name: 'ECDSA', 251 namedCurve: 'P-384' 252 }, true, ['verify']), 253 subtle.importKey('pkcs8', pkcs8, { 254 name: 'ECDSA', 255 namedCurve: 'P-384' 256 }, true, ['sign']), 257 subtle.importKey('jwk', publicJwk, { 258 name: 'ECDSA', 259 namedCurve: 'P-384' 260 }, true, ['verify']), 261 subtle.importKey('jwk', privateJwk, { 262 name: 'ECDSA', 263 namedCurve: 'P-384' 264 }, true, ['sign']), 265 ]); 266 267 assert(importedSpkiPublicKey); 268 assert(importedPkcs8PrivateKey); 269 assert(importedJwkPublicKey); 270 assert(importedJwkPrivateKey); 271 } 272 273 test().then(common.mustCall()); 274} 275