Skip to content

Commit efd9bc3

Browse files
davidbenevanlucas
authored andcommitted
crypto: make node_crypto_bio compat w/ OpenSSL 1.1
This is cherry-picked from PR #8491 and then tidied up. The original had an unnecessarily large diff and messed up some public/private bits. PR-URL: #16130 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Rod Vagg <[email protected]>
1 parent 8da4983 commit efd9bc3

File tree

2 files changed

+77
-33
lines changed

2 files changed

+77
-33
lines changed

src/node_crypto_bio.cc

+64-27
Original file line numberDiff line numberDiff line change
@@ -28,24 +28,20 @@
2828
namespace node {
2929
namespace crypto {
3030

31-
const BIO_METHOD NodeBIO::method = {
32-
BIO_TYPE_MEM,
33-
"node.js SSL buffer",
34-
NodeBIO::Write,
35-
NodeBIO::Read,
36-
NodeBIO::Puts,
37-
NodeBIO::Gets,
38-
NodeBIO::Ctrl,
39-
NodeBIO::New,
40-
NodeBIO::Free,
41-
nullptr
42-
};
31+
#if OPENSSL_VERSION_NUMBER < 0x10100000L
32+
#define BIO_set_data(bio, data) bio->ptr = data
33+
#define BIO_get_data(bio) bio->ptr
34+
#define BIO_set_shutdown(bio, shutdown_) bio->shutdown = shutdown_
35+
#define BIO_get_shutdown(bio) bio->shutdown
36+
#define BIO_set_init(bio, init_) bio->init = init_
37+
#define BIO_get_init(bio) bio->init
38+
#endif
4339

4440

4541
BIO* NodeBIO::New() {
4642
// The const_cast doesn't violate const correctness. OpenSSL's usage of
4743
// BIO_METHOD is effectively const but BIO_new() takes a non-const argument.
48-
return BIO_new(const_cast<BIO_METHOD*>(&method));
44+
return BIO_new(const_cast<BIO_METHOD*>(GetMethod()));
4945
}
5046

5147

@@ -70,12 +66,11 @@ void NodeBIO::AssignEnvironment(Environment* env) {
7066

7167

7268
int NodeBIO::New(BIO* bio) {
73-
bio->ptr = new NodeBIO();
69+
BIO_set_data(bio, new NodeBIO());
7470

7571
// XXX Why am I doing it?!
76-
bio->shutdown = 1;
77-
bio->init = 1;
78-
bio->num = -1;
72+
BIO_set_shutdown(bio, 1);
73+
BIO_set_init(bio, 1);
7974

8075
return 1;
8176
}
@@ -85,10 +80,10 @@ int NodeBIO::Free(BIO* bio) {
8580
if (bio == nullptr)
8681
return 0;
8782

88-
if (bio->shutdown) {
89-
if (bio->init && bio->ptr != nullptr) {
83+
if (BIO_get_shutdown(bio)) {
84+
if (BIO_get_init(bio) && BIO_get_data(bio) != nullptr) {
9085
delete FromBIO(bio);
91-
bio->ptr = nullptr;
86+
BIO_set_data(bio, nullptr);
9287
}
9388
}
9489

@@ -97,13 +92,13 @@ int NodeBIO::Free(BIO* bio) {
9792

9893

9994
int NodeBIO::Read(BIO* bio, char* out, int len) {
100-
int bytes;
10195
BIO_clear_retry_flags(bio);
10296

103-
bytes = FromBIO(bio)->Read(out, len);
97+
NodeBIO* nbio = FromBIO(bio);
98+
int bytes = nbio->Read(out, len);
10499

105100
if (bytes == 0) {
106-
bytes = bio->num;
101+
bytes = nbio->eof_return();
107102
if (bytes != 0) {
108103
BIO_set_retry_read(bio);
109104
}
@@ -161,7 +156,7 @@ int NodeBIO::Puts(BIO* bio, const char* str) {
161156

162157

163158
int NodeBIO::Gets(BIO* bio, char* out, int size) {
164-
NodeBIO* nbio = FromBIO(bio);
159+
NodeBIO* nbio = FromBIO(bio);
165160

166161
if (nbio->Length() == 0)
167162
return 0;
@@ -201,7 +196,7 @@ long NodeBIO::Ctrl(BIO* bio, int cmd, long num, // NOLINT(runtime/int)
201196
ret = nbio->Length() == 0;
202197
break;
203198
case BIO_C_SET_BUF_MEM_EOF_RETURN:
204-
bio->num = num;
199+
nbio->set_eof_return(num);
205200
break;
206201
case BIO_CTRL_INFO:
207202
ret = nbio->Length();
@@ -216,10 +211,10 @@ long NodeBIO::Ctrl(BIO* bio, int cmd, long num, // NOLINT(runtime/int)
216211
ret = 0;
217212
break;
218213
case BIO_CTRL_GET_CLOSE:
219-
ret = bio->shutdown;
214+
ret = BIO_get_shutdown(bio);
220215
break;
221216
case BIO_CTRL_SET_CLOSE:
222-
bio->shutdown = num;
217+
BIO_set_shutdown(bio, num);
223218
break;
224219
case BIO_CTRL_WPENDING:
225220
ret = 0;
@@ -241,6 +236,41 @@ long NodeBIO::Ctrl(BIO* bio, int cmd, long num, // NOLINT(runtime/int)
241236
}
242237

243238

239+
const BIO_METHOD* NodeBIO::GetMethod() {
240+
#if OPENSSL_VERSION_NUMBER < 0x10100000L
241+
static const BIO_METHOD method = {
242+
BIO_TYPE_MEM,
243+
"node.js SSL buffer",
244+
Write,
245+
Read,
246+
Puts,
247+
Gets,
248+
Ctrl,
249+
New,
250+
Free,
251+
nullptr
252+
};
253+
254+
return &method;
255+
#else
256+
static BIO_METHOD* method = nullptr;
257+
258+
if (method == nullptr) {
259+
method = BIO_meth_new(BIO_TYPE_MEM, "node.js SSL buffer");
260+
BIO_meth_set_write(method, Write);
261+
BIO_meth_set_read(method, Read);
262+
BIO_meth_set_puts(method, Puts);
263+
BIO_meth_set_gets(method, Gets);
264+
BIO_meth_set_ctrl(method, Ctrl);
265+
BIO_meth_set_create(method, New);
266+
BIO_meth_set_destroy(method, Free);
267+
}
268+
269+
return method;
270+
#endif
271+
}
272+
273+
244274
void NodeBIO::TryMoveReadHead() {
245275
// `read_pos_` and `write_pos_` means the position of the reader and writer
246276
// inside the buffer, respectively. When they're equal - its safe to reset
@@ -488,5 +518,12 @@ NodeBIO::~NodeBIO() {
488518
write_head_ = nullptr;
489519
}
490520

521+
522+
NodeBIO* NodeBIO::FromBIO(BIO* bio) {
523+
CHECK_NE(BIO_get_data(bio), nullptr);
524+
return static_cast<NodeBIO*>(BIO_get_data(bio));
525+
}
526+
527+
491528
} // namespace crypto
492529
} // namespace node

src/node_crypto_bio.h

+13-6
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class NodeBIO {
3737
NodeBIO() : env_(nullptr),
3838
initial_(kInitialBufferLength),
3939
length_(0),
40+
eof_return_(-1),
4041
read_head_(nullptr),
4142
write_head_(nullptr) {
4243
}
@@ -95,14 +96,19 @@ class NodeBIO {
9596
return length_;
9697
}
9798

99+
inline void set_eof_return(int num) {
100+
eof_return_ = num;
101+
}
102+
103+
inline int eof_return() {
104+
return eof_return_;
105+
}
106+
98107
inline void set_initial(size_t initial) {
99108
initial_ = initial;
100109
}
101110

102-
static inline NodeBIO* FromBIO(BIO* bio) {
103-
CHECK_NE(bio->ptr, nullptr);
104-
return static_cast<NodeBIO*>(bio->ptr);
105-
}
111+
static NodeBIO* FromBIO(BIO* bio);
106112

107113
private:
108114
static int New(BIO* bio);
@@ -114,12 +120,12 @@ class NodeBIO {
114120
static long Ctrl(BIO* bio, int cmd, long num, // NOLINT(runtime/int)
115121
void* ptr);
116122

123+
static const BIO_METHOD* GetMethod();
124+
117125
// Enough to handle the most of the client hellos
118126
static const size_t kInitialBufferLength = 1024;
119127
static const size_t kThroughputBufferLength = 16384;
120128

121-
static const BIO_METHOD method;
122-
123129
class Buffer {
124130
public:
125131
Buffer(Environment* env, size_t len) : env_(env),
@@ -151,6 +157,7 @@ class NodeBIO {
151157
Environment* env_;
152158
size_t initial_;
153159
size_t length_;
160+
int eof_return_;
154161
Buffer* read_head_;
155162
Buffer* write_head_;
156163
};

0 commit comments

Comments
 (0)