@@ -107,6 +107,77 @@ using v8::Value;
107
107
108
108
109
109
#if OPENSSL_VERSION_NUMBER < 0x10100000L
110
+ static void RSA_get0_key (const RSA* r, const BIGNUM** n, const BIGNUM** e,
111
+ const BIGNUM** d) {
112
+ if (n != nullptr ) {
113
+ *n = r->n ;
114
+ }
115
+ if (e != nullptr ) {
116
+ *e = r->e ;
117
+ }
118
+ if (d != nullptr ) {
119
+ *d = r->d ;
120
+ }
121
+ }
122
+
123
+ static void DH_get0_pqg (const DH* dh, const BIGNUM** p, const BIGNUM** q,
124
+ const BIGNUM** g) {
125
+ if (p != nullptr ) {
126
+ *p = dh->p ;
127
+ }
128
+ if (q != nullptr ) {
129
+ *q = dh->q ;
130
+ }
131
+ if (g != nullptr ) {
132
+ *g = dh->g ;
133
+ }
134
+ }
135
+
136
+ static int DH_set0_pqg (DH* dh, BIGNUM* p, BIGNUM* q, BIGNUM* g) {
137
+ if ((dh->p == nullptr && p == nullptr ) ||
138
+ (dh->g == nullptr && g == nullptr )) {
139
+ return 0 ;
140
+ }
141
+
142
+ if (p != nullptr ) {
143
+ BN_free (dh->p );
144
+ dh->p = p;
145
+ }
146
+ if (q != nullptr ) {
147
+ BN_free (dh->q );
148
+ dh->q = q;
149
+ }
150
+ if (g != nullptr ) {
151
+ BN_free (dh->g );
152
+ dh->g = g;
153
+ }
154
+
155
+ return 1 ;
156
+ }
157
+
158
+ static void DH_get0_key (const DH* dh, const BIGNUM** pub_key,
159
+ const BIGNUM** priv_key) {
160
+ if (pub_key != nullptr ) {
161
+ *pub_key = dh->pub_key ;
162
+ }
163
+ if (priv_key != nullptr ) {
164
+ *priv_key = dh->priv_key ;
165
+ }
166
+ }
167
+
168
+ static int DH_set0_key (DH* dh, BIGNUM* pub_key, BIGNUM* priv_key) {
169
+ if (pub_key != nullptr ) {
170
+ BN_free (dh->pub_key );
171
+ dh->pub_key = pub_key;
172
+ }
173
+ if (priv_key != nullptr ) {
174
+ BN_free (dh->priv_key );
175
+ dh->priv_key = priv_key;
176
+ }
177
+
178
+ return 1 ;
179
+ }
180
+
110
181
static void SSL_SESSION_get0_ticket (const SSL_SESSION* s,
111
182
const unsigned char ** tick, size_t * len) {
112
183
*len = s->tlsext_ticklen ;
@@ -1008,7 +1079,9 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
1008
1079
if (dh == nullptr )
1009
1080
return ;
1010
1081
1011
- const int size = BN_num_bits (dh->p );
1082
+ const BIGNUM* p;
1083
+ DH_get0_pqg (dh, &p, nullptr , nullptr );
1084
+ const int size = BN_num_bits (p);
1012
1085
if (size < 1024 ) {
1013
1086
return env->ThrowError (" DH parameter is less than 1024 bits" );
1014
1087
} else if (size < 2048 ) {
@@ -1628,14 +1701,17 @@ static Local<Object> X509ToObject(Environment* env, X509* cert) {
1628
1701
rsa = EVP_PKEY_get1_RSA (pkey);
1629
1702
1630
1703
if (rsa != nullptr ) {
1631
- BN_print (bio, rsa->n );
1704
+ const BIGNUM* n;
1705
+ const BIGNUM* e;
1706
+ RSA_get0_key (rsa, &n, &e, nullptr );
1707
+ BN_print (bio, n);
1632
1708
BIO_get_mem_ptr (bio, &mem);
1633
1709
info->Set (env->modulus_string (),
1634
1710
String::NewFromUtf8 (env->isolate (), mem->data ,
1635
1711
String::kNormalString , mem->length ));
1636
1712
(void ) BIO_reset (bio);
1637
1713
1638
- uint64_t exponent_word = static_cast <uint64_t >(BN_get_word (rsa-> e ));
1714
+ uint64_t exponent_word = static_cast <uint64_t >(BN_get_word (e));
1639
1715
uint32_t lo = static_cast <uint32_t >(exponent_word);
1640
1716
uint32_t hi = static_cast <uint32_t >(exponent_word >> 32 );
1641
1717
if (hi == 0 ) {
@@ -4602,10 +4678,15 @@ bool DiffieHellman::Init(int primeLength, int g) {
4602
4678
4603
4679
bool DiffieHellman::Init (const char * p, int p_len, int g) {
4604
4680
dh = DH_new ();
4605
- dh->p = BN_bin2bn (reinterpret_cast <const unsigned char *>(p), p_len, 0 );
4606
- dh->g = BN_new ();
4607
- if (!BN_set_word (dh->g , g))
4681
+ BIGNUM* bn_p =
4682
+ BN_bin2bn (reinterpret_cast <const unsigned char *>(p), p_len, nullptr );
4683
+ BIGNUM* bn_g = BN_new ();
4684
+ if (!BN_set_word (bn_g, g) ||
4685
+ !DH_set0_pqg (dh, bn_p, nullptr , bn_g)) {
4686
+ BN_free (bn_p);
4687
+ BN_free (bn_g);
4608
4688
return false ;
4689
+ }
4609
4690
bool result = VerifyContext ();
4610
4691
if (!result)
4611
4692
return false ;
@@ -4616,8 +4697,13 @@ bool DiffieHellman::Init(const char* p, int p_len, int g) {
4616
4697
4617
4698
bool DiffieHellman::Init (const char * p, int p_len, const char * g, int g_len) {
4618
4699
dh = DH_new ();
4619
- dh->p = BN_bin2bn (reinterpret_cast <const unsigned char *>(p), p_len, 0 );
4620
- dh->g = BN_bin2bn (reinterpret_cast <const unsigned char *>(g), g_len, 0 );
4700
+ BIGNUM *bn_p = BN_bin2bn (reinterpret_cast <const unsigned char *>(p), p_len, 0 );
4701
+ BIGNUM *bn_g = BN_bin2bn (reinterpret_cast <const unsigned char *>(g), g_len, 0 );
4702
+ if (!DH_set0_pqg (dh, bn_p, nullptr , bn_g)) {
4703
+ BN_free (bn_p);
4704
+ BN_free (bn_g);
4705
+ return false ;
4706
+ }
4621
4707
bool result = VerifyContext ();
4622
4708
if (!result)
4623
4709
return false ;
@@ -4705,22 +4791,25 @@ void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
4705
4791
return ThrowCryptoError (env, ERR_get_error (), " Key generation failed" );
4706
4792
}
4707
4793
4708
- size_t size = BN_num_bytes (diffieHellman->dh ->pub_key );
4794
+ const BIGNUM* pub_key;
4795
+ DH_get0_key (diffieHellman->dh , &pub_key, nullptr );
4796
+ size_t size = BN_num_bytes (pub_key);
4709
4797
char * data = Malloc (size);
4710
- BN_bn2bin (diffieHellman-> dh -> pub_key , reinterpret_cast <unsigned char *>(data));
4798
+ BN_bn2bin (pub_key, reinterpret_cast <unsigned char *>(data));
4711
4799
args.GetReturnValue ().Set (Buffer::New (env, data, size).ToLocalChecked ());
4712
4800
}
4713
4801
4714
4802
4715
4803
void DiffieHellman::GetField (const FunctionCallbackInfo<Value>& args,
4716
- BIGNUM* (DH::*field), const char * err_if_null) {
4804
+ const BIGNUM* (*get_field)(const DH*),
4805
+ const char * err_if_null) {
4717
4806
Environment* env = Environment::GetCurrent (args);
4718
4807
4719
4808
DiffieHellman* dh;
4720
4809
ASSIGN_OR_RETURN_UNWRAP (&dh, args.Holder ());
4721
4810
if (!dh->initialised_ ) return env->ThrowError (" Not initialized" );
4722
4811
4723
- const BIGNUM* num = (dh->dh )->*field ;
4812
+ const BIGNUM* num = get_field (dh->dh );
4724
4813
if (num == nullptr ) return env->ThrowError (err_if_null);
4725
4814
4726
4815
size_t size = BN_num_bytes (num);
@@ -4730,24 +4819,38 @@ void DiffieHellman::GetField(const FunctionCallbackInfo<Value>& args,
4730
4819
}
4731
4820
4732
4821
void DiffieHellman::GetPrime (const FunctionCallbackInfo<Value>& args) {
4733
- GetField (args, &DH::p, " p is null" );
4822
+ GetField (args, [](const DH* dh) -> const BIGNUM* {
4823
+ const BIGNUM* p;
4824
+ DH_get0_pqg (dh, &p, nullptr , nullptr );
4825
+ return p;
4826
+ }, " p is null" );
4734
4827
}
4735
4828
4736
4829
4737
4830
void DiffieHellman::GetGenerator (const FunctionCallbackInfo<Value>& args) {
4738
- GetField (args, &DH::g, " g is null" );
4831
+ GetField (args, [](const DH* dh) -> const BIGNUM* {
4832
+ const BIGNUM* g;
4833
+ DH_get0_pqg (dh, nullptr , nullptr , &g);
4834
+ return g;
4835
+ }, " g is null" );
4739
4836
}
4740
4837
4741
4838
4742
4839
void DiffieHellman::GetPublicKey (const FunctionCallbackInfo<Value>& args) {
4743
- GetField (args, &DH::pub_key,
4744
- " No public key - did you forget to generate one?" );
4840
+ GetField (args, [](const DH* dh) -> const BIGNUM* {
4841
+ const BIGNUM* pub_key;
4842
+ DH_get0_key (dh, &pub_key, nullptr );
4843
+ return pub_key;
4844
+ }, " No public key - did you forget to generate one?" );
4745
4845
}
4746
4846
4747
4847
4748
4848
void DiffieHellman::GetPrivateKey (const FunctionCallbackInfo<Value>& args) {
4749
- GetField (args, &DH::priv_key,
4750
- " No private key - did you forget to generate one?" );
4849
+ GetField (args, [](const DH* dh) -> const BIGNUM* {
4850
+ const BIGNUM* priv_key;
4851
+ DH_get0_key (dh, nullptr , &priv_key);
4852
+ return priv_key;
4853
+ }, " No private key - did you forget to generate one?" );
4751
4854
}
4752
4855
4753
4856
@@ -4823,16 +4926,14 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
4823
4926
args.GetReturnValue ().Set (rc);
4824
4927
}
4825
4928
4826
-
4827
4929
void DiffieHellman::SetKey (const v8::FunctionCallbackInfo<v8::Value>& args,
4828
- BIGNUM* (DH::*field ), const char * what) {
4930
+ void (*set_field)(DH*, BIGNUM* ), const char * what) {
4829
4931
Environment* env = Environment::GetCurrent (args);
4830
4932
4831
4933
DiffieHellman* dh;
4832
4934
ASSIGN_OR_RETURN_UNWRAP (&dh, args.Holder ());
4833
4935
if (!dh->initialised_ ) return env->ThrowError (" Not initialized" );
4834
4936
4835
- BIGNUM** num = &((dh->dh )->*field);
4836
4937
char errmsg[64 ];
4837
4938
4838
4939
if (args.Length () == 0 ) {
@@ -4845,19 +4946,28 @@ void DiffieHellman::SetKey(const v8::FunctionCallbackInfo<v8::Value>& args,
4845
4946
return env->ThrowTypeError (errmsg);
4846
4947
}
4847
4948
4848
- *num = BN_bin2bn (reinterpret_cast <unsigned char *>(Buffer::Data (args[0 ])),
4849
- Buffer::Length (args[0 ]), *num);
4850
- CHECK_NE (*num, nullptr );
4949
+ BIGNUM* num =
4950
+ BN_bin2bn (reinterpret_cast <unsigned char *>(Buffer::Data (args[0 ])),
4951
+ Buffer::Length (args[0 ]), nullptr );
4952
+ CHECK_NE (num, nullptr );
4953
+ set_field (dh->dh , num);
4851
4954
}
4852
4955
4853
4956
4854
4957
void DiffieHellman::SetPublicKey (const FunctionCallbackInfo<Value>& args) {
4855
- SetKey (args, &DH::pub_key, " Public key" );
4958
+ SetKey (args, [](DH* dh, BIGNUM* num) { DH_set0_key (dh, num, nullptr ); },
4959
+ " Public key" );
4856
4960
}
4857
4961
4858
-
4859
4962
void DiffieHellman::SetPrivateKey (const FunctionCallbackInfo<Value>& args) {
4860
- SetKey (args, &DH::priv_key, " Private key" );
4963
+ #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
4964
+ OPENSSL_VERSION_NUMBER < 0x10100070L
4965
+ // Older versions of OpenSSL 1.1.0 have a DH_set0_key which does not work for
4966
+ // Node. See https://github.com/openssl/openssl/pull/4384.
4967
+ #error "OpenSSL 1.1.0 revisions before 1.1.0g are not supported"
4968
+ #endif
4969
+ SetKey (args, [](DH* dh, BIGNUM* num) { DH_set0_key (dh, nullptr , num); },
4970
+ " Private key" );
4861
4971
}
4862
4972
4863
4973
0 commit comments