diff --git a/include/haproxy/jwt-t.h b/include/haproxy/jwt-t.h index ecd05f509..6ac68b166 100644 --- a/include/haproxy/jwt-t.h +++ b/include/haproxy/jwt-t.h @@ -40,6 +40,27 @@ enum jwt_alg { JWS_ALG_PS384, JWS_ALG_PS512, }; + +struct jwt_item { + char *start; + size_t length; +}; + +struct jwt_ctx { + enum jwt_alg alg; + struct jwt_item jose; + struct jwt_item claims; + struct jwt_item signature; + char *key; + unsigned int key_length; +}; + +enum jwt_elt { + JWT_ELT_JOSE = 0, + JWT_ELT_CLAIMS, + JWT_ELT_SIG, + JWT_ELT_MAX +}; #endif /* USE_OPENSSL */ diff --git a/include/haproxy/jwt.h b/include/haproxy/jwt.h index e1abdb5e5..b24cc28cf 100644 --- a/include/haproxy/jwt.h +++ b/include/haproxy/jwt.h @@ -27,6 +27,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); #endif /* USE_OPENSSL */ #endif /* _HAPROXY_JWT_H */ diff --git a/src/jwt.c b/src/jwt.c index 3d7536852..9f39a89fe 100644 --- a/src/jwt.c +++ b/src/jwt.c @@ -77,4 +77,47 @@ enum jwt_alg jwt_parse_alg(const char *alg_str, unsigned int alg_len) return alg; } + + +/* + * Split a JWT into its separate dot-separated parts. + * Since only JWS following the Compact Serialization format are managed for + * now, we don't need to manage more than three subparts in the tokens. + * See section 3.1 of RFC7515 for more information about JWS Compact + * Serialization. + * Returns 0 in case of success. + */ +int jwt_tokenize(const struct buffer *jwt, struct jwt_item *items, unsigned int *item_num) +{ + char *ptr = jwt->area; + char *jwt_end = jwt->area + jwt->data; + unsigned int index = 0; + unsigned int length = 0; + + if (index < *item_num) { + items[index].start = ptr; + items[index].length = 0; + } + + while (index < *item_num && ptr < jwt_end) { + if (*ptr++ == '.') { + items[index++].length = length; + + if (index == *item_num) + return -1; + items[index].start = ptr; + items[index].length = 0; + length = 0; + } else + ++length; + } + + if (index < *item_num) + items[index].length = length; + + *item_num = (index+1); + + return (ptr != jwt_end); +} + #endif /* USE_OPENSSL */