Update, remove old patches, add http2 support

This commit is contained in:
Zuzana Svetlikova 2017-08-16 15:36:43 +02:00
parent 084cd602c3
commit e8fe25864b
7 changed files with 17 additions and 835 deletions

1
.gitignore vendored
View File

@ -74,3 +74,4 @@
/node-v8.2.0-stripped.tar.gz
/node-v8.2.1-stripped.tar.gz
/node-v8.3.0-stripped.tar.gz
/node-v8.4.0-stripped.tar.gz

View File

@ -1,648 +0,0 @@
From 91d1a67b8cc249af59929cd1a76629a2614860bd Mon Sep 17 00:00:00 2001
From: Haikel Guemar <hguemar@fedoraproject.org>
Date: Tue, 26 Jul 2016 22:50:22 +0200
Subject: [PATCH 2/4] Use openssl 1.0.1
Based on Solaris patches from upstream #2783
https://github.com/nodejs/node/issues/2783
---
doc/api/tls.md | 6 ++
src/node_constants.cc | 5 ++
src/node_crypto.cc | 201 ++++++++++++++++++++++++++++++++++++++++++++++----
src/node_crypto.h | 16 ++++
src/tls_wrap.cc | 8 ++
5 files changed, 223 insertions(+), 13 deletions(-)
diff --git a/doc/api/tls.md b/doc/api/tls.md
index 3784210ba7b6c046b39d74b45e44538041d35ae2..3c9d72b8d5ef81d15773aed077bd00d2041c9e93 100644
--- a/doc/api/tls.md
+++ b/doc/api/tls.md
@@ -113,10 +113,16 @@ handshake extensions:
* ALPN/NPN - Allows the use of one TLS server for multiple protocols (HTTP,
SPDY, HTTP/2)
* SNI - Allows the use of one TLS server for multiple hostnames with different
SSL certificates.
+ **NOTE**: dueto a design flaw in node **SNI cannot be
+ used on the server side**, even so all parameters in related functions are
+ accepted for compatibility reasons. And thus the related events will not
+ fire unless one aranges this explicitly. This may change, when the OS
+ provides OpenSSL v1.0.2 or better and node gets linked to this version.
+
*Note*: Use of ALPN is recommended over NPN. The NPN extension has never been
formally defined or documented and generally not recommended for use.
### Client-initiated renegotiation attack mitigation
diff --git a/src/node_constants.cc b/src/node_constants.cc
index 2e6be8df37c345a383d8a78898daf2a147d90630..239eadbac8ea8e601745a63347a8bb301c22d1b1 100644
--- a/src/node_constants.cc
+++ b/src/node_constants.cc
@@ -12,11 +12,14 @@
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#if HAVE_OPENSSL
+# include <openssl/opensslconf.h>
+# ifndef OPENSSL_NO_EC
# include <openssl/ec.h>
+# endif
# include <openssl/ssl.h>
# ifndef OPENSSL_NO_ENGINE
# include <openssl/engine.h>
# endif // !OPENSSL_NO_ENGINE
#endif
@@ -974,16 +977,18 @@ void DefineOpenSSLConstants(Local<Object> target) {
NODE_DEFINE_CONSTANT(target, RSA_PKCS1_PSS_PADDING);
#endif
#if HAVE_OPENSSL
// NOTE: These are not defines
+# ifndef OPENSSL_NO_EC
NODE_DEFINE_CONSTANT(target, POINT_CONVERSION_COMPRESSED);
NODE_DEFINE_CONSTANT(target, POINT_CONVERSION_UNCOMPRESSED);
NODE_DEFINE_CONSTANT(target, POINT_CONVERSION_HYBRID);
#endif
+#endif
}
void DefineSystemConstants(Local<Object> target) {
// file access modes
NODE_DEFINE_CONSTANT(target, O_RDONLY);
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index 482ec230c0f4500b63b705d705a142e63ff179e5..c5630f30d0bef75ced53b36062bb1f0324dbdb9d 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -22,10 +22,86 @@
#include <limits.h> // INT_MAX
#include <math.h>
#include <stdlib.h>
#include <string.h>
+#ifndef SSL_get_server_tmp_key
+/*
+ 1.0.2 SSL_get_server_tmp_key(s, pk) "backport". BAD HACK!!!
+ NOTE: This imports "foreign" knowledge and thus will break, when SESS_CERT
+ or CERT_PKEY change, which is definitely the case for the later for
+ all OpenSSL lib vers != 1.0.1. So don't try to bind to something else!
+ */
+# define SSL_PKEY_NUM 8
+typedef struct cert_pkey_st {
+ X509 *x509;
+ EVP_PKEY *privatekey;
+ /* Digest to use when signing */
+ const EVP_MD *digest;
+} CERT_PKEY;
+
+typedef struct sess_cert_st {
+ STACK_OF(X509) *cert_chain; /* as received from peer (not for SSL2) */
+ /* The 'peer_...' members are used only by clients. */
+ int peer_cert_type;
+ CERT_PKEY *peer_key; /* points to an element of peer_pkeys (never
+ * NULL!) */
+ CERT_PKEY peer_pkeys[SSL_PKEY_NUM];
+ /*
+ * Obviously we don't have the private keys of these, so maybe we
+ * shouldn't even use the CERT_PKEY type here.
+ */
+# ifndef OPENSSL_NO_RSA
+ RSA *peer_rsa_tmp; /* not used for SSL 2 */
+# endif
+# ifndef OPENSSL_NO_DH
+ DH *peer_dh_tmp; /* not used for SSL 2 */
+# endif
+# ifndef OPENSSL_NO_ECDH
+ EC_KEY *peer_ecdh_tmp;
+# endif
+ int references; /* actually always 1 at the moment */
+} SESS_CERT;
+
+static long SSL_get_server_tmp_key(SSL *s, void *parg) {
+ if (s->server || !s->session || !s->session->sess_cert)
+ return 0;
+ else {
+ SESS_CERT *sc;
+ EVP_PKEY *ptmp;
+ int rv = 0;
+ sc = s->session->sess_cert;
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDH)
+ if (!sc->peer_rsa_tmp && !sc->peer_dh_tmp && !sc->peer_ecdh_tmp)
+ return 0;
+#endif
+ ptmp = EVP_PKEY_new();
+ if (!ptmp)
+ return 0;
+ if (0) ;
+#ifndef OPENSSL_NO_RSA
+ else if (sc->peer_rsa_tmp)
+ rv = EVP_PKEY_set1_RSA(ptmp, sc->peer_rsa_tmp);
+#endif
+#ifndef OPENSSL_NO_DH
+ else if (sc->peer_dh_tmp)
+ rv = EVP_PKEY_set1_DH(ptmp, sc->peer_dh_tmp);
+#endif
+#ifndef OPENSSL_NO_ECDH
+ else if (sc->peer_ecdh_tmp)
+ rv = EVP_PKEY_set1_EC_KEY(ptmp, sc->peer_ecdh_tmp);
+#endif
+ if (rv) {
+ *(EVP_PKEY **)parg = ptmp;
+ return 1;
+ }
+ EVP_PKEY_free(ptmp);
+ return 0;
+ }
+}
+#endif /* SSL_get_server_tmp_key */
+
#define THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(val, prefix) \
do { \
if (!Buffer::HasInstance(val) && !val->IsString()) { \
return env->ThrowTypeError(prefix " must be a string or a buffer"); \
} \
@@ -161,11 +237,15 @@ template int SSLWrap<TLSWrap>::SelectNextProtoCallback(
#ifdef NODE__HAVE_TLSEXT_STATUS_CB
template int SSLWrap<TLSWrap>::TLSExtStatusCallback(SSL* s, void* arg);
#endif
template void SSLWrap<TLSWrap>::DestroySSL();
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
template int SSLWrap<TLSWrap>::SSLCertCallback(SSL* s, void* arg);
+#else
+template int SSLWrap<TLSWrap>::SSLCertCallback(SSL* s, X509 **x509, EVP_PKEY **pkey);
+#endif
template void SSLWrap<TLSWrap>::WaitForCertCb(CertCb cb, void* arg);
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
template int SSLWrap<TLSWrap>::SelectALPNCallback(
SSL* s,
@@ -281,12 +361,16 @@ void SecureContext::Initialize(Environment* env, Local<Object> target) {
env->SetProtoMethod(t, "setCert", SecureContext::SetCert);
env->SetProtoMethod(t, "addCACert", SecureContext::AddCACert);
env->SetProtoMethod(t, "addCRL", SecureContext::AddCRL);
env->SetProtoMethod(t, "addRootCerts", SecureContext::AddRootCerts);
env->SetProtoMethod(t, "setCiphers", SecureContext::SetCiphers);
+#ifndef OPENSSL_NO_ECDH
env->SetProtoMethod(t, "setECDHCurve", SecureContext::SetECDHCurve);
+#endif
+#ifndef OPENSSL_NO_DH
env->SetProtoMethod(t, "setDHParam", SecureContext::SetDHParam);
+#endif
env->SetProtoMethod(t, "setOptions", SecureContext::SetOptions);
env->SetProtoMethod(t, "setSessionIdContext",
SecureContext::SetSessionIdContext);
env->SetProtoMethod(t, "setSessionTimeout",
SecureContext::SetSessionTimeout);
@@ -514,12 +598,24 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
SSL_CTX_clear_extra_chain_certs(ctx);
for (int i = 0; i < sk_X509_num(extra_certs); i++) {
X509* ca = sk_X509_value(extra_certs, i);
- // NOTE: Increments reference count on `ca`
- r = SSL_CTX_add1_chain_cert(ctx, ca);
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+ // If ctx->cert->key != NULL create ctx->cert->key->chain if not
+ // already there, push 'ca' to this chain and finally increment the ca
+ // reference count by 1 (this is the diff between *_add1_* and *_add0_*
+ // - the later increments by 0 ;-)) and return 1. Otherwise or if
+ // something fails in between, return 0.
+ r = SSL_CTX_add1_chain_cert(ctx, ca);
+#else
+ // Create ctx->extra_certs if not already there, just push 'ca' to this
+ // chain and return 1. If something fails, return 0.
+ // NOTE: 1.0.1- does not support multiple certs having its own chain in
+ // a single context. There is just one: extra_chain!
+ r = SSL_CTX_add_extra_chain_cert(ctx, ca);
+#endif
if (!r) {
ret = 0;
*issuer = nullptr;
goto end;
@@ -868,10 +964,11 @@ void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
const node::Utf8Value ciphers(args.GetIsolate(), args[0]);
SSL_CTX_set_cipher_list(sc->ctx_, *ciphers);
}
+#ifndef OPENSSL_NO_ECDH
void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
SecureContext* sc;
ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
Environment* env = sc->env();
@@ -895,12 +992,14 @@ void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_ECDH_USE);
SSL_CTX_set_tmp_ecdh(sc->ctx_, ecdh);
EC_KEY_free(ecdh);
}
+#endif
+#ifndef OPENSSL_NO_DH
void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
SecureContext* sc;
ASSIGN_OR_RETURN_UNWRAP(&sc, args.This());
Environment* env = sc->env();
ClearErrorOnReturn clear_error_on_return;
@@ -935,10 +1034,11 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
DH_free(dh);
if (!r)
return env->ThrowTypeError("Error setting temp DH parameter");
}
+#endif
void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) {
SecureContext* sc;
ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
@@ -1952,10 +2052,11 @@ void SSLWrap<Base>::GetEphemeralKeyInfo(
info->Set(env->type_string(),
FIXED_ONE_BYTE_STRING(env->isolate(), "DH"));
info->Set(env->size_string(),
Integer::New(env->isolate(), EVP_PKEY_bits(key)));
break;
+#ifndef OPENSSL_NO_ECDH
case EVP_PKEY_EC:
{
EC_KEY* ec = EVP_PKEY_get1_EC_KEY(key);
int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
EC_KEY_free(ec);
@@ -1964,10 +2065,11 @@ void SSLWrap<Base>::GetEphemeralKeyInfo(
info->Set(env->name_string(),
OneByteString(args.GetIsolate(), OBJ_nid2sn(nid)));
info->Set(env->size_string(),
Integer::New(env->isolate(), EVP_PKEY_bits(key)));
}
+#endif
}
EVP_PKEY_free(key);
}
return args.GetReturnValue().Set(info);
@@ -2382,11 +2484,16 @@ void SSLWrap<Base>::WaitForCertCb(CertCb cb, void* arg) {
cert_cb_arg_ = arg;
}
template <class Base>
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
int SSLWrap<Base>::SSLCertCallback(SSL* s, void* arg) {
+#else
+/* NOTE: For now this callback gets usually never called dueto design flaws */
+int SSLWrap<Base>::SSLCertCallback(SSL* s, X509 **x509, EVP_PKEY **pkey) {
+#endif
Base* w = static_cast<Base*>(SSL_get_app_data(s));
if (!w->is_server())
return 1;
@@ -2451,23 +2558,57 @@ void SSLWrap<Base>::CertCbDone(const FunctionCallbackInfo<Value>& args) {
ASSIGN_OR_RETURN_UNWRAP(&sc, ctx.As<Object>());
w->sni_context_.Reset();
w->sni_context_.Reset(env->isolate(), ctx);
int rv;
+ X509* x509;
+ EVP_PKEY* pkey;
+ STACK_OF(X509)* chain;
// NOTE: reference count is not increased by this API methods
- X509* x509 = SSL_CTX_get0_certificate(sc->ctx_);
- EVP_PKEY* pkey = SSL_CTX_get0_privatekey(sc->ctx_);
- STACK_OF(X509)* chain;
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+ x509 = SSL_CTX_get0_certificate(sc->ctx_);
+ pkey = SSL_CTX_get0_privatekey(sc->ctx_);
+ rv = SSL_CTX_get0_chain_certs(sc->ctx_, &chain);
+#else
+ SSL *ssl = SSL_new(sc->ctx_);
+ rv = SSL_CTX_get_extra_chain_certs(sc->ctx_, &chain);
+ if (ssl) {
+ SSL_set_connect_state(ssl); /* just cleanup/reset state - cheap */
+ x509 = SSL_get_certificate(ssl);
+ SSL_free(ssl);
+ } else {
+ x509 = NULL;
+ pkey = NULL;
+ }
+#endif
- rv = SSL_CTX_get0_chain_certs(sc->ctx_, &chain);
- if (rv)
- rv = SSL_use_certificate(w->ssl_, x509);
- if (rv)
- rv = SSL_use_PrivateKey(w->ssl_, pkey);
- if (rv && chain != nullptr)
- rv = SSL_set1_chain(w->ssl_, chain);
+ if (rv)
+ rv = SSL_use_certificate(w->ssl_, x509);
+ if (rv)
+ rv = SSL_use_PrivateKey(w->ssl_, pkey);
+ if (rv && chain != nullptr) {
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+ // replaces w->ssl_->cert->key->chain with a copy of the given chain,
+ // which is allowed to be NULL
+ rv = SSL_set1_chain(w->ssl_, chain);
+#else
+ // just replace the extra chain with the given chain - 1.0.1- does not
+ // support chain per cert
+ SSL_CTX_clear_extra_chain_certs(w->ssl_->ctx);
+ if (chain != NULL) {
+ int i;
+ SSL_CTX* ctx = w->ssl_->ctx;
+ for (i = 0; i < sk_X509_num(chain); i++) {
+ // can't do anything: however others might be ok and still
+ // satisfy requirements
+ SSL_CTX_add_extra_chain_cert(ctx, sk_X509_value(chain,i));
+ }
+ }
+ rv = 1;
+#endif
+ }
if (rv)
rv = w->SetCACerts(sc);
if (!rv) {
unsigned long err = ERR_get_error(); // NOLINT(runtime/int)
if (!err)
@@ -2527,14 +2668,18 @@ void SSLWrap<Base>::SetSNIContext(SecureContext* sc) {
}
template <class Base>
int SSLWrap<Base>::SetCACerts(SecureContext* sc) {
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
int err = SSL_set1_verify_cert_store(ssl_, SSL_CTX_get_cert_store(sc->ctx_));
if (err != 1)
return err;
-
+#else
+ // there is no ssl_->cert->verify_store in <= 1.0.1. So no need to: free the
+ // old store, set the new one to it and increment its ref count.
+#endif
STACK_OF(X509_NAME)* list = SSL_dup_CA_list(
SSL_CTX_get_client_CA_list(sc->ctx_));
// NOTE: `SSL_set_client_CA_list` takes the ownership of `list`
SSL_set_client_CA_list(ssl_, list);
@@ -2808,11 +2953,15 @@ inline int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx) {
// Server does not need to check the whitelist.
SSL* ssl = static_cast<SSL*>(
X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()));
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
if (SSL_is_server(ssl))
+#else
+ if (ssl->server)
+#endif
return 1;
// Client needs to check if the server cert is listed in the
// whitelist when it is issued by the specific rootCAs.
CheckResult ret = CheckWhitelistedServerCert(ctx);
@@ -2891,11 +3040,25 @@ void Connection::New(const FunctionCallbackInfo<Value>& args) {
if (is_server)
SSL_set_info_callback(conn->ssl_, SSLInfoCallback);
InitNPN(sc);
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
SSL_set_cert_cb(conn->ssl_, SSLWrap<Connection>::SSLCertCallback, conn);
+#else
+ /* 1.0.1 and less have no general cert callback. The closest for a client is
+ SSL_CTX_set_client_cert_cb(conn->ssl_->ctx, SSLWrap<Connection>::SSLCertCallback);
+ but on the client it is not needed/used by this implementation. Since this
+ the SSLCertCallback actually calls lib/_tls_wrap.js:oncertcb(), which in
+ turn loadSNI() and this the actual SNICallback of the JSON object, sets
+ the context and finally requestOCSP() and certCbDone(). Not sure, why
+ the SNICallback of the JSON object, doesn't get invoked via
+ SelectSNIContextCallback_() - design flaw because lets do 2 things at once
+ (i.e. do SNICallback and attach the certs ca chain), however, this means
+ no server side support for the SNI TLS/OCSP_state extension anymore.
+ */
+#endif
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
if (is_server) {
SSL_CTX_set_tlsext_servername_callback(sc->ctx_, SelectSNIContextCallback_);
} else if (args[2]->IsString()) {
@@ -4476,10 +4639,11 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(vbuf);
delete[] out_value;
}
+#ifndef OPENSSL_NO_DH
void DiffieHellman::Initialize(Environment* env, Local<Object> target) {
Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
const PropertyAttribute attributes =
static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
@@ -4877,12 +5041,14 @@ bool DiffieHellman::VerifyContext() {
if (!DH_check(dh, &codes))
return false;
verifyError_ = codes;
return true;
}
+#endif
+#ifndef OPENSSL_NO_ECDH
void ECDH::Initialize(Environment* env, Local<Object> target) {
HandleScope scope(env->isolate());
Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
@@ -5106,10 +5272,11 @@ void ECDH::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
return env->ThrowError("Failed to set generated public key");
}
EC_POINT_free(pub);
}
+#endif
void ECDH::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
@@ -5659,10 +5826,11 @@ void GetHashes(const FunctionCallbackInfo<Value>& args) {
EVP_MD_do_all_sorted(array_push_back<EVP_MD>, &ctx);
args.GetReturnValue().Set(ctx.arr);
}
+# ifndef OPENSSL_NO_EC
void GetCurves(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
const size_t num_curves = EC_get_builtin_curves(nullptr, 0);
Local<Array> arr = Array::New(env->isolate(), num_curves);
EC_builtin_curve* curves;
@@ -5683,10 +5851,11 @@ void GetCurves(const FunctionCallbackInfo<Value>& args) {
free(curves);
}
args.GetReturnValue().Set(arr);
}
+#endif
bool VerifySpkac(const char* data, unsigned int len) {
bool i = 0;
EVP_PKEY* pkey = nullptr;
@@ -5995,12 +6164,16 @@ void InitCrypto(Local<Object> target,
Environment* env = Environment::GetCurrent(context);
SecureContext::Initialize(env, target);
Connection::Initialize(env, target);
CipherBase::Initialize(env, target);
+# ifndef OPENSSL_NO_EC
DiffieHellman::Initialize(env, target);
+#endif
+#ifndef OPENSSL_NO_ECDH
ECDH::Initialize(env, target);
+#endif
Hmac::Initialize(env, target);
Hash::Initialize(env, target);
Sign::Initialize(env, target);
Verify::Initialize(env, target);
@@ -6016,11 +6189,13 @@ void InitCrypto(Local<Object> target,
env->SetMethod(target, "randomBytes", RandomBytes);
env->SetMethod(target, "timingSafeEqual", TimingSafeEqual);
env->SetMethod(target, "getSSLCiphers", GetSSLCiphers);
env->SetMethod(target, "getCiphers", GetCiphers);
env->SetMethod(target, "getHashes", GetHashes);
+# ifndef OPENSSL_NO_EC
env->SetMethod(target, "getCurves", GetCurves);
+#endif
env->SetMethod(target, "publicEncrypt",
PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
EVP_PKEY_encrypt_init,
EVP_PKEY_encrypt>);
env->SetMethod(target, "privateDecrypt",
diff --git a/src/node_crypto.h b/src/node_crypto.h
index 175206c40df58602b0c24d039b8b5a8bb6f56ba3..5ecc43b08d0b4d97311f09271a26f5a735a6e018 100644
--- a/src/node_crypto.h
+++ b/src/node_crypto.h
@@ -16,12 +16,16 @@
#include "base-object-inl.h"
#include "v8.h"
#include <openssl/ssl.h>
+# ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
+# endif
+# ifndef OPENSSL_NO_ECDH
#include <openssl/ecdh.h>
+# endif
#ifndef OPENSSL_NO_ENGINE
# include <openssl/engine.h>
#endif // !OPENSSL_NO_ENGINE
#include <openssl/err.h>
#include <openssl/evp.h>
@@ -100,12 +104,16 @@ class SecureContext : public BaseObject {
static void SetCert(const v8::FunctionCallbackInfo<v8::Value>& args);
static void AddCACert(const v8::FunctionCallbackInfo<v8::Value>& args);
static void AddCRL(const v8::FunctionCallbackInfo<v8::Value>& args);
static void AddRootCerts(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetCiphers(const v8::FunctionCallbackInfo<v8::Value>& args);
+#ifndef OPENSSL_NO_ECDH
static void SetECDHCurve(const v8::FunctionCallbackInfo<v8::Value>& args);
+#endif
+# ifndef OPENSSL_NO_DH
static void SetDHParam(const v8::FunctionCallbackInfo<v8::Value>& args);
+#endif
static void SetOptions(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetSessionIdContext(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetSessionTimeout(
const v8::FunctionCallbackInfo<v8::Value>& args);
@@ -273,11 +281,15 @@ class SSLWrap {
unsigned char* outlen,
const unsigned char* in,
unsigned int inlen,
void* arg);
static int TLSExtStatusCallback(SSL* s, void* arg);
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
static int SSLCertCallback(SSL* s, void* arg);
+#else
+ static int SSLCertCallback(SSL* s, X509 **x509, EVP_PKEY **pkey);
+#endif
static void SSLGetter(v8::Local<v8::String> property,
const v8::PropertyCallbackInfo<v8::Value>& info);
void DestroySSL();
void WaitForCertCb(CertCb cb, void* arg);
@@ -635,10 +647,11 @@ class PublicKeyCipher {
EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
EVP_PKEY_cipher_t EVP_PKEY_cipher>
static void Cipher(const v8::FunctionCallbackInfo<v8::Value>& args);
};
+#ifndef OPENSSL_NO_DH
class DiffieHellman : public BaseObject {
public:
~DiffieHellman() override {
if (dh != nullptr) {
DH_free(dh);
@@ -680,11 +693,13 @@ class DiffieHellman : public BaseObject {
bool initialised_;
int verifyError_;
DH* dh;
};
+#endif
+# ifndef OPENSSL_NO_ECDH
class ECDH : public BaseObject {
public:
~ECDH() override {
if (key_ != nullptr)
EC_KEY_free(key_);
@@ -717,10 +732,11 @@ class ECDH : public BaseObject {
bool IsKeyValidForCurve(const BIGNUM* private_key);
EC_KEY* key_;
const EC_GROUP* group_;
};
+#endif
bool EntropySource(unsigned char* buffer, size_t length);
#ifndef OPENSSL_NO_ENGINE
void SetEngine(const v8::FunctionCallbackInfo<v8::Value>& args);
#endif // !OPENSSL_NO_ENGINE
diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc
index d1b1aeccdd95b00b3fd0421c08fd7816cd70d182..a6e63d7c1ccc81e6f7d782dffe833234b003de15 100644
--- a/src/tls_wrap.cc
+++ b/src/tls_wrap.cc
@@ -140,11 +140,19 @@ void TLSWrap::InitSSL() {
}
#endif // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
InitNPN(sc_);
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
SSL_set_cert_cb(ssl_, SSLWrap<TLSWrap>::SSLCertCallback, this);
+#else
+ /* 1.0.1 and less have at most for the client side the function
+ SSL_CTX_set_client_cert_cb(ssl_->ctx, SSLWrap<TLSWrap>::SSLCertCallback);
+ but on the client it is not needed/used by this implementation.
+ For more info see comments in src/node_crypto.cc Connection::New().
+ */
+#endif
if (is_server()) {
SSL_set_accept_state(ssl_);
} else if (is_client()) {
// Enough space for server response (hello, cert)
--
2.12.0

View File

@ -1,36 +0,0 @@
From 15dfe22be278cb1f0194de0b0ab790ba9dc4fc33 Mon Sep 17 00:00:00 2001
From: Zuzana Svetlikova <zsvetlik@redhat.com>
Date: Fri, 23 Jun 2017 23:11:28 +0200
Subject: [PATCH] c-ares NAPTR parser out of bounds access
CVE: CVE-2017-1000381
Upstream bug: https://c-ares.haxx.se/adv_20170620.html
---
deps/cares/src/ares_parse_naptr_reply.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/deps/cares/src/ares_parse_naptr_reply.c b/deps/cares/src/ares_parse_naptr_reply.c
index 11634df984..717d355778 100644
--- a/deps/cares/src/ares_parse_naptr_reply.c
+++ b/deps/cares/src/ares_parse_naptr_reply.c
@@ -110,6 +110,12 @@ ares_parse_naptr_reply (const unsigned char *abuf, int alen,
status = ARES_EBADRESP;
break;
}
+ /* RR must contain at least 7 bytes = 2 x int16 + 3 x name */
+ if (rr_len < 7)
+ {
+ status = ARES_EBADRESP;
+ break;
+ }
/* Check if we are really looking at a NAPTR record */
if (rr_class == C_IN && rr_type == T_NAPTR)
@@ -185,4 +191,3 @@ ares_parse_naptr_reply (const unsigned char *abuf, int alen,
return ARES_SUCCESS;
}
-
--
2.13.1

View File

@ -1,112 +0,0 @@
From a75f63218b84ee508c770391519a13bd400a5003 Mon Sep 17 00:00:00 2001
From: Ben Noordhuis <info@bnoordhuis.nl>
Date: Thu, 13 Apr 2017 13:48:01 +0200
Subject: [PATCH 4/4] v8: fix build errors with g++ 7
This is a local patch because upstream fixed it differently by moving
large chunks of code out of objects.h. We cannot easily back-port
those changes due to their size and invasiveness.
Fixes: https://github.com/nodejs/node/issues/10388
PR-URL: https://github.com/nodejs/node/pull/12392
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
---
deps/v8/src/objects-body-descriptors.h | 2 +-
deps/v8/src/objects-inl.h | 21 +++++++++++++++++++++
deps/v8/src/objects.h | 20 ++++----------------
3 files changed, 26 insertions(+), 17 deletions(-)
diff --git a/deps/v8/src/objects-body-descriptors.h b/deps/v8/src/objects-body-descriptors.h
index 91cb8883be88739eab2b10df71f6f0d08aab436e..a1c3634bd762d7e03b4c87d38aa14a9a3ce318e4 100644
--- a/deps/v8/src/objects-body-descriptors.h
+++ b/deps/v8/src/objects-body-descriptors.h
@@ -97,11 +97,11 @@ class FixedBodyDescriptor final : public BodyDescriptorBase {
IterateBodyImpl<StaticVisitor>(heap, obj, start_offset, end_offset);
}
template <typename StaticVisitor>
static inline void IterateBody(HeapObject* obj, int object_size) {
- IterateBody(obj);
+ IterateBody<StaticVisitor>(obj);
}
};
// This class describes a body of an object of a variable size
diff --git a/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h
index 11f4d7498d7558f56037483004a3d5839154516b..72208c2f00f4a9ff47ae487fa9a42f8f82cf12ea 100644
--- a/deps/v8/src/objects-inl.h
+++ b/deps/v8/src/objects-inl.h
@@ -34,10 +34,31 @@
#include "src/v8memory.h"
namespace v8 {
namespace internal {
+template <typename Derived, typename Shape, typename Key>
+uint32_t HashTable<Derived, Shape, Key>::Hash(Key key) {
+ if (Shape::UsesSeed) {
+ return Shape::SeededHash(key, GetHeap()->HashSeed());
+ } else {
+ return Shape::Hash(key);
+ }
+}
+
+
+template <typename Derived, typename Shape, typename Key>
+uint32_t HashTable<Derived, Shape, Key>::HashForObject(Key key,
+ Object* object) {
+ if (Shape::UsesSeed) {
+ return Shape::SeededHashForObject(key, GetHeap()->HashSeed(), object);
+ } else {
+ return Shape::HashForObject(key, object);
+ }
+}
+
+
PropertyDetails::PropertyDetails(Smi* smi) {
value_ = smi->value();
}
diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h
index d1632c9deb298218faea31886ffdb0a8e0201cdc..47b02dadcff9658c9fcfe629e137667015e12079 100644
--- a/deps/v8/src/objects.h
+++ b/deps/v8/src/objects.h
@@ -3259,26 +3259,14 @@ class HashTableBase : public FixedArray {
template <typename Derived, typename Shape, typename Key>
class HashTable : public HashTableBase {
public:
- // Wrapper methods
- inline uint32_t Hash(Key key) {
- if (Shape::UsesSeed) {
- return Shape::SeededHash(key, GetHeap()->HashSeed());
- } else {
- return Shape::Hash(key);
- }
- }
-
- inline uint32_t HashForObject(Key key, Object* object) {
- if (Shape::UsesSeed) {
- return Shape::SeededHashForObject(key, GetHeap()->HashSeed(), object);
- } else {
- return Shape::HashForObject(key, object);
- }
- }
+ // Wrapper methods. Defined in src/objects-inl.h
+ // to break a cycle with src/heap/heap.h.
+ inline uint32_t Hash(Key key);
+ inline uint32_t HashForObject(Key key, Object* object);
// Returns a new HashTable object.
MUST_USE_RESULT static Handle<Derived> New(
Isolate* isolate, int at_least_space_for,
MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY,
--
2.12.2

View File

@ -1,30 +0,0 @@
diff -ru a/src/node_crypto.cc b/src/node_crypto.cc
--- a/src/node_crypto.cc 2017-03-31 22:39:56.483283868 +0200
+++ b/src/node_crypto.cc 2017-03-31 22:45:36.250267750 +0200
@@ -851,8 +851,6 @@
}
}
- // Increment reference count so global store is not deleted along with CTX.
- X509_STORE_up_ref(root_cert_store);
SSL_CTX_set_cert_store(sc->ctx_, root_cert_store);
}
diff -ru a/src/node_crypto.h b/src/node_crypto.h
--- a/src/node_crypto.h 2017-03-21 20:43:33.000000000 +0100
+++ b/src/node_crypto.h 2017-03-31 22:43:15.548183432 +0200
@@ -145,6 +145,13 @@
}
env()->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize);
+ if (ctx_->cert_store == root_cert_store) {
+ // SSL_CTX_free() will attempt to free the cert_store as well.
+ // Since we want our root_cert_store to stay around forever
+ // we just clear the field. Hopefully OpenSSL will not modify this
+ // struct in future versions.
+ ctx_->cert_store = nullptr;
+ }
SSL_CTX_free(ctx_);
if (cert_ != nullptr)
X509_free(cert_);

View File

@ -17,7 +17,7 @@
# than a Fedora release lifecycle.
%global nodejs_epoch 1
%global nodejs_major 8
%global nodejs_minor 3
%global nodejs_minor 4
%global nodejs_patch 0
%global nodejs_abi %{nodejs_major}.%{nodejs_minor}
%global nodejs_version %{nodejs_major}.%{nodejs_minor}.%{nodejs_patch}
@ -97,13 +97,6 @@ Source7: nodejs_native.attr
# Disable running gyp on bundled deps we don't use
Patch1: 0001-Disable-running-gyp-files-for-bundled-deps.patch
# EPEL only has OpenSSL 1.0.1, so we need to carry a patch on that platform
Patch2: 0002-Use-openssl-1.0.1.patch
# RHEL 7 still uses OpenSSL 1.0.1 for now, and it segfaults on SSL
# Revert this upstream patch until RHEL 7 upgrades to 1.0.2
Patch5: EPEL01-openssl101-compat.patch
BuildRequires: python2-devel
BuildRequires: libuv-devel >= 1:1.9.1
Requires: libuv >= 1:1.9.1
@ -173,6 +166,10 @@ Provides: bundled(c-ares) = %{c_ares_version}
# See https://github.com/nodejs/node/commit/d726a177ed59c37cf5306983ed00ecd858cfbbef
Provides: bundled(v8) = %{v8_version}
# As of v8.4.0, Node.js has http/2 support. They however don't provide --shared-<lib>
# option yet.
Provides: bundled(nghttp2) = 1.22.0
# Make sure we keep NPM up to date when we update Node.js
%if 0%{?epel}
# EPEL doesn't support Recommends, so make it strict
@ -283,6 +280,8 @@ export CXXFLAGS="$(echo ${CXXFLAGS} | tr '\n\\' ' ')"
--shared-http-parser \
--with-dtrace \
--with-intl=system-icu \
--debug-http2 \
--debug-nghttp2 \
--openssl-use-def-ca-store
%else
./configure --prefix=%{_prefix} \
@ -291,6 +290,8 @@ export CXXFLAGS="$(echo ${CXXFLAGS} | tr '\n\\' ' ')"
--shared-libuv \
--without-dtrace \
--with-intl=system-icu \
--debug-http2 \
--debug-nghttp2 \
--openssl-use-def-ca-store
%endif
@ -443,6 +444,12 @@ NODE_PATH=%{buildroot}%{_prefix}/lib/node_modules %{buildroot}/%{_bindir}/node -
%{_pkgdocdir}/npm/doc
%changelog
* Wed Aug 16 2017 Zuzana Svetlikova <zsvetlik@redhat.com> - 1:8.4.0-1
- Update to v8.4.0
- https://nodejs.org/en/blog/release/v8.4.0/
- http2 is now supported, add bundled nghttp2
- remove openssl 1.0.1 patches, we won't be using them in fedora
* Thu Aug 10 2017 Zuzana Svetlikova <zsvetlik@redhat.com> - 1:8.3.0-1
- Update to v8.3.0
- https://nodejs.org/en/blog/release/v8.3.0/

View File

@ -1 +1 @@
SHA512 (node-v8.3.0-stripped.tar.gz) = e1947f48966f5ddf0976f39e444ec6d4020a0a63aa935f19f5890ec96dc53f39f650c7651b26f8b2a9f3445ebcb1b85795e010b0bc14c48c8250a60652bf9d6d
SHA512 (node-v8.4.0-stripped.tar.gz) = fb49b47427bb25e235c0a179f2d2b8060920eb2ea482ecf361f51b15f3b1e84e6f65b691abcc1e0ec79b99a0fed249e6cf7300ba2096fb526d47912e15a3552c