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

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

	if (ebst_insert(&jwt_cert_tree, &entry->node) != &entry->node) {
		free(entry);
		return 0; /* Entry already in the tree */
	}

	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->pkey = pkey;
		retval = 0;
	}

end:
	if (retval) {
		/* Some error happened during pkey parsing, remove the already
		 * inserted node from the tree and free it.
		 */
		ebmb_delete(&entry->node);
		free(entry);
	}
	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);
		ebmb_delete(node);
		EVP_PKEY_free(entry->pkey);
		ha_free(&entry);
		node = ebmb_first(&jwt_cert_tree);
	}
}
REGISTER_POST_DEINIT(jwt_deinit);


#endif /* USE_OPENSSL */
