]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: jwt: Parse JWT alg field
authorRemi Tricot-Le Breton <rlebreton@haproxy.com>
Fri, 1 Oct 2021 13:36:54 +0000 (15:36 +0200)
committerWilliam Lallemand <wlallemand@haproxy.org>
Thu, 14 Oct 2021 14:38:08 +0000 (16:38 +0200)
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
include/haproxy/jwt-t.h [new file with mode: 0644]
include/haproxy/jwt.h [new file with mode: 0644]
src/jwt.c [new file with mode: 0644]

index 9401237815fa60140f7d88c43eb325a1bdbd6b76..50a21b3105cd66d069cc102b3bc64366926374e5 100644 (file)
--- 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 (file)
index 0000000..ecd05f5
--- /dev/null
@@ -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 <rlebreton@haproxy.com>
+ *
+ * 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 (file)
index 0000000..e1abdb5
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * include/haproxy/jwt.h
+ * Functions for JSON Web Token (JWT) management.
+ *
+ * Copyright (C) 2021 HAProxy Technologies, Remi Tricot-Le Breton <rlebreton@haproxy.com>
+ *
+ * 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 <haproxy/jwt-t.h>
+#include <haproxy/buf-t.h>
+
+#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 (file)
index 0000000..3d75368
--- /dev/null
+++ b/src/jwt.c
@@ -0,0 +1,80 @@
+/*
+ * JSON Web Token (JWT) processing
+ *
+ * Copyright 2021 HAProxy Technologies
+ * Remi Tricot-Le Breton <rlebreton@haproxy.com>
+ *
+ * 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 <import/ebmbtree.h>
+#include <import/ebsttree.h>
+
+#include <haproxy/api.h>
+#include <haproxy/tools.h>
+#include <haproxy/openssl-compat.h>
+#include <haproxy/base64.h>
+#include <haproxy/jwt.h>
+
+
+#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 */