Skip to content

Commit d85b0a3

Browse files
addaleaxrvagg
authored andcommitted
src: use smart pointers for NodeBIO
PR-URL: #21984 Reviewed-By: Anatoli Papirovski <apapirovski@mac.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent f506a5f commit d85b0a3

File tree

4 files changed

+36
-42
lines changed

4 files changed

+36
-42
lines changed

src/node_crypto.cc

+7-4
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
483483

484484
// Takes a string or buffer and loads it into a BIO.
485485
// Caller responsible for BIO_free_all-ing the returned object.
486-
static BIO* LoadBIO(Environment* env, Local<Value> v) {
486+
static BIOPointer LoadBIO(Environment* env, Local<Value> v) {
487487
HandleScope scope(env->isolate());
488488

489489
if (v->IsString()) {
@@ -738,9 +738,12 @@ static X509_STORE* NewRootCertStore() {
738738

739739
if (root_certs_vector.empty()) {
740740
for (size_t i = 0; i < arraysize(root_certs); i++) {
741-
BIO* bp = NodeBIO::NewFixed(root_certs[i], strlen(root_certs[i]));
742-
X509* x509 = PEM_read_bio_X509(bp, nullptr, NoPasswordCallback, nullptr);
743-
BIO_free(bp);
741+
X509* x509 =
742+
PEM_read_bio_X509(NodeBIO::NewFixed(root_certs[i],
743+
strlen(root_certs[i])).get(),
744+
nullptr, // no re-use of X509 structure
745+
NoPasswordCallback,
746+
nullptr); // no callback data
744747

745748
// Parse errors from the built-in roots are fatal.
746749
CHECK_NOT_NULL(x509);

src/node_crypto_bio.cc

+11-15
Original file line numberDiff line numberDiff line change
@@ -38,36 +38,32 @@ namespace crypto {
3838
#endif
3939

4040

41-
BIO* NodeBIO::New() {
41+
BIOPointer NodeBIO::New(Environment* env) {
4242
// The const_cast doesn't violate const correctness. OpenSSL's usage of
4343
// BIO_METHOD is effectively const but BIO_new() takes a non-const argument.
44-
return BIO_new(const_cast<BIO_METHOD*>(GetMethod()));
44+
BIOPointer bio(BIO_new(const_cast<BIO_METHOD*>(GetMethod())));
45+
if (bio && env != nullptr)
46+
NodeBIO::FromBIO(bio.get())->env_ = env;
47+
return bio;
4548
}
4649

4750

48-
BIO* NodeBIO::NewFixed(const char* data, size_t len) {
49-
BIO* bio = New();
51+
BIOPointer NodeBIO::NewFixed(const char* data, size_t len, Environment* env) {
52+
BIOPointer bio = New(env);
5053

51-
if (bio == nullptr ||
54+
if (!bio ||
5255
len > INT_MAX ||
53-
BIO_write(bio, data, len) != static_cast<int>(len) ||
54-
BIO_set_mem_eof_return(bio, 0) != 1) {
55-
BIO_free(bio);
56-
return nullptr;
56+
BIO_write(bio.get(), data, len) != static_cast<int>(len) ||
57+
BIO_set_mem_eof_return(bio.get(), 0) != 1) {
58+
return BIOPointer();
5759
}
5860

5961
return bio;
6062
}
6163

6264

63-
void NodeBIO::AssignEnvironment(Environment* env) {
64-
env_ = env;
65-
}
66-
67-
6865
int NodeBIO::New(BIO* bio) {
6966
BIO_set_data(bio, new NodeBIO());
70-
7167
BIO_set_init(bio, 1);
7268

7369
return 1;

src/node_crypto_bio.h

+15-18
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
2626

27+
#include "node_crypto.h"
2728
#include "openssl/bio.h"
2829
#include "env-inl.h"
2930
#include "util-inl.h"
@@ -32,25 +33,21 @@
3233
namespace node {
3334
namespace crypto {
3435

36+
// This class represents buffers for OpenSSL I/O, implemented as a singly-linked
37+
// list of chunks. It can be used both for writing data from Node to OpenSSL
38+
// and back, but only one direction per instance.
39+
// The structure is only accessed, and owned by, the OpenSSL BIOPointer
40+
// (a.k.a. std::unique_ptr<BIO>).
3541
class NodeBIO : public MemoryRetainer {
3642
public:
37-
NodeBIO() : env_(nullptr),
38-
initial_(kInitialBufferLength),
39-
length_(0),
40-
eof_return_(-1),
41-
read_head_(nullptr),
42-
write_head_(nullptr) {
43-
}
44-
4543
~NodeBIO();
4644

47-
static BIO* New();
45+
static BIOPointer New(Environment* env = nullptr);
4846

4947
// NewFixed takes a copy of `len` bytes from `data` and returns a BIO that,
5048
// when read from, returns those bytes followed by EOF.
51-
static BIO* NewFixed(const char* data, size_t len);
52-
53-
void AssignEnvironment(Environment* env);
49+
static BIOPointer NewFixed(const char* data, size_t len,
50+
Environment* env = nullptr);
5451

5552
// Move read head to next buffer if needed
5653
void TryMoveReadHead();
@@ -161,12 +158,12 @@ class NodeBIO : public MemoryRetainer {
161158
char* data_;
162159
};
163160

164-
Environment* env_;
165-
size_t initial_;
166-
size_t length_;
167-
int eof_return_;
168-
Buffer* read_head_;
169-
Buffer* write_head_;
161+
Environment* env_ = nullptr;
162+
size_t initial_ = kInitialBufferLength;
163+
size_t length_ = 0;
164+
int eof_return_ = -1;
165+
Buffer* read_head_ = nullptr;
166+
Buffer* write_head_ = nullptr;
170167
};
171168

172169
} // namespace crypto

src/tls_wrap.cc

+3-5
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,9 @@ void TLSWrap::NewSessionDoneCb() {
112112

113113

114114
void TLSWrap::InitSSL() {
115-
// Initialize SSL
116-
enc_in_ = crypto::NodeBIO::New();
117-
enc_out_ = crypto::NodeBIO::New();
118-
crypto::NodeBIO::FromBIO(enc_in_)->AssignEnvironment(env());
119-
crypto::NodeBIO::FromBIO(enc_out_)->AssignEnvironment(env());
115+
// Initialize SSL – OpenSSL takes ownership of these.
116+
enc_in_ = crypto::NodeBIO::New(env()).release();
117+
enc_out_ = crypto::NodeBIO::New(env()).release();
120118

121119
SSL_set_bio(ssl_.get(), enc_in_, enc_out_);
122120

0 commit comments

Comments
 (0)