@@ -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 ;
@@ -1005,7 +1076,9 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
1005
1076
if (dh == nullptr )
1006
1077
return ;
1007
1078
1008
- const int size = BN_num_bits (dh->p );
1079
+ const BIGNUM* p;
1080
+ DH_get0_pqg (dh, &p, nullptr , nullptr );
1081
+ const int size = BN_num_bits (p);
1009
1082
if (size < 1024 ) {
1010
1083
return env->ThrowError (" DH parameter is less than 1024 bits" );
1011
1084
} else if (size < 2048 ) {
@@ -1625,14 +1698,17 @@ static Local<Object> X509ToObject(Environment* env, X509* cert) {
1625
1698
rsa = EVP_PKEY_get1_RSA (pkey);
1626
1699
1627
1700
if (rsa != nullptr ) {
1628
- BN_print (bio, rsa->n );
1701
+ const BIGNUM* n;
1702
+ const BIGNUM* e;
1703
+ RSA_get0_key (rsa, &n, &e, nullptr );
1704
+ BN_print (bio, n);
1629
1705
BIO_get_mem_ptr (bio, &mem);
1630
1706
info->Set (env->modulus_string (),
1631
1707
String::NewFromUtf8 (env->isolate (), mem->data ,
1632
1708
String::kNormalString , mem->length ));
1633
1709
(void ) BIO_reset (bio);
1634
1710
1635
- uint64_t exponent_word = static_cast <uint64_t >(BN_get_word (rsa-> e ));
1711
+ uint64_t exponent_word = static_cast <uint64_t >(BN_get_word (e));
1636
1712
uint32_t lo = static_cast <uint32_t >(exponent_word);
1637
1713
uint32_t hi = static_cast <uint32_t >(exponent_word >> 32 );
1638
1714
if (hi == 0 ) {
@@ -4599,10 +4675,15 @@ bool DiffieHellman::Init(int primeLength, int g) {
4599
4675
4600
4676
bool DiffieHellman::Init (const char * p, int p_len, int g) {
4601
4677
dh = DH_new ();
4602
- dh->p = BN_bin2bn (reinterpret_cast <const unsigned char *>(p), p_len, 0 );
4603
- dh->g = BN_new ();
4604
- if (!BN_set_word (dh->g , g))
4678
+ BIGNUM* bn_p =
4679
+ BN_bin2bn (reinterpret_cast <const unsigned char *>(p), p_len, nullptr );
4680
+ BIGNUM* bn_g = BN_new ();
4681
+ if (!BN_set_word (bn_g, g) ||
4682
+ !DH_set0_pqg (dh, bn_p, nullptr , bn_g)) {
4683
+ BN_free (bn_p);
4684
+ BN_free (bn_g);
4605
4685
return false ;
4686
+ }
4606
4687
bool result = VerifyContext ();
4607
4688
if (!result)
4608
4689
return false ;
@@ -4613,8 +4694,13 @@ bool DiffieHellman::Init(const char* p, int p_len, int g) {
4613
4694
4614
4695
bool DiffieHellman::Init (const char * p, int p_len, const char * g, int g_len) {
4615
4696
dh = DH_new ();
4616
- dh->p = BN_bin2bn (reinterpret_cast <const unsigned char *>(p), p_len, 0 );
4617
- dh->g = BN_bin2bn (reinterpret_cast <const unsigned char *>(g), g_len, 0 );
4697
+ BIGNUM *bn_p = BN_bin2bn (reinterpret_cast <const unsigned char *>(p), p_len, 0 );
4698
+ BIGNUM *bn_g = BN_bin2bn (reinterpret_cast <const unsigned char *>(g), g_len, 0 );
4699
+ if (!DH_set0_pqg (dh, bn_p, nullptr , bn_g)) {
4700
+ BN_free (bn_p);
4701
+ BN_free (bn_g);
4702
+ return false ;
4703
+ }
4618
4704
bool result = VerifyContext ();
4619
4705
if (!result)
4620
4706
return false ;
@@ -4702,22 +4788,25 @@ void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
4702
4788
return ThrowCryptoError (env, ERR_get_error (), " Key generation failed" );
4703
4789
}
4704
4790
4705
- size_t size = BN_num_bytes (diffieHellman->dh ->pub_key );
4791
+ const BIGNUM* pub_key;
4792
+ DH_get0_key (diffieHellman->dh , &pub_key, nullptr );
4793
+ size_t size = BN_num_bytes (pub_key);
4706
4794
char * data = Malloc (size);
4707
- BN_bn2bin (diffieHellman-> dh -> pub_key , reinterpret_cast <unsigned char *>(data));
4795
+ BN_bn2bin (pub_key, reinterpret_cast <unsigned char *>(data));
4708
4796
args.GetReturnValue ().Set (Buffer::New (env, data, size).ToLocalChecked ());
4709
4797
}
4710
4798
4711
4799
4712
4800
void DiffieHellman::GetField (const FunctionCallbackInfo<Value>& args,
4713
- BIGNUM* (DH::*field), const char * err_if_null) {
4801
+ const BIGNUM* (*get_field)(const DH*),
4802
+ const char * err_if_null) {
4714
4803
Environment* env = Environment::GetCurrent (args);
4715
4804
4716
4805
DiffieHellman* dh;
4717
4806
ASSIGN_OR_RETURN_UNWRAP (&dh, args.Holder ());
4718
4807
if (!dh->initialised_ ) return env->ThrowError (" Not initialized" );
4719
4808
4720
- const BIGNUM* num = (dh->dh )->*field ;
4809
+ const BIGNUM* num = get_field (dh->dh );
4721
4810
if (num == nullptr ) return env->ThrowError (err_if_null);
4722
4811
4723
4812
size_t size = BN_num_bytes (num);
@@ -4727,24 +4816,38 @@ void DiffieHellman::GetField(const FunctionCallbackInfo<Value>& args,
4727
4816
}
4728
4817
4729
4818
void DiffieHellman::GetPrime (const FunctionCallbackInfo<Value>& args) {
4730
- GetField (args, &DH::p, " p is null" );
4819
+ GetField (args, [](const DH* dh) -> const BIGNUM* {
4820
+ const BIGNUM* p;
4821
+ DH_get0_pqg (dh, &p, nullptr , nullptr );
4822
+ return p;
4823
+ }, " p is null" );
4731
4824
}
4732
4825
4733
4826
4734
4827
void DiffieHellman::GetGenerator (const FunctionCallbackInfo<Value>& args) {
4735
- GetField (args, &DH::g, " g is null" );
4828
+ GetField (args, [](const DH* dh) -> const BIGNUM* {
4829
+ const BIGNUM* g;
4830
+ DH_get0_pqg (dh, nullptr , nullptr , &g);
4831
+ return g;
4832
+ }, " g is null" );
4736
4833
}
4737
4834
4738
4835
4739
4836
void DiffieHellman::GetPublicKey (const FunctionCallbackInfo<Value>& args) {
4740
- GetField (args, &DH::pub_key,
4741
- " No public key - did you forget to generate one?" );
4837
+ GetField (args, [](const DH* dh) -> const BIGNUM* {
4838
+ const BIGNUM* pub_key;
4839
+ DH_get0_key (dh, &pub_key, nullptr );
4840
+ return pub_key;
4841
+ }, " No public key - did you forget to generate one?" );
4742
4842
}
4743
4843
4744
4844
4745
4845
void DiffieHellman::GetPrivateKey (const FunctionCallbackInfo<Value>& args) {
4746
- GetField (args, &DH::priv_key,
4747
- " No private key - did you forget to generate one?" );
4846
+ GetField (args, [](const DH* dh) -> const BIGNUM* {
4847
+ const BIGNUM* priv_key;
4848
+ DH_get0_key (dh, nullptr , &priv_key);
4849
+ return priv_key;
4850
+ }, " No private key - did you forget to generate one?" );
4748
4851
}
4749
4852
4750
4853
@@ -4820,16 +4923,14 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
4820
4923
args.GetReturnValue ().Set (rc);
4821
4924
}
4822
4925
4823
-
4824
4926
void DiffieHellman::SetKey (const v8::FunctionCallbackInfo<v8::Value>& args,
4825
- BIGNUM* (DH::*field ), const char * what) {
4927
+ void (*set_field)(DH*, BIGNUM* ), const char * what) {
4826
4928
Environment* env = Environment::GetCurrent (args);
4827
4929
4828
4930
DiffieHellman* dh;
4829
4931
ASSIGN_OR_RETURN_UNWRAP (&dh, args.Holder ());
4830
4932
if (!dh->initialised_ ) return env->ThrowError (" Not initialized" );
4831
4933
4832
- BIGNUM** num = &((dh->dh )->*field);
4833
4934
char errmsg[64 ];
4834
4935
4835
4936
if (args.Length () == 0 ) {
@@ -4842,19 +4943,28 @@ void DiffieHellman::SetKey(const v8::FunctionCallbackInfo<v8::Value>& args,
4842
4943
return env->ThrowTypeError (errmsg);
4843
4944
}
4844
4945
4845
- *num = BN_bin2bn (reinterpret_cast <unsigned char *>(Buffer::Data (args[0 ])),
4846
- Buffer::Length (args[0 ]), *num);
4847
- CHECK_NE (*num, nullptr );
4946
+ BIGNUM* num =
4947
+ BN_bin2bn (reinterpret_cast <unsigned char *>(Buffer::Data (args[0 ])),
4948
+ Buffer::Length (args[0 ]), nullptr );
4949
+ CHECK_NE (num, nullptr );
4950
+ set_field (dh->dh , num);
4848
4951
}
4849
4952
4850
4953
4851
4954
void DiffieHellman::SetPublicKey (const FunctionCallbackInfo<Value>& args) {
4852
- SetKey (args, &DH::pub_key, " Public key" );
4955
+ SetKey (args, [](DH* dh, BIGNUM* num) { DH_set0_key (dh, num, nullptr ); },
4956
+ " Public key" );
4853
4957
}
4854
4958
4855
-
4856
4959
void DiffieHellman::SetPrivateKey (const FunctionCallbackInfo<Value>& args) {
4857
- SetKey (args, &DH::priv_key, " Private key" );
4960
+ #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
4961
+ OPENSSL_VERSION_NUMBER < 0x10100070L
4962
+ // Older versions of OpenSSL 1.1.0 have a DH_set0_key which does not work for
4963
+ // Node. See https://github.com/openssl/openssl/pull/4384.
4964
+ #error "OpenSSL 1.1.0 revisions before 1.1.0g are not supported"
4965
+ #endif
4966
+ SetKey (args, [](DH* dh, BIGNUM* num) { DH_set0_key (dh, nullptr , num); },
4967
+ " Private key" );
4858
4968
}
4859
4969
4860
4970
0 commit comments