]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: jws: return size_t in JWS functions
authorWilliam Lallemand <wlallemand@haproxy.com>
Thu, 11 Sep 2025 12:25:03 +0000 (14:25 +0200)
committerWilliam Lallemand <wlallemand@haproxy.com>
Thu, 11 Sep 2025 12:31:32 +0000 (14:31 +0200)
JWS functions are supposed to return 0 upon error or when nothing was
produced. This was done in order to put easily the return value in
trash->data without having to check the return value.

However functions like a2base64url() or snprintf() could return a
negative value, which would be casted in a unsigned int if this happen.

This patch add checks on the JWS functions to ensure that no negative
value can be returned, and change the prototype from int to size_t.

This is also related to issue #3114.

Must be backported to 3.2.

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

index 7c419777c364dd05b3bbfc989adc9f7df4790826..f68147cff2a0050de8f202d3cfcd22cbe83f114c 100644 (file)
@@ -6,13 +6,13 @@
 #include <haproxy/openssl-compat.h>
 #include <haproxy/jwt-t.h>
 
-int bn2base64url(const BIGNUM *bn, char *dst, size_t dsize);
-int EVP_PKEY_to_pub_jwk(EVP_PKEY *pkey, char *dst, size_t dsize);
+size_t bn2base64url(const BIGNUM *bn, char *dst, size_t dsize);
+size_t EVP_PKEY_to_pub_jwk(EVP_PKEY *pkey, char *dst, size_t dsize);
 enum jwt_alg EVP_PKEY_to_jws_alg(EVP_PKEY *pkey);
-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);
+size_t jws_b64_payload(char *payload, char *dst, size_t dsize);
+size_t jws_b64_protected(enum jwt_alg alg, char *kid, char *jwk, char *nonce, char *url, char *dst, size_t dsize);
+size_t jws_b64_signature(EVP_PKEY *pkey, enum jwt_alg alg, char *b64protected, char *b64payload, char *dst, size_t dsize);
+size_t jws_flattened(char *protected, char *payload, char *signature, char *dst, size_t dsize);
+size_t jws_thumbprint(EVP_PKEY *pkey, char *dst, size_t dsize);
 
 #endif /* ! _HAPROXY_JWK_H_ */
index a7461c0b70b91026e229ead463608846eb0d9499..d83ce9b969eab949594a2aeb10416abc938b705f 100644 (file)
--- a/src/jws.c
+++ b/src/jws.c
@@ -18,7 +18,7 @@
  *
  * Return the size of the data dumped in <dst>
  */
-int bn2base64url(const BIGNUM *bn, char *dst, size_t dsize)
+size_t bn2base64url(const BIGNUM *bn, char *dst, size_t dsize)
 {
        struct buffer *bin;
        int binlen;
@@ -36,7 +36,9 @@ int bn2base64url(const BIGNUM *bn, char *dst, size_t dsize)
 
        ret = a2base64url(bin->area, binlen, dst, dsize);
 out:
-       return ret;
+       if (ret > 0)
+               return ret;
+       return 0;
 }
 
 /*
@@ -45,7 +47,7 @@ out:
  *
  * Return the size of the data or 0
  */
-static int EVP_PKEY_EC_to_pub_jwk(EVP_PKEY *pkey, char *dst, size_t dsize)
+static size_t EVP_PKEY_EC_to_pub_jwk(EVP_PKEY *pkey, char *dst, size_t dsize)
 {
        BIGNUM *x = NULL, *y = NULL;
        struct buffer *str_x = NULL, *str_y = NULL;
@@ -125,7 +127,9 @@ out:
        BN_free(x);
        BN_free(y);
 
-       return ret;
+       if (ret > 0)
+               return ret;
+       return 0;
 }
 
 /*
@@ -134,7 +138,7 @@ out:
  *
  * Return the size of the data or 0
  */
