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

13eaef
diff --git a/doc/api/cli.md b/doc/api/cli.md
13eaef
index fdc1d790f1..619a9b11c4 100644
13eaef
--- a/doc/api/cli.md
13eaef
+++ b/doc/api/cli.md
13eaef
@@ -670,14 +670,6 @@ added: v12.0.0
13eaef
 Set [`tls.DEFAULT_MAX_VERSION`][] to 'TLSv1.2'. Use to disable support for
13eaef
 TLSv1.3.
13eaef
 
13eaef
-### `--tls-max-v1.3`
13eaef
-
13eaef
-added: v12.0.0
13eaef
--->
13eaef
-
13eaef
-Set default [`tls.DEFAULT_MAX_VERSION`][] to 'TLSv1.3'. Use to enable support
13eaef
-for TLSv1.3.
13eaef
-
13eaef
 ### `--tls-min-v1.0`
13eaef
 
13eaef
 added: v12.0.0
13eaef
@@ -703,14 +695,6 @@ Set default [`tls.DEFAULT_MIN_VERSION`][] to 'TLSv1.2'. This is the default for
13eaef
 12.x and later, but the option is supported for compatibility with older Node.js
13eaef
 versions.
13eaef
 
13eaef
-### `--tls-min-v1.3`
13eaef
-
13eaef
-added: v12.0.0
13eaef
--->
13eaef
-
13eaef
-Set default [`tls.DEFAULT_MIN_VERSION`][] to 'TLSv1.3'. Use to disable support
13eaef
-for TLSv1.2, which is not as secure as TLSv1.3.
13eaef
-
13eaef
 ### `--trace-deprecation`
13eaef
 
13eaef
 added: v0.8.0
13eaef
@@ -1042,11 +1026,9 @@ Node.js options that are allowed are:
13eaef
 - `--title`
13eaef
 - `--tls-cipher-list`
13eaef
 - `--tls-max-v1.2`
13eaef
-- `--tls-max-v1.3`
13eaef
 - `--tls-min-v1.0`
13eaef
 - `--tls-min-v1.1`
13eaef
 - `--tls-min-v1.2`
13eaef
-- `--tls-min-v1.3`
13eaef
 - `--trace-deprecation`
13eaef
 - `--trace-event-categories`
13eaef
 - `--trace-event-file-pattern`
13eaef
diff --git a/lib/_tls_common.js b/lib/_tls_common.js
13eaef
index efe9040956..a88bbdc7fd 100644
13eaef
--- a/lib/_tls_common.js
13eaef
+++ b/lib/_tls_common.js
13eaef
@@ -49,7 +49,7 @@ function toV(which, v, def) {
13eaef
   if (v === 'TLSv1') return TLS1_VERSION;
13eaef
   if (v === 'TLSv1.1') return TLS1_1_VERSION;
13eaef
   if (v === 'TLSv1.2') return TLS1_2_VERSION;
13eaef
-  if (v === 'TLSv1.3') return TLS1_3_VERSION;
13eaef
+  if (v === 'TLSv1.3' && TLS1_3_VERSION) return TLS1_3_VERSION;
13eaef
   throw new ERR_TLS_INVALID_PROTOCOL_VERSION(v, which);
13eaef
 }
13eaef
 
13eaef
diff --git a/lib/internal/crypto/keygen.js b/lib/internal/crypto/keygen.js
13eaef
index 0a4bde77fa..33e88e2065 100644
13eaef
--- a/lib/internal/crypto/keygen.js
13eaef
+++ b/lib/internal/crypto/keygen.js
13eaef
@@ -9,10 +9,10 @@ const {
13eaef
   generateKeyPairDSA,
13eaef
   generateKeyPairEC,
13eaef
   generateKeyPairNid,
13eaef
-  EVP_PKEY_ED25519,
13eaef
-  EVP_PKEY_ED448,
13eaef
-  EVP_PKEY_X25519,
13eaef
-  EVP_PKEY_X448,
13eaef
+  //EVP_PKEY_ED25519,
13eaef
+  //EVP_PKEY_ED448,
13eaef
+  //EVP_PKEY_X25519,
13eaef
+  //EVP_PKEY_X448,
13eaef
   OPENSSL_EC_NAMED_CURVE,
13eaef
   OPENSSL_EC_EXPLICIT_CURVE
13eaef
 } = internalBinding('crypto');
13eaef
diff --git a/lib/tls.js b/lib/tls.js
13eaef
index 2ac43c01d3..429ccfd214 100644
13eaef
--- a/lib/tls.js
13eaef
+++ b/lib/tls.js
13eaef
@@ -62,17 +62,10 @@ else if (getOptionValue('--tls-min-v1.1'))
13eaef
   exports.DEFAULT_MIN_VERSION = 'TLSv1.1';
13eaef
 else if (getOptionValue('--tls-min-v1.2'))
13eaef
   exports.DEFAULT_MIN_VERSION = 'TLSv1.2';
13eaef
-else if (getOptionValue('--tls-min-v1.3'))
13eaef
-  exports.DEFAULT_MIN_VERSION = 'TLSv1.3';
13eaef
 else
13eaef
   exports.DEFAULT_MIN_VERSION = 'TLSv1.2';
13eaef
 
13eaef
-if (getOptionValue('--tls-max-v1.3'))
13eaef
-  exports.DEFAULT_MAX_VERSION = 'TLSv1.3';
13eaef
-else if (getOptionValue('--tls-max-v1.2'))
13eaef
-  exports.DEFAULT_MAX_VERSION = 'TLSv1.2';
13eaef
-else
13eaef
-  exports.DEFAULT_MAX_VERSION = 'TLSv1.3'; // Will depend on node version.
13eaef
+exports.DEFAULT_MAX_VERSION = 'TLSv1.2'; // Will depend on node version.
13eaef
 
13eaef
 
13eaef
 exports.getCiphers = internalUtil.cachedResult(
13eaef
diff --git a/src/node_constants.cc b/src/node_constants.cc
13eaef
index 7c9e4ce276..df349e69d6 100644
13eaef
--- a/src/node_constants.cc
13eaef
+++ b/src/node_constants.cc
13eaef
@@ -956,8 +956,12 @@ void DefineCryptoConstants(Local<Object> target) {
13eaef
     NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_RAND);
13eaef
 # endif
13eaef
 
13eaef
-# ifdef ENGINE_METHOD_EC
13eaef
-    NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_EC);
13eaef
+# ifdef ENGINE_METHOD_ECDH
13eaef
+    NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_ECDH);
13eaef
+# endif
13eaef
+
13eaef
+# ifdef ENGINE_METHOD_ECDSA
13eaef
+    NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_ECDSA);
13eaef
 # endif
13eaef
 
13eaef
 # ifdef ENGINE_METHOD_CIPHERS
13eaef
@@ -968,6 +972,10 @@ void DefineCryptoConstants(Local<Object> target) {
13eaef
     NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_DIGESTS);
13eaef
 # endif
13eaef
 
13eaef
+# ifdef ENGINE_METHOD_STORE
13eaef
+    NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_STORE);
13eaef
+# endif
13eaef
+
13eaef
 # ifdef ENGINE_METHOD_PKEY_METHS
13eaef
     NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_PKEY_METHS);
13eaef
 # endif
13eaef
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
13eaef
index e32cdac70c..2af7d03e78 100644
13eaef
--- a/src/node_crypto.cc
13eaef
+++ b/src/node_crypto.cc
13eaef
@@ -55,6 +55,7 @@
13eaef
 #include <cstring>
13eaef
 
