]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: jws: emit the JWK thumbprint
authorWilliam Lallemand <wlallemand@haproxy.com>
Tue, 25 Mar 2025 14:21:50 +0000 (15:21 +0100)
committerWilliam Lallemand <wlallemand@haproxy.com>
Tue, 1 Apr 2025 09:57:55 +0000 (11:57 +0200)
jwk_thumbprint() is a function which is a function which implements
RFC7368 and emits a JWK thumbprint using a EVP_PKEY.

EVP_PKEY_EC_to_pub_jwk() and EVP_PKEY_RSA_to_pub_jwk() were changed in
order to match what is required to emit a thumbprint (ie, no spaces or
lines and the lexicographic order of the fields)

include/haproxy/jws.h
src/jws.c

index 43d4776957d50dda29f8ad8cc640b2cb8ef08b8c..7c419777c364dd05b3bbfc989adc9f7df4790826 100644 (file)
@@ -13,5 +13,6 @@ int jws_b64_payload(char *payload, char *dst, size_t dsize);
 int jws_b64_protected(enum jwt_alg alg, char *kid, char *jwk, char *nonce, char *url, char *dst, size_t dsize);
 int jws_b64_signature(EVP_PKEY *pkey, enum jwt_alg alg, char *b64protected, char *b64payload, char *dst, size_t dsize);
 int jws_flattened(char *protected, char *payload, char *signature, char *dst, size_t dsize);
+int jws_thumbprint(EVP_PKEY *pkey, char *dst, size_t dsize);
 
 #endif /* ! _HAPROXY_JWK_H_ */
index 8278df43b712884e924585333b304a5ae4adda41..731e6ad46ab939443a644011e2abf4435c6e5ba7 100644 (file)
--- a/src/jws.c
+++ b/src/jws.c
@@ -148,13 +148,13 @@ static int EVP_PKEY_EC_to_pub_jwk(EVP_PKEY *pkey, char *dst, size_t dsize)
        if (str_x->data == 0 || str_y->data == 0)
                goto out;
 
-       ret = snprintf(dst, dsize, "{\n"
-                       "    \"kty\": \"%s\",\n"
-                       "    \"crv\": \"%s\",\n"
-                       "    \"x\":   \"%s\",\n"
-                       "    \"y\":   \"%s\"\n"
-                       "}\n",
-                       "EC", crv, str_x->area, str_y->area);
+       ret = snprintf(dst, dsize, "{"
+                       "\"crv\":\"%s\","
+                       "\"kty\":\"%s\","
+                       "\"x\":\"%s\","
+                       "\"y\":\"%s\""
+                       "}",
+                       crv, "EC", str_x->area, str_y->area);
        if (ret >= dsize)
                ret = 0;
 
@@ -209,12 +209,12 @@ static int EVP_PKEY_RSA_to_pub_jwk(EVP_PKEY *pkey, char *dst, size_t dsize)
        if (str_n->data == 0 || str_e->data == 0)
                goto out;
 
-       ret = snprintf(dst, dsize, "{\n"
-                       "    \"kty\": \"%s\",\n"
-                       "    \"n\":   \"%s\",\n"
-                       "    \"e\":   \"%s\"\n"
-                       "}\n",
-                       "RSA", str_n->area, str_e->area);
+       ret = snprintf(dst, dsize, "{"
+                       "\"e\":\"%s\","
+                       "\"kty\":\"%s\","
+                       "\"n\":\"%s\""
+                       "}",
+                       str_e->area, "RSA", str_n->area );
        if (ret >= dsize)
                ret = 0;
 
@@ -486,6 +486,44 @@ out:
 
 }
 
+/*
+ * Fill a <dst> buffer of <dsize> size with a jwk thumbprint from a pkey
+ *
+ * Return the size of the data or 0
+ */
+int jws_thumbprint(EVP_PKEY *pkey, char *dst, size_t dsize)
+{
+       int ret = 0;
+       struct buffer *jwk = NULL;
+       unsigned char md[EVP_MAX_MD_SIZE];
+       unsigned int size;
+
+       if ((jwk = alloc_trash_chunk()) == NULL)
+               goto out;
+
+       switch (EVP_PKEY_base_id(pkey)) {
+               case EVP_PKEY_RSA:
+                       jwk->data = EVP_PKEY_RSA_to_pub_jwk(pkey, jwk->area, jwk->size);
+                       break;
+               case EVP_PKEY_EC:
+                       jwk->data = EVP_PKEY_EC_to_pub_jwk(pkey, jwk->area, jwk->size);
+                       break;
+               default:
+                       break;
+       }
+
+
+       if (EVP_Digest(jwk->area, jwk->data, md, &size, EVP_sha256(), NULL) == 0)
+               goto out;
+
+       ret = a2base64url((const char *)md, size, dst, dsize);
+
+out:
+       free_trash_chunk(jwk);
+       return ret;
+}
+
+
 int jws_flattened(char *protected, char *payload, char *signature, char *dst, size_t dsize)
 {
        int ret = 0;