static apr_byte_t oidc_oauth_validate_jwt_access_token(request_rec *r,
		oidc_cfg *c, const char *access_token, json_t **token, char **response) {

	oidc_debug(r, "enter: JWT access_token header=%s",
			oidc_proto_peek_jwt_header(r, access_token, NULL));

	oidc_jose_error_t err;
	oidc_jwk_t *jwk = NULL;
	if (oidc_util_create_symmetric_key(r, c->provider.client_secret, 0, NULL,
			TRUE, &jwk) == FALSE)
		return FALSE;

	oidc_jwt_t *jwt = NULL;
	if (oidc_jwt_parse(r->pool, access_token, &jwt,
			oidc_util_merge_symmetric_key(r->pool, c->private_keys, jwk),
			&err) == FALSE) {
		oidc_error(r, "could not parse JWT from access_token: %s",
				oidc_jose_e2s(r->pool, err));
		return FALSE;
	}

	oidc_jwk_destroy(jwk);
	oidc_debug(r, "successfully parsed JWT with header: %s",
			jwt->header.value.str);

	/* validate the access token JWT, validating optional exp + iat */
	if (oidc_proto_validate_jwt(r, jwt, NULL, FALSE, FALSE,
			c->provider.idtoken_iat_slack) == FALSE) {
		oidc_jwt_destroy(jwt);
		return FALSE;
	}

	oidc_debug(r,
			"verify JWT against %d statically configured public keys and %d shared keys, with JWKs URI set to %s",
			c->oauth.verify_public_keys ?
					apr_hash_count(c->oauth.verify_public_keys) : 0,
					c->oauth.verify_shared_keys ?
							apr_hash_count(c->oauth.verify_shared_keys) : 0,
							c->oauth.verify_jwks_uri);

	oidc_jwks_uri_t jwks_uri = { c->oauth.verify_jwks_uri,
			c->provider.jwks_refresh_interval, c->oauth.ssl_validate_server };
	if (oidc_proto_jwt_verify(r, c, jwt, &jwks_uri,
			oidc_util_merge_key_sets(r->pool, c->oauth.verify_public_keys,
					c->oauth.verify_shared_keys)) == FALSE) {
		oidc_error(r,
				"JWT access token signature could not be validated, aborting");
		oidc_jwt_destroy(jwt);
		return FALSE;
	}

	oidc_debug(r, "successfully verified JWT access token: %s",
			jwt->payload.value.str);

	*token = jwt->payload.value.json;
	*response = jwt->payload.value.str;

	return TRUE;
}
static apr_byte_t oidc_oauth_validate_jwt_access_token(request_rec *r,
		oidc_cfg *c, const char *access_token, json_t **token, char **response) {

	oidc_debug(r, "enter: JWT access_token header=%s",
			oidc_proto_peek_jwt_header(r, access_token, NULL));

	oidc_jose_error_t err;
	oidc_jwk_t *jwk = NULL;
	if (oidc_util_create_symmetric_key(r, c->provider.client_secret, 0, NULL,
			TRUE, &jwk) == FALSE)
		return FALSE;

	oidc_jwt_t *jwt = NULL;
	if (oidc_jwt_parse(r->pool, access_token, &jwt,
			oidc_util_merge_symmetric_key(r->pool, c->private_keys, jwk),
			&err) == FALSE) {
		oidc_error(r, "could not parse JWT from access_token: %s",
				oidc_jose_e2s(r->pool, err));
		return FALSE;
	}

	oidc_jwk_destroy(jwk);
	oidc_debug(r, "successfully parsed JWT with header: %s",
			jwt->header.value.str);

	 
	if (oidc_proto_validate_jwt(r, jwt, NULL, FALSE, FALSE,
			c->provider.idtoken_iat_slack) == FALSE) {
		oidc_jwt_destroy(jwt);
		return FALSE;
	}

	oidc_debug(r,
			"verify JWT against %d statically configured public keys and %d shared keys, with JWKs URI set to %s",
			c->oauth.verify_public_keys ?
					apr_hash_count(c->oauth.verify_public_keys) : 0,
					c->oauth.verify_shared_keys ?
							apr_hash_count(c->oauth.verify_shared_keys) : 0,
							c->oauth.verify_jwks_uri);

	oidc_jwks_uri_t jwks_uri = { c->oauth.verify_jwks_uri,
			c->provider.jwks_refresh_interval, c->oauth.ssl_validate_server };
	if (oidc_proto_jwt_verify(r, c, jwt, &jwks_uri,
			oidc_util_merge_key_sets(r->pool, c->oauth.verify_public_keys,
					c->oauth.verify_shared_keys)) == FALSE) {
		oidc_error(r,
				"JWT access token signature could not be validated, aborting");
		oidc_jwt_destroy(jwt);
		return FALSE;
	}

	oidc_debug(r, "successfully verified JWT access token: %s",
			jwt->payload.value.str);

	*token = jwt->payload.value.json;
	*response = jwt->payload.value.str;

	return TRUE;
}