13eaef
 #include <algorithm>
13eaef
+#include <atomic>
13eaef
 #include <memory>
13eaef
 #include <utility>
13eaef
 #include <vector>
13eaef
@@ -128,6 +129,230 @@ struct OpenSSLBufferDeleter {
13eaef
 };
13eaef
 using OpenSSLBuffer = std::unique_ptr<char[], OpenSSLBufferDeleter>;
13eaef
 
13eaef
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
13eaef
+static void RSA_get0_key(const RSA* r, const BIGNUM** n, const BIGNUM** e,
13eaef
+                         const BIGNUM** d) {
13eaef
+  if (n != nullptr) {
13eaef
+    *n = r->n;
13eaef
+  }
13eaef
+  if (e != nullptr) {
13eaef
+    *e = r->e;
13eaef
+  }
13eaef
+  if (d != nullptr) {
13eaef
+    *d = r->d;
13eaef
+  }
13eaef
+}
13eaef
+
13eaef
+static void DH_get0_pqg(const DH* dh, const BIGNUM** p, const BIGNUM** q,
13eaef
+                        const BIGNUM** g) {
13eaef
+  if (p != nullptr) {
13eaef
+    *p = dh->p;
13eaef
+  }
13eaef
+  if (q != nullptr) {
13eaef
+    *q = dh->q;
13eaef
+  }
13eaef
+  if (g != nullptr) {
13eaef
+    *g = dh->g;
13eaef
+  }
13eaef
+}
13eaef
+
13eaef
+static int DH_set0_pqg(DH* dh, BIGNUM* p, BIGNUM* q, BIGNUM* g) {
13eaef
+  if ((dh->p == nullptr && p == nullptr) ||
13eaef
+      (dh->g == nullptr && g == nullptr)) {
13eaef
+    return 0;
13eaef
+  }
13eaef
+
13eaef
+  if (p != nullptr) {
13eaef
+    BN_free(dh->p);
13eaef
+    dh->p = p;
13eaef
+  }
13eaef
+  if (q != nullptr) {
13eaef
+    BN_free(dh->q);
13eaef
+    dh->q = q;
13eaef
+  }
13eaef
+  if (g != nullptr) {
13eaef
+    BN_free(dh->g);
13eaef
+    dh->g = g;
13eaef
+  }
13eaef
+
13eaef
+  return 1;
13eaef
+}
13eaef
+
13eaef
+static void DH_get0_key(const DH* dh, const BIGNUM** pub_key,
13eaef
+                        const BIGNUM** priv_key) {
13eaef
+  if (pub_key != nullptr) {
13eaef
+    *pub_key = dh->pub_key;
13eaef
+  }
13eaef
+  if (priv_key != nullptr) {
13eaef
+    *priv_key = dh->priv_key;
13eaef
+  }
13eaef
+}
13eaef
+
13eaef
+static int DH_set0_key(DH* dh, BIGNUM* pub_key, BIGNUM* priv_key) {
13eaef
+  if (pub_key != nullptr) {
13eaef
+    BN_free(dh->pub_key);
13eaef
+    dh->pub_key = pub_key;
13eaef
+  }
13eaef
+  if (priv_key != nullptr) {
13eaef
+    BN_free(dh->priv_key);
13eaef
+    dh->priv_key = priv_key;
13eaef
+  }
13eaef
+
13eaef
+  return 1;
13eaef
+}
13eaef
+
13eaef
+static int EC_GROUP_order_bits(const EC_GROUP *group) {
13eaef
+  int num_bits = 0;
13eaef
+  BIGNUM *order = BN_new();
13eaef
+  BN_CTX *ctx = BN_CTX_new();
13eaef
+  if (order == nullptr || ctx == nullptr) { goto end; }
13eaef
+
13eaef
+  if (EC_GROUP_get_order(group, order, ctx) != 1) { goto end; }
13eaef
+  num_bits = BN_num_bits(order);
13eaef
+
13eaef
+end:
13eaef
+  BN_CTX_free(ctx), ctx = nullptr;
13eaef
+  BN_free(order), order = nullptr;
13eaef
+
13eaef
+  return num_bits;
13eaef
+}
13eaef
+
13eaef
+static int EVP_PKEY_up_ref(EVP_PKEY *pkey) {
13eaef
+  int refcount = std::atomic_fetch_add_explicit(
13eaef
+    reinterpret_cast<std::atomic<int>*>(&pkey->references),
13eaef
+    1,
13eaef
+    std::memory_order_relaxed
13eaef
+  ) + 1;
13eaef
+  return (refcount > 1) ? 1 : 0;
13eaef
+}
13eaef
+static unsigned long EVP_MD_meth_get_flags(const EVP_MD *md) {
13eaef
+  return md->flags;
13eaef
+}
13eaef
+static int EVP_DigestSign(
13eaef
+  EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
13eaef
+  const unsigned char *tbs, size_t tbslen)
13eaef
+{
13eaef
+  if (sigret != nullptr && EVP_DigestSignUpdate(ctx, tbs, tbslen) <= 0) {
13eaef
+    return 0;
13eaef
+  }
13eaef
+  return EVP_DigestSignFinal(ctx, sigret, siglen);
13eaef
+}
13eaef
+static int EVP_DigestVerify(
13eaef
+  EVP_MD_CTX *ctx, const unsigned char *sigret,
13eaef
+  size_t siglen, const unsigned char *tbs, size_t tbslen)
13eaef
+{
13eaef
+  if (EVP_DigestVerifyUpdate(ctx, tbs, tbslen) <= 0) {
13eaef
+    return -1;
13eaef
+  }
13eaef
+  return EVP_DigestVerifyFinal(ctx, sigret, siglen);
13eaef
+}
13eaef
+
13eaef
+static const SSL_METHOD* TLS_method() { return SSLv23_method(); }
13eaef
+
13eaef
+static void SSL_SESSION_get0_ticket(const SSL_SESSION* s,
13eaef
+                                    const unsigned char** tick, size_t* len) {
13eaef
+  *len = s->tlsext_ticklen;
13eaef
+  if (tick != nullptr) {
13eaef
+    *tick = s->tlsext_tick;
13eaef
+  }
13eaef
+}
13eaef
+
13eaef
+#define SSL_get_tlsext_status_type(ssl) (ssl->tlsext_status_type)
13eaef
+
13eaef
+static int X509_STORE_up_ref(X509_STORE* store) {
13eaef
+  CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE);
13eaef
+  return 1;
13eaef
+}
13eaef
+
13eaef
+static int X509_up_ref(X509* cert) {
13eaef
+  CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
13eaef
+  return 1;
13eaef
+}
13eaef
+
13eaef
+HMAC_CTX* HMAC_CTX_new() {
13eaef
+  HMAC_CTX* ctx = Malloc<HMAC_CTX>(1);
13eaef
+  HMAC_CTX_init(ctx);
13eaef
+  return ctx;
13eaef
+}
13eaef
+
13eaef
+// Disable all TLS version lower than the version argument
13eaef
+int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version) {
13eaef
+    switch (version) {
13eaef
+        case TLS1_2_VERSION:
13eaef
+            SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1);
13eaef
+            [[fallthrough]];
13eaef
+
13eaef
+        case TLS1_1_VERSION:
13eaef
+            SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1);
13eaef
+            [[fallthrough]];
13eaef
+
13eaef
+        case TLS1_VERSION:
13eaef
+            SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2);
13eaef
+            return 1;
13eaef
+
13eaef
+        default:
13eaef
+            return 0;  // unsupported
13eaef
+    }
13eaef
+}
13eaef
+// Extract minimum supported version. Should be inverse of the setter above.
13eaef
+int SSL_CTX_get_min_proto_version(SSL_CTX *ctx) {
13eaef
+  static const auto full_mask = SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1;
13eaef
+
13eaef
+  auto opts = SSL_CTX_get_options(ctx);
13eaef
+
13eaef
+  switch (opts & full_mask) {
13eaef
+    case SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1:
13eaef
+      return TLS1_2_VERSION;
13eaef
+
13eaef
+    case SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1:
13eaef
+      return TLS1_1_VERSION;
13eaef
+
13eaef
+    case SSL_OP_NO_SSLv3:
13eaef
+      return TLS1_VERSION;
13eaef
+
13eaef
+    default:
13eaef
+      return 0;
13eaef
+  }
13eaef
+}
13eaef
+
13eaef
+// Disable all TLS version higher than the version argument
13eaef
+int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version) {
13eaef
+    switch (version) {
13eaef
+        case TLS1_VERSION:
13eaef
+            SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1);
13eaef
+            [[fallthrough]];
13eaef
+
13eaef
+        case TLS1_1_VERSION:
13eaef
+            SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2);
13eaef
+            [[fallthrough]];
13eaef
+
13eaef
+        case TLS1_2_VERSION:
13eaef
+            return 1;
13eaef
+
13eaef
+        default:
13eaef
+            return 0;  // unsupported
13eaef
+    }
13eaef
+}
13eaef
+// Extract maximum supported version. Should be inverse of the setter above.
13eaef
+int SSL_CTX_get_max_proto_version(SSL_CTX *ctx) {
13eaef
+  static const auto full_mask = SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2;
13eaef
+
13eaef
+  auto opts = SSL_CTX_get_options(ctx);
13eaef
+  switch (opts & full_mask) {
13eaef
+    case SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2:
13eaef
+      return TLS1_VERSION;
13eaef
+
13eaef
+    case SSL_OP_NO_TLSv1_2:
13eaef
+      return TLS1_1_VERSION;
13eaef
+
13eaef
+    default:
13eaef
+      return 0;
13eaef
+  }
13eaef
+}
13eaef
+
13eaef
+#endif  // OPENSSL_VERSION_NUMBER < 0x10100000L
13eaef
+
13eaef
+
13eaef
 static const char* const root_certs[] = {
13eaef
 #include "node_root_certs.h"  // NOLINT(build/include_order)
13eaef
 };
