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 [<id>]
+show ssl ocsp-response [[text|base64] <id>]
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. The information displayed is the same as in an "openssl ocsp -respin
- <ocsp-response> -text" call.
+ 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.
Example :
Next Update: Oct 12 15:43:38 2048 GMT
[...]
+ $ echo "show ssl ocsp-response base64 304b300906052b0e03021a0500041448dac[...]" | socat /var/run/haproxy.sock -
+ MIIB8woBAKCCAewwggHoBgkrBgEFBQcwAQEEggHZMIIB1TCBvqE[...]
+
show ssl ocsp-updates
Display information about the entries concerned by the OCSP update mechanism.
The command will output one line per OCSP response and will contain the
return 1;
}
+
+enum {
+ SHOW_OCSPRESP_FMT_DFLT,
+ SHOW_OCSPRESP_FMT_TEXT,
+ SHOW_OCSPRESP_FMT_B64
+};
+
+struct show_ocspresp_cli_ctx {
+ struct certificate_ocsp *ocsp;
+ int format;
+};
+
/*
* Dump the details about an OCSP response in DER format stored in
* <ocsp_response> into buffer <out>.
return retval;
}
+/*
+ * Dump the contents of an OCSP response in DER format stored in
+ * <ocsp_response> into buffer <out> after converting it to base64.
+ * Returns 0 in case of success.
+ */
+static int ssl_ocsp_response_print_base64(struct buffer *ocsp_response, struct buffer *out)
+{
+ int b64len = 0;
+
+ b64len = a2base64(b_orig(ocsp_response), b_data(ocsp_response),
+ b_orig(out), b_size(out));
+
+ if (b64len < 0)
+ return 1;
+
+ out->data = b64len;
+
+ /* Add empty line */
+ chunk_appendf(ocsp_response, "\n");
+
+ return 0;
+}
+
/*
* Dump the details of the OCSP response of ID <ocsp_certid> into buffer <out>.
* Returns 0 in case of success.
*/
static int cli_io_handler_show_ocspresponse_detail(struct appctx *appctx)
{
- struct buffer *trash = alloc_trash_chunk();
- struct certificate_ocsp *ocsp = appctx->svcctx;
+ struct buffer *trash = get_trash_chunk();
+ struct show_ocspresp_cli_ctx *ctx = appctx->svcctx;
+ struct certificate_ocsp *ocsp = ctx->ocsp;
+ int retval = 0;
- if (trash == NULL)
- return 1;
+ switch (ctx->format) {
+ case SHOW_OCSPRESP_FMT_DFLT:
+ case SHOW_OCSPRESP_FMT_TEXT:
+ retval = ssl_ocsp_response_print(&ocsp->response, trash);
+ break;
+ case SHOW_OCSPRESP_FMT_B64:
+ retval = ssl_ocsp_response_print_base64(&ocsp->response, trash);
+ break;
+ }
- if (ssl_ocsp_response_print(&ocsp->response, trash)) {
- free_trash_chunk(trash);
+ if (retval)
return 1;
- }
if (applet_putchk(appctx, trash) == -1)
goto yield;
appctx->svcctx = NULL;
- if (trash)
- free_trash_chunk(trash);
return 1;
yield:
- if (trash)
- free_trash_chunk(trash);
-
return 0;
}
static int cli_parse_show_ocspresponse(char **args, char *payload, struct appctx *appctx, void *private)
{
#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;
+
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;
- if (strlen(args[3]) > OCSP_MAX_CERTID_ASN1_LENGTH*2) {
+ if (strcmp(args[3], "text") == 0) {
+ ctx->format = SHOW_OCSPRESP_FMT_TEXT;
+ ++certid_arg_idx;
+ } else if (strcmp(args[3], "base64") == 0) {
+ ctx->format = SHOW_OCSPRESP_FMT_B64;
+ ++certid_arg_idx;
+ }
+
+ if (ctx->format != SHOW_OCSPRESP_FMT_DFLT && !*args[certid_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");
}
- if (!parse_binary(args[3], &key_ptr, &key_length, NULL)) {
+ 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");
}
++ocsp->refcount;
HA_SPIN_UNLOCK(OCSP_LOCK, &ocsp_tree_lock);
- appctx->svcctx = ocsp;
+ ctx->ocsp = ocsp;
appctx->io_handler = cli_io_handler_show_ocspresponse_detail;
}
struct certificate_ocsp *ocsp = NULL;
BIO *bio = NULL;
int write = -1;
+ struct show_ocspresp_cli_ctx *ctx = appctx->svcctx;
if (trash == NULL)
return 1;
if ((bio = BIO_new(BIO_s_mem())) == NULL)
goto end;
- if (!appctx->svcctx) {
+ if (!ctx->ocsp) {
chunk_appendf(trash, "# Certificate IDs\n");
node = ebmb_first(&cert_ocsp_tree);
} else {
- node = &((struct certificate_ocsp *)appctx->svcctx)->key;
+ node = &ctx->ocsp->key;
}
while (node) {
end:
HA_SPIN_UNLOCK(OCSP_LOCK, &ocsp_tree_lock);
- appctx->svcctx = NULL;
free_trash_chunk(trash);
free_trash_chunk(tmp);
BIO_free(bio);
BIO_free(bio);
++ocsp->refcount;
- appctx->svcctx = ocsp;
+ ctx->ocsp = ocsp;
HA_SPIN_UNLOCK(OCSP_LOCK, &ocsp_tree_lock);
return 0;
#else
static struct cli_kw_list cli_kws = {{ },{
- { { "set", "ssl", "ocsp-response", NULL }, "set ssl ocsp-response <resp|payload> : update a certificate's OCSP Response from a base64-encode DER", cli_parse_set_ocspresponse, NULL },
+ { { "set", "ssl", "ocsp-response", NULL }, "set ssl ocsp-response <resp|payload> : update a certificate's OCSP Response from a base64-encode DER", cli_parse_set_ocspresponse, NULL },
- { { "show", "ssl", "ocsp-response", NULL },"show ssl ocsp-response [id] : display the IDs of the OCSP responses used in memory, or the details of a single OCSP response", cli_parse_show_ocspresponse, cli_io_handler_show_ocspresponse, NULL },
- { { "show", "ssl", "ocsp-updates", NULL }, "show ssl ocsp-updates : display information about the next 'nb' ocsp responses that will be updated automatically", cli_parse_show_ocsp_updates, cli_io_handler_show_ocsp_updates, cli_release_show_ocsp_updates },
+ { { "show", "ssl", "ocsp-response", NULL },"show ssl ocsp-response [[text|base64] id] : display the IDs of the OCSP responses used in memory, or the details of a single OCSP response (in text or base64 format)", cli_parse_show_ocspresponse, cli_io_handler_show_ocspresponse, NULL },
+ { { "show", "ssl", "ocsp-updates", NULL }, "show ssl ocsp-updates : display information about the next 'nb' ocsp responses that will be updated automatically", cli_parse_show_ocsp_updates, cli_io_handler_show_ocsp_updates, cli_release_show_ocsp_updates },
#if ((defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP) && !defined OPENSSL_IS_BORINGSSL)
- { { "update", "ssl", "ocsp-response", NULL }, "update ssl ocsp-response <certfile> : send ocsp request and update stored ocsp response", cli_parse_update_ocsp_response, cli_io_handler_update_ocsp_response, cli_release_update_ocsp_response },
+ { { "update", "ssl", "ocsp-response", NULL }, "update ssl ocsp-response <certfile> : send ocsp request and update stored ocsp response", cli_parse_update_ocsp_response, cli_io_handler_update_ocsp_response, cli_release_update_ocsp_response },
#endif
{ { NULL }, NULL, NULL, NULL }
}};