Skip to content

Commit 3048ac0

Browse files
aglrvagg
authored andcommittedFeb 15, 2016
crypto: have fixed NodeBIOs return EOF
Prior to this change, the NodeBIO objects used to wrap fixed data had `num` equal to -1. This caused them to return -1 and set the retry flags when they ran out of data. Since the data is fixed, that's incorrect. Instead they should return zero to signal EOF. This change adds a new, static function, NodeBIO::NewFixed to create a BIO that wraps fixed data and which returns zero when exhausted. The practical impact of this is limited since most (all?) the parsing functions that these BIOs get passed to consider any return value less than one to be EOF and ignore the retry flags anyway. PR-URL: #5105 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Fedor Indutny <[email protected]>
1 parent 98596a9 commit 3048ac0

File tree

3 files changed

+26
-20
lines changed

3 files changed

+26
-20
lines changed
 

‎src/node_crypto.cc

+6-20
Original file line numberDiff line numberDiff line change
@@ -416,29 +416,18 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
416416
// Takes a string or buffer and loads it into a BIO.
417417
// Caller responsible for BIO_free_all-ing the returned object.
418418
static BIO* LoadBIO(Environment* env, Local<Value> v) {
419-
BIO* bio = NodeBIO::New();
420-
if (!bio)
421-
return nullptr;
422-
423419
HandleScope scope(env->isolate());
424420

425-
int r = -1;
426-
427421
if (v->IsString()) {
428422
const node::Utf8Value s(env->isolate(), v);
429-
r = BIO_write(bio, *s, s.length());
430-
} else if (Buffer::HasInstance(v)) {
431-
char* buffer_data = Buffer::Data(v);
432-
size_t buffer_length = Buffer::Length(v);
433-
r = BIO_write(bio, buffer_data, buffer_length);
423+
return NodeBIO::NewFixed(*s, s.length());
434424
}
435425

436-
if (r <= 0) {
437-
BIO_free_all(bio);
438-
return nullptr;
426+
if (Buffer::HasInstance(v)) {
427+
return NodeBIO::NewFixed(Buffer::Data(v), Buffer::Length(v));
439428
}
440429

441-
return bio;
430+
return nullptr;
442431
}
443432

444433

@@ -761,15 +750,12 @@ void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
761750
root_cert_store = X509_STORE_new();
762751

763752
for (size_t i = 0; i < ARRAY_SIZE(root_certs); i++) {
764-
BIO* bp = NodeBIO::New();
765-
766-
if (!BIO_write(bp, root_certs[i], strlen(root_certs[i]))) {
767-
BIO_free_all(bp);
753+
BIO* bp = NodeBIO::NewFixed(root_certs[i], strlen(root_certs[i]));
754+
if (bp == nullptr) {
768755
return;
769756
}
770757

771758
X509 *x509 = PEM_read_bio_X509(bp, nullptr, CryptoPemCallback, nullptr);
772-
773759
if (x509 == nullptr) {
774760
BIO_free_all(bp);
775761
return;

‎src/node_crypto_bio.cc

+16
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "openssl/bio.h"
33
#include "util.h"
44
#include "util-inl.h"
5+
#include <limits.h>
56
#include <string.h>
67

78
namespace node {
@@ -27,6 +28,21 @@ BIO* NodeBIO::New() {
2728
}
2829

2930

31+
BIO* NodeBIO::NewFixed(const char* data, size_t len) {
32+
BIO* bio = New();
33+
34+
if (bio == nullptr ||
35+
len > INT_MAX ||
36+
BIO_write(bio, data, len) != static_cast<int>(len) ||
37+
BIO_set_mem_eof_return(bio, 0) != 1) {
38+
BIO_free(bio);
39+
return nullptr;
40+
}
41+
42+
return bio;
43+
}
44+
45+
3046
void NodeBIO::AssignEnvironment(Environment* env) {
3147
env_ = env;
3248
}

‎src/node_crypto_bio.h

+4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ class NodeBIO {
2323

2424
static BIO* New();
2525

26+
// NewFixed takes a copy of `len` bytes from `data` and returns a BIO that,
27+
// when read from, returns those bytes followed by EOF.
28+
static BIO* NewFixed(const char* data, size_t len);
29+
2630
void AssignEnvironment(Environment* env);
2731

2832
// Move read head to next buffer if needed

0 commit comments

Comments
 (0)
Please sign in to comment.