13eaef
@@ -144,11 +369,19 @@ template void SSLWrap<TLSWrap>::AddMethods(Environment* env,
13eaef
 template void SSLWrap<TLSWrap>::ConfigureSecureContext(SecureContext* sc);
13eaef
 template void SSLWrap<TLSWrap>::SetSNIContext(SecureContext* sc);
13eaef
 template int SSLWrap<TLSWrap>::SetCACerts(SecureContext* sc);
13eaef
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
13eaef
+template SSL_SESSION* SSLWrap<TLSWrap>::GetSessionCallback(
13eaef
+    SSL* s,
13eaef
+    unsigned char* key,
13eaef
+    int len,
13eaef
+    int* copy);
13eaef
+#else
13eaef
 template SSL_SESSION* SSLWrap<TLSWrap>::GetSessionCallback(
13eaef
     SSL* s,
13eaef
     const unsigned char* key,
13eaef
     int len,
13eaef
     int* copy);
13eaef
+#endif
13eaef
 template int SSLWrap<TLSWrap>::NewSessionCallback(SSL* s,
13eaef
                                                   SSL_SESSION* sess);
13eaef
 template void SSLWrap<TLSWrap>::KeylogCallback(const SSL* s,
13eaef
@@ -168,6 +401,35 @@ template int SSLWrap<TLSWrap>::SelectALPNCallback(
13eaef
     unsigned int inlen,
13eaef
     void* arg);
13eaef
 
13eaef
+
13eaef
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
13eaef
+static Mutex* mutexes;
13eaef
+
13eaef
+static void crypto_threadid_cb(CRYPTO_THREADID* tid) {
13eaef
+  static_assert(sizeof(uv_thread_t) <= sizeof(void*),
13eaef
+                "uv_thread_t does not fit in a pointer");
13eaef
+  CRYPTO_THREADID_set_pointer(tid, reinterpret_cast<void*>(uv_thread_self()));
13eaef
+}
13eaef
+
13eaef
+
13eaef
+static void crypto_lock_init(void) {
13eaef
+  mutexes = new Mutex[CRYPTO_num_locks()];
13eaef
+}
13eaef
+
13eaef
+
13eaef
+static void crypto_lock_cb(int mode, int n, const char* file, int line) {
13eaef
+  CHECK(!(mode & CRYPTO_LOCK) ^ !(mode & CRYPTO_UNLOCK));
13eaef
+  CHECK(!(mode & CRYPTO_READ) ^ !(mode & CRYPTO_WRITE));
13eaef
+
13eaef
+  auto mutex = &mutexes[n];
13eaef
+  if (mode & CRYPTO_LOCK)
13eaef
+    mutex->Lock();
13eaef
+  else
13eaef
+    mutex->Unlock();
13eaef
+}
13eaef
+#endif
13eaef
+
13eaef
+
13eaef
 static int PasswordCallback(char* buf, int size, int rwflag, void* u) {
13eaef
   const char* passphrase = static_cast<char*>(u);
13eaef
   if (passphrase != nullptr) {
13eaef
@@ -299,15 +561,10 @@ Maybe<bool> Decorate(Environment* env, Local<Object> obj,
13eaef
     V(COMP)                                                                   \
13eaef
     V(ECDSA)                                                                  \
13eaef
     V(ECDH)                                                                   \
13eaef
-    V(OSSL_STORE)                                                             \
13eaef
     V(FIPS)                                                                   \
13eaef
     V(CMS)                                                                    \
13eaef
     V(TS)                                                                     \
13eaef
     V(HMAC)                                                                   \
13eaef
-    V(CT)                                                                     \
13eaef
-    V(ASYNC)                                                                  \
13eaef
-    V(KDF)                                                                    \
13eaef
-    V(SM2)                                                                    \
13eaef
     V(USER)                                                                   \
13eaef
 
13eaef
 #define V(name) case ERR_LIB_##name: lib = #name "_"; break;
13eaef
@@ -533,9 +790,13 @@ void SecureContext::New(const FunctionCallbackInfo<Value>& args) {
13eaef
   new SecureContext(env, args.This());
13eaef
 }
13eaef
 
13eaef
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
 // A maxVersion of 0 means "any", but OpenSSL may support TLS versions that
13eaef
 // Node.js doesn't, so pin the max to what we do support.
13eaef
 const int MAX_SUPPORTED_VERSION = TLS1_3_VERSION;
13eaef
+#else
13eaef
+const int MAX_SUPPORTED_VERSION = TLS1_2_VERSION;
13eaef
+#endif
13eaef
 
13eaef
 void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
13eaef
   SecureContext* sc;
13eaef
@@ -548,7 +809,7 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
13eaef
 
13eaef
   int min_version = args[1].As<Int32>()->Value();
13eaef
   int max_version = args[2].As<Int32>()->Value();
13eaef
-  const SSL_METHOD* method = TLS_method();
13eaef
+  const SSL_METHOD* method = SSLv23_method();
13eaef
 
13eaef
   if (max_version == 0)
13eaef
     max_version = MAX_SUPPORTED_VERSION;
13eaef
@@ -582,54 +843,57 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
13eaef
       max_version = TLS1_2_VERSION;
13eaef
     } else if (strcmp(*sslmethod, "SSLv23_server_method") == 0) {
13eaef
       max_version = TLS1_2_VERSION;
13eaef
-      method = TLS_server_method();
13eaef
+      method = SSLv23_server_method();
13eaef
     } else if (strcmp(*sslmethod, "SSLv23_client_method") == 0) {
13eaef
       max_version = TLS1_2_VERSION;
13eaef
-      method = TLS_client_method();
13eaef
+      method = SSLv23_client_method();
13eaef
     } else if (strcmp(*sslmethod, "TLS_method") == 0) {
13eaef
       min_version = 0;
13eaef
       max_version = MAX_SUPPORTED_VERSION;
13eaef
     } else if (strcmp(*sslmethod, "TLS_server_method") == 0) {
13eaef
       min_version = 0;
13eaef
       max_version = MAX_SUPPORTED_VERSION;
13eaef
-      method = TLS_server_method();
13eaef
+      method = SSLv23_server_method();
13eaef
     } else if (strcmp(*sslmethod, "TLS_client_method") == 0) {
13eaef
       min_version = 0;
13eaef
       max_version = MAX_SUPPORTED_VERSION;
13eaef
-      method = TLS_client_method();
13eaef
+      method = SSLv23_client_method();
13eaef
     } else if (strcmp(*sslmethod, "TLSv1_method") == 0) {
13eaef
       min_version = TLS1_VERSION;
13eaef
       max_version = TLS1_VERSION;
13eaef
+      method = TLSv1_method();
13eaef
     } else if (strcmp(*sslmethod, "TLSv1_server_method") == 0) {
13eaef
       min_version = TLS1_VERSION;
13eaef
       max_version = TLS1_VERSION;
13eaef
-      method = TLS_server_method();
13eaef
+      method = TLSv1_server_method();
13eaef
     } else if (strcmp(*sslmethod, "TLSv1_client_method") == 0) {
13eaef
       min_version = TLS1_VERSION;
13eaef
       max_version = TLS1_VERSION;
13eaef
-      method = TLS_client_method();
13eaef
+      method = TLSv1_client_method();
13eaef
     } else if (strcmp(*sslmethod, "TLSv1_1_method") == 0) {
13eaef
       min_version = TLS1_1_VERSION;
13eaef
       max_version = TLS1_1_VERSION;
13eaef
+      method = TLSv1_1_method();
13eaef
     } else if (strcmp(*sslmethod, "TLSv1_1_server_method") == 0) {
13eaef
       min_version = TLS1_1_VERSION;
13eaef
       max_version = TLS1_1_VERSION;
13eaef
-      method = TLS_server_method();
13eaef
+      method = TLSv1_1_server_method();
13eaef
     } else if (strcmp(*sslmethod, "TLSv1_1_client_method") == 0) {
13eaef
       min_version = TLS1_1_VERSION;
13eaef
       max_version = TLS1_1_VERSION;
13eaef
-      method = TLS_client_method();
13eaef
+      method = TLSv1_1_client_method();
13eaef
     } else if (strcmp(*sslmethod, "TLSv1_2_method") == 0) {
13eaef
       min_version = TLS1_2_VERSION;
13eaef
       max_version = TLS1_2_VERSION;
13eaef
+      method = TLSv1_2_method();
13eaef
     } else if (strcmp(*sslmethod, "TLSv1_2_server_method") == 0) {
13eaef
       min_version = TLS1_2_VERSION;
13eaef
       max_version = TLS1_2_VERSION;
13eaef
-      method = TLS_server_method();
13eaef
+      method = TLSv1_2_server_method();
13eaef
     } else if (strcmp(*sslmethod, "TLSv1_2_client_method") == 0) {
13eaef
       min_version = TLS1_2_VERSION;
13eaef
       max_version = TLS1_2_VERSION;
13eaef
-      method = TLS_client_method();
13eaef
+      method = TLSv1_2_client_method();
13eaef
     } else {
13eaef
       const std::string msg("Unknown method: ");
13eaef
       THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, (msg + * sslmethod).c_str());
13eaef
@@ -659,9 +923,16 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
13eaef
                                  SSL_SESS_CACHE_NO_INTERNAL |
13eaef
                                  SSL_SESS_CACHE_NO_AUTO_CLEAR);
13eaef
 
13eaef
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
13eaef
+  if (max_version == 0) {
13eaef
+    // Selecting some secureProtocol methods allows the TLS version to be "any
13eaef
+    // supported", but we don't support TLSv1.3, even if OpenSSL does.
13eaef
+    max_version = TLS1_2_VERSION;
13eaef
+  }
13eaef
+#endif
13eaef
   SSL_CTX_set_min_proto_version(sc->ctx_.get(), min_version);
13eaef
   SSL_CTX_set_max_proto_version(sc->ctx_.get(), max_version);
13eaef
-
13eaef
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
   // OpenSSL 1.1.0 changed the ticket key size, but the OpenSSL 1.0.x size was
13eaef
   // exposed in the public API. To retain compatibility, install a callback
13eaef
   // which restores the old algorithm.
13eaef
@@ -671,6 +942,7 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
13eaef
     return env->ThrowError("Error generating ticket keys");
13eaef
   }
13eaef
   SSL_CTX_set_tlsext_ticket_key_cb(sc->ctx_.get(), TicketCompatibilityCallback);
13eaef
+#endif
13eaef
 }
13eaef
 
13eaef
 
13eaef
@@ -1131,6 +1403,7 @@ void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
13eaef
   CHECK_EQ(args.Length(), 1);
13eaef
   CHECK(args[0]->IsString());
13eaef
 
13eaef
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
   const node::Utf8Value ciphers(args.GetIsolate(), args[0]);
13eaef
   if (!SSL_CTX_set_cipher_list(sc->ctx_.get(), *ciphers)) {
13eaef
     unsigned long err = ERR_get_error();  // NOLINT(runtime/int)
13eaef
@@ -1146,6 +1419,32 @@ void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
13eaef
       // that's actually an error.
13eaef
       return;
13eaef
     }
13eaef
+#else
13eaef
+  // Note: set_ciphersuites() is for TLSv1.3 and was introduced in openssl
13eaef
+  // 1.1.1, set_cipher_list() is for TLSv1.2 and earlier.
13eaef
+  //
13eaef
+  // In openssl 1.1.0, set_cipher_list() would error if it resulted in no
13eaef
+  // TLSv1.2 (and earlier) cipher suites, and there is no TLSv1.3 support.
13eaef
+  //
13eaef
+  // In openssl 1.1.1, set_cipher_list() will not error if it results in no
13eaef
+  // TLSv1.2 cipher suites if there are any TLSv1.3 cipher suites, which there
13eaef
+  // are by default. There will be an error later, during the handshake, but
13eaef
+  // that results in an async error event, rather than a sync error thrown,
13eaef
+  // which is a semver-major change for the tls API.
13eaef
+  //
13eaef
+  // Since we don't currently support TLSv1.3, work around this by removing the
13eaef
+  // TLSv1.3 cipher suites, so we get backwards compatible synchronous errors.
13eaef
+  const node::Utf8Value ciphers(args.GetIsolate(), args[0]);
13eaef
+  if (
13eaef
+#if defined(TLS1_3_VERSION) && !defined(OPENSSL_IS_BORINGSSL)
13eaef
+      !SSL_CTX_set_ciphersuites(sc->ctx_.get(), "") ||
13eaef
+#endif
13eaef
+      !SSL_CTX_set_cipher_list(sc->ctx_.get(), *ciphers)) {
13eaef
+    unsigned long err = ERR_get_error();  // NOLINT(runtime/int)
13eaef
+    if (!err) {
13eaef
+      return env->ThrowError("Failed to set ciphers");
13eaef
+    }
13eaef
+#endif
13eaef
     return ThrowCryptoError(env, err);
13eaef
   }
13eaef
 }
