]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ssl: Accept certpath as param in "show ssl ocsp-response" CLI command
authorRemi Tricot-Le Breton <rlebreton@haproxy.com>
Mon, 13 Mar 2023 14:56:34 +0000 (15:56 +0100)
committerWilliam Lallemand <wlallemand@haproxy.org>
Tue, 14 Mar 2023 10:07:32 +0000 (11:07 +0100)
In order to increase usability, the "show ssl ocsp-response" also takes
a frontend certificate path as parameter. In such a case, it behaves the
same way as "show ssl cert foo.pem.ocsp".

doc/management.txt
reg-tests/ssl/show_ssl_ocspresponse.vtc
src/ssl_ocsp.c

index 008f2b09edfaaf8a1b2f385b3c20ddddf762bbc3..022348e67ae173f2529933ddbf30b48d124830ac 100644 (file)
@@ -3432,16 +3432,17 @@ show ssl crt-list [-n] [<filename>]
     ecdsa.pem:3 [verify none allow-0rtt ssl-min-ver TLSv1.0 ssl-max-ver TLSv1.3] localhost !www.test1.com
     ecdsa.pem:4 [verify none allow-0rtt ssl-min-ver TLSv1.0 ssl-max-ver TLSv1.3]
 
-show ssl ocsp-response [[text|base64] <id>]
+show ssl ocsp-response [[text|base64] <id|path>]
   Display the IDs of the OCSP tree entries corresponding to all the OCSP
   responses used in HAProxy, as well as the issuer's name and key hash and the
-  serial number of the certificate for which the OCSP response was built.  If a
-  valid <id> is provided, display the contents of the corresponding OCSP
-  response. When an <id> is provided, it it possible to format in which the
-  data is dumped. The 'text' option is the default one and it allows to display
-  detailed information about the OCSP response the same way as in an "openssl
-  ocsp -respin <ocsp-response> -text" call. The 'base64' format allows to dump
-  the contents of an OCSP response in base64.
+  serial number of the certificate for which the OCSP response was built.
+  If a valid <id> or the <path> of a valid frontend certificate is provided,
+  display the contents of the corresponding OCSP response. When an <id> is
+  provided, it it possible to define the format in which the data is dumped.
+  The 'text' option is the default one and it allows to display detailed
+  information about the OCSP response the same way as in an "openssl ocsp
+  -respin <ocsp-response> -text" call. The 'base64' format allows to dump the
+  contents of an OCSP response in base64.
 
   Example :
 
@@ -3471,7 +3472,7 @@ show ssl ocsp-response [[text|base64] <id>]
       Next Update: Oct 12 15:43:38 2048 GMT
       [...]
 
-    $ echo "show ssl ocsp-response base64 304b300906052b0e03021a0500041448dac[...]" | socat /var/run/haproxy.sock -
+    $ echo "show ssl ocsp-response base64 /path_to_cert/foo.pem" | socat /var/run/haproxy.sock -
       MIIB8woBAKCCAewwggHoBgkrBgEFBQcwAQEEggHZMIIB1TCBvqE[...]
 
 show ssl ocsp-updates
index 3d67fe53083faae990adc8fca9bb7a331d234605..6c1a6b2cfb4cd7d2ec52e21586d45661077113e7 100644 (file)
@@ -64,6 +64,14 @@ haproxy h1 -cli {
     expect ~ "Cert Status: good"
 }
 
