diff options
Diffstat (limited to 'src/reclaim/oidc_helper.c')
-rw-r--r-- | src/reclaim/oidc_helper.c | 179 |
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 | ||
37 | GNUNET_NETWORK_STRUCT_BEGIN | ||
38 | |||
39 | /** | ||
40 | * The signature used to generate the authorization code | ||
41 | */ | ||
42 | struct 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 | |||
75 | GNUNET_NETWORK_STRUCT_END | ||
35 | 76 | ||
36 | static char * | 77 | static char * |
37 | create_jwt_header (void) | 78 | create_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 | */ |
385 | char * | 426 | char * |
386 | OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | 427 | OIDC_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, | |||
513 | int | 562 | int |
514 | OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, | 563 | OIDC_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 | |||