13eaef
@@ -1163,6 +1462,11 @@ void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
13eaef
 
13eaef
   node::Utf8Value curve(env->isolate(), args[0]);
13eaef
 
13eaef
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
13eaef
+  SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_SINGLE_ECDH_USE);
13eaef
+  SSL_CTX_set_ecdh_auto(sc->ctx_.get(), 1);
13eaef
+#endif
13eaef
+
13eaef
   if (strcmp(*curve, "auto") == 0)
13eaef
     return;
13eaef
 
13eaef
@@ -1468,9 +1772,17 @@ void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
13eaef
   ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
13eaef
 
13eaef
   Local<Object> buff = Buffer::New(wrap->env(), 48).ToLocalChecked();
13eaef
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
   memcpy(Buffer::Data(buff), wrap->ticket_key_name_, 16);
13eaef
   memcpy(Buffer::Data(buff) + 16, wrap->ticket_key_hmac_, 16);
13eaef
   memcpy(Buffer::Data(buff) + 32, wrap->ticket_key_aes_, 16);
13eaef
+#else
13eaef
+  if (SSL_CTX_set_tlsext_ticket_keys(wrap->ctx_.get(),
13eaef
+                                     Buffer::Data(buff),
13eaef
+                                     Buffer::Length(buff)) != 1) {
13eaef
+    return wrap->env()->ThrowError("Failed to fetch tls ticket keys");
13eaef
+  }
13eaef
+#endif
13eaef
 
