aboutsummaryrefslogtreecommitdiff
path: root/src/reclaim/oidc_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/reclaim/oidc_helper.c')
-rw-r--r--src/reclaim/oidc_helper.c179
1 files changed, 124 insertions, 55 deletions
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