]> granicus.if.org Git - curl/commitdiff
vtls: allow selecting which SSL backend to use at runtime
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Wed, 14 Jun 2017 14:56:00 +0000 (16:56 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 28 Aug 2017 12:56:58 +0000 (14:56 +0200)
When building software for the masses, it is sometimes not possible to
decide for all users which SSL backend is appropriate.

Git for Windows, for example,  uses cURL to perform clones, fetches and
pushes via HTTPS, and some users strongly prefer OpenSSL, while other
users really need to use Secure Channel because it offers
enterprise-ready tools to manage credentials via Windows' Credential
Store.

The current Git for Windows versions use the ugly work-around of
building libcurl once with OpenSSL support and once with Secure Channel
support, and switching out the binaries in the installer depending on
the user's choice.

Needless to say, this is a super ugly workaround that actually only
works in some cases: Git for Windows also comes in a portable form, and
in a form intended for third-party applications requiring Git
functionality, in which cases this "swap out libcurl-4.dll" simply is
not an option.

Therefore, the Git for Windows project has a vested interest in teaching
cURL to make the SSL backend a *runtime* option.

This patch makes that possible.

By running ./configure with multiple --with-<backend> options, cURL will
be built with multiple backends.

For the moment, the backend can be configured using the environment
variable CURL_SSL_BACKEND (valid values are e.g. "openssl" and
"schannel").

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
12 files changed:
configure.ac
lib/vtls/axtls.c
lib/vtls/cyassl.c
lib/vtls/darwinssl.c
lib/vtls/gskit.c
lib/vtls/gtls.c
lib/vtls/mbedtls.c
lib/vtls/nss.c
lib/vtls/openssl.c
lib/vtls/polarssl.c
lib/vtls/schannel.c
lib/vtls/vtls.c

index 1b3f821846ad9d161f0ed44dab27490e564f9e36..a84974b7b66507dcdb64d77b4cd7fef07e5cf3aa 100755 (executable)
@@ -165,7 +165,7 @@ curl_verbose_msg="enabled (--disable-verbose)"
   curl_mtlnk_msg="no      (--with-libmetalink)"
     curl_psl_msg="no      (--with-libpsl)"
 
-    init_ssl_msg=${curl_ssl_msg}
+    ssl_backends=
 
 dnl
 dnl Save some initial values the user might have provided
@@ -1345,13 +1345,14 @@ AC_HELP_STRING([--without-winssl], [disable Windows native SSL/TLS]),
   OPT_WINSSL=$withval)
 
 AC_MSG_CHECKING([whether to enable Windows native SSL/TLS (Windows native builds only)])
-if test "$curl_ssl_msg" = "$init_ssl_msg"; then
+if test -z "$ssl_backends" -o "x$OPT_WINSSL" != xno; then
+  ssl_msg=
   if test "x$OPT_WINSSL" != "xno"  &&
      test "x$curl_cv_native_windows" = "xyes"; then
     AC_MSG_RESULT(yes)
     AC_DEFINE(USE_SCHANNEL, 1, [to enable Windows native SSL/TLS support])
     AC_SUBST(USE_SCHANNEL, [1])
-    curl_ssl_msg="enabled (Windows-native)"
+    ssl_msg="Windows-native"
     WINSSL_ENABLED=1
     # --with-winssl implies --enable-sspi
     AC_DEFINE(USE_WINDOWS_SSPI, 1, [to enable SSPI support])
@@ -1361,6 +1362,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
   else
     AC_MSG_RESULT(no)
   fi
+  test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg"
 else
   AC_MSG_RESULT(no)
 fi
@@ -1372,18 +1374,19 @@ AC_HELP_STRING([--without-darwinssl], [disable Apple OS native SSL/TLS]),
   OPT_DARWINSSL=$withval)
 
 AC_MSG_CHECKING([whether to enable Apple OS native SSL/TLS])
-if test "$curl_ssl_msg" = "$init_ssl_msg"; then
+if test -z "$ssl_backends" -o "x$OPT_DARWINSSL" != xno; then
   if test "x$OPT_DARWINSSL" != "xno" &&
      test -d "/System/Library/Frameworks/Security.framework"; then
     AC_MSG_RESULT(yes)
     AC_DEFINE(USE_DARWINSSL, 1, [to enable Apple OS native SSL/TLS support])
     AC_SUBST(USE_DARWINSSL, [1])