13eaef
   args.GetReturnValue().Set(buff);
13eaef
 #endif  // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
13eaef
@@ -1506,6 +1818,14 @@ void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
13eaef
 
13eaef
 
13eaef
 void SecureContext::SetFreeListLength(const FunctionCallbackInfo<Value>& args) {
13eaef
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
13eaef
+  // |freelist_max_len| was removed in OpenSSL 1.1.0. In that version OpenSSL
13eaef
+  // mallocs and frees buffers directly, without the use of a freelist.
13eaef
+  SecureContext* wrap;
13eaef
+  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
13eaef
+
13eaef
+  wrap->ctx_->freelist_max_len = args[0].As<Int32>()->Value();
13eaef
+#endif
13eaef
 }
13eaef
 
13eaef
 
13eaef
@@ -1608,6 +1928,7 @@ int SecureContext::TicketKeyCallback(SSL* ssl,
13eaef
 }
13eaef
 
13eaef
 
13eaef
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
 int SecureContext::TicketCompatibilityCallback(SSL* ssl,
13eaef
                                                unsigned char* name,
13eaef
                                                unsigned char* iv,
13eaef
@@ -1642,6 +1963,7 @@ int SecureContext::TicketCompatibilityCallback(SSL* ssl,
13eaef
   }
13eaef
   return 1;
13eaef
 }
13eaef
+#endif
13eaef
 
13eaef
 
