]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: jwt: Insert public certificates into dedicated JWT tree
authorRemi Tricot-Le Breton <rlebreton@haproxy.com>
Fri, 1 Oct 2021 13:36:56 +0000 (15:36 +0200)
committerWilliam Lallemand <wlallemand@haproxy.org>
Thu, 14 Oct 2021 14:38:12 +0000 (16:38 +0200)
A JWT signed with the RSXXX or ESXXX algorithm (RSA or ECDSA) requires a
public certificate to be verified and to ensure it is valid. Those
certificates must not be read on disk at runtime so we need a caching
mechanism into which those certificates will be loaded during init.
This is done through a dedicated ebtree that is filled during
configuration parsing. The path to the public certificates will need to
be explicitely mentioned in the configuration so that certificates can
be loaded as early as possible.
This tree is different from the ckch one because ckch entries are much
bigger than the public certificates used in JWT validation process.

include/haproxy/jwt-t.h
include/haproxy/jwt.h
src/jwt.c

index 6ac68b166e6e6a94bd89899c5c986bcb794b267c..4189e65065407a8b0df07e95d56498e6f449d5a0 100644 (file)
@@ -61,6 +61,12 @@ enum jwt_elt {
        JWT_ELT_SIG,
        JWT_ELT_MAX
 };
+
+struct jwt_cert_tree_entry {
+       EVP_PKEY *pkey;
+       struct ebmb_node node;
+       char path[VAR_ARRAY];
+};
 #endif /* USE_OPENSSL */
 
 
index b24cc28cf7770940ea29a054dde35bef1074260c..6ae6e638027f72a8dfa66b89aa361b4ea63169a3 100644 (file)
@@ -28,6 +28,7 @@
 #ifdef USE_OPENSSL
 enum jwt_alg jwt_parse_alg(const char *alg_str, unsigned int alg_len);
 int jwt_tokenize(const struct buffer *jwt, struct jwt_item *items, unsigned int *item_num);
+int jwt_tree_load_cert(char *path, int pathlen, char **err);
 #endif /* USE_OPENSSL */
 
 #endif /* _HAPROXY_JWT_H */
index 9f39a89fe8dc19691b4c65161ebacf7228606254..210308364992536c4d8e3d3bbd864570b4246fc3 100644 (file)
--- a/src/jwt.c
+++ b/src/jwt.c
@@ -21,6 +21,9 @@
 
 
 #ifdef USE_OPENSSL
+/* Tree into which the public certificates used to validate JWTs will be stored. */
+static struct eb_root jwt_cert_tree = EB_ROOT_UNIQUE;
+
 /*
  * The possible algorithm strings that can be found in a JWS's JOSE header are
  * defined in section 3.1 of RFC7518.
@@ -120,4 +123,47 @@ int jwt_tokenize(const struct buffer *jwt, struct jwt_item *items, unsigned int
        return (ptr != jwt_end);
 }
 
+/*
+ * Parse a public certificate and insert it into the jwt_cert_tree.
+ * Returns 0 in case of success.
+ */
+int jwt_tree_load_cert(char *path, int pathlen, char **err)
+{
+       int retval = -1;
+       struct jwt_cert_tree_entry *entry = NULL;
+       EVP_PKEY *pkey = NULL;
+       BIO *bio = NULL;
+
+       bio = BIO_new(BIO_s_file());
+       if (!bio) {
+               memprintf(err, "%sunable to allocate memory (BIO).\n", err && *err ? *err : "");
+               goto end;
+       }
+
+       if (BIO_read_filename(bio, path) == 1) {
+
+               pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
+
+               if (!pkey) {
+                       memprintf(err, "%sfile not found (%s)\n", err && *err ? *err : "", path);
+                       goto end;
+               }
+
+               entry = calloc(1, sizeof(*entry) + pathlen + 1);
+               if (!entry) {
+                       memprintf(err, "%sunable to allocate memory (jwt_cert_tree_entry).\n", err && *err ? *err : "");
+                       goto end;
+               }
+
+               memcpy(entry->path, path, pathlen + 1);
+               entry->pkey = pkey;
+
+               ebst_insert(&jwt_cert_tree, &entry->node);
+               retval = 0;
+       }
+
+end:
+       BIO_free(bio);
+       return retval;
+}
 #endif /* USE_OPENSSL */