11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
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_ci{
111cb0ef41Sopenharmony_ci  const size = common.hasFipsCrypto || common.hasOpenSSL3 ? 1024 : 256;
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ci  function unlessInvalidState(f) {
141cb0ef41Sopenharmony_ci    try {
151cb0ef41Sopenharmony_ci      return f();
161cb0ef41Sopenharmony_ci    } catch (err) {
171cb0ef41Sopenharmony_ci      if (err.code !== 'ERR_CRYPTO_INVALID_STATE') {
181cb0ef41Sopenharmony_ci        throw err;
191cb0ef41Sopenharmony_ci      }
201cb0ef41Sopenharmony_ci    }
211cb0ef41Sopenharmony_ci  }
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ci  function testGenerateKeysChangesKeys(setup, expected) {
241cb0ef41Sopenharmony_ci    const dh = crypto.createDiffieHellman(size);
251cb0ef41Sopenharmony_ci    setup(dh);
261cb0ef41Sopenharmony_ci    const firstPublicKey = unlessInvalidState(() => dh.getPublicKey());
271cb0ef41Sopenharmony_ci    const firstPrivateKey = unlessInvalidState(() => dh.getPrivateKey());
281cb0ef41Sopenharmony_ci    dh.generateKeys();
291cb0ef41Sopenharmony_ci    const secondPublicKey = dh.getPublicKey();
301cb0ef41Sopenharmony_ci    const secondPrivateKey = dh.getPrivateKey();
311cb0ef41Sopenharmony_ci    function changed(shouldChange, first, second) {
321cb0ef41Sopenharmony_ci      if (shouldChange) {
331cb0ef41Sopenharmony_ci        assert.notDeepStrictEqual(first, second);
341cb0ef41Sopenharmony_ci      } else {
351cb0ef41Sopenharmony_ci        assert.deepStrictEqual(first, second);
361cb0ef41Sopenharmony_ci      }
371cb0ef41Sopenharmony_ci    }
381cb0ef41Sopenharmony_ci    changed(expected.includes('public'), firstPublicKey, secondPublicKey);
391cb0ef41Sopenharmony_ci    changed(expected.includes('private'), firstPrivateKey, secondPrivateKey);
401cb0ef41Sopenharmony_ci  }
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci  // Both the private and the public key are missing: generateKeys() generates both.
431cb0ef41Sopenharmony_ci  testGenerateKeysChangesKeys(() => {
441cb0ef41Sopenharmony_ci    // No setup.
451cb0ef41Sopenharmony_ci  }, ['public', 'private']);
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci  // Neither key is missing: generateKeys() does nothing.
481cb0ef41Sopenharmony_ci  testGenerateKeysChangesKeys((dh) => {
491cb0ef41Sopenharmony_ci    dh.generateKeys();
501cb0ef41Sopenharmony_ci  }, []);
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci  // Only the public key is missing: generateKeys() generates only the public key.
531cb0ef41Sopenharmony_ci  testGenerateKeysChangesKeys((dh) => {
541cb0ef41Sopenharmony_ci    dh.setPrivateKey(Buffer.from('01020304', 'hex'));
551cb0ef41Sopenharmony_ci  }, ['public']);
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci  // The public key is outdated: generateKeys() generates only the public key.
581cb0ef41Sopenharmony_ci  testGenerateKeysChangesKeys((dh) => {
591cb0ef41Sopenharmony_ci    const oldPublicKey = dh.generateKeys();
601cb0ef41Sopenharmony_ci    dh.setPrivateKey(Buffer.from('01020304', 'hex'));
611cb0ef41Sopenharmony_ci    assert.deepStrictEqual(dh.getPublicKey(), oldPublicKey);
621cb0ef41Sopenharmony_ci  }, ['public']);
631cb0ef41Sopenharmony_ci}
64