diff options
Diffstat (limited to 'src/service/rest/openid_plugin.c')
-rw-r--r-- | src/service/rest/openid_plugin.c | 85 |
1 files changed, 52 insertions, 33 deletions
diff --git a/src/service/rest/openid_plugin.c b/src/service/rest/openid_plugin.c index 61904494b..fc1125690 100644 --- a/src/service/rest/openid_plugin.c +++ b/src/service/rest/openid_plugin.c | |||
@@ -34,12 +34,10 @@ | |||
34 | #include "gnunet_gns_service.h" | 34 | #include "gnunet_gns_service.h" |
35 | #include "gnunet_gnsrecord_lib.h" | 35 | #include "gnunet_gnsrecord_lib.h" |
36 | #include "gnunet_identity_service.h" | 36 | #include "gnunet_identity_service.h" |
37 | #include "gnunet_namestore_service.h" | ||
38 | #include "gnunet_reclaim_lib.h" | 37 | #include "gnunet_reclaim_lib.h" |
39 | #include "gnunet_reclaim_service.h" | 38 | #include "gnunet_reclaim_service.h" |
40 | #include "gnunet_rest_lib.h" | 39 | #include "gnunet_rest_lib.h" |
41 | #include "gnunet_rest_plugin.h" | 40 | #include "gnunet_rest_plugin.h" |
42 | #include "gnunet_signatures.h" | ||
43 | #include "microhttpd.h" | 41 | #include "microhttpd.h" |
44 | #include "oidc_helper.h" | 42 | #include "oidc_helper.h" |
45 | 43 | ||
@@ -242,7 +240,7 @@ | |||
242 | * How long to wait for a consume in userinfo endpoint | 240 | * How long to wait for a consume in userinfo endpoint |
243 | */ | 241 | */ |
244 | #define CONSUME_TIMEOUT GNUNET_TIME_relative_multiply ( \ | 242 | #define CONSUME_TIMEOUT GNUNET_TIME_relative_multiply ( \ |
245 | GNUNET_TIME_UNIT_SECONDS,2) | 243 | GNUNET_TIME_UNIT_SECONDS,2) |
246 | 244 | ||
247 | /** | 245 | /** |
248 | * OIDC ignored parameter array | 246 | * OIDC ignored parameter array |
@@ -1248,7 +1246,7 @@ oidc_cred_collect_finished_cb (void *cls) | |||
1248 | le_m->attribute->name); | 1246 | le_m->attribute->name); |
1249 | handle->idp_op = GNUNET_RECLAIM_ticket_issue (idp, | 1247 | handle->idp_op = GNUNET_RECLAIM_ticket_issue (idp, |
1250 | &handle->priv_key, | 1248 | &handle->priv_key, |
1251 | &handle->oidc->client_pkey, | 1249 | handle->oidc->client_id, |
1252 | merged_list, | 1250 | merged_list, |
1253 | &oidc_ticket_issue_cb, | 1251 | &oidc_ticket_issue_cb, |
1254 | handle); | 1252 | handle); |
@@ -2193,6 +2191,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2193 | char *oidc_jwk_path = NULL; | 2191 | char *oidc_jwk_path = NULL; |
2194 | char *oidc_directory = NULL; | 2192 | char *oidc_directory = NULL; |
2195 | char *tmp_at = NULL; | 2193 | char *tmp_at = NULL; |
2194 | char *received_cid = NULL; | ||
2196 | 2195 | ||
2197 | /* | 2196 | /* |
2198 | * Check Authorization | 2197 | * Check Authorization |
@@ -2204,6 +2203,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2204 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 2203 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
2205 | return; | 2204 | return; |
2206 | } | 2205 | } |
2206 | received_cid = get_url_parameter_copy (handle, OIDC_CLIENT_ID_KEY); | ||
2207 | 2207 | ||
2208 | /* | 2208 | /* |
2209 | * Check parameter | 2209 | * Check parameter |
@@ -2265,12 +2265,16 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2265 | } | 2265 | } |
2266 | 2266 | ||
2267 | // decode code | 2267 | // decode code |
2268 | if (GNUNET_OK != OIDC_parse_authz_code (&cid, code, code_verifier, &ticket, | 2268 | char *emsg = NULL; |
2269 | if (GNUNET_OK != OIDC_parse_authz_code (received_cid, &cid, code, | ||
2270 | code_verifier, | ||
2271 | &ticket, | ||
2269 | &cl, &pl, &nonce, | 2272 | &cl, &pl, &nonce, |
2270 | OIDC_VERIFICATION_DEFAULT)) | 2273 | OIDC_VERIFICATION_DEFAULT, |
2274 | &emsg)) | ||
2271 | { | 2275 | { |
2272 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); | 2276 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); |
2273 | handle->edesc = GNUNET_strdup ("invalid code"); | 2277 | handle->edesc = emsg; |
2274 | handle->response_code = MHD_HTTP_BAD_REQUEST; | 2278 | handle->response_code = MHD_HTTP_BAD_REQUEST; |
2275 | GNUNET_free (code); | 2279 | GNUNET_free (code); |
2276 | if (NULL != code_verifier) | 2280 | if (NULL != code_verifier) |
@@ -2311,6 +2315,9 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2311 | jwa = JWT_ALG_VALUE_RSA; | 2315 | jwa = JWT_ALG_VALUE_RSA; |
2312 | } | 2316 | } |
2313 | 2317 | ||
2318 | struct GNUNET_CRYPTO_PublicKey issuer; | ||
2319 | GNUNET_GNS_parse_ztld (ticket.gns_name, &issuer); | ||
2320 | |||
2314 | if (! strcmp (jwa, JWT_ALG_VALUE_RSA)) | 2321 | if (! strcmp (jwa, JWT_ALG_VALUE_RSA)) |
2315 | { | 2322 | { |
2316 | // Replace for now | 2323 | // Replace for now |
@@ -2338,8 +2345,8 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2338 | } | 2345 | } |
2339 | 2346 | ||
2340 | // Generate oidc token | 2347 | // Generate oidc token |
2341 | id_token = OIDC_generate_id_token_rsa (&ticket.audience, | 2348 | id_token = OIDC_generate_id_token_rsa (received_cid, |
2342 | &ticket.identity, | 2349 | &issuer, |
2343 | cl, | 2350 | cl, |
2344 | pl, | 2351 | pl, |
2345 | &expiration_time, | 2352 | &expiration_time, |
@@ -2366,8 +2373,8 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2366 | return; | 2373 | return; |
2367 | } | 2374 | } |
2368 | 2375 | ||
2369 | id_token = OIDC_generate_id_token_hmac (&ticket.audience, | 2376 | id_token = OIDC_generate_id_token_hmac (received_cid, |
2370 | &ticket.identity, | 2377 | &issuer, |
2371 | cl, | 2378 | cl, |
2372 | pl, | 2379 | pl, |
2373 | &expiration_time, | 2380 | &expiration_time, |
@@ -2383,7 +2390,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2383 | 2390 | ||
2384 | if (NULL != nonce) | 2391 | if (NULL != nonce) |
2385 | GNUNET_free (nonce); | 2392 | GNUNET_free (nonce); |
2386 | access_token = OIDC_access_token_new (&ticket); | 2393 | access_token = OIDC_access_token_new (&ticket, handle->oidc->redirect_uri); |
2387 | /** | 2394 | /** |
2388 | * Store mapping from access token to code so we can later | 2395 | * Store mapping from access token to code so we can later |
2389 | * fall back on the provided attributes in userinfo one time. | 2396 | * fall back on the provided attributes in userinfo one time. |
@@ -2481,7 +2488,15 @@ consume_ticket (void *cls, | |||
2481 | 2488 | ||
2482 | if (NULL == identity) | 2489 | if (NULL == identity) |
2483 | { | 2490 | { |
2484 | result_str = OIDC_generate_userinfo (&handle->ticket.identity, | 2491 | char *tmp = GNUNET_strdup (handle->ticket.gns_name); |
2492 | GNUNET_assert (NULL != strtok (tmp, ".")); | ||
2493 | char *key = strtok (NULL, "."); | ||
2494 | struct GNUNET_CRYPTO_PublicKey issuer; | ||
2495 | GNUNET_assert (NULL != key); | ||
2496 | GNUNET_assert (GNUNET_OK == | ||
2497 | GNUNET_CRYPTO_public_key_from_string (key, &issuer)); | ||
2498 | GNUNET_free (tmp); | ||
2499 | result_str = OIDC_generate_userinfo (&issuer, | ||
2485 | handle->attr_userinfo_list, | 2500 | handle->attr_userinfo_list, |
2486 | handle->presentations); | 2501 | handle->presentations); |
2487 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Userinfo: %s\n", result_str); | 2502 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Userinfo: %s\n", result_str); |
@@ -2538,11 +2553,12 @@ consume_fail (void *cls) | |||
2538 | struct GNUNET_RECLAIM_AttributeList *cl = NULL; | 2553 | struct GNUNET_RECLAIM_AttributeList *cl = NULL; |
2539 | struct GNUNET_RECLAIM_PresentationList *pl = NULL; | 2554 | struct GNUNET_RECLAIM_PresentationList *pl = NULL; |
2540 | struct GNUNET_RECLAIM_Ticket ticket; | 2555 | struct GNUNET_RECLAIM_Ticket ticket; |
2556 | struct GNUNET_CRYPTO_PublicKey cid; | ||
2541 | struct MHD_Response *resp; | 2557 | struct MHD_Response *resp; |
2542 | char *nonce; | 2558 | char *nonce; |
2543 | char *cached_code; | 2559 | char *cached_code; |
2544 | char *result_str; | 2560 | char *result_str; |
2545 | 2561 | char *received_cid; | |
2546 | 2562 | ||
2547 | handle->consume_timeout_op = NULL; | 2563 | handle->consume_timeout_op = NULL; |
2548 | if (NULL != handle->idp_op) | 2564 | if (NULL != handle->idp_op) |
@@ -2571,15 +2587,21 @@ consume_fail (void *cls) | |||
2571 | GNUNET_CONTAINER_multihashmap_remove (oidc_code_cache, | 2587 | GNUNET_CONTAINER_multihashmap_remove (oidc_code_cache, |
2572 | &cache_key, | 2588 | &cache_key, |
2573 | cached_code)); | 2589 | cached_code)); |
2590 | received_cid = get_url_parameter_copy (handle, OIDC_CLIENT_ID_KEY); | ||
2591 | GNUNET_STRINGS_string_to_data (received_cid, | ||
2592 | strlen (received_cid), | ||
2593 | &cid, | ||
2594 | sizeof(struct GNUNET_CRYPTO_PublicKey)); | ||
2574 | 2595 | ||
2575 | // decode code | 2596 | // decode code |
2576 | if (GNUNET_OK != OIDC_parse_authz_code (&handle->ticket.audience, | 2597 | char *emsg; |
2598 | if (GNUNET_OK != OIDC_parse_authz_code (received_cid, &cid, | ||
2577 | cached_code, NULL, &ticket, | 2599 | cached_code, NULL, &ticket, |
2578 | &cl, &pl, &nonce, | 2600 | &cl, &pl, &nonce, |
2579 | OIDC_VERIFICATION_NO_CODE_VERIFIER)) | 2601 | OIDC_VERIFICATION_NO_CODE_VERIFIER, &emsg)) |
2580 | { | 2602 | { |
2581 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); | 2603 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); |
2582 | handle->edesc = GNUNET_strdup ("invalid code"); | 2604 | handle->edesc = emsg; |
2583 | handle->response_code = MHD_HTTP_BAD_REQUEST; | 2605 | handle->response_code = MHD_HTTP_BAD_REQUEST; |
2584 | GNUNET_free (cached_code); | 2606 | GNUNET_free (cached_code); |
2585 | if (NULL != nonce) | 2607 | if (NULL != nonce) |
@@ -2590,7 +2612,15 @@ consume_fail (void *cls) | |||
2590 | 2612 | ||
2591 | GNUNET_free (cached_code); | 2613 | GNUNET_free (cached_code); |
2592 | 2614 | ||
2593 | result_str = OIDC_generate_userinfo (&handle->ticket.identity, | 2615 | char *tmp = GNUNET_strdup (handle->ticket.gns_name); |
2616 | GNUNET_assert (NULL != strtok (tmp, ".")); | ||
2617 | char *key = strtok (NULL, "."); | ||
2618 | struct GNUNET_CRYPTO_PublicKey issuer; | ||
2619 | GNUNET_assert (NULL != key); | ||
2620 | GNUNET_assert (GNUNET_OK == | ||
2621 | GNUNET_CRYPTO_public_key_from_string (key, &issuer)); | ||
2622 | GNUNET_free (tmp); | ||
2623 | result_str = OIDC_generate_userinfo (&issuer, | ||
2594 | cl, | 2624 | cl, |
2595 | pl); | 2625 | pl); |
2596 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Userinfo: %s\n", result_str); | 2626 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Userinfo: %s\n", result_str); |
@@ -2624,8 +2654,6 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2624 | char *authorization; | 2654 | char *authorization; |
2625 | char *authorization_type; | 2655 | char *authorization_type; |
2626 | char *authorization_access_token; | 2656 | char *authorization_access_token; |
2627 | const struct EgoEntry *aud_ego; | ||
2628 | const struct GNUNET_CRYPTO_PrivateKey *privkey; | ||
2629 | 2657 | ||
2630 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting userinfo\n"); | 2658 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting userinfo\n"); |
2631 | GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, | 2659 | GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, |
@@ -2669,8 +2697,9 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2669 | return; | 2697 | return; |
2670 | } | 2698 | } |
2671 | 2699 | ||
2700 | char *rp_uri; | ||
2672 | if (GNUNET_OK != OIDC_access_token_parse (authorization_access_token, | 2701 | if (GNUNET_OK != OIDC_access_token_parse (authorization_access_token, |
2673 | &ticket)) | 2702 | &ticket, &rp_uri)) |
2674 | { | 2703 | { |
2675 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); | 2704 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); |
2676 | handle->edesc = GNUNET_strdup ("The access token is invalid"); | 2705 | handle->edesc = GNUNET_strdup ("The access token is invalid"); |
@@ -2683,18 +2712,7 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2683 | GNUNET_assert (NULL != ticket); | 2712 | GNUNET_assert (NULL != ticket); |
2684 | handle->ticket = *ticket; | 2713 | handle->ticket = *ticket; |
2685 | GNUNET_free (ticket); | 2714 | GNUNET_free (ticket); |
2686 | aud_ego = find_ego (handle, &handle->ticket.audience); | ||
2687 | if (NULL == aud_ego) | ||
2688 | { | ||
2689 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); | ||
2690 | handle->edesc = GNUNET_strdup ("The access token expired"); | ||
2691 | handle->response_code = MHD_HTTP_UNAUTHORIZED; | ||
2692 | GNUNET_SCHEDULER_add_now (&do_userinfo_error, handle); | ||
2693 | GNUNET_free (authorization); | ||
2694 | return; | ||
2695 | } | ||
2696 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Consuming ticket\n"); | 2715 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Consuming ticket\n"); |
2697 | privkey = GNUNET_IDENTITY_ego_get_private_key (aud_ego->ego); | ||
2698 | handle->attr_userinfo_list = | 2716 | handle->attr_userinfo_list = |
2699 | GNUNET_new (struct GNUNET_RECLAIM_AttributeList); | 2717 | GNUNET_new (struct GNUNET_RECLAIM_AttributeList); |
2700 | handle->presentations = | 2718 | handle->presentations = |
@@ -2706,11 +2724,12 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
2706 | &consume_fail, | 2724 | &consume_fail, |
2707 | handle); | 2725 | handle); |
2708 | handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp, | 2726 | handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp, |
2709 | privkey, | ||
2710 | &handle->ticket, | 2727 | &handle->ticket, |
2728 | rp_uri, | ||
2711 | &consume_ticket, | 2729 | &consume_ticket, |
2712 | handle); | 2730 | handle); |
2713 | GNUNET_free (authorization); | 2731 | GNUNET_free (authorization); |
2732 | GNUNET_free (rp_uri); | ||
2714 | } | 2733 | } |
2715 | 2734 | ||
2716 | 2735 | ||