I'm using generate-certificates to save some hassle with a lot of api backends. 
For the most
part it works great, but I ran into trouble with a java client (OkHttp) which 
wouldn't
trust the haproxy-generated certificates.

Some clients such as Google Chrome and OkHttp do not trust the server 
certificate
unless it has a Subject Alternate Name. For the generate-certificates case it 
seems safe
and unambiguous to do this, because it is based on the SNI name which must be a 
DNS name?

Example configuration demonstrating the issue. You'll get a warning from Chrome 
if you
try to hit this config, but if the SAN is set the warning goes away. If you 
apply the really
hacky patch (apologies: I'm afraid of openssl), there won't be a verification 
issue because 
the SAN extension with the DNS name is available.

--- 
frontend fe
  mode http
  bind :8993 ssl crt default.chain ca-sign-file ca.chain generate-certificates 
no-sslv3
  use_backend be

backend be
  mode http
  stats uri /
--- 
 src/ssl_sock.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 50af63b2..d994dcae 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -1684,6 +1684,8 @@ ssl_sock_do_create_cert(const char *servername, struct 
bind_conf *bind_conf, SSL
        SSL          *tmp_ssl = NULL;
        CONF         *ctmp    = NULL;
        X509_NAME    *name;
+       X509_EXTENSION *san_ext;
+       char         *san_value;
        const EVP_MD *digest;
        X509V3_CTX    ctx;
        unsigned int  i;
@@ -1754,6 +1756,24 @@ ssl_sock_do_create_cert(const char *servername, struct 
bind_conf *bind_conf, SSL
                X509_EXTENSION_free(ext);
        }
 
+       /* Add Subject Alternative Name for the server */
+       san_value = (char *)malloc(4 + strlen(servername) + 1);
+       if (!san_value)
+               goto mkcert_error;
+       *san_value = '\0';
+       strcat(san_value, "DNS:");
+       strcat(san_value, servername);
+       if (!(san_ext = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_alt_name, 
san_value))) {
+               free(san_value);
+               goto mkcert_error;
+       }
+       free(san_value);
+       if (!X509_add_ext(newcrt, san_ext, -1)) {
+               X509_EXTENSION_free(san_ext);
+               goto mkcert_error;
+       }
+       X509_EXTENSION_free(san_ext);
+
        /* Sign the certificate with the CA private key */
 
        key_type = EVP_PKEY_base_id(capkey);
-- 
2.18.0


Reply via email to