11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ciconst common = require('../common');
31cb0ef41Sopenharmony_ciif (!common.hasCrypto)
41cb0ef41Sopenharmony_ci  common.skip('missing crypto');
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ciconst assert = require('assert');
71cb0ef41Sopenharmony_ciconst fs = require('fs');
81cb0ef41Sopenharmony_ciconst path = require('path');
91cb0ef41Sopenharmony_ciconst exec = require('child_process').exec;
101cb0ef41Sopenharmony_ciconst crypto = require('crypto');
111cb0ef41Sopenharmony_ciconst fixtures = require('../common/fixtures');
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ci// Test certificates
141cb0ef41Sopenharmony_ciconst certPem = fixtures.readKey('rsa_cert.crt');
151cb0ef41Sopenharmony_ciconst keyPem = fixtures.readKey('rsa_private.pem');
161cb0ef41Sopenharmony_ciconst keySize = 2048;
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ci{
191cb0ef41Sopenharmony_ci  const Sign = crypto.Sign;
201cb0ef41Sopenharmony_ci  const instance = Sign('SHA256');
211cb0ef41Sopenharmony_ci  assert(instance instanceof Sign, 'Sign is expected to return a new ' +
221cb0ef41Sopenharmony_ci                                   'instance when called without `new`');
231cb0ef41Sopenharmony_ci}
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ci{
261cb0ef41Sopenharmony_ci  const Verify = crypto.Verify;
271cb0ef41Sopenharmony_ci  const instance = Verify('SHA256');
281cb0ef41Sopenharmony_ci  assert(instance instanceof Verify, 'Verify is expected to return a new ' +
291cb0ef41Sopenharmony_ci                                     'instance when called without `new`');
301cb0ef41Sopenharmony_ci}
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci// Test handling of exceptional conditions
331cb0ef41Sopenharmony_ci{
341cb0ef41Sopenharmony_ci  const library = {
351cb0ef41Sopenharmony_ci    configurable: true,
361cb0ef41Sopenharmony_ci    set() {
371cb0ef41Sopenharmony_ci      throw new Error('bye, bye, library');
381cb0ef41Sopenharmony_ci    }
391cb0ef41Sopenharmony_ci  };
401cb0ef41Sopenharmony_ci  Object.defineProperty(Object.prototype, 'library', library);
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci  assert.throws(() => {
431cb0ef41Sopenharmony_ci    crypto.createSign('sha1').sign(
441cb0ef41Sopenharmony_ci      `-----BEGIN RSA PRIVATE KEY-----
451cb0ef41Sopenharmony_ci      AAAAAAAAAAAA
461cb0ef41Sopenharmony_ci      -----END RSA PRIVATE KEY-----`);
471cb0ef41Sopenharmony_ci  }, { message: 'bye, bye, library' });
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci  delete Object.prototype.library;
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci  const errorStack = {
521cb0ef41Sopenharmony_ci    configurable: true,
531cb0ef41Sopenharmony_ci    set() {
541cb0ef41Sopenharmony_ci      throw new Error('bye, bye, error stack');
551cb0ef41Sopenharmony_ci    }
561cb0ef41Sopenharmony_ci  };
571cb0ef41Sopenharmony_ci  Object.defineProperty(Object.prototype, 'opensslErrorStack', errorStack);
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ci  assert.throws(() => {
601cb0ef41Sopenharmony_ci    crypto.createSign('SHA1')
611cb0ef41Sopenharmony_ci      .update('Test123')
621cb0ef41Sopenharmony_ci      .sign({
631cb0ef41Sopenharmony_ci        key: keyPem,
641cb0ef41Sopenharmony_ci        padding: crypto.constants.RSA_PKCS1_OAEP_PADDING
651cb0ef41Sopenharmony_ci      });
661cb0ef41Sopenharmony_ci  }, { message: common.hasOpenSSL3 ?
671cb0ef41Sopenharmony_ci    'error:1C8000A5:Provider routines::illegal or unsupported padding mode' :
681cb0ef41Sopenharmony_ci    'bye, bye, error stack' });
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ci  delete Object.prototype.opensslErrorStack;
711cb0ef41Sopenharmony_ci}
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ciassert.throws(
741cb0ef41Sopenharmony_ci  () => crypto.createVerify('SHA256').verify({
751cb0ef41Sopenharmony_ci    key: certPem,
761cb0ef41Sopenharmony_ci    padding: null,
771cb0ef41Sopenharmony_ci  }, ''),
781cb0ef41Sopenharmony_ci  {
791cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_VALUE',
801cb0ef41Sopenharmony_ci    name: 'TypeError',
811cb0ef41Sopenharmony_ci    message: "The property 'options.padding' is invalid. Received null",
821cb0ef41Sopenharmony_ci  });
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ciassert.throws(
851cb0ef41Sopenharmony_ci  () => crypto.createVerify('SHA256').verify({
861cb0ef41Sopenharmony_ci    key: certPem,
871cb0ef41Sopenharmony_ci    saltLength: null,
881cb0ef41Sopenharmony_ci  }, ''),
891cb0ef41Sopenharmony_ci  {
901cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_VALUE',
911cb0ef41Sopenharmony_ci    name: 'TypeError',
921cb0ef41Sopenharmony_ci    message: "The property 'options.saltLength' is invalid. Received null",
931cb0ef41Sopenharmony_ci  });
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci// Test signing and verifying
961cb0ef41Sopenharmony_ci{
971cb0ef41Sopenharmony_ci  const s1 = crypto.createSign('SHA1')
981cb0ef41Sopenharmony_ci                   .update('Test123')
991cb0ef41Sopenharmony_ci                   .sign(keyPem, 'base64');
1001cb0ef41Sopenharmony_ci  let s1stream = crypto.createSign('SHA1');
1011cb0ef41Sopenharmony_ci  s1stream.end('Test123');
1021cb0ef41Sopenharmony_ci  s1stream = s1stream.sign(keyPem, 'base64');
1031cb0ef41Sopenharmony_ci  assert.strictEqual(s1, s1stream, `${s1} should equal ${s1stream}`);
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci  const verified = crypto.createVerify('SHA1')
1061cb0ef41Sopenharmony_ci                         .update('Test')
1071cb0ef41Sopenharmony_ci                         .update('123')
1081cb0ef41Sopenharmony_ci                         .verify(certPem, s1, 'base64');
1091cb0ef41Sopenharmony_ci  assert.strictEqual(verified, true);
1101cb0ef41Sopenharmony_ci}
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci{
1131cb0ef41Sopenharmony_ci  const s2 = crypto.createSign('SHA256')
1141cb0ef41Sopenharmony_ci                   .update('Test123')
1151cb0ef41Sopenharmony_ci                   .sign(keyPem, 'latin1');
1161cb0ef41Sopenharmony_ci  let s2stream = crypto.createSign('SHA256');
1171cb0ef41Sopenharmony_ci  s2stream.end('Test123');
1181cb0ef41Sopenharmony_ci  s2stream = s2stream.sign(keyPem, 'latin1');
1191cb0ef41Sopenharmony_ci  assert.strictEqual(s2, s2stream, `${s2} should equal ${s2stream}`);
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_ci  let verified = crypto.createVerify('SHA256')
1221cb0ef41Sopenharmony_ci                       .update('Test')
1231cb0ef41Sopenharmony_ci                       .update('123')
1241cb0ef41Sopenharmony_ci                       .verify(certPem, s2, 'latin1');
1251cb0ef41Sopenharmony_ci  assert.strictEqual(verified, true);
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ci  const verStream = crypto.createVerify('SHA256');
1281cb0ef41Sopenharmony_ci  verStream.write('Tes');
1291cb0ef41Sopenharmony_ci  verStream.write('t12');
1301cb0ef41Sopenharmony_ci  verStream.end('3');
1311cb0ef41Sopenharmony_ci  verified = verStream.verify(certPem, s2, 'latin1');
1321cb0ef41Sopenharmony_ci  assert.strictEqual(verified, true);
1331cb0ef41Sopenharmony_ci}
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci{
1361cb0ef41Sopenharmony_ci  const s3 = crypto.createSign('SHA1')
1371cb0ef41Sopenharmony_ci                   .update('Test123')
1381cb0ef41Sopenharmony_ci                   .sign(keyPem, 'buffer');
1391cb0ef41Sopenharmony_ci  let verified = crypto.createVerify('SHA1')
1401cb0ef41Sopenharmony_ci                       .update('Test')
1411cb0ef41Sopenharmony_ci                       .update('123')
1421cb0ef41Sopenharmony_ci                       .verify(certPem, s3);
1431cb0ef41Sopenharmony_ci  assert.strictEqual(verified, true);
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ci  const verStream = crypto.createVerify('SHA1');
1461cb0ef41Sopenharmony_ci  verStream.write('Tes');
1471cb0ef41Sopenharmony_ci  verStream.write('t12');
1481cb0ef41Sopenharmony_ci  verStream.end('3');
1491cb0ef41Sopenharmony_ci  verified = verStream.verify(certPem, s3);
1501cb0ef41Sopenharmony_ci  assert.strictEqual(verified, true);
1511cb0ef41Sopenharmony_ci}
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ci// Special tests for RSA_PKCS1_PSS_PADDING
1541cb0ef41Sopenharmony_ci{
1551cb0ef41Sopenharmony_ci  function testPSS(algo, hLen) {
1561cb0ef41Sopenharmony_ci    // Maximum permissible salt length
1571cb0ef41Sopenharmony_ci    const max = keySize / 8 - hLen - 2;
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_ci    function getEffectiveSaltLength(saltLength) {
1601cb0ef41Sopenharmony_ci      switch (saltLength) {
1611cb0ef41Sopenharmony_ci        case crypto.constants.RSA_PSS_SALTLEN_DIGEST:
1621cb0ef41Sopenharmony_ci          return hLen;
1631cb0ef41Sopenharmony_ci        case crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN:
1641cb0ef41Sopenharmony_ci          return max;
1651cb0ef41Sopenharmony_ci        default:
1661cb0ef41Sopenharmony_ci          return saltLength;
1671cb0ef41Sopenharmony_ci      }
1681cb0ef41Sopenharmony_ci    }
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ci    const signSaltLengths = [
1711cb0ef41Sopenharmony_ci      crypto.constants.RSA_PSS_SALTLEN_DIGEST,
1721cb0ef41Sopenharmony_ci      getEffectiveSaltLength(crypto.constants.RSA_PSS_SALTLEN_DIGEST),
1731cb0ef41Sopenharmony_ci      crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN,
1741cb0ef41Sopenharmony_ci      getEffectiveSaltLength(crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN),
1751cb0ef41Sopenharmony_ci      0, 16, 32, 64, 128,
1761cb0ef41Sopenharmony_ci    ];
1771cb0ef41Sopenharmony_ci
1781cb0ef41Sopenharmony_ci    const verifySaltLengths = [
1791cb0ef41Sopenharmony_ci      crypto.constants.RSA_PSS_SALTLEN_DIGEST,
1801cb0ef41Sopenharmony_ci      getEffectiveSaltLength(crypto.constants.RSA_PSS_SALTLEN_DIGEST),
1811cb0ef41Sopenharmony_ci      getEffectiveSaltLength(crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN),
1821cb0ef41Sopenharmony_ci      0, 16, 32, 64, 128,
1831cb0ef41Sopenharmony_ci    ];
1841cb0ef41Sopenharmony_ci    const errMessage = /^Error:.*data too large for key size$/;
1851cb0ef41Sopenharmony_ci
1861cb0ef41Sopenharmony_ci    const data = Buffer.from('Test123');
1871cb0ef41Sopenharmony_ci
1881cb0ef41Sopenharmony_ci    signSaltLengths.forEach((signSaltLength) => {
1891cb0ef41Sopenharmony_ci      if (signSaltLength > max) {
1901cb0ef41Sopenharmony_ci        // If the salt length is too big, an Error should be thrown
1911cb0ef41Sopenharmony_ci        assert.throws(() => {
1921cb0ef41Sopenharmony_ci          crypto.createSign(algo)
1931cb0ef41Sopenharmony_ci            .update(data)
1941cb0ef41Sopenharmony_ci            .sign({
1951cb0ef41Sopenharmony_ci              key: keyPem,
1961cb0ef41Sopenharmony_ci              padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
1971cb0ef41Sopenharmony_ci              saltLength: signSaltLength
1981cb0ef41Sopenharmony_ci            });
1991cb0ef41Sopenharmony_ci        }, errMessage);
2001cb0ef41Sopenharmony_ci        assert.throws(() => {
2011cb0ef41Sopenharmony_ci          crypto.sign(algo, data, {
2021cb0ef41Sopenharmony_ci            key: keyPem,
2031cb0ef41Sopenharmony_ci            padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
2041cb0ef41Sopenharmony_ci            saltLength: signSaltLength
2051cb0ef41Sopenharmony_ci          });
2061cb0ef41Sopenharmony_ci        }, errMessage);
2071cb0ef41Sopenharmony_ci      } else {
2081cb0ef41Sopenharmony_ci        // Otherwise, a valid signature should be generated
2091cb0ef41Sopenharmony_ci        const s4 = crypto.createSign(algo)
2101cb0ef41Sopenharmony_ci                         .update(data)
2111cb0ef41Sopenharmony_ci                         .sign({
2121cb0ef41Sopenharmony_ci                           key: keyPem,
2131cb0ef41Sopenharmony_ci                           padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
2141cb0ef41Sopenharmony_ci                           saltLength: signSaltLength
2151cb0ef41Sopenharmony_ci                         });
2161cb0ef41Sopenharmony_ci        const s4_2 = crypto.sign(algo, data, {
2171cb0ef41Sopenharmony_ci          key: keyPem,
2181cb0ef41Sopenharmony_ci          padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
2191cb0ef41Sopenharmony_ci          saltLength: signSaltLength
2201cb0ef41Sopenharmony_ci        });
2211cb0ef41Sopenharmony_ci
2221cb0ef41Sopenharmony_ci        [s4, s4_2].forEach((sig) => {
2231cb0ef41Sopenharmony_ci          let verified;
2241cb0ef41Sopenharmony_ci          verifySaltLengths.forEach((verifySaltLength) => {
2251cb0ef41Sopenharmony_ci            // Verification should succeed if and only if the salt length is
2261cb0ef41Sopenharmony_ci            // correct
2271cb0ef41Sopenharmony_ci            verified = crypto.createVerify(algo)
2281cb0ef41Sopenharmony_ci                             .update(data)
2291cb0ef41Sopenharmony_ci                             .verify({
2301cb0ef41Sopenharmony_ci                               key: certPem,
2311cb0ef41Sopenharmony_ci                               padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
2321cb0ef41Sopenharmony_ci                               saltLength: verifySaltLength
2331cb0ef41Sopenharmony_ci                             }, sig);
2341cb0ef41Sopenharmony_ci            assert.strictEqual(verified, crypto.verify(algo, data, {
2351cb0ef41Sopenharmony_ci              key: certPem,
2361cb0ef41Sopenharmony_ci              padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
2371cb0ef41Sopenharmony_ci              saltLength: verifySaltLength
2381cb0ef41Sopenharmony_ci            }, sig));
2391cb0ef41Sopenharmony_ci            const saltLengthCorrect = getEffectiveSaltLength(signSaltLength) ===
2401cb0ef41Sopenharmony_ci                                      getEffectiveSaltLength(verifySaltLength);
2411cb0ef41Sopenharmony_ci            assert.strictEqual(verified, saltLengthCorrect);
2421cb0ef41Sopenharmony_ci          });
2431cb0ef41Sopenharmony_ci
2441cb0ef41Sopenharmony_ci          // Verification using RSA_PSS_SALTLEN_AUTO should always work
2451cb0ef41Sopenharmony_ci          verified = crypto.createVerify(algo)
2461cb0ef41Sopenharmony_ci                           .update(data)
2471cb0ef41Sopenharmony_ci                           .verify({
2481cb0ef41Sopenharmony_ci                             key: certPem,
2491cb0ef41Sopenharmony_ci                             padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
2501cb0ef41Sopenharmony_ci                             saltLength: crypto.constants.RSA_PSS_SALTLEN_AUTO
2511cb0ef41Sopenharmony_ci                           }, sig);
2521cb0ef41Sopenharmony_ci          assert.strictEqual(verified, true);
2531cb0ef41Sopenharmony_ci          assert.strictEqual(verified, crypto.verify(algo, data, {
2541cb0ef41Sopenharmony_ci            key: certPem,
2551cb0ef41Sopenharmony_ci            padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
2561cb0ef41Sopenharmony_ci            saltLength: crypto.constants.RSA_PSS_SALTLEN_AUTO
2571cb0ef41Sopenharmony_ci          }, sig));
2581cb0ef41Sopenharmony_ci
2591cb0ef41Sopenharmony_ci          // Verifying an incorrect message should never work
2601cb0ef41Sopenharmony_ci          const wrongData = Buffer.from('Test1234');
2611cb0ef41Sopenharmony_ci          verified = crypto.createVerify(algo)
2621cb0ef41Sopenharmony_ci                           .update(wrongData)
2631cb0ef41Sopenharmony_ci                           .verify({
2641cb0ef41Sopenharmony_ci                             key: certPem,
2651cb0ef41Sopenharmony_ci                             padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
2661cb0ef41Sopenharmony_ci                             saltLength: crypto.constants.RSA_PSS_SALTLEN_AUTO
2671cb0ef41Sopenharmony_ci                           }, sig);
2681cb0ef41Sopenharmony_ci          assert.strictEqual(verified, false);
2691cb0ef41Sopenharmony_ci          assert.strictEqual(verified, crypto.verify(algo, wrongData, {
2701cb0ef41Sopenharmony_ci            key: certPem,
2711cb0ef41Sopenharmony_ci            padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
2721cb0ef41Sopenharmony_ci            saltLength: crypto.constants.RSA_PSS_SALTLEN_AUTO
2731cb0ef41Sopenharmony_ci          }, sig));
2741cb0ef41Sopenharmony_ci        });
2751cb0ef41Sopenharmony_ci      }
2761cb0ef41Sopenharmony_ci    });
2771cb0ef41Sopenharmony_ci  }
2781cb0ef41Sopenharmony_ci
2791cb0ef41Sopenharmony_ci  testPSS('SHA1', 20);
2801cb0ef41Sopenharmony_ci  testPSS('SHA256', 32);
2811cb0ef41Sopenharmony_ci}
2821cb0ef41Sopenharmony_ci
2831cb0ef41Sopenharmony_ci// Test vectors for RSA_PKCS1_PSS_PADDING provided by the RSA Laboratories:
2841cb0ef41Sopenharmony_ci// https://www.emc.com/emc-plus/rsa-labs/standards-initiatives/pkcs-rsa-cryptography-standard.htm
2851cb0ef41Sopenharmony_ci{
2861cb0ef41Sopenharmony_ci  // We only test verification as we cannot specify explicit salts when signing
2871cb0ef41Sopenharmony_ci  function testVerify(cert, vector) {
2881cb0ef41Sopenharmony_ci    const verified = crypto.createVerify('SHA1')
2891cb0ef41Sopenharmony_ci                          .update(Buffer.from(vector.message, 'hex'))
2901cb0ef41Sopenharmony_ci                          .verify({
2911cb0ef41Sopenharmony_ci                            key: cert,
2921cb0ef41Sopenharmony_ci                            padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
2931cb0ef41Sopenharmony_ci                            saltLength: vector.salt.length / 2
2941cb0ef41Sopenharmony_ci                          }, vector.signature, 'hex');
2951cb0ef41Sopenharmony_ci    assert.strictEqual(verified, true);
2961cb0ef41Sopenharmony_ci  }
2971cb0ef41Sopenharmony_ci
2981cb0ef41Sopenharmony_ci  const examples = JSON.parse(fixtures.readSync('pss-vectors.json', 'utf8'));
2991cb0ef41Sopenharmony_ci
3001cb0ef41Sopenharmony_ci  for (const key in examples) {
3011cb0ef41Sopenharmony_ci    const example = examples[key];
3021cb0ef41Sopenharmony_ci    const publicKey = example.publicKey.join('\n');
3031cb0ef41Sopenharmony_ci    example.tests.forEach((test) => testVerify(publicKey, test));
3041cb0ef41Sopenharmony_ci  }
3051cb0ef41Sopenharmony_ci}
3061cb0ef41Sopenharmony_ci
3071cb0ef41Sopenharmony_ci// Test exceptions for invalid `padding` and `saltLength` values
3081cb0ef41Sopenharmony_ci{
3091cb0ef41Sopenharmony_ci  [null, NaN, 'boom', {}, [], true, false]
3101cb0ef41Sopenharmony_ci    .forEach((invalidValue) => {
3111cb0ef41Sopenharmony_ci      assert.throws(() => {
3121cb0ef41Sopenharmony_ci        crypto.createSign('SHA256')
3131cb0ef41Sopenharmony_ci          .update('Test123')
3141cb0ef41Sopenharmony_ci          .sign({
3151cb0ef41Sopenharmony_ci            key: keyPem,
3161cb0ef41Sopenharmony_ci            padding: invalidValue
3171cb0ef41Sopenharmony_ci          });
3181cb0ef41Sopenharmony_ci      }, {
3191cb0ef41Sopenharmony_ci        code: 'ERR_INVALID_ARG_VALUE',
3201cb0ef41Sopenharmony_ci        name: 'TypeError'
3211cb0ef41Sopenharmony_ci      });
3221cb0ef41Sopenharmony_ci
3231cb0ef41Sopenharmony_ci      assert.throws(() => {
3241cb0ef41Sopenharmony_ci        crypto.createSign('SHA256')
3251cb0ef41Sopenharmony_ci          .update('Test123')
3261cb0ef41Sopenharmony_ci          .sign({
3271cb0ef41Sopenharmony_ci            key: keyPem,
3281cb0ef41Sopenharmony_ci            padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
3291cb0ef41Sopenharmony_ci            saltLength: invalidValue
3301cb0ef41Sopenharmony_ci          });
3311cb0ef41Sopenharmony_ci      }, {
3321cb0ef41Sopenharmony_ci        code: 'ERR_INVALID_ARG_VALUE',
3331cb0ef41Sopenharmony_ci        name: 'TypeError'
3341cb0ef41Sopenharmony_ci      });
3351cb0ef41Sopenharmony_ci    });
3361cb0ef41Sopenharmony_ci
3371cb0ef41Sopenharmony_ci  assert.throws(() => {
3381cb0ef41Sopenharmony_ci    crypto.createSign('SHA1')
3391cb0ef41Sopenharmony_ci      .update('Test123')
3401cb0ef41Sopenharmony_ci      .sign({
3411cb0ef41Sopenharmony_ci        key: keyPem,
3421cb0ef41Sopenharmony_ci        padding: crypto.constants.RSA_PKCS1_OAEP_PADDING
3431cb0ef41Sopenharmony_ci      });
3441cb0ef41Sopenharmony_ci  }, common.hasOpenSSL3 ? {
3451cb0ef41Sopenharmony_ci    code: 'ERR_OSSL_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE',
3461cb0ef41Sopenharmony_ci    message: /illegal or unsupported padding mode/,
3471cb0ef41Sopenharmony_ci  } : {
3481cb0ef41Sopenharmony_ci    code: 'ERR_OSSL_RSA_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE',
3491cb0ef41Sopenharmony_ci    message: /illegal or unsupported padding mode/,
3501cb0ef41Sopenharmony_ci    opensslErrorStack: [
3511cb0ef41Sopenharmony_ci      'error:06089093:digital envelope routines:EVP_PKEY_CTX_ctrl:' +
3521cb0ef41Sopenharmony_ci      'command not supported',
3531cb0ef41Sopenharmony_ci    ],
3541cb0ef41Sopenharmony_ci  });
3551cb0ef41Sopenharmony_ci}
3561cb0ef41Sopenharmony_ci
3571cb0ef41Sopenharmony_ci// Test throws exception when key options is null
3581cb0ef41Sopenharmony_ci{
3591cb0ef41Sopenharmony_ci  assert.throws(() => {
3601cb0ef41Sopenharmony_ci    crypto.createSign('SHA1').update('Test123').sign(null, 'base64');
3611cb0ef41Sopenharmony_ci  }, {
3621cb0ef41Sopenharmony_ci    code: 'ERR_CRYPTO_SIGN_KEY_REQUIRED',
3631cb0ef41Sopenharmony_ci    name: 'Error'
3641cb0ef41Sopenharmony_ci  });
3651cb0ef41Sopenharmony_ci}
3661cb0ef41Sopenharmony_ci
3671cb0ef41Sopenharmony_ci{
3681cb0ef41Sopenharmony_ci  const sign = crypto.createSign('SHA1');
3691cb0ef41Sopenharmony_ci  const verify = crypto.createVerify('SHA1');
3701cb0ef41Sopenharmony_ci
3711cb0ef41Sopenharmony_ci  [1, [], {}, undefined, null, true, Infinity].forEach((input) => {
3721cb0ef41Sopenharmony_ci    const errObj = {
3731cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE',
3741cb0ef41Sopenharmony_ci      name: 'TypeError',
3751cb0ef41Sopenharmony_ci      message: 'The "algorithm" argument must be of type string.' +
3761cb0ef41Sopenharmony_ci               `${common.invalidArgTypeHelper(input)}`
3771cb0ef41Sopenharmony_ci    };
3781cb0ef41Sopenharmony_ci    assert.throws(() => crypto.createSign(input), errObj);
3791cb0ef41Sopenharmony_ci    assert.throws(() => crypto.createVerify(input), errObj);
3801cb0ef41Sopenharmony_ci
3811cb0ef41Sopenharmony_ci    errObj.message = 'The "data" argument must be of type string or an ' +
3821cb0ef41Sopenharmony_ci                     'instance of Buffer, TypedArray, or DataView.' +
3831cb0ef41Sopenharmony_ci                     common.invalidArgTypeHelper(input);
3841cb0ef41Sopenharmony_ci    assert.throws(() => sign.update(input), errObj);
3851cb0ef41Sopenharmony_ci    assert.throws(() => verify.update(input), errObj);
3861cb0ef41Sopenharmony_ci    assert.throws(() => sign._write(input, 'utf8', () => {}), errObj);
3871cb0ef41Sopenharmony_ci    assert.throws(() => verify._write(input, 'utf8', () => {}), errObj);
3881cb0ef41Sopenharmony_ci  });
3891cb0ef41Sopenharmony_ci
3901cb0ef41Sopenharmony_ci  [
3911cb0ef41Sopenharmony_ci    Uint8Array, Uint16Array, Uint32Array, Float32Array, Float64Array,
3921cb0ef41Sopenharmony_ci  ].forEach((clazz) => {
3931cb0ef41Sopenharmony_ci    // These should all just work
3941cb0ef41Sopenharmony_ci    sign.update(new clazz());
3951cb0ef41Sopenharmony_ci    verify.update(new clazz());
3961cb0ef41Sopenharmony_ci  });
3971cb0ef41Sopenharmony_ci
3981cb0ef41Sopenharmony_ci  [1, {}, [], Infinity].forEach((input) => {
3991cb0ef41Sopenharmony_ci    const errObj = {
4001cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE',
4011cb0ef41Sopenharmony_ci      name: 'TypeError',
4021cb0ef41Sopenharmony_ci    };
4031cb0ef41Sopenharmony_ci    assert.throws(() => sign.sign(input), errObj);
4041cb0ef41Sopenharmony_ci    assert.throws(() => verify.verify(input), errObj);
4051cb0ef41Sopenharmony_ci    assert.throws(() => verify.verify('test', input), errObj);
4061cb0ef41Sopenharmony_ci  });
4071cb0ef41Sopenharmony_ci}
4081cb0ef41Sopenharmony_ci
4091cb0ef41Sopenharmony_ci{
4101cb0ef41Sopenharmony_ci  assert.throws(
4111cb0ef41Sopenharmony_ci    () => crypto.createSign('sha8'),
4121cb0ef41Sopenharmony_ci    /Invalid digest/);
4131cb0ef41Sopenharmony_ci  assert.throws(
4141cb0ef41Sopenharmony_ci    () => crypto.sign('sha8', Buffer.alloc(1), keyPem),
4151cb0ef41Sopenharmony_ci    /Invalid digest/);
4161cb0ef41Sopenharmony_ci}
4171cb0ef41Sopenharmony_ci
4181cb0ef41Sopenharmony_ci[
4191cb0ef41Sopenharmony_ci  { private: fixtures.readKey('ed25519_private.pem', 'ascii'),
4201cb0ef41Sopenharmony_ci    public: fixtures.readKey('ed25519_public.pem', 'ascii'),
4211cb0ef41Sopenharmony_ci    algo: null,
4221cb0ef41Sopenharmony_ci    sigLen: 64 },
4231cb0ef41Sopenharmony_ci  { private: fixtures.readKey('ed448_private.pem', 'ascii'),
4241cb0ef41Sopenharmony_ci    public: fixtures.readKey('ed448_public.pem', 'ascii'),
4251cb0ef41Sopenharmony_ci    algo: null,
4261cb0ef41Sopenharmony_ci    sigLen: 114 },
4271cb0ef41Sopenharmony_ci  { private: fixtures.readKey('rsa_private_2048.pem', 'ascii'),
4281cb0ef41Sopenharmony_ci    public: fixtures.readKey('rsa_public_2048.pem', 'ascii'),
4291cb0ef41Sopenharmony_ci    algo: 'sha1',
4301cb0ef41Sopenharmony_ci    sigLen: 256 },
4311cb0ef41Sopenharmony_ci].forEach((pair) => {
4321cb0ef41Sopenharmony_ci  const algo = pair.algo;
4331cb0ef41Sopenharmony_ci
4341cb0ef41Sopenharmony_ci  {
4351cb0ef41Sopenharmony_ci    const data = Buffer.from('Hello world');
4361cb0ef41Sopenharmony_ci    const sig = crypto.sign(algo, data, pair.private);
4371cb0ef41Sopenharmony_ci    assert.strictEqual(sig.length, pair.sigLen);
4381cb0ef41Sopenharmony_ci
4391cb0ef41Sopenharmony_ci    assert.strictEqual(crypto.verify(algo, data, pair.private, sig),
4401cb0ef41Sopenharmony_ci                       true);
4411cb0ef41Sopenharmony_ci    assert.strictEqual(crypto.verify(algo, data, pair.public, sig),
4421cb0ef41Sopenharmony_ci                       true);
4431cb0ef41Sopenharmony_ci  }
4441cb0ef41Sopenharmony_ci
4451cb0ef41Sopenharmony_ci  {
4461cb0ef41Sopenharmony_ci    const data = Buffer.from('Hello world');
4471cb0ef41Sopenharmony_ci    const privKeyObj = crypto.createPrivateKey(pair.private);
4481cb0ef41Sopenharmony_ci    const pubKeyObj = crypto.createPublicKey(pair.public);
4491cb0ef41Sopenharmony_ci
4501cb0ef41Sopenharmony_ci    const sig = crypto.sign(algo, data, privKeyObj);
4511cb0ef41Sopenharmony_ci    assert.strictEqual(sig.length, pair.sigLen);
4521cb0ef41Sopenharmony_ci
4531cb0ef41Sopenharmony_ci    assert.strictEqual(crypto.verify(algo, data, privKeyObj, sig), true);
4541cb0ef41Sopenharmony_ci    assert.strictEqual(crypto.verify(algo, data, pubKeyObj, sig), true);
4551cb0ef41Sopenharmony_ci  }
4561cb0ef41Sopenharmony_ci
4571cb0ef41Sopenharmony_ci  {
4581cb0ef41Sopenharmony_ci    const data = Buffer.from('Hello world');
4591cb0ef41Sopenharmony_ci    const otherData = Buffer.from('Goodbye world');
4601cb0ef41Sopenharmony_ci    const otherSig = crypto.sign(algo, otherData, pair.private);
4611cb0ef41Sopenharmony_ci    assert.strictEqual(crypto.verify(algo, data, pair.private, otherSig),
4621cb0ef41Sopenharmony_ci                       false);
4631cb0ef41Sopenharmony_ci  }
4641cb0ef41Sopenharmony_ci
4651cb0ef41Sopenharmony_ci  [
4661cb0ef41Sopenharmony_ci    Uint8Array, Uint16Array, Uint32Array, Float32Array, Float64Array,
4671cb0ef41Sopenharmony_ci  ].forEach((clazz) => {
4681cb0ef41Sopenharmony_ci    const data = new clazz();
4691cb0ef41Sopenharmony_ci    const sig = crypto.sign(algo, data, pair.private);
4701cb0ef41Sopenharmony_ci    assert.strictEqual(crypto.verify(algo, data, pair.private, sig),
4711cb0ef41Sopenharmony_ci                       true);
4721cb0ef41Sopenharmony_ci  });
4731cb0ef41Sopenharmony_ci});
4741cb0ef41Sopenharmony_ci
4751cb0ef41Sopenharmony_ci[1, {}, [], true, Infinity].forEach((input) => {
4761cb0ef41Sopenharmony_ci  const data = Buffer.alloc(1);
4771cb0ef41Sopenharmony_ci  const sig = Buffer.alloc(1);
4781cb0ef41Sopenharmony_ci  const errObj = {
4791cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_TYPE',
4801cb0ef41Sopenharmony_ci    name: 'TypeError',
4811cb0ef41Sopenharmony_ci  };
4821cb0ef41Sopenharmony_ci
4831cb0ef41Sopenharmony_ci  assert.throws(() => crypto.sign(null, input, 'asdf'), errObj);
4841cb0ef41Sopenharmony_ci  assert.throws(() => crypto.verify(null, input, 'asdf', sig), errObj);
4851cb0ef41Sopenharmony_ci
4861cb0ef41Sopenharmony_ci  assert.throws(() => crypto.sign(null, data, input), errObj);
4871cb0ef41Sopenharmony_ci  assert.throws(() => crypto.verify(null, data, input, sig), errObj);
4881cb0ef41Sopenharmony_ci
4891cb0ef41Sopenharmony_ci  errObj.message = 'The "signature" argument must be an instance of ' +
4901cb0ef41Sopenharmony_ci                   'Buffer, TypedArray, or DataView.' +
4911cb0ef41Sopenharmony_ci                   common.invalidArgTypeHelper(input);
4921cb0ef41Sopenharmony_ci  assert.throws(() => crypto.verify(null, data, 'test', input), errObj);
4931cb0ef41Sopenharmony_ci});
4941cb0ef41Sopenharmony_ci
4951cb0ef41Sopenharmony_ci{
4961cb0ef41Sopenharmony_ci  const data = Buffer.from('Hello world');
4971cb0ef41Sopenharmony_ci  const keys = [['ec-key.pem', 64], ['dsa_private_1025.pem', 40]];
4981cb0ef41Sopenharmony_ci
4991cb0ef41Sopenharmony_ci  for (const [file, length] of keys) {
5001cb0ef41Sopenharmony_ci    const privKey = fixtures.readKey(file);
5011cb0ef41Sopenharmony_ci    [
5021cb0ef41Sopenharmony_ci      crypto.createSign('sha1').update(data).sign(privKey),
5031cb0ef41Sopenharmony_ci      crypto.sign('sha1', data, privKey),
5041cb0ef41Sopenharmony_ci      crypto.sign('sha1', data, { key: privKey, dsaEncoding: 'der' }),
5051cb0ef41Sopenharmony_ci    ].forEach((sig) => {
5061cb0ef41Sopenharmony_ci      // Signature length variability due to DER encoding
5071cb0ef41Sopenharmony_ci      assert(sig.length >= length + 4 && sig.length <= length + 8);
5081cb0ef41Sopenharmony_ci
5091cb0ef41Sopenharmony_ci      assert.strictEqual(
5101cb0ef41Sopenharmony_ci        crypto.createVerify('sha1').update(data).verify(privKey, sig),
5111cb0ef41Sopenharmony_ci        true
5121cb0ef41Sopenharmony_ci      );
5131cb0ef41Sopenharmony_ci      assert.strictEqual(crypto.verify('sha1', data, privKey, sig), true);
5141cb0ef41Sopenharmony_ci    });
5151cb0ef41Sopenharmony_ci
5161cb0ef41Sopenharmony_ci    // Test (EC)DSA signature conversion.
5171cb0ef41Sopenharmony_ci    const opts = { key: privKey, dsaEncoding: 'ieee-p1363' };
5181cb0ef41Sopenharmony_ci    let sig = crypto.sign('sha1', data, opts);
5191cb0ef41Sopenharmony_ci    // Unlike DER signatures, IEEE P1363 signatures have a predictable length.
5201cb0ef41Sopenharmony_ci    assert.strictEqual(sig.length, length);
5211cb0ef41Sopenharmony_ci    assert.strictEqual(crypto.verify('sha1', data, opts, sig), true);
5221cb0ef41Sopenharmony_ci    assert.strictEqual(crypto.createVerify('sha1')
5231cb0ef41Sopenharmony_ci                             .update(data)
5241cb0ef41Sopenharmony_ci                             .verify(opts, sig), true);
5251cb0ef41Sopenharmony_ci
5261cb0ef41Sopenharmony_ci    // Test invalid signature lengths.
5271cb0ef41Sopenharmony_ci    for (const i of [-2, -1, 1, 2, 4, 8]) {
5281cb0ef41Sopenharmony_ci      sig = crypto.randomBytes(length + i);
5291cb0ef41Sopenharmony_ci      let result;
5301cb0ef41Sopenharmony_ci      try {
5311cb0ef41Sopenharmony_ci        result = crypto.verify('sha1', data, opts, sig);
5321cb0ef41Sopenharmony_ci      } catch (err) {
5331cb0ef41Sopenharmony_ci        assert.match(err.message, /asn1 encoding/);
5341cb0ef41Sopenharmony_ci        assert.strictEqual(err.library, 'asn1 encoding routines');
5351cb0ef41Sopenharmony_ci        continue;
5361cb0ef41Sopenharmony_ci      }
5371cb0ef41Sopenharmony_ci      assert.strictEqual(result, false);
5381cb0ef41Sopenharmony_ci    }
5391cb0ef41Sopenharmony_ci  }
5401cb0ef41Sopenharmony_ci
5411cb0ef41Sopenharmony_ci  // Test verifying externally signed messages.
5421cb0ef41Sopenharmony_ci  const extSig = Buffer.from('494c18ab5c8a62a72aea5041966902bcfa229821af2bf65' +
5431cb0ef41Sopenharmony_ci                             '0b5b4870d1fe6aebeaed9460c62210693b5b0a300033823' +
5441cb0ef41Sopenharmony_ci                             '33d9529c8abd8c5948940af944828be16c', 'hex');
5451cb0ef41Sopenharmony_ci  for (const ok of [true, false]) {
5461cb0ef41Sopenharmony_ci    assert.strictEqual(
5471cb0ef41Sopenharmony_ci      crypto.verify('sha256', data, {
5481cb0ef41Sopenharmony_ci        key: fixtures.readKey('ec-key.pem'),
5491cb0ef41Sopenharmony_ci        dsaEncoding: 'ieee-p1363'
5501cb0ef41Sopenharmony_ci      }, extSig),
5511cb0ef41Sopenharmony_ci      ok
5521cb0ef41Sopenharmony_ci    );
5531cb0ef41Sopenharmony_ci
5541cb0ef41Sopenharmony_ci    assert.strictEqual(
5551cb0ef41Sopenharmony_ci      crypto.createVerify('sha256').update(data).verify({
5561cb0ef41Sopenharmony_ci        key: fixtures.readKey('ec-key.pem'),
5571cb0ef41Sopenharmony_ci        dsaEncoding: 'ieee-p1363'
5581cb0ef41Sopenharmony_ci      }, extSig),
5591cb0ef41Sopenharmony_ci      ok
5601cb0ef41Sopenharmony_ci    );
5611cb0ef41Sopenharmony_ci
5621cb0ef41Sopenharmony_ci    extSig[Math.floor(Math.random() * extSig.length)] ^= 1;
5631cb0ef41Sopenharmony_ci  }
5641cb0ef41Sopenharmony_ci
5651cb0ef41Sopenharmony_ci  // Non-(EC)DSA keys should ignore the option.
5661cb0ef41Sopenharmony_ci  const sig = crypto.sign('sha1', data, {
5671cb0ef41Sopenharmony_ci    key: keyPem,
5681cb0ef41Sopenharmony_ci    dsaEncoding: 'ieee-p1363'
5691cb0ef41Sopenharmony_ci  });
5701cb0ef41Sopenharmony_ci  assert.strictEqual(crypto.verify('sha1', data, certPem, sig), true);
5711cb0ef41Sopenharmony_ci  assert.strictEqual(
5721cb0ef41Sopenharmony_ci    crypto.verify('sha1', data, {
5731cb0ef41Sopenharmony_ci      key: certPem,
5741cb0ef41Sopenharmony_ci      dsaEncoding: 'ieee-p1363'
5751cb0ef41Sopenharmony_ci    }, sig),
5761cb0ef41Sopenharmony_ci    true
5771cb0ef41Sopenharmony_ci  );
5781cb0ef41Sopenharmony_ci  assert.strictEqual(
5791cb0ef41Sopenharmony_ci    crypto.verify('sha1', data, {
5801cb0ef41Sopenharmony_ci      key: certPem,
5811cb0ef41Sopenharmony_ci      dsaEncoding: 'der'
5821cb0ef41Sopenharmony_ci    }, sig),
5831cb0ef41Sopenharmony_ci    true
5841cb0ef41Sopenharmony_ci  );
5851cb0ef41Sopenharmony_ci
5861cb0ef41Sopenharmony_ci  for (const dsaEncoding of ['foo', null, {}, 5, true, NaN]) {
5871cb0ef41Sopenharmony_ci    assert.throws(() => {
5881cb0ef41Sopenharmony_ci      crypto.sign('sha1', data, {
5891cb0ef41Sopenharmony_ci        key: certPem,
5901cb0ef41Sopenharmony_ci        dsaEncoding
5911cb0ef41Sopenharmony_ci      });
5921cb0ef41Sopenharmony_ci    }, {
5931cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_VALUE'
5941cb0ef41Sopenharmony_ci    });
5951cb0ef41Sopenharmony_ci  }
5961cb0ef41Sopenharmony_ci}
5971cb0ef41Sopenharmony_ci
5981cb0ef41Sopenharmony_ci
5991cb0ef41Sopenharmony_ci// RSA-PSS Sign test by verifying with 'openssl dgst -verify'
6001cb0ef41Sopenharmony_ci// Note: this particular test *must* be the last in this file as it will exit
6011cb0ef41Sopenharmony_ci// early if no openssl binary is found
6021cb0ef41Sopenharmony_ci{
6031cb0ef41Sopenharmony_ci  if (!common.opensslCli)
6041cb0ef41Sopenharmony_ci    common.skip('node compiled without OpenSSL CLI.');
6051cb0ef41Sopenharmony_ci
6061cb0ef41Sopenharmony_ci  const pubfile = fixtures.path('keys', 'rsa_public_2048.pem');
6071cb0ef41Sopenharmony_ci  const privkey = fixtures.readKey('rsa_private_2048.pem');
6081cb0ef41Sopenharmony_ci
6091cb0ef41Sopenharmony_ci  const msg = 'Test123';
6101cb0ef41Sopenharmony_ci  const s5 = crypto.createSign('SHA256')
6111cb0ef41Sopenharmony_ci    .update(msg)
6121cb0ef41Sopenharmony_ci    .sign({
6131cb0ef41Sopenharmony_ci      key: privkey,
6141cb0ef41Sopenharmony_ci      padding: crypto.constants.RSA_PKCS1_PSS_PADDING
6151cb0ef41Sopenharmony_ci    });
6161cb0ef41Sopenharmony_ci
6171cb0ef41Sopenharmony_ci  const tmpdir = require('../common/tmpdir');
6181cb0ef41Sopenharmony_ci  tmpdir.refresh();
6191cb0ef41Sopenharmony_ci
6201cb0ef41Sopenharmony_ci  const sigfile = path.join(tmpdir.path, 's5.sig');
6211cb0ef41Sopenharmony_ci  fs.writeFileSync(sigfile, s5);
6221cb0ef41Sopenharmony_ci  const msgfile = path.join(tmpdir.path, 's5.msg');
6231cb0ef41Sopenharmony_ci  fs.writeFileSync(msgfile, msg);
6241cb0ef41Sopenharmony_ci
6251cb0ef41Sopenharmony_ci  const cmd =
6261cb0ef41Sopenharmony_ci    `"${common.opensslCli}" dgst -sha256 -verify "${pubfile}" -signature "${
6271cb0ef41Sopenharmony_ci      sigfile}" -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-2 "${
6281cb0ef41Sopenharmony_ci      msgfile}"`;
6291cb0ef41Sopenharmony_ci
6301cb0ef41Sopenharmony_ci  exec(cmd, common.mustCall((err, stdout, stderr) => {
6311cb0ef41Sopenharmony_ci    assert(stdout.includes('Verified OK'));
6321cb0ef41Sopenharmony_ci  }));
6331cb0ef41Sopenharmony_ci}
6341cb0ef41Sopenharmony_ci
6351cb0ef41Sopenharmony_ci{
6361cb0ef41Sopenharmony_ci  // Test RSA-PSS.
6371cb0ef41Sopenharmony_ci  {
6381cb0ef41Sopenharmony_ci    // This key pair does not restrict the message digest algorithm or salt
6391cb0ef41Sopenharmony_ci    // length.
6401cb0ef41Sopenharmony_ci    const publicPem = fixtures.readKey('rsa_pss_public_2048.pem');
6411cb0ef41Sopenharmony_ci    const privatePem = fixtures.readKey('rsa_pss_private_2048.pem');
6421cb0ef41Sopenharmony_ci
6431cb0ef41Sopenharmony_ci    const publicKey = crypto.createPublicKey(publicPem);
6441cb0ef41Sopenharmony_ci    const privateKey = crypto.createPrivateKey(privatePem);
6451cb0ef41Sopenharmony_ci
6461cb0ef41Sopenharmony_ci    for (const key of [privatePem, privateKey]) {
6471cb0ef41Sopenharmony_ci      // Any algorithm should work.
6481cb0ef41Sopenharmony_ci      for (const algo of ['sha1', 'sha256']) {
6491cb0ef41Sopenharmony_ci        // Any salt length should work.
6501cb0ef41Sopenharmony_ci        for (const saltLength of [undefined, 8, 10, 12, 16, 18, 20]) {
6511cb0ef41Sopenharmony_ci          const signature = crypto.sign(algo, 'foo', { key, saltLength });
6521cb0ef41Sopenharmony_ci
6531cb0ef41Sopenharmony_ci          for (const pkey of [key, publicKey, publicPem]) {
6541cb0ef41Sopenharmony_ci            const okay = crypto.verify(
6551cb0ef41Sopenharmony_ci              algo,
6561cb0ef41Sopenharmony_ci              'foo',
6571cb0ef41Sopenharmony_ci              { key: pkey, saltLength },
6581cb0ef41Sopenharmony_ci              signature
6591cb0ef41Sopenharmony_ci            );
6601cb0ef41Sopenharmony_ci
6611cb0ef41Sopenharmony_ci            assert.ok(okay);
6621cb0ef41Sopenharmony_ci          }
6631cb0ef41Sopenharmony_ci        }
6641cb0ef41Sopenharmony_ci      }
6651cb0ef41Sopenharmony_ci    }
6661cb0ef41Sopenharmony_ci  }
6671cb0ef41Sopenharmony_ci
6681cb0ef41Sopenharmony_ci  {
6691cb0ef41Sopenharmony_ci    // This key pair enforces sha256 as the message digest and the MGF1
6701cb0ef41Sopenharmony_ci    // message digest and a salt length of at least 16 bytes.
6711cb0ef41Sopenharmony_ci    const publicPem =
6721cb0ef41Sopenharmony_ci      fixtures.readKey('rsa_pss_public_2048_sha256_sha256_16.pem');
6731cb0ef41Sopenharmony_ci    const privatePem =
6741cb0ef41Sopenharmony_ci      fixtures.readKey('rsa_pss_private_2048_sha256_sha256_16.pem');
6751cb0ef41Sopenharmony_ci
6761cb0ef41Sopenharmony_ci    const publicKey = crypto.createPublicKey(publicPem);
6771cb0ef41Sopenharmony_ci    const privateKey = crypto.createPrivateKey(privatePem);
6781cb0ef41Sopenharmony_ci
6791cb0ef41Sopenharmony_ci    for (const key of [privatePem, privateKey]) {
6801cb0ef41Sopenharmony_ci      // Signing with anything other than sha256 should fail.
6811cb0ef41Sopenharmony_ci      assert.throws(() => {
6821cb0ef41Sopenharmony_ci        crypto.sign('sha1', 'foo', key);
6831cb0ef41Sopenharmony_ci      }, /digest not allowed/);
6841cb0ef41Sopenharmony_ci
6851cb0ef41Sopenharmony_ci      // Signing with salt lengths less than 16 bytes should fail.
6861cb0ef41Sopenharmony_ci      for (const saltLength of [8, 10, 12]) {
6871cb0ef41Sopenharmony_ci        assert.throws(() => {
6881cb0ef41Sopenharmony_ci          crypto.sign('sha256', 'foo', { key, saltLength });
6891cb0ef41Sopenharmony_ci        }, /pss saltlen too small/);
6901cb0ef41Sopenharmony_ci      }
6911cb0ef41Sopenharmony_ci
6921cb0ef41Sopenharmony_ci      // Signing with sha256 and appropriate salt lengths should work.
6931cb0ef41Sopenharmony_ci      for (const saltLength of [undefined, 16, 18, 20]) {
6941cb0ef41Sopenharmony_ci        const signature = crypto.sign('sha256', 'foo', { key, saltLength });
6951cb0ef41Sopenharmony_ci
6961cb0ef41Sopenharmony_ci        for (const pkey of [key, publicKey, publicPem]) {
6971cb0ef41Sopenharmony_ci          const okay = crypto.verify(
6981cb0ef41Sopenharmony_ci            'sha256',
6991cb0ef41Sopenharmony_ci            'foo',
7001cb0ef41Sopenharmony_ci            { key: pkey, saltLength },
7011cb0ef41Sopenharmony_ci            signature
7021cb0ef41Sopenharmony_ci          );
7031cb0ef41Sopenharmony_ci
7041cb0ef41Sopenharmony_ci          assert.ok(okay);
7051cb0ef41Sopenharmony_ci        }
7061cb0ef41Sopenharmony_ci      }
7071cb0ef41Sopenharmony_ci    }
7081cb0ef41Sopenharmony_ci  }
7091cb0ef41Sopenharmony_ci
7101cb0ef41Sopenharmony_ci  {
7111cb0ef41Sopenharmony_ci    // This key enforces sha512 as the message digest and sha256 as the MGF1
7121cb0ef41Sopenharmony_ci    // message digest.
7131cb0ef41Sopenharmony_ci    const publicPem =
7141cb0ef41Sopenharmony_ci      fixtures.readKey('rsa_pss_public_2048_sha512_sha256_20.pem');
7151cb0ef41Sopenharmony_ci    const privatePem =
7161cb0ef41Sopenharmony_ci      fixtures.readKey('rsa_pss_private_2048_sha512_sha256_20.pem');
7171cb0ef41Sopenharmony_ci
7181cb0ef41Sopenharmony_ci    const publicKey = crypto.createPublicKey(publicPem);
7191cb0ef41Sopenharmony_ci    const privateKey = crypto.createPrivateKey(privatePem);
7201cb0ef41Sopenharmony_ci
7211cb0ef41Sopenharmony_ci    // Node.js usually uses the same hash function for the message and for MGF1.
7221cb0ef41Sopenharmony_ci    // However, when a different MGF1 message digest algorithm has been
7231cb0ef41Sopenharmony_ci    // specified as part of the key, it should automatically switch to that.
7241cb0ef41Sopenharmony_ci    // This behavior is required by sections 3.1 and 3.3 of RFC4055.
7251cb0ef41Sopenharmony_ci    for (const key of [privatePem, privateKey]) {
7261cb0ef41Sopenharmony_ci      // sha256 matches the MGF1 hash function and should be used internally,
7271cb0ef41Sopenharmony_ci      // but it should not be permitted as the main message digest algorithm.
7281cb0ef41Sopenharmony_ci      for (const algo of ['sha1', 'sha256']) {
7291cb0ef41Sopenharmony_ci        assert.throws(() => {
7301cb0ef41Sopenharmony_ci          crypto.sign(algo, 'foo', key);
7311cb0ef41Sopenharmony_ci        }, /digest not allowed/);
7321cb0ef41Sopenharmony_ci      }
7331cb0ef41Sopenharmony_ci
7341cb0ef41Sopenharmony_ci      // sha512 should produce a valid signature.
7351cb0ef41Sopenharmony_ci      const signature = crypto.sign('sha512', 'foo', key);
7361cb0ef41Sopenharmony_ci
7371cb0ef41Sopenharmony_ci      for (const pkey of [key, publicKey, publicPem]) {
7381cb0ef41Sopenharmony_ci        const okay = crypto.verify('sha512', 'foo', pkey, signature);
7391cb0ef41Sopenharmony_ci
7401cb0ef41Sopenharmony_ci        assert.ok(okay);
7411cb0ef41Sopenharmony_ci      }
7421cb0ef41Sopenharmony_ci    }
7431cb0ef41Sopenharmony_ci  }
7441cb0ef41Sopenharmony_ci}
7451cb0ef41Sopenharmony_ci
7461cb0ef41Sopenharmony_ci// The sign function should not swallow OpenSSL errors.
7471cb0ef41Sopenharmony_ci// Regression test for https://github.com/nodejs/node/issues/40794.
7481cb0ef41Sopenharmony_ci{
7491cb0ef41Sopenharmony_ci  assert.throws(() => {
7501cb0ef41Sopenharmony_ci    const { privateKey } = crypto.generateKeyPairSync('rsa', {
7511cb0ef41Sopenharmony_ci      modulusLength: 512
7521cb0ef41Sopenharmony_ci    });
7531cb0ef41Sopenharmony_ci    crypto.sign('sha512', 'message', privateKey);
7541cb0ef41Sopenharmony_ci  }, {
7551cb0ef41Sopenharmony_ci    code: 'ERR_OSSL_RSA_DIGEST_TOO_BIG_FOR_RSA_KEY',
7561cb0ef41Sopenharmony_ci    message: /digest too big for rsa key/
7571cb0ef41Sopenharmony_ci  });
7581cb0ef41Sopenharmony_ci}
7591cb0ef41Sopenharmony_ci
7601cb0ef41Sopenharmony_ci{
7611cb0ef41Sopenharmony_ci  // This should not cause a crash: https://github.com/nodejs/node/issues/44471
7621cb0ef41Sopenharmony_ci  for (const key of ['', 'foo', null, undefined, true, Boolean]) {
7631cb0ef41Sopenharmony_ci    assert.throws(() => {
7641cb0ef41Sopenharmony_ci      crypto.verify('sha256', 'foo', { key, format: 'jwk' }, Buffer.alloc(0));
7651cb0ef41Sopenharmony_ci    }, { code: 'ERR_INVALID_ARG_TYPE', message: /The "key\.key" property must be of type object/ });
7661cb0ef41Sopenharmony_ci    assert.throws(() => {
7671cb0ef41Sopenharmony_ci      crypto.createVerify('sha256').verify({ key, format: 'jwk' }, Buffer.alloc(0));
7681cb0ef41Sopenharmony_ci    }, { code: 'ERR_INVALID_ARG_TYPE', message: /The "key\.key" property must be of type object/ });
7691cb0ef41Sopenharmony_ci    assert.throws(() => {
7701cb0ef41Sopenharmony_ci      crypto.sign('sha256', 'foo', { key, format: 'jwk' });
7711cb0ef41Sopenharmony_ci    }, { code: 'ERR_INVALID_ARG_TYPE', message: /The "key\.key" property must be of type object/ });
7721cb0ef41Sopenharmony_ci    assert.throws(() => {
7731cb0ef41Sopenharmony_ci      crypto.createSign('sha256').sign({ key, format: 'jwk' });
7741cb0ef41Sopenharmony_ci    }, { code: 'ERR_INVALID_ARG_TYPE', message: /The "key\.key" property must be of type object/ });
7751cb0ef41Sopenharmony_ci  }
7761cb0ef41Sopenharmony_ci}
777