BUG/MINOR: ssl: Fix crash when no private key is found in pem
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.
(cherry picked from commit 9bf3a1f67eb3bc6f02abcabf8ab141840c7a1db2)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit bd5a6c43ef3714c3c75d653392ed48a12a69f9af)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/ssl_ckch.c b/src/ssl_ckch.c
index 86cc584..9743532 100644
--- a/src/ssl_ckch.c
+++ b/src/ssl_ckch.c
@@ -247,6 +247,7 @@
{
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) {
@@ -281,34 +282,38 @@
}
- /* 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",