/*
 * 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
/* Tree into which the public certificates used to validate JWTs will be stored. */
static struct eb_root jwt_cert_tree = EB_ROOT_UNIQUE;

/*
 * 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 (alg_len == sizeof("none")-1 && strcmp("none", alg_str) == 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;
}

/*
 * 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);
}

/*
 * Parse a public certificate and insert it into the jwt_cert_tree.
 * Returns 0 in case of success.
 */
int jwt_tree_load_cert(char *path, int pathlen, char **err)
{
	int retval = -1;
	struct jwt_cert_tree_entry *entry = NULL;
	EVP_PKEY *pkey = NULL;
	BIO *bio = NULL;

	bio = BIO_new(BIO_s_file());
	if (!bio) {
		memprintf(err, "%sunable to allocate memory (BIO).\n", err && *err ? *err : "");
		goto end;
	}

	if (BIO_read_filename(bio, path) == 1) {

		pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);

		if (!pkey) {
			memprintf(err, "%sfile not found (%s)\n", err && *err ? *err : "", path);
			goto end;
		}

		entry = calloc(1, sizeof(*entry) + pathlen + 1);
		if (!entry) {
			memprintf(err, "%sunable to allocate memory (jwt_cert_tree_entry).\n", err && *err ? *err : "");
			goto end;
		}

		memcpy(entry->path, path, pathlen + 1);
		entry->pkey = pkey;

		ebst_insert(&jwt_cert_tree, &entry->node);
		retval = 0;
	}

end:
	BIO_free(bio);
	return retval;
}

/*
 * Calculate the HMAC signature of a specific JWT and check that it matches the
 * one included in the token.
 * Returns 1 in case of success.
 */
static enum jwt_vrfy_status
jwt_jwsverify_hmac(const struct jwt_ctx *ctx, const struct buffer *decoded_signature)
{
	const EVP_MD *evp = NULL;
	unsigned char signature[EVP_MAX_MD_SIZE];
	unsigned int signature_length = 0;
	unsigned char *hmac_res = NULL;
	enum jwt_vrfy_status retval = JWT_VRFY_KO;

	switch(ctx->alg) {
	case JWS_ALG_HS256:
		evp = EVP_sha256();
		break;
	case JWS_ALG_HS384:
		evp = EVP_sha384();
		break;
	case JWS_ALG_HS512:
		evp = EVP_sha512();
		break;
	default: break;
	}

	hmac_res = HMAC(evp, ctx->key, ctx->key_length, (const unsigned char*)ctx->jose.start,
			ctx->jose.length + ctx->claims.length + 1, signature, &signature_length);

	if (hmac_res && signature_length == decoded_signature->data &&
		  (CRYPTO_memcmp(decoded_signature->area, signature, signature_length) == 0))
		retval = JWT_VRFY_OK;

	return retval;
}

/*
 * Check that the signature included in a JWT signed via RSA or ECDSA is valid
 * and can be verified thanks to a given public certificate.
 * Returns 1 in case of success.
 */
static enum jwt_vrfy_status
jwt_jwsverify_rsa_ecdsa(const struct jwt_ctx *ctx, const struct buffer *decoded_signature)
{
	const EVP_MD *evp = NULL;
	EVP_MD_CTX *evp_md_ctx;
	enum jwt_vrfy_status retval = JWT_VRFY_KO;
	struct ebmb_node *eb;
	struct jwt_cert_tree_entry *entry = NULL;

	switch(ctx->alg) {
	case JWS_ALG_RS256:
	case JWS_ALG_ES256:
		evp = EVP_sha256();
		break;
	case JWS_ALG_RS384:
	case JWS_ALG_ES384:
		evp = EVP_sha384();
		break;
	case JWS_ALG_RS512:
	case JWS_ALG_ES512:
		evp = EVP_sha512();
		break;
	default: break;
	}

	evp_md_ctx = EVP_MD_CTX_new();
	if (!evp_md_ctx)
		return JWT_VRFY_OUT_OF_MEMORY;

	eb = ebst_lookup(&jwt_cert_tree, ctx->key);

	if (!eb) {
		retval = JWT_VRFY_UNKNOWN_CERT;
		goto end;
	}

	entry = ebmb_entry(eb, struct jwt_cert_tree_entry, node);

	if (!entry->pkey) {
		retval = JWT_VRFY_UNKNOWN_CERT;
		goto end;
	}

	if (EVP_DigestVerifyInit(evp_md_ctx, NULL, evp, NULL,entry-> pkey) == 1 &&
	    EVP_DigestVerifyUpdate(evp_md_ctx, (const unsigned char*)ctx->jose.start,
				   ctx->jose.length + ctx->claims.length + 1) == 1 &&
	    EVP_DigestVerifyFinal(evp_md_ctx, (const unsigned char*)decoded_signature->area, decoded_signature->data) == 1) {
		retval = JWT_VRFY_OK;
	}

end:
	EVP_MD_CTX_free(evp_md_ctx);
	return retval;
}

