Blame SOURCES/0001-Remove-or-backport-OpenSSL-features.patch

b2803b
From 3b512b3127b2ad733460d30bf8def2b5553bc648 Mon Sep 17 00:00:00 2001
b2803b
From: rpm-build <rpm-build>
b2803b
Date: Thu, 29 Aug 2019 14:28:57 +0200
b2803b
Subject: [PATCH] Remove or backport OpenSSL features
6261c9
b2803b
Signed-off-by: rpm-build <rpm-build>
6261c9
---
b2803b
 src/node_constants.cc                         |  12 +-
b2803b
 src/node_crypto.cc                            | 268 ++++++++++++++++--
b2803b
 src/node_crypto.h                             |  22 ++
b2803b
 test/parallel/test-crypto-authenticated.js    |   4 +-
b2803b
 test/parallel/test-crypto-keygen.js           |   8 +-
b2803b
 test/parallel/test-crypto-pbkdf2.js           |  18 --
b2803b
 .../test-tls-client-getephemeralkeyinfo.js    |   1 -
b2803b
 test/parallel/test-tls-passphrase.js          |   2 +-
b2803b
 8 files changed, 291 insertions(+), 44 deletions(-)
6261c9
6261c9
diff --git a/src/node_constants.cc b/src/node_constants.cc
b2803b
index 9cd50fe..65f3159 100644
6261c9
--- a/src/node_constants.cc
6261c9
+++ b/src/node_constants.cc
6261c9
@@ -951,8 +951,12 @@ void DefineOpenSSLConstants(Local<Object> target) {
6261c9
     NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_RAND);
6261c9
 # endif
6261c9
 
6261c9
-# ifdef ENGINE_METHOD_EC
6261c9
-    NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_EC);
6261c9
+# ifdef ENGINE_METHOD_ECDH
6261c9
+    NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_ECDH);
6261c9
+# endif
6261c9
+
6261c9
+# ifdef ENGINE_METHOD_ECDSA
6261c9
+    NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_ECDSA);
6261c9
 # endif
6261c9
 
6261c9
 # ifdef ENGINE_METHOD_CIPHERS
6261c9
@@ -963,6 +967,10 @@ void DefineOpenSSLConstants(Local<Object> target) {
6261c9
     NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_DIGESTS);
6261c9
 # endif
6261c9
 
6261c9
+# ifdef ENGINE_METHOD_STORE
6261c9
+    NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_STORE);
6261c9
+# endif
6261c9
+
6261c9
 # ifdef ENGINE_METHOD_PKEY_METHS
6261c9
     NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_PKEY_METHS);
6261c9
 # endif
6261c9
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
b2803b
index 1d9214f..17c6d77 100644
6261c9
--- a/src/node_crypto.cc
6261c9
+++ b/src/node_crypto.cc
b2803b
@@ -109,6 +109,137 @@ struct OpenSSLBufferDeleter {
6261c9
 };
6261c9
 using OpenSSLBuffer = std::unique_ptr<char[], OpenSSLBufferDeleter>;
6261c9
 