+# Test the "show ssl ocsp-response" command with a certificate path as parameter
+shell {
+    ocsp_response=$(echo "show ssl ocsp-response ${testdir}/show_ocsp_server.pem" | socat "${tmpdir}/h1/stats" -)
+
+    echo "$ocsp_response" | grep "Responder Id: C = FR, O = HAProxy Technologies, CN = ocsp.haproxy.com" &&
+    echo "$ocsp_response" | grep "Cert Status: good"
+}
+
 # Test the "show ssl cert foo.pem.ocsp" command
 haproxy h1 -cli {
     send "show ssl cert"
index 14fb7e9153e6bb2db1d31106a7c1f272724e011b..17d217e07b1f8b12b8576e056e29a753d34c65f3 100644 (file)
@@ -1464,31 +1464,52 @@ static int cli_parse_show_ocspresponse(char **args, char *payload, struct appctx
 #if ((defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP) && !defined OPENSSL_IS_BORINGSSL)
 
        struct show_ocspresp_cli_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
-       int certid_arg_idx = 3;
+       int arg_idx = 3;
 
        if (*args[3]) {
                struct certificate_ocsp *ocsp = NULL;
                char key[OCSP_MAX_CERTID_ASN1_LENGTH] = {};
                int key_length = OCSP_MAX_CERTID_ASN1_LENGTH;
                char *key_ptr = key;
+               unsigned char *p;
+               struct ckch_store *ckch_store = NULL;
 
                if (strcmp(args[3], "text") == 0) {
                        ctx->format = SHOW_OCSPRESP_FMT_TEXT;
-                       ++certid_arg_idx;
+                       ++arg_idx;
                } else if (strcmp(args[3], "base64") == 0) {
                        ctx->format = SHOW_OCSPRESP_FMT_B64;
-                       ++certid_arg_idx;
+                       ++arg_idx;
                }
 
-               if (ctx->format != SHOW_OCSPRESP_FMT_DFLT && !*args[certid_arg_idx])
+               if (ctx->format != SHOW_OCSPRESP_FMT_DFLT && !*args[arg_idx])
                        return cli_err(appctx, "'show ssl ocsp-response [text|base64]' expects a valid certid.\n");
 
-               if (strlen(args[certid_arg_idx]) > OCSP_MAX_CERTID_ASN1_LENGTH*2) {
-                       return cli_err(appctx, "'show ssl ocsp-response' received a too big key.\n");
+               /* Try to convert parameter into an OCSP certid first, and consider it
+                * as a filename if it fails. */
+               if (strlen(args[arg_idx]) > OCSP_MAX_CERTID_ASN1_LENGTH*2 ||
+                   !parse_binary(args[arg_idx], &key_ptr, &key_length, NULL)) {
+
+                       key_ptr = key;
+                       key_length = 0;
+
+                       /* The operations on the CKCH architecture are locked so we can
+                        * manipulate ckch_store and ckch_inst */
+                       if (HA_SPIN_TRYLOCK(CKCH_LOCK, &ckch_lock)) {
+                               return cli_err(appctx, "Operations on certificates are currently locked!\n");
+                       }
+
+                       ckch_store = ckchs_lookup(args[arg_idx]);
+
+                       if (ckch_store) {
+                               p = (unsigned char*)key;
+                               key_length = i2d_OCSP_CERTID(ckch_store->data->ocsp_cid, &p);
+                       }
+                       HA_SPIN_UNLOCK(CKCH_LOCK, &ckch_lock);
                }
 
-               if (!parse_binary(args[certid_arg_idx], &key_ptr, &key_length, NULL)) {
-                       return cli_err(appctx, "'show ssl ocsp-response' received an invalid key.\n");
+               if (key_length == 0) {
+                       return cli_err(appctx, "'show ssl ocsp-response' expects a valid certid or certificate path.\n");
                }
 
                HA_SPIN_LOCK(OCSP_LOCK, &ocsp_tree_lock);
@@ -1496,7 +1517,7 @@ static int cli_parse_show_ocspresponse(char **args, char *payload, struct appctx
 
                if (!ocsp) {
                        HA_SPIN_UNLOCK(OCSP_LOCK, &ocsp_tree_lock);
-                       return cli_err(appctx, "Certificate ID does not match any certificate.\n");
+                       return cli_err(appctx, "Certificate ID or path does not match any certificate.\n");
                }
                ++ocsp->refcount;
                HA_SPIN_UNLOCK(OCSP_LOCK, &ocsp_tree_lock);