From 18ff130e9d88b95b229295cdcc567af6d9606797 Mon Sep 17 00:00:00 2001 From: Remi Tricot-Le Breton Date: Thu, 2 Oct 2025 15:32:43 +0200 Subject: [PATCH] MINOR: jwt: Add new "jwt" certificate option This option can be used to enable the use of a given certificate for JWT verification. It defaults to 'off' so certificates that are declared in a crt-store and will be used for JWT verification must have a "jwt on" option in the configuration. --- include/haproxy/ssl_ckch-t.h | 1 + src/jwt.c | 4 +++- src/ssl_ckch.c | 10 ++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/include/haproxy/ssl_ckch-t.h b/include/haproxy/ssl_ckch-t.h index 31705faaf..c435d4218 100644 --- a/include/haproxy/ssl_ckch-t.h +++ b/include/haproxy/ssl_ckch-t.h @@ -67,6 +67,7 @@ struct ckch_conf { char *issuer; char *sctl; int ocsp_update_mode; + int jwt; /* info stored here for now but should be in a dedicated jwt instance */ struct { char *id; char **domains; diff --git a/src/jwt.c b/src/jwt.c index ed9680d21..8790c868f 100644 --- a/src/jwt.c +++ b/src/jwt.c @@ -227,6 +227,8 @@ int jwt_tree_load_cert(char *path, int pathlen, int tryload_cert, const char *fi } } + store->conf.jwt = 1; + retval = 0; HA_SPIN_UNLOCK(CKCH_LOCK, &ckch_lock); @@ -403,7 +405,7 @@ jwt_jwsverify_rsa_ecdsa(const struct jwt_ctx *ctx, struct buffer *decoded_signat if (!HA_SPIN_TRYLOCK(CKCH_LOCK, &ckch_lock)) { store = ckchs_lookup(ctx->key); - if (store) { + if (store && store->conf.jwt) { pubkey = X509_get_pubkey(store->data->cert); if (pubkey) EVP_PKEY_up_ref(pubkey); diff --git a/src/ssl_ckch.c b/src/ssl_ckch.c index 9b720e597..d64f46a25 100644 --- a/src/ssl_ckch.c +++ b/src/ssl_ckch.c @@ -1043,6 +1043,7 @@ struct ckch_store *ckchs_dup(const struct ckch_store *src) dst->conf.ocsp_update_mode = src->conf.ocsp_update_mode; + dst->conf.jwt = src->conf.jwt; /* copy ckch_conf * XXX: could be automated for each field with the @@ -2251,6 +2252,8 @@ static int cli_io_handler_show_cert_detail(struct appctx *appctx) chunk_appendf(out, "Empty\n"); else if (ckchs == ckchs_transaction.new_ckchs) chunk_appendf(out, "Uncommitted\n"); + else if (ckchs->conf.jwt) + chunk_appendf(out, "Used for JWT verification\n"); else if (LIST_ISEMPTY(&ckchs->ckch_inst)) chunk_appendf(out, "Unused\n"); else @@ -3165,6 +3168,12 @@ static int cli_parse_del_cert(char **args, char *payload, struct appctx *appctx, memprintf(&err, "certificate '%s' doesn't exist!\n", filename); goto error; } + + if (store->conf.jwt) { + memprintf(&err, "certificate '%s' in use for JWT validation, can't be deleted!\n", filename); + goto error; + } + if (!LIST_ISEMPTY(&store->ckch_inst)) { memprintf(&err, "certificate '%s' in use, can't be deleted!\n", filename); goto error; @@ -4601,6 +4610,7 @@ struct ckch_conf_kws ckch_conf_kws[] = { #if defined(HAVE_SSL_OCSP) { "ocsp-update", offsetof(struct ckch_conf, ocsp_update_mode), PARSE_TYPE_ONOFF, ocsp_update_init, }, #endif + { "jwt", offsetof(struct ckch_conf, jwt), PARSE_TYPE_ONOFF, NULL, }, #if defined(HAVE_ACME) { "acme", offsetof(struct ckch_conf, acme.id), PARSE_TYPE_STR, ckch_conf_acme_init, }, #endif