aboutsummaryrefslogtreecommitdiff
path: root/src/service/rest/openid_plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/service/rest/openid_plugin.c')
-rw-r--r--src/service/rest/openid_plugin.c85
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