Package: pound
Version: 2.7-1.3

Hi everyone,

This patch allows Pound to present ECDHA certificates to clients that
can use them while still presenting RSA certificates to older clients.

Robert de Bath <robert$@debath.co.uk>


Index: pound-2.7/config.c
===================================================================
This patch alters the way the "Cert" loads certificates and keys.

If the Common Name on the certificate is distinct from those on other
ones the operation is unchanged.  However, if the Common Name on this
certificate matches one used on a previous certificate this one will
be loaded into the same SSL context as the previous one. The result is
that if you load two (or three) certificates will different signature
algorithms all the OpenSSL ciphers that require any of the loaded
algorithms will be available to communicate with the client.

This allows ECDHA certificates to be presented to clients that can use
them while still presenting RSA certificates to older clients.

--- pound-2.7.orig/config.c     2017-04-22 18:42:23.412469733 +0100
+++ pound-2.7/config.c  2017-04-22 18:43:16.020025597 +0100
@@ -1041,50 +1041,72 @@ parse_HTTPS(void)
 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
             /* we have support for SNI */
             FILE        *fcert;
-            char        server_name[MAXBUF], *cp;
+            char        server_name[MAXBUF], *cp, *server_cname;
             X509        *x509;
+           regmatch_t CN_matches[2];
+           int         extra_cert = 0;

             if(has_other)
conf_err("Cert directives MUST precede other SSL-specific directives - aborted");
+
+            lin[matches[1].rm_eo] = '\0';
+            if((fcert = fopen(lin + matches[1].rm_so, "r")) == NULL)
+                conf_err("ListenHTTPS: could not open certificate file");
+            if((x509 = PEM_read_X509(fcert, NULL, NULL, NULL)) == NULL)
+                conf_err("ListenHTTPS: could not get certificate subject");
+            fclose(fcert);
+            memset(server_name, '\0', MAXBUF);
+ X509_NAME_oneline(X509_get_subject_name(x509), server_name, MAXBUF - 1);
+
+            if(!regexec(&CNName, server_name, 2, CN_matches, 0)) {
+                server_name[CN_matches[1].rm_eo] = '\0';
+ if((server_cname = strdup(server_name + CN_matches[1].rm_so)) == NULL) + conf_err("ListenHTTPS: could not set certificate subject");
+            } else
+                conf_err("ListenHTTPS: could not get certificate CN");
+
             if(res->ctx) {
                 for(pc = res->ctx; pc->next; pc = pc->next)
-                    ;
-                if((pc->next = malloc(sizeof(POUND_CTX))) == NULL)
- conf_err("ListenHTTPS new POUND_CTX: out of memory - aborted");
-                pc = pc->next;
+                    if (strcmp(pc->server_name, server_cname) == 0) {
+                       extra_cert = 1;
+                       break;
+                   }
+               if (!extra_cert && strcmp(pc->server_name, server_cname) == 0)
+                   extra_cert = 1;
+
+               if (!extra_cert ) {
+                   if((pc->next = malloc(sizeof(POUND_CTX))) == NULL)
+ conf_err("ListenHTTPS new POUND_CTX: out of memory - aborted");
+                   pc = pc->next;
+               }
             } else {
                 if((res->ctx = malloc(sizeof(POUND_CTX))) == NULL)
conf_err("ListenHTTPS new POUND_CTX: out of memory - aborted");
                 pc = res->ctx;
             }
-            if((pc->ctx = SSL_CTX_new(SSLv23_server_method())) == NULL)
-                conf_err("SSL_CTX_new failed - aborted");
-            pc->server_name = NULL;
-            pc->next = NULL;
-            lin[matches[1].rm_eo] = '\0';
+
+           if (!extra_cert) {
+               if((pc->ctx = SSL_CTX_new(SSLv23_server_method())) == NULL)
+                   conf_err("SSL_CTX_new failed - aborted");
+               pc->server_name = NULL;
+               pc->next = NULL;
+           }
+
if(SSL_CTX_use_certificate_chain_file(pc->ctx, lin + matches[1].rm_so) != 1) conf_err("SSL_CTX_use_certificate_chain_file failed - aborted"); if(SSL_CTX_use_PrivateKey_file(pc->ctx, lin + matches[1].rm_so, SSL_FILETYPE_PEM) != 1)
                 conf_err("SSL_CTX_use_PrivateKey_file failed - aborted");
             if(SSL_CTX_check_private_key(pc->ctx) != 1)
                 conf_err("SSL_CTX_check_private_key failed - aborted");
-            if((fcert = fopen(lin + matches[1].rm_so, "r")) == NULL)
-                conf_err("ListenHTTPS: could not open certificate file");
-            if((x509 = PEM_read_X509(fcert, NULL, NULL, NULL)) == NULL)
-                conf_err("ListenHTTPS: could not get certificate subject");
-            fclose(fcert);
-            memset(server_name, '\0', MAXBUF);
- X509_NAME_oneline(X509_get_subject_name(x509), server_name, MAXBUF - 1);
-            pc->subjectAltNameCount = 0;
-            pc->subjectAltNames = NULL;
- pc->subjectAltNames = get_subjectaltnames(x509, &(pc->subjectAltNameCount));
+
+           if (!extra_cert) {
+               pc->server_name = server_cname;
+               pc->subjectAltNameCount = 0;
+               pc->subjectAltNames = NULL;
+ pc->subjectAltNames = get_subjectaltnames(x509, &(pc->subjectAltNameCount));
+           } else
+               free(server_cname;
             X509_free(x509);
-            if(!regexec(&CNName, server_name, 4, matches, 0)) {
-                server_name[matches[1].rm_eo] = '\0';
- if((pc->server_name = strdup(server_name + matches[1].rm_so)) == NULL) - conf_err("ListenHTTPS: could not set certificate subject");
-            } else
-                conf_err("ListenHTTPS: could not get certificate CN");
 #else
             /* no SNI support */
             if(has_other)



--
Rob.                          (Robert de Bath <robert$ @ debath.co.uk>)
                                             <http://www.debath.co.uk/>

Reply via email to