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 namedCurve: 'P-521', 151cb0ef41Sopenharmony_ci pkcs8: '3081ee020100301006072a8648ce3d020106052b810400230481d63081d302010' + 161cb0ef41Sopenharmony_ci '1044201a67ed321915a64aa359b7d648ddc2618fa8e8d1867e8f71830b10d25ed' + 171cb0ef41Sopenharmony_ci '2891faf12f3c7e75421a2ea264f9a915320d274fe1470742b984e96b98912081f' + 181cb0ef41Sopenharmony_ci 'acd478da18189038186000400209d483f28666881c6641f3a126f400f51e46511' + 191cb0ef41Sopenharmony_ci '70fe678c75e85712e2868adc850824997bebf0bc82b43028a6d2ec1777ca45279' + 201cb0ef41Sopenharmony_ci 'f7206a3ea8b5cd2073f493e45000cb54c3a5acaa268c56710428878d98b8afbf6' + 211cb0ef41Sopenharmony_ci '8a612153632846d807e92672698f1b9c611de7d38e34cd6c73889092c56e52d68' + 221cb0ef41Sopenharmony_ci '0f1dfd092b87ac8ef9ff3c8fb48', 231cb0ef41Sopenharmony_ci spki: '30819b301006072a8648ce3d020106052b81040023038186000400ee69f94715d7' + 241cb0ef41Sopenharmony_ci '01e9e2011333d4f4f96cba7d91f88b112baf75cf09cc1f8aca97618da9389822d2' + 251cb0ef41Sopenharmony_ci '9b6fe9996a61203ef752b771e8958fc4677bb3778565ab60d6ed00deab6761895b' + 261cb0ef41Sopenharmony_ci '935e3ad325fb8549e56f13786aa73f88a2ecfe40933473d8aef240c4dfd7d506f2' + 271cb0ef41Sopenharmony_ci '2cdd0e55558f3fbf05ebf7efef7a72d78f46469b8448f26e2712', 281cb0ef41Sopenharmony_ci result: '009c2bce57be80adab3b07385b8e5990eb7d6fdebdb01bf35371a4f6075e9d28', 291cb0ef41Sopenharmony_ci }, 301cb0ef41Sopenharmony_ci { 311cb0ef41Sopenharmony_ci namedCurve: 'P-384', 321cb0ef41Sopenharmony_ci pkcs8: '3081b6020100301006072a8648ce3d020106052b8104002204819e30819b02010' + 331cb0ef41Sopenharmony_ci '10430f871a5666589c14a5747263ef85b319cc023db6e35676c3d781eef8b055f' + 341cb0ef41Sopenharmony_ci 'cfbe86fa0d06d056b5195fb1323af8de25b3a16403620004f11965df7dd4594d0' + 351cb0ef41Sopenharmony_ci '419c5086482a3b826b9797f9be0bd0d109c9e1e9989c1b9a92b8f269f98e17ad1' + 361cb0ef41Sopenharmony_ci '84ba73c1f79762af45af8141602642da271a6bb0ffeb0cb4478fcf707e661aa6d' + 371cb0ef41Sopenharmony_ci '6cdf51549c88c3f130be9e8201f6f6a09f4185aaf95c4', 381cb0ef41Sopenharmony_ci spki: '3076301006072a8648ce3d020106052b810400220362000491822dc2af59c18f5b' + 391cb0ef41Sopenharmony_ci '67f80df61a2603c2a8f0b3c0af822d63c279701a824560404401dde9a56ee52757' + 401cb0ef41Sopenharmony_ci 'ea8bc748d4c82b5337b48d7b65583a3d572438880036bac6730f42ca5278966bd5' + 411cb0ef41Sopenharmony_ci 'f21e86e21d30c5a6d0463ec513dd509ffcdcaf1ff5', 421cb0ef41Sopenharmony_ci result: 'e0bd6bce0aef8ca48838a6e2fcc57e67b9c5e8860c5f0be9dabec53e454e18a0', 431cb0ef41Sopenharmony_ci }, 441cb0ef41Sopenharmony_ci]; 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ciasync function prepareKeys() { 471cb0ef41Sopenharmony_ci const keys = {}; 481cb0ef41Sopenharmony_ci await Promise.all( 491cb0ef41Sopenharmony_ci kTests.map(async ({ namedCurve, size, pkcs8, spki, result }) => { 501cb0ef41Sopenharmony_ci const [ 511cb0ef41Sopenharmony_ci privateKey, 521cb0ef41Sopenharmony_ci publicKey, 531cb0ef41Sopenharmony_ci ] = await Promise.all([ 541cb0ef41Sopenharmony_ci subtle.importKey( 551cb0ef41Sopenharmony_ci 'pkcs8', 561cb0ef41Sopenharmony_ci Buffer.from(pkcs8, 'hex'), 571cb0ef41Sopenharmony_ci { 581cb0ef41Sopenharmony_ci name: 'ECDH', 591cb0ef41Sopenharmony_ci namedCurve 601cb0ef41Sopenharmony_ci }, 611cb0ef41Sopenharmony_ci true, 621cb0ef41Sopenharmony_ci ['deriveKey', 'deriveBits']), 631cb0ef41Sopenharmony_ci subtle.importKey( 641cb0ef41Sopenharmony_ci 'spki', 651cb0ef41Sopenharmony_ci Buffer.from(spki, 'hex'), 661cb0ef41Sopenharmony_ci { 671cb0ef41Sopenharmony_ci name: 'ECDH', 681cb0ef41Sopenharmony_ci namedCurve 691cb0ef41Sopenharmony_ci }, 701cb0ef41Sopenharmony_ci true, 711cb0ef41Sopenharmony_ci []), 721cb0ef41Sopenharmony_ci ]); 731cb0ef41Sopenharmony_ci keys[namedCurve] = { 741cb0ef41Sopenharmony_ci privateKey, 751cb0ef41Sopenharmony_ci publicKey, 761cb0ef41Sopenharmony_ci size, 771cb0ef41Sopenharmony_ci result, 781cb0ef41Sopenharmony_ci }; 791cb0ef41Sopenharmony_ci })); 801cb0ef41Sopenharmony_ci return keys; 811cb0ef41Sopenharmony_ci} 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci(async function() { 841cb0ef41Sopenharmony_ci const keys = await prepareKeys(); 851cb0ef41Sopenharmony_ci const otherArgs = [ 861cb0ef41Sopenharmony_ci { name: 'HMAC', hash: 'SHA-256', length: 256 }, 871cb0ef41Sopenharmony_ci true, 881cb0ef41Sopenharmony_ci ['sign', 'verify']]; 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci await Promise.all( 911cb0ef41Sopenharmony_ci Object.keys(keys).map(async (namedCurve) => { 921cb0ef41Sopenharmony_ci const { result, privateKey, publicKey } = keys[namedCurve]; 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ci { 951cb0ef41Sopenharmony_ci // Good parameters 961cb0ef41Sopenharmony_ci const key = await subtle.deriveKey({ 971cb0ef41Sopenharmony_ci name: 'ECDH', 981cb0ef41Sopenharmony_ci public: publicKey 991cb0ef41Sopenharmony_ci }, privateKey, ...otherArgs); 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci const raw = await subtle.exportKey('raw', key); 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ci assert.strictEqual(Buffer.from(raw).toString('hex'), result); 1041cb0ef41Sopenharmony_ci } 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci { 1071cb0ef41Sopenharmony_ci // Case insensitivity 1081cb0ef41Sopenharmony_ci const key = await subtle.deriveKey({ 1091cb0ef41Sopenharmony_ci name: 'eCdH', 1101cb0ef41Sopenharmony_ci public: publicKey 1111cb0ef41Sopenharmony_ci }, privateKey, { 1121cb0ef41Sopenharmony_ci name: 'HmAc', 1131cb0ef41Sopenharmony_ci hash: 'SHA-256', 1141cb0ef41Sopenharmony_ci length: 256 1151cb0ef41Sopenharmony_ci }, true, ['sign', 'verify']); 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ci const raw = await subtle.exportKey('raw', key); 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci assert.strictEqual(Buffer.from(raw).toString('hex'), result); 1201cb0ef41Sopenharmony_ci } 1211cb0ef41Sopenharmony_ci })); 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ci // Error tests 1241cb0ef41Sopenharmony_ci { 1251cb0ef41Sopenharmony_ci // Missing public property 1261cb0ef41Sopenharmony_ci await assert.rejects( 1271cb0ef41Sopenharmony_ci subtle.deriveKey( 1281cb0ef41Sopenharmony_ci { name: 'ECDH' }, 1291cb0ef41Sopenharmony_ci keys['P-384'].privateKey, 1301cb0ef41Sopenharmony_ci ...otherArgs), 1311cb0ef41Sopenharmony_ci { code: 'ERR_MISSING_OPTION' }); 1321cb0ef41Sopenharmony_ci } 1331cb0ef41Sopenharmony_ci 1341cb0ef41Sopenharmony_ci { 1351cb0ef41Sopenharmony_ci // The public property is not a CryptoKey 1361cb0ef41Sopenharmony_ci await assert.rejects( 1371cb0ef41Sopenharmony_ci subtle.deriveKey( 1381cb0ef41Sopenharmony_ci { 1391cb0ef41Sopenharmony_ci name: 'ECDH', 1401cb0ef41Sopenharmony_ci public: { message: 'Not a CryptoKey' } 1411cb0ef41Sopenharmony_ci }, 1421cb0ef41Sopenharmony_ci keys['P-384'].privateKey, 1431cb0ef41Sopenharmony_ci ...otherArgs), 1441cb0ef41Sopenharmony_ci { code: 'ERR_INVALID_ARG_TYPE' }); 1451cb0ef41Sopenharmony_ci } 1461cb0ef41Sopenharmony_ci 1471cb0ef41Sopenharmony_ci { 1481cb0ef41Sopenharmony_ci // Mismatched named curves 1491cb0ef41Sopenharmony_ci await assert.rejects( 1501cb0ef41Sopenharmony_ci subtle.deriveKey( 1511cb0ef41Sopenharmony_ci { 1521cb0ef41Sopenharmony_ci name: 'ECDH', 1531cb0ef41Sopenharmony_ci public: keys['P-384'].publicKey 1541cb0ef41Sopenharmony_ci }, 1551cb0ef41Sopenharmony_ci keys['P-521'].privateKey, 1561cb0ef41Sopenharmony_ci ...otherArgs), 1571cb0ef41Sopenharmony_ci { message: /Named curve mismatch/ }); 1581cb0ef41Sopenharmony_ci } 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_ci { 1611cb0ef41Sopenharmony_ci // Incorrect public key algorithm 1621cb0ef41Sopenharmony_ci const { publicKey } = await subtle.generateKey( 1631cb0ef41Sopenharmony_ci { 1641cb0ef41Sopenharmony_ci name: 'ECDSA', 1651cb0ef41Sopenharmony_ci namedCurve: 'P-521' 1661cb0ef41Sopenharmony_ci }, 1671cb0ef41Sopenharmony_ci false, 1681cb0ef41Sopenharmony_ci ['sign', 'verify']); 1691cb0ef41Sopenharmony_ci 1701cb0ef41Sopenharmony_ci await assert.rejects( 1711cb0ef41Sopenharmony_ci subtle.deriveKey( 1721cb0ef41Sopenharmony_ci { 1731cb0ef41Sopenharmony_ci name: 'ECDH', 1741cb0ef41Sopenharmony_ci public: publicKey 1751cb0ef41Sopenharmony_ci }, 1761cb0ef41Sopenharmony_ci keys['P-521'].privateKey, 1771cb0ef41Sopenharmony_ci ...otherArgs), 1781cb0ef41Sopenharmony_ci { message: /Keys must be ECDH, X25519, or X448 keys/ }); 1791cb0ef41Sopenharmony_ci } 1801cb0ef41Sopenharmony_ci 1811cb0ef41Sopenharmony_ci { 1821cb0ef41Sopenharmony_ci // Private key does not have correct usages 1831cb0ef41Sopenharmony_ci const privateKey = await subtle.importKey( 1841cb0ef41Sopenharmony_ci 'pkcs8', 1851cb0ef41Sopenharmony_ci Buffer.from(kTests[0].pkcs8, 'hex'), 1861cb0ef41Sopenharmony_ci { 1871cb0ef41Sopenharmony_ci name: 'ECDH', 1881cb0ef41Sopenharmony_ci namedCurve: 'P-521' 1891cb0ef41Sopenharmony_ci }, false, ['deriveBits']); 1901cb0ef41Sopenharmony_ci 1911cb0ef41Sopenharmony_ci await assert.rejects( 1921cb0ef41Sopenharmony_ci subtle.deriveKey( 1931cb0ef41Sopenharmony_ci { 1941cb0ef41Sopenharmony_ci name: 'ECDH', 1951cb0ef41Sopenharmony_ci public: keys['P-521'].publicKey, 1961cb0ef41Sopenharmony_ci }, 1971cb0ef41Sopenharmony_ci privateKey, 1981cb0ef41Sopenharmony_ci ...otherArgs), 1991cb0ef41Sopenharmony_ci { message: /baseKey does not have deriveKey usage/ }); 2001cb0ef41Sopenharmony_ci } 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_ci { 2031cb0ef41Sopenharmony_ci // Base key is not a private key 2041cb0ef41Sopenharmony_ci await assert.rejects( 2051cb0ef41Sopenharmony_ci subtle.deriveKey( 2061cb0ef41Sopenharmony_ci { 2071cb0ef41Sopenharmony_ci name: 'ECDH', 2081cb0ef41Sopenharmony_ci public: keys['P-521'].publicKey 2091cb0ef41Sopenharmony_ci }, 2101cb0ef41Sopenharmony_ci keys['P-521'].publicKey, 2111cb0ef41Sopenharmony_ci ...otherArgs), 2121cb0ef41Sopenharmony_ci { name: 'InvalidAccessError' }); 2131cb0ef41Sopenharmony_ci } 2141cb0ef41Sopenharmony_ci 2151cb0ef41Sopenharmony_ci { 2161cb0ef41Sopenharmony_ci // Base key is not a private key 2171cb0ef41Sopenharmony_ci await assert.rejects( 2181cb0ef41Sopenharmony_ci subtle.deriveKey( 2191cb0ef41Sopenharmony_ci { 2201cb0ef41Sopenharmony_ci name: 'ECDH', 2211cb0ef41Sopenharmony_ci public: keys['P-521'].privateKey 2221cb0ef41Sopenharmony_ci }, 2231cb0ef41Sopenharmony_ci keys['P-521'].publicKey, 2241cb0ef41Sopenharmony_ci ...otherArgs), 2251cb0ef41Sopenharmony_ci { name: 'InvalidAccessError' }); 2261cb0ef41Sopenharmony_ci } 2271cb0ef41Sopenharmony_ci 2281cb0ef41Sopenharmony_ci { 2291cb0ef41Sopenharmony_ci // Public is a secret key 2301cb0ef41Sopenharmony_ci const keyData = webcrypto.getRandomValues(new Uint8Array(32)); 2311cb0ef41Sopenharmony_ci const key = await subtle.importKey( 2321cb0ef41Sopenharmony_ci 'raw', 2331cb0ef41Sopenharmony_ci keyData, 2341cb0ef41Sopenharmony_ci { name: 'AES-CBC', length: 256 }, 2351cb0ef41Sopenharmony_ci false, ['encrypt']); 2361cb0ef41Sopenharmony_ci 2371cb0ef41Sopenharmony_ci await assert.rejects( 2381cb0ef41Sopenharmony_ci subtle.deriveKey( 2391cb0ef41Sopenharmony_ci { 2401cb0ef41Sopenharmony_ci name: 'ECDH', 2411cb0ef41Sopenharmony_ci public: key 2421cb0ef41Sopenharmony_ci }, 2431cb0ef41Sopenharmony_ci keys['P-521'].publicKey, 2441cb0ef41Sopenharmony_ci ...otherArgs), 2451cb0ef41Sopenharmony_ci { name: 'InvalidAccessError' }); 2461cb0ef41Sopenharmony_ci } 2471cb0ef41Sopenharmony_ci})().then(common.mustCall()); 248