]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: jwt: Add new "jwt" certificate option
authorRemi Tricot-Le Breton <rlebreton@haproxy.com>
Thu, 2 Oct 2025 13:32:43 +0000 (15:32 +0200)
committerWilliam Lallemand <wlallemand@haproxy.com>
Mon, 13 Oct 2025 08:38:52 +0000 (10:38 +0200)
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
src/jwt.c
src/ssl_ckch.c

index 31705faaff836168c1debe50c9194b62927d9227..c435d4218001acab447011a50d7ca3816e6e3004 100644 (file)
@@ -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;
index ed9680d2190d1ec63d942614224268ed089716a1..8790c868f9a52cde1df1a3dcf9925ff531706866 100644 (file)
--- 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);
index 9b720e597d084c4bb373b56f5b273a4a3c637ca4..d64f46a256ae225739986208e14adb7d854df59f 100644 (file)
@@ -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