apr_byte_t oidc_util_jwt_create(request_rec *r, const char *secret, json_t *payload,
		char **compact_encoded_jwt, apr_byte_t strip_header) {

	apr_byte_t rv = FALSE;
	oidc_jose_error_t err;

	oidc_jwk_t *jwk = NULL;
	oidc_jwt_t *jwt = NULL;
	oidc_jwt_t *jwe = NULL;

	if (oidc_util_create_symmetric_key(r, secret, 0, OIDC_JOSE_ALG_SHA256, FALSE, &jwk) == FALSE)
		goto end;

	jwt = oidc_jwt_new(r->pool, TRUE, FALSE);
	if (jwt == NULL) {
		oidc_error(r, "creating JWT failed");
		goto end;
	}

	jwt->header.alg = apr_pstrdup(r->pool, CJOSE_HDR_ALG_HS256);
	jwt->payload.value.json = payload;

	if (oidc_jwt_sign(r->pool, jwt, jwk, &err) == FALSE) {
		oidc_error(r, "signing JWT failed: %s", oidc_jose_e2s(r->pool, err));
		goto end;
	}

	jwe = oidc_jwt_new(r->pool, TRUE, FALSE);
	if (jwe == NULL) {
		oidc_error(r, "creating JWE failed");
		goto end;
	}

	jwe->header.alg = apr_pstrdup(r->pool, CJOSE_HDR_ALG_DIR);
	jwe->header.enc = apr_pstrdup(r->pool, CJOSE_HDR_ENC_A256GCM);

	const char *cser = oidc_jwt_serialize(r->pool, jwt, &err);
	if (oidc_jwt_encrypt(r->pool, jwe, jwk, cser, compact_encoded_jwt, &err) == FALSE) {
		oidc_error(r, "encrypting JWT failed: %s", oidc_jose_e2s(r->pool, err));
		goto end;
	}

	if (strip_header == TRUE)
		*compact_encoded_jwt += strlen(OIDC_JWT_HDR_DIR_A256GCM);

	rv = TRUE;

end:

	if (jwe != NULL)
		oidc_jwt_destroy(jwe);
	if (jwk != NULL)
		oidc_jwk_destroy(jwk);
	if (jwt != NULL) {
		jwt->payload.value.json = NULL;
		oidc_jwt_destroy(jwt);
	}

	return rv;
}
apr_byte_t oidc_util_jwt_create(request_rec *r, const char *secret, json_t *payload,
		char **compact_encoded_jwt, apr_byte_t strip_header) {

	apr_byte_t rv = FALSE;
	oidc_jose_error_t err;

	oidc_jwk_t *jwk = NULL;
	oidc_jwt_t *jwt = NULL;
	oidc_jwt_t *jwe = NULL;

	if (oidc_util_create_symmetric_key(r, secret, 0, OIDC_JOSE_ALG_SHA256, FALSE, &jwk) == FALSE)
		goto end;

	jwt = oidc_jwt_new(r->pool, TRUE, FALSE);
	if (jwt == NULL) {
		oidc_error(r, "creating JWT failed");
		goto end;
	}

	jwt->header.alg = apr_pstrdup(r->pool, CJOSE_HDR_ALG_HS256);
	jwt->payload.value.json = payload;

	if (oidc_jwt_sign(r->pool, jwt, jwk, &err) == FALSE) {
		oidc_error(r, "signing JWT failed: %s", oidc_jose_e2s(r->pool, err));
		goto end;
	}

	jwe = oidc_jwt_new(r->pool, TRUE, FALSE);
	if (jwe == NULL) {
		oidc_error(r, "creating JWE failed");
		goto end;
	}

	jwe->header.alg = apr_pstrdup(r->pool, CJOSE_HDR_ALG_DIR);
	jwe->header.enc = apr_pstrdup(r->pool, CJOSE_HDR_ENC_A256GCM);

	const char *cser = oidc_jwt_serialize(r->pool, jwt, &err);
	if (oidc_jwt_encrypt(r->pool, jwe, jwk, cser, compact_encoded_jwt, &err) == FALSE) {
		oidc_error(r, "encrypting JWT failed: %s", oidc_jose_e2s(r->pool, err));
		goto end;
	}

	if (strip_header == TRUE)
		*compact_encoded_jwt += strlen(OIDC_JWT_HDR_DIR_A256GCM);

	rv = TRUE;

end:

	if (jwe != NULL)
		oidc_jwt_destroy(jwe);
	if (jwk != NULL)
		oidc_jwk_destroy(jwk);
	if (jwt != NULL) {
		jwt->payload.value.json = NULL;
		oidc_jwt_destroy(jwt);
	}

	return rv;
}