]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: ssl: Fix crash when no private key is found in pem
authorRemi Tricot-Le Breton <rlebreton@haproxy.com>
Mon, 9 May 2022 09:07:13 +0000 (11:07 +0200)
committerWilliam Lallemand <wlallemand@haproxy.org>
Tue, 17 May 2022 13:51:41 +0000 (15:51 +0200)
If no private key can be found in a bind line's certificate and
ssl-load-extra-files is set to none we end up trying to call
X509_check_private_key with a NULL key, which crashes.

This fix should be backported to all stable branches.

src/ssl_ckch.c

index 20e2dfcd438a24d3fca36c13456bed68ab7283d7..055c44352938124fa55db04e0257bd7862408d5c 100644 (file)
@@ -339,6 +339,7 @@ int ssl_sock_load_files_into_ckch(const char *path, struct cert_key_and_chain *c
 {
        struct buffer *fp = NULL;
        int ret = 1;
+       struct stat st;
 
        /* try to load the PEM */
        if (ssl_sock_load_pem_into_ckch(path, NULL, ckch , err) != 0) {
@@ -373,34 +374,38 @@ int ssl_sock_load_files_into_ckch(const char *path, struct cert_key_and_chain *c
 
        }
 
-       /* try to load an external private key if it wasn't in the PEM */
-       if ((ckch->key == NULL) && (global_ssl.extra_files & SSL_GF_KEY)) {
-               struct stat st;
+       /* If no private key was found yet and we cannot look for it in extra
+        * files, raise an error.
+        */
+       if ((ckch->key == NULL) && !(global_ssl.extra_files & SSL_GF_KEY)) {
+               memprintf(err, "%sNo Private Key found in '%s'.\n", err && *err ? *err : "", fp->area);
+               goto end;
+       }
 
+       /* try to load an external private key if it wasn't in the PEM */
+       if (!chunk_strcat(fp, ".key") || (b_data(fp) > MAXPATHLEN)) {
+               memprintf(err, "%s '%s' filename too long'.\n",
+                         err && *err ? *err : "", fp->area);
+               ret = 1;
+               goto end;
+       }
 
-               if (!chunk_strcat(fp, ".key") || (b_data(fp) > MAXPATHLEN)) {
-                       memprintf(err, "%s '%s' filename too long'.\n",
-                                 err && *err ? *err : "", fp->area);
-                       ret = 1;
+       if (stat(fp->area, &st) == 0) {
+               if (ssl_sock_load_key_into_ckch(fp->area, NULL, ckch, err)) {
+                       memprintf(err, "%s '%s' is present but cannot be read or parsed'.\n",
+                                 err && *err ? *err : "", fp->area);
                        goto end;
                }
+       }
 
-               if (stat(fp->area, &st) == 0) {
-                       if (ssl_sock_load_key_into_ckch(fp->area, NULL, ckch, err)) {
-                               memprintf(err, "%s '%s' is present but cannot be read or parsed'.\n",
-                                         err && *err ? *err : "", fp->area);
-                               goto end;
-                       }
-               }
-
-               if (ckch->key == NULL) {
-                       memprintf(err, "%sNo Private Key found in '%s'.\n", err && *err ? *err : "", fp->area);
-                       goto end;
-               }
-               /* remove the added extension */
-               *(fp->area + fp->data - strlen(".key")) = '\0';
-               b_sub(fp, strlen(".key"));
+       if (ckch->key == NULL) {
+               memprintf(err, "%sNo Private Key found in '%s'.\n", err && *err ? *err : "", fp->area);
+               goto end;
        }
+       /* remove the added extension */
+       *(fp->area + fp->data - strlen(".key")) = '\0';
+       b_sub(fp, strlen(".key"));
+
 
        if (!X509_check_private_key(ckch->cert, ckch->key)) {
                memprintf(err, "%sinconsistencies between private key and certificate loaded '%s'.\n",