Skip to content

Commit

Permalink
test: fix tests work on both openssl102 and 110
Browse files Browse the repository at this point in the history
This fixes that tests can run and pass on both built with
OpenSSL-1.0.2 and 1.1.0.

Only the test of `test/parallel/test-tls-econnreset.js` is skipped
because there are no way to leads TLS handshake failure and send
ECONNRESET from the tls client to tls server with using OpenSSL-1.1.0.
  • Loading branch information
shigeki authored and danbev committed Jun 13, 2017
1 parent 45677ca commit 8fde1f2
Show file tree
Hide file tree
Showing 28 changed files with 280 additions and 219 deletions.
19 changes: 3 additions & 16 deletions src/crypto_impl/openssl/1_1_0f/node_crypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,6 @@ void SecureContext::Initialize(Environment* env, Local<Object> target) {
env->SetProtoMethod(t, "loadPKCS12", SecureContext::LoadPKCS12);
env->SetProtoMethod(t, "getTicketKeys", SecureContext::GetTicketKeys);
env->SetProtoMethod(t, "setTicketKeys", SecureContext::SetTicketKeys);
env->SetProtoMethod(t, "setFreeListLength", SecureContext::SetFreeListLength);
env->SetProtoMethod(t,
"enableTicketKeyCallback",
SecureContext::EnableTicketKeyCallback);
Expand Down Expand Up @@ -1196,18 +1195,6 @@ void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
}


void SecureContext::SetFreeListLength(const FunctionCallbackInfo<Value>& args) {
#if OPENSSL_VERSION_NUMBER < 0x10100000L && !defined(OPENSSL_IS_BORINGSSL)
// |freelist_max_len| was removed in OpenSSL 1.1.0. In that version OpenSSL
// mallocs and frees buffers directly, without the use of a freelist.
SecureContext* wrap;
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());

wrap->ctx_->freelist_max_len = args[0]->Int32Value();
#endif
}


