|
|
|
@ -320,6 +320,12 @@ grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims *claims, |
|
|
|
|
|
|
|
|
|
/* --- verifier_cb_ctx object. --- */ |
|
|
|
|
|
|
|
|
|
typedef enum { |
|
|
|
|
HTTP_RESPONSE_OPENID = 0, |
|
|
|
|
HTTP_RESPONSE_KEYS, |
|
|
|
|
HTTP_RESPONSE_COUNT /* must be last */ |
|
|
|
|
} http_response_index; |
|
|
|
|
|
|
|
|
|
typedef struct { |
|
|
|
|
grpc_jwt_verifier *verifier; |
|
|
|
|
grpc_pollset *pollset; |
|
|
|
@ -330,7 +336,7 @@ typedef struct { |
|
|
|
|
gpr_slice signed_data; |
|
|
|
|
void *user_data; |
|
|
|
|
grpc_jwt_verification_done_cb user_cb; |
|
|
|
|
grpc_http_response responses[2]; |
|
|
|
|
grpc_http_response responses[HTTP_RESPONSE_COUNT]; |
|
|
|
|
} verifier_cb_ctx; |
|
|
|
|
|
|
|
|
|
/* Takes ownership of the header, claims and signature. */ |
|
|
|
@ -359,7 +365,7 @@ void verifier_cb_ctx_destroy(verifier_cb_ctx *ctx) { |
|
|
|
|
gpr_slice_unref(ctx->signature); |
|
|
|
|
gpr_slice_unref(ctx->signed_data); |
|
|
|
|
jose_header_destroy(ctx->header); |
|
|
|
|
for (size_t i = 0; i < GPR_ARRAY_SIZE(ctx->responses); i++) { |
|
|
|
|
for (size_t i = 0; i < HTTP_RESPONSE_COUNT; i++) { |
|
|
|
|
grpc_http_response_destroy(&ctx->responses[i]); |
|
|
|
|
} |
|
|
|
|
/* TODO: see what to do with claims... */ |
|
|
|
@ -578,7 +584,7 @@ end: |
|
|
|
|
static void on_keys_retrieved(grpc_exec_ctx *exec_ctx, void *user_data, |
|
|
|
|
grpc_error *error) { |
|
|
|
|
verifier_cb_ctx *ctx = (verifier_cb_ctx *)user_data; |
|
|
|
|
grpc_json *json = json_from_http(&ctx->responses[1]); |
|
|
|
|
grpc_json *json = json_from_http(&ctx->responses[HTTP_RESPONSE_KEYS]); |
|
|
|
|
EVP_PKEY *verification_key = NULL; |
|
|
|
|
grpc_jwt_verifier_status status = GRPC_JWT_VERIFIER_GENERIC_ERROR; |
|
|
|
|
grpc_jwt_claims *claims = NULL; |
|
|
|
@ -620,7 +626,7 @@ static void on_openid_config_retrieved(grpc_exec_ctx *exec_ctx, void *user_data, |
|
|
|
|
grpc_error *error) { |
|
|
|
|
const grpc_json *cur; |
|
|
|
|
verifier_cb_ctx *ctx = (verifier_cb_ctx *)user_data; |
|
|
|
|
const grpc_http_response *response = &ctx->responses[0]; |
|
|
|
|
const grpc_http_response *response = &ctx->responses[HTTP_RESPONSE_OPENID]; |
|
|
|
|
grpc_json *json = json_from_http(response); |
|
|
|
|
grpc_httpcli_request req; |
|
|
|
|
const char *jwks_uri; |
|
|
|
@ -651,7 +657,8 @@ static void on_openid_config_retrieved(grpc_exec_ctx *exec_ctx, void *user_data, |
|
|
|
|
grpc_httpcli_get( |
|
|
|
|
exec_ctx, &ctx->verifier->http_ctx, ctx->pollset, &req, |
|
|
|
|
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay), |
|
|
|
|
grpc_closure_create(on_keys_retrieved, ctx), &ctx->responses[1]); |
|
|
|
|
grpc_closure_create(on_keys_retrieved, ctx), |
|
|
|
|
&ctx->responses[HTTP_RESPONSE_KEYS]); |
|
|
|
|
grpc_json_destroy(json); |
|
|
|
|
gpr_free(req.host); |
|
|
|
|
return; |
|
|
|
@ -699,7 +706,7 @@ static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx, |
|
|
|
|
grpc_httpcli_request req; |
|
|
|
|
memset(&req, 0, sizeof(grpc_httpcli_request)); |
|
|
|
|
req.handshaker = &grpc_httpcli_ssl; |
|
|
|
|
int rsp_idx; |
|
|
|
|
http_response_index rsp_idx; |
|
|
|
|
|
|
|
|
|
GPR_ASSERT(ctx != NULL && ctx->header != NULL && ctx->claims != NULL); |
|
|
|
|
iss = ctx->claims->iss; |
|
|
|
@ -739,7 +746,7 @@ static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx, |
|
|
|
|
gpr_asprintf(&req.http.path, "/%s/%s", path_prefix, iss); |
|
|
|
|
} |
|
|
|
|
http_cb = grpc_closure_create(on_keys_retrieved, ctx); |
|
|
|
|
rsp_idx = 1; |
|
|
|
|
rsp_idx = HTTP_RESPONSE_KEYS; |
|
|
|
|
} else { |
|
|
|
|
req.host = gpr_strdup(strstr(iss, "https://") == iss ? iss + 8 : iss); |
|
|
|
|
path_prefix = strchr(req.host, '/'); |
|
|
|
@ -751,7 +758,7 @@ static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx, |
|
|
|
|
GRPC_OPENID_CONFIG_URL_SUFFIX); |
|
|
|
|
} |
|
|
|
|
http_cb = grpc_closure_create(on_openid_config_retrieved, ctx); |
|
|
|
|
rsp_idx = 0; |
|
|
|
|
rsp_idx = HTTP_RESPONSE_OPENID; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
grpc_httpcli_get( |
|
|
|
|