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 { subtle } = require('crypto').webcrypto; 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ciconst { 121cb0ef41Sopenharmony_ci passing 131cb0ef41Sopenharmony_ci} = require('../fixtures/crypto/rsa')(); 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ciasync function importVectorKey( 161cb0ef41Sopenharmony_ci publicKeyBuffer, 171cb0ef41Sopenharmony_ci privateKeyBuffer, 181cb0ef41Sopenharmony_ci name, 191cb0ef41Sopenharmony_ci hash, 201cb0ef41Sopenharmony_ci publicUsages, 211cb0ef41Sopenharmony_ci privateUsages) { 221cb0ef41Sopenharmony_ci const [publicKey, privateKey] = await Promise.all([ 231cb0ef41Sopenharmony_ci subtle.importKey( 241cb0ef41Sopenharmony_ci 'spki', publicKeyBuffer, { name, hash }, false, publicUsages), 251cb0ef41Sopenharmony_ci subtle.importKey( 261cb0ef41Sopenharmony_ci 'pkcs8', privateKeyBuffer, { name, hash }, false, privateUsages), 271cb0ef41Sopenharmony_ci ]); 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ci return { publicKey, privateKey }; 301cb0ef41Sopenharmony_ci} 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ciasync function testDecryption({ ciphertext, 331cb0ef41Sopenharmony_ci algorithm, 341cb0ef41Sopenharmony_ci plaintext, 351cb0ef41Sopenharmony_ci hash, 361cb0ef41Sopenharmony_ci publicKeyBuffer, 371cb0ef41Sopenharmony_ci privateKeyBuffer }) { 381cb0ef41Sopenharmony_ci if (ciphertext === undefined) 391cb0ef41Sopenharmony_ci return; 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci const { 421cb0ef41Sopenharmony_ci privateKey 431cb0ef41Sopenharmony_ci } = await importVectorKey( 441cb0ef41Sopenharmony_ci publicKeyBuffer, 451cb0ef41Sopenharmony_ci privateKeyBuffer, 461cb0ef41Sopenharmony_ci algorithm.name, 471cb0ef41Sopenharmony_ci hash, 481cb0ef41Sopenharmony_ci ['encrypt'], 491cb0ef41Sopenharmony_ci ['decrypt']); 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci const encodedPlaintext = Buffer.from(plaintext).toString('hex'); 521cb0ef41Sopenharmony_ci const result = await subtle.decrypt(algorithm, privateKey, ciphertext); 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci assert.strictEqual( 551cb0ef41Sopenharmony_ci Buffer.from(result).toString('hex'), 561cb0ef41Sopenharmony_ci encodedPlaintext); 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci const ciphercopy = Buffer.from(ciphertext); 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci // Modifying the ciphercopy after calling decrypt should just work 611cb0ef41Sopenharmony_ci const result2 = await subtle.decrypt(algorithm, privateKey, ciphercopy); 621cb0ef41Sopenharmony_ci ciphercopy[0] = 255 - ciphercopy[0]; 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci assert.strictEqual( 651cb0ef41Sopenharmony_ci Buffer.from(result2).toString('hex'), 661cb0ef41Sopenharmony_ci encodedPlaintext); 671cb0ef41Sopenharmony_ci} 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ciasync function testEncryption( 701cb0ef41Sopenharmony_ci { 711cb0ef41Sopenharmony_ci ciphertext, 721cb0ef41Sopenharmony_ci algorithm, 731cb0ef41Sopenharmony_ci plaintext, 741cb0ef41Sopenharmony_ci hash, 751cb0ef41Sopenharmony_ci publicKeyBuffer, 761cb0ef41Sopenharmony_ci privateKeyBuffer 771cb0ef41Sopenharmony_ci }, 781cb0ef41Sopenharmony_ci modify = false) { 791cb0ef41Sopenharmony_ci const { 801cb0ef41Sopenharmony_ci publicKey, 811cb0ef41Sopenharmony_ci privateKey 821cb0ef41Sopenharmony_ci } = await importVectorKey( 831cb0ef41Sopenharmony_ci publicKeyBuffer, 841cb0ef41Sopenharmony_ci privateKeyBuffer, 851cb0ef41Sopenharmony_ci algorithm.name, 861cb0ef41Sopenharmony_ci hash, 871cb0ef41Sopenharmony_ci ['encrypt'], 881cb0ef41Sopenharmony_ci ['decrypt']); 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci if (modify) 911cb0ef41Sopenharmony_ci plaintext = Buffer.from(plaintext); // make a copy 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci const encodedPlaintext = Buffer.from(plaintext).toString('hex'); 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci const result = await subtle.encrypt(algorithm, publicKey, plaintext); 961cb0ef41Sopenharmony_ci if (modify) 971cb0ef41Sopenharmony_ci plaintext[0] = 255 - plaintext[0]; 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ci assert.strictEqual( 1001cb0ef41Sopenharmony_ci result.byteLength * 8, 1011cb0ef41Sopenharmony_ci privateKey.algorithm.modulusLength); 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ci const out = await subtle.decrypt(algorithm, privateKey, result); 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ci assert.strictEqual( 1061cb0ef41Sopenharmony_ci Buffer.from(out).toString('hex'), 1071cb0ef41Sopenharmony_ci encodedPlaintext); 1081cb0ef41Sopenharmony_ci} 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ciasync function testEncryptionLongPlaintext({ algorithm, 1111cb0ef41Sopenharmony_ci plaintext, 1121cb0ef41Sopenharmony_ci hash, 1131cb0ef41Sopenharmony_ci publicKeyBuffer, 1141cb0ef41Sopenharmony_ci privateKeyBuffer }) { 1151cb0ef41Sopenharmony_ci const { 1161cb0ef41Sopenharmony_ci publicKey, 1171cb0ef41Sopenharmony_ci } = await importVectorKey( 1181cb0ef41Sopenharmony_ci publicKeyBuffer, 1191cb0ef41Sopenharmony_ci privateKeyBuffer, 1201cb0ef41Sopenharmony_ci algorithm.name, 1211cb0ef41Sopenharmony_ci hash, 1221cb0ef41Sopenharmony_ci ['encrypt'], 1231cb0ef41Sopenharmony_ci ['decrypt']); 1241cb0ef41Sopenharmony_ci const newplaintext = new Uint8Array(plaintext.byteLength + 1); 1251cb0ef41Sopenharmony_ci newplaintext.set(plaintext, 0); 1261cb0ef41Sopenharmony_ci newplaintext[plaintext.byteLength] = 32; 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_ci return assert.rejects( 1291cb0ef41Sopenharmony_ci subtle.encrypt(algorithm, publicKey, newplaintext), { 1301cb0ef41Sopenharmony_ci name: 'OperationError' 1311cb0ef41Sopenharmony_ci }); 1321cb0ef41Sopenharmony_ci} 1331cb0ef41Sopenharmony_ci 1341cb0ef41Sopenharmony_ciasync function testEncryptionWrongKey({ algorithm, 1351cb0ef41Sopenharmony_ci plaintext, 1361cb0ef41Sopenharmony_ci hash, 1371cb0ef41Sopenharmony_ci publicKeyBuffer, 1381cb0ef41Sopenharmony_ci privateKeyBuffer }) { 1391cb0ef41Sopenharmony_ci const { 1401cb0ef41Sopenharmony_ci privateKey, 1411cb0ef41Sopenharmony_ci } = await importVectorKey( 1421cb0ef41Sopenharmony_ci publicKeyBuffer, 1431cb0ef41Sopenharmony_ci privateKeyBuffer, 1441cb0ef41Sopenharmony_ci algorithm.name, 1451cb0ef41Sopenharmony_ci hash, 1461cb0ef41Sopenharmony_ci ['encrypt'], 1471cb0ef41Sopenharmony_ci ['decrypt']); 1481cb0ef41Sopenharmony_ci return assert.rejects( 1491cb0ef41Sopenharmony_ci subtle.encrypt(algorithm, privateKey, plaintext), { 1501cb0ef41Sopenharmony_ci message: /The requested operation is not valid/ 1511cb0ef41Sopenharmony_ci }); 1521cb0ef41Sopenharmony_ci} 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_ciasync function testEncryptionBadUsage({ algorithm, 1551cb0ef41Sopenharmony_ci plaintext, 1561cb0ef41Sopenharmony_ci hash, 1571cb0ef41Sopenharmony_ci publicKeyBuffer, 1581cb0ef41Sopenharmony_ci privateKeyBuffer }) { 1591cb0ef41Sopenharmony_ci const { 1601cb0ef41Sopenharmony_ci publicKey, 1611cb0ef41Sopenharmony_ci } = await importVectorKey( 1621cb0ef41Sopenharmony_ci publicKeyBuffer, 1631cb0ef41Sopenharmony_ci privateKeyBuffer, 1641cb0ef41Sopenharmony_ci algorithm.name, 1651cb0ef41Sopenharmony_ci hash, 1661cb0ef41Sopenharmony_ci ['wrapKey'], 1671cb0ef41Sopenharmony_ci ['decrypt']); 1681cb0ef41Sopenharmony_ci return assert.rejects( 1691cb0ef41Sopenharmony_ci subtle.encrypt(algorithm, publicKey, plaintext), { 1701cb0ef41Sopenharmony_ci message: /The requested operation is not valid/ 1711cb0ef41Sopenharmony_ci }); 1721cb0ef41Sopenharmony_ci} 1731cb0ef41Sopenharmony_ci 1741cb0ef41Sopenharmony_ciasync function testDecryptionWrongKey({ ciphertext, 1751cb0ef41Sopenharmony_ci algorithm, 1761cb0ef41Sopenharmony_ci hash, 1771cb0ef41Sopenharmony_ci publicKeyBuffer, 1781cb0ef41Sopenharmony_ci privateKeyBuffer }) { 1791cb0ef41Sopenharmony_ci if (ciphertext === undefined) 1801cb0ef41Sopenharmony_ci return; 1811cb0ef41Sopenharmony_ci 1821cb0ef41Sopenharmony_ci const { 1831cb0ef41Sopenharmony_ci publicKey 1841cb0ef41Sopenharmony_ci } = await importVectorKey( 1851cb0ef41Sopenharmony_ci publicKeyBuffer, 1861cb0ef41Sopenharmony_ci privateKeyBuffer, 1871cb0ef41Sopenharmony_ci algorithm.name, 1881cb0ef41Sopenharmony_ci hash, 1891cb0ef41Sopenharmony_ci ['encrypt'], 1901cb0ef41Sopenharmony_ci ['decrypt']); 1911cb0ef41Sopenharmony_ci 1921cb0ef41Sopenharmony_ci return assert.rejects( 1931cb0ef41Sopenharmony_ci subtle.decrypt(algorithm, publicKey, ciphertext), { 1941cb0ef41Sopenharmony_ci message: /The requested operation is not valid/ 1951cb0ef41Sopenharmony_ci }); 1961cb0ef41Sopenharmony_ci} 1971cb0ef41Sopenharmony_ci 1981cb0ef41Sopenharmony_ciasync function testDecryptionBadUsage({ ciphertext, 1991cb0ef41Sopenharmony_ci algorithm, 2001cb0ef41Sopenharmony_ci hash, 2011cb0ef41Sopenharmony_ci publicKeyBuffer, 2021cb0ef41Sopenharmony_ci privateKeyBuffer }) { 2031cb0ef41Sopenharmony_ci if (ciphertext === undefined) 2041cb0ef41Sopenharmony_ci return; 2051cb0ef41Sopenharmony_ci 2061cb0ef41Sopenharmony_ci const { 2071cb0ef41Sopenharmony_ci publicKey 2081cb0ef41Sopenharmony_ci } = await importVectorKey( 2091cb0ef41Sopenharmony_ci publicKeyBuffer, 2101cb0ef41Sopenharmony_ci privateKeyBuffer, 2111cb0ef41Sopenharmony_ci algorithm.name, 2121cb0ef41Sopenharmony_ci hash, 2131cb0ef41Sopenharmony_ci ['encrypt'], 2141cb0ef41Sopenharmony_ci ['unwrapKey']); 2151cb0ef41Sopenharmony_ci 2161cb0ef41Sopenharmony_ci return assert.rejects( 2171cb0ef41Sopenharmony_ci subtle.decrypt(algorithm, publicKey, ciphertext), { 2181cb0ef41Sopenharmony_ci message: /The requested operation is not valid/ 2191cb0ef41Sopenharmony_ci }); 2201cb0ef41Sopenharmony_ci} 2211cb0ef41Sopenharmony_ci 2221cb0ef41Sopenharmony_ci(async function() { 2231cb0ef41Sopenharmony_ci const variations = []; 2241cb0ef41Sopenharmony_ci 2251cb0ef41Sopenharmony_ci // Test decryption 2261cb0ef41Sopenharmony_ci passing.forEach(async (vector) => { 2271cb0ef41Sopenharmony_ci variations.push(testDecryption(vector)); 2281cb0ef41Sopenharmony_ci variations.push(testDecryptionWrongKey(vector)); 2291cb0ef41Sopenharmony_ci variations.push(testDecryptionBadUsage(vector)); 2301cb0ef41Sopenharmony_ci variations.push(testEncryption(vector)); 2311cb0ef41Sopenharmony_ci variations.push(testEncryption(vector, true)); 2321cb0ef41Sopenharmony_ci variations.push(testEncryptionLongPlaintext(vector)); 2331cb0ef41Sopenharmony_ci variations.push(testEncryptionWrongKey(vector)); 2341cb0ef41Sopenharmony_ci variations.push(testEncryptionBadUsage(vector)); 2351cb0ef41Sopenharmony_ci }); 2361cb0ef41Sopenharmony_ci 2371cb0ef41Sopenharmony_ci await Promise.all(variations); 2381cb0ef41Sopenharmony_ci})().then(common.mustCall()); 239