-    curl_ssl_msg="enabled (Apple OS-native)"
+    ssl_msg="$ssh_backends, Apple OS-native"
     DARWINSSL_ENABLED=1
     LDFLAGS="$LDFLAGS -framework CoreFoundation -framework Security"
   else
     AC_MSG_RESULT(no)
   fi
+  test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg"
 else
   AC_MSG_RESULT(no)
 fi
@@ -1401,7 +1404,10 @@ AC_HELP_STRING([--with-ssl=PATH],[Where to look for OpenSSL, PATH points to the
 AC_HELP_STRING([--without-ssl], [disable OpenSSL]),
   OPT_SSL=$withval)
 
-if test "$curl_ssl_msg" = "$init_ssl_msg" && test X"$OPT_SSL" != Xno; then
+if test -z "$ssl_backends" -o "x$OPT_SSL" != xno &&
+   test X"$OPT_SSL" != Xno; then
+  ssl_msg=
+
   dnl backup the pre-ssl variables
   CLEANLDFLAGS="$LDFLAGS"
   CLEANCPPFLAGS="$CPPFLAGS"
@@ -1582,7 +1588,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg" && test X"$OPT_SSL" != Xno; then
       dnl Have the libraries--check for OpenSSL headers
       AC_CHECK_HEADERS(openssl/x509.h openssl/rsa.h openssl/crypto.h \
                        openssl/pem.h openssl/ssl.h openssl/err.h,
-        curl_ssl_msg="enabled (OpenSSL)"
+        ssl_msg="OpenSSL"
         OPENSSL_ENABLED=1
         AC_DEFINE(USE_OPENSSL, 1, [if OpenSSL is in use]))
 
@@ -1596,7 +1602,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg" && test X"$OPT_SSL" != Xno; then
            test $ac_cv_header_crypto_h = yes &&
            test $ac_cv_header_ssl_h = yes; then
           dnl three matches
-          curl_ssl_msg="enabled (OpenSSL)"
+          ssl_msg="OpenSSL"
           OPENSSL_ENABLED=1
         fi
       fi
@@ -1647,7 +1653,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg" && test X"$OPT_SSL" != Xno; then
         AC_MSG_RESULT([yes])
         AC_DEFINE_UNQUOTED(HAVE_BORINGSSL, 1,
                            [Define to 1 if using BoringSSL.])
-        curl_ssl_msg="enabled (BoringSSL)"
+        ssl_msg="BoringSSL"
     ],[
         AC_MSG_RESULT([no])
     ])
@@ -1663,7 +1669,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg" && test X"$OPT_SSL" != Xno; then
       AC_MSG_RESULT([yes])
       AC_DEFINE_UNQUOTED(HAVE_LIBRESSL, 1,
         [Define to 1 if using libressl.])
-      curl_ssl_msg="enabled (libressl)"
+      ssl_msg="libressl"
     ],[
       AC_MSG_RESULT([no])
     ])
@@ -1683,6 +1689,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg" && test X"$OPT_SSL" != Xno; then
     CURL_CHECK_OPENSSL_API
   fi
 
+  test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg"
 fi
 
 dnl **********************************************************************
@@ -1744,7 +1751,8 @@ AC_HELP_STRING([--with-gnutls=PATH],[where to look for GnuTLS, PATH points to th
 AC_HELP_STRING([--without-gnutls], [disable GnuTLS detection]),
   OPT_GNUTLS=$withval)
 
-if test "$curl_ssl_msg" = "$init_ssl_msg"; then
+if test -z "$ssl_backends" -o "x$OPT_GNUTLS" != xno; then
+  ssl_msg=
 
   if test X"$OPT_GNUTLS" != Xno; then
 
@@ -1818,7 +1826,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
        AC_SUBST(USE_GNUTLS, [1])
        GNUTLS_ENABLED=1
        USE_GNUTLS="yes"
-       curl_ssl_msg="enabled (GnuTLS)"
+       ssl_msg="GnuTLS"
        ],
        [
          LIBS="$CLEANLIBS"
@@ -1846,6 +1854,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
 
   fi dnl GNUTLS not disabled
 
+  test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg"
 fi
 
 dnl ---
@@ -1903,7 +1912,8 @@ AC_HELP_STRING([--with-polarssl=PATH],[where to look for PolarSSL, PATH points t
 AC_HELP_STRING([--without-polarssl], [disable PolarSSL detection]),
   OPT_POLARSSL=$withval)
 
-if test "$curl_ssl_msg" = "$init_ssl_msg"; then
+if test -z "$ssl_backends" -o "x$OPT_POLARSSL" != xno; then
+  ssl_msg=
 
   if test X"$OPT_POLARSSL" != Xno; then
 
@@ -1921,7 +1931,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
          AC_SUBST(USE_POLARSSL, [1])
          POLARSSL_ENABLED=1
          USE_POLARSSL="yes"
-         curl_ssl_msg="enabled (PolarSSL)"
+         ssl_msg="PolarSSL"
         ])
     fi
 
