From 42fa1df9ff50fce456af0c4f2ea973681db90f65 Mon Sep 17 00:00:00 2001
From: Emmanuel Hocdet <manu@gandi.net>
Date: Mon, 2 Oct 2017 17:12:06 +0200
Subject: [PATCH] MINOR: ssl: build with recent BoringSSL library

BoringSSL switch OPENSSL_VERSION_NUMBER to 1.1.0 for compatibility.
Fix BoringSSL call and openssl-compat.h/#define occordingly.
This will not break openssl/libressl compat.
---
 include/proto/openssl-compat.h | 21 ++++++++++++++-------
 src/ssl_sock.c                 | 35 ++++++++++++++++++-----------------
 2 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/include/proto/openssl-compat.h b/include/proto/openssl-compat.h
index 8fe1c183c..b6fe1d2c1 100644
--- a/include/proto/openssl-compat.h
+++ b/include/proto/openssl-compat.h
@@ -89,9 +89,9 @@ static inline int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned cha
 }
 #endif
 
-#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) || defined(LIBRESSL_VERSION_NUMBER)
+#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) || defined(LIBRESSL_VERSION_NUMBER) || defined(OPENSSL_IS_BORINGSSL)
 /*
- * Functions introduced in OpenSSL 1.1.0 and not yet present in LibreSSL
+ * Functions introduced in OpenSSL 1.1.0 and not yet present in LibreSSL / BoringSSL
  */
 
 static inline const unsigned char *SSL_SESSION_get0_id_context(const SSL_SESSION *sess, unsigned int *sid_ctx_length)
@@ -107,6 +107,11 @@ static inline int SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid,
 	return 1;
 }
 
+static inline X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x)
+{
+	return x->cert_info->signature;
+}
+
 #if (!defined OPENSSL_NO_OCSP)
 static inline const OCSP_CERTID *OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *single)
 {
@@ -114,6 +119,13 @@ static inline const OCSP_CERTID *OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *
 }
 #endif
 
+#endif
+
+#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) || defined(LIBRESSL_VERSION_NUMBER)
+/*
+ * Functions introduced in OpenSSL 1.1.0 and not yet present in LibreSSL
+ */
+
 static inline pem_password_cb *SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx)
 {
 	return ctx->default_passwd_callback;
@@ -139,11 +151,6 @@ static inline const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x)
 	return x->data;
 }
 
-static inline X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x)
-{
-	return x->cert_info->signature;
-}
-
 #endif
 
 #if (OPENSSL_VERSION_NUMBER >= 0x1010000fL)
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 989d7e1cf..3058b675d 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -46,6 +46,7 @@
 #include <openssl/x509.h>
 #include <openssl/err.h>
 #include <openssl/rand.h>
+#include <openssl/hmac.h>
 #if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
 #include <openssl/ocsp.h>
 #endif
@@ -56,7 +57,7 @@
 #include <openssl/engine.h>
 #endif
 
-#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
 #include <openssl/async.h>
 #endif
 
@@ -362,7 +363,7 @@ fail_get:
 }
 #endif
 
-#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
 /*
  * openssl async fd handler
  */
@@ -1843,7 +1844,7 @@ ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_con
 #define SSL_MODE_SMALL_BUFFERS 0
 #endif
 
-#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
+#if (OPENSSL_VERSION_NUMBER < 0x1010000fL)
 typedef enum { SET_CLIENT, SET_SERVER } set_context_func;
 
 static void ctx_set_SSLv3_func(SSL_CTX *ctx, set_context_func c)
@@ -2055,7 +2056,7 @@ static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
 				goto abort;
 			}
 			cipher = SSL_get_cipher_by_value(cipher_suite);
-			if (cipher && SSL_CIPHER_is_ECDSA(cipher)) {
+			if (cipher && SSL_CIPHER_get_auth_nid(cipher) == NID_auth_ecdsa) {
 				has_ecdsa = 1;
 				break;
 			}
@@ -3606,7 +3607,7 @@ ssl_sock_initial_ctx(struct bind_conf *bind_conf)
 	conf_ssl_methods->min = min;
 	conf_ssl_methods->max = max;
 
-#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
+#if (OPENSSL_VERSION_NUMBER < 0x1010000fL)
 	/* Keep force-xxx implementation as it is in older haproxy. It's a
 	   precautionary measure to avoid any suprise with older openssl version. */
 	if (min == max)
@@ -3627,7 +3628,7 @@ ssl_sock_initial_ctx(struct bind_conf *bind_conf)
 		options &= ~SSL_OP_CIPHER_SERVER_PREFERENCE;
 	SSL_CTX_set_options(ctx, options);
 
-#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
 	if (global_ssl.async)
 		mode |= SSL_MODE_ASYNC;
 #endif
@@ -4106,7 +4107,7 @@ int ssl_sock_prepare_srv_ctx(struct server *srv)
 		cfgerr += 1;
 	}
 
