From e4d92e371a19cfc01450233ed0020efb2e15cba9 Mon Sep 17 00:00:00 2001
From: Emmanuel Hocdet <manu@gandi.net>
Date: Thu, 23 Nov 2017 12:40:07 +0100
Subject: [PATCH] MINOR: ssl: Handle early data with BoringSSL

BoringSSL early data differ from OpenSSL 1.1.1 implementation. When early
handshake is done, SSL_in_early_data report if SSL_read will be done on early
data. CO_FL_EARLY_SSL_HS and CO_FL_EARLY_DATA can be adjust accordingly.
---
 src/ssl_sock.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 24bb36877..6e558b0d1 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -5000,7 +5000,7 @@ static int ssl_sock_init(struct connection *conn)
 
 		/* leave init state and start handshake */
 		conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
-#if OPENSSL_VERSION_NUMBER >= 0x10101000L
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L || defined(OPENSSL_IS_BORINGSSL)
 		conn->flags |= CO_FL_EARLY_SSL_HS;
 #endif
 
@@ -5150,6 +5150,16 @@ int ssl_sock_handshake(struct connection *conn, unsigned int flag)
 		goto reneg_ok;
 	}
 	ret = SSL_do_handshake(conn->xprt_ctx);
+#ifdef OPENSSL_IS_BORINGSSL
+	if (ret == 1 && conn->flags & CO_FL_EARLY_SSL_HS) {
+		if (SSL_in_early_data(conn->xprt_ctx)) {
+			conn->flags &= ~(CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN);
+			return 1;
+		} else {
+			conn->flags &= ~CO_FL_EARLY_SSL_HS;
+		}
+	}
+#endif
 check_error:
 	if (ret != 1) {
 		/* handshake did not complete, let's find why */
@@ -5318,7 +5328,7 @@ static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int coun
 	/* let's realign the buffer to optimize I/O */
 	if (buffer_empty(buf)) {
 		buf->p = buf->data;
-#if (OPENSSL_VERSION_NUMBER >= 0x10101000L)
+#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) || defined(OPENSSL_IS_BORINGSSL)
 		/*
 		 * If we're done reading the early data, and we're using
 		 * a new buffer, then we know for sure we're not tainted
@@ -5385,6 +5395,16 @@ static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int coun
 		} else
 #endif
 		ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
+#ifdef OPENSSL_IS_BORINGSSL
+		if (conn->flags & CO_FL_EARLY_SSL_HS) {
+			if (SSL_in_early_data(conn->xprt_ctx)) {
+				if (ret > 0)
+					conn->flags |= CO_FL_EARLY_DATA;
+			} else {
+				conn->flags &= ~(CO_FL_EARLY_SSL_HS | CO_FL_EARLY_DATA);
+			}
+		}
+#endif
 		if (conn->flags & CO_FL_ERROR) {
 			/* CO_FL_ERROR may be set by ssl_sock_infocbk */
 			goto out_error;
-- 
2.11.0

