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.
diff --git a/Makefile b/Makefile
index 9401237..50a21b3 100644
--- a/Makefile
+++ b/Makefile
@@ -585,7 +585,7 @@
 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 0000000..ecd05f5
--- /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 <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
index 0000000..e1abdb5
--- /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 <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
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 */