// Currently, EnableTicketKeyCallback and TicketKeyCallback are only present for
// the regression test in test/parallel/test-https-resume-after-renew.js.
void SecureContext::EnableTicketKeyCallback(
Expand Down Expand Up @@ -4147,7 +4134,7 @@ static int Node_SignFinal(EVP_MD_CTX* mdctx, unsigned char* md,
if (!EVP_DigestFinal_ex(mdctx, m, &m_len))
return rv;

if (EVP_MD_CTX_test_flags(mdctx, EVP_MD_FLAG_DIGALGID_MASK)) {
if(EVP_MD_CTX_pkey_ctx(mdctx) == nullptr) {
size_t sltmp = static_cast<size_t>(EVP_PKEY_size(pkey));
pkctx = EVP_PKEY_CTX_new(pkey, nullptr);
if (pkctx == nullptr)
Expand All @@ -4156,7 +4143,7 @@ static int Node_SignFinal(EVP_MD_CTX* mdctx, unsigned char* md,
goto err;
if (!ApplyRSAOptions(pkey, pkctx, padding, pss_salt_len))
goto err;
if (EVP_PKEY_CTX_set_signature_md(pkctx, EVP_MD_CTX_md_data(mdctx)) <= 0)
if (EVP_PKEY_CTX_set_signature_md(pkctx, EVP_MD_CTX_md(mdctx)) <= 0)
goto err;
if (EVP_PKEY_sign(pkctx, md, &sltmp, m, m_len) <= 0)
goto err;
Expand Down Expand Up @@ -4457,7 +4444,7 @@ SignBase::Error Verify::VerifyFinal(const char* key_pem,
goto err;
if (!ApplyRSAOptions(pkey, pkctx, padding, saltlen))
goto err;
if (EVP_PKEY_CTX_set_signature_md(pkctx, EVP_MD_CTX_md_data(mdctx_)) <= 0)
if (EVP_PKEY_CTX_set_signature_md(pkctx, EVP_MD_CTX_md(mdctx_)) <= 0)
goto err;
r = EVP_PKEY_verify(pkctx,
reinterpret_cast<const unsigned char*>(sig),
Expand Down
6 changes: 4 additions & 2 deletions src/crypto_impl/openssl/1_1_0f/node_crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,6 @@ class SecureContext : public BaseObject {
static void LoadPKCS12(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetTicketKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetTicketKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetFreeListLength(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void EnableTicketKeyCallback(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void CtxGetter(v8::Local<v8::String> property,
Expand Down Expand Up @@ -466,6 +464,7 @@ class CipherBase : public BaseObject {
auth_tag_(nullptr),
auth_tag_len_(0) {
MakeWeak<CipherBase>(this);
ctx_ = EVP_CIPHER_CTX_new();
}

private:
Expand Down Expand Up @@ -501,6 +500,7 @@ class Hmac : public BaseObject {
: BaseObject(env, wrap),
initialised_(false) {
MakeWeak<Hmac>(this);
ctx_ = HMAC_CTX_new();
}

private:
Expand Down Expand Up @@ -530,6 +530,7 @@ class Hash : public BaseObject {
: BaseObject(env, wrap),
initialised_(false) {
MakeWeak<Hash>(this);
mdctx_ = EVP_MD_CTX_new();
}

private:
Expand All @@ -553,6 +554,7 @@ class SignBase : public BaseObject {
SignBase(Environment* env, v8::Local<v8::Object> wrap)
: BaseObject(env, wrap),
initialised_(false) {
mdctx_ = EVP_MD_CTX_new();
}

~SignBase() override {
Expand Down
95 changes: 39 additions & 56 deletions src/crypto_impl/openssl/1_1_0f/node_crypto_bio.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,47 +28,28 @@

namespace node {

const BIO_METHOD* NodeBIO::CreateBioMethod() {
BIO_METHOD* biom = BIO_meth_new(BIO_TYPE_MEM, "node.js SSL buffer");
BIO_meth_set_write(biom, Write);
BIO_meth_set_read(biom, NodeBIO::Read);
BIO_meth_set_puts(biom, NodeBIO::Puts);
BIO_meth_set_gets(biom, NodeBIO::Gets);
BIO_meth_set_ctrl(biom, NodeBIO::Ctrl);
BIO_meth_set_create(biom, NodeBIO::New);
BIO_meth_set_destroy(biom, NodeBIO::Free);
return biom;
static int New(BIO* bio);
static int Free(BIO* bio);
static int Read(BIO* bio, char* out, int len);
static int Write(BIO* bio, const char* data, int len);
static int Puts(BIO* bio, const char* str);
static int Gets(BIO* bio, char* out, int size);
static long Ctrl(BIO* bio, int cmd, long num, // NOLINT(runtime/int)
void* ptr);

BIO_METHOD* GetBioMethod() {
BIO_METHOD* method = BIO_meth_new(BIO_TYPE_MEM, "node.js SSL buffer");
BIO_meth_set_write(method, Write);
BIO_meth_set_read(method, Read);
BIO_meth_set_puts(method, Puts);
BIO_meth_set_gets(method, Gets);
BIO_meth_set_ctrl(method, Ctrl);
BIO_meth_set_create(method, New);
BIO_meth_set_destroy(method, Free);
return method;
}
const BIO_METHOD* NodeBIO::method = NodeBIO::CreateBioMethod();
/*
BIO_TYPE_MEM,
"node.js SSL buffer",
NodeBIO::Write,
NodeBIO::Read,
NodeBIO::Puts,
NodeBIO::Gets,
NodeBIO::Ctrl,
NodeBIO::New,
NodeBIO::Free,
nullptr
};
{
if (method_tls_corrupt == NULL) {
method_tls_corrupt = BIO_meth_new(BIO_TYPE_CUSTOM_FILTER, "node.js SSL buffer");
if ( method_tls_corrupt == NULL
|| !BIO_meth_set_write(method_tls_corrupt, tls_corrupt_write)
|| !BIO_meth_set_read(method_tls_corrupt, tls_corrupt_read)
|| !BIO_meth_set_puts(method_tls_corrupt, tls_corrupt_puts)
|| !BIO_meth_set_gets(method_tls_corrupt, tls_corrupt_gets)
|| !BIO_meth_set_ctrl(method_tls_corrupt, tls_corrupt_ctrl)
|| !BIO_meth_set_create(method_tls_corrupt, tls_corrupt_new)
|| !BIO_meth_set_destroy(method_tls_corrupt, tls_corrupt_free))
return NULL;
}
return method_tls_corrupt;
}
*/

const BIO_METHOD* method = GetBioMethod();

BIO* NodeBIO::New() {
// The const_cast doesn't violate const correctness. OpenSSL's usage of
Expand Down Expand Up @@ -97,7 +78,7 @@ void NodeBIO::AssignEnvironment(Environment* env) {
}


int NodeBIO::New(BIO* bio) {
static int New(BIO* bio) {
BIO_set_data(bio, new NodeBIO());

// XXX Why am I doing it?!
Expand All @@ -108,13 +89,13 @@ int NodeBIO::New(BIO* bio) {
}


int NodeBIO::Free(BIO* bio) {
static int Free(BIO* bio) {
if (bio == nullptr)
return 0;

if (BIO_get_shutdown(bio)) {
if (BIO_get_init(bio) && BIO_get_data(bio) != nullptr) {
delete FromBIO(bio);
delete NodeBIO::FromBIO(bio);
BIO_set_data(bio, nullptr);
}
}
Expand All @@ -123,16 +104,17 @@ int NodeBIO::Free(BIO* bio) {
}


int NodeBIO::Read(BIO* bio, char* out, int len) {
static int Read(BIO* bio, char* out, int len) {
int bytes;
NodeBIO* nbio = NodeBIO::FromBIO(bio);

BIO_clear_retry_flags(bio);

bytes = FromBIO(bio)->Read(out, len);
bytes = nbio->Read(out, len);

if (bytes == 0) {
//bytes = bio->num;
//if (bytes != 0) {
if (BIO_should_retry(bio)) {
bytes = nbio->eof_return();
if (bytes != 0) {
BIO_set_retry_read(bio);
}
}
Expand Down Expand Up @@ -174,22 +156,22 @@ size_t NodeBIO::PeekMultiple(char** out, size_t* size, size_t* count) {
}


int NodeBIO::Write(BIO* bio, const char* data, int len) {
static int Write(BIO* bio, const char* data, int len) {
BIO_clear_retry_flags(bio);

FromBIO(bio)->Write(data, len);
NodeBIO::FromBIO(bio)->Write(data, len);

return len;
}


int NodeBIO::Puts(BIO* bio, const char* str) {
static int Puts(BIO* bio, const char* str) {
return Write(bio, str, strlen(str));
}


int NodeBIO::Gets(BIO* bio, char* out, int size) {
NodeBIO* nbio = FromBIO(bio);
static int Gets(BIO* bio, char* out, int size) {
NodeBIO* nbio = NodeBIO::FromBIO(bio);

if (nbio->Length() == 0)
return 0;
Expand All @@ -213,12 +195,12 @@ int NodeBIO::Gets(BIO* bio, char* out, int size) {
}


long NodeBIO::Ctrl(BIO* bio, int cmd, long num, // NOLINT(runtime/int)
void* ptr) {
static long Ctrl(BIO* bio, int cmd, long num, // NOLINT(runtime/int)
void* ptr) {
NodeBIO* nbio;
long ret; // NOLINT(runtime/int)

nbio = FromBIO(bio);
nbio = NodeBIO::FromBIO(bio);
ret = 1;

switch (cmd) {
Expand All @@ -229,7 +211,8 @@ long NodeBIO::Ctrl(BIO* bio, int cmd, long num, // NOLINT(runtime/int)
ret = nbio->Length() == 0;
break;
case BIO_C_SET_BUF_MEM_EOF_RETURN:
BIO_set_mem_eof_return(bio, num);
//BIO_set_mem_eof_return(bio, num);
nbio->set_eof_return(num);
break;
case BIO_CTRL_INFO:
ret = nbio->Length();
Expand Down
22 changes: 10 additions & 12 deletions src/crypto_impl/openssl/1_1_0f/node_crypto_bio.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class NodeBIO {
NodeBIO() : env_(nullptr),
initial_(kInitialBufferLength),
length_(0),
eof_return_(-1),
read_head_(nullptr),
write_head_(nullptr) {
}
Expand Down Expand Up @@ -100,28 +101,24 @@ class NodeBIO {
initial_ = initial;
}

inline void set_eof_return(int num) {
eof_return_ = num;
}

inline int eof_return() {
return eof_return_;
}

static inline NodeBIO* FromBIO(BIO* bio) {
CHECK_NE(BIO_get_data(bio), nullptr);
return static_cast<NodeBIO*>(BIO_get_data(bio));
}

private:
static int New(BIO* bio);
static int Free(BIO* bio);
static int Read(BIO* bio, char* out, int len);
static int Write(BIO* bio, const char* data, int len);
static int Puts(BIO* bio, const char* str);
static int Gets(BIO* bio, char* out, int size);
static long Ctrl(BIO* bio, int cmd, long num, // NOLINT(runtime/int)
void* ptr);

// Enough to handle the most of the client hellos
static const size_t kInitialBufferLength = 1024;
static const size_t kThroughputBufferLength = 16384;

static const BIO_METHOD* CreateBioMethod();
static const BIO_METHOD* method;

class Buffer {
public:
Buffer(Environment* env, size_t len) : env_(env),
Expand Down Expand Up @@ -153,6 +150,7 @@ class NodeBIO {
Environment* env_;
size_t initial_;
size_t length_;
int eof_return_;
Buffer* read_head_;
Buffer* write_head_;
};
Expand Down
3 changes: 3 additions & 0 deletions test/common/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@ Object.defineProperty(exports, 'localhostIPv4', {
}
});

exports.isOpenSSL10 = !!process.versions.openssl.match(/^1\.0\./);
exports.needNoRandScreen = exports.isOpenSSL10 && exports.isWindows;

// opensslCli defined lazily to reduce overhead of spawnSync
Object.defineProperty(exports, 'opensslCli', {get: function() {
if (opensslCli !== null) return opensslCli;
Expand Down
12 changes: 10 additions & 2 deletions test/parallel/test-crypto.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ if (!common.hasCrypto) {
return;
}

const isOpenSSL10 = common.isOpenSSL10;

const assert = require('assert');
const crypto = require('crypto');
const fs = require('fs');
Expand Down Expand Up @@ -105,7 +107,9 @@ validateList(tlsCiphers);
// Assert that we have sha and sha1 but not SHA and SHA1.
assert.notStrictEqual(0, crypto.getHashes().length);
assert(crypto.getHashes().includes('sha1'));
assert(crypto.getHashes().includes('sha'));
if (isOpenSSL10)
assert(crypto.getHashes().includes('sha'));

assert(!crypto.getHashes().includes('SHA1'));
assert(!crypto.getHashes().includes('SHA'));
assert(crypto.getHashes().includes('RSA-SHA1'));
Expand Down Expand Up @@ -167,6 +171,10 @@ assert.throws(function() {
crypto.createSign('RSA-SHA256').update('test').sign(priv);
}, /digest too big for rsa key$/);

const err_msg = isOpenSSL10 ?
/asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag/ :
/asn1 encoding routines:asn1_check_tlen:wrong tag/;

assert.throws(function() {
// The correct header inside `test_bad_rsa_privkey.pem` should have been
// -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY-----
Expand All @@ -181,7 +189,7 @@ assert.throws(function() {
`${common.fixturesDir}/test_bad_rsa_privkey.pem`, 'ascii');
// this would inject errors onto OpenSSL's error stack
crypto.createSign('sha1').sign(sha1_privateKey);
}, /asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag/);
}, err_msg);

// Make sure memory isn't released before being returned
console.log(crypto.randomBytes(16));
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-https-agent-session-eviction.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function faultyServer(port) {
https.createServer(options, function(req, res) {
res.end('hello faulty');
}).listen(port, function() {
second(this);
common.isOpenSSL10 ? second(this) : forth(this);
});
}

Expand Down
4 changes: 3 additions & 1 deletion test/parallel/test-https-agent-session-reuse.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ const agent = new https.Agent({
maxCachedSessions: 1
});

const ticketSize = common.isOpenSSL10 ? 48 : 80;

const server = https.createServer(options, function(req, res) {
if (req.url === '/drop-key')
server.setTicketKeys(crypto.randomBytes(48));
server.setTicketKeys(crypto.randomBytes(ticketSize));

serverRequests++;
res.end('ok');
Expand Down
Loading

0 comments on commit 8fde1f2

Please sign in to comment.