From a7dcf7271bae7773fe0a5626fee9b48314a5c6e8 Mon Sep 17 00:00:00 2001
From: "Thierry FOURNIER / OZON.IO" <thierry.fournier@ozon.io>
Date: Sun, 27 Nov 2016 01:29:49 +0100
Subject: [PATCH 4/4] wip 2

---
 src/ssl_sock.c | 93 +++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 53 insertions(+), 40 deletions(-)

diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 162f019..48394b1 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -2363,43 +2363,31 @@ end:
 	return ret;
 }
 
-static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, int fcount, char **err)
+static int ssl_sock_load_cert_bio(BIO *in, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, int fcount, char **err)
 {
 	int ret;
 	SSL_CTX *ctx;
-	BIO *in;
 	EVP_PKEY *key;
 
-	in = BIO_new(BIO_s_file());
-	if (in == NULL) {
-		memprintf(err, "Out of memory error.\n");
-		return 1;
-	}
-
-	if (BIO_read_filename(in, path) <= 0) {
-		memprintf(err, "Error loading file '%s'.\n", path);
-		return 1;
-	}
-
 	ctx = SSL_CTX_new(SSLv23_server_method());
 	if (!ctx) {
-		memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
-		          err && *err ? *err : "", path);
+		memprintf(err, "%sunable to allocate SSL context",
+		          err && *err ? *err : "");
 		return 1;
 	}
 
 	/* Read Private Key */
 	key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
 	if (key == NULL) {
-		memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
-		          err && *err ? *err : "", path);
+		memprintf(err, "%sunable to load SSL private key",
+		          err && *err ? *err : "");
 		SSL_CTX_free(ctx);
 		return 1;
 	}
 
 	if (SSL_CTX_use_PrivateKey(ctx, key) != 1) {
-		memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
-		          err && *err ? *err : "", path);
+		memprintf(err, "%sunable to load SSL private key",
+		          err && *err ? *err : "");
 		EVP_PKEY_free(key);
 		SSL_CTX_free(ctx);
 		return 1;
@@ -2416,37 +2404,56 @@ static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf
 
 	ret = ssl_sock_load_cert_chain_file(ctx, in, bind_conf, sni_filter, fcount);
 	if (ret <= 0) {
-		memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
-		          err && *err ? *err : "", path);
+		memprintf(err, "%sunable to load SSL certificate",
+		          err && *err ? *err : "");
 		if (ret < 0) /* serious error, must do that ourselves */
 			SSL_CTX_free(ctx);
 		return 1;
 	}
 
 	if (SSL_CTX_check_private_key(ctx) <= 0) {
-		memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
-		          err && *err ? *err : "", path);
+		memprintf(err, "%sinconsistencies between private key and certificate loaded",
+		          err && *err ? *err : "");
 		return 1;
 	}
 
 	/* we must not free the SSL_CTX anymore below, since it's already in
 	 * the tree, so it will be discovered and cleaned in time.
 	 */
-#ifndef OPENSSL_NO_DH
-	/* store a NULL pointer to indicate we have not yet loaded
-	   a custom DH param file */
-	if (ssl_dh_ptr_index >= 0) {
-		SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
+#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
+	if (bind_conf->default_ctx) {
+		memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
+		          err && *err ? *err : "");
+		return 1;
 	}
+#endif
+	if (!bind_conf->default_ctx)
+		bind_conf->default_ctx = ctx;
 
-	ret = ssl_sock_load_dh_params(ctx, path);
-	if (ret < 0) {
-		if (err)
-			memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
-				  *err ? *err : "", path);
+	return 0;
+}
+
+static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, int fcount, char **err)
+{
+	BIO *in;
+	int ret;
+
+	in = BIO_new(BIO_s_file());
+	if (in == NULL) {
+		memprintf(err, "Out of memory error.\n");
+		return 1;
+	}
+
+	if (BIO_read_filename(in, path) <= 0) {
+		memprintf(err, "Error loading file '%s'.\n", path);
+		return 1;
+	}
+
+	ret = ssl_sock_load_cert_bio(in, bind_conf, curproxy, sni_filter, fcount, err);
+	if (ret != 0) {
+		memprintf(err, "Loading file '%s': %s.\n", path, *err);
 		return 1;
 	}
-#endif
 
 #if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
 	ret = ssl_sock_load_ocsp(ctx, path);
@@ -2470,15 +2477,21 @@ static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf
 	}
 #endif
 
-#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
-	if (bind_conf->default_ctx) {
-		memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
-		          err && *err ? *err : "");
+#ifndef OPENSSL_NO_DH
+	/* store a NULL pointer to indicate we have not yet loaded
+	   a custom DH param file */
+	if (ssl_dh_ptr_index >= 0) {
+		SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
+	}
+
+	ret = ssl_sock_load_dh_params(ctx, path);
+	if (ret < 0) {
+		if (err)
+			memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
+				  *err ? *err : "", path);
 		return 1;
 	}
 #endif
-	if (!bind_conf->default_ctx)
-		bind_conf->default_ctx = ctx;
 
 	return 0;
 }
-- 
2.9.5