-static int EVP_PKEY_RSA_to_pub_jwk(EVP_PKEY *pkey, char *dst, size_t dsize)
+static size_t EVP_PKEY_RSA_to_pub_jwk(EVP_PKEY *pkey, char *dst, size_t dsize)
 {
        BIGNUM *n = NULL, *e = NULL;
        struct buffer *str_n = NULL, *str_e = NULL;
@@ -184,7 +188,9 @@ out:
        free_trash_chunk(str_n);
        free_trash_chunk(str_e);
 
-       return ret;
+       if (ret > 0)
+               return ret;
+       return 0;
 }
 
 /* Convert an EVP_PKEY to a public key JWK
@@ -192,9 +198,9 @@ out:
  *
  * Return the size of the data or 0
  */
-int EVP_PKEY_to_pub_jwk(EVP_PKEY *pkey, char *dst, size_t dsize)
+size_t EVP_PKEY_to_pub_jwk(EVP_PKEY *pkey, char *dst, size_t dsize)
 {
-       int ret = 0;
+       size_t ret = 0;
 
        switch (EVP_PKEY_base_id(pkey)) {
                case EVP_PKEY_RSA:
@@ -217,8 +223,8 @@ int EVP_PKEY_to_pub_jwk(EVP_PKEY *pkey, char *dst, size_t dsize)
  * Return the size of the data or 0
  */
 
-int jws_b64_protected(enum jwt_alg alg, char *kid, char *jwk, char *nonce, char *url,
-                      char *dst, size_t dsize)
+size_t jws_b64_protected(enum jwt_alg alg, char *kid, char *jwk, char *nonce, char *url,
+                         char *dst, size_t dsize)
 {
        char *acc;
        char *acctype;
@@ -262,7 +268,9 @@ int jws_b64_protected(enum jwt_alg alg, char *kid, char *jwk, char *nonce, char
        ret = a2base64url(json->area, json->data, dst, dsize);
 out:
        free_trash_chunk(json);
-       return ret;
+       if (ret > 0)
+               return ret;
+       return 0;
 }
 
 /*
@@ -271,13 +279,15 @@ out:
  * Return the size of the data or 0
  */
 
-int jws_b64_payload(char *payload, char *dst, size_t dsize)
+size_t jws_b64_payload(char *payload, char *dst, size_t dsize)
 {
        int ret = 0;
 
        ret = a2base64url(payload, strlen(payload), dst, dsize);
 
-       return ret;
+       if (ret > 0)
+               return ret;
+       return 0;
 }
 
 /*
@@ -344,7 +354,7 @@ out:
  *
  *  Return the size of the data or 0
  */
-int jws_b64_signature(EVP_PKEY *pkey, enum jwt_alg alg, char *b64protected, char *b64payload, char *dst, size_t dsize)
+size_t jws_b64_signature(EVP_PKEY *pkey, enum jwt_alg alg, char *b64protected, char *b64payload, char *dst, size_t dsize)
 {
        EVP_MD_CTX *ctx;
        const EVP_MD *evp_md = NULL;
@@ -442,8 +452,9 @@ int jws_b64_signature(EVP_PKEY *pkey, enum jwt_alg alg, char *b64protected, char
 out:
        free_trash_chunk(sign);
 
-       return ret;
-
+       if (ret > 0)
+               return ret;
+       return 0;
 }
 
 /*
@@ -451,7 +462,7 @@ out:
  *
  * Return the size of the data or 0
  */
-int jws_thumbprint(EVP_PKEY *pkey, char *dst, size_t dsize)
+size_t jws_thumbprint(EVP_PKEY *pkey, char *dst, size_t dsize)
 {
        int ret = 0;
        struct buffer *jwk = NULL;
@@ -480,11 +491,13 @@ int jws_thumbprint(EVP_PKEY *pkey, char *dst, size_t dsize)
 
 out:
        free_trash_chunk(jwk);
-       return ret;
+       if (ret > 0)
+               return ret;
+       return 0;
 }
 
 
-int jws_flattened(char *protected, char *payload, char *signature, char *dst, size_t dsize)
+size_t jws_flattened(char *protected, char *payload, char *signature, char *dst, size_t dsize)
 {
        int ret = 0;
 
@@ -497,7 +510,10 @@ int jws_flattened(char *protected, char *payload, char *signature, char *dst, si
 
        if (ret >= dsize)
                ret = 0;
-       return ret;
+
+       if (ret > 0)
+               return ret;
+       return 0;
 }