apr_byte_t oidc_util_json_validate_cnf_tbh(request_rec *r,
		int token_binding_policy, const char *tbh_str) {
	const char *tbp_str = NULL;
	char *tbp = NULL;
	int tbp_len = -1;
	unsigned char *tbp_hash = NULL;
	unsigned int tbp_hash_len = -1;
	char *tbh = NULL;
	int tbh_len = -1;

	tbp_str = oidc_util_get_provided_token_binding_id(r);
	if (tbp_str == NULL) {
		oidc_debug(r,
				"no Provided Token Binding ID environment variable found");
		goto out_err;
	}

	tbp_len = oidc_base64url_decode(r->pool, &tbp, tbp_str);
	if (tbp_len <= 0) {
		oidc_warn(r,
				"Provided Token Binding ID environment variable could not be decoded");
		goto out_err;
	}

	if (oidc_jose_hash_bytes(r->pool, OIDC_JOSE_ALG_SHA256,
			(const unsigned char*) tbp, tbp_len, &tbp_hash, &tbp_hash_len,
			NULL) == FALSE) {
		oidc_warn(r,
				"hashing Provided Token Binding ID environment variable failed");
		goto out_err;
	}

	tbh_len = oidc_base64url_decode(r->pool, &tbh, tbh_str);
	if (tbh_len <= 0) {
		oidc_warn(r, "cnf[\"tbh\"] provided but it could not be decoded");
		goto out_err;
	}

	if (tbp_hash_len != tbh_len) {
		oidc_warn(r,
				"hash length of provided token binding ID environment variable: %d does not match length of cnf[\"tbh\"]: %d",
				tbp_hash_len, tbh_len);
		goto out_err;
	}

	if (memcmp(tbp_hash, tbh, tbh_len) != 0) {
		oidc_warn(r,
				"hash of provided token binding ID environment variable does not match cnf[\"tbh\"]");
		goto out_err;
	}

	oidc_debug(r,
			"hash of provided token binding ID environment variable matches cnf[\"tbh\"]");

	return TRUE;

out_err:

	if (token_binding_policy == OIDC_TOKEN_BINDING_POLICY_OPTIONAL)
		return TRUE;
	if (token_binding_policy == OIDC_TOKEN_BINDING_POLICY_ENFORCED)
		return FALSE;

	// token_binding_policy == OIDC_TOKEN_BINDING_POLICY_REQURIED
	return (tbp_str == NULL);
}
apr_byte_t oidc_util_json_validate_cnf_tbh(request_rec *r,
		int token_binding_policy, const char *tbh_str) {
	const char *tbp_str = NULL;
	char *tbp = NULL;
	int tbp_len = -1;
	unsigned char *tbp_hash = NULL;
	unsigned int tbp_hash_len = -1;
	char *tbh = NULL;
	int tbh_len = -1;

	tbp_str = oidc_util_get_provided_token_binding_id(r);
	if (tbp_str == NULL) {
		oidc_debug(r,
				"no Provided Token Binding ID environment variable found");
		goto out_err;
	}

	tbp_len = oidc_base64url_decode(r->pool, &tbp, tbp_str);
	if (tbp_len <= 0) {
		oidc_warn(r,
				"Provided Token Binding ID environment variable could not be decoded");
		goto out_err;
	}

	if (oidc_jose_hash_bytes(r->pool, OIDC_JOSE_ALG_SHA256,
			(const unsigned char*) tbp, tbp_len, &tbp_hash, &tbp_hash_len,
			NULL) == FALSE) {
		oidc_warn(r,
				"hashing Provided Token Binding ID environment variable failed");
		goto out_err;
	}

	tbh_len = oidc_base64url_decode(r->pool, &tbh, tbh_str);
	if (tbh_len <= 0) {
		oidc_warn(r, "cnf[\"tbh\"] provided but it could not be decoded");
		goto out_err;
	}

	if (tbp_hash_len != tbh_len) {
		oidc_warn(r,
				"hash length of provided token binding ID environment variable: %d does not match length of cnf[\"tbh\"]: %d",
				tbp_hash_len, tbh_len);
		goto out_err;
	}

	if (memcmp(tbp_hash, tbh, tbh_len) != 0) {
		oidc_warn(r,
				"hash of provided token binding ID environment variable does not match cnf[\"tbh\"]");
		goto out_err;
	}

	oidc_debug(r,
			"hash of provided token binding ID environment variable matches cnf[\"tbh\"]");

	return TRUE;

out_err:

	if (token_binding_policy == OIDC_TOKEN_BINDING_POLICY_OPTIONAL)
		return TRUE;
	if (token_binding_policy == OIDC_TOKEN_BINDING_POLICY_ENFORCED)
		return FALSE;

	 
	return (tbp_str == NULL);
}