@@ -1947,7 +1957,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
        AC_SUBST(USE_POLARSSL, [1])
        POLARSSL_ENABLED=1
        USE_POLARSSL="yes"
-       curl_ssl_msg="enabled (PolarSSL)"
+       ssl_msg="PolarSSL"
        ],
        [
          CPPFLAGS=$_cppflags
@@ -1975,6 +1985,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
 
   fi dnl PolarSSL not disabled
 
+  test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg"
 fi
 
 dnl ----------------------------------------------------
@@ -1990,7 +2001,8 @@ AC_HELP_STRING([--with-mbedtls=PATH],[where to look for mbedTLS, PATH points to
 AC_HELP_STRING([--without-mbedtls], [disable mbedTLS detection]),
   OPT_MBEDTLS=$withval)
 
-if test "$curl_ssl_msg" = "$init_ssl_msg"; then
+if test -z "$ssl_backends" -o "x$OPT_MBEDTLS" != xno; then
+  ssl_msg=
 
   if test X"$OPT_MBEDTLS" != Xno; then
 
@@ -2008,7 +2020,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
          AC_SUBST(USE_MBEDTLS, [1])
          MBEDTLS_ENABLED=1
          USE_MBEDTLS="yes"
-         curl_ssl_msg="enabled (mbedTLS)"
+         ssl_msg="mbedTLS"
         ], [], -lmbedx509 -lmbedcrypto)
     fi
 
@@ -2034,7 +2046,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
        AC_SUBST(USE_MBEDTLS, [1])
        MBEDTLS_ENABLED=1
        USE_MBEDTLS="yes"
-       curl_ssl_msg="enabled (mbedTLS)"
+       ssl_msg="mbedTLS"
        ],
        [
          CPPFLAGS=$_cppflags
@@ -2062,6 +2074,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
 
   fi dnl mbedTLS not disabled
 
+  test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg"
 fi
 
 dnl ----------------------------------------------------
@@ -2078,7 +2091,8 @@ AC_HELP_STRING([--with-cyassl=PATH],[where to look for CyaSSL, PATH points to th
 AC_HELP_STRING([--without-cyassl], [disable CyaSSL detection]),
   OPT_CYASSL=$withval)
 
-if test "$curl_ssl_msg" = "$init_ssl_msg"; then
+if test -z "$ssl_backends" -o "x$OPT_CYASSL" != xno; then
+  ssl_msg=
 
   if test X"$OPT_CYASSL" != Xno; then
 
@@ -2100,7 +2114,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
          AC_SUBST(USE_CYASSL, [1])
          CYASSL_ENABLED=1
          USE_CYASSL="yes"
-         curl_ssl_msg="enabled (CyaSSL)"
+         ssl_msg="CyaSSL"
         ])
     fi
 
@@ -2126,7 +2140,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
        AC_SUBST(USE_CYASSL, [1])
        CYASSL_ENABLED=1
        USE_CYASSL="yes"
