Skip to content

Commit 63907e1

Browse files
authored
crypto: throw on uninitialized DH computeSecret
Reject DiffieHellman computeSecret() when the instance does not have private key material instead of returning an empty buffer. Fixes: #63674 Signed-off-by: Filip Skokan <panva.ip@gmail.com> PR-URL: #63922 Fixes: #63674 Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent ef42d32 commit 63907e1

4 files changed

Lines changed: 35 additions & 0 deletions

File tree

‎deps/ncrypto/ncrypto.cc‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1710,6 +1710,13 @@ DataPointer DHPointer::getPrivateKey() const {
17101710
return BignumPointer::Encode(pvt_key);
17111711
}
17121712

1713+
bool DHPointer::hasPrivateKey() const {
1714+
if (!dh_) return false;
1715+
const BIGNUM* pvt_key = nullptr;
1716+
DH_get0_key(dh_.get(), nullptr, &pvt_key);
1717+
return pvt_key != nullptr;
1718+
}
1719+
17131720
DataPointer DHPointer::generateKeys() const {
17141721
ClearErrorOnReturn clearErrorOnReturn;
17151722
if (!dh_) return {};

‎deps/ncrypto/ncrypto.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,7 @@ class DHPointer final {
11161116
DataPointer getGenerator() const;
11171117
DataPointer getPublicKey() const;
11181118
DataPointer getPrivateKey() const;
1119+
bool hasPrivateKey() const;
11191120
DataPointer generateKeys() const;
11201121
DataPointer computeSecret(const BignumPointer& peer) const;
11211122

‎src/crypto/crypto_dh.cc‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,11 @@ void ComputeSecret(const FunctionCallbackInfo<Value>& args) {
324324
break;
325325
}
326326

327+
if (!dh.hasPrivateKey()) {
328+
return THROW_ERR_CRYPTO_INVALID_STATE(
329+
env, "Cannot compute shared secret without a private key");
330+
}
331+
327332
auto dp = dh.computeSecret(key);
328333

329334
Local<Value> buffer;

‎test/parallel/test-crypto-dh-errors.js‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,28 @@ assert.throws(
100100
'failed to throw the expected error.'
101101
);
102102

103+
{
104+
const group = crypto.getDiffieHellman('modp14');
105+
const alice = crypto.createDiffieHellman(
106+
group.getPrime(), group.getGenerator());
107+
const bob = crypto.createDiffieHellman(
108+
group.getPrime(), group.getGenerator());
109+
bob.generateKeys();
110+
111+
assert.throws(
112+
() => alice.computeSecret(bob.getPublicKey()),
113+
{
114+
name: 'Error',
115+
code: 'ERR_CRYPTO_INVALID_STATE',
116+
message: 'Cannot compute shared secret without a private key'
117+
});
118+
119+
alice.generateKeys();
120+
assert.deepStrictEqual(
121+
alice.computeSecret(bob.getPublicKey()),
122+
bob.computeSecret(alice.getPublicKey()));
123+
}
124+
103125
assert.throws(
104126
() => crypto.createDiffieHellman('', true),
105127
{

0 commit comments

Comments
 (0)