1'use strict';
2
3const common = require('../common');
4if (!common.hasCrypto)
5  common.skip('missing crypto');
6
7const assert = require('assert');
8const crypto = require('crypto');
9
10{
11  const size = common.hasFipsCrypto || common.hasOpenSSL3 ? 1024 : 256;
12
13  function unlessInvalidState(f) {
14    try {
15      return f();
16    } catch (err) {
17      if (err.code !== 'ERR_CRYPTO_INVALID_STATE') {
18        throw err;
19      }
20    }
21  }
22
23  function testGenerateKeysChangesKeys(setup, expected) {
24    const dh = crypto.createDiffieHellman(size);
25    setup(dh);
26    const firstPublicKey = unlessInvalidState(() => dh.getPublicKey());
27    const firstPrivateKey = unlessInvalidState(() => dh.getPrivateKey());
28    dh.generateKeys();
29    const secondPublicKey = dh.getPublicKey();
30    const secondPrivateKey = dh.getPrivateKey();
31    function changed(shouldChange, first, second) {
32      if (shouldChange) {
33        assert.notDeepStrictEqual(first, second);
34      } else {
35        assert.deepStrictEqual(first, second);
36      }
37    }
38    changed(expected.includes('public'), firstPublicKey, secondPublicKey);
39    changed(expected.includes('private'), firstPrivateKey, secondPrivateKey);
40  }
41
42  // Both the private and the public key are missing: generateKeys() generates both.
43  testGenerateKeysChangesKeys(() => {
44    // No setup.
45  }, ['public', 'private']);
46
47  // Neither key is missing: generateKeys() does nothing.
48  testGenerateKeysChangesKeys((dh) => {
49    dh.generateKeys();
50  }, []);
51
52  // Only the public key is missing: generateKeys() generates only the public key.
53  testGenerateKeysChangesKeys((dh) => {
54    dh.setPrivateKey(Buffer.from('01020304', 'hex'));
55  }, ['public']);
56
57  // The public key is outdated: generateKeys() generates only the public key.
58  testGenerateKeysChangesKeys((dh) => {
59    const oldPublicKey = dh.generateKeys();
60    dh.setPrivateKey(Buffer.from('01020304', 'hex'));
61    assert.deepStrictEqual(dh.getPublicKey(), oldPublicKey);
62  }, ['public']);
63}
64