MINOR: ssl: support Openssl 1.1.1 early callback for switchctx

Use Openssl-1.1.1 SSL_CTX_set_client_hello_cb to mimic BoringSSL early callback.
Native multi certificate and SSL/TLS method per certificate is now supported by
Openssl >= 1.1.1.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 5a8c8b5..bd8cafa 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -10399,8 +10399,9 @@
   to use both RSA and ECDSA cipher suites. Users connecting with an SNI of
   "rsa.example.com" will only be able to use RSA cipher suites, and users
   connecting with "ecdsa.example.com" will only be able to use ECDSA cipher
-  suites. With BoringSSL multi-cert is natively supported, no need to bundle
-  certificates. ECDSA certificate will be preferred if client support it.
+  suites. With BoringSSL and Openssl >= 1.1.1 multi-cert is natively supported,
+  no need to bundle certificates. ECDSA certificate will be preferred if client
+  support it.
 
   If a directory name is given as the <cert> argument, haproxy will
   automatically search and load bundled files in that directory.
@@ -10424,7 +10425,7 @@
 
   sslbindconf support "npn", "alpn", "verify", "ca-file", "no-ca-names",
   crl-file", "ecdhe", "curves", "ciphers" configuration. With BoringSSL
-  "ssl-min-ver" and "ssl-max-ver" are also supported.
+  and Openssl >= 1.1.1 "ssl-min-ver" and "ssl-max-ver" are also supported.
   It override the configuration set in bind line for the certificate.
 
   Wildcards are supported in the SNI filter. Negative filter are also supported,
@@ -10438,9 +10439,9 @@
 
   Multi-cert bundling (see "crt") is supported with crt-list, as long as only
   the base name is given in the crt-list. SNI filter will do the same work on
-  all bundled certificates. With BoringSSL multi-cert is natively supported,
-  avoid multi-cert bundling. RSA and ECDSA certificates can be declared in a
-  row, and set different ssl and filter parameter.
+  all bundled certificates. With BoringSSL and Openssl >= 1.1.1 multi-cert is
+  natively supported, avoid multi-cert bundling. RSA and ECDSA certificates can
+  be declared in a row, and set different ssl and filter parameter.
 
   crt-list file example:
         cert1.pem
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 25b846b..e1cfc66 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -1828,7 +1828,7 @@
 #ifndef SSL_OP_NO_TLSv1_2                               /* needs OpenSSL >= 1.0.1 */
 #define SSL_OP_NO_TLSv1_2 0
 #endif
-#ifndef SSL_OP_NO_TLSv1_3                               /* dev */
+#ifndef SSL_OP_NO_TLSv1_3                               /* needs OpenSSL >= 1.1.1 */
 #define SSL_OP_NO_TLSv1_3 0
 #endif
 #ifndef SSL_OP_SINGLE_DH_USE                            /* needs OpenSSL >= 0.9.6 */
@@ -1951,7 +1951,7 @@
 	SSL_set_SSL_CTX(ssl, ctx);
 }
 
-#ifdef OPENSSL_IS_BORINGSSL
+#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) || defined(OPENSSL_IS_BORINGSSL)
 
 static int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv)
 {
@@ -1963,9 +1963,14 @@
 	return SSL_TLSEXT_ERR_OK;
 }
 
+#ifdef OPENSSL_IS_BORINGSSL
 static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
 {
 	SSL *ssl = ctx->ssl;
+#else
+static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
+{
+#endif
 	struct connection *conn;
 	struct bind_conf *s;
 	const uint8_t *extension_data;
@@ -1981,8 +1986,12 @@
 	conn = SSL_get_app_data(ssl);
 	s = objt_listener(conn->target)->bind_conf;
 
+#ifdef OPENSSL_IS_BORINGSSL
 	if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name,
 						 &extension_data, &extension_len)) {
+#else
+	if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &extension_data, &extension_len)) {
+#endif
 		/*
 		 * The server_name extension was given too much extensibility when it
 		 * was written, so parsing the normal case is a bit complex.
@@ -2022,7 +2031,11 @@
 	}
 
 	/* extract/check clientHello informations */
+#ifdef OPENSSL_IS_BORINGSSL
 	if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_signature_algorithms, &extension_data, &extension_len)) {
+#else
+	if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_signature_algorithms, &extension_data, &extension_len)) {
+#endif
 		uint8_t sign;
 		size_t len;
 		if (extension_len < 2)
@@ -2057,13 +2070,21 @@
 		const SSL_CIPHER *cipher;
 		size_t len;
 		const uint8_t *cipher_suites;
+#ifdef OPENSSL_IS_BORINGSSL
 		len = ctx->cipher_suites_len;
 		cipher_suites = ctx->cipher_suites;
+#else
+		len = SSL_client_hello_get0_ciphers(ssl, &cipher_suites);
+#endif
 		if (len % 2 != 0)
 			goto abort;
 		for (; len != 0; len -= 2, cipher_suites += 2) {
+#ifdef OPENSSL_IS_BORINGSSL
 			uint16_t cipher_suite = (cipher_suites[0] << 8) | cipher_suites[1];
 			cipher = SSL_get_cipher_by_value(cipher_suite);
+#else
+			cipher = SSL_CIPHER_find(ssl, cipher_suites);
+#endif
 			if (cipher && SSL_CIPHER_get_auth_nid(cipher) == NID_auth_ecdsa) {
 				has_ecdsa = 1;
 				break;
@@ -2152,7 +2173,12 @@
  abort:
 	/* abort handshake (was SSL_TLSEXT_ERR_ALERT_FATAL) */
 	conn->err_code = CO_ER_SSL_HANDSHAKE;
+#ifdef OPENSSL_IS_BORINGSSL
 	return ssl_select_cert_error;
+#else
+	*al = SSL_AD_UNRECOGNIZED_NAME;
+	return 0;
+#endif
 }
 
 #else /* OPENSSL_IS_BORINGSSL */
@@ -3647,6 +3673,9 @@
 #ifdef OPENSSL_IS_BORINGSSL
 	SSL_CTX_set_select_certificate_cb(ctx, ssl_sock_switchctx_cbk);
 	SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
+#elif (OPENSSL_VERSION_NUMBER >= 0x10101000L)
+	SSL_CTX_set_client_hello_cb(ctx, ssl_sock_switchctx_cbk, NULL);
+	SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
 #else
 	SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
 	SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
@@ -6773,7 +6802,7 @@
 
 static int ssl_bind_parse_tls_method_minmax(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
 {
-#if !defined(OPENSSL_IS_BORINGSSL)
+#if (OPENSSL_VERSION_NUMBER < 0x10101000L) || !defined(OPENSSL_IS_BORINGSSL)
 	Warning("crt-list: ssl-min-ver and ssl-max-ver are not supported with this Openssl version (skipped).\n");
 #endif
 	return parse_tls_method_minmax(args, cur_arg, &conf->ssl_methods, err);