-       curl_ssl_msg="enabled (CyaSSL)"
+       ssl_msg="CyaSSL"
        ],
        [
          CPPFLAGS=$_cppflags
@@ -2171,7 +2185,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
          AC_SUBST(USE_CYASSL, [1])
          CYASSL_ENABLED=1
          USE_CYASSL="yes"
-         curl_ssl_msg="enabled (WolfSSL)"
+         ssl_msg="WolfSSL"
        ],
        [
          AC_MSG_RESULT(no)
@@ -2225,6 +2239,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
 
   fi dnl CyaSSL not disabled
 
+  test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg"
 fi
 
 dnl ----------------------------------------------------
@@ -2239,7 +2254,8 @@ AC_HELP_STRING([--with-nss=PATH],[where to look for NSS, PATH points to the inst
 AC_HELP_STRING([--without-nss], [disable NSS detection]),
   OPT_NSS=$withval)
 
-if test "$curl_ssl_msg" = "$init_ssl_msg"; then
+if test -z "$ssl_backends" -o "x$OPT_NSS" != xno; then
+  ssl_msg=
 
   if test X"$OPT_NSS" != Xno; then
 
@@ -2314,7 +2330,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
      AC_SUBST(USE_NSS, [1])
      USE_NSS="yes"
      NSS_ENABLED=1
-     curl_ssl_msg="enabled (NSS)"
+     ssl_msg="NSS"
      ],
      [
        LDFLAGS="$CLEANLDFLAGS"
@@ -2343,7 +2359,8 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
 
   fi dnl NSS not disabled
 
-fi dnl curl_ssl_msg = init_ssl_msg
+  test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg"
+fi
 
 OPT_AXTLS=off
 
@@ -2352,7 +2369,8 @@ AC_HELP_STRING([--with-axtls=PATH],[Where to look for axTLS, PATH points to the
 AC_HELP_STRING([--without-axtls], [disable axTLS]),
   OPT_AXTLS=$withval)
 
-if test "$curl_ssl_msg" = "$init_ssl_msg"; then
+if test -z "$ssl_backends" -o "x$OPT_AXTLS" != xno; then
+  ssl_msg=
   if test X"$OPT_AXTLS" != Xno; then
     dnl backup the pre-axtls variables
     CLEANLDFLAGS="$LDFLAGS"
@@ -2386,7 +2404,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
       AC_SUBST(USE_AXTLS, [1])
       AXTLS_ENABLED=1
       USE_AXTLS="yes"
-      curl_ssl_msg="enabled (axTLS)"
+      ssl_msg="axTLS"
 
       if test "x$cross_compiling" != "xyes"; then
         LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$LIB_AXTLS"
@@ -2399,6 +2417,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
       LIBS="$CLEANLIBS"
     ])
   fi
+  test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg"
 fi
 
 if test "x$OPENSSL_ENABLED$GNUTLS_ENABLED$NSS_ENABLED$POLARSSL_ENABLED$MBEDTLS_ENABLED$AXTLS_ENABLED$CYASSL_ENABLED$WINSSL_ENABLED$DARWINSSL_ENABLED" = "x"; then
@@ -2410,6 +2429,10 @@ else
   SSL_ENABLED="1"
 fi
 
+if test -n "$ssl_backends"; then
+  curl_ssl_msg="enabled ($ssl_backends)"
+fi
+
 dnl **********************************************************************
 dnl Check for the CA bundle
 dnl **********************************************************************
index 65f3b24092cb46351d696ede443dd01e9d1faad5..cfdb1b70fc21a8368704ac492368083bb72c3de8 100644 (file)
@@ -740,6 +740,4 @@ const struct Curl_ssl Curl_ssl_axtls = {
   NULL                            /* sha256sum */
 };
 
-const struct Curl_ssl *Curl_ssl = &Curl_ssl_axtls;
-
 #endif /* USE_AXTLS */
index 01ed678df98338b6d3c37b5cf2cf41661c397692..d679752fbda8ca62dbe7091239a1afd7cf549bad 100644 (file)
@@ -1015,6 +1015,4 @@ const struct Curl_ssl Curl_ssl_cyassl = {
   Curl_cyassl_sha256sum            /* sha256sum */
 };
 
-const struct Curl_ssl *Curl_ssl = &Curl_ssl_cyassl;
-
 #endif
index f65e93d861a833be7636ce21f3c3c0566fbda4ca..b2ca52cb72658f0be9c5496bb1c2838979d7ab66 100644 (file)
@@ -2927,8 +2927,6 @@ const struct Curl_ssl Curl_ssl_darwinssl = {
   Curl_darwinssl_sha256sum            /* sha256sum */
 };
 
-const struct Curl_ssl *Curl_ssl = &Curl_ssl_darwinssl;
-
 #ifdef __clang__
 #pragma clang diagnostic pop
 #endif
index 9d5568cf92a5ca0c9e935246c1393581fb45afa8..a1599dd5fa85d16d574fa038666e107048596af9 100644 (file)
@@ -1388,6 +1388,4 @@ const struct Curl_ssl Curl_ssl_gskit = {
   NULL                            /* sha256sum */
 };
 
-const struct Curl_ssl *Curl_ssl = &Curl_ssl_gskit;
-
 #endif /* USE_GSKIT */
index f63f5460f074de6915e419b605e557234f7dffbe..498634b29c01bc0c782a3595d8d94e59e95eea8b 100644 (file)
@@ -1839,5 +1839,4 @@ const struct Curl_ssl Curl_ssl_gnutls = {
   Curl_gtls_sha256sum            /* sha256sum */
 };
 
-const struct Curl_ssl *Curl_ssl = &Curl_ssl_gnutls;
 #endif /* USE_GNUTLS */
index 61eee09bcab60a97082cab6db2b6dd71a3e9a5a8..d7e16177bd3f490dc9b1368e35578bc0c2aa8d40 100644 (file)
@@ -1072,6 +1072,4 @@ const struct Curl_ssl Curl_ssl_mbedtls = {
   Curl_mbedtls_sha256sum            /* sha256sum */
 };
 
-const struct Curl_ssl *Curl_ssl = &Curl_ssl_mbedtls;
-
 #endif /* USE_MBEDTLS */
index 14dd154239df935bf95c4811f3cc3a8b3a339ca7..91f6530afab5d730e1b1518340fd38b28ca2be9e 100644 (file)
@@ -2378,5 +2378,4 @@ const struct Curl_ssl Curl_ssl_nss = {
   Curl_nss_sha256sum            /* sha256sum */
 };
 
-const struct Curl_ssl *Curl_ssl = &Curl_ssl_nss;
 #endif /* USE_NSS */
index a96604dd656c365ab4c6e33413a9e94f4cddfd97..136d8e4752c5b203a684757bf7e3e3be70ea6dd1 100644 (file)
@@ -3453,6 +3453,4 @@ const struct Curl_ssl Curl_ssl_openssl = {
 #endif
 };
 
-const struct Curl_ssl *Curl_ssl = &Curl_ssl_openssl;
-
 #endif /* USE_OPENSSL */
index ae3f6f81492e9003b9e768cc280f1b622439b847..9d4aeacfb7421abbee8a1f4979cfb05d8594dff5 100644 (file)
@@ -937,6 +937,4 @@ const struct Curl_ssl Curl_ssl_polarssl = {
   Curl_polarssl_sha256sum            /* sha256sum */
 };
 
-const struct Curl_ssl *Curl_ssl = &Curl_ssl_polarssl;
-
 #endif /* USE_POLARSSL */
index b1cd60e11eb0f4f4d9c6be682ccb1fce52ffddd4..bd7a85bae529368fd8f47417c69df8a2a99260b7 100644 (file)
@@ -1849,6 +1849,4 @@ const struct Curl_ssl Curl_ssl_schannel = {
   NULL                               /* sha256sum */
 };
 
-const struct Curl_ssl *Curl_ssl = &Curl_ssl_schannel;
-
 #endif /* USE_SCHANNEL */
index 3e52220fc2f56cba3697ece5bbeff1e4efebde8a..ed43e1d467badcd943d45a852bdf2ad7ce25b29c 100644 (file)
@@ -130,9 +130,14 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc)
   Curl_safefree(sslc->clientcert);
 }
 