13eaef
 void SecureContext::CtxGetter(const FunctionCallbackInfo<Value>& info) {
13eaef
@@ -1719,11 +2041,19 @@ void SSLWrap<Base>::ConfigureSecureContext(SecureContext* sc) {
13eaef
 }
13eaef
 
13eaef
 
13eaef
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
13eaef
+template <class Base>
13eaef
+SSL_SESSION* SSLWrap<Base>::GetSessionCallback(SSL* s,
13eaef
+                                               unsigned char* key,
13eaef
+                                               int len,
13eaef
+                                               int* copy) {
13eaef
+#else
13eaef
 template <class Base>
13eaef
 SSL_SESSION* SSLWrap<Base>::GetSessionCallback(SSL* s,
13eaef
                                                const unsigned char* key,
13eaef
                                                int len,
13eaef
                                                int* copy) {
13eaef
+#endif
13eaef
   Base* w = static_cast<Base*>(SSL_get_app_data(s));
13eaef
 
13eaef
   *copy = 0;
13eaef
@@ -2488,6 +2818,7 @@ void SSLWrap<Base>::GetEphemeralKeyInfo(
13eaef
             .Check();
13eaef
         break;
13eaef
       case EVP_PKEY_EC:
13eaef
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
       case EVP_PKEY_X25519:
13eaef
       case EVP_PKEY_X448:
13eaef
         {
13eaef
@@ -2510,6 +2841,21 @@ void SSLWrap<Base>::GetEphemeralKeyInfo(
13eaef
                                  EVP_PKEY_bits(key.get()))).Check();
13eaef
         }
13eaef
         break;
13eaef
+#else
13eaef
+        {
13eaef
+          EC_KEY* ec = EVP_PKEY_get1_EC_KEY(key.get());
13eaef
+          int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
13eaef
+          EC_KEY_free(ec);
13eaef
+          info->Set(context, env->type_string(),
13eaef
+                    FIXED_ONE_BYTE_STRING(env->isolate(), "ECDH")).Check();
13eaef
+          info->Set(context, env->name_string(),
13eaef
+                    OneByteString(args.GetIsolate(),
13eaef
+                                  OBJ_nid2sn(nid))).Check();
13eaef
+          info->Set(context, env->size_string(),
13eaef
+                    Integer::New(env->isolate(),
13eaef
+                                  EVP_PKEY_bits(key.get()))).Check();
13eaef
+         }
13eaef
+#endif
13eaef
       default:
13eaef
         break;
13eaef
     }
13eaef
@@ -3735,12 +4081,15 @@ Local<Value> KeyObject::GetAsymmetricKeyType() const {
13eaef
   switch (EVP_PKEY_id(this->asymmetric_key_.get())) {
13eaef
   case EVP_PKEY_RSA:
13eaef
     return env()->crypto_rsa_string();
13eaef
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
   case EVP_PKEY_RSA_PSS:
13eaef
     return env()->crypto_rsa_pss_string();
13eaef
+#endif
13eaef
   case EVP_PKEY_DSA:
13eaef
     return env()->crypto_dsa_string();
13eaef
   case EVP_PKEY_EC:
13eaef
     return env()->crypto_ec_string();
13eaef
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
   case EVP_PKEY_ED25519:
13eaef
     return env()->crypto_ed25519_string();
13eaef
   case EVP_PKEY_ED448:
13eaef
@@ -3749,6 +4098,7 @@ Local<Value> KeyObject::GetAsymmetricKeyType() const {
13eaef
     return env()->crypto_x25519_string();
13eaef
   case EVP_PKEY_X448:
13eaef
     return env()->crypto_x448_string();
13eaef
+#endif
13eaef
   default:
13eaef
     return Undefined(env()->isolate());
13eaef
   }
13eaef
@@ -4044,10 +4394,10 @@ bool CipherBase::InitAuthenticated(const char* cipher_type, int iv_len,
13eaef
   CHECK(IsAuthenticatedMode());
13eaef
   MarkPopErrorOnReturn mark_pop_error_on_return;
13eaef
 
13eaef
-  if (!EVP_CIPHER_CTX_ctrl(ctx_.get(),
13eaef
-                           EVP_CTRL_AEAD_SET_IVLEN,
13eaef
-                           iv_len,
13eaef
-                           nullptr)) {
13eaef
+  // TODO(tniessen) Use EVP_CTRL_AEAD_SET_IVLEN when migrating to OpenSSL 1.1.0
13eaef
+  static_assert(EVP_CTRL_CCM_SET_IVLEN == EVP_CTRL_GCM_SET_IVLEN,
13eaef
+                "OpenSSL constants differ between GCM and CCM");
13eaef
+  if (!EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_GCM_SET_IVLEN, iv_len, nullptr)) {
13eaef
     env()->ThrowError("Invalid IV length");
13eaef
     return false;
13eaef
   }
13eaef
@@ -4395,8 +4745,12 @@ bool CipherBase::Final(AllocatedBuffer* out) {
13eaef
         CHECK(mode == EVP_CIPH_GCM_MODE);
13eaef
         auth_tag_len_ = sizeof(auth_tag_);
13eaef
       }
13eaef
-      CHECK_EQ(1, EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_GET_TAG,
13eaef
-                      auth_tag_len_,
13eaef
+//      CHECK_EQ(1, EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_GET_TAG,
13eaef
+//                      auth_tag_len_,
13eaef
+      // TOOD(tniessen) Use EVP_CTRL_AEAP_GET_TAG in OpenSSL 1.1.0
13eaef
+      static_assert(EVP_CTRL_CCM_GET_TAG == EVP_CTRL_GCM_GET_TAG,
13eaef
+                    "OpenSSL constants differ between GCM and CCM");
13eaef
+      CHECK_EQ(1, EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_GCM_GET_TAG, auth_tag_len_,
13eaef
                       reinterpret_cast<unsigned char*>(auth_tag_)));
13eaef
     }
13eaef
   }
13eaef
@@ -4676,8 +5030,12 @@ void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
13eaef
       ret = EVP_DigestFinal_ex(hash->mdctx_.get(), hash->md_value_,
13eaef
                                &hash->md_len_);
13eaef
     } else {
13eaef
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
       ret = EVP_DigestFinalXOF(hash->mdctx_.get(), hash->md_value_,
13eaef
                                hash->md_len_);
13eaef
+#else
13eaef
+      return env->ThrowError("Unsupported XOF digest");
13eaef
+#endif  // OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
     }
13eaef
 
13eaef
     if (ret != 1) {
13eaef
@@ -4707,12 +5065,14 @@ void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
13eaef
 
13eaef
 SignBase::Error SignBase::Init(const char* sign_type) {
13eaef
   CHECK_NULL(mdctx_);
13eaef
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
   // Historically, "dss1" and "DSS1" were DSA aliases for SHA-1
13eaef
   // exposed through the public API.
13eaef
   if (strcmp(sign_type, "dss1") == 0 ||
13eaef
       strcmp(sign_type, "DSS1") == 0) {
13eaef
     sign_type = "SHA1";
13eaef
   }
13eaef
+#endif
13eaef
   const EVP_MD* md = EVP_get_digestbyname(sign_type);
13eaef
   if (md == nullptr)
13eaef
     return kSignUnknownDigest;
13eaef
@@ -4781,9 +5141,14 @@ static bool ApplyRSAOptions(const ManagedEVPPKey& pkey,
13eaef
                             EVP_PKEY_CTX* pkctx,
13eaef
                             int padding,
13eaef
                             const Maybe<int>& salt_len) {
13eaef
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
   if (EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA ||
13eaef
       EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA2 ||
13eaef
       EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA_PSS) {
13eaef
+#else
13eaef
+  if (EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA ||
13eaef
+      EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA2) {
13eaef
+#endif
13eaef
     if (EVP_PKEY_CTX_set_rsa_padding(pkctx, padding) <= 0)
13eaef
       return false;
13eaef
     if (padding == RSA_PKCS1_PSS_PADDING && salt_len.IsJust()) {
13eaef
@@ -4838,9 +5203,13 @@ void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
13eaef
   sign->CheckThrow(err);
13eaef
 }
13eaef
 
13eaef
-static int GetDefaultSignPadding(const ManagedEVPPKey& key) {
13eaef
+static int GetDefaultSignPadding([[maybe_unused]] const ManagedEVPPKey& key) {
13eaef
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
13eaef
+  return RSA_PKCS1_PADDING;
13eaef
+#else
13eaef
   return EVP_PKEY_id(key.get()) == EVP_PKEY_RSA_PSS ? RSA_PKCS1_PSS_PADDING :
13eaef
                                                       RSA_PKCS1_PADDING;
13eaef
+#endif  // OPENSSL_VERSION_NUMBER < 0x10100000L
13eaef
 }
13eaef
 
13eaef
 static AllocatedBuffer Node_SignFinal(Environment* env,
13eaef
@@ -5991,9 +6360,24 @@ struct PBKDF2Job : public CryptoJob {
13eaef
   }
13eaef
 
13eaef
   inline void DoThreadPoolWork() override {
13eaef
-    auto salt_data = reinterpret_cast<const unsigned char*>(salt.data());
13eaef
+    static const auto *empty = "";
13eaef
+
13eaef
+    auto pass_data = reinterpret_cast<const char *>(empty);
13eaef
+    auto pass_size = int(0);
13eaef
+    auto salt_data = reinterpret_cast<const unsigned char *>(empty);
13eaef
+    auto salt_size = int(0);
13eaef
+
13eaef
+    if (pass.size() > 0) {
13eaef
+      pass_data = pass.data();
13eaef
+      pass_size = pass.size();
13eaef
+    }
13eaef
+    if (salt.size() > 0) {
13eaef
+      salt_data = reinterpret_cast<const unsigned char *>(salt.data());
13eaef
+      salt_size = salt.size();
13eaef
+    }
13eaef
+
13eaef
     const bool ok =
13eaef
-        PKCS5_PBKDF2_HMAC(pass.data(), pass.size(), salt_data, salt.size(),
13eaef
+        PKCS5_PBKDF2_HMAC(pass_data, pass_size, salt_data, salt_size,
13eaef
                           iteration_count, digest, keybuf_size, keybuf_data);
13eaef
     success = Just(ok);
13eaef
     Cleanse();
13eaef
@@ -6176,6 +6560,7 @@ class RSAKeyPairGenerationConfig : public KeyPairGenerationConfig {
13eaef
   const unsigned int exponent_;
13eaef
 };
13eaef
 
13eaef
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
 class RSAPSSKeyPairGenerationConfig : public RSAKeyPairGenerationConfig {
13eaef
  public:
13eaef
   RSAPSSKeyPairGenerationConfig(unsigned int modulus_bits,
13eaef
@@ -6217,6 +6602,7 @@ class RSAPSSKeyPairGenerationConfig : public RSAKeyPairGenerationConfig {
13eaef
   const EVP_MD* mgf1_md_;
13eaef
   const int saltlen_;
13eaef
 };
13eaef
+#endif
13eaef
 
13eaef
 class DSAKeyPairGenerationConfig : public KeyPairGenerationConfig {
13eaef
  public:
13eaef
@@ -6292,6 +6678,7 @@ class ECKeyPairGenerationConfig : public KeyPairGenerationConfig {
13eaef
   const int param_encoding_;
13eaef
 };
13eaef
 
13eaef
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
 class NidKeyPairGenerationConfig : public KeyPairGenerationConfig {
13eaef
  public:
13eaef
   explicit NidKeyPairGenerationConfig(int id) : id_(id) {}
13eaef
@@ -6303,6 +6690,7 @@ class NidKeyPairGenerationConfig : public KeyPairGenerationConfig {
13eaef
  private:
13eaef
   const int id_;
13eaef
 };
13eaef
+#endif
13eaef
 
13eaef
 class GenerateKeyPairJob : public CryptoJob {
13eaef
  public:
13eaef
@@ -6447,6 +6835,7 @@ void GenerateKeyPairRSA(const FunctionCallbackInfo<Value>& args) {
13eaef
   GenerateKeyPair(args, 2, std::move(config));
13eaef
 }
13eaef
 
13eaef
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
 void GenerateKeyPairRSAPSS(const FunctionCallbackInfo<Value>& args) {
13eaef
   Environment* env = Environment::GetCurrent(args);
13eaef
 
13eaef
@@ -6484,6 +6873,7 @@ void GenerateKeyPairRSAPSS(const FunctionCallbackInfo<Value>& args) {
13eaef
                                         md, mgf1_md, saltlen));
13eaef
   GenerateKeyPair(args, 5, std::move(config));
13eaef
 }
13eaef
+#endif
13eaef
 
13eaef
 void GenerateKeyPairDSA(const FunctionCallbackInfo<Value>& args) {
13eaef
   CHECK(args[0]->IsUint32());
13eaef
@@ -6515,6 +6905,7 @@ void GenerateKeyPairEC(const FunctionCallbackInfo<Value>& args) {
13eaef
   GenerateKeyPair(args, 2, std::move(config));
13eaef
 }
13eaef
 
13eaef
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
 void GenerateKeyPairNid(const FunctionCallbackInfo<Value>& args) {
13eaef
   CHECK(args[0]->IsInt32());
13eaef
   const int id = args[0].As<Int32>()->Value();
13eaef
@@ -6522,6 +6913,7 @@ void GenerateKeyPairNid(const FunctionCallbackInfo<Value>& args) {
13eaef
       new NidKeyPairGenerationConfig(id));
13eaef
   GenerateKeyPair(args, 1, std::move(config));
13eaef
 }
13eaef
+#endif
13eaef
 
13eaef
 
13eaef
 void GetSSLCiphers(const FunctionCallbackInfo<Value>& args) {
13eaef
@@ -6545,6 +6937,7 @@ void GetSSLCiphers(const FunctionCallbackInfo<Value>& args) {
13eaef
                            SSL_CIPHER_get_name(cipher))).Check();
13eaef
   }
13eaef
 
13eaef
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
   // TLSv1.3 ciphers aren't listed by EVP. There are only 5, we could just
13eaef
   // document them, but since there are only 5, easier to just add them manually
13eaef
   // and not have to explain their absence in the API docs. They are lower-cased
13eaef
@@ -6562,6 +6955,7 @@ void GetSSLCiphers(const FunctionCallbackInfo<Value>& args) {
13eaef
     arr->Set(env->context(),
13eaef
              arr->Length(), OneByteString(args.GetIsolate(), name)).Check();
13eaef
   }
13eaef
+#endif
13eaef
 
13eaef
   args.GetReturnValue().Set(arr);
13eaef
 }
13eaef
@@ -6815,6 +7209,12 @@ void InitCryptoOnce() {
13eaef
   SSL_library_init();
13eaef
   OpenSSL_add_all_algorithms();
13eaef
 
13eaef
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
13eaef
+  crypto_lock_init();
13eaef
+  CRYPTO_set_locking_callback(crypto_lock_cb);
13eaef
+  CRYPTO_THREADID_set_callback(crypto_threadid_cb);
13eaef
+#endif
13eaef
+
13eaef
 #ifdef NODE_FIPS_MODE
13eaef
   /* Override FIPS settings in cnf file, if needed. */
13eaef
   unsigned long err = 0;  // NOLINT(runtime/int)
13eaef
@@ -6936,14 +7336,18 @@ void Initialize(Local<Object> target,
13eaef
 
13eaef
   env->SetMethod(target, "pbkdf2", PBKDF2);
13eaef
   env->SetMethod(target, "generateKeyPairRSA", GenerateKeyPairRSA);
13eaef
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
   env->SetMethod(target, "generateKeyPairRSAPSS", GenerateKeyPairRSAPSS);
13eaef
+#endif
13eaef
   env->SetMethod(target, "generateKeyPairDSA", GenerateKeyPairDSA);
13eaef
   env->SetMethod(target, "generateKeyPairEC", GenerateKeyPairEC);
13eaef
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
   env->SetMethod(target, "generateKeyPairNid", GenerateKeyPairNid);
13eaef
   NODE_DEFINE_CONSTANT(target, EVP_PKEY_ED25519);
13eaef
   NODE_DEFINE_CONSTANT(target, EVP_PKEY_ED448);
13eaef
   NODE_DEFINE_CONSTANT(target, EVP_PKEY_X25519);
13eaef
   NODE_DEFINE_CONSTANT(target, EVP_PKEY_X448);
13eaef
+#endif
13eaef
   NODE_DEFINE_CONSTANT(target, OPENSSL_EC_NAMED_CURVE);
13eaef
   NODE_DEFINE_CONSTANT(target, OPENSSL_EC_EXPLICIT_CURVE);
13eaef
   NODE_DEFINE_CONSTANT(target, kKeyEncodingPKCS1);
13eaef
diff --git a/src/node_crypto.h b/src/node_crypto.h
13eaef
index 99e6c48117..667fa87ad2 100644
13eaef
--- a/src/node_crypto.h
13eaef
+++ b/src/node_crypto.h
13eaef
@@ -36,6 +36,41 @@
13eaef
 #include <openssl/err.h>
13eaef
 #include <openssl/ssl.h>
13eaef
 
13eaef
+// OpenSSL backport shims
13eaef
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
13eaef
+
13eaef
+// Declare what OpenSSL features we do not support
13eaef
+// Pretending we are BoringSSL can also help
13eaef
+#define OPENSSL_IS_BORINGSSL
13eaef
+#define OPENSSL_NO_OCB
13eaef
+#define OPENSSL_NO_SCRYPT
13eaef
+
13eaef
+#define EVP_CTRL_AEAD_SET_TAG EVP_CTRL_CCM_SET_TAG
13eaef
+#define EVP_MD_CTX_free EVP_MD_CTX_destroy
13eaef
+#define EVP_MD_CTX_new EVP_MD_CTX_create
13eaef
+
13eaef
+// Values from upstream
13eaef
+#define OPENSSL_EC_EXPLICIT_CURVE           0x0
13eaef
+#define NID_chacha20_poly1305               1018
13eaef
+#define EVP_MD_FLAG_XOF                     0x0002
13eaef
+#define EVP_F_EVP_DIGESTFINALXOF            0
13eaef
+#define EVP_R_NOT_XOF_OR_INVALID_LENGTH     178
13eaef
+
13eaef
+inline void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX* ctx) { EVP_CIPHER_CTX_cleanup(ctx); }
13eaef
+inline void HMAC_CTX_free(HMAC_CTX* ctx) { if (ctx == nullptr) { return; } HMAC_CTX_cleanup(ctx); free(ctx); }
13eaef
+inline void OPENSSL_clear_free(void* ptr, size_t len) {
13eaef
+  if (ptr == nullptr) { return; }
13eaef
+  OPENSSL_cleanse(ptr, len);
13eaef
+  OPENSSL_free(ptr);
13eaef
+}
13eaef
+
13eaef
+inline int BN_bn2binpad(const BIGNUM* a, unsigned char *to, int tolen) {
13eaef
+    if (tolen < 0 || to == nullptr) { return -1; }
13eaef
+    OPENSSL_cleanse(to, tolen);
13eaef
+    return BN_bn2bin(a, to);
13eaef
+}
13eaef
+#endif // OPENSSL_VERSION_NUMBER < 0x10100000L
13eaef
+
13eaef
 namespace node {
13eaef
 namespace crypto {
13eaef
 
13eaef
@@ -230,10 +265,17 @@ class SSLWrap {
13eaef
   static void ConfigureSecureContext(SecureContext* sc);
13eaef
   static void AddMethods(Environment* env, v8::Local<v8::FunctionTemplate> t);
13eaef
 
13eaef
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
13eaef
+  static SSL_SESSION* GetSessionCallback(SSL* s,
13eaef
+                                         unsigned char* key,
13eaef
+                                         int len,
13eaef
+                                         int* copy);
13eaef
+#else
13eaef
   static SSL_SESSION* GetSessionCallback(SSL* s,
13eaef
                                          const unsigned char* key,
13eaef
                                          int len,
13eaef
                                          int* copy);
13eaef
+#endif
13eaef
   static int NewSessionCallback(SSL* s, SSL_SESSION* sess);
13eaef
   static void KeylogCallback(const SSL* s, const char* line);
13eaef
   static void OnClientHello(void* arg,
13eaef
diff --git a/src/node_crypto_bio.cc b/src/node_crypto_bio.cc
13eaef
index fc143043ba..75b55eb30c 100644
13eaef
--- a/src/node_crypto_bio.cc
13eaef
+++ b/src/node_crypto_bio.cc
13eaef
@@ -30,8 +30,18 @@
13eaef
 namespace node {
13eaef
 namespace crypto {
13eaef
 
13eaef
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
13eaef
+#define BIO_set_data(bio, data) bio->ptr = data
13eaef
+#define BIO_get_data(bio) bio->ptr
13eaef
+#define BIO_set_shutdown(bio, shutdown_) bio->shutdown = shutdown_
13eaef
+#define BIO_get_shutdown(bio) bio->shutdown
13eaef
+#define BIO_set_init(bio, init_) bio->init = init_
13eaef
+#define BIO_get_init(bio) bio->init
13eaef
+#endif
13eaef
+
13eaef
+
13eaef
 BIOPointer NodeBIO::New(Environment* env) {
13eaef
-  BIOPointer bio(BIO_new(GetMethod()));
13eaef
+  BIOPointer bio(BIO_new(const_cast<BIO_METHOD*>(GetMethod())));
13eaef
   if (bio && env != nullptr)
13eaef
     NodeBIO::FromBIO(bio.get())->env_ = env;
13eaef
   return bio;
13eaef
@@ -221,6 +231,22 @@ long NodeBIO::Ctrl(BIO* bio, int cmd, long num,  // NOLINT(runtime/int)
13eaef
 
13eaef
 
13eaef
 const BIO_METHOD* NodeBIO::GetMethod() {
13eaef
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
13eaef
+  static const BIO_METHOD method = {
13eaef
+    BIO_TYPE_MEM,
13eaef
+    "node.js SSL buffer",
13eaef
+    Write,
13eaef
+    Read,
13eaef
+    Puts,
13eaef
+    Gets,
13eaef
+    Ctrl,
13eaef
+    New,
13eaef
+    Free,
13eaef
+    nullptr
13eaef
+  };
13eaef
+
13eaef
+  return &method;
13eaef
+#else
13eaef
   // This is called from InitCryptoOnce() to avoid race conditions during
13eaef
   // initialization.
13eaef
   static BIO_METHOD* method = nullptr;
13eaef
@@ -237,6 +263,7 @@ const BIO_METHOD* NodeBIO::GetMethod() {
13eaef
   }
13eaef
 
13eaef
   return method;
13eaef
+#endif
13eaef
 }
13eaef
 
13eaef
 
13eaef
diff --git a/src/node_errors.h b/src/node_errors.h
13eaef
index 261c6077bb..85a68f8acd 100644
13eaef
--- a/src/node_errors.h
13eaef
+++ b/src/node_errors.h
13eaef
@@ -148,8 +148,8 @@ inline v8::Local<v8::Value> ERR_STRING_TOO_LONG(v8::Isolate* isolate) {
13eaef
 
13eaef
 #define THROW_AND_RETURN_IF_NOT_STRING(env, val, prefix)                     \
13eaef
   do {                                                                       \
13eaef
-    if (!val->IsString())                                                    \
13eaef
-      return node::THROW_ERR_INVALID_ARG_TYPE(env,                           \
13eaef
+    if (!(val)->IsString())                                                  \
13eaef
+      return node::THROW_ERR_INVALID_ARG_TYPE((env),                         \
13eaef
                                               prefix " must be a string");   \
13eaef
   } while (0)
13eaef
 
13eaef
diff --git a/src/node_options.cc b/src/node_options.cc
13eaef
index 98049453d8..5d40231b11 100644
13eaef
--- a/src/node_options.cc
13eaef
+++ b/src/node_options.cc
13eaef
@@ -528,10 +528,12 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
13eaef
             "set default TLS minimum to TLSv1.2 (default: TLSv1.2)",
13eaef
             &EnvironmentOptions::tls_min_v1_2,
13eaef
             kAllowedInEnvironment);
13eaef
+#ifdef TLS1_3_VERSION
13eaef
   AddOption("--tls-min-v1.3",
13eaef
             "set default TLS minimum to TLSv1.3 (default: TLSv1.2)",
13eaef
             &EnvironmentOptions::tls_min_v1_3,
13eaef
             kAllowedInEnvironment);
13eaef
+#endif // TLS1_3_VERSION
13eaef
   AddOption("--tls-max-v1.2",
13eaef
             "set default TLS maximum to TLSv1.2 (default: TLSv1.3)",
13eaef
             &EnvironmentOptions::tls_max_v1_2,
13eaef
@@ -540,10 +542,12 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
13eaef
   // - 11.x and below: TLS1.3 is opt-in with --tls-max-v1.3
13eaef
   // - 12.x: TLS1.3 is opt-out with --tls-max-v1.2
13eaef
   // In either case, support both options they are uniformly available.
13eaef
+#ifdef TLS1_3_VERSION
13eaef
   AddOption("--tls-max-v1.3",
13eaef
             "set default TLS maximum to TLSv1.3 (default: TLSv1.3)",
13eaef
             &EnvironmentOptions::tls_max_v1_3,
13eaef
             kAllowedInEnvironment);
13eaef
+#endif // TLS1_3_VERSION
13eaef
 }
13eaef
 
13eaef
 PerIsolateOptionsParser::PerIsolateOptionsParser(
13eaef
diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc
13eaef
index 2d36c1a265..26af6e2fa8 100644
13eaef
--- a/src/tls_wrap.cc
13eaef
+++ b/src/tls_wrap.cc
13eaef
@@ -910,11 +910,13 @@ void TLSWrap::EnableSessionCallbacks(
13eaef
 
13eaef
 void TLSWrap::EnableKeylogCallback(
13eaef
     const FunctionCallbackInfo<Value>& args) {
13eaef
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
   TLSWrap* wrap;
13eaef
   ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
13eaef
   CHECK_NOT_NULL(wrap->sc_);
13eaef
   SSL_CTX_set_keylog_callback(wrap->sc_->ctx_.get(),
13eaef
       SSLWrap<TLSWrap>::KeylogCallback);
13eaef
+#endif // OPENSSL_VERSION_NUMBER >= 0x10100000L
13eaef
 }
13eaef
 
13eaef
 // Check required capabilities were not excluded from the OpenSSL build: