Commit 1a11939c authored by Jérémy Lal's avatar Jérémy Lal

Backport #16130: support both openssl 1.0.1 and 1.1.0

parent f34b44e5
From 00872a851f9be8fccaed42b8f22f8e2c8f68012b Mon Sep 17 00:00:00 2001
From: David Benjamin <davidben@google.com>
Date: Sat, 23 Sep 2017 03:03:26 -0400
Subject: [PATCH] test: test with a larger RSA key
OpenSSL 1.1.0 rejects RSA keys smaller than 1024 bits by default. Fix
the tests to use larger ones. This test only cares that the PEM blob be
missing a trailing newline. Certificate adapted from
test/fixtures/cert.pem.
PR-URL: https://github.com/nodejs/node/pull/16130
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Rod Vagg <rod@vagg.org>
---
test/parallel/test-tls-cert-regression.js | 48 ++++++++++++++++++++-----------
1 file changed, 31 insertions(+), 17 deletions(-)
diff --git a/test/parallel/test-tls-cert-regression.js b/test/parallel/test-tls-cert-regression.js
index ab967bb2c6e..9329dea9fb1 100644
--- a/test/parallel/test-tls-cert-regression.js
+++ b/test/parallel/test-tls-cert-regression.js
@@ -27,29 +27,43 @@ if (!common.hasCrypto)
const tls = require('tls');
-
const cert =
`-----BEGIN CERTIFICATE-----
-MIIBfjCCASgCCQDmmNjAojbDQjANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB
-VTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0
-cyBQdHkgTHRkMCAXDTE0MDExNjE3NTMxM1oYDzIyODcxMDMxMTc1MzEzWjBFMQsw
-CQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJu
-ZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAPKwlfMX
-6HGZIt1xm7fna72eWcOYfUfSxSugghvqYgJt2Oi3lH+wsU1O9FzRIVmpeIjDXhbp
-Mjsa1HtzSiccPXsCAwEAATANBgkqhkiG9w0BAQUFAANBAHOoKy0NkyfiYH7Ne5ka
-uvCyndyeB4d24FlfqEUlkfaWCZlNKRaV9YhLDiEg3BcIreFo4brtKQfZzTRs0GVm
-KHg=
+MIIDNDCCAp2gAwIBAgIJAJvXLQpGPpm7MA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV
+BAYTAkdCMRAwDgYDVQQIEwdHd3luZWRkMREwDwYDVQQHEwhXYXVuZmF3cjEUMBIG
+A1UEChMLQWNrbmFjayBMdGQxEjAQBgNVBAsTCVRlc3QgQ2VydDESMBAGA1UEAxMJ
+bG9jYWxob3N0MB4XDTA5MTEwMjE5MzMwNVoXDTEwMTEwMjE5MzMwNVowcDELMAkG
+A1UEBhMCR0IxEDAOBgNVBAgTB0d3eW5lZGQxETAPBgNVBAcTCFdhdW5mYXdyMRQw
+EgYDVQQKEwtBY2tuYWNrIEx0ZDESMBAGA1UECxMJVGVzdCBDZXJ0MRIwEAYDVQQD
+Ewlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANdym7nGe2yw
+6LlJfJrQtC5TmKOGrSXiyolYCbGOy4xZI4KD31d3097jhlQFJyF+10gwkE62DuJe
+fLvBZDUsvLe1R8bzlVhZnBVn+3QJyUIWQAL+DsRj8P3KoD7k363QN5dIaA1GOAg2
+vZcPy1HCUsvOgvDXGRUCZqNLAyt+h/cpAgMBAAGjgdUwgdIwHQYDVR0OBBYEFK4s
+VBV4shKUj3UX/fvSJnFaaPBjMIGiBgNVHSMEgZowgZeAFK4sVBV4shKUj3UX/fvS
+JnFaaPBjoXSkcjBwMQswCQYDVQQGEwJHQjEQMA4GA1UECBMHR3d5bmVkZDERMA8G
+A1UEBxMIV2F1bmZhd3IxFDASBgNVBAoTC0Fja25hY2sgTHRkMRIwEAYDVQQLEwlU
+ZXN0IENlcnQxEjAQBgNVBAMTCWxvY2FsaG9zdIIJAJvXLQpGPpm7MAwGA1UdEwQF
+MAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAFxR7BA1mUlsYqPiogtxSIfLzHWh+s0bJ
+SBuhNrHes4U8QxS8+x/KWjd/81gzsf9J1C2VzTlFaydAgigz3SkQYgs+TMnFkT2o
+9jqoJrcdf4WpZ2DQXUALaZgwNzPumMUSx8Ac5gO+BY/RHyP6fCodYvdNwyKslnI3
+US7eCSHZsVo=
-----END CERTIFICATE-----`;
const key =
`-----BEGIN RSA PRIVATE KEY-----
-MIIBPQIBAAJBAPKwlfMX6HGZIt1xm7fna72eWcOYfUfSxSugghvqYgJt2Oi3lH+w
-sU1O9FzRIVmpeIjDXhbpMjsa1HtzSiccPXsCAwEAAQJBAM4uU9aJE0OfdE1p/X+K
-LrCT3XMdFCJ24GgmHyOURtwDy18upQJecDVdcZp16fjtOPmaW95GoYRyifB3R4I5
-RxECIQD7jRM9slCSVV8xp9kOJQNpHjhRQYVGBn+pyllS2sb+RQIhAPb7Y+BIccri
-NWnuhwCW8hA7Fkj/kaBdAwyW7L3Tvui/AiEAiqLCovMecre4Yi6GcsQ1b/6mvSmm
-IOS+AT6zIfXPTB0CIQCJKGR3ymN/Qw5crL1GQ41cHCQtF9ickOq/lBUW+j976wIh
-AOaJnkQrmurlRdePX6LvN/LgGAQoxwovfjcOYNnZsIVY
+MIICXgIBAAKBgQDXcpu5xntssOi5SXya0LQuU5ijhq0l4sqJWAmxjsuMWSOCg99X
+d9Pe44ZUBSchftdIMJBOtg7iXny7wWQ1LLy3tUfG85VYWZwVZ/t0CclCFkAC/g7E
+Y/D9yqA+5N+t0DeXSGgNRjgINr2XD8tRwlLLzoLw1xkVAmajSwMrfof3KQIDAQAB
+AoGBAIBHR/tT93ce2mJAJAXV0AJpWc+7x2pwX2FpXtQujnlxNZhnRlrBCRCD7h4m
+t0bVS/86kyGaesBDvAbavfx/N5keYzzmmSp5Ht8IPqKPydGWdigk4x90yWvktai7
+dWuRKF94FXr0GUuBONb/dfHdp4KBtzN7oIF9WydYGGXA9ZmBAkEA8/k01bfwQZIu
+AgcdNEM94Zcug1gSspXtUu8exNQX4+PNVbadghZb1+OnUO4d3gvWfqvAnaXD3KV6
+N4OtUhQQ0QJBAOIRbKMfaymQ9yE3CQQxYfKmEhHXWARXVwuYqIFqjmhSjSXx0l/P
+7mSHz1I9uDvxkJev8sQgu1TKIyTOdqPH1tkCQQDPa6H1yYoj1Un0Q2Qa2Mg1kTjk
+Re6vkjPQ/KcmJEOjZjtekgFbZfLzmwLXFXqjG2FjFFaQMSxR3QYJSJQEYjbhAkEA
+sy7OZcjcXnjZeEkv61Pc57/7qIp/6Aj2JGnefZ1gvI1Z9Q5kCa88rA/9Iplq8pA4
+ZBKAoDW1ZbJGAsFmxc/6mQJAdPilhci0qFN86IGmf+ZBnwsDflIwHKDaVofti4wQ
+sPWhSOb9VQjMXekI4Y2l8fqAVTS2Fn6+8jkVKxXBywSVCw==
-----END RSA PRIVATE KEY-----`;
function test(cert, key, cb) {
From 00a55e62877faab053dbbe1178488f7cf8dee466 Mon Sep 17 00:00:00 2001
From: David Benjamin <davidben@google.com>
Date: Sat, 23 Sep 2017 00:16:52 -0400
Subject: [PATCH] test: remove sha from test expectations
"sha" in OpenSSL refers to SHA-0 which was removed from OpenSSL 1.1.0
and is insecure. Replace it with SHA-256 which is present in both 1.0.2
and 1.1.0. Short of shipping a reimplementation in Node, this is an
unavoidable behavior change with 1.1.0.
PR-URL: https://github.com/nodejs/node/pull/16130
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Rod Vagg <rod@vagg.org>
---
test/parallel/test-crypto.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/test/parallel/test-crypto.js
+++ b/test/parallel/test-crypto.js
@@ -101,12 +101,12 @@
assert(tlsCiphers.every((value) => noCapitals.test(value)));
validateList(tlsCiphers);
-// Assert that we have sha and sha1 but not SHA and SHA1.
+// Assert that we have sha1 and sha256 but not SHA1 and SHA256.
assert.notStrictEqual(0, crypto.getHashes().length);
assert(crypto.getHashes().includes('sha1'));
-assert(crypto.getHashes().includes('sha'));
+assert(crypto.getHashes().includes('sha256'));
assert(!crypto.getHashes().includes('SHA1'));
-assert(!crypto.getHashes().includes('SHA'));
+assert(!crypto.getHashes().includes('SHA256'));
assert(crypto.getHashes().includes('RSA-SHA1'));
assert(!crypto.getHashes().includes('rsa-sha1'));
validateList(crypto.getHashes());
From 0f842f500eb7e117428e2227482f864ae72f58f0 Mon Sep 17 00:00:00 2001
From: David Benjamin <davidben@google.com>
Date: Sat, 16 Sep 2017 03:16:17 -0400
Subject: [PATCH] crypto: remove unnecessary SSLerr calls
These are OpenSSL-internal APIs that are no longer accessible in 1.1.0
and weren't necessary. OpenSSL will push its own errors and, if it
doesn't, the calling code would handle it anyway.
PR-URL: https://github.com/nodejs/node/pull/16130
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Rod Vagg <rod@vagg.org>
---
src/node_crypto.cc | 2 --
1 file changed, 2 deletions(-)
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -616,7 +616,6 @@
x = PEM_read_bio_X509_AUX(in, nullptr, NoPasswordCallback, nullptr);
if (x == nullptr) {
- SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
return 0;
}
@@ -627,7 +626,6 @@
// Read extra certs
STACK_OF(X509)* extra_certs = sk_X509_new_null();
if (extra_certs == nullptr) {
- SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_MALLOC_FAILURE);
goto done;
}
From 146e8f8340d2b6b4fc08e235f522a53848d01290 Mon Sep 17 00:00:00 2001
From: David Benjamin <davidben@google.com>
Date: Wed, 20 Sep 2017 18:54:30 -0400
Subject: [PATCH] crypto: make CipherBase 1.1.0-compatible
In OpenSSL 1.1.0, EVP_CIPHER_CTX must be heap-allocated. Once we're
heap-allocating them, there's no need in a separate initialised_ bit.
The presence of ctx_ is sufficient.
PR-URL: https://github.com/nodejs/node/pull/16130
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Rod Vagg <rod@vagg.org>
---
src/node_crypto.cc | 72 +++++++++++++++++++++++++++---------------------------
src/node_crypto.h | 11 +++------
2 files changed, 39 insertions(+), 44 deletions(-)
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -3415,7 +3415,7 @@
}
#endif // NODE_FIPS_MODE
- CHECK_EQ(initialised_, false);
+ CHECK_EQ(ctx_, nullptr);
const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
if (cipher == nullptr) {
return env()->ThrowError("Unknown cipher");
@@ -3433,21 +3433,20 @@
key,
iv);
- EVP_CIPHER_CTX_init(&ctx_);
+ ctx_ = EVP_CIPHER_CTX_new();
const bool encrypt = (kind_ == kCipher);
- EVP_CipherInit_ex(&ctx_, cipher, nullptr, nullptr, nullptr, encrypt);
- if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
- EVP_CIPHER_CTX_cleanup(&ctx_);
+ EVP_CipherInit_ex(ctx_, cipher, nullptr, nullptr, nullptr, encrypt);
+ if (!EVP_CIPHER_CTX_set_key_length(ctx_, key_len)) {
+ EVP_CIPHER_CTX_free(ctx_);
return env()->ThrowError("Invalid key length");
}
- EVP_CipherInit_ex(&ctx_,
+ EVP_CipherInit_ex(ctx_,
nullptr,
nullptr,
reinterpret_cast<unsigned char*>(key),
reinterpret_cast<unsigned char*>(iv),
kind_ == kCipher);
- initialised_ = true;
}
@@ -3489,28 +3488,27 @@
return env()->ThrowError("Invalid IV length");
}
- EVP_CIPHER_CTX_init(&ctx_);
+ ctx_ = EVP_CIPHER_CTX_new();
const bool encrypt = (kind_ == kCipher);
- EVP_CipherInit_ex(&ctx_, cipher, nullptr, nullptr, nullptr, encrypt);
+ EVP_CipherInit_ex(ctx_, cipher, nullptr, nullptr, nullptr, encrypt);
if (is_gcm_mode &&
- !EVP_CIPHER_CTX_ctrl(&ctx_, EVP_CTRL_GCM_SET_IVLEN, iv_len, nullptr)) {
- EVP_CIPHER_CTX_cleanup(&ctx_);
+ !EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_GCM_SET_IVLEN, iv_len, nullptr)) {
+ EVP_CIPHER_CTX_free(ctx_);
return env()->ThrowError("Invalid IV length");
}
- if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
- EVP_CIPHER_CTX_cleanup(&ctx_);
+ if (!EVP_CIPHER_CTX_set_key_length(ctx_, key_len)) {
+ EVP_CIPHER_CTX_free(ctx_);
return env()->ThrowError("Invalid key length");
}
- EVP_CipherInit_ex(&ctx_,
+ EVP_CipherInit_ex(ctx_,
nullptr,
nullptr,
reinterpret_cast<const unsigned char*>(key),
reinterpret_cast<const unsigned char*>(iv),
kind_ == kCipher);
- initialised_ = true;
}
@@ -3538,8 +3536,8 @@
bool CipherBase::IsAuthenticatedMode() const {
// Check if this cipher operates in an AEAD mode that we support.
- CHECK_EQ(initialised_, true);
- const EVP_CIPHER* const cipher = EVP_CIPHER_CTX_cipher(&ctx_);
+ CHECK_NE(ctx_, nullptr);
+ const EVP_CIPHER* const cipher = EVP_CIPHER_CTX_cipher(ctx_);
int mode = EVP_CIPHER_mode(cipher);
return mode == EVP_CIPH_GCM_MODE;
}
@@ -3551,7 +3549,7 @@
ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
// Only callable after Final and if encrypting.
- if (cipher->initialised_ ||
+ if (cipher->ctx_ != nullptr ||
cipher->kind_ != kCipher ||
cipher->auth_tag_len_ == 0) {
return env->ThrowError("Attempting to get auth tag in unsupported state");
@@ -3572,7 +3570,7 @@
CipherBase* cipher;
ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
- if (!cipher->initialised_ ||
+ if (cipher->ctx_ == nullptr ||
!cipher->IsAuthenticatedMode() ||
cipher->kind_ != kDecipher) {
return env->ThrowError("Attempting to set auth tag in unsupported state");
@@ -3590,10 +3588,10 @@
bool CipherBase::SetAAD(const char* data, unsigned int len) {
- if (!initialised_ || !IsAuthenticatedMode())
+ if (ctx_ == nullptr || !IsAuthenticatedMode())
return false;
int outlen;
- if (!EVP_CipherUpdate(&ctx_,
+ if (!EVP_CipherUpdate(ctx_,
nullptr,
&outlen,
reinterpret_cast<const unsigned char*>(data),
@@ -3621,21 +3619,21 @@
int len,
unsigned char** out,
int* out_len) {
- if (!initialised_)
+ if (ctx_ == nullptr)
return 0;
// on first update:
if (kind_ == kDecipher && IsAuthenticatedMode() && auth_tag_len_ > 0) {
- EVP_CIPHER_CTX_ctrl(&ctx_,
+ EVP_CIPHER_CTX_ctrl(ctx_,
EVP_CTRL_GCM_SET_TAG,
auth_tag_len_,
reinterpret_cast<unsigned char*>(auth_tag_));
auth_tag_len_ = 0;
}
- *out_len = len + EVP_CIPHER_CTX_block_size(&ctx_);
+ *out_len = len + EVP_CIPHER_CTX_block_size(ctx_);
*out = Malloc<unsigned char>(static_cast<size_t>(*out_len));
- return EVP_CipherUpdate(&ctx_,
+ return EVP_CipherUpdate(ctx_,
*out,
out_len,
reinterpret_cast<const unsigned char*>(data),
@@ -3683,9 +3681,9 @@
bool CipherBase::SetAutoPadding(bool auto_padding) {
- if (!initialised_)
+ if (ctx_ == nullptr)
return false;
- return EVP_CIPHER_CTX_set_padding(&ctx_, auto_padding);
+ return EVP_CIPHER_CTX_set_padding(ctx_, auto_padding);
}
@@ -3701,22 +3699,22 @@
bool CipherBase::Final(unsigned char** out, int *out_len) {
- if (!initialised_)
+ if (ctx_ == nullptr)
return false;
*out = Malloc<unsigned char>(
- static_cast<size_t>(EVP_CIPHER_CTX_block_size(&ctx_)));
- int r = EVP_CipherFinal_ex(&ctx_, *out, out_len);
+ static_cast<size_t>(EVP_CIPHER_CTX_block_size(ctx_)));
+ int r = EVP_CipherFinal_ex(ctx_, *out, out_len);
if (r == 1 && kind_ == kCipher && IsAuthenticatedMode()) {
auth_tag_len_ = sizeof(auth_tag_);
- r = EVP_CIPHER_CTX_ctrl(&ctx_, EVP_CTRL_GCM_GET_TAG, auth_tag_len_,
+ r = EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_GCM_GET_TAG, auth_tag_len_,
reinterpret_cast<unsigned char*>(auth_tag_));
CHECK_EQ(r, 1);
}
- EVP_CIPHER_CTX_cleanup(&ctx_);
- initialised_ = false;
+ EVP_CIPHER_CTX_free(ctx_);
+ ctx_ = nullptr;
return r == 1;
}
@@ -3727,7 +3725,7 @@
CipherBase* cipher;
ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
- if (!cipher->initialised_) return env->ThrowError("Unsupported state");
+ if (cipher->ctx_ == nullptr) return env->ThrowError("Unsupported state");
unsigned char* out_value = nullptr;
int out_len = -1;
--- a/src/node_crypto.h
+++ b/src/node_crypto.h
@@ -53,8 +53,6 @@
#include <openssl/rand.h>
#include <openssl/pkcs12.h>
-#define EVP_F_EVP_DECRYPTFINAL 101
-
#if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb)
# define NODE__HAVE_TLSEXT_STATUS_CB
#endif // !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb)
@@ -444,9 +442,7 @@
class CipherBase : public BaseObject {
public:
~CipherBase() override {
- if (!initialised_)
- return;
- EVP_CIPHER_CTX_cleanup(&ctx_);
+ EVP_CIPHER_CTX_free(ctx_);
}
static void Initialize(Environment* env, v8::Local<v8::Object> target);
@@ -485,15 +481,14 @@
v8::Local<v8::Object> wrap,
CipherKind kind)
: BaseObject(env, wrap),
- initialised_(false),
+ ctx_(nullptr),
kind_(kind),
auth_tag_len_(0) {
MakeWeak<CipherBase>(this);
}
private:
- EVP_CIPHER_CTX ctx_; /* coverity[member_decl] */
- bool initialised_;
+ EVP_CIPHER_CTX* ctx_;
const CipherKind kind_;
unsigned int auth_tag_len_;
char auth_tag_[EVP_GCM_TLS_TAG_LEN];
From 2b28d6cfacfd0ddd7ff97536152f4ad895bf4120 Mon Sep 17 00:00:00 2001
From: David Benjamin <davidben@google.com>
Date: Fri, 22 Sep 2017 18:51:21 -0400
Subject: [PATCH] crypto: make Hash 1.1.0-compatible
OpenSSL 1.1.0 requires EVP_MD_CTX be heap-allocated.
PR-URL: https://github.com/nodejs/node/pull/16130
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Rod Vagg <rod@vagg.org>
---
src/node_crypto.cc | 23 ++++++++++++++++-------
src/node_crypto.h | 12 ++++--------
2 files changed, 20 insertions(+), 15 deletions(-)
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -207,6 +207,9 @@
CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
return 1;
}
+
+#define EVP_MD_CTX_new EVP_MD_CTX_create
+#define EVP_MD_CTX_free EVP_MD_CTX_destroy
#endif // OPENSSL_VERSION_NUMBER < 0x10100000L
// Subject DER of CNNIC ROOT CA and CNNIC EV ROOT CA are taken from
@@ -3890,6 +3893,11 @@
}
+Hash::~Hash() {
+ EVP_MD_CTX_free(mdctx_);
+}
+
+
void Hash::Initialize(Environment* env, v8::Local<v8::Object> target) {
Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
@@ -3924,20 +3932,22 @@
const EVP_MD* md = EVP_get_digestbyname(hash_type);
if (md == nullptr)
return false;
- EVP_MD_CTX_init(&mdctx_);
- if (EVP_DigestInit_ex(&mdctx_, md, nullptr) <= 0) {
+ mdctx_ = EVP_MD_CTX_new();
+ if (mdctx_ == nullptr ||
+ EVP_DigestInit_ex(mdctx_, md, nullptr) <= 0) {
+ EVP_MD_CTX_free(mdctx_);
+ mdctx_ = nullptr;
return false;
}
- initialised_ = true;
finalized_ = false;
return true;
}
bool Hash::HashUpdate(const char* data, int len) {
- if (!initialised_)
+ if (mdctx_ == nullptr)
return false;
- EVP_DigestUpdate(&mdctx_, data, len);
+ EVP_DigestUpdate(mdctx_, data, len);
return true;
}
@@ -4002,8 +4012,7 @@
unsigned char md_value[EVP_MAX_MD_SIZE];
unsigned int md_len;
- EVP_DigestFinal_ex(&hash->mdctx_, md_value, &md_len);
- EVP_MD_CTX_cleanup(&hash->mdctx_);
+ EVP_DigestFinal_ex(hash->mdctx_, md_value, &md_len);
hash->finalized_ = true;
Local<Value> error;
--- a/src/node_crypto.h
+++ b/src/node_crypto.h
@@ -526,11 +526,7 @@
class Hash : public BaseObject {
public:
- ~Hash() override {
- if (!initialised_)
- return;
- EVP_MD_CTX_cleanup(&mdctx_);
- }
+ ~Hash() override;
static void Initialize(Environment* env, v8::Local<v8::Object> target);
@@ -544,13 +540,13 @@
Hash(Environment* env, v8::Local<v8::Object> wrap)
: BaseObject(env, wrap),
- initialised_(false) {
+ mdctx_(nullptr),
+ finalized_(false) {
MakeWeak<Hash>(this);
}
private:
- EVP_MD_CTX mdctx_; /* coverity[member_decl] */
- bool initialised_;
+ EVP_MD_CTX* mdctx_;
bool finalized_;
};
From 560f79777606363a6d31896e0fe5744a45302ff5 Mon Sep 17 00:00:00 2001
From: David Benjamin <davidben@google.com>
Date: Sat, 21 Oct 2017 13:29:18 -0400
Subject: [PATCH] crypto: deprecate {ecdhCurve: false}
This doesn't work in OpenSSL 1.1.0. Per discussion on the PR, it is
preferable to just deprecate this setting. Deprecate it and skip the
test in OpenSSL 1.1.0.
PR-URL: https://github.com/nodejs/node/pull/16130
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Rod Vagg <rod@vagg.org>
---
doc/api/deprecations.md | 10 ++++++++++
lib/_tls_common.js | 12 ++++++++++++
test/parallel/test-tls-ecdh-disable.js | 8 ++++++++
3 files changed, 30 insertions(+)
--- a/doc/api/deprecations.md
+++ b/doc/api/deprecations.md
@@ -694,3 +694,14 @@
[alloc_unsafe_size]: buffer.html#buffer_class_method_buffer_allocunsafe_size
[from_arraybuffer]: buffer.html#buffer_class_method_buffer_from_arraybuffer_byteoffset_length
[from_string_encoding]: buffer.html#buffer_class_method_buffer_from_string_encoding
+
+<a id="DEP0083"></a>
+### DEP0083: Disabling ECDH by setting ecdhCurve to false
+
+Type: Runtime
+
+The `ecdhCurve` option to `tls.createSecureContext()` and `tls.TLSSocket` could
+be set to `false` to disable ECDH entirely on the server only. This mode is
+deprecated in preparation for migrating to OpenSSL 1.1.0 and consistency with
+the client. Use the `ciphers` parameter instead.
+
--- a/lib/_tls_common.js
+++ b/lib/_tls_common.js
@@ -55,6 +55,16 @@
exports.SecureContext = SecureContext;
+function ecdhCurveWarning() {
+ if (ecdhCurveWarning.emitted) return;
+ process.emitWarning('{ ecdhCurve: false } is deprecated.',
+ 'DeprecationWarning',
+ 'DEP0083');
+ ecdhCurveWarning.emitted = true;
+}
+ecdhCurveWarning.emitted = false;
+
+
exports.createSecureContext = function createSecureContext(options, context) {
if (!options) options = {};
@@ -115,6 +125,8 @@
c.context.setECDHCurve(tls.DEFAULT_ECDH_CURVE);
else if (options.ecdhCurve)
c.context.setECDHCurve(options.ecdhCurve);
+ else
+ ecdhCurveWarning();
if (options.dhparam) {
const warning = c.context.setDHParam(options.dhparam);
--- a/test/parallel/test-tls-ecdh-disable.js
+++ b/test/parallel/test-tls-ecdh-disable.js
@@ -27,6 +27,11 @@
if (!common.opensslCli)
common.skip('missing openssl-cli');
+const OPENSSL_VERSION_NUMBER =
+ require('crypto').constants.OPENSSL_VERSION_NUMBER;
+if (OPENSSL_VERSION_NUMBER >= 0x10100000)
+ common.skip('false ecdhCurve not supported in OpenSSL 1.1.0');
+
const assert = require('assert');
const tls = require('tls');
const exec = require('child_process').exec;
@@ -39,6 +44,9 @@
ecdhCurve: false
};
+common.expectWarning('DeprecationWarning',
+ '{ ecdhCurve: false } is deprecated.');
+
const server = tls.createServer(options, common.mustNotCall());
server.listen(0, '127.0.0.1', common.mustCall(function() {
From 594ef761d1c583a8ef6e49876a4a57aec4b62394 Mon Sep 17 00:00:00 2001
From: David Benjamin <davidben@google.com>
Date: Fri, 22 Sep 2017 20:14:25 -0400
Subject: [PATCH] crypto: add compat logic for "DSS1" and "dss1"
In OpenSSL 1.1.0, EVP_dss1() is removed. These hash names were exposed
in Node's public API, so add compatibility hooks for them.
PR-URL: https://github.com/nodejs/node/pull/16130
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Rod Vagg <rod@vagg.org>
---
src/node_crypto.cc | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -4059,6 +4059,14 @@
SignBase::Error SignBase::Init(const char* sign_type) {
CHECK_EQ(mdctx_, nullptr);
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ // Historically, "dss1" and "DSS1" were DSA aliases for SHA-1
+ // exposed through the public API.
+ if (strcmp(sign_type, "dss1") == 0 ||
+ strcmp(sign_type, "DSS1") == 0) {
+ sign_type = "SHA1";
+ }
+#endif
const EVP_MD* md = EVP_get_digestbyname(sign_type);
if (md == nullptr)
return kSignUnknownDigest;
From 5d94712b859339d48b3eb2d3bdd00d04d66f6160 Mon Sep 17 00:00:00 2001
From: David Benjamin <davidben@google.com>
Date: Fri, 15 Sep 2017 20:09:43 -0400
Subject: [PATCH] crypto: estimate kExternalSize
Based on a build of OpenSSL 1.1.0f.
The exact sizes are not particularly important (the original value was
missing all the objects hanging off anyway), only that V8 garbage
collector be aware that there is some memory usage beyond the sockets
themselves.
PR-URL: https://github.com/nodejs/node/pull/16130
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Rod Vagg <rod@vagg.org>
---
src/node_crypto.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
--- a/src/node_crypto.h
+++ b/src/node_crypto.h
@@ -108,7 +108,13 @@
static const int kTicketKeyIVIndex = 4;
protected:
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
static const int64_t kExternalSize = sizeof(SSL_CTX);
+#else
+ // OpenSSL 1.1.0 has opaque structures. This is an estimate based on the size
+ // as of OpenSSL 1.1.0f.
+ static const int64_t kExternalSize = 872;
+#endif
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Init(const v8::FunctionCallbackInfo<v8::Value>& args);
@@ -222,11 +228,17 @@
protected:
typedef void (*CertCb)(void* arg);
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
// Size allocated by OpenSSL: one for SSL structure, one for SSL3_STATE and
// some for buffers.
// NOTE: Actually it is much more than this
static const int64_t kExternalSize =
sizeof(SSL) + sizeof(SSL3_STATE) + 42 * 1024;
+#else
+ // OpenSSL 1.1.0 has opaque structures. This is an estimate based on the size
+ // as of OpenSSL 1.1.0f.
+ static const int64_t kExternalSize = 4448 + 1024 + 42 * 1024;
+#endif
static void InitNPN(SecureContext* sc);
static void AddMethods(Environment* env, v8::Local<v8::FunctionTemplate> t);
From 5fe81c8aff03261f6443580dbc08f608013718c6 Mon Sep 17 00:00:00 2001
From: David Benjamin <davidben@google.com>
Date: Sat, 23 Sep 2017 00:35:33 -0400
Subject: [PATCH] crypto: hard-code tlsSocket.getCipher().version
This aligns the documentation with reality. This API never did what Node
claims it did.
The SSL_CIPHER_get_version function just isn't useful. In OpenSSL 1.0.2,
it always returned the string "TLSv1/SSLv3" for anything but SSLv2
ciphers, which Node does not support. Note how test-tls-multi-pfx.js
claims that ECDHE-ECDSA-AES256-GCM-SHA384 was added in TLSv1/SSLv3 which
is not true. That cipher is new as of TLS 1.2. The OpenSSL 1.0.2
implementation is:
char *SSL_CIPHER_get_version(const SSL_CIPHER *c)
{
int i;
if (c == NULL)
return ("(NONE)");
i = (int)(c->id >> 24L);
if (i == 3)
return ("TLSv1/SSLv3");
else if (i == 2)
return ("SSLv2");
else
return ("unknown");
} <