MINOR: ssl: Accept certpath as param in "show ssl ocsp-response" CLI command

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".
This commit is contained in:
Remi Tricot-Le Breton 2023-03-13 15:56:34 +01:00 committed by William Lallemand
parent f64a05979d
commit dafc068f12
3 changed files with 48 additions and 18 deletions

View 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

View 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"

View 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);