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.c157
1 files changed, 78 insertions, 79 deletions
diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c
index 01a3d0179..40b07a5d0 100644
--- a/src/reclaim/oidc_helper.c
+++ b/src/reclaim/oidc_helper.c
@@ -60,16 +60,6 @@ struct OIDC_Parameters
60 * The length of the attributes list 60 * The length of the attributes list
61 */ 61 */
62 uint16_t attr_list_len GNUNET_PACKED; 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}; 63};
74 64
75GNUNET_NETWORK_STRUCT_END 65GNUNET_NETWORK_STRUCT_END
@@ -349,7 +339,7 @@ derive_aes_key (struct GNUNET_CRYPTO_SymmetricSessionKey *key,
349 NULL); 339 NULL);
350 GNUNET_CRYPTO_kdf (iv, 340 GNUNET_CRYPTO_kdf (iv,
351 sizeof ( 341 sizeof (
352 struct GNUNET_CRYPTO_SymmetricInitializationVector), 342 struct GNUNET_CRYPTO_SymmetricInitializationVector),
353 ctx_iv, 343 ctx_iv,
354 strlen (ctx_iv), 344 strlen (ctx_iv),
355 key_material, 345 key_material,
@@ -409,7 +399,7 @@ encrypt_payload (const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub,
409 399
410 calculate_key_pub (&key, &iv, ecdsa_pub, ecdh_priv); 400 calculate_key_pub (&key, &iv, ecdsa_pub, ecdh_priv);
411 GNUNET_break ( 401 GNUNET_break (
412 GNUNET_CRYPTO_symmetric_encrypt (payload, payload_len, &key, &iv, buf)); 402 GNUNET_CRYPTO_symmetric_encrypt (payload, payload_len, &key, &iv, buf));
413} 403}
414 404
415/** 405/**
@@ -430,13 +420,15 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
430 const char *nonce_str, 420 const char *nonce_str,
431 const char *code_challenge) 421 const char *code_challenge)
432{ 422{
433 struct OIDC_Parameters *params = GNUNET_new (struct OIDC_Parameters); 423 struct OIDC_Parameters params;
434 char *code_payload; 424 char *code_payload;
435 char *plaintext; 425 char *payload;
426 char *tmp;
436 char *code_str; 427 char *code_str;
437 char *buf_ptr = NULL; 428 char *buf_ptr = NULL;
438 size_t signature_payload_len; 429 size_t payload_len;
439 size_t code_payload_len; 430 size_t code_payload_len;
431 size_t attr_list_len = 0;
440 uint32_t nonce; 432 uint32_t nonce;
441 uint32_t nonce_tmp; 433 uint32_t nonce_tmp;
442 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; 434 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
@@ -445,65 +437,66 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
445 437
446 /** PLAINTEXT **/ 438 /** PLAINTEXT **/
447 // Assign ticket 439 // Assign ticket
448 params->ticket = ticket; 440 memset (&params, 0, sizeof (params));
441 params.ticket = ticket;
449 // Assign nonce 442 // Assign nonce
450 nonce = 0; 443 nonce = 0;
451 if (NULL != nonce_str && strcmp("", nonce_str) != 0) 444 payload_len = sizeof (struct OIDC_Parameters);
445 if (NULL != nonce_str && strcmp ("", nonce_str) != 0)
452 { 446 {
453 if ((1 != SSCANF (nonce_str, "%u", &nonce)) || (nonce > UINT32_MAX)) 447 if ((1 != SSCANF (nonce_str, "%u", &nonce)) || (nonce > UINT32_MAX))
454 { 448 {
455 GNUNET_break (0); 449 GNUNET_break (0);
456 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid nonce %s\n", nonce_str); 450 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid nonce %s\n", nonce_str);
457 GNUNET_free (params);
458 return NULL; 451 return NULL;
459 } 452 }
460 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 453 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
461 "Got nonce: %u from %s\n", 454 "Got nonce: %u from %s\n",
462 nonce, 455 nonce,
463 nonce_str); 456 nonce_str);
464 } 457 }
465 nonce_tmp = htonl (nonce); 458 nonce_tmp = htonl (nonce);
466 params->nonce = nonce_tmp; 459 params.nonce = nonce_tmp;
467 // Assign code challenge 460 // Assign code challenge
468 if (NULL == code_challenge || strcmp("", code_challenge) == 0) 461 if (NULL == code_challenge || strcmp ("", code_challenge) == 0)
469 { 462 {
470 GNUNET_break (0); 463 GNUNET_break (0);
471 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "PKCE: Code challenge missing"); 464 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "PKCE: Code challenge missing");
472 GNUNET_free (params); 465 return NULL;
473 return NULL;
474 } 466 }
475 params->code_challenge_len = strlen (code_challenge); 467 payload_len += strlen (code_challenge);
476 params->code_challenge = code_challenge; 468 params.code_challenge_len = htonl (strlen (code_challenge));
477 // Assign attributes 469 // Assign attributes
478 params->attrs_ser = NULL;
479 if (NULL != attrs) 470 if (NULL != attrs)
480 { 471 {
481 // Get length 472 // Get length
482 params->attr_list_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (attrs); 473 attr_list_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (attrs);
474 params.attr_list_len = htonl (attr_list_len);
483 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 475 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
484 "Length of serialized attributes: %lu\n", 476 "Length of serialized attributes: %lu\n",
485 params->attr_list_len); 477 attr_list_len);
486 // Get serialized attributes 478 // Get serialized attributes
487 params->attrs_ser = GNUNET_malloc (params->attr_list_len); 479 payload_len += attr_list_len;
488 GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, params->attrs_ser);
489 } 480 }
490
491 // Get plaintext length 481 // Get plaintext length
492 signature_payload_len = sizeof (struct OIDC_Parameters); 482 payload = GNUNET_malloc (payload_len);
493 plaintext = GNUNET_malloc (signature_payload_len); 483 memcpy (payload, &params, sizeof (params));
494 memcpy (plaintext, params, signature_payload_len); 484 tmp = payload + sizeof (params);
485 memcpy (tmp, code_challenge, strlen (code_challenge));
486 tmp += strlen (code_challenge);
487 if (0 < attr_list_len)
488 GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, tmp);
495 /** END **/ 489 /** END **/
496 490
497 /** ENCRYPT **/ 491 /** ENCRYPT **/
498 // Get length 492 // Get length
499 code_payload_len = sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + 493 code_payload_len = sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
500 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + 494 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
501 signature_payload_len + 495 payload_len + sizeof (struct GNUNET_CRYPTO_EcdsaSignature);
502 sizeof (struct GNUNET_CRYPTO_EcdsaSignature);
503 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 496 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
504 "Length of data to encode: %lu\n", 497 "Length of data to encode: %lu\n",
505 code_payload_len); 498 code_payload_len);
506 499
507 // Generate ECDH key 500 // Generate ECDH key
508 ecdh_priv = GNUNET_CRYPTO_ecdhe_key_create (); 501 ecdh_priv = GNUNET_CRYPTO_ecdhe_key_create ();
509 GNUNET_CRYPTO_ecdhe_key_get_public (ecdh_priv, &ecdh_pub); 502 GNUNET_CRYPTO_ecdhe_key_get_public (ecdh_priv, &ecdh_pub);
@@ -512,7 +505,7 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
512 GNUNET_assert (NULL != code_payload); 505 GNUNET_assert (NULL != code_payload);
513 purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload; 506 purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload;
514 purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + 507 purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
515 sizeof (ecdh_pub) + signature_payload_len); 508 sizeof (ecdh_pub) + payload_len);
516 purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN); 509 purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN);
517 // Store pubkey 510 // Store pubkey
518 buf_ptr = (char *) &purpose[1]; 511 buf_ptr = (char *) &purpose[1];
@@ -521,19 +514,18 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
521 // Encrypt plaintext and store 514 // Encrypt plaintext and store
522 encrypt_payload (&ticket->audience, 515 encrypt_payload (&ticket->audience,
523 ecdh_priv, 516 ecdh_priv,
524 plaintext, 517 payload,
525 signature_payload_len, 518 payload_len,
526 buf_ptr); 519 buf_ptr);
527 GNUNET_free (ecdh_priv); 520 GNUNET_free (ecdh_priv);
528 GNUNET_free (plaintext); 521 GNUNET_free (payload);
529 GNUNET_free (params); 522 buf_ptr += payload_len;
530 buf_ptr += signature_payload_len;
531 // Sign and store signature 523 // Sign and store signature
532 if (GNUNET_SYSERR == 524 if (GNUNET_SYSERR ==
533 GNUNET_CRYPTO_ecdsa_sign (issuer, 525 GNUNET_CRYPTO_ecdsa_sign (issuer,
534 purpose, 526 purpose,
535 (struct GNUNET_CRYPTO_EcdsaSignature *) 527 (struct GNUNET_CRYPTO_EcdsaSignature *)
536 buf_ptr)) 528 buf_ptr))
537 { 529 {
538 GNUNET_break (0); 530 GNUNET_break (0);
539 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to sign code\n"); 531 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to sign code\n");
@@ -570,15 +562,18 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
570 char *code_payload; 562 char *code_payload;
571 char *ptr; 563 char *ptr;
572 char *plaintext; 564 char *plaintext;
573 char *code_verifier_tmp; 565 char *attrs_ser;
566 char *expected_code_challenge;
567 char *code_challenge;
568 char *code_verifier_hash;
574 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; 569 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
575 struct GNUNET_CRYPTO_EcdsaSignature *signature; 570 struct GNUNET_CRYPTO_EcdsaSignature *signature;
576 struct GNUNET_CRYPTO_EcdsaPublicKey ecdsa_pub; 571 struct GNUNET_CRYPTO_EcdsaPublicKey ecdsa_pub;
577 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub; 572 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub;
578 size_t code_payload_len; 573 size_t code_challenge_len;
579 size_t attrs_ser_len; 574 size_t attrs_ser_len;
580 size_t signature_offset;
581 size_t plaintext_len; 575 size_t plaintext_len;
576 size_t code_payload_len;
582 uint32_t nonce = 0; 577 uint32_t nonce = 0;
583 struct OIDC_Parameters *params; 578 struct OIDC_Parameters *params;
584 579
@@ -587,10 +582,9 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
587 code_payload_len = 582 code_payload_len =
588 GNUNET_STRINGS_base64_decode (code, strlen (code), (void **) &code_payload); 583 GNUNET_STRINGS_base64_decode (code, strlen (code), (void **) &code_payload);
589 if (code_payload_len < sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + 584 if (code_payload_len < sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
590 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + 585 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
591 sizeof (struct GNUNET_RECLAIM_Ticket) + 586 sizeof (struct OIDC_Parameters) +
592 sizeof (uint32_t) + 587 sizeof (struct GNUNET_CRYPTO_EcdsaSignature))
593 sizeof (struct GNUNET_CRYPTO_EcdsaSignature))
594 { 588 {
595 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Authorization code malformed\n"); 589 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Authorization code malformed\n");
596 GNUNET_free_non_null (code_payload); 590 GNUNET_free_non_null (code_payload);
@@ -598,52 +592,57 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
598 } 592 }
599 593
600 purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload; 594 purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload;
601 attrs_ser_len = code_payload_len; 595 plaintext_len = code_payload_len;
602 attrs_ser_len -= sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose); 596 plaintext_len -= sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose);
603 ptr = (char *) &purpose[1]; 597 ptr = (char *) &purpose[1];
604 // Public ECDH key 598 // Public ECDH key
605 ecdh_pub = (struct GNUNET_CRYPTO_EcdhePublicKey *) ptr; 599 ecdh_pub = (struct GNUNET_CRYPTO_EcdhePublicKey *) ptr;
606 ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey); 600 ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
607 attrs_ser_len -= sizeof (struct GNUNET_CRYPTO_EcdhePublicKey); 601 plaintext_len -= sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
608 602
609 // Decrypt ciphertext 603 // Decrypt ciphertext
610 plaintext_len = attrs_ser_len - sizeof (struct GNUNET_CRYPTO_EcdsaSignature); 604 plaintext_len -= sizeof (struct GNUNET_CRYPTO_EcdsaSignature);
611 plaintext = GNUNET_malloc (plaintext_len); 605 plaintext = GNUNET_malloc (plaintext_len);
612 decrypt_payload (ecdsa_priv, ecdh_pub, ptr, plaintext_len, plaintext); 606 decrypt_payload (ecdsa_priv, ecdh_pub, ptr, plaintext_len, plaintext);
613 //ptr = plaintext; 607 //ptr = plaintext;
614 params = (struct OIDC_Parameters *) plaintext; 608 params = (struct OIDC_Parameters *) plaintext;
615 609
616 // cmp code_challenge code_verifier 610 // cmp code_challenge code_verifier
617 code_verifier_tmp = GNUNET_malloc (strlen (code_verifier)); 611 code_verifier_hash = GNUNET_malloc (strlen (code_verifier));
618 // hash code verifier 612 // hash code verifier
619 gcry_md_hash_buffer (GCRY_MD_SHA256, 613 gcry_md_hash_buffer (GCRY_MD_SHA256,
620 code_verifier_tmp, 614 code_verifier_hash,
621 code_verifier, 615 code_verifier,
622 strlen(code_verifier)); 616 strlen (code_verifier));
623 // encode code verifier 617 // encode code verifier
624 code_verifier_tmp = base64_encode (code_verifier_tmp, strlen (code_verifier_tmp)); 618 expected_code_challenge =
625 619 base64_encode (code_verifier_hash, strlen (code_verifier_hash));
626 if (0 != strcmp (code_verifier_tmp, params->code_challenge)) 620 code_challenge = (char*)&params[1];
621 code_challenge_len = ntohl (params->code_challenge_len);
622 GNUNET_free (code_verifier_hash);
623 if ((strlen (expected_code_challenge) != code_challenge_len) ||
624 (0 !=
625 strncmp (expected_code_challenge, code_challenge, code_challenge_len)))
627 { 626 {
628 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid code verifier\n"); 627 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid code verifier\n");
629 GNUNET_free_non_null (code_payload); 628 GNUNET_free_non_null (code_payload);
630 GNUNET_free (code_verifier_tmp); 629 GNUNET_free (expected_code_challenge);
631 return GNUNET_SYSERR; 630 return GNUNET_SYSERR;
632 } 631 }
633 GNUNET_free (code_verifier_tmp); 632 GNUNET_free (expected_code_challenge);
634
635 // Ticket 633 // Ticket
636 ticket = params->ticket; 634 memcpy (ticket, params->ticket, sizeof (*ticket));
637 // Nonce 635 // Nonce
638 nonce = ntohl (params->nonce);//ntohl (*((uint32_t *) ptr)); 636 nonce = ntohl (params->nonce); //ntohl (*((uint32_t *) ptr));
639 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %u\n", nonce); 637 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %u\n", nonce);
640 // Attributes 638 // Attributes
641 *attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (params->attrs_ser, params->attr_list_len); 639 attrs_ser = ((char *) &params[1]) + code_challenge_len;
640 attrs_ser_len = ntohl (params->attr_list_len);
641 *attrs =
642 GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (attrs_ser,
643 attrs_ser_len);
642 // Signature 644 // Signature
643 signature_offset = 645 signature = (struct GNUNET_CRYPTO_EcdsaSignature *) attrs_ser + attrs_ser_len;
644 code_payload_len - sizeof (struct GNUNET_CRYPTO_EcdsaSignature);
645 signature =
646 (struct GNUNET_CRYPTO_EcdsaSignature *) &code_payload[signature_offset];
647 GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub); 646 GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub);
648 if (0 != GNUNET_memcmp (&ecdsa_pub, &ticket->audience)) 647 if (0 != GNUNET_memcmp (&ecdsa_pub, &ticket->audience))
649 { 648 {