]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: ssl: rewind the BIO when reading certificates
authorWilly Tarreau <w@1wt.eu>
Wed, 6 Apr 2016 17:02:38 +0000 (19:02 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 6 Apr 2016 17:02:38 +0000 (19:02 +0200)
Emeric found that some certificate files that were valid with the old method
(the one with the explicit name involving SSL_CTX_use_PrivateKey_file()) do
not work anymore with the new one (the one trying to load multiple cert types
using PEM_read_bio_PrivateKey()). With the last one, the private key couldn't
be loaded.

The difference was related to the ordering in the PEM file was different. The
old method would always work. The new method only works if the private key is
at the top, or if it appears as an "EC" private key. The cause in fact is that
we never rewind the BIO between the various calls. So this patch moves the
loading of the private key as the first step, then it rewinds the BIO, and
then it loads the cert and the chain. With this everything works.

No backport is needed, this issue came with the recent addition of the
multi-cert support.

src/ssl_sock.c

index 8e577abd95acb7dbeecb42cb57db82d6d7301e7f..0d35c298dcca4cb99eb1df15764dab4bb4d744c0 100644 (file)
@@ -1796,14 +1796,6 @@ static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_an
        if (BIO_read_filename(in, path) <= 0)
                goto end;
 
-       /* Read Certificate */
-       ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
-       if (ckch->cert == NULL) {
-               memprintf(err, "%sunable to load certificate from file '%s'.\n",
-                               err && *err ? *err : "", path);
-               goto end;
-       }
-
        /* Read Private Key */
        ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
        if (ckch->key == NULL) {
@@ -1812,6 +1804,17 @@ static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_an
                goto end;
        }
 
+       /* Seek back to beginning of file */
+       BIO_reset(in);
+
+       /* Read Certificate */
+       ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
+       if (ckch->cert == NULL) {
+               memprintf(err, "%sunable to load certificate from file '%s'.\n",
+                               err && *err ? *err : "", path);
+               goto end;
+       }
+
        /* Read Certificate Chain */
        while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
                /* Grow the chain certs */