diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc index 38378b730aca66..d9fe8c65514d3c 100644 --- a/deps/ncrypto/ncrypto.cc +++ b/deps/ncrypto/ncrypto.cc @@ -1710,6 +1710,13 @@ DataPointer DHPointer::getPrivateKey() const { return BignumPointer::Encode(pvt_key); } +bool DHPointer::hasPrivateKey() const { + if (!dh_) return false; + const BIGNUM* pvt_key = nullptr; + DH_get0_key(dh_.get(), nullptr, &pvt_key); + return pvt_key != nullptr; +} + DataPointer DHPointer::generateKeys() const { ClearErrorOnReturn clearErrorOnReturn; if (!dh_) return {}; diff --git a/deps/ncrypto/ncrypto.h b/deps/ncrypto/ncrypto.h index b27e2e76c3dcfc..025de840c4ca90 100644 --- a/deps/ncrypto/ncrypto.h +++ b/deps/ncrypto/ncrypto.h @@ -1116,6 +1116,7 @@ class DHPointer final { DataPointer getGenerator() const; DataPointer getPublicKey() const; DataPointer getPrivateKey() const; + bool hasPrivateKey() const; DataPointer generateKeys() const; DataPointer computeSecret(const BignumPointer& peer) const; diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc index fa8f36fa33c08f..c99cf2fb23619a 100644 --- a/src/crypto/crypto_dh.cc +++ b/src/crypto/crypto_dh.cc @@ -324,6 +324,11 @@ void ComputeSecret(const FunctionCallbackInfo& args) { break; } + if (!dh.hasPrivateKey()) { + return THROW_ERR_CRYPTO_INVALID_STATE( + env, "Cannot compute shared secret without a private key"); + } + auto dp = dh.computeSecret(key); Local buffer; diff --git a/test/parallel/test-crypto-dh-errors.js b/test/parallel/test-crypto-dh-errors.js index d7527d82617efc..3ff9b746e020b0 100644 --- a/test/parallel/test-crypto-dh-errors.js +++ b/test/parallel/test-crypto-dh-errors.js @@ -100,6 +100,28 @@ assert.throws( 'failed to throw the expected error.' ); +{ + const group = crypto.getDiffieHellman('modp14'); + const alice = crypto.createDiffieHellman( + group.getPrime(), group.getGenerator()); + const bob = crypto.createDiffieHellman( + group.getPrime(), group.getGenerator()); + bob.generateKeys(); + + assert.throws( + () => alice.computeSecret(bob.getPublicKey()), + { + name: 'Error', + code: 'ERR_CRYPTO_INVALID_STATE', + message: 'Cannot compute shared secret without a private key' + }); + + alice.generateKeys(); + assert.deepStrictEqual( + alice.computeSecret(bob.getPublicKey()), + bob.computeSecret(alice.getPublicKey())); +} + assert.throws( () => crypto.createDiffieHellman('', true), {