aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexia Pagkopoulou <a.pagkopoulou@tum.de>2019-09-04 15:27:54 +0200
committerAlexia Pagkopoulou <a.pagkopoulou@tum.de>2019-09-04 15:27:54 +0200
commitde8c2a206a6e1fe92cf01be548b6069e7e78e679 (patch)
tree442fe3732d8ca787d63c431a43861300f95f0400 /src
parent86d9a1259ace3d5c6cf646a6d61f7f424b50a112 (diff)
downloadgnunet-de8c2a206a6e1fe92cf01be548b6069e7e78e679.tar.gz
gnunet-de8c2a206a6e1fe92cf01be548b6069e7e78e679.zip
support for PKCE extension
Diffstat (limited to 'src')
-rw-r--r--src/reclaim/Makefile.am3
-rw-r--r--src/reclaim/oidc_helper.c179
-rw-r--r--src/reclaim/oidc_helper.h8
-rw-r--r--src/reclaim/plugin_rest_openid_connect.c55
4 files changed, 183 insertions, 62 deletions
diff --git a/src/reclaim/Makefile.am b/src/reclaim/Makefile.am
index 6937b1af6..69dcc605e 100644
--- a/src/reclaim/Makefile.am
+++ b/src/reclaim/Makefile.am
@@ -77,7 +77,8 @@ libgnunet_plugin_rest_openid_connect_la_LIBADD = \
77 $(top_builddir)/src/gns/libgnunetgns.la \ 77 $(top_builddir)/src/gns/libgnunetgns.la \
78 $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ 78 $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
79 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ 79 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
80 $(LTLIBINTL) -ljansson $(MHD_LIBS) 80 $(LTLIBINTL) -ljansson $(MHD_LIBS) \
81 $(LIBGCRYPT_LIBS)
81libgnunet_plugin_rest_openid_connect_la_LDFLAGS = \ 82libgnunet_plugin_rest_openid_connect_la_LDFLAGS = \
82 $(GN_PLUGIN_LDFLAGS) 83 $(GN_PLUGIN_LDFLAGS)
83libgnunet_plugin_rest_openid_connect_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS) 84libgnunet_plugin_rest_openid_connect_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS)
diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c
index d2789f978..01a3d0179 100644
--- a/src/reclaim/oidc_helper.c
+++ b/src/reclaim/oidc_helper.c
@@ -31,7 +31,48 @@
31#include "gnunet_reclaim_service.h" 31#include "gnunet_reclaim_service.h"
32#include "gnunet_signatures.h" 32#include "gnunet_signatures.h"
33#include "oidc_helper.h" 33#include "oidc_helper.h"
34//#include "benchmark.h"
35#include <gcrypt.h>
34 36
37GNUNET_NETWORK_STRUCT_BEGIN
38
39/**
40 * The signature used to generate the authorization code
41 */
42struct OIDC_Parameters
43{
44 /**
45 * The reclaim ticket
46 */
47 const struct GNUNET_RECLAIM_Ticket *ticket;
48
49 /**
50 * The nonce
51 */
52 uint32_t nonce GNUNET_PACKED;
53
54 /**
55 * The length of the PKCE code_challenge
56 */
57 uint16_t code_challenge_len GNUNET_PACKED;
58
59 /**
60 * The length of the attributes list
61 */
62 uint16_t attr_list_len GNUNET_PACKED;
63
64 /**
65 * The PKCE code_challenge
66 */
67 const char *code_challenge;
68
69 /**
70 * The (serialized) attributes
71 */
72 char *attrs_ser;
73};
74
75GNUNET_NETWORK_STRUCT_END
35 76
36static char * 77static char *
37create_jwt_header (void) 78create_jwt_header (void)
@@ -371,30 +412,30 @@ encrypt_payload (const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub,
371 GNUNET_CRYPTO_symmetric_encrypt (payload, payload_len, &key, &iv, buf)); 412 GNUNET_CRYPTO_symmetric_encrypt (payload, payload_len, &key, &iv, buf));
372} 413}
373 414
374
375/** 415/**
376 * Builds an OIDC authorization code including 416 * Builds an OIDC authorization code including
377 * a reclaim ticket and nonce 417 * a reclaim ticket and nonce
378 * 418 *
379 * @param issuer the issuer of the ticket, used to sign the ticket and nonce 419 * @param issuer the issuer of the ticket, used to sign the ticket and nonce
380 * @param ticket the ticket to include in the code 420 * @param ticket the ticket to include in the code
381 * @param attrs list of attributes whicha re shared 421 * @param attrs list of attributes which are shared
382 * @param nonce the nonce to include in the code 422 * @param nonce the nonce to include in the code
423 * @param code_challenge PKCE code challenge
383 * @return a new authorization code (caller must free) 424 * @return a new authorization code (caller must free)
384 */ 425 */
385char * 426char *
386OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, 427OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
387 const struct GNUNET_RECLAIM_Ticket *ticket, 428 const struct GNUNET_RECLAIM_Ticket *ticket,
388 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, 429 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
389 const char *nonce_str) 430 const char *nonce_str,
431 const char *code_challenge)
390{ 432{
433 struct OIDC_Parameters *params = GNUNET_new (struct OIDC_Parameters);
391 char *code_payload; 434 char *code_payload;
392 char *plaintext; 435 char *plaintext;
393 char *attrs_ser;
394 char *code_str; 436 char *code_str;
395 char *buf_ptr; 437 char *buf_ptr = NULL;
396 size_t signature_payload_len; 438 size_t signature_payload_len;
397 size_t attr_list_len;
398 size_t code_payload_len; 439 size_t code_payload_len;
399 uint32_t nonce; 440 uint32_t nonce;
400 uint32_t nonce_tmp; 441 uint32_t nonce_tmp;
@@ -402,61 +443,67 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
402 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv; 443 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv;
403 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pub; 444 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pub;
404 445
405 attrs_ser = NULL; 446 /** PLAINTEXT **/
406 signature_payload_len = 447 // Assign ticket
407 sizeof (struct GNUNET_RECLAIM_Ticket) + sizeof (uint32_t); 448 params->ticket = ticket;
408 449 // Assign nonce
409 if (NULL != attrs)
410 {
411 attr_list_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (attrs);
412 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
413 "Length of serialized attributes: %lu\n",
414 attr_list_len);
415 signature_payload_len += attr_list_len;
416 attrs_ser = GNUNET_malloc (attr_list_len);
417 GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, attrs_ser);
418 }
419
420 code_payload_len = sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
421 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
422 signature_payload_len +
423 sizeof (struct GNUNET_CRYPTO_EcdsaSignature);
424 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
425 "Length of data to encode: %lu\n",
426 code_payload_len);
427 plaintext = GNUNET_malloc (signature_payload_len);
428 // First, copy ticket
429 buf_ptr = plaintext;
430 memcpy (buf_ptr, ticket, sizeof (struct GNUNET_RECLAIM_Ticket));
431 buf_ptr += sizeof (struct GNUNET_RECLAIM_Ticket);
432
433 // Then copy nonce
434 nonce = 0; 450 nonce = 0;
435 if (NULL != nonce_str && strcmp("", nonce_str) != 0) 451 if (NULL != nonce_str && strcmp("", nonce_str) != 0)
436 { 452 {
437 if ((1 != SSCANF (nonce_str, "%u", &nonce)) || (nonce > UINT32_MAX)) 453 if ((1 != SSCANF (nonce_str, "%u", &nonce)) || (nonce > UINT32_MAX))
438 { 454 {
439 GNUNET_break (0); 455 GNUNET_break (0);
440 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid nonce %s\n", nonce_str); 456 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid nonce %s\n", nonce_str);
441 GNUNET_free (plaintext); 457 GNUNET_free (params);
442 GNUNET_free_non_null (attrs_ser);
443 return NULL; 458 return NULL;
444 } 459 }
445 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 460 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
446 "Got nonce: %u from %s\n", 461 "Got nonce: %u from %s\n",
447 nonce, 462 nonce,
448 nonce_str); 463 nonce_str);
449 } 464 }
450 nonce_tmp = htonl (nonce); 465 nonce_tmp = htonl (nonce);
451 memcpy (buf_ptr, &nonce_tmp, sizeof (uint32_t)); 466 params->nonce = nonce_tmp;
452 buf_ptr += sizeof (uint32_t); 467 // Assign code challenge
453 468 if (NULL == code_challenge || strcmp("", code_challenge) == 0)
454 // Finally, attributes 469 {
455 if (NULL != attrs_ser) 470 GNUNET_break (0);
471 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "PKCE: Code challenge missing");
472 GNUNET_free (params);
473 return NULL;
474 }
475 params->code_challenge_len = strlen (code_challenge);
476 params->code_challenge = code_challenge;
477 // Assign attributes
478 params->attrs_ser = NULL;
479 if (NULL != attrs)
456 { 480 {
457 memcpy (buf_ptr, attrs_ser, attr_list_len); 481 // Get length
458 GNUNET_free (attrs_ser); 482 params->attr_list_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (attrs);
483 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
484 "Length of serialized attributes: %lu\n",
485 params->attr_list_len);
486 // Get serialized attributes
487 params->attrs_ser = GNUNET_malloc (params->attr_list_len);
488 GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, params->attrs_ser);
459 } 489 }
490
491 // Get plaintext length
492 signature_payload_len = sizeof (struct OIDC_Parameters);
493 plaintext = GNUNET_malloc (signature_payload_len);
494 memcpy (plaintext, params, signature_payload_len);
495 /** END **/
496
497 /** ENCRYPT **/
498 // Get length
499 code_payload_len = sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
500 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
501 signature_payload_len +
502 sizeof (struct GNUNET_CRYPTO_EcdsaSignature);
503 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
504 "Length of data to encode: %lu\n",
505 code_payload_len);
506
460 // Generate ECDH key 507 // Generate ECDH key
461 ecdh_priv = GNUNET_CRYPTO_ecdhe_key_create (); 508 ecdh_priv = GNUNET_CRYPTO_ecdhe_key_create ();
462 GNUNET_CRYPTO_ecdhe_key_get_public (ecdh_priv, &ecdh_pub); 509 GNUNET_CRYPTO_ecdhe_key_get_public (ecdh_priv, &ecdh_pub);
@@ -479,6 +526,7 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
479 buf_ptr); 526 buf_ptr);
480 GNUNET_free (ecdh_priv); 527 GNUNET_free (ecdh_priv);
481 GNUNET_free (plaintext); 528 GNUNET_free (plaintext);
529 GNUNET_free (params);
482 buf_ptr += signature_payload_len; 530 buf_ptr += signature_payload_len;
483 // Sign and store signature 531 // Sign and store signature
484 if (GNUNET_SYSERR == 532 if (GNUNET_SYSERR ==
@@ -505,6 +553,7 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
505 * 553 *
506 * @param audience the expected audience of the code 554 * @param audience the expected audience of the code
507 * @param code the string representation of the code 555 * @param code the string representation of the code
556 * @param code_verfier PKCE code verifier
508 * @param ticket where to store the ticket 557 * @param ticket where to store the ticket
509 * @param attrs the attributes in the code 558 * @param attrs the attributes in the code
510 * @param nonce where to store the nonce 559 * @param nonce where to store the nonce
@@ -513,6 +562,7 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
513int 562int
514OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, 563OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
515 const char *code, 564 const char *code,
565 const char *code_verifier,
516 struct GNUNET_RECLAIM_Ticket *ticket, 566 struct GNUNET_RECLAIM_Ticket *ticket,
517 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList **attrs, 567 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList **attrs,
518 char **nonce_str) 568 char **nonce_str)
@@ -520,6 +570,7 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
520 char *code_payload; 570 char *code_payload;
521 char *ptr; 571 char *ptr;
522 char *plaintext; 572 char *plaintext;
573 char *code_verifier_tmp;
523 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; 574 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
524 struct GNUNET_CRYPTO_EcdsaSignature *signature; 575 struct GNUNET_CRYPTO_EcdsaSignature *signature;
525 struct GNUNET_CRYPTO_EcdsaPublicKey ecdsa_pub; 576 struct GNUNET_CRYPTO_EcdsaPublicKey ecdsa_pub;
@@ -529,6 +580,7 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
529 size_t signature_offset; 580 size_t signature_offset;
530 size_t plaintext_len; 581 size_t plaintext_len;
531 uint32_t nonce = 0; 582 uint32_t nonce = 0;
583 struct OIDC_Parameters *params;
532 584
533 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code); 585 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code);
534 code_payload = NULL; 586 code_payload = NULL;
@@ -558,19 +610,35 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
558 plaintext_len = attrs_ser_len - sizeof (struct GNUNET_CRYPTO_EcdsaSignature); 610 plaintext_len = attrs_ser_len - sizeof (struct GNUNET_CRYPTO_EcdsaSignature);
559 plaintext = GNUNET_malloc (plaintext_len); 611 plaintext = GNUNET_malloc (plaintext_len);
560 decrypt_payload (ecdsa_priv, ecdh_pub, ptr, plaintext_len, plaintext); 612 decrypt_payload (ecdsa_priv, ecdh_pub, ptr, plaintext_len, plaintext);
561 ptr = plaintext; 613 //ptr = plaintext;
614 params = (struct OIDC_Parameters *) plaintext;
615
616 // cmp code_challenge code_verifier
617 code_verifier_tmp = GNUNET_malloc (strlen (code_verifier));
618 // hash code verifier
619 gcry_md_hash_buffer (GCRY_MD_SHA256,
620 code_verifier_tmp,
621 code_verifier,
622 strlen(code_verifier));
623 // encode code verifier
624 code_verifier_tmp = base64_encode (code_verifier_tmp, strlen (code_verifier_tmp));
625
626 if (0 != strcmp (code_verifier_tmp, params->code_challenge))
627 {
628 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid code verifier\n");
629 GNUNET_free_non_null (code_payload);
630 GNUNET_free (code_verifier_tmp);
631 return GNUNET_SYSERR;
632 }
633 GNUNET_free (code_verifier_tmp);
634
562 // Ticket 635 // Ticket
563 *ticket = *((struct GNUNET_RECLAIM_Ticket *) ptr); 636 ticket = params->ticket;
564 attrs_ser_len -= sizeof (struct GNUNET_RECLAIM_Ticket);
565 ptr += sizeof (struct GNUNET_RECLAIM_Ticket);
566 // Nonce 637 // Nonce
567 nonce = ntohl (*((uint32_t *) ptr)); 638 nonce = ntohl (params->nonce);//ntohl (*((uint32_t *) ptr));
568 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %u\n", nonce); 639 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %u\n", nonce);
569 attrs_ser_len -= sizeof (uint32_t);
570 ptr += sizeof (uint32_t);
571 // Attributes 640 // Attributes
572 attrs_ser_len -= sizeof (struct GNUNET_CRYPTO_EcdsaSignature); 641 *attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (params->attrs_ser, params->attr_list_len);
573 *attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (ptr, attrs_ser_len);
574 // Signature 642 // Signature
575 signature_offset = 643 signature_offset =
576 code_payload_len - sizeof (struct GNUNET_CRYPTO_EcdsaSignature); 644 code_payload_len - sizeof (struct GNUNET_CRYPTO_EcdsaSignature);
@@ -656,3 +724,4 @@ OIDC_access_token_new ()
656 &access_token); 724 &access_token);
657 return access_token; 725 return access_token;
658} 726}
727
diff --git a/src/reclaim/oidc_helper.h b/src/reclaim/oidc_helper.h
index 6c10a4ab0..10e43ea27 100644
--- a/src/reclaim/oidc_helper.h
+++ b/src/reclaim/oidc_helper.h
@@ -64,13 +64,15 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
64 * @param ticket the ticket to include in the code 64 * @param ticket the ticket to include in the code
65 * @param attrs list of attributes to share 65 * @param attrs list of attributes to share
66 * @param nonce the nonce to include in the code 66 * @param nonce the nonce to include in the code
67 * @param code_challenge PKCE code challenge
67 * @return a new authorization code (caller must free) 68 * @return a new authorization code (caller must free)
68 */ 69 */
69char* 70char*
70OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, 71OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
71 const struct GNUNET_RECLAIM_Ticket *ticket, 72 const struct GNUNET_RECLAIM_Ticket *ticket,
72 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, 73 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
73 const char* nonce); 74 const char *nonce,
75 const char *code_challenge);
74 76
75/** 77/**
76 * Parse reclaim ticket and nonce from 78 * Parse reclaim ticket and nonce from
@@ -79,6 +81,7 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
79 * 81 *
80 * @param ecdsa_priv the audience of the ticket 82 * @param ecdsa_priv the audience of the ticket
81 * @param code the string representation of the code 83 * @param code the string representation of the code
84 * @param code_verfier PKCE code verifier
82 * @param ticket where to store the ticket 85 * @param ticket where to store the ticket
83 * @param attrs the attributes found in the code 86 * @param attrs the attributes found in the code
84 * @param nonce where to store the nonce 87 * @param nonce where to store the nonce
@@ -86,7 +89,8 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
86 */ 89 */
87int 90int
88OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, 91OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
89 const char* code, 92 const char *code,
93 const char *code_verifier,
90 struct GNUNET_RECLAIM_Ticket *ticket, 94 struct GNUNET_RECLAIM_Ticket *ticket,
91 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList **attrs, 95 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList **attrs,
92 char **nonce); 96 char **nonce);
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);