-#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
+#if (OPENSSL_VERSION_NUMBER < 0x1010000fL)
 	/* Keep force-xxx implementation as it is in older haproxy. It's a
 	   precautionary measure to avoid any suprise with older openssl version. */
 	if (min == max)
@@ -4125,7 +4126,7 @@ int ssl_sock_prepare_srv_ctx(struct server *srv)
 		options |= SSL_OP_NO_TICKET;
 	SSL_CTX_set_options(ctx, options);
 
-#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
 	if (global_ssl.async)
 		mode |= SSL_MODE_ASYNC;
 #endif
@@ -4638,7 +4639,7 @@ int ssl_sock_handshake(struct connection *conn, unsigned int flag)
 				fd_cant_recv(conn->handle.fd);
 				return 0;
 			}
-#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
 			else if (ret == SSL_ERROR_WANT_ASYNC) {
 				ssl_async_process_fds(conn, conn->xprt_ctx);
 				return 0;
@@ -4722,7 +4723,7 @@ int ssl_sock_handshake(struct connection *conn, unsigned int flag)
 			fd_cant_recv(conn->handle.fd);
 			return 0;
 		}
-#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
 		else if (ret == SSL_ERROR_WANT_ASYNC) {
 			ssl_async_process_fds(conn, conn->xprt_ctx);
 			return 0;
@@ -4784,7 +4785,7 @@ int ssl_sock_handshake(struct connection *conn, unsigned int flag)
 
 reneg_ok:
 
-#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
 	/* ASYNC engine API doesn't support moving read/write
 	 * buffers. So we disable ASYNC mode right after
 	 * the handshake to avoid buffer oveflows.
@@ -4908,7 +4909,7 @@ static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int coun
 				/* handshake is running, and it needs to enable write */
 				conn->flags |= CO_FL_SSL_WAIT_HS;
 				__conn_sock_want_send(conn);
-#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
 				/* Async mode can be re-enabled, because we're leaving data state.*/
 				if (global_ssl.async)
 					SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
@@ -4920,7 +4921,7 @@ static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int coun
 					/* handshake is running, and it may need to re-enable read */
 					conn->flags |= CO_FL_SSL_WAIT_HS;
 					__conn_sock_want_recv(conn);
-#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
 					/* Async mode can be re-enabled, because we're leaving data state.*/
 					if (global_ssl.async)
 						SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
@@ -5021,7 +5022,7 @@ static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int fl
 					/* handshake is running, and it may need to re-enable write */
 					conn->flags |= CO_FL_SSL_WAIT_HS;
 					__conn_sock_want_send(conn);
-#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
 					/* Async mode can be re-enabled, because we're leaving data state.*/
 					if (global_ssl.async)
 						SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
@@ -5036,7 +5037,7 @@ static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int fl
 				/* handshake is running, and it needs to enable read */
 				conn->flags |= CO_FL_SSL_WAIT_HS;
 				__conn_sock_want_recv(conn);
-#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
 				/* Async mode can be re-enabled, because we're leaving data state.*/
 				if (global_ssl.async)
 					SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
@@ -5060,7 +5061,7 @@ static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int fl
 static void ssl_sock_close(struct connection *conn) {
 
 	if (conn->xprt_ctx) {
-#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
 		if (global_ssl.async) {
 			OSSL_ASYNC_FD all_fd[32], afd;
 			size_t num_all_fds = 0;
@@ -7389,7 +7390,7 @@ static int ssl_parse_global_ssl_async(char **args, int section_type, struct prox
                                        struct proxy *defpx, const char *file, int line,
                                        char **err)
 {
-#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
 	global_ssl.async = 1;
 	return 0;
 #else
-- 
2.11.0

