diff options
author | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2019-09-04 20:42:06 +0200 |
---|---|---|
committer | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2019-09-04 20:42:06 +0200 |
commit | 1ec3a53b7f19e8b9d48571cff05c34923df963dd (patch) | |
tree | 7bbd6cfd600cf4698763b705599bad9ba8fce755 /src | |
parent | de8c2a206a6e1fe92cf01be548b6069e7e78e679 (diff) | |
download | gnunet-1ec3a53b7f19e8b9d48571cff05c34923df963dd.tar.gz gnunet-1ec3a53b7f19e8b9d48571cff05c34923df963dd.zip |
fix serialization
Diffstat (limited to 'src')
-rw-r--r-- | src/reclaim/oidc_helper.c | 157 |
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 | ||
75 | GNUNET_NETWORK_STRUCT_END | 65 | GNUNET_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 (¶ms, 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, ¶ms, 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*)¶ms[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 *) ¶ms[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 | { |