MEDIUM: ssl: support SNI filters with multicerts

SNI filters used to be ignored with multicerts (eg: those providing
ECDSA and RSA at the same time). This patch makes them work like
other certs.

Note: most of the changes in this patch are due to an extra level of
      indent, read it with "git show -b".
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 378fddc..957bc97 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -1934,7 +1934,7 @@
  *     0 on success
  *     1 on failure
  */
-static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, char **err)
+static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, int fcount, char **err)
 {
 	char fp[MAXPATHLEN+1] = {0};
 	int n = 0;
@@ -1978,37 +1978,42 @@
 		if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
 			continue;
 
-		/* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
-		 * so the line that contains logic is marked via comments
-		 */
-		xname = X509_get_subject_name(certs_and_keys[n].cert);
-		i = -1;
-		while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
-			X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
+		if (fcount) {
+			for (i = 0; i < fcount, i++)
+				ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
+		} else {
+			/* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
+			 * so the line that contains logic is marked via comments
+			 */
+			xname = X509_get_subject_name(certs_and_keys[n].cert);
+			i = -1;
+			while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
+				X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
 
-			if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
-				/* Important line is here */
-				ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
+				if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
+					/* Important line is here */
+					ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
 
-				OPENSSL_free(str);
-				str = NULL;
+					OPENSSL_free(str);
+					str = NULL;
+				}
 			}
-		}
 
-		/* Do the above logic for each SAN */
+			/* Do the above logic for each SAN */
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
-		names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
-		if (names) {
-			for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
-				GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
+			names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
+			if (names) {
+				for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
+					GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
 
-				if (name->type == GEN_DNS) {
-					if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
-						/* Important line is here */
-						ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
+					if (name->type == GEN_DNS) {
+						if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
+							/* Important line is here */
+							ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
 
-						OPENSSL_free(str);
-						str = NULL;
+							OPENSSL_free(str);
+							str = NULL;
+						}
 					}
 				}
 			}
@@ -2101,7 +2106,7 @@
 		}
 
 		/* Update SNI Tree */
-		ssl_sock_add_cert_sni(cur_ctx, bind_conf, str, key_combos[i-1].order++);
+		key_combos[i-1].order = ssl_sock_add_cert_sni(cur_ctx, bind_conf, str, key_combos[i-1].order);
 		node = ebmb_next(node);
 	}
 
@@ -2135,7 +2140,7 @@
 }
 #else
 /* This is a dummy, that just logs an error and returns error */
-static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, char **err)
+static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, int fcount, char **err)
 {
 	memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
 	          err && *err ? *err : "", path, strerror(errno));
@@ -2400,7 +2405,7 @@
 						}
 
 						snprintf(fp, sizeof(fp), "%s/%s", path, dp);
-						ssl_sock_load_multi_cert(fp, bind_conf, curproxy, NULL, err);
+						ssl_sock_load_multi_cert(fp, bind_conf, curproxy, NULL, 0, err);
 
 						/* Successfully processed the bundle */
 						goto ignore_entry;
@@ -2418,7 +2423,7 @@
 		return cfgerr;
 	}
 
-	cfgerr = ssl_sock_load_multi_cert(path, bind_conf, curproxy, NULL, err);
+	cfgerr = ssl_sock_load_multi_cert(path, bind_conf, curproxy, NULL, 0, err);
 
 	return cfgerr;
 }
@@ -2505,7 +2510,7 @@
 		if (stat(args[0], &buf) == 0) {
 			cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
 		} else {
-			cfgerr = ssl_sock_load_multi_cert(args[0], bind_conf, curproxy, NULL, err);
+			cfgerr = ssl_sock_load_multi_cert(args[0], bind_conf, curproxy, &args[1], arg-1, err);
 		}
 
 		if (cfgerr) {