/*
 * Check that the <token> that was signed via algorithm <alg> using the <key>
 * (either an HMAC secret or the path to a public certificate) has a valid
 * signature.
 * Returns 1 in case of success.
 */
enum jwt_vrfy_status jwt_verify(const struct buffer *token, const struct buffer *alg,
				const struct buffer *key)
{
	struct jwt_item items[JWT_ELT_MAX] = { { 0 } };
	unsigned int item_num = JWT_ELT_MAX;
	struct buffer *decoded_sig = NULL;
	struct jwt_ctx ctx = {};
	enum jwt_vrfy_status retval = JWT_VRFY_KO;
	int ret;

	ctx.alg = jwt_parse_alg(alg->area, alg->data);

	if (ctx.alg == JWT_ALG_DEFAULT)
		return JWT_VRFY_UNKNOWN_ALG;

	if (jwt_tokenize(token, items, &item_num))
		return JWT_VRFY_INVALID_TOKEN;

	if (item_num != JWT_ELT_MAX)
		if (ctx.alg != JWS_ALG_NONE || item_num != JWT_ELT_SIG)
			return JWT_VRFY_INVALID_TOKEN;

	ctx.jose = items[JWT_ELT_JOSE];
	ctx.claims = items[JWT_ELT_CLAIMS];
	ctx.signature = items[JWT_ELT_SIG];

	/* "alg" is "none", the signature must be empty for the JWS to be valid. */
	if (ctx.alg == JWS_ALG_NONE) {
		return (ctx.signature.length == 0) ? JWT_VRFY_OK : JWT_VRFY_KO;
	}

	if (ctx.signature.length == 0)
		return JWT_VRFY_INVALID_TOKEN;

	decoded_sig = alloc_trash_chunk();
	if (!decoded_sig)
		return JWT_VRFY_OUT_OF_MEMORY;

	ret = base64urldec(ctx.signature.start, ctx.signature.length,
	                   decoded_sig->area, decoded_sig->size);
	if (ret == -1) {
		retval = JWT_VRFY_INVALID_TOKEN;
		goto end;
	}

	decoded_sig->data = ret;
	ctx.key = key->area;
	ctx.key_length = key->data;

	/* We have all three sections, signature calculation can begin. */

	switch(ctx.alg) {

	case JWS_ALG_HS256:
	case JWS_ALG_HS384:
	case JWS_ALG_HS512:
		/* HMAC + SHA-XXX */
		retval = jwt_jwsverify_hmac(&ctx, decoded_sig);
		break;
	case JWS_ALG_RS256:
	case JWS_ALG_RS384:
	case JWS_ALG_RS512:
	case JWS_ALG_ES256:
	case JWS_ALG_ES384:
	case JWS_ALG_ES512:
		/* RSASSA-PKCS1-v1_5 + SHA-XXX */
		/* ECDSA using P-XXX and SHA-XXX */
		retval = jwt_jwsverify_rsa_ecdsa(&ctx, decoded_sig);
		break;
	case JWS_ALG_PS256:
	case JWS_ALG_PS384:
	case JWS_ALG_PS512:
	default:
		/* RSASSA-PSS using SHA-XXX and MGF1 with SHA-XXX */

		/* Not managed yet */
		retval = JWT_VRFY_UNMANAGED_ALG;
		break;
	}

end:
	free_trash_chunk(decoded_sig);

	return retval;
}

static void jwt_deinit(void)
{
	struct ebmb_node *node = NULL;
	struct jwt_cert_tree_entry *entry = NULL;

	node = ebmb_first(&jwt_cert_tree);
	while (node) {
		entry = ebmb_entry(node, struct jwt_cert_tree_entry, node);
		ha_free(&entry);
		node = ebmb_first(&jwt_cert_tree);
	}
}
REGISTER_POST_DEINIT(jwt_deinit);


#endif /* USE_OPENSSL */
