From 7feb36177618026a9ed5b2f21c995093b087bd7e Mon Sep 17 00:00:00 2001 From: Remi Tricot-Le Breton Date: Fri, 1 Oct 2021 15:36:54 +0200 Subject: [PATCH] MINOR: jwt: Parse JWT alg field The full list of possible algorithms used to create a JWS signature is defined in section 3.1 of RFC7518. This patch adds a helper function that converts the "alg" strings into an enum member. --- Makefile | 2 +- include/haproxy/jwt-t.h | 46 ++++++++++++++++++++++++ include/haproxy/jwt.h | 32 +++++++++++++++++ src/jwt.c | 80 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 include/haproxy/jwt-t.h create mode 100644 include/haproxy/jwt.h create mode 100644 src/jwt.c diff --git a/Makefile b/Makefile index 940123781..50a21b310 100644 --- a/Makefile +++ b/Makefile @@ -585,7 +585,7 @@ OPTIONS_LDFLAGS += $(if $(SSL_LIB),-L$(SSL_LIB)) -lssl -lcrypto ifneq ($(USE_DL),) OPTIONS_LDFLAGS += -ldl endif -OPTIONS_OBJS += src/ssl_sample.o src/ssl_sock.o src/ssl_crtlist.o src/ssl_ckch.o src/ssl_utils.o src/cfgparse-ssl.o +OPTIONS_OBJS += src/ssl_sample.o src/ssl_sock.o src/ssl_crtlist.o src/ssl_ckch.o src/ssl_utils.o src/cfgparse-ssl.o src/jwt.o endif ifneq ($(USE_QUIC),) OPTIONS_OBJS += src/quic_sock.o src/proto_quic.o src/xprt_quic.o src/quic_tls.o \ diff --git a/include/haproxy/jwt-t.h b/include/haproxy/jwt-t.h new file mode 100644 index 000000000..ecd05f509 --- /dev/null +++ b/include/haproxy/jwt-t.h @@ -0,0 +1,46 @@ +/* + * include/haproxy/jwt-t.h + * Macros, variables and structures for JWT management. + * + * Copyright (C) 2021 HAProxy Technologies, Remi Tricot-Le Breton + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, version 2.1 + * exclusively. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _HAPROXY_JWT_T_H +#define _HAPROXY_JWT_T_H + + +#ifdef USE_OPENSSL +enum jwt_alg { + JWT_ALG_DEFAULT, + JWS_ALG_NONE, + JWS_ALG_HS256, + JWS_ALG_HS384, + JWS_ALG_HS512, + JWS_ALG_RS256, + JWS_ALG_RS384, + JWS_ALG_RS512, + JWS_ALG_ES256, + JWS_ALG_ES384, + JWS_ALG_ES512, + JWS_ALG_PS256, + JWS_ALG_PS384, + JWS_ALG_PS512, +}; +#endif /* USE_OPENSSL */ + + +#endif /* _HAPROXY_JWT_T_H */ diff --git a/include/haproxy/jwt.h b/include/haproxy/jwt.h new file mode 100644 index 000000000..e1abdb5e5 --- /dev/null +++ b/include/haproxy/jwt.h @@ -0,0 +1,32 @@ +/* + * include/haproxy/jwt.h + * Functions for JSON Web Token (JWT) management. + * + * Copyright (C) 2021 HAProxy Technologies, Remi Tricot-Le Breton + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, version 2.1 + * exclusively. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _HAPROXY_JWT_H +#define _HAPROXY_JWT_H + +#include +#include + +#ifdef USE_OPENSSL +enum jwt_alg jwt_parse_alg(const char *alg_str, unsigned int alg_len); +#endif /* USE_OPENSSL */ + +#endif /* _HAPROXY_JWT_H */ diff --git a/src/jwt.c b/src/jwt.c new file mode 100644 index 000000000..3d7536852 --- /dev/null +++ b/src/jwt.c @@ -0,0 +1,80 @@ +/* + * JSON Web Token (JWT) processing + * + * Copyright 2021 HAProxy Technologies + * Remi Tricot-Le Breton + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include + +#include +#include +#include +#include +#include + + +#ifdef USE_OPENSSL +/* + * The possible algorithm strings that can be found in a JWS's JOSE header are + * defined in section 3.1 of RFC7518. + */ +enum jwt_alg jwt_parse_alg(const char *alg_str, unsigned int alg_len) +{ + enum jwt_alg alg = JWT_ALG_DEFAULT; + + /* Algorithms are all 5 characters long apart from "none". */ + if (alg_len < sizeof("HS256")-1) { + if (strncmp("none", alg_str, alg_len) == 0) + alg = JWS_ALG_NONE; + return alg; + } + + if (alg == JWT_ALG_DEFAULT) { + switch(*alg_str++) { + case 'H': + if (strncmp(alg_str, "S256", alg_len-1) == 0) + alg = JWS_ALG_HS256; + else if (strncmp(alg_str, "S384", alg_len-1) == 0) + alg = JWS_ALG_HS384; + else if (strncmp(alg_str, "S512", alg_len-1) == 0) + alg = JWS_ALG_HS512; + break; + case 'R': + if (strncmp(alg_str, "S256", alg_len-1) == 0) + alg = JWS_ALG_RS256; + else if (strncmp(alg_str, "S384", alg_len-1) == 0) + alg = JWS_ALG_RS384; + else if (strncmp(alg_str, "S512", alg_len-1) == 0) + alg = JWS_ALG_RS512; + break; + case 'E': + if (strncmp(alg_str, "S256", alg_len-1) == 0) + alg = JWS_ALG_ES256; + else if (strncmp(alg_str, "S384", alg_len-1) == 0) + alg = JWS_ALG_ES384; + else if (strncmp(alg_str, "S512", alg_len-1) == 0) + alg = JWS_ALG_ES512; + break; + case 'P': + if (strncmp(alg_str, "S256", alg_len-1) == 0) + alg = JWS_ALG_PS256; + else if (strncmp(alg_str, "S384", alg_len-1) == 0) + alg = JWS_ALG_PS384; + else if (strncmp(alg_str, "S512", alg_len-1) == 0) + alg = JWS_ALG_PS512; + break; + default: + break; + } + } + + return alg; +} +#endif /* USE_OPENSSL */