Skip to content

Commit ff70ecb

Browse files
bnoordhuistargos
authored andcommitted
crypto: check DiffieHellman p and g params
It's possible to pass in the prime and generator params as buffers but that mode of input wasn't as rigorously checked as numeric input. PR-URL: #32739 Fixes: #32738 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Zeyu Yang <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 22c08cd commit ff70ecb

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

src/node_crypto.cc

+23-2
Original file line numberDiff line numberDiff line change
@@ -5164,6 +5164,14 @@ bool DiffieHellman::Init(int primeLength, int g) {
51645164

51655165
bool DiffieHellman::Init(const char* p, int p_len, int g) {
51665166
dh_.reset(DH_new());
5167+
if (p_len <= 0) {
5168+
BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL);
5169+
return false;
5170+
}
5171+
if (g <= 1) {
5172+
DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
5173+
return false;
5174+
}
51675175
BIGNUM* bn_p =
51685176
BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, nullptr);
51695177
BIGNUM* bn_g = BN_new();
@@ -5179,10 +5187,23 @@ bool DiffieHellman::Init(const char* p, int p_len, int g) {
51795187

51805188
bool DiffieHellman::Init(const char* p, int p_len, const char* g, int g_len) {
51815189
dh_.reset(DH_new());
5182-
BIGNUM* bn_p =
5183-
BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, nullptr);
5190+
if (p_len <= 0) {
5191+
BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL);
5192+
return false;
5193+
}
5194+
if (g_len <= 0) {
5195+
DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
5196+
return false;
5197+
}
51845198
BIGNUM* bn_g =
51855199
BN_bin2bn(reinterpret_cast<const unsigned char*>(g), g_len, nullptr);
5200+
if (BN_is_zero(bn_g) || BN_is_one(bn_g)) {
5201+
BN_free(bn_g);
5202+
DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
5203+
return false;
5204+
}
5205+
BIGNUM* bn_p =
5206+
BN_bin2bn(reinterpret_cast<const unsigned char*>(p), p_len, nullptr);
51865207
if (!DH_set0_pqg(dh_.get(), bn_p, nullptr, bn_g)) {
51875208
BN_free(bn_p);
51885209
BN_free(bn_g);

test/parallel/test-crypto-dh.js

+31
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,37 @@ for (const bits of [-1, 0, 1]) {
4545
});
4646
}
4747

48+
// Through a fluke of history, g=0 defaults to DH_GENERATOR (2).
49+
{
50+
const g = 0;
51+
crypto.createDiffieHellman('abcdef', g);
52+
crypto.createDiffieHellman('abcdef', 'hex', g);
53+
}
54+
55+
for (const g of [-1, 1]) {
56+
const ex = {
57+
code: 'ERR_OSSL_DH_BAD_GENERATOR',
58+
name: 'Error',
59+
message: /bad generator/,
60+
};
61+
assert.throws(() => crypto.createDiffieHellman('abcdef', g), ex);
62+
assert.throws(() => crypto.createDiffieHellman('abcdef', 'hex', g), ex);
63+
}
64+
65+
crypto.createDiffieHellman('abcdef', Buffer.from([2])); // OK
66+
67+
for (const g of [Buffer.from([]),
68+
Buffer.from([0]),
69+
Buffer.from([1])]) {
70+
const ex = {
71+
code: 'ERR_OSSL_DH_BAD_GENERATOR',
72+
name: 'Error',
73+
message: /bad generator/,
74+
};
75+
assert.throws(() => crypto.createDiffieHellman('abcdef', g), ex);
76+
assert.throws(() => crypto.createDiffieHellman('abcdef', 'hex', g), ex);
77+
}
78+
4879
{
4980
const DiffieHellman = crypto.DiffieHellman;
5081
const dh = DiffieHellman(p1, 'buffer');

0 commit comments

Comments
 (0)