diff options
Diffstat (limited to 'src/reclaim/plugin_rest_openid_connect.c')
-rw-r--r-- | src/reclaim/plugin_rest_openid_connect.c | 55 |
1 files changed, 51 insertions, 4 deletions
diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index 03e037261..a16e6592c 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c | |||
@@ -120,6 +120,16 @@ | |||
120 | #define OIDC_NONCE_KEY "nonce" | 120 | #define OIDC_NONCE_KEY "nonce" |
121 | 121 | ||
122 | /** | 122 | /** |
123 | * OIDC PKCE code challenge | ||
124 | */ | ||
125 | #define OIDC_CODE_CHALLENGE_KEY "code_challenge" | ||
126 | |||
127 | /** | ||
128 | * OIDC PKCE code verifier | ||
129 | */ | ||
130 | #define OIDC_CODE_VERIFIER_KEY "code_verifier" | ||
131 | |||
132 | /** | ||
123 | * OIDC cookie expiration (in seconds) | 133 | * OIDC cookie expiration (in seconds) |
124 | */ | 134 | */ |
125 | #define OIDC_COOKIE_EXPIRATION 3 | 135 | #define OIDC_COOKIE_EXPIRATION 3 |
@@ -296,6 +306,16 @@ struct OIDC_Variables | |||
296 | int user_cancelled; | 306 | int user_cancelled; |
297 | 307 | ||
298 | /** | 308 | /** |
309 | * The PKCE code_challenge | ||
310 | */ | ||
311 | char *code_challenge; | ||
312 | |||
313 | /** | ||
314 | * The PKCE code_verifier | ||
315 | */ | ||
316 | char *code_verifier; | ||
317 | |||
318 | /** | ||
299 | * The response JSON | 319 | * The response JSON |
300 | */ | 320 | */ |
301 | json_t *response; | 321 | json_t *response; |
@@ -812,7 +832,7 @@ login_redirect (void *cls) | |||
812 | &login_base_url)) | 832 | &login_base_url)) |
813 | { | 833 | { |
814 | GNUNET_asprintf (&new_redirect, | 834 | GNUNET_asprintf (&new_redirect, |
815 | "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s", | 835 | "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s", |
816 | login_base_url, | 836 | login_base_url, |
817 | OIDC_RESPONSE_TYPE_KEY, | 837 | OIDC_RESPONSE_TYPE_KEY, |
818 | handle->oidc->response_type, | 838 | handle->oidc->response_type, |
@@ -824,6 +844,8 @@ login_redirect (void *cls) | |||
824 | handle->oidc->scope, | 844 | handle->oidc->scope, |
825 | OIDC_STATE_KEY, | 845 | OIDC_STATE_KEY, |
826 | (NULL != handle->oidc->state) ? handle->oidc->state : "", | 846 | (NULL != handle->oidc->state) ? handle->oidc->state : "", |
847 | OIDC_CODE_CHALLENGE_KEY, | ||
848 | (NULL != handle->oidc->code_challenge) ? handle->oidc->code_challenge : "", | ||
827 | OIDC_NONCE_KEY, | 849 | OIDC_NONCE_KEY, |
828 | (NULL != handle->oidc->nonce) ? handle->oidc->nonce : ""); | 850 | (NULL != handle->oidc->nonce) ? handle->oidc->nonce : ""); |
829 | resp = GNUNET_REST_create_response (""); | 851 | resp = GNUNET_REST_create_response (""); |
@@ -885,7 +907,8 @@ oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) | |||
885 | code_string = OIDC_build_authz_code (&handle->priv_key, | 907 | code_string = OIDC_build_authz_code (&handle->priv_key, |
886 | &handle->ticket, | 908 | &handle->ticket, |
887 | handle->attr_list, | 909 | handle->attr_list, |
888 | handle->oidc->nonce); | 910 | handle->oidc->nonce, |
911 | handle->oidc->code_challenge); | ||
889 | if ((NULL != handle->redirect_prefix) && (NULL != handle->redirect_suffix) && | 912 | if ((NULL != handle->redirect_prefix) && (NULL != handle->redirect_suffix) && |
890 | (NULL != handle->tld)) | 913 | (NULL != handle->tld)) |
891 | { | 914 | { |
@@ -1382,6 +1405,17 @@ authorize_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
1382 | return; | 1405 | return; |
1383 | } | 1406 | } |
1384 | 1407 | ||
1408 | // REQUIRED value: code_challenge | ||
1409 | handle->oidc->code_challenge = get_url_parameter_copy (handle, OIDC_CODE_CHALLENGE_KEY); | ||
1410 | if (NULL == handle->oidc->code_challenge) | ||
1411 | { | ||
1412 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); | ||
1413 | handle->edesc = GNUNET_strdup ("missing parameter code_challenge"); | ||
1414 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | ||
1415 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1416 | return; | ||
1417 | } | ||
1418 | |||
1385 | if (GNUNET_OK != | 1419 | if (GNUNET_OK != |
1386 | GNUNET_CRYPTO_ecdsa_public_key_from_string (handle->oidc->client_id, | 1420 | GNUNET_CRYPTO_ecdsa_public_key_from_string (handle->oidc->client_id, |
1387 | strlen ( | 1421 | strlen ( |
@@ -1666,7 +1700,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
1666 | char *access_token; | 1700 | char *access_token; |
1667 | char *jwt_secret; | 1701 | char *jwt_secret; |
1668 | char *nonce; | 1702 | char *nonce; |
1669 | 1703 | char *code_verifier; | |
1670 | /* | 1704 | /* |
1671 | * Check Authorization | 1705 | * Check Authorization |
1672 | */ | 1706 | */ |
@@ -1728,8 +1762,20 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
1728 | return; | 1762 | return; |
1729 | } | 1763 | } |
1730 | privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | 1764 | privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); |
1765 | |||
1766 | // REQUIRED code verifier | ||
1767 | code_verifier = get_url_parameter_copy (handle, OIDC_CODE_VERIFIER_KEY); | ||
1768 | if (NULL == code_verifier) | ||
1769 | { | ||
1770 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); | ||
1771 | handle->edesc = GNUNET_strdup ("missing parameter code_verifier"); | ||
1772 | handle->response_code = MHD_HTTP_BAD_REQUEST; | ||
1773 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1774 | return; | ||
1775 | } | ||
1776 | |||
1731 | // decode code | 1777 | // decode code |
1732 | if (GNUNET_OK != OIDC_parse_authz_code (privkey, code, &ticket, &cl, &nonce)) | 1778 | if (GNUNET_OK != OIDC_parse_authz_code (privkey, code, code_verifier, &ticket, &cl, &nonce)) |
1733 | { | 1779 | { |
1734 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); | 1780 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); |
1735 | handle->edesc = GNUNET_strdup ("invalid code"); | 1781 | handle->edesc = GNUNET_strdup ("invalid code"); |
@@ -2003,6 +2049,7 @@ list_ego (void *cls, | |||
2003 | } | 2049 | } |
2004 | GNUNET_assert (NULL != ego); | 2050 | GNUNET_assert (NULL != ego); |
2005 | if (ID_REST_STATE_INIT == handle->state) | 2051 | if (ID_REST_STATE_INIT == handle->state) |
2052 | |||
2006 | { | 2053 | { |
2007 | ego_entry = GNUNET_new (struct EgoEntry); | 2054 | ego_entry = GNUNET_new (struct EgoEntry); |
2008 | GNUNET_IDENTITY_ego_get_public_key (ego, &pk); | 2055 | GNUNET_IDENTITY_ego_get_public_key (ego, &pk); |