@@ -114,6 +114,77 @@ using v8::Value;
114
114
115
115
116
116
#if OPENSSL_VERSION_NUMBER < 0x10100000L
117
+ static void RSA_get0_key (const RSA* r, const BIGNUM** n, const BIGNUM** e,
118
+ const BIGNUM** d) {
119
+ if (n != nullptr ) {
120
+ *n = r->n ;
121
+ }
122
+ if (e != nullptr ) {
123
+ *e = r->e ;
124
+ }
125
+ if (d != nullptr ) {
126
+ *d = r->d ;
127
+ }
128
+ }
129
+
130
+ static void DH_get0_pqg (const DH* dh, const BIGNUM** p, const BIGNUM** q,
131
+ const BIGNUM** g) {
132
+ if (p != nullptr ) {
133
+ *p = dh->p ;
134
+ }
135
+ if (q != nullptr ) {
136
+ *q = dh->q ;
137
+ }
138
+ if (g != nullptr ) {
139
+ *g = dh->g ;
140
+ }
141
+ }
142
+
143
+ static int DH_set0_pqg (DH* dh, BIGNUM* p, BIGNUM* q, BIGNUM* g) {
144
+ if ((dh->p == nullptr && p == nullptr ) ||
145
+ (dh->g == nullptr && g == nullptr )) {
146
+ return 0 ;
147
+ }
148
+
149
+ if (p != nullptr ) {
150
+ BN_free (dh->p );
151
+ dh->p = p;
152
+ }
153
+ if (q != nullptr ) {
154
+ BN_free (dh->q );
155
+ dh->q = q;
156
+ }
157
+ if (g != nullptr ) {
158
+ BN_free (dh->g );
159
+ dh->g = g;
160
+ }
161
+
162
+ return 1 ;
163
+ }
164
+
165
+ static void DH_get0_key (const DH* dh, const BIGNUM** pub_key,
166
+ const BIGNUM** priv_key) {
167
+ if (pub_key != nullptr ) {
168
+ *pub_key = dh->pub_key ;
169
+ }
170
+ if (priv_key != nullptr ) {
171
+ *priv_key = dh->priv_key ;
172
+ }
173
+ }
174
+
175
+ static int DH_set0_key (DH* dh, BIGNUM* pub_key, BIGNUM* priv_key) {
176
+ if (pub_key != nullptr ) {
177
+ BN_free (dh->pub_key );
178
+ dh->pub_key = pub_key;
179
+ }
180
+ if (priv_key != nullptr ) {
181
+ BN_free (dh->priv_key );
182
+ dh->priv_key = priv_key;
183
+ }
184
+
185
+ return 1 ;
186
+ }
187
+
117
188
static void SSL_SESSION_get0_ticket (const SSL_SESSION* s,
118
189
const unsigned char ** tick, size_t * len) {
119
190
*len = s->tlsext_ticklen ;
@@ -1015,7 +1086,9 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
1015
1086
if (dh == nullptr )
1016
1087
return ;
1017
1088
1018
- const int size = BN_num_bits (dh->p );
1089
+ const BIGNUM* p;
1090
+ DH_get0_pqg (dh, &p, nullptr , nullptr );
1091
+ const int size = BN_num_bits (p);
1019
1092
if (size < 1024 ) {
1020
1093
return env->ThrowError (" DH parameter is less than 1024 bits" );
1021
1094
} else if (size < 2048 ) {
@@ -1635,14 +1708,17 @@ static Local<Object> X509ToObject(Environment* env, X509* cert) {
1635
1708
rsa = EVP_PKEY_get1_RSA (pkey);
1636
1709
1637
1710
if (rsa != nullptr ) {
1638
- BN_print (bio, rsa->n );
1711
+ const BIGNUM* n;
1712
+ const BIGNUM* e;
1713
+ RSA_get0_key (rsa, &n, &e, nullptr );
1714
+ BN_print (bio, n);
1639
1715
BIO_get_mem_ptr (bio, &mem);
1640
1716
info->Set (env->modulus_string (),
1641
1717
String::NewFromUtf8 (env->isolate (), mem->data ,
1642
1718
String::kNormalString , mem->length ));
1643
1719
(void ) BIO_reset (bio);
1644
1720
1645
- uint64_t exponent_word = static_cast <uint64_t >(BN_get_word (rsa-> e ));
1721
+ uint64_t exponent_word = static_cast <uint64_t >(BN_get_word (e));
1646
1722
uint32_t lo = static_cast <uint32_t >(exponent_word);
1647
1723
uint32_t hi = static_cast <uint32_t >(exponent_word >> 32 );
1648
1724
if (hi == 0 ) {
@@ -4633,10 +4709,15 @@ bool DiffieHellman::Init(int primeLength, int g) {
4633
4709
4634
4710
bool DiffieHellman::Init (const char * p, int p_len, int g) {
4635
4711
dh = DH_new ();
4636
- dh->p = BN_bin2bn (reinterpret_cast <const unsigned char *>(p), p_len, 0 );
4637
- dh->g = BN_new ();
4638
- if (!BN_set_word (dh->g , g))
4712
+ BIGNUM* bn_p =
4713
+ BN_bin2bn (reinterpret_cast <const unsigned char *>(p), p_len, nullptr );
4714
+ BIGNUM* bn_g = BN_new ();
4715
+ if (!BN_set_word (bn_g, g) ||
4716
+ !DH_set0_pqg (dh, bn_p, nullptr , bn_g)) {
4717
+ BN_free (bn_p);
4718
+ BN_free (bn_g);
4639
4719
return false ;
4720
+ }
4640
4721
bool result = VerifyContext ();
4641
4722
if (!result)
4642
4723
return false ;
@@ -4647,8 +4728,13 @@ bool DiffieHellman::Init(const char* p, int p_len, int g) {
4647
4728
4648
4729
bool DiffieHellman::Init (const char * p, int p_len, const char * g, int g_len) {
4649
4730
dh = DH_new ();
4650
- dh->p = BN_bin2bn (reinterpret_cast <const unsigned char *>(p), p_len, 0 );
4651
- dh->g = BN_bin2bn (reinterpret_cast <const unsigned char *>(g), g_len, 0 );
4731
+ BIGNUM *bn_p = BN_bin2bn (reinterpret_cast <const unsigned char *>(p), p_len, 0 );
4732
+ BIGNUM *bn_g = BN_bin2bn (reinterpret_cast <const unsigned char *>(g), g_len, 0 );
4733
+ if (!DH_set0_pqg (dh, bn_p, nullptr , bn_g)) {
4734
+ BN_free (bn_p);
4735
+ BN_free (bn_g);
4736
+ return false ;
4737
+ }
4652
4738
bool result = VerifyContext ();
4653
4739
if (!result)
4654
4740
return false ;
@@ -4736,22 +4822,25 @@ void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
4736
4822
return ThrowCryptoError (env, ERR_get_error (), " Key generation failed" );
4737
4823
}
4738
4824
4739
- size_t size = BN_num_bytes (diffieHellman->dh ->pub_key );
4825
+ const BIGNUM* pub_key;
4826
+ DH_get0_key (diffieHellman->dh , &pub_key, nullptr );
4827
+ size_t size = BN_num_bytes (pub_key);
4740
4828
char * data = Malloc (size);
4741
- BN_bn2bin (diffieHellman-> dh -> pub_key , reinterpret_cast <unsigned char *>(data));
4829
+ BN_bn2bin (pub_key, reinterpret_cast <unsigned char *>(data));
4742
4830
args.GetReturnValue ().Set (Buffer::New (env, data, size).ToLocalChecked ());
4743
4831
}
4744
4832
4745
4833
4746
4834
void DiffieHellman::GetField (const FunctionCallbackInfo<Value>& args,
4747
- BIGNUM* (DH::*field), const char * err_if_null) {
4835
+ const BIGNUM* (*get_field)(const DH*),
4836
+ const char * err_if_null) {
4748
4837
Environment* env = Environment::GetCurrent (args);
4749
4838
4750
4839
DiffieHellman* dh;
4751
4840
ASSIGN_OR_RETURN_UNWRAP (&dh, args.Holder ());
4752
4841
if (!dh->initialised_ ) return env->ThrowError (" Not initialized" );
4753
4842
4754
- const BIGNUM* num = (dh->dh )->*field ;
4843
+ const BIGNUM* num = get_field (dh->dh );
4755
4844
if (num == nullptr ) return env->ThrowError (err_if_null);
4756
4845
4757
4846
size_t size = BN_num_bytes (num);
@@ -4761,24 +4850,38 @@ void DiffieHellman::GetField(const FunctionCallbackInfo<Value>& args,
4761
4850
}
4762
4851
4763
4852
void DiffieHellman::GetPrime (const FunctionCallbackInfo<Value>& args) {
4764
- GetField (args, &DH::p, " p is null" );
4853
+ GetField (args, [](const DH* dh) -> const BIGNUM* {
4854
+ const BIGNUM* p;
4855
+ DH_get0_pqg (dh, &p, nullptr , nullptr );
4856
+ return p;
4857
+ }, " p is null" );
4765
4858
}
4766
4859
4767
4860
4768
4861
void DiffieHellman::GetGenerator (const FunctionCallbackInfo<Value>& args) {
4769
- GetField (args, &DH::g, " g is null" );
4862
+ GetField (args, [](const DH* dh) -> const BIGNUM* {
4863
+ const BIGNUM* g;
4864
+ DH_get0_pqg (dh, nullptr , nullptr , &g);
4865
+ return g;
4866
+ }, " g is null" );
4770
4867
}
4771
4868
4772
4869
4773
4870
void DiffieHellman::GetPublicKey (const FunctionCallbackInfo<Value>& args) {
4774
- GetField (args, &DH::pub_key,
4775
- " No public key - did you forget to generate one?" );
4871
+ GetField (args, [](const DH* dh) -> const BIGNUM* {
4872
+ const BIGNUM* pub_key;
4873
+ DH_get0_key (dh, &pub_key, nullptr );
4874
+ return pub_key;
4875
+ }, " No public key - did you forget to generate one?" );
4776
4876
}
4777
4877
4778
4878
4779
4879
void DiffieHellman::GetPrivateKey (const FunctionCallbackInfo<Value>& args) {
4780
- GetField (args, &DH::priv_key,
4781
- " No private key - did you forget to generate one?" );
4880
+ GetField (args, [](const DH* dh) -> const BIGNUM* {
4881
+ const BIGNUM* priv_key;
4882
+ DH_get0_key (dh, nullptr , &priv_key);
4883
+ return priv_key;
4884
+ }, " No private key - did you forget to generate one?" );
4782
4885
}
4783
4886
4784
4887
@@ -4854,16 +4957,14 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
4854
4957
args.GetReturnValue ().Set (rc);
4855
4958
}
4856
4959
4857
-
4858
4960
void DiffieHellman::SetKey (const v8::FunctionCallbackInfo<v8::Value>& args,
4859
- BIGNUM* (DH::*field ), const char * what) {
4961
+ void (*set_field)(DH*, BIGNUM* ), const char * what) {
4860
4962
Environment* env = Environment::GetCurrent (args);
4861
4963
4862
4964
DiffieHellman* dh;
4863
4965
ASSIGN_OR_RETURN_UNWRAP (&dh, args.Holder ());
4864
4966
if (!dh->initialised_ ) return env->ThrowError (" Not initialized" );
4865
4967
4866
- BIGNUM** num = &((dh->dh )->*field);
4867
4968
char errmsg[64 ];
4868
4969
4869
4970
if (args.Length () == 0 ) {
@@ -4876,19 +4977,28 @@ void DiffieHellman::SetKey(const v8::FunctionCallbackInfo<v8::Value>& args,
4876
4977
return env->ThrowTypeError (errmsg);
4877
4978
}
4878
4979
4879
- *num = BN_bin2bn (reinterpret_cast <unsigned char *>(Buffer::Data (args[0 ])),
4880
- Buffer::Length (args[0 ]), *num);
4881
- CHECK_NE (*num, nullptr );
4980
+ BIGNUM* num =
4981
+ BN_bin2bn (reinterpret_cast <unsigned char *>(Buffer::Data (args[0 ])),
4982
+ Buffer::Length (args[0 ]), nullptr );
4983
+ CHECK_NE (num, nullptr );
4984
+ set_field (dh->dh , num);
4882
4985
}
4883
4986
4884
4987
4885
4988
void DiffieHellman::SetPublicKey (const FunctionCallbackInfo<Value>& args) {
4886
- SetKey (args, &DH::pub_key, " Public key" );
4989
+ SetKey (args, [](DH* dh, BIGNUM* num) { DH_set0_key (dh, num, nullptr ); },
4990
+ " Public key" );
4887
4991
}
4888
4992
4889
-
4890
4993
void DiffieHellman::SetPrivateKey (const FunctionCallbackInfo<Value>& args) {
4891
- SetKey (args, &DH::priv_key, " Private key" );
4994
+ #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
4995
+ OPENSSL_VERSION_NUMBER < 0x10100070L
4996
+ // Older versions of OpenSSL 1.1.0 have a DH_set0_key which does not work for
4997
+ // Node. See https://github.com/openssl/openssl/pull/4384.
4998
+ #error "OpenSSL 1.1.0 revisions before 1.1.0g are not supported"
4999
+ #endif
5000
+ SetKey (args, [](DH* dh, BIGNUM* num) { DH_set0_key (dh, nullptr , num); },
5001
+ " Private key" );
4892
5002
}
4893
5003
4894
5004
0 commit comments