11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst common = require('../common'); 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ciif (!common.hasCrypto) 61cb0ef41Sopenharmony_ci common.skip('missing crypto'); 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ciconst assert = require('assert'); 91cb0ef41Sopenharmony_ciconst { webcrypto } = require('crypto'); 101cb0ef41Sopenharmony_ciconst { subtle } = webcrypto; 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ciconst kTests = [ 131cb0ef41Sopenharmony_ci { 141cb0ef41Sopenharmony_ci name: 'X25519', 151cb0ef41Sopenharmony_ci size: 32, 161cb0ef41Sopenharmony_ci pkcs8: '302e020100300506032b656e04220420c8838e76d057dfb7d8c95a69e138160ad' + 171cb0ef41Sopenharmony_ci 'd6373fd71a4d276bb56e3a81b64ff61', 181cb0ef41Sopenharmony_ci spki: '302a300506032b656e0321001cf2b1e6022ec537371ed7f53e54fa1154d83e98eb' + 191cb0ef41Sopenharmony_ci '64ea51fae5b3307cfe9706', 201cb0ef41Sopenharmony_ci result: '2768409dfab99ec23b8c89b93ff5880295f76176088f89e43dfebe7ea1950008' 211cb0ef41Sopenharmony_ci }, 221cb0ef41Sopenharmony_ci { 231cb0ef41Sopenharmony_ci name: 'X448', 241cb0ef41Sopenharmony_ci size: 56, 251cb0ef41Sopenharmony_ci pkcs8: '3046020100300506032b656f043a043858c7d29a3eb519b29d00cfb191bb64fc6' + 261cb0ef41Sopenharmony_ci 'd8a42d8f17176272b89f2272d1819295c6525c0829671b052ef0727530f188e31' + 271cb0ef41Sopenharmony_ci 'd0cc53bf26929e', 281cb0ef41Sopenharmony_ci spki: '3042300506032b656f033900b604a1d1a5cd1d9426d561ef630a9eb16cbe69d5b9' + 291cb0ef41Sopenharmony_ci 'ca615edc53633efb52ea31e6e6a0a1dbacc6e76cbce6482d7e4ba3d55d9e802765' + 301cb0ef41Sopenharmony_ci 'ce6f', 311cb0ef41Sopenharmony_ci result: 'f0f6c5f17f94f4291eab7178866d37ec8906dd6c514143dc85be7cf28deff39b' 321cb0ef41Sopenharmony_ci }, 331cb0ef41Sopenharmony_ci]; 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ciasync function prepareKeys() { 361cb0ef41Sopenharmony_ci const keys = {}; 371cb0ef41Sopenharmony_ci await Promise.all( 381cb0ef41Sopenharmony_ci kTests.map(async ({ name, size, pkcs8, spki, result }) => { 391cb0ef41Sopenharmony_ci const [ 401cb0ef41Sopenharmony_ci privateKey, 411cb0ef41Sopenharmony_ci publicKey, 421cb0ef41Sopenharmony_ci ] = await Promise.all([ 431cb0ef41Sopenharmony_ci subtle.importKey( 441cb0ef41Sopenharmony_ci 'pkcs8', 451cb0ef41Sopenharmony_ci Buffer.from(pkcs8, 'hex'), 461cb0ef41Sopenharmony_ci { name }, 471cb0ef41Sopenharmony_ci true, 481cb0ef41Sopenharmony_ci ['deriveKey', 'deriveBits']), 491cb0ef41Sopenharmony_ci subtle.importKey( 501cb0ef41Sopenharmony_ci 'spki', 511cb0ef41Sopenharmony_ci Buffer.from(spki, 'hex'), 521cb0ef41Sopenharmony_ci { name }, 531cb0ef41Sopenharmony_ci true, 541cb0ef41Sopenharmony_ci []), 551cb0ef41Sopenharmony_ci ]); 561cb0ef41Sopenharmony_ci keys[name] = { 571cb0ef41Sopenharmony_ci privateKey, 581cb0ef41Sopenharmony_ci publicKey, 591cb0ef41Sopenharmony_ci size, 601cb0ef41Sopenharmony_ci result, 611cb0ef41Sopenharmony_ci }; 621cb0ef41Sopenharmony_ci })); 631cb0ef41Sopenharmony_ci return keys; 641cb0ef41Sopenharmony_ci} 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci(async function() { 671cb0ef41Sopenharmony_ci const keys = await prepareKeys(); 681cb0ef41Sopenharmony_ci const otherArgs = [ 691cb0ef41Sopenharmony_ci { name: 'HMAC', hash: 'SHA-256', length: 256 }, 701cb0ef41Sopenharmony_ci true, 711cb0ef41Sopenharmony_ci ['sign', 'verify']]; 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci await Promise.all( 741cb0ef41Sopenharmony_ci Object.keys(keys).map(async (name) => { 751cb0ef41Sopenharmony_ci const { result, privateKey, publicKey } = keys[name]; 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci { 781cb0ef41Sopenharmony_ci // Good parameters 791cb0ef41Sopenharmony_ci const key = await subtle.deriveKey({ 801cb0ef41Sopenharmony_ci name, 811cb0ef41Sopenharmony_ci public: publicKey 821cb0ef41Sopenharmony_ci }, privateKey, ...otherArgs); 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_ci const raw = await subtle.exportKey('raw', key); 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci assert.strictEqual(Buffer.from(raw).toString('hex'), result); 871cb0ef41Sopenharmony_ci } 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci { 901cb0ef41Sopenharmony_ci // Case insensitivity 911cb0ef41Sopenharmony_ci const key = await subtle.deriveKey({ 921cb0ef41Sopenharmony_ci name: name.toLowerCase(), 931cb0ef41Sopenharmony_ci public: publicKey 941cb0ef41Sopenharmony_ci }, privateKey, { 951cb0ef41Sopenharmony_ci name: 'HmAc', 961cb0ef41Sopenharmony_ci hash: 'SHA-256', 971cb0ef41Sopenharmony_ci length: 256 981cb0ef41Sopenharmony_ci }, true, ['sign', 'verify']); 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci const raw = await subtle.exportKey('raw', key); 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci assert.strictEqual(Buffer.from(raw).toString('hex'), result); 1031cb0ef41Sopenharmony_ci } 1041cb0ef41Sopenharmony_ci })); 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci // Error tests 1071cb0ef41Sopenharmony_ci { 1081cb0ef41Sopenharmony_ci // Missing public property 1091cb0ef41Sopenharmony_ci await assert.rejects( 1101cb0ef41Sopenharmony_ci subtle.deriveKey( 1111cb0ef41Sopenharmony_ci { name: 'X448' }, 1121cb0ef41Sopenharmony_ci keys.X448.privateKey, 1131cb0ef41Sopenharmony_ci ...otherArgs), 1141cb0ef41Sopenharmony_ci { code: 'ERR_MISSING_OPTION' }); 1151cb0ef41Sopenharmony_ci } 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ci { 1181cb0ef41Sopenharmony_ci // The public property is not a CryptoKey 1191cb0ef41Sopenharmony_ci await assert.rejects( 1201cb0ef41Sopenharmony_ci subtle.deriveKey( 1211cb0ef41Sopenharmony_ci { 1221cb0ef41Sopenharmony_ci name: 'X448', 1231cb0ef41Sopenharmony_ci public: { message: 'Not a CryptoKey' } 1241cb0ef41Sopenharmony_ci }, 1251cb0ef41Sopenharmony_ci keys.X448.privateKey, 1261cb0ef41Sopenharmony_ci ...otherArgs), 1271cb0ef41Sopenharmony_ci { code: 'ERR_INVALID_ARG_TYPE' }); 1281cb0ef41Sopenharmony_ci } 1291cb0ef41Sopenharmony_ci 1301cb0ef41Sopenharmony_ci { 1311cb0ef41Sopenharmony_ci // Mismatched named curves 1321cb0ef41Sopenharmony_ci await assert.rejects( 1331cb0ef41Sopenharmony_ci subtle.deriveKey( 1341cb0ef41Sopenharmony_ci { 1351cb0ef41Sopenharmony_ci name: 'X448', 1361cb0ef41Sopenharmony_ci public: keys.X25519.publicKey 1371cb0ef41Sopenharmony_ci }, 1381cb0ef41Sopenharmony_ci keys.X448.privateKey, 1391cb0ef41Sopenharmony_ci ...otherArgs), 1401cb0ef41Sopenharmony_ci { message: 'The public and private keys must be of the same type' }); 1411cb0ef41Sopenharmony_ci } 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_ci { 1441cb0ef41Sopenharmony_ci // Base key is not a private key 1451cb0ef41Sopenharmony_ci await assert.rejects( 1461cb0ef41Sopenharmony_ci subtle.deriveKey( 1471cb0ef41Sopenharmony_ci { 1481cb0ef41Sopenharmony_ci name: 'X448', 1491cb0ef41Sopenharmony_ci public: keys.X448.publicKey 1501cb0ef41Sopenharmony_ci }, 1511cb0ef41Sopenharmony_ci keys.X448.publicKey, 1521cb0ef41Sopenharmony_ci ...otherArgs), 1531cb0ef41Sopenharmony_ci { name: 'InvalidAccessError' }); 1541cb0ef41Sopenharmony_ci } 1551cb0ef41Sopenharmony_ci 1561cb0ef41Sopenharmony_ci { 1571cb0ef41Sopenharmony_ci // Public is not a public key 1581cb0ef41Sopenharmony_ci await assert.rejects( 1591cb0ef41Sopenharmony_ci subtle.deriveKey( 1601cb0ef41Sopenharmony_ci { 1611cb0ef41Sopenharmony_ci name: 'X448', 1621cb0ef41Sopenharmony_ci public: keys.X448.privateKey 1631cb0ef41Sopenharmony_ci }, 1641cb0ef41Sopenharmony_ci keys.X448.privateKey, 1651cb0ef41Sopenharmony_ci ...otherArgs), 1661cb0ef41Sopenharmony_ci { name: 'InvalidAccessError' }); 1671cb0ef41Sopenharmony_ci } 1681cb0ef41Sopenharmony_ci 1691cb0ef41Sopenharmony_ci { 1701cb0ef41Sopenharmony_ci // Public is a secret key 1711cb0ef41Sopenharmony_ci const keyData = webcrypto.getRandomValues(new Uint8Array(32)); 1721cb0ef41Sopenharmony_ci const key = await subtle.importKey( 1731cb0ef41Sopenharmony_ci 'raw', 1741cb0ef41Sopenharmony_ci keyData, 1751cb0ef41Sopenharmony_ci { name: 'AES-CBC', length: 256 }, 1761cb0ef41Sopenharmony_ci false, ['encrypt']); 1771cb0ef41Sopenharmony_ci 1781cb0ef41Sopenharmony_ci await assert.rejects( 1791cb0ef41Sopenharmony_ci subtle.deriveKey( 1801cb0ef41Sopenharmony_ci { 1811cb0ef41Sopenharmony_ci name: 'X448', 1821cb0ef41Sopenharmony_ci public: key 1831cb0ef41Sopenharmony_ci }, 1841cb0ef41Sopenharmony_ci keys.X448.publicKey, 1851cb0ef41Sopenharmony_ci ...otherArgs), 1861cb0ef41Sopenharmony_ci { name: 'InvalidAccessError' }); 1871cb0ef41Sopenharmony_ci } 1881cb0ef41Sopenharmony_ci})().then(common.mustCall()); 189