diff options
author | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2019-09-05 08:22:51 +0200 |
---|---|---|
committer | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2019-09-05 08:22:51 +0200 |
commit | 74c328220897196de3d93710e74666230a57cfee (patch) | |
tree | f8b63e77c3f1036a67e8ac5651349a3ab268a231 | |
parent | d9a37dee7a3f425b0846a8dd1b6089dc7f27d723 (diff) | |
download | gnunet-74c328220897196de3d93710e74666230a57cfee.tar.gz gnunet-74c328220897196de3d93710e74666230a57cfee.zip |
attempt to make PKCE optional
-rw-r--r-- | src/reclaim/oidc_helper.c | 67 | ||||
-rw-r--r-- | src/reclaim/plugin_rest_openid_connect.c | 13 |
2 files changed, 40 insertions, 40 deletions
diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c index cbf0d1a1d..4769ed2d1 100644 --- a/src/reclaim/oidc_helper.c +++ b/src/reclaim/oidc_helper.c | |||
@@ -460,6 +460,7 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
460 | size_t payload_len; | 460 | size_t payload_len; |
461 | size_t code_payload_len; | 461 | size_t code_payload_len; |
462 | size_t attr_list_len = 0; | 462 | size_t attr_list_len = 0; |
463 | size_t code_challenge_len = 0; | ||
463 | uint32_t nonce; | 464 | uint32_t nonce; |
464 | uint32_t nonce_tmp; | 465 | uint32_t nonce_tmp; |
465 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; | 466 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; |
@@ -489,14 +490,10 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
489 | nonce_tmp = htonl (nonce); | 490 | nonce_tmp = htonl (nonce); |
490 | params.nonce = nonce_tmp; | 491 | params.nonce = nonce_tmp; |
491 | // Assign code challenge | 492 | // Assign code challenge |
492 | if (NULL == code_challenge || strcmp ("", code_challenge) == 0) | 493 | if (NULL != code_challenge) |
493 | { | 494 | code_challenge_len = strlen (code_challenge); |
494 | GNUNET_break (0); | 495 | payload_len += code_challenge_len; |
495 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "PKCE: Code challenge missing"); | 496 | params.code_challenge_len = htonl (code_challenge_len); |
496 | return NULL; | ||
497 | } | ||
498 | payload_len += strlen (code_challenge); | ||
499 | params.code_challenge_len = htonl (strlen (code_challenge)); | ||
500 | // Assign attributes | 497 | // Assign attributes |
501 | if (NULL != attrs) | 498 | if (NULL != attrs) |
502 | { | 499 | { |
@@ -513,8 +510,11 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | |||
513 | payload = GNUNET_malloc (payload_len); | 510 | payload = GNUNET_malloc (payload_len); |
514 | memcpy (payload, ¶ms, sizeof (params)); | 511 | memcpy (payload, ¶ms, sizeof (params)); |
515 | tmp = payload + sizeof (params); | 512 | tmp = payload + sizeof (params); |
516 | memcpy (tmp, code_challenge, strlen (code_challenge)); | 513 | if (0 < code_challenge_len) |
517 | tmp += strlen (code_challenge); | 514 | { |
515 | memcpy (tmp, code_challenge, code_challenge_len); | ||
516 | tmp += code_challenge_len; | ||
517 | } | ||
518 | if (0 < attr_list_len) | 518 | if (0 < attr_list_len) |
519 | GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, tmp); | 519 | GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, tmp); |
520 | /** END **/ | 520 | /** END **/ |
@@ -633,35 +633,38 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | |||
633 | decrypt_payload (ecdsa_priv, ecdh_pub, ptr, plaintext_len, plaintext); | 633 | decrypt_payload (ecdsa_priv, ecdh_pub, ptr, plaintext_len, plaintext); |
634 | //ptr = plaintext; | 634 | //ptr = plaintext; |
635 | ptr += plaintext_len; | 635 | ptr += plaintext_len; |
636 | signature = (struct GNUNET_CRYPTO_EcdsaSignature*) ptr; | 636 | signature = (struct GNUNET_CRYPTO_EcdsaSignature *) ptr; |
637 | params = (struct OIDC_Parameters *) plaintext; | 637 | params = (struct OIDC_Parameters *) plaintext; |
638 | 638 | ||
639 | // cmp code_challenge code_verifier | 639 | // cmp code_challenge code_verifier |
640 | code_verifier_hash = GNUNET_malloc (256 / 8); | ||
641 | // hash code verifier | ||
642 | gcry_md_hash_buffer (GCRY_MD_SHA256, | ||
643 | code_verifier_hash, | ||
644 | code_verifier, | ||
645 | strlen (code_verifier)); | ||
646 | // encode code verifier | ||
647 | expected_code_challenge = base64url_encode (code_verifier_hash, 256 / 8); | ||
648 | code_challenge = (char *) ¶ms[1]; | ||
649 | code_challenge_len = ntohl (params->code_challenge_len); | 640 | code_challenge_len = ntohl (params->code_challenge_len); |
650 | GNUNET_free (code_verifier_hash); | 641 | if (0 != code_challenge_len) /* Only check if this code requires a CV */ |
651 | if ((strlen (expected_code_challenge) != code_challenge_len) || | ||
652 | (0 != | ||
653 | strncmp (expected_code_challenge, code_challenge, code_challenge_len))) | ||
654 | { | 642 | { |
655 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 643 | code_verifier_hash = GNUNET_malloc (256 / 8); |
656 | "Invalid code verifier! Expected: %s, Got: %.*s\n", | 644 | // hash code verifier |
657 | expected_code_challenge, | 645 | gcry_md_hash_buffer (GCRY_MD_SHA256, |
658 | code_challenge_len, | 646 | code_verifier_hash, |
659 | code_challenge); | 647 | code_verifier, |
660 | GNUNET_free_non_null (code_payload); | 648 | strlen (code_verifier)); |
649 | // encode code verifier | ||
650 | expected_code_challenge = base64url_encode (code_verifier_hash, 256 / 8); | ||
651 | code_challenge = (char *) ¶ms[1]; | ||
652 | GNUNET_free (code_verifier_hash); | ||
653 | if ((strlen (expected_code_challenge) != code_challenge_len) || | ||
654 | (0 != | ||
655 | strncmp (expected_code_challenge, code_challenge, code_challenge_len))) | ||
656 | { | ||
657 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
658 | "Invalid code verifier! Expected: %s, Got: %.*s\n", | ||
659 | expected_code_challenge, | ||
660 | code_challenge_len, | ||
661 | code_challenge); | ||
662 | GNUNET_free_non_null (code_payload); | ||
663 | GNUNET_free (expected_code_challenge); | ||
664 | return GNUNET_SYSERR; | ||
665 | } | ||
661 | GNUNET_free (expected_code_challenge); | 666 | GNUNET_free (expected_code_challenge); |
662 | return GNUNET_SYSERR; | ||
663 | } | 667 | } |
664 | GNUNET_free (expected_code_challenge); | ||
665 | // Ticket | 668 | // Ticket |
666 | memcpy (ticket, ¶ms->ticket, sizeof (params->ticket)); | 669 | memcpy (ticket, ¶ms->ticket, sizeof (params->ticket)); |
667 | // Nonce | 670 | // Nonce |
diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index a16e6592c..bf1e950da 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c | |||
@@ -1405,15 +1405,12 @@ authorize_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
1405 | return; | 1405 | return; |
1406 | } | 1406 | } |
1407 | 1407 | ||
1408 | // REQUIRED value: code_challenge | 1408 | // OPTIONAL value: code_challenge |
1409 | handle->oidc->code_challenge = get_url_parameter_copy (handle, OIDC_CODE_CHALLENGE_KEY); | 1409 | handle->oidc->code_challenge = get_url_parameter_copy (handle, OIDC_CODE_CHALLENGE_KEY); |
1410 | if (NULL == handle->oidc->code_challenge) | 1410 | if (NULL == handle->oidc->code_challenge) |
1411 | { | 1411 | { |
1412 | handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); | 1412 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1413 | handle->edesc = GNUNET_strdup ("missing parameter code_challenge"); | 1413 | "OAuth authorization request does not contain PKCE parameters!\n"); |
1414 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | ||
1415 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1416 | return; | ||
1417 | } | 1414 | } |
1418 | 1415 | ||
1419 | if (GNUNET_OK != | 1416 | if (GNUNET_OK != |
@@ -1762,7 +1759,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, | |||
1762 | return; | 1759 | return; |
1763 | } | 1760 | } |
1764 | privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | 1761 | privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); |
1765 | 1762 | ||
1766 | // REQUIRED code verifier | 1763 | // REQUIRED code verifier |
1767 | code_verifier = get_url_parameter_copy (handle, OIDC_CODE_VERIFIER_KEY); | 1764 | code_verifier = get_url_parameter_copy (handle, OIDC_CODE_VERIFIER_KEY); |
1768 | if (NULL == code_verifier) | 1765 | if (NULL == code_verifier) |
@@ -2049,7 +2046,7 @@ list_ego (void *cls, | |||
2049 | } | 2046 | } |
2050 | GNUNET_assert (NULL != ego); | 2047 | GNUNET_assert (NULL != ego); |
2051 | if (ID_REST_STATE_INIT == handle->state) | 2048 | if (ID_REST_STATE_INIT == handle->state) |
2052 | 2049 | ||
2053 | { | 2050 | { |
2054 | ego_entry = GNUNET_new (struct EgoEntry); | 2051 | ego_entry = GNUNET_new (struct EgoEntry); |
2055 | GNUNET_IDENTITY_ego_get_public_key (ego, &pk); | 2052 | GNUNET_IDENTITY_ego_get_public_key (ego, &pk); |