Move to requiring OpenSSL 1.0.2

Unbundle http-parser again.
This commit is contained in:
Stephen Gallagher 2017-08-23 12:00:54 -04:00
parent efe742cebc
commit 001b20df9c
No known key found for this signature in database
GPG Key ID: 7A25556236BAA3A3
5 changed files with 23 additions and 876 deletions

View File

@ -1,25 +1,29 @@
From 55269de7552aebc324cb0333d38d600897555b9c Mon Sep 17 00:00:00 2001
From be1738c229765ad0796b97e842515b5d8834c894 Mon Sep 17 00:00:00 2001
From: Zuzana Svetlikova <zsvetlik@redhat.com>
Date: Tue, 22 Aug 2017 13:11:56 +0200
Subject: [PATCH] Disable gyp
Date: Wed, 22 Mar 2017 19:13:10 +0100
Subject: [PATCH] Disable running gyp files for bundled deps
---
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index cfbd426033..ee05b63f8f 100644
index cfbd426033c7f2882f77cd60faaf3bb0277e6c57..8ca97d5552ebb328d8d6727531b13843864a6e86 100644
--- a/Makefile
+++ b/Makefile
@@ -77,7 +77,7 @@ $(NODE_G_EXE): config.gypi out/Makefile
@@ -75,11 +75,11 @@ $(NODE_EXE): config.gypi out/Makefile
$(NODE_G_EXE): config.gypi out/Makefile
$(MAKE) -C out BUILDTYPE=Debug V=$(V)
if [ ! -r $@ -o ! -L $@ ]; then ln -fs out/Debug/$(NODE_EXE) $@; fi
-out/Makefile: common.gypi deps/uv/uv.gyp deps/http_parser/http_parser.gyp deps/zlib/zlib.gyp deps/v8/build/toolchain.gypi deps/v8/build/features.gypi deps/v8/tools/gyp/v8.gyp node.gyp config.gypi
+out/Makefile: common.gypi deps/http_parser/http_parser.gyp deps/v8/build/toolchain.gypi deps/v8/build/features.gypi deps/v8/tools/gyp/v8.gyp node.gyp config.gypi
+out/Makefile: common.gypi deps/v8/build/toolchain.gypi deps/v8/build/features.gypi deps/v8/tools/gyp/v8.gyp node.gyp config.gypi
$(PYTHON) tools/gyp_node.py -f make
config.gypi: configure
$(error Missing or stale $@, please run ./$<)
--
2.14.1
2.13.5

View File

@ -1,648 +0,0 @@
From 2411d250a2789675aa9c902aeea3f0c55b34a4e0 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/3] 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 b7e5c8f15e2bf4e8604cdd1bc95ea0e98a96b7d6..6b3069f9352ae44d0dab37b3e4b2eebdbc104609 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 750df9c669bad38e0cc05158bd8ef1c90d810f74..d693851c4bb6c247cfda7436c5ea0baf5bebc886 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 f654dcf60cb42479b06fcd2be96e5bda287606c7..7aaff07fb513945d6272f238814a4cd297da7b0e 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -26,10 +26,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"); \
} \
@@ -165,11 +241,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,
@@ -295,12 +375,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);
@@ -531,12 +615,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;
@@ -887,10 +983,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();
@@ -914,12 +1011,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;
@@ -954,10 +1053,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());
@@ -1977,10 +2077,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);
@@ -1989,10 +2090,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);
@@ -2407,11 +2509,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;
@@ -2476,23 +2583,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)
@@ -2552,14 +2693,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);
@@ -2871,11 +3016,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 CHECK_OK;
// 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);
@@ -2954,11 +3103,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()) {
@@ -4541,10 +4704,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);
@@ -4942,12 +5106,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);
@@ -5173,10 +5339,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);
@@ -5728,10 +5895,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;
@@ -5752,10 +5920,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;
@@ -6063,12 +6232,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);
@@ -6084,11 +6257,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 38f49ba5a05063438372471b4a58036190954cd3..8304e719719dae41757071b4463f8631cb1e442f 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 8eab962a66f61c3f3020c59f4db472f286856d97..5d741576720b9e3a0fbc50b08f8f3ebd715148dc 100644
--- a/src/tls_wrap.cc
+++ b/src/tls_wrap.cc
@@ -141,11 +141,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.13.5

View File

@ -1,84 +0,0 @@
From f1a0660b9186c3f4d55d7c07219126e199c787f9 Mon Sep 17 00:00:00 2001
From: Adam Majer <amajer@suse.de>
Date: Wed, 21 Dec 2016 11:16:38 +0100
Subject: [PATCH 3/4] crypto: Use system CAs instead of using bundled ones
NodeJS can already use an external, shared OpenSSL library. This
library knows where to look for OS managed certificates. Allow
a compile-time option to use this CA store by default instead of
using bundled certificates.
In case when using bundled OpenSSL, the paths are also valid for
majority of Linux systems without additional intervention. If
this is not set, we can use SSL_CERT_DIR to point it to correct
location.
Fixes: https://github.com/nodejs/node/issues/3159
PR-URL: https://github.com/nodejs/node/pull/8334
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
---
configure | 7 +++++++
src/node_crypto.cc | 4 ++++
2 files changed, 11 insertions(+)
diff --git a/configure b/configure
index 821b8771bc8909d8453bc31e3c8d8dc65368c0e4..e64bad9a030693b726e0974f48aefa6e1ad87723 100755
--- a/configure
+++ b/configure
@@ -142,10 +142,15 @@ parser.add_option("--openssl-no-asm",
parser.add_option('--openssl-fips',
action='store',
dest='openssl_fips',
help='Build OpenSSL using FIPS canister .o file in supplied folder')
+parser.add_option('--openssl-use-def-ca-store',
+ action='store_true',
+ dest='use_openssl_ca_store',
+ help='Use OpenSSL supplied CA store instead of compiled-in Mozilla CA copy.')
+
shared_optgroup.add_option('--shared-http-parser',
action='store_true',
dest='shared_http_parser',
help='link to a shared http_parser DLL instead of static linking')
@@ -937,10 +942,12 @@ def configure_v8(o):
def configure_openssl(o):
o['variables']['node_use_openssl'] = b(not options.without_ssl)
o['variables']['node_shared_openssl'] = b(options.shared_openssl)
o['variables']['openssl_no_asm'] = 1 if options.openssl_no_asm else 0
+ if options.use_openssl_ca_store:
+ o['defines'] += ['NODE_OPENSSL_CERT_STORE']
if options.openssl_fips:
o['variables']['openssl_fips'] = options.openssl_fips
fips_dir = os.path.join(root_dir, 'deps', 'openssl', 'fips')
fips_ld = os.path.abspath(os.path.join(fips_dir, 'fipsld'))
o['make_fips_settings'] = [
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index c5630f30d0bef75ced53b36062bb1f0324dbdb9d..873b37d71b51aa62c8ebd56ea5b182567675e2dd 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -803,14 +803,18 @@ static X509_STORE* NewRootCertStore() {
root_certs_vector->push_back(x509);
}
}
X509_STORE* store = X509_STORE_new();
+#if defined(NODE_OPENSSL_CERT_STORE)
+ X509_STORE_set_default_paths(store);
+#else
for (auto& cert : *root_certs_vector) {
X509_up_ref(cert);
X509_STORE_add_cert(store, cert);
}
+#endif
return store;
}
--
2.12.0

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

@ -19,7 +19,7 @@
%global nodejs_patch 2
%global nodejs_abi %{nodejs_major}.%{nodejs_minor}
%global nodejs_version %{nodejs_major}.%{nodejs_minor}.%{nodejs_patch}
%global nodejs_release 1.3
%global nodejs_release 2
# == Bundled Dependency Versions ==
# v8 - from deps/v8/include/v8-version.h
@ -88,37 +88,23 @@ 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
# RHEL 7.4 now has 1.0.2, but as of this writing, CentOS hasn't picked it up
# yet. Drop the openssl 1.0.1 compatibility patches once this happens.
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: python-devel
BuildRequires: libuv-devel >= 1:1.9.1
Requires: libuv >= 1:1.9.1
#Requires: http-parser >= 2.7.0
Requires: http-parser >= 2.7.0
BuildRequires: libicu-devel
BuildRequires: zlib-devel
BuildRequires: gcc >= 4.8.0
BuildRequires: gcc-c++ >= 4.8.0
#BuildRequires: http-parser-devel >= 2.7.0
Provides: bundled(http-parser) = 2.7.0
BuildRequires: http-parser-devel >= 2.7.0
%if 0%{?epel} || 0%{?rhel}
BuildRequires: openssl-devel >= 1:1.0.1
%else
%if 0%{?fedora} > 25
BuildRequires: compat-openssl10-devel >= 1:1.0.2
%else
BuildRequires: openssl-devel >= 1:1.0.2
%endif
%endif
# we need the system certificate store when Patch2 is applied
# we need the system certificate store
Requires: ca-certificates
#we need ABI virtual provides where SONAMEs aren't enough/not present so deps
@ -182,7 +168,7 @@ Summary: JavaScript runtime - development headers
Group: Development/Languages
Requires: %{name}%{?_isa} = %{epoch}:%{nodejs_version}-%{nodejs_release}%{?dist}
Requires: libuv-devel%{?_isa}
#Requires: http-parser-devel%{?_isa}
Requires: http-parser-devel%{?_isa}
Requires: openssl-devel%{?_isa}
Requires: zlib-devel%{?_isa}
Requires: nodejs-packaging
@ -231,15 +217,11 @@ The API documentation for the Node.js JavaScript runtime.
# remove bundled dependencies that we aren't building
%patch1 -p1
rm -rf deps/icu-small \
rm -rf deps/http-parser \
deps/icu-small \
deps/uv \
deps/zlib
%if 0%{?epel} || 0%{?rhel}
%patch2 -p1
%patch5 -p1
%endif
%build
# build with debugging symbols and add defines from libuv (#892601)
@ -264,6 +246,7 @@ export CXXFLAGS="$(echo ${CXXFLAGS} | tr '\n\\' ' ')"
--shared-openssl \
--shared-zlib \
--shared-libuv \
--shared-http-parser \
--without-dtrace \
--with-intl=system-icu \
--openssl-use-def-ca-store
@ -407,6 +390,10 @@ NODE_PATH=%{buildroot}%{_prefix}/lib/node_modules %{buildroot}/%{_bindir}/node -
%{_pkgdocdir}/npm/doc
%changelog
* Wed Aug 23 2017 Stephen Gallagher <sgallagh@redhat.com> - 1:6.11.2-2
- Move to requiring OpenSSL 1.0.2
- Unbundle http-parser again
* Tue Aug 22 2017 Zuzana Svetlikova <zsvetlik@redhat.com> - 1:6.11.2-1.3
- Run gyp on http-parser