11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst common = require('../common'); 41cb0ef41Sopenharmony_ciconst fixtures = require('../common/fixtures'); 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_ciif (!common.hasCrypto) 71cb0ef41Sopenharmony_ci common.skip('missing crypto'); 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ciconst assert = require('assert'); 101cb0ef41Sopenharmony_ciconst crypto = require('crypto'); 111cb0ef41Sopenharmony_ciconst { subtle } = crypto.webcrypto; 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ciconst curves = ['P-256', 'P-384', 'P-521']; 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ciconst keyData = { 161cb0ef41Sopenharmony_ci 'P-521': { 171cb0ef41Sopenharmony_ci jwsAlg: 'ES512', 181cb0ef41Sopenharmony_ci spki: Buffer.from( 191cb0ef41Sopenharmony_ci '30819b301006072a8648ce3d020106052b8104002303818600040156f479f8df' + 201cb0ef41Sopenharmony_ci '1e20a7ffc04ce420c3e154ae251996bee42f034b84d41b743f34e45f311b813a' + 211cb0ef41Sopenharmony_ci '9cdec8cda59bbbbd31d460b3292521e7c1b722e5667c03db2fae753f01501736' + 221cb0ef41Sopenharmony_ci 'cfe247394320d8e4afc2fd39b5a9331061b81e2241282b9e17891822b5b79e05' + 231cb0ef41Sopenharmony_ci '2f4597b59643fd39379c51bd5125c4f48bc3f025ce3cd36953286ccb38fb', 241cb0ef41Sopenharmony_ci 'hex'), 251cb0ef41Sopenharmony_ci pkcs8: Buffer.from( 261cb0ef41Sopenharmony_ci '3081ee020100301006072a8648ce3d020106052b810400230481d63081d3020' + 271cb0ef41Sopenharmony_ci '101044200f408758368ba930f30f76ae054fe5cd2ce7fda2c9f76a6d436cf75' + 281cb0ef41Sopenharmony_ci 'd66c440bfe6331c7c172a12478193c8251487bc91263fa50217f85ff636f59c' + 291cb0ef41Sopenharmony_ci 'd546e3ab483b4a1818903818600040156f479f8df1e20a7ffc04ce420c3e154' + 301cb0ef41Sopenharmony_ci 'ae251996bee42f034b84d41b743f34e45f311b813a9cdec8cda59bbbbd31d46' + 311cb0ef41Sopenharmony_ci '0b3292521e7c1b722e5667c03db2fae753f01501736cfe247394320d8e4afc2' + 321cb0ef41Sopenharmony_ci 'fd39b5a9331061b81e2241282b9e17891822b5b79e052f4597b59643fd39379' + 331cb0ef41Sopenharmony_ci 'c51bd5125c4f48bc3f025ce3cd36953286ccb38fb', 'hex'), 341cb0ef41Sopenharmony_ci jwk: { 351cb0ef41Sopenharmony_ci kty: 'EC', 361cb0ef41Sopenharmony_ci crv: 'P-521', 371cb0ef41Sopenharmony_ci x: 'AVb0efjfHiCn_8BM5CDD4VSuJRmWvuQvA0uE1Bt0PzTkXzEbgTqc3sjN' + 381cb0ef41Sopenharmony_ci 'pZu7vTHUYLMpJSHnwbci5WZ8A9svrnU_', 391cb0ef41Sopenharmony_ci y: 'AVAXNs_iRzlDINjkr8L9ObWpMxBhuB4iQSgrnheJGCK1t54FL0W' + 401cb0ef41Sopenharmony_ci 'XtZZD_Tk3nFG9USXE9IvD8CXOPNNpUyhsyzj7', 411cb0ef41Sopenharmony_ci d: 'APQIdYNoupMPMPdq4FT-XNLOf9osn3am1DbPddZsRAv-YzHHw' + 421cb0ef41Sopenharmony_ci 'XKhJHgZPIJRSHvJEmP6UCF_hf9jb1nNVG46tIO0' 431cb0ef41Sopenharmony_ci } 441cb0ef41Sopenharmony_ci }, 451cb0ef41Sopenharmony_ci 'P-384': { 461cb0ef41Sopenharmony_ci jwsAlg: 'ES384', 471cb0ef41Sopenharmony_ci spki: Buffer.from( 481cb0ef41Sopenharmony_ci '3076301006072a8648ce3d020106052b8104002203620004219c14d66617b36e' + 491cb0ef41Sopenharmony_ci 'c6d8856b385b73a74d344fd8ae75ef046435dda54e3b44bd5fbdebd1d08dd69e' + 501cb0ef41Sopenharmony_ci '2d7dc1dc218cb435bd28138cc778337a842f6bd61b240e74249f24667c2a5810' + 511cb0ef41Sopenharmony_ci 'a76bfc28e0335f88a6501dec01976da85afb00869cb6ace8', 'hex'), 521cb0ef41Sopenharmony_ci pkcs8: Buffer.from( 531cb0ef41Sopenharmony_ci '3081b6020100301006072a8648ce3d020106052b8104002204819e30819b0201' + 541cb0ef41Sopenharmony_ci '0104304537b5990784d3c2d22e96a8f92fa1aa492ee873e576a41582e144183c' + 551cb0ef41Sopenharmony_ci '9888d10e6b9eb4ced4b2cc4012e4ac5ea84073a16403620004219c14d66617b3' + 561cb0ef41Sopenharmony_ci '6ec6d8856b385b73a74d344fd8ae75ef046435dda54e3b44bd5fbdebd1d08dd6' + 571cb0ef41Sopenharmony_ci '9e2d7dc1dc218cb435bd28138cc778337a842f6bd61b240e74249f24667c2a58' + 581cb0ef41Sopenharmony_ci '10a76bfc28e0335f88a6501dec01976da85afb00869cb6ace8', 'hex'), 591cb0ef41Sopenharmony_ci jwk: { 601cb0ef41Sopenharmony_ci kty: 'EC', 611cb0ef41Sopenharmony_ci crv: 'P-384', 621cb0ef41Sopenharmony_ci x: 'IZwU1mYXs27G2IVrOFtzp000T9iude8EZDXdpU47RL1fvevR0I3Wni19wdwhjLQ1', 631cb0ef41Sopenharmony_ci y: 'vSgTjMd4M3qEL2vWGyQOdCSfJGZ8KlgQp2v8KOAzX4imUB3sAZdtqFr7AIactqzo', 641cb0ef41Sopenharmony_ci d: 'RTe1mQeE08LSLpao-S-hqkku6HPldqQVguFEGDyYiNEOa560ztSyzEAS5KxeqEBz' 651cb0ef41Sopenharmony_ci } 661cb0ef41Sopenharmony_ci }, 671cb0ef41Sopenharmony_ci 'P-256': { 681cb0ef41Sopenharmony_ci jwsAlg: 'ES256', 691cb0ef41Sopenharmony_ci spki: Buffer.from( 701cb0ef41Sopenharmony_ci '3059301306072a8648ce3d020106082a8648ce3d03010703420004d6e8328a95' + 711cb0ef41Sopenharmony_ci 'fe29afcdc30977b9251efbb219022807f6b14bb34695b6b4bdb93ee6684548a4' + 721cb0ef41Sopenharmony_ci 'ad13c49d00433c45315e8274f3540f58f5d79ef7a1b184f4c21d17', 'hex'), 731cb0ef41Sopenharmony_ci pkcs8: Buffer.from( 741cb0ef41Sopenharmony_ci '308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02' + 751cb0ef41Sopenharmony_ci '010104202bc2eda265e46866efa8f8f99da993175b6c85c246e15dceaed7e307' + 761cb0ef41Sopenharmony_ci '0f13fbf8a14403420004d6e8328a95fe29afcdc30977b9251efbb219022807f6' + 771cb0ef41Sopenharmony_ci 'b14bb34695b6b4bdb93ee6684548a4ad13c49d00433c45315e8274f3540f58f5' + 781cb0ef41Sopenharmony_ci 'd79ef7a1b184f4c21d17', 'hex'), 791cb0ef41Sopenharmony_ci jwk: { 801cb0ef41Sopenharmony_ci kty: 'EC', 811cb0ef41Sopenharmony_ci crv: 'P-256', 821cb0ef41Sopenharmony_ci x: '1ugyipX-Ka_Nwwl3uSUe-7IZAigH9rFLs0aVtrS9uT4', 831cb0ef41Sopenharmony_ci y: '5mhFSKStE8SdAEM8RTFegnTzVA9Y9dee96GxhPTCHRc', 841cb0ef41Sopenharmony_ci d: 'K8LtomXkaGbvqPj5namTF1tshcJG4V3OrtfjBw8T-_g' 851cb0ef41Sopenharmony_ci } 861cb0ef41Sopenharmony_ci }, 871cb0ef41Sopenharmony_ci}; 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ciconst testVectors = [ 901cb0ef41Sopenharmony_ci { 911cb0ef41Sopenharmony_ci name: 'ECDSA', 921cb0ef41Sopenharmony_ci privateUsages: ['sign'], 931cb0ef41Sopenharmony_ci publicUsages: ['verify'] 941cb0ef41Sopenharmony_ci }, 951cb0ef41Sopenharmony_ci { 961cb0ef41Sopenharmony_ci name: 'ECDH', 971cb0ef41Sopenharmony_ci privateUsages: ['deriveKey', 'deriveBits'], 981cb0ef41Sopenharmony_ci publicUsages: [] 991cb0ef41Sopenharmony_ci }, 1001cb0ef41Sopenharmony_ci]; 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ciasync function testImportSpki({ name, publicUsages }, namedCurve, extractable) { 1031cb0ef41Sopenharmony_ci const key = await subtle.importKey( 1041cb0ef41Sopenharmony_ci 'spki', 1051cb0ef41Sopenharmony_ci keyData[namedCurve].spki, 1061cb0ef41Sopenharmony_ci { name, namedCurve }, 1071cb0ef41Sopenharmony_ci extractable, 1081cb0ef41Sopenharmony_ci publicUsages); 1091cb0ef41Sopenharmony_ci assert.strictEqual(key.type, 'public'); 1101cb0ef41Sopenharmony_ci assert.strictEqual(key.extractable, extractable); 1111cb0ef41Sopenharmony_ci assert.deepStrictEqual(key.usages, publicUsages); 1121cb0ef41Sopenharmony_ci assert.deepStrictEqual(key.algorithm.name, name); 1131cb0ef41Sopenharmony_ci assert.deepStrictEqual(key.algorithm.namedCurve, namedCurve); 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci if (extractable) { 1161cb0ef41Sopenharmony_ci // Test the roundtrip 1171cb0ef41Sopenharmony_ci const spki = await subtle.exportKey('spki', key); 1181cb0ef41Sopenharmony_ci assert.strictEqual( 1191cb0ef41Sopenharmony_ci Buffer.from(spki).toString('hex'), 1201cb0ef41Sopenharmony_ci keyData[namedCurve].spki.toString('hex')); 1211cb0ef41Sopenharmony_ci } else { 1221cb0ef41Sopenharmony_ci await assert.rejects( 1231cb0ef41Sopenharmony_ci subtle.exportKey('spki', key), { 1241cb0ef41Sopenharmony_ci message: /key is not extractable/ 1251cb0ef41Sopenharmony_ci }); 1261cb0ef41Sopenharmony_ci } 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_ci // Bad usage 1291cb0ef41Sopenharmony_ci await assert.rejects( 1301cb0ef41Sopenharmony_ci subtle.importKey( 1311cb0ef41Sopenharmony_ci 'spki', 1321cb0ef41Sopenharmony_ci keyData[namedCurve].spki, 1331cb0ef41Sopenharmony_ci { name, namedCurve }, 1341cb0ef41Sopenharmony_ci extractable, 1351cb0ef41Sopenharmony_ci ['wrapKey']), 1361cb0ef41Sopenharmony_ci { message: /Unsupported key usage/ }); 1371cb0ef41Sopenharmony_ci} 1381cb0ef41Sopenharmony_ci 1391cb0ef41Sopenharmony_ciasync function testImportPkcs8( 1401cb0ef41Sopenharmony_ci { name, privateUsages }, 1411cb0ef41Sopenharmony_ci namedCurve, 1421cb0ef41Sopenharmony_ci extractable) { 1431cb0ef41Sopenharmony_ci const key = await subtle.importKey( 1441cb0ef41Sopenharmony_ci 'pkcs8', 1451cb0ef41Sopenharmony_ci keyData[namedCurve].pkcs8, 1461cb0ef41Sopenharmony_ci { name, namedCurve }, 1471cb0ef41Sopenharmony_ci extractable, 1481cb0ef41Sopenharmony_ci privateUsages); 1491cb0ef41Sopenharmony_ci assert.strictEqual(key.type, 'private'); 1501cb0ef41Sopenharmony_ci assert.strictEqual(key.extractable, extractable); 1511cb0ef41Sopenharmony_ci assert.deepStrictEqual(key.usages, privateUsages); 1521cb0ef41Sopenharmony_ci assert.deepStrictEqual(key.algorithm.name, name); 1531cb0ef41Sopenharmony_ci assert.deepStrictEqual(key.algorithm.namedCurve, namedCurve); 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_ci if (extractable) { 1561cb0ef41Sopenharmony_ci // Test the roundtrip 1571cb0ef41Sopenharmony_ci const pkcs8 = await subtle.exportKey('pkcs8', key); 1581cb0ef41Sopenharmony_ci assert.strictEqual( 1591cb0ef41Sopenharmony_ci Buffer.from(pkcs8).toString('hex'), 1601cb0ef41Sopenharmony_ci keyData[namedCurve].pkcs8.toString('hex')); 1611cb0ef41Sopenharmony_ci } else { 1621cb0ef41Sopenharmony_ci await assert.rejects( 1631cb0ef41Sopenharmony_ci subtle.exportKey('pkcs8', key), { 1641cb0ef41Sopenharmony_ci message: /key is not extractable/ 1651cb0ef41Sopenharmony_ci }); 1661cb0ef41Sopenharmony_ci } 1671cb0ef41Sopenharmony_ci 1681cb0ef41Sopenharmony_ci await assert.rejects( 1691cb0ef41Sopenharmony_ci subtle.importKey( 1701cb0ef41Sopenharmony_ci 'pkcs8', 1711cb0ef41Sopenharmony_ci keyData[namedCurve].pkcs8, 1721cb0ef41Sopenharmony_ci { name, namedCurve }, 1731cb0ef41Sopenharmony_ci extractable, 1741cb0ef41Sopenharmony_ci [/* empty usages */]), 1751cb0ef41Sopenharmony_ci { name: 'SyntaxError', message: 'Usages cannot be empty when importing a private key.' }); 1761cb0ef41Sopenharmony_ci} 1771cb0ef41Sopenharmony_ci 1781cb0ef41Sopenharmony_ciasync function testImportJwk( 1791cb0ef41Sopenharmony_ci { name, publicUsages, privateUsages }, 1801cb0ef41Sopenharmony_ci namedCurve, 1811cb0ef41Sopenharmony_ci extractable) { 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ci const jwk = keyData[namedCurve].jwk; 1841cb0ef41Sopenharmony_ci 1851cb0ef41Sopenharmony_ci const [ 1861cb0ef41Sopenharmony_ci publicKey, 1871cb0ef41Sopenharmony_ci privateKey, 1881cb0ef41Sopenharmony_ci ] = await Promise.all([ 1891cb0ef41Sopenharmony_ci subtle.importKey( 1901cb0ef41Sopenharmony_ci 'jwk', 1911cb0ef41Sopenharmony_ci { 1921cb0ef41Sopenharmony_ci kty: jwk.kty, 1931cb0ef41Sopenharmony_ci crv: jwk.crv, 1941cb0ef41Sopenharmony_ci x: jwk.x, 1951cb0ef41Sopenharmony_ci y: jwk.y, 1961cb0ef41Sopenharmony_ci }, 1971cb0ef41Sopenharmony_ci { name, namedCurve }, 1981cb0ef41Sopenharmony_ci extractable, publicUsages), 1991cb0ef41Sopenharmony_ci subtle.importKey( 2001cb0ef41Sopenharmony_ci 'jwk', 2011cb0ef41Sopenharmony_ci jwk, 2021cb0ef41Sopenharmony_ci { name, namedCurve }, 2031cb0ef41Sopenharmony_ci extractable, 2041cb0ef41Sopenharmony_ci privateUsages), 2051cb0ef41Sopenharmony_ci subtle.importKey( 2061cb0ef41Sopenharmony_ci 'jwk', 2071cb0ef41Sopenharmony_ci { 2081cb0ef41Sopenharmony_ci alg: name === 'ECDSA' ? keyData[namedCurve].jwsAlg : 'ECDH-ES', 2091cb0ef41Sopenharmony_ci kty: jwk.kty, 2101cb0ef41Sopenharmony_ci crv: jwk.crv, 2111cb0ef41Sopenharmony_ci x: jwk.x, 2121cb0ef41Sopenharmony_ci y: jwk.y, 2131cb0ef41Sopenharmony_ci }, 2141cb0ef41Sopenharmony_ci { name, namedCurve }, 2151cb0ef41Sopenharmony_ci extractable, publicUsages), 2161cb0ef41Sopenharmony_ci subtle.importKey( 2171cb0ef41Sopenharmony_ci 'jwk', 2181cb0ef41Sopenharmony_ci { 2191cb0ef41Sopenharmony_ci ...jwk, 2201cb0ef41Sopenharmony_ci alg: name === 'ECDSA' ? keyData[namedCurve].jwsAlg : 'ECDH-ES', 2211cb0ef41Sopenharmony_ci }, 2221cb0ef41Sopenharmony_ci { name, namedCurve }, 2231cb0ef41Sopenharmony_ci extractable, 2241cb0ef41Sopenharmony_ci privateUsages), 2251cb0ef41Sopenharmony_ci ]); 2261cb0ef41Sopenharmony_ci 2271cb0ef41Sopenharmony_ci assert.strictEqual(publicKey.type, 'public'); 2281cb0ef41Sopenharmony_ci assert.strictEqual(privateKey.type, 'private'); 2291cb0ef41Sopenharmony_ci assert.strictEqual(publicKey.extractable, extractable); 2301cb0ef41Sopenharmony_ci assert.strictEqual(privateKey.extractable, extractable); 2311cb0ef41Sopenharmony_ci assert.deepStrictEqual(publicKey.usages, publicUsages); 2321cb0ef41Sopenharmony_ci assert.deepStrictEqual(privateKey.usages, privateUsages); 2331cb0ef41Sopenharmony_ci assert.strictEqual(publicKey.algorithm.name, name); 2341cb0ef41Sopenharmony_ci assert.strictEqual(privateKey.algorithm.name, name); 2351cb0ef41Sopenharmony_ci assert.strictEqual(publicKey.algorithm.namedCurve, namedCurve); 2361cb0ef41Sopenharmony_ci assert.strictEqual(privateKey.algorithm.namedCurve, namedCurve); 2371cb0ef41Sopenharmony_ci 2381cb0ef41Sopenharmony_ci if (extractable) { 2391cb0ef41Sopenharmony_ci // Test the round trip 2401cb0ef41Sopenharmony_ci const [ 2411cb0ef41Sopenharmony_ci pubJwk, 2421cb0ef41Sopenharmony_ci pvtJwk, 2431cb0ef41Sopenharmony_ci ] = await Promise.all([ 2441cb0ef41Sopenharmony_ci subtle.exportKey('jwk', publicKey), 2451cb0ef41Sopenharmony_ci subtle.exportKey('jwk', privateKey), 2461cb0ef41Sopenharmony_ci ]); 2471cb0ef41Sopenharmony_ci 2481cb0ef41Sopenharmony_ci assert.deepStrictEqual(pubJwk.key_ops, publicUsages); 2491cb0ef41Sopenharmony_ci assert.strictEqual(pubJwk.ext, true); 2501cb0ef41Sopenharmony_ci assert.strictEqual(pubJwk.kty, 'EC'); 2511cb0ef41Sopenharmony_ci assert.strictEqual(pubJwk.x, jwk.x); 2521cb0ef41Sopenharmony_ci assert.strictEqual(pubJwk.y, jwk.y); 2531cb0ef41Sopenharmony_ci assert.strictEqual(pubJwk.crv, jwk.crv); 2541cb0ef41Sopenharmony_ci 2551cb0ef41Sopenharmony_ci assert.deepStrictEqual(pvtJwk.key_ops, privateUsages); 2561cb0ef41Sopenharmony_ci assert.strictEqual(pvtJwk.ext, true); 2571cb0ef41Sopenharmony_ci assert.strictEqual(pvtJwk.kty, 'EC'); 2581cb0ef41Sopenharmony_ci assert.strictEqual(pvtJwk.x, jwk.x); 2591cb0ef41Sopenharmony_ci assert.strictEqual(pvtJwk.y, jwk.y); 2601cb0ef41Sopenharmony_ci assert.strictEqual(pvtJwk.crv, jwk.crv); 2611cb0ef41Sopenharmony_ci assert.strictEqual(pvtJwk.d, jwk.d); 2621cb0ef41Sopenharmony_ci } else { 2631cb0ef41Sopenharmony_ci await assert.rejects( 2641cb0ef41Sopenharmony_ci subtle.exportKey('jwk', publicKey), { 2651cb0ef41Sopenharmony_ci message: /key is not extractable/ 2661cb0ef41Sopenharmony_ci }); 2671cb0ef41Sopenharmony_ci await assert.rejects( 2681cb0ef41Sopenharmony_ci subtle.exportKey('jwk', privateKey), { 2691cb0ef41Sopenharmony_ci message: /key is not extractable/ 2701cb0ef41Sopenharmony_ci }); 2711cb0ef41Sopenharmony_ci } 2721cb0ef41Sopenharmony_ci 2731cb0ef41Sopenharmony_ci { 2741cb0ef41Sopenharmony_ci const invalidUse = name === 'ECDH' ? 'sig' : 'enc'; 2751cb0ef41Sopenharmony_ci await assert.rejects( 2761cb0ef41Sopenharmony_ci subtle.importKey( 2771cb0ef41Sopenharmony_ci 'jwk', 2781cb0ef41Sopenharmony_ci { ...jwk, use: invalidUse }, 2791cb0ef41Sopenharmony_ci { name, namedCurve }, 2801cb0ef41Sopenharmony_ci extractable, 2811cb0ef41Sopenharmony_ci privateUsages), 2821cb0ef41Sopenharmony_ci { message: 'Invalid JWK "use" Parameter' }); 2831cb0ef41Sopenharmony_ci } 2841cb0ef41Sopenharmony_ci 2851cb0ef41Sopenharmony_ci if (name === 'ECDSA') { 2861cb0ef41Sopenharmony_ci await assert.rejects( 2871cb0ef41Sopenharmony_ci subtle.importKey( 2881cb0ef41Sopenharmony_ci 'jwk', 2891cb0ef41Sopenharmony_ci { kty: jwk.kty, x: jwk.x, y: jwk.y, crv: jwk.crv, alg: jwk.crv === 'P-256' ? 'ES384' : 'ES256' }, 2901cb0ef41Sopenharmony_ci { name, namedCurve }, 2911cb0ef41Sopenharmony_ci extractable, 2921cb0ef41Sopenharmony_ci publicUsages), 2931cb0ef41Sopenharmony_ci { message: 'JWK "alg" does not match the requested algorithm' }); 2941cb0ef41Sopenharmony_ci 2951cb0ef41Sopenharmony_ci await assert.rejects( 2961cb0ef41Sopenharmony_ci subtle.importKey( 2971cb0ef41Sopenharmony_ci 'jwk', 2981cb0ef41Sopenharmony_ci { ...jwk, alg: jwk.crv === 'P-256' ? 'ES384' : 'ES256' }, 2991cb0ef41Sopenharmony_ci { name, namedCurve }, 3001cb0ef41Sopenharmony_ci extractable, 3011cb0ef41Sopenharmony_ci privateUsages), 3021cb0ef41Sopenharmony_ci { message: 'JWK "alg" does not match the requested algorithm' }); 3031cb0ef41Sopenharmony_ci } 3041cb0ef41Sopenharmony_ci 3051cb0ef41Sopenharmony_ci for (const crv of [undefined, namedCurve === 'P-256' ? 'P-384' : 'P-256']) { 3061cb0ef41Sopenharmony_ci await assert.rejects( 3071cb0ef41Sopenharmony_ci subtle.importKey( 3081cb0ef41Sopenharmony_ci 'jwk', 3091cb0ef41Sopenharmony_ci { kty: jwk.kty, x: jwk.x, y: jwk.y, crv }, 3101cb0ef41Sopenharmony_ci { name, namedCurve }, 3111cb0ef41Sopenharmony_ci extractable, 3121cb0ef41Sopenharmony_ci publicUsages), 3131cb0ef41Sopenharmony_ci { message: 'JWK "crv" does not match the requested algorithm' }); 3141cb0ef41Sopenharmony_ci 3151cb0ef41Sopenharmony_ci await assert.rejects( 3161cb0ef41Sopenharmony_ci subtle.importKey( 3171cb0ef41Sopenharmony_ci 'jwk', 3181cb0ef41Sopenharmony_ci { ...jwk, crv }, 3191cb0ef41Sopenharmony_ci { name, namedCurve }, 3201cb0ef41Sopenharmony_ci extractable, 3211cb0ef41Sopenharmony_ci privateUsages), 3221cb0ef41Sopenharmony_ci { message: 'JWK "crv" does not match the requested algorithm' }); 3231cb0ef41Sopenharmony_ci } 3241cb0ef41Sopenharmony_ci 3251cb0ef41Sopenharmony_ci await assert.rejects( 3261cb0ef41Sopenharmony_ci subtle.importKey( 3271cb0ef41Sopenharmony_ci 'jwk', 3281cb0ef41Sopenharmony_ci { ...jwk }, 3291cb0ef41Sopenharmony_ci { name, namedCurve }, 3301cb0ef41Sopenharmony_ci extractable, 3311cb0ef41Sopenharmony_ci [/* empty usages */]), 3321cb0ef41Sopenharmony_ci { name: 'SyntaxError', message: 'Usages cannot be empty when importing a private key.' }); 3331cb0ef41Sopenharmony_ci} 3341cb0ef41Sopenharmony_ci 3351cb0ef41Sopenharmony_ciasync function testImportRaw({ name, publicUsages }, namedCurve) { 3361cb0ef41Sopenharmony_ci const jwk = keyData[namedCurve].jwk; 3371cb0ef41Sopenharmony_ci 3381cb0ef41Sopenharmony_ci const [publicKey] = await Promise.all([ 3391cb0ef41Sopenharmony_ci subtle.importKey( 3401cb0ef41Sopenharmony_ci 'raw', 3411cb0ef41Sopenharmony_ci Buffer.concat([ 3421cb0ef41Sopenharmony_ci Buffer.alloc(1, 0x04), 3431cb0ef41Sopenharmony_ci Buffer.from(jwk.x, 'base64url'), 3441cb0ef41Sopenharmony_ci Buffer.from(jwk.y, 'base64url'), 3451cb0ef41Sopenharmony_ci ]), 3461cb0ef41Sopenharmony_ci { name, namedCurve }, 3471cb0ef41Sopenharmony_ci true, publicUsages), 3481cb0ef41Sopenharmony_ci subtle.importKey( 3491cb0ef41Sopenharmony_ci 'raw', 3501cb0ef41Sopenharmony_ci Buffer.concat([ 3511cb0ef41Sopenharmony_ci Buffer.alloc(1, 0x03), 3521cb0ef41Sopenharmony_ci Buffer.from(jwk.x, 'base64url'), 3531cb0ef41Sopenharmony_ci ]), 3541cb0ef41Sopenharmony_ci { name, namedCurve }, 3551cb0ef41Sopenharmony_ci true, publicUsages), 3561cb0ef41Sopenharmony_ci ]); 3571cb0ef41Sopenharmony_ci 3581cb0ef41Sopenharmony_ci assert.strictEqual(publicKey.type, 'public'); 3591cb0ef41Sopenharmony_ci assert.deepStrictEqual(publicKey.usages, publicUsages); 3601cb0ef41Sopenharmony_ci assert.strictEqual(publicKey.algorithm.name, name); 3611cb0ef41Sopenharmony_ci assert.strictEqual(publicKey.algorithm.namedCurve, namedCurve); 3621cb0ef41Sopenharmony_ci} 3631cb0ef41Sopenharmony_ci 3641cb0ef41Sopenharmony_ci(async function() { 3651cb0ef41Sopenharmony_ci const tests = []; 3661cb0ef41Sopenharmony_ci testVectors.forEach((vector) => { 3671cb0ef41Sopenharmony_ci curves.forEach((namedCurve) => { 3681cb0ef41Sopenharmony_ci [true, false].forEach((extractable) => { 3691cb0ef41Sopenharmony_ci tests.push(testImportSpki(vector, namedCurve, extractable)); 3701cb0ef41Sopenharmony_ci tests.push(testImportPkcs8(vector, namedCurve, extractable)); 3711cb0ef41Sopenharmony_ci tests.push(testImportJwk(vector, namedCurve, extractable)); 3721cb0ef41Sopenharmony_ci }); 3731cb0ef41Sopenharmony_ci tests.push(testImportRaw(vector, namedCurve)); 3741cb0ef41Sopenharmony_ci }); 3751cb0ef41Sopenharmony_ci }); 3761cb0ef41Sopenharmony_ci 3771cb0ef41Sopenharmony_ci await Promise.all(tests); 3781cb0ef41Sopenharmony_ci})().then(common.mustCall()); 3791cb0ef41Sopenharmony_ci 3801cb0ef41Sopenharmony_ci 3811cb0ef41Sopenharmony_ci// https://github.com/nodejs/node/issues/45859 3821cb0ef41Sopenharmony_ci(async function() { 3831cb0ef41Sopenharmony_ci const compressed = Buffer.from([48, 57, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 3, 34, 0, 2, 210, 16, 176, 166, 249, 217, 240, 18, 134, 128, 88, 180, 63, 164, 244, 113, 1, 133, 67, 187, 160, 12, 146, 80, 223, 146, 87, 194, 172, 174, 93, 209]); // eslint-disable-line max-len 3841cb0ef41Sopenharmony_ci const uncompressed = Buffer.from([48, 89, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 3, 66, 0, 4, 210, 16, 176, 166, 249, 217, 240, 18, 134, 128, 88, 180, 63, 164, 244, 113, 1, 133, 67, 187, 160, 12, 146, 80, 223, 146, 87, 194, 172, 174, 93, 209, 206, 3, 117, 82, 212, 129, 69, 12, 227, 155, 77, 16, 149, 112, 27, 23, 91, 250, 179, 75, 142, 108, 9, 158, 24, 241, 193, 152, 53, 131, 97, 232]); // eslint-disable-line max-len 3851cb0ef41Sopenharmony_ci for (const name of ['ECDH', 'ECDSA']) { 3861cb0ef41Sopenharmony_ci const options = { name, namedCurve: 'P-256' }; 3871cb0ef41Sopenharmony_ci const key = await subtle.importKey('spki', compressed, options, true, []); 3881cb0ef41Sopenharmony_ci const spki = await subtle.exportKey('spki', key); 3891cb0ef41Sopenharmony_ci assert.deepStrictEqual(uncompressed, Buffer.from(spki)); 3901cb0ef41Sopenharmony_ci } 3911cb0ef41Sopenharmony_ci})().then(common.mustCall()); 3921cb0ef41Sopenharmony_ci 3931cb0ef41Sopenharmony_ci{ 3941cb0ef41Sopenharmony_ci const rsaPublic = crypto.createPublicKey( 3951cb0ef41Sopenharmony_ci fixtures.readKey('rsa_public_2048.pem')); 3961cb0ef41Sopenharmony_ci const rsaPrivate = crypto.createPrivateKey( 3971cb0ef41Sopenharmony_ci fixtures.readKey('rsa_private_2048.pem')); 3981cb0ef41Sopenharmony_ci 3991cb0ef41Sopenharmony_ci for (const [name, publicUsages, privateUsages] of [ 4001cb0ef41Sopenharmony_ci ['ECDSA', ['verify'], ['sign']], 4011cb0ef41Sopenharmony_ci ['ECDH', [], ['deriveBits', 'deriveBits']], 4021cb0ef41Sopenharmony_ci ]) { 4031cb0ef41Sopenharmony_ci assert.rejects( 4041cb0ef41Sopenharmony_ci subtle.importKey( 4051cb0ef41Sopenharmony_ci 'spki', 4061cb0ef41Sopenharmony_ci rsaPublic.export({ format: 'der', type: 'spki' }), 4071cb0ef41Sopenharmony_ci { name, hash: 'SHA-256', namedCurve: 'P-256' }, 4081cb0ef41Sopenharmony_ci true, publicUsages), { message: /Invalid key type/ }, 4091cb0ef41Sopenharmony_ci ).then(common.mustCall()); 4101cb0ef41Sopenharmony_ci assert.rejects( 4111cb0ef41Sopenharmony_ci subtle.importKey( 4121cb0ef41Sopenharmony_ci 'pkcs8', 4131cb0ef41Sopenharmony_ci rsaPrivate.export({ format: 'der', type: 'pkcs8' }), 4141cb0ef41Sopenharmony_ci { name, hash: 'SHA-256', namedCurve: 'P-256' }, 4151cb0ef41Sopenharmony_ci true, privateUsages), { message: /Invalid key type/ }, 4161cb0ef41Sopenharmony_ci ).then(common.mustCall()); 4171cb0ef41Sopenharmony_ci } 4181cb0ef41Sopenharmony_ci} 4191cb0ef41Sopenharmony_ci 4201cb0ef41Sopenharmony_ci// Bad private keys 4211cb0ef41Sopenharmony_ci{ 4221cb0ef41Sopenharmony_ci for (const { namedCurve, key: pkcs8 } of [ 4231cb0ef41Sopenharmony_ci // The private key is exactly equal to the order, and the public key is 4241cb0ef41Sopenharmony_ci // private key * order. 4251cb0ef41Sopenharmony_ci { 4261cb0ef41Sopenharmony_ci namedCurve: 'P-256', 4271cb0ef41Sopenharmony_ci key: Buffer.from( 4281cb0ef41Sopenharmony_ci '3066020100301306072a8648ce3d020106082a8648ce3d030107044c304a0201' + 4291cb0ef41Sopenharmony_ci '010420ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc' + 4301cb0ef41Sopenharmony_ci '632551a12303210000ffffff00000000ffffffffffffffffbce6faada7179e84' + 4311cb0ef41Sopenharmony_ci 'f3b9cac2fc632551', 'hex'), 4321cb0ef41Sopenharmony_ci }, 4331cb0ef41Sopenharmony_ci // The private key is exactly equal to the order, and the public key is 4341cb0ef41Sopenharmony_ci // omitted. 4351cb0ef41Sopenharmony_ci { 4361cb0ef41Sopenharmony_ci namedCurve: 'P-256', 4371cb0ef41Sopenharmony_ci key: Buffer.from( 4381cb0ef41Sopenharmony_ci '3041020100301306072a8648ce3d020106082a8648ce3d030107042730250201' + 4391cb0ef41Sopenharmony_ci '010420ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc' + 4401cb0ef41Sopenharmony_ci '632551', 'hex'), 4411cb0ef41Sopenharmony_ci }, 4421cb0ef41Sopenharmony_ci // The private key is exactly equal to the order + 11, and the public key is 4431cb0ef41Sopenharmony_ci // private key * order. 4441cb0ef41Sopenharmony_ci { 4451cb0ef41Sopenharmony_ci namedCurve: 'P-521', 4461cb0ef41Sopenharmony_ci key: Buffer.from( 4471cb0ef41Sopenharmony_ci '3081ee020100301006072a8648ce3d020106052b810400230481d63081d30201' + 4481cb0ef41Sopenharmony_ci '01044201ffffffffffffffffffffffffffffffffffffffffffffffffffffffff' + 4491cb0ef41Sopenharmony_ci 'fffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb7' + 4501cb0ef41Sopenharmony_ci '1e91386414a181890381860004008a75841259fdedff546f1a39573b4315cfed' + 4511cb0ef41Sopenharmony_ci '5dc7ed7c17849543ef2c54f2991652f3dbc5332663da1bd19b1aebe319108501' + 4521cb0ef41Sopenharmony_ci '5c024fa4c9a902ecc0e02dda0cdb9a0096fb303fcbba2129849d0ca877054fb2' + 4531cb0ef41Sopenharmony_ci '293add566210bd0493ed2e95d4e0b9b82b1bc8a90e8b42a4ab3892331914a953' + 4541cb0ef41Sopenharmony_ci '36dcac80e3f4819b5d58874f92ce48c808', 'hex'), 4551cb0ef41Sopenharmony_ci }, 4561cb0ef41Sopenharmony_ci // The private key is exactly equal to the order + 11, and the public key is 4571cb0ef41Sopenharmony_ci // omitted. 4581cb0ef41Sopenharmony_ci { 4591cb0ef41Sopenharmony_ci namedCurve: 'P-521', 4601cb0ef41Sopenharmony_ci key: Buffer.from( 4611cb0ef41Sopenharmony_ci '3060020100301006072a8648ce3d020106052b81040023044930470201010442' + 4621cb0ef41Sopenharmony_ci '01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' + 4631cb0ef41Sopenharmony_ci 'fffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138' + 4641cb0ef41Sopenharmony_ci '6414', 'hex'), 4651cb0ef41Sopenharmony_ci }, 4661cb0ef41Sopenharmony_ci ]) { 4671cb0ef41Sopenharmony_ci for (const [name, privateUsages] of [ 4681cb0ef41Sopenharmony_ci ['ECDSA', ['sign']], 4691cb0ef41Sopenharmony_ci ['ECDH', ['deriveBits', 'deriveBits']], 4701cb0ef41Sopenharmony_ci ]) { 4711cb0ef41Sopenharmony_ci assert.rejects( 4721cb0ef41Sopenharmony_ci subtle.importKey( 4731cb0ef41Sopenharmony_ci 'pkcs8', 4741cb0ef41Sopenharmony_ci pkcs8, 4751cb0ef41Sopenharmony_ci { name, hash: 'SHA-256', namedCurve }, 4761cb0ef41Sopenharmony_ci true, privateUsages), { name: 'DataError', message: /Invalid keyData/ }, 4771cb0ef41Sopenharmony_ci ).then(common.mustCall()); 4781cb0ef41Sopenharmony_ci } 4791cb0ef41Sopenharmony_ci } 4801cb0ef41Sopenharmony_ci} 481