6261c9
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
6261c9
+static void RSA_get0_key(const RSA* r, const BIGNUM** n, const BIGNUM** e,
6261c9
+                         const BIGNUM** d) {
6261c9
+  if (n != nullptr) {
6261c9
+    *n = r->n;
6261c9
+  }
6261c9
+  if (e != nullptr) {
6261c9
+    *e = r->e;
6261c9
+  }
6261c9
+  if (d != nullptr) {
6261c9
+    *d = r->d;
6261c9
+  }
6261c9
+}
6261c9
+
6261c9
+static void DH_get0_pqg(const DH* dh, const BIGNUM** p, const BIGNUM** q,
6261c9
+                        const BIGNUM** g) {
6261c9
+  if (p != nullptr) {
6261c9
+    *p = dh->p;
6261c9
+  }
6261c9
+  if (q != nullptr) {
6261c9
+    *q = dh->q;
6261c9
+  }
6261c9
+  if (g != nullptr) {
6261c9
+    *g = dh->g;
6261c9
+  }
6261c9
+}
6261c9
+
6261c9
+static int DH_set0_pqg(DH* dh, BIGNUM* p, BIGNUM* q, BIGNUM* g) {
6261c9
+  if ((dh->p == nullptr && p == nullptr) ||
6261c9
+      (dh->g == nullptr && g == nullptr)) {
6261c9
+    return 0;
6261c9
+  }
6261c9
+
6261c9
+  if (p != nullptr) {
6261c9
+    BN_free(dh->p);
6261c9
+    dh->p = p;
6261c9
+  }
6261c9
+  if (q != nullptr) {
6261c9
+    BN_free(dh->q);
6261c9
+    dh->q = q;
6261c9
+  }
6261c9
+  if (g != nullptr) {
6261c9
+    BN_free(dh->g);
6261c9
+    dh->g = g;
6261c9
+  }
6261c9
+
6261c9
+  return 1;
6261c9
+}
6261c9
+
6261c9
+static void DH_get0_key(const DH* dh, const BIGNUM** pub_key,
6261c9
+                        const BIGNUM** priv_key) {
6261c9
+  if (pub_key != nullptr) {
6261c9
+    *pub_key = dh->pub_key;
6261c9
+  }
6261c9
+  if (priv_key != nullptr) {
6261c9
+    *priv_key = dh->priv_key;
6261c9
+  }
6261c9
+}
6261c9
+
6261c9
+static int DH_set0_key(DH* dh, BIGNUM* pub_key, BIGNUM* priv_key) {
6261c9
+  if (pub_key != nullptr) {
6261c9
+    BN_free(dh->pub_key);
6261c9
+    dh->pub_key = pub_key;
6261c9
+  }
6261c9
+  if (priv_key != nullptr) {
6261c9
+    BN_free(dh->priv_key);
6261c9
+    dh->priv_key = priv_key;
6261c9
+  }
6261c9
+
6261c9
+  return 1;
6261c9
+}
6261c9
+
6261c9
+static const SSL_METHOD* TLS_method() { return SSLv23_method(); }
6261c9
+
6261c9
+static void SSL_SESSION_get0_ticket(const SSL_SESSION* s,
6261c9
+                                    const unsigned char** tick, size_t* len) {
6261c9
+  *len = s->tlsext_ticklen;
6261c9
+  if (tick != nullptr) {
6261c9
+    *tick = s->tlsext_tick;
6261c9
+  }
6261c9
+}
6261c9
+
6261c9
+#define SSL_get_tlsext_status_type(ssl) (ssl->tlsext_status_type)
6261c9
+
6261c9
+static int X509_STORE_up_ref(X509_STORE* store) {
6261c9
+  CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE);
6261c9
+  return 1;
6261c9
+}
6261c9
+
6261c9
+static int X509_up_ref(X509* cert) {
6261c9
+  CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
6261c9
+  return 1;
6261c9
+}
6261c9
+
6261c9
+HMAC_CTX* HMAC_CTX_new() {
6261c9
+  HMAC_CTX* ctx = Malloc<HMAC_CTX>(1);
6261c9
+  HMAC_CTX_init(ctx);
6261c9
+  return ctx;
6261c9
+}
6261c9
+
b2803b
+// Disable all TLS version lower than the version argument
b2803b
+int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version) {
b2803b
+    switch (version) {
b2803b
+        [[gnu::fallthrough]] case TLS1_2_VERSION:
b2803b
+            SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1);
b2803b
+        [[gnu::fallthrough]] case TLS1_1_VERSION:
b2803b
+            SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1);
b2803b
+        [[gnu::fallthrough]] case TLS1_VERSION:
b2803b
+            SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
b2803b
+            return 1;
b2803b
+        default:
b2803b
+            return 0;  // unsupported
b2803b
+    }
b2803b
+}
b2803b
+// Disable all TLS version higher than the version argument
b2803b
+int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version) {
b2803b
+    switch (version) {
b2803b
+        [[gnu::fallthrough]] case TLS1_VERSION:
b2803b
+            SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1);
b2803b
+        [[gnu::fallthrough]] case TLS1_1_VERSION:
b2803b
+            SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2);
b2803b
+        [[gnu::fallthrough]] case TLS1_2_VERSION:
b2803b
+            return 1;
b2803b
+        default:
b2803b
+            return 0;  // unsupported
b2803b
+    }
6261c9
+}
b2803b
+
6261c9
+#endif  // OPENSSL_VERSION_NUMBER < 0x10100000L
6261c9
+
6261c9
+
6261c9
 static const char* const root_certs[] = {
6261c9
 #include "node_root_certs.h"  // NOLINT(build/include_order)
6261c9
 };
