diff options
Diffstat (limited to 'src/reclaim/oidc_helper.c')
-rw-r--r-- | src/reclaim/oidc_helper.c | 78 |
1 files changed, 48 insertions, 30 deletions
diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c index c6d56e02d..1dde7b673 100644 --- a/src/reclaim/oidc_helper.c +++ b/src/reclaim/oidc_helper.c | |||
@@ -567,6 +567,48 @@ OIDC_build_authz_code (const struct GNUNET_IDENTITY_PrivateKey *issuer, | |||
567 | } | 567 | } |
568 | 568 | ||
569 | 569 | ||
570 | enum GNUNET_GenericReturnValue | ||
571 | check_code_challenge (const char *code_challenge, | ||
572 | uint32_t code_challenge_len, | ||
573 | const char *code_verifier) | ||
574 | { | ||
575 | char *code_verifier_hash; | ||
576 | char *expected_code_challenge; | ||
577 | |||
578 | if (0 == code_challenge_len) /* Only check if this code requires a CV */ | ||
579 | return GNUNET_OK; | ||
580 | if (NULL == code_verifier) | ||
581 | { | ||
582 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
583 | "Expected code verifier!\n"); | ||
584 | return GNUNET_SYSERR; | ||
585 | } | ||
586 | code_verifier_hash = GNUNET_malloc (256 / 8); | ||
587 | // hash code verifier | ||
588 | gcry_md_hash_buffer (GCRY_MD_SHA256, | ||
589 | code_verifier_hash, | ||
590 | code_verifier, | ||
591 | strlen (code_verifier)); | ||
592 | // encode code verifier | ||
593 | GNUNET_STRINGS_base64url_encode (code_verifier_hash, 256 / 8, | ||
594 | &expected_code_challenge); | ||
595 | GNUNET_free (code_verifier_hash); | ||
596 | if (0 != | ||
597 | strncmp (expected_code_challenge, code_challenge, code_challenge_len)) | ||
598 | { | ||
599 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
600 | "Invalid code verifier! Expected: %s, Got: %.*s\n", | ||
601 | expected_code_challenge, | ||
602 | code_challenge_len, | ||
603 | code_challenge); | ||
604 | GNUNET_free (expected_code_challenge); | ||
605 | return GNUNET_SYSERR; | ||
606 | } | ||
607 | GNUNET_free (expected_code_challenge); | ||
608 | return GNUNET_OK; | ||
609 | } | ||
610 | |||
611 | |||
570 | /** | 612 | /** |
571 | * Parse reclaim ticket and nonce from | 613 | * Parse reclaim ticket and nonce from |
572 | * authorization code. | 614 | * authorization code. |
@@ -589,16 +631,15 @@ OIDC_parse_authz_code (const struct GNUNET_IDENTITY_PublicKey *audience, | |||
589 | struct GNUNET_RECLAIM_Ticket *ticket, | 631 | struct GNUNET_RECLAIM_Ticket *ticket, |
590 | struct GNUNET_RECLAIM_AttributeList **attrs, | 632 | struct GNUNET_RECLAIM_AttributeList **attrs, |
591 | struct GNUNET_RECLAIM_PresentationList **presentations, | 633 | struct GNUNET_RECLAIM_PresentationList **presentations, |
592 | char **nonce_str) | 634 | char **nonce_str, |
635 | enum OIDC_VerificationOptions opts) | ||
593 | { | 636 | { |
594 | char *code_payload; | 637 | char *code_payload; |
595 | char *ptr; | 638 | char *ptr; |
596 | char *plaintext; | 639 | char *plaintext; |
597 | char *attrs_ser; | 640 | char *attrs_ser; |
598 | char *presentations_ser; | 641 | char *presentations_ser; |
599 | char *expected_code_challenge; | ||
600 | char *code_challenge; | 642 | char *code_challenge; |
601 | char *code_verifier_hash; | ||
602 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; | 643 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; |
603 | struct GNUNET_IDENTITY_Signature *signature; | 644 | struct GNUNET_IDENTITY_Signature *signature; |
604 | uint32_t code_challenge_len; | 645 | uint32_t code_challenge_len; |
@@ -636,38 +677,15 @@ OIDC_parse_authz_code (const struct GNUNET_IDENTITY_PublicKey *audience, | |||
636 | // cmp code_challenge code_verifier | 677 | // cmp code_challenge code_verifier |
637 | code_challenge_len = ntohl (params->code_challenge_len); | 678 | code_challenge_len = ntohl (params->code_challenge_len); |
638 | code_challenge = ((char *) ¶ms[1]); | 679 | code_challenge = ((char *) ¶ms[1]); |
639 | if (0 != code_challenge_len) /* Only check if this code requires a CV */ | 680 | if (!(opts & OIDC_VERIFICATION_NO_CODE_VERIFIER)) |
640 | { | 681 | { |
641 | if (NULL == code_verifier) | 682 | if (GNUNET_OK != check_code_challenge (code_challenge, |
642 | { | 683 | code_challenge_len, |
643 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 684 | code_verifier)) |
644 | "Expected code verifier!\n"); | ||
645 | GNUNET_free (code_payload); | ||
646 | return GNUNET_SYSERR; | ||
647 | } | ||
648 | code_verifier_hash = GNUNET_malloc (256 / 8); | ||
649 | // hash code verifier | ||
650 | gcry_md_hash_buffer (GCRY_MD_SHA256, | ||
651 | code_verifier_hash, | ||
652 | code_verifier, | ||
653 | strlen (code_verifier)); | ||
654 | // encode code verifier | ||
655 | GNUNET_STRINGS_base64url_encode (code_verifier_hash, 256 / 8, | ||
656 | &expected_code_challenge); | ||
657 | GNUNET_free (code_verifier_hash); | ||
658 | if (0 != | ||
659 | strncmp (expected_code_challenge, code_challenge, code_challenge_len)) | ||
660 | { | 685 | { |
661 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
662 | "Invalid code verifier! Expected: %s, Got: %.*s\n", | ||
663 | expected_code_challenge, | ||
664 | code_challenge_len, | ||
665 | code_challenge); | ||
666 | GNUNET_free (code_payload); | 686 | GNUNET_free (code_payload); |
667 | GNUNET_free (expected_code_challenge); | ||
668 | return GNUNET_SYSERR; | 687 | return GNUNET_SYSERR; |
669 | } | 688 | } |
670 | GNUNET_free (expected_code_challenge); | ||
671 | } | 689 | } |
672 | nonce_len = ntohl (params->nonce_len); | 690 | nonce_len = ntohl (params->nonce_len); |
673 | if (0 != nonce_len) | 691 | if (0 != nonce_len) |