+#ifdef USE_SSL
+static int multissl_init(void);
+#endif
+
 int Curl_ssl_backend(void)
 {
 #ifdef USE_SSL
+  multissl_init();
   return Curl_ssl->id;
 #else
   return (int)CURLSSLBACKEND_NONE;
@@ -1049,4 +1054,142 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen,
   return CURLE_OK;
 }
 
+static int Curl_multissl_init(void)
+{
+  if(multissl_init())
+    return 1;
+  return Curl_ssl->init();
+}
+
+static size_t Curl_multissl_version(char *buffer, size_t size)
+{
+  if(multissl_init())
+    return 0;
+  return Curl_ssl->version(buffer, size);
+}
+
+static CURLcode Curl_multissl_connect(struct connectdata *conn, int sockindex)
+{
+  if(multissl_init())
+    return CURLE_FAILED_INIT;
+  return Curl_ssl->connect(conn, sockindex);
+}
+
+static CURLcode Curl_multissl_connect_nonblocking(struct connectdata *conn,
+                                                  int sockindex, bool *done)
+{
+  if(multissl_init())
+    return CURLE_FAILED_INIT;
+  return Curl_ssl->connect_nonblocking(conn, sockindex, done);
+}
+
+static void *Curl_multissl_get_internals(struct ssl_connect_data *connssl,
+                                         CURLINFO info)
+{
+  if(multissl_init())
+    return NULL;
+  return Curl_ssl->get_internals(connssl, info);
+}
+
+static void Curl_multissl_close(struct connectdata *conn, int sockindex)
+{
+  if(multissl_init())
+    return;
+  Curl_ssl->close(conn, sockindex);
+}
+
+static const struct Curl_ssl Curl_ssl_multi = {
+  "multi",                           /* name */
+  CURLSSLBACKEND_NONE,
+
+  0, /* have_ca_path */
+  0, /* have_certinfo */
+  0, /* have_pinnedpubkey */
+  0, /* have_ssl_ctx */
+  0, /* support_https_proxy */
+
+  (size_t)-1, /* something insanely large to be on the safe side */
+
+  Curl_multissl_init,                /* init */
+  Curl_none_cleanup,                 /* cleanup */
+  Curl_multissl_version,             /* version */
+  Curl_none_check_cxn,               /* check_cxn */
+  Curl_none_shutdown,                /* shutdown */
+  Curl_none_data_pending,            /* data_pending */
+  Curl_none_random,                  /* random */
+  Curl_none_cert_status_request,     /* cert_status_request */
+  Curl_multissl_connect,             /* connect */
+  Curl_multissl_connect_nonblocking, /* connect_nonblocking */
+  Curl_multissl_get_internals,       /* get_internals */
+  Curl_multissl_close,               /* close */
+  Curl_none_close_all,               /* close_all */
+  Curl_none_session_free,            /* session_free */
+  Curl_none_set_engine,              /* set_engine */
+  Curl_none_set_engine_default,      /* set_engine_default */
+  Curl_none_engines_list,            /* engines_list */
+  Curl_none_false_start,             /* false_start */
+  Curl_none_md5sum,                  /* md5sum */
+  NULL                               /* sha256sum */
+};
+
+const struct Curl_ssl *Curl_ssl = &Curl_ssl_multi;
+
+static const struct Curl_ssl *available_backends[] = {
+#if defined(USE_AXTLS)
+  &Curl_ssl_axtls,
+#endif
+#if defined(USE_CYASSL)
+  &Curl_ssl_cyassl,
+#endif
+#if defined(USE_DARWINSSL)
+  &Curl_ssl_darwinssl,
+#endif
+#if defined(USE_GNUTLS)
+  &Curl_ssl_gnutls,
+#endif
+#if defined(USE_GSKIT)
+  &Curl_ssl_gskit,
+#endif
+#if defined(USE_MBEDTLS)
+  &Curl_ssl_mbedtls,
+#endif
+#if defined(USE_NSS)
+  &Curl_ssl_nss,
+#endif
+#if defined(USE_OPENSSL)
+  &Curl_ssl_openssl,
+#endif
+#if defined(USE_POLARSSL)
+  &Curl_ssl_polarssl,
+#endif
+#if defined(USE_SCHANNEL)
+  &Curl_ssl_schannel,
+#endif
+  NULL
+};
+
+static int multissl_init(void)
+{
+  const char *env;
+  int i;
+
+  if(Curl_ssl != &Curl_ssl_multi)
+    return 1;
+
+  if(!available_backends[0])
+    return 1;
+
+  env = getenv("CURL_SSL_BACKEND");
+  if(env)
+    for(i = 0; available_backends[i]; i++)
+      if(!strcmp(env, available_backends[i]->name)) {
+        Curl_ssl = available_backends[i];
+        return 0;
+      }
+
+  /* Fall back to first available backend */
+  Curl_ssl = available_backends[0];
+  return 0;
+}
+
 #endif /* USE_SSL */