b2803b
@@ -125,11 +256,19 @@ template void SSLWrap<TLSWrap>::AddMethods(Environment* env,
6261c9
 template void SSLWrap<TLSWrap>::ConfigureSecureContext(SecureContext* sc);
6261c9
 template void SSLWrap<TLSWrap>::SetSNIContext(SecureContext* sc);
6261c9
 template int SSLWrap<TLSWrap>::SetCACerts(SecureContext* sc);
6261c9
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
6261c9
+template SSL_SESSION* SSLWrap<TLSWrap>::GetSessionCallback(
6261c9
+    SSL* s,
6261c9
+    unsigned char* key,
6261c9
+    int len,
6261c9
+    int* copy);
6261c9
+#else
6261c9
 template SSL_SESSION* SSLWrap<TLSWrap>::GetSessionCallback(
6261c9
     SSL* s,
6261c9
     const unsigned char* key,
6261c9
     int len,
6261c9
     int* copy);
6261c9
+#endif
6261c9
 template int SSLWrap<TLSWrap>::NewSessionCallback(SSL* s,
6261c9
                                                   SSL_SESSION* sess);
6261c9
 template void SSLWrap<TLSWrap>::OnClientHello(
b2803b
@@ -148,6 +287,34 @@ template int SSLWrap<TLSWrap>::SelectALPNCallback(
6261c9
     void* arg);
6261c9
 
6261c9
 
6261c9
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
6261c9
+static Mutex* mutexes;
6261c9
+
6261c9
+static void crypto_threadid_cb(CRYPTO_THREADID* tid) {
6261c9
+  static_assert(sizeof(uv_thread_t) <= sizeof(void*),
6261c9
+                "uv_thread_t does not fit in a pointer");
6261c9
+  CRYPTO_THREADID_set_pointer(tid, reinterpret_cast<void*>(uv_thread_self()));
6261c9
+}
6261c9
+
6261c9
+
6261c9
+static void crypto_lock_init(void) {
6261c9
+  mutexes = new Mutex[CRYPTO_num_locks()];
6261c9
+}
6261c9
+
6261c9
+
6261c9
+static void crypto_lock_cb(int mode, int n, const char* file, int line) {
6261c9
+  CHECK(!(mode & CRYPTO_LOCK) ^ !(mode & CRYPTO_UNLOCK));
6261c9
+  CHECK(!(mode & CRYPTO_READ) ^ !(mode & CRYPTO_WRITE));
6261c9
+
6261c9
+  auto mutex = &mutexes[n];
6261c9
+  if (mode & CRYPTO_LOCK)
6261c9
+    mutex->Lock();
6261c9
+  else
6261c9
+    mutex->Unlock();
6261c9
+}
6261c9
+#endif
6261c9
+
6261c9
+
6261c9
 static int PasswordCallback(char* buf, int size, int rwflag, void* u) {
6261c9
   if (u) {
6261c9
     size_t buflen = static_cast<size_t>(size);
b2803b
@@ -401,7 +568,7 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
b2803b
 
b2803b
   int min_version = args[1].As<Int32>()->Value();
b2803b
   int max_version = args[2].As<Int32>()->Value();
b2803b
-  const SSL_METHOD* method = TLS_method();
b2803b
+  const SSL_METHOD* method = SSLv23_method();
b2803b
 
b2803b
   if (args[0]->IsString()) {
b2803b
     const node::Utf8Value sslmethod(env->isolate(), args[0]);
b2803b
@@ -425,9 +592,9 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
6261c9
     } else if (strcmp(*sslmethod, "SSLv23_method") == 0) {
b2803b
       // noop
6261c9
     } else if (strcmp(*sslmethod, "SSLv23_server_method") == 0) {
6261c9
-      method = TLS_server_method();
6261c9
+      method = SSLv23_server_method();
6261c9
     } else if (strcmp(*sslmethod, "SSLv23_client_method") == 0) {
6261c9
-      method = TLS_client_method();
6261c9
+      method = SSLv23_client_method();
b2803b
     } else if (strcmp(*sslmethod, "TLS_method") == 0) {
b2803b
       min_version = 0;
b2803b
       max_version = 0;
b2803b
@@ -437,33 +604,33 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
6261c9
     } else if (strcmp(*sslmethod, "TLSv1_server_method") == 0) {
b2803b
       min_version = TLS1_VERSION;
b2803b
       max_version = TLS1_VERSION;
6261c9
-      method = TLS_server_method();
b2803b
+      method = SSLv23_server_method();
6261c9
     } else if (strcmp(*sslmethod, "TLSv1_client_method") == 0) {
b2803b
       min_version = TLS1_VERSION;
b2803b
       max_version = TLS1_VERSION;
6261c9
-      method = TLS_client_method();
b2803b
+      method = SSLv23_client_method();
6261c9
     } else if (strcmp(*sslmethod, "TLSv1_1_method") == 0) {
b2803b
       min_version = TLS1_1_VERSION;
b2803b
       max_version = TLS1_1_VERSION;
6261c9
     } else if (strcmp(*sslmethod, "TLSv1_1_server_method") == 0) {
b2803b
       min_version = TLS1_1_VERSION;
b2803b
       max_version = TLS1_1_VERSION;
6261c9
-      method = TLS_server_method();
b2803b
+      method = SSLv23_server_method();
6261c9
     } else if (strcmp(*sslmethod, "TLSv1_1_client_method") == 0) {
b2803b
       min_version = TLS1_1_VERSION;
b2803b
       max_version = TLS1_1_VERSION;
6261c9
-      method = TLS_client_method();
b2803b
+      method = SSLv23_client_method();
6261c9
     } else if (strcmp(*sslmethod, "TLSv1_2_method") == 0) {
b2803b
       min_version = TLS1_2_VERSION;
b2803b
       max_version = TLS1_2_VERSION;
6261c9
     } else if (strcmp(*sslmethod, "TLSv1_2_server_method") == 0) {
b2803b
       min_version = TLS1_2_VERSION;
b2803b
       max_version = TLS1_2_VERSION;
6261c9
-      method = TLS_server_method();
b2803b
+      method = SSLv23_server_method();
6261c9
     } else if (strcmp(*sslmethod, "TLSv1_2_client_method") == 0) {
b2803b
       min_version = TLS1_2_VERSION;
b2803b
       max_version = TLS1_2_VERSION;
6261c9
-      method = TLS_client_method();
b2803b
+      method = SSLv23_client_method();
6261c9
     } else {
6261c9
       return env->ThrowError("Unknown method");
6261c9
     }
b2803b
@@ -498,6 +665,7 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
b2803b
     max_version = TLS1_2_VERSION;
b2803b
   }
6261c9
   SSL_CTX_set_max_proto_version(sc->ctx_.get(), max_version);
b2803b
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
6261c9
   // OpenSSL 1.1.0 changed the ticket key size, but the OpenSSL 1.0.x size was
b2803b
   // exposed in the public API. To retain compatibility, install a callback
b2803b
   // which restores the old algorithm.
b2803b
@@ -507,6 +675,7 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
6261c9
     return env->ThrowError("Error generating ticket keys");
6261c9
   }
6261c9
   SSL_CTX_set_tlsext_ticket_key_cb(sc->ctx_.get(), TicketCompatibilityCallback);
6261c9
+#endif
6261c9
 }
6261c9
 
6261c9
 
b2803b
@@ -937,6 +1106,11 @@ void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
6261c9
 
6261c9
   node::Utf8Value curve(env->isolate(), args[0]);
6261c9
 
6261c9
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
b2803b
+  SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_SINGLE_ECDH_USE);
b2803b
+  SSL_CTX_set_ecdh_auto(sc->ctx_.get(), 1);
6261c9
+#endif
6261c9
+
6261c9
   if (strcmp(*curve, "auto") == 0)
6261c9
     return;
6261c9
 
b2803b
@@ -1191,9 +1365,17 @@ void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
6261c9
   ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
6261c9
 
6261c9
   Local<Object> buff = Buffer::New(wrap->env(), 48).ToLocalChecked();
6261c9
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
6261c9
   memcpy(Buffer::Data(buff), wrap->ticket_key_name_, 16);
6261c9
   memcpy(Buffer::Data(buff) + 16, wrap->ticket_key_hmac_, 16);
6261c9
   memcpy(Buffer::Data(buff) + 32, wrap->ticket_key_aes_, 16);
6261c9
+#else
b2803b
+  if (SSL_CTX_get_tlsext_ticket_keys(wrap->ctx_.get(),
6261c9
+                                     Buffer::Data(buff),
6261c9
+                                     Buffer::Length(buff)) != 1) {
6261c9
+    return wrap->env()->ThrowError("Failed to fetch tls ticket keys");
6261c9
+  }
6261c9
+#endif
6261c9
 
6261c9
   args.GetReturnValue().Set(buff);
6261c9
 #endif  // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
b2803b
@@ -1217,9 +1399,17 @@ void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
6261c9
         env, "Ticket keys length must be 48 bytes");
6261c9
   }
6261c9
 
6261c9
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
6261c9
   memcpy(wrap->ticket_key_name_, Buffer::Data(args[0]), 16);
6261c9
   memcpy(wrap->ticket_key_hmac_, Buffer::Data(args[0]) + 16, 16);
6261c9
   memcpy(wrap->ticket_key_aes_, Buffer::Data(args[0]) + 32, 16);
6261c9
+#else
b2803b
+  if (SSL_CTX_set_tlsext_ticket_keys(wrap->ctx_.get(),
6261c9
+                                     Buffer::Data(args[0]),
6261c9
+                                     Buffer::Length(args[0])) != 1) {
6261c9
+    return env->ThrowError("Failed to fetch tls ticket keys");
6261c9
+  }
6261c9
+#endif
6261c9
 
6261c9
   args.GetReturnValue().Set(true);
6261c9
 #endif  // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
b2803b
@@ -1227,6 +1417,14 @@ void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
6261c9
 
6261c9
 
6261c9
 void SecureContext::SetFreeListLength(const FunctionCallbackInfo<Value>& args) {
6261c9
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
6261c9
+  // |freelist_max_len| was removed in OpenSSL 1.1.0. In that version OpenSSL
6261c9
+  // mallocs and frees buffers directly, without the use of a freelist.
6261c9
+  SecureContext* wrap;
6261c9
+  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
6261c9
+
6261c9
+  wrap->ctx_->freelist_max_len = args[0]->Int32Value();
6261c9
+#endif
6261c9
 }
6261c9
 
6261c9
 
b2803b
@@ -1323,6 +1521,7 @@ int SecureContext::TicketKeyCallback(SSL* ssl,
6261c9
 }
6261c9
 
6261c9
 
6261c9
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
6261c9
 int SecureContext::TicketCompatibilityCallback(SSL* ssl,
6261c9
                                                unsigned char* name,
6261c9
                                                unsigned char* iv,
b2803b
@@ -1357,6 +1556,7 @@ int SecureContext::TicketCompatibilityCallback(SSL* ssl,
6261c9
   }
6261c9
   return 1;
6261c9
 }
6261c9
+#endif
6261c9
 
6261c9
 
b2803b
 void SecureContext::CtxGetter(const FunctionCallbackInfo<Value>& info) {
b2803b
@@ -1433,11 +1633,19 @@ void SSLWrap<Base>::ConfigureSecureContext(SecureContext* sc) {
6261c9
 }
6261c9
 
6261c9
 
6261c9
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
6261c9
+template <class Base>
6261c9
+SSL_SESSION* SSLWrap<Base>::GetSessionCallback(SSL* s,
6261c9
+                                               unsigned char* key,
6261c9
+                                               int len,
6261c9
+                                               int* copy) {
6261c9
+#else
6261c9
 template <class Base>
6261c9
 SSL_SESSION* SSLWrap<Base>::GetSessionCallback(SSL* s,
6261c9
                                                const unsigned char* key,
6261c9
                                                int len,
6261c9
                                                int* copy) {
6261c9
+#endif
6261c9
   Base* w = static_cast<Base*>(SSL_get_app_data(s));
6261c9
 
6261c9
   *copy = 0;
b2803b
@@ -2094,6 +2302,7 @@ void SSLWrap<Base>::GetEphemeralKeyInfo(
6261c9
                   Integer::New(env->isolate(), EVP_PKEY_bits(key))).FromJust();
6261c9
         break;
6261c9
       case EVP_PKEY_EC:
6261c9
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
6261c9
       // TODO(shigeki) Change this to EVP_PKEY_X25519 and add EVP_PKEY_X448
6261c9
       // after upgrading to 1.1.1.
6261c9
       case NID_X25519:
b2803b
@@ -2114,9 +2323,24 @@ void SSLWrap<Base>::GetEphemeralKeyInfo(
6261c9
                                   curve_name)).FromJust();
6261c9
           info->Set(context, env->size_string(),
6261c9
                     Integer::New(env->isolate(),
6261c9
-                                 EVP_PKEY_bits(key))).FromJust();
6261c9
+                                  EVP_PKEY_bits(key))).FromJust();
6261c9
         }
6261c9
         break;
6261c9
+#else
6261c9
+        {
6261c9
+          EC_KEY* ec = EVP_PKEY_get1_EC_KEY(key);
6261c9
+          int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
6261c9
+          EC_KEY_free(ec);
6261c9
+          info->Set(context, env->type_string(),
6261c9
+                    FIXED_ONE_BYTE_STRING(env->isolate(), "ECDH")).FromJust();
6261c9
+          info->Set(context, env->name_string(),
6261c9
+                    OneByteString(args.GetIsolate(),
6261c9
+                                  OBJ_nid2sn(nid))).FromJust();
6261c9
+          info->Set(context, env->size_string(),
6261c9
+                    Integer::New(env->isolate(),
6261c9
+                                  EVP_PKEY_bits(key))).FromJust();
6261c9
+         }
6261c9
+#endif
6261c9
     }
6261c9
     EVP_PKEY_free(key);
6261c9
   }
b2803b
@@ -2776,10 +3000,10 @@ bool CipherBase::InitAuthenticated(const char* cipher_type, int iv_len,
6261c9
   CHECK(IsAuthenticatedMode());
6261c9
   MarkPopErrorOnReturn mark_pop_error_on_return;
6261c9
 
6261c9
-  if (!EVP_CIPHER_CTX_ctrl(ctx_.get(),
6261c9
-                           EVP_CTRL_AEAD_SET_IVLEN,
6261c9
-                           iv_len,
6261c9
-                           nullptr)) {
6261c9
+  // TODO(tniessen) Use EVP_CTRL_AEAD_SET_IVLEN when migrating to OpenSSL 1.1.0
6261c9
+  static_assert(EVP_CTRL_CCM_SET_IVLEN == EVP_CTRL_GCM_SET_IVLEN,
6261c9
+                "OpenSSL constants differ between GCM and CCM");
b2803b
+  if (!EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_GCM_SET_IVLEN, iv_len, nullptr)) {
6261c9
     env()->ThrowError("Invalid IV length");
6261c9
     return false;
6261c9
   }
b2803b
@@ -2910,6 +3134,7 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
b2803b
           "Valid GCM tag lengths are 4, 8, 12, 13, 14, 15, 16.", tag_len);
b2803b
       ProcessEmitDeprecationWarning(cipher->env(), msg, "DEP0090");
b2803b
     }
b2803b
+#ifndef OPENSSL_NO_OCB
b2803b
   } else if (mode == EVP_CIPH_OCB_MODE) {
b2803b
     // At this point, the tag length is already known and must match the
b2803b
     // length of the given authentication tag.
b2803b
@@ -2921,6 +3146,7 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
b2803b
           "Invalid authentication tag length: %u", tag_len);
b2803b
       return cipher->env()->ThrowError(msg);
b2803b
     }
b2803b
+#endif // OPENSSL_NO_OCB
b2803b
   }
b2803b
 
b2803b
   // Note: we don't use std::min() here to work around a header conflict.
b2803b
@@ -3140,8 +3366,10 @@ bool CipherBase::Final(unsigned char** out, int* out_len) {
6261c9
         CHECK(mode == EVP_CIPH_GCM_MODE);
6261c9
         auth_tag_len_ = sizeof(auth_tag_);
6261c9
       }
6261c9
-      CHECK_EQ(1, EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_GET_TAG,
6261c9
-                      auth_tag_len_,
6261c9
+      // TOOD(tniessen) Use EVP_CTRL_AEAP_GET_TAG in OpenSSL 1.1.0
6261c9
+      static_assert(EVP_CTRL_CCM_GET_TAG == EVP_CTRL_GCM_GET_TAG,
6261c9
+                    "OpenSSL constants differ between GCM and CCM");
b2803b
+      CHECK_EQ(1, EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_GCM_GET_TAG, auth_tag_len_,
6261c9
                       reinterpret_cast<unsigned char*>(auth_tag_)));
6261c9
     }
6261c9
   }
b2803b
@@ -3417,12 +3645,14 @@ void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
6261c9
 
