/*
 * 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>
#include <haproxy/buf.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;
}

/*
 * Convert a JWT ECDSA signature (R and S parameters concatenatedi, see section
 * 3.4 of RFC7518) into an ECDSA_SIG that can be fed back into OpenSSL's digest
 * verification functions.
 * Returns 0 in case of success.
 */
static int convert_ecdsa_sig(const struct jwt_ctx *ctx, EVP_PKEY *pkey, struct buffer *signature)
{
	int retval = 0;
	ECDSA_SIG *ecdsa_sig = NULL;
	BIGNUM *ec_R = NULL, *ec_S = NULL;
	unsigned int bignum_len;
	unsigned char *p;

	ecdsa_sig = ECDSA_SIG_new();
	if (!ecdsa_sig) {
		retval = JWT_VRFY_OUT_OF_MEMORY;
		goto end;
	}

	if (b_data(signature) % 2) {
		retval = JWT_VRFY_INVALID_TOKEN;
		goto end;
	}

	bignum_len = b_data(signature) / 2;

	ec_R = BN_bin2bn((unsigned char*)b_orig(signature), bignum_len, NULL);
	ec_S = BN_bin2bn((unsigned char *)(b_orig(signature) + bignum_len), bignum_len, NULL);

	if (!ec_R || !ec_S) {
		retval = JWT_VRFY_INVALID_TOKEN;
		goto end;
	}

	/* Build ecdsa out of R and S values. */
	ECDSA_SIG_set0(ecdsa_sig, ec_R, ec_S);

	p = (unsigned char*)signature->area;

	signature->data = i2d_ECDSA_SIG(ecdsa_sig, &p);
	if (signature->data == 0) {
		retval = JWT_VRFY_INVALID_TOKEN;
		goto end;
	}

end:
	ECDSA_SIG_free(ecdsa_sig);
	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, 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;
	int is_ecdsa = 0;

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

	case JWS_ALG_ES256:
		evp = EVP_sha256();
		is_ecdsa = 1;
		break;
	case JWS_ALG_ES384:
		evp = EVP_sha384();
		is_ecdsa = 1;
		break;
	case JWS_ALG_ES512:
		evp = EVP_sha512();
		is_ecdsa = 1;
		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;
	}

	/*
	 * ECXXX signatures are a direct concatenation of the (R, S) pair and
	 * need to be converted back to asn.1 in order for verify operations to
	 * work with OpenSSL.
	 */
	if (is_ecdsa) {
		int conv_retval = convert_ecdsa_sig(ctx, entry->pkey, decoded_signature);
		if (conv_retval != 0) {
			retval = conv_retval;
			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 */
