diff --git a/doc/configuration.txt b/doc/configuration.txt index 021721e0a..14b2e8812 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -30742,6 +30742,9 @@ jwt [ off | on ] not work. In order to be deleted, a certificate must not be used, either for SSL handshakes or JWT validation. + This option can be changed during runtime via the "add ssl jwt" and "del ssl + jwt" CLI commands. See also "show ssl jwt" CLI command. + 12.8. ACME ---------- diff --git a/doc/management.txt b/doc/management.txt index dc01a00b1..e98a4a961 100644 --- a/doc/management.txt +++ b/doc/management.txt @@ -1834,6 +1834,13 @@ add ssl crt-list $ echo -e 'add ssl crt-list certlist1 <<\nfoobar.pem [allow-0rtt] foo.bar.com !test1.com\n' | socat /tmp/sock1 - +add ssl jwt + Add an already loaded certificate to the list of certificates that can be + used for JWT validation (see "jwt_verify_cert" converter). This command does + not work on ongoing transactions. + See also "del ssl jwt" and "show ssl jwt" commands. + See "jwt" certificate option for more information. + clear counters Clear the max values of the statistics counters in each proxy (frontend & backend) and in each server. The accumulated counters are not affected. The @@ -2103,6 +2110,13 @@ del ssl crt-list you will need to provide which line you want to delete. To display the line numbers, use "show ssl crt-list -n ". +del ssl jwt + Remove an already loaded certificate to the list of certificates that can be + used for JWT validation (see "jwt_verify_cert" converter). This command does + not work on ongoing transactions. + See also "add ssl jwt" and "show ssl jwt" commands. + See "jwt" certificate option for more information. + del server / Delete a removable server attached to the backend . A removable server is the server which satisfies all of these conditions : @@ -3779,6 +3793,16 @@ show ssl crt-list [-n] [] 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 jwt + Display the list of certificates that can be used for JWT validation. + See also "add ssl jwt" and "del ssl jwt" commands. + See "jwt" certificate option for more information. + + Example: + echo "show ssl jwt" | socat /tmp/sock1 - + #filename + jwt.pem + show ssl ocsp-response [[text|base64] ] Display the IDs of the OCSP tree entries corresponding to all the OCSP responses used in HAProxy, as well as the corresponding frontend diff --git a/src/ssl_ckch.c b/src/ssl_ckch.c index f720f3729..43a76ca74 100644 --- a/src/ssl_ckch.c +++ b/src/ssl_ckch.c @@ -88,6 +88,11 @@ struct show_cert_ctx { int transaction; }; +/* CLI context used by "show ssl jwt" */ +struct show_jwt_ctx { + struct ckch_store *cur_ckchs; +}; + #define SHOW_SNI_OPT_1FRONTEND (1 << 0) /* show only the selected frontend */ #define SHOW_SNI_OPT_NOTAFTER (1 << 1) /* show certificates that are [A]fter the notAfter date */ @@ -2444,6 +2449,113 @@ error: return cli_err(appctx, "Can't display the certificate: Not found or the certificate is a bundle!\n"); } +static inline int cli_set_ssl_jwt(char **args, struct appctx *appctx, int value) +{ + struct ckch_store *ckchs; + char *err = NULL; + + if (!cli_has_level(appctx, ACCESS_LVL_ADMIN)) + return cli_err(appctx, "Can't allocate memory!\n"); + + /* check if there is a certificate to lookup */ + if (!*args[3]) + return cli_dynerr(appctx, memprintf(&err, "'%s ssl cert' expects a filename\n", args[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, "Can't show!\nOperations on certificates are currently locked!\n"); + + if ((ckchs = ckchs_lookup(args[3])) == NULL) + goto error; + + ckchs->conf.jwt = value; + + HA_SPIN_UNLOCK(CKCH_LOCK, &ckch_lock); + return 0; + +error: + HA_SPIN_UNLOCK(CKCH_LOCK, &ckch_lock); + return cli_err(appctx, "Can't display the certificate: Not found or the certificate is a bundle!\n"); +} + +/* parsing function for 'add ssl jwt ' */ +static int cli_parse_add_jwt(char **args, char *payload, struct appctx *appctx, void *private) +{ + return cli_set_ssl_jwt(args, appctx, 1); +} + +/* parsing function for 'del ssl jwt ' */ +static int cli_parse_del_jwt(char **args, char *payload, struct appctx *appctx, void *private) +{ + return cli_set_ssl_jwt(args, appctx, 0); +} + +/* parsing function for 'show ssl jwt ' */ +static int cli_parse_show_jwt(char **args, char *payload, struct appctx *appctx, void *private) +{ + struct show_jwt_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx)); + + if (!cli_has_level(appctx, ACCESS_LVL_OPER)) + return cli_err(appctx, "Can't allocate memory!\n"); + + /* 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, "Can't show!\nOperations on certificates are currently locked!\n"); + + return 0; + +error: + HA_SPIN_UNLOCK(CKCH_LOCK, &ckch_lock); + return cli_err(appctx, "Can't display the certificate: Not found or the certificate is a bundle!\n"); +} + +/* IO handler of "show ssl jwt". + * It makes use of a show_jwt_ctx context. + */ +static int cli_io_handler_show_jwt(struct appctx *appctx) +{ + struct show_jwt_ctx *ctx = appctx->svcctx; + struct buffer *trash = alloc_trash_chunk(); + struct ebmb_node *node; + struct ckch_store *ckchs = NULL; + + if (trash == NULL) + return 1; + + if (!ctx->cur_ckchs) { + chunk_appendf(trash, "# filename\n"); + node = ebmb_first(&ckchs_tree); + } else { + node = &ctx->cur_ckchs->node; + } + while (node) { + ckchs = ebmb_entry(node, struct ckch_store, node); + if (ckchs->conf.jwt) + chunk_appendf(trash, "%s\n", ckchs->path); + + node = ebmb_next(node); + if (applet_putchk(appctx, trash) == -1) + goto yield; + } + + ctx->cur_ckchs = NULL; + free_trash_chunk(trash); + return 1; +yield: + + free_trash_chunk(trash); + ctx->cur_ckchs = ckchs; + return 0; /* should come back */ +} + +/* release function of the 'show ssl jwt' command */ +static void cli_release_show_jwt(struct appctx *appctx) +{ + HA_SPIN_UNLOCK(CKCH_LOCK, &ckch_lock); +} + /* * Dump a CKCH in PEM format over the CLI @@ -4570,6 +4682,10 @@ static struct cli_kw_list cli_kws = {{ },{ { { "show", "ssl", "cert", NULL }, "show ssl cert [] : display the SSL certificates used in memory, or the details of a file", cli_parse_show_cert, cli_io_handler_show_cert, cli_release_show_cert }, { { "dump", "ssl", "cert", NULL }, "dump ssl cert : dump the SSL certificates in PEM format", cli_parse_dump_cert, cli_io_handler_dump_cert, cli_release_dump_cert }, + { { "add", "ssl", "jwt", NULL }, "add ssl jwt : add certificate to list of certificates used for JWT validation", cli_parse_add_jwt, NULL, NULL }, + { { "del", "ssl", "jwt", NULL }, "del ssl jwt : remove certificate from list of certificates used for JWT validation", cli_parse_del_jwt, NULL, NULL }, + { { "show", "ssl", "jwt", NULL }, "show ssl jwt : show list of certificates used for JWT validation", cli_parse_show_jwt, cli_io_handler_show_jwt, cli_release_show_jwt }, + { { "new", "ssl", "ca-file", NULL }, "new ssl ca-file : create a new CA file to be used in a crt-list", cli_parse_new_cafile, NULL, NULL }, { { "add", "ssl", "ca-file", NULL }, "add ssl ca-file : add a certificate into the CA file", cli_parse_set_cafile, NULL, NULL },