6261c9
 SignBase::Error SignBase::Init(const char* sign_type) {
6261c9
   CHECK_NULL(mdctx_);
6261c9
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
6261c9
   // Historically, "dss1" and "DSS1" were DSA aliases for SHA-1
6261c9
   // exposed through the public API.
6261c9
   if (strcmp(sign_type, "dss1") == 0 ||
6261c9
       strcmp(sign_type, "DSS1") == 0) {
6261c9
     sign_type = "SHA1";
6261c9
   }
6261c9
+#endif
6261c9
   const EVP_MD* md = EVP_get_digestbyname(sign_type);
6261c9
   if (md == nullptr)
6261c9
     return kSignUnknownDigest;
b2803b
@@ -5587,6 +5817,12 @@ void InitCryptoOnce() {
6261c9
   SSL_library_init();
6261c9
   OpenSSL_add_all_algorithms();
6261c9
 
6261c9
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
6261c9
+  crypto_lock_init();
6261c9
+  CRYPTO_set_locking_callback(crypto_lock_cb);
6261c9
+  CRYPTO_THREADID_set_callback(crypto_threadid_cb);
6261c9
+#endif
6261c9
+
6261c9
 #ifdef NODE_FIPS_MODE
6261c9
   /* Override FIPS settings in cnf file, if needed. */
6261c9
   unsigned long err = 0;  // NOLINT(runtime/int)
6261c9
diff --git a/src/node_crypto.h b/src/node_crypto.h
b2803b
index b64a8c2..2e6042f 100644
6261c9
--- a/src/node_crypto.h
6261c9
+++ b/src/node_crypto.h
6261c9
@@ -44,8 +44,10 @@
6261c9
 #endif  // !OPENSSL_NO_ENGINE
6261c9
 #include <openssl/err.h>
6261c9
 #include <openssl/evp.h>
6261c9
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
6261c9
 // TODO(shigeki) Remove this after upgrading to 1.1.1
6261c9
 #include <openssl/obj_mac.h>
6261c9
+#endif
6261c9
 #include <openssl/pem.h>
6261c9
 #include <openssl/x509.h>
6261c9
 #include <openssl/x509v3.h>
b2803b
@@ -53,6 +55,26 @@
b2803b
 #include <openssl/rand.h>
b2803b
 #include <openssl/pkcs12.h>
b2803b
 
b2803b
+// OpenSSL backport shims
b2803b
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
b2803b
+
b2803b
+#define EVP_CTRL_AEAD_SET_TAG EVP_CTRL_CCM_SET_TAG
b2803b
+#define EVP_MD_CTX_free EVP_MD_CTX_destroy
b2803b
+#define EVP_MD_CTX_new EVP_MD_CTX_create
b2803b
+
b2803b
+#define OPENSSL_EC_EXPLICIT_CURVE 0x0
b2803b
+
b2803b
+inline void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX* ctx) { EVP_CIPHER_CTX_cleanup(ctx); }
b2803b
+inline void HMAC_CTX_free(HMAC_CTX* ctx) { if (ctx == nullptr) { return; } HMAC_CTX_cleanup(ctx); free(ctx); }
b2803b
+inline void OPENSSL_clear_free(void* ptr, size_t len) { OPENSSL_cleanse(ptr, len); OPENSSL_free(ptr); }
b2803b
+
b2803b
+inline int BN_bn2binpad(const BIGNUM* a, unsigned char *to, int tolen) {
b2803b
+    if (tolen < 0) { return -1; }
b2803b
+    OPENSSL_cleanse(to, tolen);
b2803b
+    return BN_bn2bin(a, to);
b2803b
+}
b2803b
+#endif // OPENSSL_VERSION_NUMBER < 0x10100000L
b2803b
+
b2803b
 namespace node {
b2803b
 namespace crypto {
b2803b
 
b2803b
diff --git a/test/parallel/test-crypto-authenticated.js b/test/parallel/test-crypto-authenticated.js
b2803b
index dc19a7b..5e94d41 100644
b2803b
--- a/test/parallel/test-crypto-authenticated.js
b2803b
+++ b/test/parallel/test-crypto-authenticated.js
b2803b
@@ -425,7 +425,7 @@ for (const test of TEST_CASES) {
b2803b
 // Test that create(De|C)ipher(iv)? throws if the mode is CCM or OCB and no
b2803b
 // authentication tag has been specified.
b2803b
 {
b2803b
-  for (const mode of ['ccm', 'ocb']) {
b2803b
+  for (const mode of ['ccm']) {
b2803b
     assert.throws(() => {
b2803b
       crypto.createCipheriv(`aes-256-${mode}`,
b2803b
                             'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8',
b2803b
@@ -585,7 +585,7 @@ for (const test of TEST_CASES) {
b2803b
   const key = Buffer.from('0123456789abcdef', 'utf8');
b2803b
   const iv = Buffer.from('0123456789ab', 'utf8');
b2803b
 
b2803b
-  for (const mode of ['gcm', 'ocb']) {
b2803b
+  for (const mode of ['gcm']) {
b2803b
     for (const authTagLength of mode === 'gcm' ? [undefined, 8] : [8]) {
b2803b
       const cipher = crypto.createCipheriv(`aes-128-${mode}`, key, iv, {
b2803b
         authTagLength
b2803b
diff --git a/test/parallel/test-crypto-keygen.js b/test/parallel/test-crypto-keygen.js
b2803b
index 0ffaa1c..7c567f3 100644
b2803b
--- a/test/parallel/test-crypto-keygen.js
b2803b
+++ b/test/parallel/test-crypto-keygen.js
b2803b
@@ -171,7 +171,7 @@ function convertDERToPEM(label, der) {
b2803b
     // Since the private key is encrypted, signing shouldn't work anymore.
b2803b
     assert.throws(() => {
b2803b
       testSignVerify(publicKey, privateKey);
b2803b
-    }, /bad decrypt|asn1 encoding routines/);
b2803b
+    }, /bad decrypt|bad password read|asn1 encoding routines/);
b2803b
 
b2803b
     const key = { key: privateKey, passphrase: 'secret' };
b2803b
     testEncryptDecrypt(publicKey, key);
b2803b
@@ -209,7 +209,7 @@ function convertDERToPEM(label, der) {
b2803b
     // Since the private key is encrypted, signing shouldn't work anymore.
b2803b
     assert.throws(() => {
b2803b
       testSignVerify(publicKey, privateKey);
b2803b
-    }, /bad decrypt|asn1 encoding routines/);
b2803b
+    }, /bad decrypt|bad password read|asn1 encoding routines/);
b2803b
 
b2803b
     // Signing should work with the correct password.
b2803b
     testSignVerify(publicKey, {
b2803b
@@ -269,7 +269,7 @@ function convertDERToPEM(label, der) {
b2803b
     // Since the private key is encrypted, signing shouldn't work anymore.
b2803b
     assert.throws(() => {
b2803b
       testSignVerify(publicKey, privateKey);
b2803b
-    }, /bad decrypt|asn1 encoding routines/);
b2803b
+    }, /bad decrypt|bad password read|asn1 encoding routines/);
b2803b
 
b2803b
     testSignVerify(publicKey, { key: privateKey, passphrase: 'secret' });
b2803b
   }));
b2803b
@@ -302,7 +302,7 @@ function convertDERToPEM(label, der) {
b2803b
     // Since the private key is encrypted, signing shouldn't work anymore.
b2803b
     assert.throws(() => {
b2803b
       testSignVerify(publicKey, privateKey);
b2803b
-    }, /bad decrypt|asn1 encoding routines/);
b2803b
+    }, /bad decrypt|bad password read|asn1 encoding routines/);
b2803b
 
b2803b
     testSignVerify(publicKey, {
b2803b
       key: privateKey,
b2803b
diff --git a/test/parallel/test-crypto-pbkdf2.js b/test/parallel/test-crypto-pbkdf2.js
b2803b
index 0f5d461..8701d10 100644
b2803b
--- a/test/parallel/test-crypto-pbkdf2.js
b2803b
+++ b/test/parallel/test-crypto-pbkdf2.js
b2803b
@@ -216,21 +216,3 @@ crypto.pbkdf2Sync(new Float32Array(10), 'salt', 8, 8, 'sha256');
b2803b
 crypto.pbkdf2Sync('pass', new Float32Array(10), 8, 8, 'sha256');
b2803b
 crypto.pbkdf2Sync(new Float64Array(10), 'salt', 8, 8, 'sha256');
b2803b
 crypto.pbkdf2Sync('pass', new Float64Array(10), 8, 8, 'sha256');
b2803b
-
b2803b
-assert.throws(
b2803b
-  () => crypto.pbkdf2('pass', 'salt', 8, 8, 'md55', common.mustNotCall()),
b2803b
-  {
b2803b
-    code: 'ERR_CRYPTO_INVALID_DIGEST',
b2803b
-    name: 'TypeError [ERR_CRYPTO_INVALID_DIGEST]',
b2803b
-    message: 'Invalid digest: md55'
b2803b
-  }
b2803b
-);
b2803b
-
b2803b
-assert.throws(
b2803b
-  () => crypto.pbkdf2Sync('pass', 'salt', 8, 8, 'md55'),
b2803b
-  {
b2803b
-    code: 'ERR_CRYPTO_INVALID_DIGEST',
b2803b
-    name: 'TypeError [ERR_CRYPTO_INVALID_DIGEST]',
b2803b
-    message: 'Invalid digest: md55'
b2803b
-  }
b2803b
-);
6261c9
diff --git a/test/parallel/test-tls-client-getephemeralkeyinfo.js b/test/parallel/test-tls-client-getephemeralkeyinfo.js
b2803b
index a5db18a..277d36c 100644
6261c9
--- a/test/parallel/test-tls-client-getephemeralkeyinfo.js
6261c9
+++ b/test/parallel/test-tls-client-getephemeralkeyinfo.js
b2803b
@@ -55,4 +55,3 @@ test(1024, 'DH', undefined, 'DHE-RSA-AES128-GCM-SHA256');
b2803b
 test(2048, 'DH', undefined, 'DHE-RSA-AES128-GCM-SHA256');
b2803b
 test(256, 'ECDH', 'prime256v1', 'ECDHE-RSA-AES128-GCM-SHA256');
b2803b
 test(521, 'ECDH', 'secp521r1', 'ECDHE-RSA-AES128-GCM-SHA256');
b2803b
-test(253, 'ECDH', 'X25519', 'ECDHE-RSA-AES128-GCM-SHA256');
b2803b
diff --git a/test/parallel/test-tls-passphrase.js b/test/parallel/test-tls-passphrase.js
b2803b
index 6ed19c7..b183309 100644
b2803b
--- a/test/parallel/test-tls-passphrase.js
b2803b
+++ b/test/parallel/test-tls-passphrase.js
b2803b
@@ -221,7 +221,7 @@ server.listen(0, common.mustCall(function() {
b2803b
   }, common.mustCall());
b2803b
 })).unref();
b2803b
 
b2803b
-const errMessagePassword = /bad decrypt/;
b2803b
+const errMessagePassword = /bad password read/;
b2803b
 
b2803b
 // Missing passphrase
b2803b
 assert.throws(function() {
6261c9
-- 
b2803b
2.21.0
6261c9