]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: ssl/cli: 'commit ssl cert' crashes when no private key
authorWilliam Lallemand <wlallemand@haproxy.com>
Wed, 24 Jun 2020 14:26:41 +0000 (16:26 +0200)
committerWilliam Lallemand <wlallemand@haproxy.org>
Wed, 24 Jun 2020 14:52:22 +0000 (16:52 +0200)
A crash was reported in issue #707 because the private key was not
uploaded correctly with "set ssl cert".

The bug is provoked by X509_check_private_key() being called when there
is no private key, which can lead to a segfault.

This patch adds a check and return an error is the private key is not
present.

This must be backported in 2.1.

src/ssl_ckch.c

index 537c7ea7d1de783bad28eb130029e39113dfb2d7..aa7361fbb4f02f265150cfb1b15d6cc3c35eabd4 100644 (file)
@@ -1495,6 +1495,12 @@ static int cli_parse_commit_cert(char **args, char *payload, struct appctx *appc
                int n;
 
                for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
+                       /* if a certificate is here, a private key must be here too */
+                       if (ckchs_transaction.new_ckchs->ckch[n].cert && !ckchs_transaction.new_ckchs->ckch[n].key) {
+                               memprintf(&err, "The transaction must contain at least a certificate and a private key!\n");
+                               goto error;
+                       }
+
                        if (ckchs_transaction.new_ckchs->ckch[n].cert && !X509_check_private_key(ckchs_transaction.new_ckchs->ckch[n].cert, ckchs_transaction.new_ckchs->ckch[n].key)) {
                                memprintf(&err, "inconsistencies between private key and certificate loaded '%s'.\n", ckchs_transaction.path);
                                goto error;
@@ -1503,6 +1509,12 @@ static int cli_parse_commit_cert(char **args, char *payload, struct appctx *appc
        } else
 #endif
        {
+               /* if a certificate is here, a private key must be here too */
+               if (ckchs_transaction.new_ckchs->ckch->cert && !ckchs_transaction.new_ckchs->ckch->key) {
+                       memprintf(&err, "The transaction must contain at least a certificate and a private key!\n");
+                       goto error;
+               }
+
                if (!X509_check_private_key(ckchs_transaction.new_ckchs->ckch->cert, ckchs_transaction.new_ckchs->ckch->key)) {
                        memprintf(&err, "inconsistencies between private key and certificate loaded '%s'.\n", ckchs_transaction.path);
                        goto error;