@@ -115,6 +115,77 @@ using v8::Value;
115
115
116
116
117
117
#if OPENSSL_VERSION_NUMBER < 0x10100000L
118
+ static void RSA_get0_key (const RSA* r, const BIGNUM** n, const BIGNUM** e,
119
+ const BIGNUM** d) {
120
+ if (n != nullptr ) {
121
+ *n = r->n ;
122
+ }
123
+ if (e != nullptr ) {
124
+ *e = r->e ;
125
+ }
126
+ if (d != nullptr ) {
127
+ *d = r->d ;
128
+ }
129
+ }
130
+
131
+ static void DH_get0_pqg (const DH* dh, const BIGNUM** p, const BIGNUM** q,
132
+ const BIGNUM** g) {
133
+ if (p != nullptr ) {
134
+ *p = dh->p ;
135
+ }
136
+ if (q != nullptr ) {
137
+ *q = dh->q ;
138
+ }
139
+ if (g != nullptr ) {
140
+ *g = dh->g ;
141
+ }
142
+ }
143
+
144
+ static int DH_set0_pqg (DH* dh, BIGNUM* p, BIGNUM* q, BIGNUM* g) {
145
+ if ((dh->p == nullptr && p == nullptr ) ||
146
+ (dh->g == nullptr && g == nullptr )) {
147
+ return 0 ;
148
+ }
149
+
150
+ if (p != nullptr ) {
151
+ BN_free (dh->p );
152
+ dh->p = p;
153
+ }
154
+ if (q != nullptr ) {
155
+ BN_free (dh->q );
156
+ dh->q = q;
157
+ }
158
+ if (g != nullptr ) {
159
+ BN_free (dh->g );
160
+ dh->g = g;
161
+ }
162
+
163
+ return 1 ;
164
+ }
165
+
166
+ static void DH_get0_key (const DH* dh, const BIGNUM** pub_key,
167
+ const BIGNUM** priv_key) {
168
+ if (pub_key != nullptr ) {
169
+ *pub_key = dh->pub_key ;
170
+ }
171
+ if (priv_key != nullptr ) {
172
+ *priv_key = dh->priv_key ;
173
+ }
174
+ }
175
+
176
+ static int DH_set0_key (DH* dh, BIGNUM* pub_key, BIGNUM* priv_key) {
177
+ if (pub_key != nullptr ) {
178
+ BN_free (dh->pub_key );
179
+ dh->pub_key = pub_key;
180
+ }
181
+ if (priv_key != nullptr ) {
182
+ BN_free (dh->priv_key );
183
+ dh->priv_key = priv_key;
184
+ }
185
+
186
+ return 1 ;
187
+ }
188
+
118
189
static void SSL_SESSION_get0_ticket (const SSL_SESSION* s,
119
190
const unsigned char ** tick, size_t * len) {
120
191
*len = s->tlsext_ticklen ;
@@ -1011,7 +1082,9 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
1011
1082
if (dh == nullptr )
1012
1083
return ;
1013
1084
1014
- const int size = BN_num_bits (dh->p );
1085
+ const BIGNUM* p;
1086
+ DH_get0_pqg (dh, &p, nullptr , nullptr );
1087
+ const int size = BN_num_bits (p);
1015
1088
if (size < 1024 ) {
1016
1089
return env->ThrowError (" DH parameter is less than 1024 bits" );
1017
1090
} else if (size < 2048 ) {
@@ -1631,14 +1704,17 @@ static Local<Object> X509ToObject(Environment* env, X509* cert) {
1631
1704
rsa = EVP_PKEY_get1_RSA (pkey);
1632
1705
1633
1706
if (rsa != nullptr ) {
1634
- BN_print (bio, rsa->n );
1707
+ const BIGNUM* n;
1708
+ const BIGNUM* e;
1709
+ RSA_get0_key (rsa, &n, &e, nullptr );
1710
+ BN_print (bio, n);
1635
1711
BIO_get_mem_ptr (bio, &mem);
1636
1712
info->Set (env->modulus_string (),
1637
1713
String::NewFromUtf8 (env->isolate (), mem->data ,
1638
1714
String::kNormalString , mem->length ));
1639
1715
(void ) BIO_reset (bio);
1640
1716
1641
- uint64_t exponent_word = static_cast <uint64_t >(BN_get_word (rsa-> e ));
1717
+ uint64_t exponent_word = static_cast <uint64_t >(BN_get_word (e));
1642
1718
uint32_t lo = static_cast <uint32_t >(exponent_word);
1643
1719
uint32_t hi = static_cast <uint32_t >(exponent_word >> 32 );
1644
1720
if (hi == 0 ) {
@@ -4719,10 +4795,15 @@ bool DiffieHellman::Init(int primeLength, int g) {
4719
4795
4720
4796
bool DiffieHellman::Init (const char * p, int p_len, int g) {
4721
4797
dh = DH_new ();
4722
- dh->p = BN_bin2bn (reinterpret_cast <const unsigned char *>(p), p_len, 0 );
4723
- dh->g = BN_new ();
4724
- if (!BN_set_word (dh->g , g))
4798
+ BIGNUM* bn_p =
4799
+ BN_bin2bn (reinterpret_cast <const unsigned char *>(p), p_len, nullptr );
4800
+ BIGNUM* bn_g = BN_new ();
4801
+ if (!BN_set_word (bn_g, g) ||
4802
+ !DH_set0_pqg (dh, bn_p, nullptr , bn_g)) {
4803
+ BN_free (bn_p);
4804
+ BN_free (bn_g);
4725
4805
return false ;
4806
+ }
4726
4807
bool result = VerifyContext ();
4727
4808
if (!result)
4728
4809
return false ;
@@ -4733,8 +4814,13 @@ bool DiffieHellman::Init(const char* p, int p_len, int g) {
4733
4814
4734
4815
bool DiffieHellman::Init (const char * p, int p_len, const char * g, int g_len) {
4735
4816
dh = DH_new ();
4736
- dh->p = BN_bin2bn (reinterpret_cast <const unsigned char *>(p), p_len, 0 );
4737
- dh->g = BN_bin2bn (reinterpret_cast <const unsigned char *>(g), g_len, 0 );
4817
+ BIGNUM *bn_p = BN_bin2bn (reinterpret_cast <const unsigned char *>(p), p_len, 0 );
4818
+ BIGNUM *bn_g = BN_bin2bn (reinterpret_cast <const unsigned char *>(g), g_len, 0 );
4819
+ if (!DH_set0_pqg (dh, bn_p, nullptr , bn_g)) {
4820
+ BN_free (bn_p);
4821
+ BN_free (bn_g);
4822
+ return false ;
4823
+ }
4738
4824
bool result = VerifyContext ();
4739
4825
if (!result)
4740
4826
return false ;
@@ -4822,22 +4908,25 @@ void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
4822
4908
return ThrowCryptoError (env, ERR_get_error (), " Key generation failed" );
4823
4909
}
4824
4910
4825
- size_t size = BN_num_bytes (diffieHellman->dh ->pub_key );
4911
+ const BIGNUM* pub_key;
4912
+ DH_get0_key (diffieHellman->dh , &pub_key, nullptr );
4913
+ size_t size = BN_num_bytes (pub_key);
4826
4914
char * data = Malloc (size);
4827
- BN_bn2bin (diffieHellman-> dh -> pub_key , reinterpret_cast <unsigned char *>(data));
4915
+ BN_bn2bin (pub_key, reinterpret_cast <unsigned char *>(data));
4828
4916
args.GetReturnValue ().Set (Buffer::New (env, data, size).ToLocalChecked ());
4829
4917
}
4830
4918
4831
4919
4832
4920
void DiffieHellman::GetField (const FunctionCallbackInfo<Value>& args,
4833
- BIGNUM* (DH::*field), const char * err_if_null) {
4921
+ const BIGNUM* (*get_field)(const DH*),
4922
+ const char * err_if_null) {
4834
4923
Environment* env = Environment::GetCurrent (args);
4835
4924
4836
4925
DiffieHellman* dh;
4837
4926
ASSIGN_OR_RETURN_UNWRAP (&dh, args.Holder ());
4838
4927
if (!dh->initialised_ ) return env->ThrowError (" Not initialized" );
4839
4928
4840
- const BIGNUM* num = (dh->dh )->*field ;
4929
+ const BIGNUM* num = get_field (dh->dh );
4841
4930
if (num == nullptr ) return env->ThrowError (err_if_null);
4842
4931
4843
4932
size_t size = BN_num_bytes (num);
@@ -4847,24 +4936,38 @@ void DiffieHellman::GetField(const FunctionCallbackInfo<Value>& args,
4847
4936
}
4848
4937
4849
4938
void DiffieHellman::GetPrime (const FunctionCallbackInfo<Value>& args) {
4850
- GetField (args, &DH::p, " p is null" );
4939
+ GetField (args, [](const DH* dh) -> const BIGNUM* {
4940
+ const BIGNUM* p;
4941
+ DH_get0_pqg (dh, &p, nullptr , nullptr );
4942
+ return p;
4943
+ }, " p is null" );
4851
4944
}
4852
4945
4853
4946
4854
4947
void DiffieHellman::GetGenerator (const FunctionCallbackInfo<Value>& args) {
4855
- GetField (args, &DH::g, " g is null" );
4948
+ GetField (args, [](const DH* dh) -> const BIGNUM* {
4949
+ const BIGNUM* g;
4950
+ DH_get0_pqg (dh, nullptr , nullptr , &g);
4951
+ return g;
4952
+ }, " g is null" );
4856
4953
}
4857
4954
4858
4955
4859
4956
void DiffieHellman::GetPublicKey (const FunctionCallbackInfo<Value>& args) {
4860
- GetField (args, &DH::pub_key,
4861
- " No public key - did you forget to generate one?" );
4957
+ GetField (args, [](const DH* dh) -> const BIGNUM* {
4958
+ const BIGNUM* pub_key;
4959
+ DH_get0_key (dh, &pub_key, nullptr );
4960
+ return pub_key;
4961
+ }, " No public key - did you forget to generate one?" );
4862
4962
}
4863
4963
4864
4964
4865
4965
void DiffieHellman::GetPrivateKey (const FunctionCallbackInfo<Value>& args) {
4866
- GetField (args, &DH::priv_key,
4867
- " No private key - did you forget to generate one?" );
4966
+ GetField (args, [](const DH* dh) -> const BIGNUM* {
4967
+ const BIGNUM* priv_key;
4968
+ DH_get0_key (dh, nullptr , &priv_key);
4969
+ return priv_key;
4970
+ }, " No private key - did you forget to generate one?" );
4868
4971
}
4869
4972
4870
4973
@@ -4940,16 +5043,14 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
4940
5043
args.GetReturnValue ().Set (rc);
4941
5044
}
4942
5045
4943
-
4944
5046
void DiffieHellman::SetKey (const v8::FunctionCallbackInfo<v8::Value>& args,
4945
- BIGNUM* (DH::*field ), const char * what) {
5047
+ void (*set_field)(DH*, BIGNUM* ), const char * what) {
4946
5048
Environment* env = Environment::GetCurrent (args);
4947
5049
4948
5050
DiffieHellman* dh;
4949
5051
ASSIGN_OR_RETURN_UNWRAP (&dh, args.Holder ());
4950
5052
if (!dh->initialised_ ) return env->ThrowError (" Not initialized" );
4951
5053
4952
- BIGNUM** num = &((dh->dh )->*field);
4953
5054
char errmsg[64 ];
4954
5055
4955
5056
if (args.Length () == 0 ) {
@@ -4962,19 +5063,28 @@ void DiffieHellman::SetKey(const v8::FunctionCallbackInfo<v8::Value>& args,
4962
5063
return env->ThrowTypeError (errmsg);
4963
5064
}
4964
5065
4965
- *num = BN_bin2bn (reinterpret_cast <unsigned char *>(Buffer::Data (args[0 ])),
4966
- Buffer::Length (args[0 ]), *num);
4967
- CHECK_NE (*num, nullptr );
5066
+ BIGNUM* num =
5067
+ BN_bin2bn (reinterpret_cast <unsigned char *>(Buffer::Data (args[0 ])),
5068
+ Buffer::Length (args[0 ]), nullptr );
5069
+ CHECK_NE (num, nullptr );
5070
+ set_field (dh->dh , num);
4968
5071
}
4969
5072
4970
5073
4971
5074
void DiffieHellman::SetPublicKey (const FunctionCallbackInfo<Value>& args) {
4972
- SetKey (args, &DH::pub_key, " Public key" );
5075
+ SetKey (args, [](DH* dh, BIGNUM* num) { DH_set0_key (dh, num, nullptr ); },
5076
+ " Public key" );
4973
5077
}
4974
5078
4975
-
4976
5079
void DiffieHellman::SetPrivateKey (const FunctionCallbackInfo<Value>& args) {
4977
- SetKey (args, &DH::priv_key, " Private key" );
5080
+ #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
5081
+ OPENSSL_VERSION_NUMBER < 0x10100070L
5082
+ // Older versions of OpenSSL 1.1.0 have a DH_set0_key which does not work for
5083
+ // Node. See https://github.com/openssl/openssl/pull/4384.
5084
+ #error "OpenSSL 1.1.0 revisions before 1.1.0g are not supported"
5085
+ #endif
5086
+ SetKey (args, [](DH* dh, BIGNUM* num) { DH_set0_key (dh, nullptr , num); },
5087
+ " Private key" );
4978
5088
}
4979
5089
4980
5090
0 commit comments