11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci// Flags: --security-revert=CVE-2023-46809 31cb0ef41Sopenharmony_ciconst common = require('../common'); 41cb0ef41Sopenharmony_ciif (!common.hasCrypto) 51cb0ef41Sopenharmony_ci common.skip('missing crypto'); 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ciconst assert = require('assert'); 81cb0ef41Sopenharmony_ciconst crypto = require('crypto'); 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ciconst constants = crypto.constants; 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ciconst fixtures = require('../common/fixtures'); 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ci// Test certificates 151cb0ef41Sopenharmony_ciconst certPem = fixtures.readKey('rsa_cert.crt'); 161cb0ef41Sopenharmony_ciconst keyPem = fixtures.readKey('rsa_private.pem'); 171cb0ef41Sopenharmony_ciconst rsaKeySize = 2048; 181cb0ef41Sopenharmony_ciconst rsaPubPem = fixtures.readKey('rsa_public.pem', 'ascii'); 191cb0ef41Sopenharmony_ciconst rsaKeyPem = fixtures.readKey('rsa_private.pem', 'ascii'); 201cb0ef41Sopenharmony_ciconst rsaKeyPemEncrypted = fixtures.readKey('rsa_private_encrypted.pem', 211cb0ef41Sopenharmony_ci 'ascii'); 221cb0ef41Sopenharmony_ciconst dsaPubPem = fixtures.readKey('dsa_public.pem', 'ascii'); 231cb0ef41Sopenharmony_ciconst dsaKeyPem = fixtures.readKey('dsa_private.pem', 'ascii'); 241cb0ef41Sopenharmony_ciconst dsaKeyPemEncrypted = fixtures.readKey('dsa_private_encrypted.pem', 251cb0ef41Sopenharmony_ci 'ascii'); 261cb0ef41Sopenharmony_ciconst rsaPkcs8KeyPem = fixtures.readKey('rsa_private_pkcs8.pem'); 271cb0ef41Sopenharmony_ciconst dsaPkcs8KeyPem = fixtures.readKey('dsa_private_pkcs8.pem'); 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ciconst ec = new TextEncoder(); 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ciconst openssl1DecryptError = { 321cb0ef41Sopenharmony_ci message: 'error:06065064:digital envelope routines:EVP_DecryptFinal_ex:' + 331cb0ef41Sopenharmony_ci 'bad decrypt', 341cb0ef41Sopenharmony_ci code: 'ERR_OSSL_EVP_BAD_DECRYPT', 351cb0ef41Sopenharmony_ci reason: 'bad decrypt', 361cb0ef41Sopenharmony_ci function: 'EVP_DecryptFinal_ex', 371cb0ef41Sopenharmony_ci library: 'digital envelope routines', 381cb0ef41Sopenharmony_ci}; 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ciconst decryptError = common.hasOpenSSL3 ? 411cb0ef41Sopenharmony_ci { message: 'error:1C800064:Provider routines::bad decrypt' } : 421cb0ef41Sopenharmony_ci openssl1DecryptError; 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ciconst decryptPrivateKeyError = common.hasOpenSSL3 ? { 451cb0ef41Sopenharmony_ci message: 'error:1C800064:Provider routines::bad decrypt', 461cb0ef41Sopenharmony_ci} : openssl1DecryptError; 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_cifunction getBufferCopy(buf) { 491cb0ef41Sopenharmony_ci return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); 501cb0ef41Sopenharmony_ci} 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci// Test RSA encryption/decryption 531cb0ef41Sopenharmony_ci{ 541cb0ef41Sopenharmony_ci const input = 'I AM THE WALRUS'; 551cb0ef41Sopenharmony_ci const bufferToEncrypt = Buffer.from(input); 561cb0ef41Sopenharmony_ci const bufferPassword = Buffer.from('password'); 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci let encryptedBuffer = crypto.publicEncrypt(rsaPubPem, bufferToEncrypt); 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci // Test other input types 611cb0ef41Sopenharmony_ci let otherEncrypted; 621cb0ef41Sopenharmony_ci { 631cb0ef41Sopenharmony_ci const ab = getBufferCopy(ec.encode(rsaPubPem)); 641cb0ef41Sopenharmony_ci const ab2enc = getBufferCopy(bufferToEncrypt); 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci crypto.publicEncrypt(ab, ab2enc); 671cb0ef41Sopenharmony_ci crypto.publicEncrypt(new Uint8Array(ab), new Uint8Array(ab2enc)); 681cb0ef41Sopenharmony_ci crypto.publicEncrypt(new DataView(ab), new DataView(ab2enc)); 691cb0ef41Sopenharmony_ci otherEncrypted = crypto.publicEncrypt({ 701cb0ef41Sopenharmony_ci key: Buffer.from(ab).toString('hex'), 711cb0ef41Sopenharmony_ci encoding: 'hex' 721cb0ef41Sopenharmony_ci }, Buffer.from(ab2enc).toString('hex')); 731cb0ef41Sopenharmony_ci } 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci let decryptedBuffer = crypto.privateDecrypt(rsaKeyPem, encryptedBuffer); 761cb0ef41Sopenharmony_ci const otherDecrypted = crypto.privateDecrypt(rsaKeyPem, otherEncrypted); 771cb0ef41Sopenharmony_ci assert.strictEqual(decryptedBuffer.toString(), input); 781cb0ef41Sopenharmony_ci assert.strictEqual(otherDecrypted.toString(), input); 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci decryptedBuffer = crypto.privateDecrypt(rsaPkcs8KeyPem, encryptedBuffer); 811cb0ef41Sopenharmony_ci assert.strictEqual(decryptedBuffer.toString(), input); 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci let decryptedBufferWithPassword = crypto.privateDecrypt({ 841cb0ef41Sopenharmony_ci key: rsaKeyPemEncrypted, 851cb0ef41Sopenharmony_ci passphrase: 'password' 861cb0ef41Sopenharmony_ci }, encryptedBuffer); 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_ci const otherDecryptedBufferWithPassword = crypto.privateDecrypt({ 891cb0ef41Sopenharmony_ci key: rsaKeyPemEncrypted, 901cb0ef41Sopenharmony_ci passphrase: ec.encode('password') 911cb0ef41Sopenharmony_ci }, encryptedBuffer); 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci assert.strictEqual( 941cb0ef41Sopenharmony_ci otherDecryptedBufferWithPassword.toString(), 951cb0ef41Sopenharmony_ci decryptedBufferWithPassword.toString()); 961cb0ef41Sopenharmony_ci 971cb0ef41Sopenharmony_ci decryptedBufferWithPassword = crypto.privateDecrypt({ 981cb0ef41Sopenharmony_ci key: rsaKeyPemEncrypted, 991cb0ef41Sopenharmony_ci passphrase: 'password' 1001cb0ef41Sopenharmony_ci }, encryptedBuffer); 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci assert.strictEqual(decryptedBufferWithPassword.toString(), input); 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci encryptedBuffer = crypto.publicEncrypt({ 1051cb0ef41Sopenharmony_ci key: rsaKeyPemEncrypted, 1061cb0ef41Sopenharmony_ci passphrase: 'password' 1071cb0ef41Sopenharmony_ci }, bufferToEncrypt); 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci decryptedBufferWithPassword = crypto.privateDecrypt({ 1101cb0ef41Sopenharmony_ci key: rsaKeyPemEncrypted, 1111cb0ef41Sopenharmony_ci passphrase: 'password' 1121cb0ef41Sopenharmony_ci }, encryptedBuffer); 1131cb0ef41Sopenharmony_ci assert.strictEqual(decryptedBufferWithPassword.toString(), input); 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci encryptedBuffer = crypto.privateEncrypt({ 1161cb0ef41Sopenharmony_ci key: rsaKeyPemEncrypted, 1171cb0ef41Sopenharmony_ci passphrase: bufferPassword 1181cb0ef41Sopenharmony_ci }, bufferToEncrypt); 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci decryptedBufferWithPassword = crypto.publicDecrypt({ 1211cb0ef41Sopenharmony_ci key: rsaKeyPemEncrypted, 1221cb0ef41Sopenharmony_ci passphrase: bufferPassword 1231cb0ef41Sopenharmony_ci }, encryptedBuffer); 1241cb0ef41Sopenharmony_ci assert.strictEqual(decryptedBufferWithPassword.toString(), input); 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_ci // Now with explicit RSA_PKCS1_PADDING. 1271cb0ef41Sopenharmony_ci encryptedBuffer = crypto.privateEncrypt({ 1281cb0ef41Sopenharmony_ci padding: crypto.constants.RSA_PKCS1_PADDING, 1291cb0ef41Sopenharmony_ci key: rsaKeyPemEncrypted, 1301cb0ef41Sopenharmony_ci passphrase: bufferPassword 1311cb0ef41Sopenharmony_ci }, bufferToEncrypt); 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ci decryptedBufferWithPassword = crypto.publicDecrypt({ 1341cb0ef41Sopenharmony_ci padding: crypto.constants.RSA_PKCS1_PADDING, 1351cb0ef41Sopenharmony_ci key: rsaKeyPemEncrypted, 1361cb0ef41Sopenharmony_ci passphrase: bufferPassword 1371cb0ef41Sopenharmony_ci }, encryptedBuffer); 1381cb0ef41Sopenharmony_ci assert.strictEqual(decryptedBufferWithPassword.toString(), input); 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_ci // Omitting padding should be okay because RSA_PKCS1_PADDING is the default. 1411cb0ef41Sopenharmony_ci decryptedBufferWithPassword = crypto.publicDecrypt({ 1421cb0ef41Sopenharmony_ci key: rsaKeyPemEncrypted, 1431cb0ef41Sopenharmony_ci passphrase: bufferPassword 1441cb0ef41Sopenharmony_ci }, encryptedBuffer); 1451cb0ef41Sopenharmony_ci assert.strictEqual(decryptedBufferWithPassword.toString(), input); 1461cb0ef41Sopenharmony_ci 1471cb0ef41Sopenharmony_ci // Now with RSA_NO_PADDING. Plaintext needs to match key size. 1481cb0ef41Sopenharmony_ci // OpenSSL 3.x has a rsa_check_padding that will cause an error if 1491cb0ef41Sopenharmony_ci // RSA_NO_PADDING is used. 1501cb0ef41Sopenharmony_ci if (!common.hasOpenSSL3) { 1511cb0ef41Sopenharmony_ci { 1521cb0ef41Sopenharmony_ci const plaintext = 'x'.repeat(rsaKeySize / 8); 1531cb0ef41Sopenharmony_ci encryptedBuffer = crypto.privateEncrypt({ 1541cb0ef41Sopenharmony_ci padding: crypto.constants.RSA_NO_PADDING, 1551cb0ef41Sopenharmony_ci key: rsaKeyPemEncrypted, 1561cb0ef41Sopenharmony_ci passphrase: bufferPassword 1571cb0ef41Sopenharmony_ci }, Buffer.from(plaintext)); 1581cb0ef41Sopenharmony_ci 1591cb0ef41Sopenharmony_ci decryptedBufferWithPassword = crypto.publicDecrypt({ 1601cb0ef41Sopenharmony_ci padding: crypto.constants.RSA_NO_PADDING, 1611cb0ef41Sopenharmony_ci key: rsaKeyPemEncrypted, 1621cb0ef41Sopenharmony_ci passphrase: bufferPassword 1631cb0ef41Sopenharmony_ci }, encryptedBuffer); 1641cb0ef41Sopenharmony_ci assert.strictEqual(decryptedBufferWithPassword.toString(), plaintext); 1651cb0ef41Sopenharmony_ci } 1661cb0ef41Sopenharmony_ci } 1671cb0ef41Sopenharmony_ci 1681cb0ef41Sopenharmony_ci encryptedBuffer = crypto.publicEncrypt(certPem, bufferToEncrypt); 1691cb0ef41Sopenharmony_ci 1701cb0ef41Sopenharmony_ci decryptedBuffer = crypto.privateDecrypt(keyPem, encryptedBuffer); 1711cb0ef41Sopenharmony_ci assert.strictEqual(decryptedBuffer.toString(), input); 1721cb0ef41Sopenharmony_ci 1731cb0ef41Sopenharmony_ci encryptedBuffer = crypto.publicEncrypt(keyPem, bufferToEncrypt); 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci decryptedBuffer = crypto.privateDecrypt(keyPem, encryptedBuffer); 1761cb0ef41Sopenharmony_ci assert.strictEqual(decryptedBuffer.toString(), input); 1771cb0ef41Sopenharmony_ci 1781cb0ef41Sopenharmony_ci encryptedBuffer = crypto.privateEncrypt(keyPem, bufferToEncrypt); 1791cb0ef41Sopenharmony_ci 1801cb0ef41Sopenharmony_ci decryptedBuffer = crypto.publicDecrypt(keyPem, encryptedBuffer); 1811cb0ef41Sopenharmony_ci assert.strictEqual(decryptedBuffer.toString(), input); 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ci assert.throws(() => { 1841cb0ef41Sopenharmony_ci crypto.privateDecrypt({ 1851cb0ef41Sopenharmony_ci key: rsaKeyPemEncrypted, 1861cb0ef41Sopenharmony_ci passphrase: 'wrong' 1871cb0ef41Sopenharmony_ci }, bufferToEncrypt); 1881cb0ef41Sopenharmony_ci }, decryptError); 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_ci assert.throws(() => { 1911cb0ef41Sopenharmony_ci crypto.publicEncrypt({ 1921cb0ef41Sopenharmony_ci key: rsaKeyPemEncrypted, 1931cb0ef41Sopenharmony_ci passphrase: 'wrong' 1941cb0ef41Sopenharmony_ci }, encryptedBuffer); 1951cb0ef41Sopenharmony_ci }, decryptError); 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ci encryptedBuffer = crypto.privateEncrypt({ 1981cb0ef41Sopenharmony_ci key: rsaKeyPemEncrypted, 1991cb0ef41Sopenharmony_ci passphrase: Buffer.from('password') 2001cb0ef41Sopenharmony_ci }, bufferToEncrypt); 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_ci assert.throws(() => { 2031cb0ef41Sopenharmony_ci crypto.publicDecrypt({ 2041cb0ef41Sopenharmony_ci key: rsaKeyPemEncrypted, 2051cb0ef41Sopenharmony_ci passphrase: Buffer.from('wrong') 2061cb0ef41Sopenharmony_ci }, encryptedBuffer); 2071cb0ef41Sopenharmony_ci }, decryptError); 2081cb0ef41Sopenharmony_ci} 2091cb0ef41Sopenharmony_ci 2101cb0ef41Sopenharmony_cifunction test_rsa(padding, encryptOaepHash, decryptOaepHash) { 2111cb0ef41Sopenharmony_ci const size = (padding === 'RSA_NO_PADDING') ? rsaKeySize / 8 : 32; 2121cb0ef41Sopenharmony_ci const input = Buffer.allocUnsafe(size); 2131cb0ef41Sopenharmony_ci for (let i = 0; i < input.length; i++) 2141cb0ef41Sopenharmony_ci input[i] = (i * 7 + 11) & 0xff; 2151cb0ef41Sopenharmony_ci const bufferToEncrypt = Buffer.from(input); 2161cb0ef41Sopenharmony_ci 2171cb0ef41Sopenharmony_ci padding = constants[padding]; 2181cb0ef41Sopenharmony_ci 2191cb0ef41Sopenharmony_ci const encryptedBuffer = crypto.publicEncrypt({ 2201cb0ef41Sopenharmony_ci key: rsaPubPem, 2211cb0ef41Sopenharmony_ci padding: padding, 2221cb0ef41Sopenharmony_ci oaepHash: encryptOaepHash 2231cb0ef41Sopenharmony_ci }, bufferToEncrypt); 2241cb0ef41Sopenharmony_ci 2251cb0ef41Sopenharmony_ci let decryptedBuffer = crypto.privateDecrypt({ 2261cb0ef41Sopenharmony_ci key: rsaKeyPem, 2271cb0ef41Sopenharmony_ci padding: padding, 2281cb0ef41Sopenharmony_ci oaepHash: decryptOaepHash 2291cb0ef41Sopenharmony_ci }, encryptedBuffer); 2301cb0ef41Sopenharmony_ci assert.deepStrictEqual(decryptedBuffer, input); 2311cb0ef41Sopenharmony_ci 2321cb0ef41Sopenharmony_ci decryptedBuffer = crypto.privateDecrypt({ 2331cb0ef41Sopenharmony_ci key: rsaPkcs8KeyPem, 2341cb0ef41Sopenharmony_ci padding: padding, 2351cb0ef41Sopenharmony_ci oaepHash: decryptOaepHash 2361cb0ef41Sopenharmony_ci }, encryptedBuffer); 2371cb0ef41Sopenharmony_ci assert.deepStrictEqual(decryptedBuffer, input); 2381cb0ef41Sopenharmony_ci} 2391cb0ef41Sopenharmony_ci 2401cb0ef41Sopenharmony_citest_rsa('RSA_NO_PADDING'); 2411cb0ef41Sopenharmony_citest_rsa('RSA_PKCS1_PADDING'); 2421cb0ef41Sopenharmony_citest_rsa('RSA_PKCS1_OAEP_PADDING'); 2431cb0ef41Sopenharmony_ci 2441cb0ef41Sopenharmony_ci// Test OAEP with different hash functions. 2451cb0ef41Sopenharmony_citest_rsa('RSA_PKCS1_OAEP_PADDING', undefined, 'sha1'); 2461cb0ef41Sopenharmony_citest_rsa('RSA_PKCS1_OAEP_PADDING', 'sha1', undefined); 2471cb0ef41Sopenharmony_citest_rsa('RSA_PKCS1_OAEP_PADDING', 'sha256', 'sha256'); 2481cb0ef41Sopenharmony_citest_rsa('RSA_PKCS1_OAEP_PADDING', 'sha512', 'sha512'); 2491cb0ef41Sopenharmony_ciassert.throws(() => { 2501cb0ef41Sopenharmony_ci test_rsa('RSA_PKCS1_OAEP_PADDING', 'sha256', 'sha512'); 2511cb0ef41Sopenharmony_ci}, { 2521cb0ef41Sopenharmony_ci code: 'ERR_OSSL_RSA_OAEP_DECODING_ERROR' 2531cb0ef41Sopenharmony_ci}); 2541cb0ef41Sopenharmony_ci 2551cb0ef41Sopenharmony_ci// The following RSA-OAEP test cases were created using the WebCrypto API to 2561cb0ef41Sopenharmony_ci// ensure compatibility when using non-SHA1 hash functions. 2571cb0ef41Sopenharmony_ci{ 2581cb0ef41Sopenharmony_ci const { decryptionTests } = 2591cb0ef41Sopenharmony_ci JSON.parse(fixtures.readSync('rsa-oaep-test-vectors.js', 'utf8')); 2601cb0ef41Sopenharmony_ci 2611cb0ef41Sopenharmony_ci for (const { ct, oaepHash, oaepLabel } of decryptionTests) { 2621cb0ef41Sopenharmony_ci const label = oaepLabel ? Buffer.from(oaepLabel, 'hex') : undefined; 2631cb0ef41Sopenharmony_ci const copiedLabel = oaepLabel ? getBufferCopy(label) : undefined; 2641cb0ef41Sopenharmony_ci 2651cb0ef41Sopenharmony_ci const decrypted = crypto.privateDecrypt({ 2661cb0ef41Sopenharmony_ci key: rsaPkcs8KeyPem, 2671cb0ef41Sopenharmony_ci oaepHash, 2681cb0ef41Sopenharmony_ci oaepLabel: oaepLabel ? label : undefined 2691cb0ef41Sopenharmony_ci }, Buffer.from(ct, 'hex')); 2701cb0ef41Sopenharmony_ci 2711cb0ef41Sopenharmony_ci assert.strictEqual(decrypted.toString('utf8'), 'Hello Node.js'); 2721cb0ef41Sopenharmony_ci 2731cb0ef41Sopenharmony_ci const otherDecrypted = crypto.privateDecrypt({ 2741cb0ef41Sopenharmony_ci key: rsaPkcs8KeyPem, 2751cb0ef41Sopenharmony_ci oaepHash, 2761cb0ef41Sopenharmony_ci oaepLabel: copiedLabel 2771cb0ef41Sopenharmony_ci }, Buffer.from(ct, 'hex')); 2781cb0ef41Sopenharmony_ci 2791cb0ef41Sopenharmony_ci assert.strictEqual(otherDecrypted.toString('utf8'), 'Hello Node.js'); 2801cb0ef41Sopenharmony_ci } 2811cb0ef41Sopenharmony_ci} 2821cb0ef41Sopenharmony_ci 2831cb0ef41Sopenharmony_ci// Test invalid oaepHash and oaepLabel options. 2841cb0ef41Sopenharmony_cifor (const fn of [crypto.publicEncrypt, crypto.privateDecrypt]) { 2851cb0ef41Sopenharmony_ci assert.throws(() => { 2861cb0ef41Sopenharmony_ci fn({ 2871cb0ef41Sopenharmony_ci key: rsaPubPem, 2881cb0ef41Sopenharmony_ci oaepHash: 'Hello world' 2891cb0ef41Sopenharmony_ci }, Buffer.alloc(10)); 2901cb0ef41Sopenharmony_ci }, { 2911cb0ef41Sopenharmony_ci code: 'ERR_OSSL_EVP_INVALID_DIGEST' 2921cb0ef41Sopenharmony_ci }); 2931cb0ef41Sopenharmony_ci 2941cb0ef41Sopenharmony_ci for (const oaepHash of [0, false, null, Symbol(), () => {}]) { 2951cb0ef41Sopenharmony_ci assert.throws(() => { 2961cb0ef41Sopenharmony_ci fn({ 2971cb0ef41Sopenharmony_ci key: rsaPubPem, 2981cb0ef41Sopenharmony_ci oaepHash 2991cb0ef41Sopenharmony_ci }, Buffer.alloc(10)); 3001cb0ef41Sopenharmony_ci }, { 3011cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE' 3021cb0ef41Sopenharmony_ci }); 3031cb0ef41Sopenharmony_ci } 3041cb0ef41Sopenharmony_ci 3051cb0ef41Sopenharmony_ci for (const oaepLabel of [0, false, null, Symbol(), () => {}, {}]) { 3061cb0ef41Sopenharmony_ci assert.throws(() => { 3071cb0ef41Sopenharmony_ci fn({ 3081cb0ef41Sopenharmony_ci key: rsaPubPem, 3091cb0ef41Sopenharmony_ci oaepLabel 3101cb0ef41Sopenharmony_ci }, Buffer.alloc(10)); 3111cb0ef41Sopenharmony_ci }, { 3121cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE' 3131cb0ef41Sopenharmony_ci }); 3141cb0ef41Sopenharmony_ci } 3151cb0ef41Sopenharmony_ci} 3161cb0ef41Sopenharmony_ci 3171cb0ef41Sopenharmony_ci// Test RSA key signing/verification 3181cb0ef41Sopenharmony_cilet rsaSign = crypto.createSign('SHA1'); 3191cb0ef41Sopenharmony_cilet rsaVerify = crypto.createVerify('SHA1'); 3201cb0ef41Sopenharmony_ciassert.ok(rsaSign); 3211cb0ef41Sopenharmony_ciassert.ok(rsaVerify); 3221cb0ef41Sopenharmony_ci 3231cb0ef41Sopenharmony_ciconst expectedSignature = fixtures.readKey( 3241cb0ef41Sopenharmony_ci 'rsa_public_sha1_signature_signedby_rsa_private_pkcs8.sha1', 3251cb0ef41Sopenharmony_ci 'hex' 3261cb0ef41Sopenharmony_ci); 3271cb0ef41Sopenharmony_ci 3281cb0ef41Sopenharmony_cirsaSign.update(rsaPubPem); 3291cb0ef41Sopenharmony_cilet rsaSignature = rsaSign.sign(rsaKeyPem, 'hex'); 3301cb0ef41Sopenharmony_ciassert.strictEqual(rsaSignature, expectedSignature); 3311cb0ef41Sopenharmony_ci 3321cb0ef41Sopenharmony_cirsaVerify.update(rsaPubPem); 3331cb0ef41Sopenharmony_ciassert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true); 3341cb0ef41Sopenharmony_ci 3351cb0ef41Sopenharmony_ci// Test RSA PKCS#8 key signing/verification 3361cb0ef41Sopenharmony_cirsaSign = crypto.createSign('SHA1'); 3371cb0ef41Sopenharmony_cirsaSign.update(rsaPubPem); 3381cb0ef41Sopenharmony_cirsaSignature = rsaSign.sign(rsaPkcs8KeyPem, 'hex'); 3391cb0ef41Sopenharmony_ciassert.strictEqual(rsaSignature, expectedSignature); 3401cb0ef41Sopenharmony_ci 3411cb0ef41Sopenharmony_cirsaVerify = crypto.createVerify('SHA1'); 3421cb0ef41Sopenharmony_cirsaVerify.update(rsaPubPem); 3431cb0ef41Sopenharmony_ciassert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true); 3441cb0ef41Sopenharmony_ci 3451cb0ef41Sopenharmony_ci// Test RSA key signing/verification with encrypted key 3461cb0ef41Sopenharmony_cirsaSign = crypto.createSign('SHA1'); 3471cb0ef41Sopenharmony_cirsaSign.update(rsaPubPem); 3481cb0ef41Sopenharmony_ciconst signOptions = { key: rsaKeyPemEncrypted, passphrase: 'password' }; 3491cb0ef41Sopenharmony_cirsaSignature = rsaSign.sign(signOptions, 'hex'); 3501cb0ef41Sopenharmony_ciassert.strictEqual(rsaSignature, expectedSignature); 3511cb0ef41Sopenharmony_ci 3521cb0ef41Sopenharmony_cirsaVerify = crypto.createVerify('SHA1'); 3531cb0ef41Sopenharmony_cirsaVerify.update(rsaPubPem); 3541cb0ef41Sopenharmony_ciassert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true); 3551cb0ef41Sopenharmony_ci 3561cb0ef41Sopenharmony_cirsaSign = crypto.createSign('SHA1'); 3571cb0ef41Sopenharmony_cirsaSign.update(rsaPubPem); 3581cb0ef41Sopenharmony_ciassert.throws(() => { 3591cb0ef41Sopenharmony_ci const signOptions = { key: rsaKeyPemEncrypted, passphrase: 'wrong' }; 3601cb0ef41Sopenharmony_ci rsaSign.sign(signOptions, 'hex'); 3611cb0ef41Sopenharmony_ci}, decryptPrivateKeyError); 3621cb0ef41Sopenharmony_ci 3631cb0ef41Sopenharmony_ci// 3641cb0ef41Sopenharmony_ci// Test RSA signing and verification 3651cb0ef41Sopenharmony_ci// 3661cb0ef41Sopenharmony_ci{ 3671cb0ef41Sopenharmony_ci const privateKey = fixtures.readKey('rsa_private_b.pem'); 3681cb0ef41Sopenharmony_ci const publicKey = fixtures.readKey('rsa_public_b.pem'); 3691cb0ef41Sopenharmony_ci 3701cb0ef41Sopenharmony_ci const input = 'I AM THE WALRUS'; 3711cb0ef41Sopenharmony_ci 3721cb0ef41Sopenharmony_ci const signature = fixtures.readKey( 3731cb0ef41Sopenharmony_ci 'I_AM_THE_WALRUS_sha256_signature_signedby_rsa_private_b.sha256', 3741cb0ef41Sopenharmony_ci 'hex' 3751cb0ef41Sopenharmony_ci ); 3761cb0ef41Sopenharmony_ci 3771cb0ef41Sopenharmony_ci const sign = crypto.createSign('SHA256'); 3781cb0ef41Sopenharmony_ci sign.update(input); 3791cb0ef41Sopenharmony_ci 3801cb0ef41Sopenharmony_ci const output = sign.sign(privateKey, 'hex'); 3811cb0ef41Sopenharmony_ci assert.strictEqual(output, signature); 3821cb0ef41Sopenharmony_ci 3831cb0ef41Sopenharmony_ci const verify = crypto.createVerify('SHA256'); 3841cb0ef41Sopenharmony_ci verify.update(input); 3851cb0ef41Sopenharmony_ci 3861cb0ef41Sopenharmony_ci assert.strictEqual(verify.verify(publicKey, signature, 'hex'), true); 3871cb0ef41Sopenharmony_ci 3881cb0ef41Sopenharmony_ci // Test the legacy signature algorithm name. 3891cb0ef41Sopenharmony_ci const sign2 = crypto.createSign('RSA-SHA256'); 3901cb0ef41Sopenharmony_ci sign2.update(input); 3911cb0ef41Sopenharmony_ci 3921cb0ef41Sopenharmony_ci const output2 = sign2.sign(privateKey, 'hex'); 3931cb0ef41Sopenharmony_ci assert.strictEqual(output2, signature); 3941cb0ef41Sopenharmony_ci 3951cb0ef41Sopenharmony_ci const verify2 = crypto.createVerify('SHA256'); 3961cb0ef41Sopenharmony_ci verify2.update(input); 3971cb0ef41Sopenharmony_ci 3981cb0ef41Sopenharmony_ci assert.strictEqual(verify2.verify(publicKey, signature, 'hex'), true); 3991cb0ef41Sopenharmony_ci} 4001cb0ef41Sopenharmony_ci 4011cb0ef41Sopenharmony_ci 4021cb0ef41Sopenharmony_ci// 4031cb0ef41Sopenharmony_ci// Test DSA signing and verification 4041cb0ef41Sopenharmony_ci// 4051cb0ef41Sopenharmony_ci{ 4061cb0ef41Sopenharmony_ci const input = 'I AM THE WALRUS'; 4071cb0ef41Sopenharmony_ci 4081cb0ef41Sopenharmony_ci // DSA signatures vary across runs so there is no static string to verify 4091cb0ef41Sopenharmony_ci // against. 4101cb0ef41Sopenharmony_ci const sign = crypto.createSign('SHA1'); 4111cb0ef41Sopenharmony_ci sign.update(input); 4121cb0ef41Sopenharmony_ci const signature = sign.sign(dsaKeyPem, 'hex'); 4131cb0ef41Sopenharmony_ci 4141cb0ef41Sopenharmony_ci const verify = crypto.createVerify('SHA1'); 4151cb0ef41Sopenharmony_ci verify.update(input); 4161cb0ef41Sopenharmony_ci 4171cb0ef41Sopenharmony_ci assert.strictEqual(verify.verify(dsaPubPem, signature, 'hex'), true); 4181cb0ef41Sopenharmony_ci 4191cb0ef41Sopenharmony_ci // Test the legacy 'DSS1' name. 4201cb0ef41Sopenharmony_ci const sign2 = crypto.createSign('DSS1'); 4211cb0ef41Sopenharmony_ci sign2.update(input); 4221cb0ef41Sopenharmony_ci const signature2 = sign2.sign(dsaKeyPem, 'hex'); 4231cb0ef41Sopenharmony_ci 4241cb0ef41Sopenharmony_ci const verify2 = crypto.createVerify('DSS1'); 4251cb0ef41Sopenharmony_ci verify2.update(input); 4261cb0ef41Sopenharmony_ci 4271cb0ef41Sopenharmony_ci assert.strictEqual(verify2.verify(dsaPubPem, signature2, 'hex'), true); 4281cb0ef41Sopenharmony_ci} 4291cb0ef41Sopenharmony_ci 4301cb0ef41Sopenharmony_ci 4311cb0ef41Sopenharmony_ci// 4321cb0ef41Sopenharmony_ci// Test DSA signing and verification with PKCS#8 private key 4331cb0ef41Sopenharmony_ci// 4341cb0ef41Sopenharmony_ci{ 4351cb0ef41Sopenharmony_ci const input = 'I AM THE WALRUS'; 4361cb0ef41Sopenharmony_ci 4371cb0ef41Sopenharmony_ci // DSA signatures vary across runs so there is no static string to verify 4381cb0ef41Sopenharmony_ci // against. 4391cb0ef41Sopenharmony_ci const sign = crypto.createSign('SHA1'); 4401cb0ef41Sopenharmony_ci sign.update(input); 4411cb0ef41Sopenharmony_ci const signature = sign.sign(dsaPkcs8KeyPem, 'hex'); 4421cb0ef41Sopenharmony_ci 4431cb0ef41Sopenharmony_ci const verify = crypto.createVerify('SHA1'); 4441cb0ef41Sopenharmony_ci verify.update(input); 4451cb0ef41Sopenharmony_ci 4461cb0ef41Sopenharmony_ci assert.strictEqual(verify.verify(dsaPubPem, signature, 'hex'), true); 4471cb0ef41Sopenharmony_ci} 4481cb0ef41Sopenharmony_ci 4491cb0ef41Sopenharmony_ci 4501cb0ef41Sopenharmony_ci// 4511cb0ef41Sopenharmony_ci// Test DSA signing and verification with encrypted key 4521cb0ef41Sopenharmony_ci// 4531cb0ef41Sopenharmony_ciconst input = 'I AM THE WALRUS'; 4541cb0ef41Sopenharmony_ci 4551cb0ef41Sopenharmony_ci{ 4561cb0ef41Sopenharmony_ci const sign = crypto.createSign('SHA1'); 4571cb0ef41Sopenharmony_ci sign.update(input); 4581cb0ef41Sopenharmony_ci assert.throws(() => { 4591cb0ef41Sopenharmony_ci sign.sign({ key: dsaKeyPemEncrypted, passphrase: 'wrong' }, 'hex'); 4601cb0ef41Sopenharmony_ci }, decryptPrivateKeyError); 4611cb0ef41Sopenharmony_ci} 4621cb0ef41Sopenharmony_ci 4631cb0ef41Sopenharmony_ci{ 4641cb0ef41Sopenharmony_ci // DSA signatures vary across runs so there is no static string to verify 4651cb0ef41Sopenharmony_ci // against. 4661cb0ef41Sopenharmony_ci const sign = crypto.createSign('SHA1'); 4671cb0ef41Sopenharmony_ci sign.update(input); 4681cb0ef41Sopenharmony_ci const signOptions = { key: dsaKeyPemEncrypted, passphrase: 'password' }; 4691cb0ef41Sopenharmony_ci const signature = sign.sign(signOptions, 'hex'); 4701cb0ef41Sopenharmony_ci 4711cb0ef41Sopenharmony_ci const verify = crypto.createVerify('SHA1'); 4721cb0ef41Sopenharmony_ci verify.update(input); 4731cb0ef41Sopenharmony_ci 4741cb0ef41Sopenharmony_ci assert.strictEqual(verify.verify(dsaPubPem, signature, 'hex'), true); 4751cb0ef41Sopenharmony_ci} 476