aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2016-01-04 12:43:47 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2016-01-04 12:43:47 +0000
commit588c1bd23e49f3264bdfdb3b02c7cf6e78b66534 (patch)
tree2fe3b1f9e930a75675eb7e75aaab5100cb13ab54 /src
parent1af781131216a54772885e8514d5a9c9ef2f6cd0 (diff)
downloadgnunet-588c1bd23e49f3264bdfdb3b02c7cf6e78b66534.tar.gz
gnunet-588c1bd23e49f3264bdfdb3b02c7cf6e78b66534.zip
- Add ecdsa ecdh functions
- Update identity token to encrypted protocol
Diffstat (limited to 'src')
-rw-r--r--src/identity-token/gnunet-service-identity-token.c2
-rw-r--r--src/identity-token/plugin_rest_identity_token.c499
-rw-r--r--src/include/gnunet_crypto_lib.h30
-rw-r--r--src/include/gnunet_signatures.h5
-rw-r--r--src/util/crypto_ecc.c91
5 files changed, 532 insertions, 95 deletions
diff --git a/src/identity-token/gnunet-service-identity-token.c b/src/identity-token/gnunet-service-identity-token.c
index 222b9d184..5fcf47e14 100644
--- a/src/identity-token/gnunet-service-identity-token.c
+++ b/src/identity-token/gnunet-service-identity-token.c
@@ -188,7 +188,7 @@ handle_token_update (void *cls,
188 char *new_payload_str; 188 char *new_payload_str;
189 char *new_payload_base64; 189 char *new_payload_base64;
190 char *sig_str; 190 char *sig_str;
191 char *key; 191 const char *key;
192 char *padding; 192 char *padding;
193 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; 193 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
194 struct EgoEntry *ego_entry = cls; 194 struct EgoEntry *ego_entry = cls;
diff --git a/src/identity-token/plugin_rest_identity_token.c b/src/identity-token/plugin_rest_identity_token.c
index 6b9106e14..2621d1f57 100644
--- a/src/identity-token/plugin_rest_identity_token.c
+++ b/src/identity-token/plugin_rest_identity_token.c
@@ -51,21 +51,23 @@
51#define GNUNET_REST_API_NS_IDENTITY_TOKEN_CHECK "/gnuid/check" 51#define GNUNET_REST_API_NS_IDENTITY_TOKEN_CHECK "/gnuid/check"
52 52
53/** 53/**
54 * OAuth2 namespace 54 * Token namespace
55 */ 55 */
56#define GNUNET_REST_API_NS_IDENTITY_OAUTH2_TOKEN "/gnuid/token" 56#define GNUNET_REST_API_NS_IDENTITY_OAUTH2_TOKEN "/gnuid/token"
57 57
58/** 58/**
59 * OAuth2 namespace 59 * Authorize namespace
60 */ 60 */
61#define GNUNET_REST_API_NS_IDENTITY_OAUTH2_AUTHORIZE "/gnuid/authorize" 61#define GNUNET_REST_API_NS_IDENTITY_OAUTH2_AUTHORIZE "/gnuid/authorize"
62 62
63#define GNUNET_REST_JSONAPI_IDENTITY_OAUTH2_CODE "code" 63#define GNUNET_REST_JSONAPI_IDENTITY_TOKEN_CODE "code"
64 64
65#define GNUNET_REST_JSONAPI_IDENTITY_OAUTH2_GRANT_TYPE_CODE "authorization_code" 65#define GNUNET_REST_JSONAPI_IDENTITY_OAUTH2_GRANT_TYPE_CODE "authorization_code"
66 66
67#define GNUNET_REST_JSONAPI_IDENTITY_OAUTH2_GRANT_TYPE "grant_type" 67#define GNUNET_REST_JSONAPI_IDENTITY_OAUTH2_GRANT_TYPE "grant_type"
68 68
69#define GNUNET_IDENTITY_TOKEN_REQUEST_NONCE "nonce"
70
69/** 71/**
70 * State while collecting all egos 72 * State while collecting all egos
71 */ 73 */
@@ -412,6 +414,88 @@ store_token_cont (void *cls,
412 GNUNET_SCHEDULER_add_now (&do_cleanup_handle_delayed, handle); 414 GNUNET_SCHEDULER_add_now (&do_cleanup_handle_delayed, handle);
413} 415}
414 416
417static int
418create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
419 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
420 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
421{
422 struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
423
424 GNUNET_CRYPTO_hash_to_enc (new_key_hash,
425 &new_key_hash_str);
426 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
427 static const char ctx_key[] = "gnuid-aes-ctx-key";
428 GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
429 new_key_hash, sizeof (struct GNUNET_HashCode),
430 ctx_key, strlen (ctx_key),
431 NULL, 0);
432 static const char ctx_iv[] = "gnuid-aes-ctx-iv";
433 GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
434 new_key_hash, sizeof (struct GNUNET_HashCode),
435 ctx_iv, strlen (ctx_iv),
436 NULL, 0);
437 return GNUNET_OK;
438}
439
440/**
441 * Create the token code
442 * The metadata is encrypted with a share ECDH derived secret using B (aud_key)
443 * and e (ecdh_privkey)
444 * The token_code also contains E (ecdh_pubkey) and a signature over the
445 * metadata and E
446 */
447static int
448create_token_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
449 const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_privkey,
450 const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pubkey,
451 const char* code_str,
452 const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
453 char **result,
454 size_t *result_len,
455 struct GNUNET_CRYPTO_EcdsaSignature *sig)
456{
457 char *write_ptr;
458 struct GNUNET_HashCode new_key_hash;
459 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
460 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
461 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
462
463 *result = GNUNET_malloc (strlen (code_str));
464 *result_len = strlen (code_str);
465
466 // Derived key K = H(eB)
467 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (ecdh_privkey,
468 aud_key,
469 &new_key_hash));
470 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
471 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Encrypting token code %s\n", code_str);
472 GNUNET_CRYPTO_symmetric_encrypt (code_str, strlen (code_str),
473 &skey, &iv,
474 *result);
475 purpose =
476 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
477 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E
478 *result_len); // E_K (code_str)
479 purpose->size =
480 htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
481 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
482 *result_len);
483 purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN_CODE);
484 write_ptr = (char*) &purpose[1];
485 memcpy (write_ptr, ecdh_pubkey, sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
486 write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
487 memcpy (write_ptr, *result, *result_len);
488 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key,
489 purpose,
490 sig))
491 {
492 GNUNET_free (purpose);
493 return GNUNET_SYSERR;
494 }
495 GNUNET_free (purpose);
496 return GNUNET_OK;
497}
498
415 499
416/** 500/**
417 * Build a GNUid token for identity 501 * Build a GNUid token for identity
@@ -426,6 +510,23 @@ static void
426sign_and_return_token (void *cls, 510sign_and_return_token (void *cls,
427 const struct GNUNET_SCHEDULER_TaskContext *tc) 511 const struct GNUNET_SCHEDULER_TaskContext *tc)
428{ 512{
513 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
514
515 struct GNUNET_CRYPTO_EcdsaSignature token_sig;
516 struct GNUNET_CRYPTO_EcdsaSignature token_code_sig;
517 struct GNUNET_CRYPTO_EcdsaPublicKey aud_pkey;
518 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_privkey;
519 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
520 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
521 struct JsonApiResource *json_resource;
522 struct RequestHandle *handle = cls;
523 struct GNUNET_GNSRECORD_Data token_record;
524 struct GNUNET_HashCode key;
525 struct GNUNET_TIME_Relative etime_rel;
526 json_t *token_str;
527 json_t *name_str;
528 json_t *token_code_json;
529 size_t token_code_payload_len;
429 char *header_str; 530 char *header_str;
430 char *payload_str; 531 char *payload_str;
431 char *header_base64; 532 char *header_base64;
@@ -435,23 +536,41 @@ sign_and_return_token (void *cls,
435 char *token; 536 char *token;
436 char *exp_str; 537 char *exp_str;
437 char *renew_str; 538 char *renew_str;
438 char *rnd_str; 539 char *token_code_str;
540 char *token_code_payload;
541 char *code_meta_str;
542 char *audience;
543 char *nonce_str;
544 char *param_str;
545 char *token_code_sig_str;
546 char *token_code_payload_str;
547 char *dh_key_str;
548 char *record_data;
549 int renew_token = GNUNET_NO;
439 uint64_t time; 550 uint64_t time;
440 uint64_t exp_time; 551 uint64_t exp_time;
441 uint64_t lbl_key; 552 uint64_t rnd_key;
442 json_t *token_str; 553
443 json_t *name_str; 554 //Remote nonce
444 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; 555 nonce_str = NULL;
445 struct GNUNET_CRYPTO_EcdsaSignature sig; 556 GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_REQUEST_NONCE,
446 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; 557 strlen (GNUNET_IDENTITY_TOKEN_REQUEST_NONCE),
447 struct JsonApiResource *json_resource; 558 &key);
448 struct RequestHandle *handle = cls; 559 if ( GNUNET_YES !=
449 struct GNUNET_GNSRECORD_Data token_record; 560 GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
450 struct GNUNET_HashCode key; 561 &key) )
451 struct GNUNET_TIME_Relative etime_rel; 562 {
452 int renew_token = GNUNET_NO; 563 handle->emsg = GNUNET_strdup ("Request nonce missing!\n");
453/* 564 GNUNET_SCHEDULER_add_now (&do_error, handle);
454 //Token audience 565 return;
566 }
567 nonce_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
568 &key);
569 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Request nonce: %s\n", nonce_str);
570 //Token audience
571 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_AUD_REQUEST,
572 strlen (GNUNET_REST_JSONAPI_IDENTITY_AUD_REQUEST),
573 &key);
455 audience = NULL; 574 audience = NULL;
456 if ( GNUNET_YES != 575 if ( GNUNET_YES !=
457 GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, 576 GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
@@ -463,8 +582,9 @@ sign_and_return_token (void *cls,
463 } 582 }
464 audience = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, 583 audience = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
465 &key); 584 &key);
466 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Audience to issue token for: %s\n", audience); 585 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Audience to issue token for: %s\n", audience);
467 //Create label for audience 586
587 //Audience pubkey (B = bG)
468 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_public_key_from_string (audience, 588 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_public_key_from_string (audience,
469 strlen (audience), 589 strlen (audience),
470 &aud_pkey)) 590 &aud_pkey))
@@ -474,46 +594,51 @@ sign_and_return_token (void *cls,
474 return; 594 return;
475 } 595 }
476 596
477 new_privkey = GNUNET_CRYPTO_ecdhe_key_create();
478
479 GNUNET_CRYPTO_ecdh_ecdsa (new_privkey,
480 &aud_pkey,
481 &new_key_hash);
482
483 GNUNET_CRYPTO_ecdhe_key_get_public (new_privkey,
484 new_pubkey);
485 static const char ctx_key[] = "gnuid-aes-ctx-key";
486 GNUNET_CRYPTO_kdf (&skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
487 new_pubkey, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
488 ctx_key, strlen (ctx_key),
489 NULL, 0);
490 static const char ctx_iv[] = "gnuid-aes-ctx-iv";
491 GNUNET_CRYPTO_kdf (&iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
492 new_pubkey, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
493 ctx_iv, strlen (ctx_iv),
494 NULL, 0);
495*/
496 //TODO: Encrypt the label
497 time = GNUNET_TIME_absolute_get().abs_value_us; 597 time = GNUNET_TIME_absolute_get().abs_value_us;
498 lbl_key = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX); 598 rnd_key = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
499 GNUNET_asprintf (&rnd_str, 599 GNUNET_STRINGS_base64_encode ((char*)&rnd_key, sizeof (uint64_t), &lbl_str);
500 "{\"nonce\": \"%uul\",\"identity\": \"%s\"}", 600 GNUNET_asprintf (&code_meta_str,
501 lbl_key, handle->ego_entry->keystring); 601 "{\"nonce\": \"%u\",\"identity\": \"%s\",\"label\": \"%s\"}",
502 GNUNET_STRINGS_base64_encode (rnd_str, strlen (rnd_str), &lbl_str); 602 nonce_str, handle->ego_entry->keystring, lbl_str);
503 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_AUD_REQUEST, 603 priv_key = GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego);
504 strlen (GNUNET_REST_JSONAPI_IDENTITY_AUD_REQUEST),
505 &key);
506 604
507/* 605 // ECDH keypair E = eG
508 GNUNET_CRYPTO_symmetric_encrypt (handle->ego_entry->keystring, strlen (handle->ego_entry->keystring), 606 ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
509 &skey, &iv, 607 token_code_payload_len = 0;
510 &block[1]); 608 token_code_payload = NULL;
609 GNUNET_CRYPTO_ecdhe_key_get_public (ecdh_privkey,
610 &ecdh_pubkey);
611 if (GNUNET_OK != create_token_code (priv_key,
612 ecdh_privkey,
613 &ecdh_pubkey,
614 code_meta_str,
615 &aud_pkey,
616 &token_code_payload,
617 &token_code_payload_len,
618 &token_code_sig))
619 {
620 handle->emsg = GNUNET_strdup ("Unable to create ref token!\n");
621 GNUNET_SCHEDULER_add_now (&do_error, handle);
622 return;
623 }
624 GNUNET_STRINGS_base64_encode (token_code_payload,
625 token_code_payload_len,
626 &token_code_payload_str);
627 token_code_sig_str = GNUNET_STRINGS_data_to_string_alloc (&token_code_sig,
628 sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
629 dh_key_str = GNUNET_STRINGS_data_to_string_alloc (&ecdh_pubkey,
630 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
631 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Using ECDH pubkey %s to encrypt\n", dh_key_str);
632 GNUNET_asprintf (&param_str, "{\"meta\": \"%s\", \"ecdh\": \"%s\", \"signature\": \"%s\"}",
633 token_code_payload_str, dh_key_str, token_code_sig_str);
634 GNUNET_STRINGS_base64_encode (param_str, strlen (param_str), &token_code_str);
635 GNUNET_free (param_str);
636 GNUNET_free (token_code_payload);
637 GNUNET_free (token_code_payload_str);
511 638
512*/
513 GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_EXP_STRING, 639 GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_EXP_STRING,
514 strlen (GNUNET_IDENTITY_TOKEN_EXP_STRING), 640 strlen (GNUNET_IDENTITY_TOKEN_EXP_STRING),
515 &key); 641 &key);
516
517 //Get expiration for token from URL parameter 642 //Get expiration for token from URL parameter
518 exp_str = NULL; 643 exp_str = NULL;
519 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, 644 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
@@ -522,9 +647,6 @@ sign_and_return_token (void *cls,
522 exp_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, 647 exp_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
523 &key); 648 &key);
524 } 649 }
525
526
527
528 if (NULL == exp_str) { 650 if (NULL == exp_str) {
529 handle->emsg = GNUNET_strdup ("No expiration given!\n"); 651 handle->emsg = GNUNET_strdup ("No expiration given!\n");
530 GNUNET_SCHEDULER_add_now (&do_error, handle); 652 GNUNET_SCHEDULER_add_now (&do_error, handle);
@@ -561,6 +683,8 @@ sign_and_return_token (void *cls,
561 json_object_set_new (handle->payload, "nbf", json_integer (time)); 683 json_object_set_new (handle->payload, "nbf", json_integer (time));
562 json_object_set_new (handle->payload, "iat", json_integer (time)); 684 json_object_set_new (handle->payload, "iat", json_integer (time));
563 json_object_set_new (handle->payload, "exp", json_integer (exp_time)); 685 json_object_set_new (handle->payload, "exp", json_integer (exp_time));
686 json_object_set_new (handle->payload, "nonce",
687 json_string (nonce_str));
564 if (GNUNET_YES == renew_token) 688 if (GNUNET_YES == renew_token)
565 { 689 {
566 json_object_set_new (handle->payload, "rnl", json_string ("yes")); 690 json_object_set_new (handle->payload, "rnl", json_string ("yes"));
@@ -583,7 +707,6 @@ sign_and_return_token (void *cls,
583 padding = strtok(NULL, "="); 707 padding = strtok(NULL, "=");
584 708
585 GNUNET_asprintf (&token, "%s,%s", header_base64, payload_base64); 709 GNUNET_asprintf (&token, "%s,%s", header_base64, payload_base64);
586 priv_key = GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego);
587 purpose = 710 purpose =
588 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + 711 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
589 strlen (token)); 712 strlen (token));
@@ -593,10 +716,10 @@ sign_and_return_token (void *cls,
593 memcpy (&purpose[1], token, strlen (token)); 716 memcpy (&purpose[1], token, strlen (token));
594 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key, 717 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key,
595 purpose, 718 purpose,
596 &sig)) 719 &token_sig))
597 GNUNET_break(0); 720 GNUNET_break(0);
598 GNUNET_free (token); 721 GNUNET_free (token);
599 GNUNET_STRINGS_base64_encode ((const char*)&sig, 722 GNUNET_STRINGS_base64_encode ((const char*)&token_sig,
600 sizeof (struct GNUNET_CRYPTO_EcdsaSignature), 723 sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
601 &sig_str); 724 &sig_str);
602 GNUNET_asprintf (&token, "%s.%s.%s", 725 GNUNET_asprintf (&token, "%s.%s.%s",
@@ -623,12 +746,20 @@ sign_and_return_token (void *cls,
623 746
624 747
625 token_str = json_string (token); 748 token_str = json_string (token);
626 GNUNET_REST_jsonapi_resource_add_attr (json_resource, 749 GNUNET_REST_jsonapi_resource_add_attr (json_resource,
627 GNUNET_REST_JSONAPI_IDENTITY_TOKEN, 750 GNUNET_REST_JSONAPI_IDENTITY_TOKEN,
628 token_str); 751 token_str);
752 token_code_json = json_string (token_code_str);
753 GNUNET_REST_jsonapi_resource_add_attr (json_resource,
754 GNUNET_REST_JSONAPI_IDENTITY_TOKEN_CODE,
755 token_code_json);
756 GNUNET_free (token_code_str);
757 json_decref (token_code_json);
629 GNUNET_REST_jsonapi_object_resource_add (handle->resp_object, json_resource); 758 GNUNET_REST_jsonapi_object_resource_add (handle->resp_object, json_resource);
630 token_record.data = token; 759
631 token_record.data_size = strlen (token); 760 GNUNET_asprintf (&record_data, "%s,%s", dh_key_str, token);
761 token_record.data = record_data;
762 token_record.data_size = strlen (record_data) + 1;
632 token_record.expiration_time = exp_time; 763 token_record.expiration_time = exp_time;
633 token_record.record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN; 764 token_record.record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN;
634 token_record.flags = GNUNET_GNSRECORD_RF_NONE; 765 token_record.flags = GNUNET_GNSRECORD_RF_NONE;
@@ -642,6 +773,7 @@ sign_and_return_token (void *cls,
642 &token_record, 773 &token_record,
643 &store_token_cont, 774 &store_token_cont,
644 handle); 775 handle);
776 GNUNET_free (record_data);
645 GNUNET_free (lbl_str); 777 GNUNET_free (lbl_str);
646 GNUNET_free (token); 778 GNUNET_free (token);
647 json_decref (token_str); 779 json_decref (token_str);
@@ -1038,22 +1170,196 @@ process_lookup_result (void *cls, uint32_t rd_count,
1038 json_decref (root); 1170 json_decref (root);
1039} 1171}
1040 1172
1173
1174/**
1175 * Decrypts metainfo part from a token code
1176 */
1177static int
1178decrypt_meta_str (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
1179 const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key,
1180 const char *enc_meta,
1181 size_t enc_meta_len,
1182 struct GNUNET_CRYPTO_EcdsaSignature *signature,
1183 char **meta_str)
1184{
1185 struct GNUNET_HashCode new_key_hash;
1186 struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
1187 struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
1188
1189 char *meta_str_buf = GNUNET_malloc (enc_meta_len);
1190 size_t meta_size;
1191
1192 //Calculate symmetric key from ecdh parameters
1193 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_ecdh (priv_key,
1194 ecdh_key,
1195 &new_key_hash));
1196
1197 create_sym_key_from_ecdh (&new_key_hash,
1198 &enc_key,
1199 &enc_iv);
1200
1201 meta_size = GNUNET_CRYPTO_symmetric_decrypt (enc_meta,
1202 enc_meta_len,
1203 &enc_key,
1204 &enc_iv,
1205 meta_str_buf);
1206 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Decrypted bytes: %d Expected bytes: %d\n", meta_size, enc_meta_len);
1207 if (-1 == meta_size)
1208 {
1209 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH signature invalid in metadata\n");
1210 return GNUNET_SYSERR;
1211 }
1212 *meta_str = GNUNET_malloc (meta_size+1);
1213 memcpy (*meta_str, meta_str_buf, meta_size);
1214 (*meta_str)[meta_size] = '\0';
1215 GNUNET_free (meta_str_buf);
1216 return GNUNET_OK;
1217
1218}
1219
1220static int
1221extract_values_from_token_code (const char *token_code,
1222 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key,
1223 struct GNUNET_CRYPTO_EcdsaSignature *signature,
1224 struct GNUNET_CRYPTO_EcdhePublicKey *ecdhe_pkey,
1225 char **label,
1226 struct GNUNET_CRYPTO_EcdsaPublicKey *id_pkey)
1227{
1228 const char* enc_meta_str;
1229 const char* ecdh_enc_str;
1230 const char* signature_enc_str;
1231 const char* label_str;
1232 const char* identity_key_str;
1233
1234 json_t *root;
1235 json_t *signature_json;
1236 json_t *ecdh_json;
1237 json_t *enc_meta_json;
1238 json_t *label_json;
1239 json_t *identity_json;
1240 json_error_t err_json;
1241 char* enc_meta;
1242 char* meta_str;
1243 char* token_code_decoded;
1244 size_t enc_meta_len;
1245
1246 GNUNET_STRINGS_base64_decode (token_code, strlen (token_code), &token_code_decoded);
1247 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Token Code: %s\n", token_code_decoded);
1248 root = json_loads (token_code_decoded, JSON_DECODE_ANY, &err_json);
1249 if (!root)
1250 {
1251 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1252 "%s\n", err_json.text);
1253 return GNUNET_SYSERR;
1254 }
1255
1256 signature_json = json_object_get (root, "signature");
1257 ecdh_json = json_object_get (root, "ecdh");
1258 enc_meta_json = json_object_get (root, "meta");
1259
1260 signature_enc_str = json_string_value (signature_json);
1261 ecdh_enc_str = json_string_value (ecdh_json);
1262 enc_meta_str = json_string_value (enc_meta_json);
1263 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (ecdh_enc_str,
1264 strlen (ecdh_enc_str),
1265 ecdhe_pkey,
1266 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)))
1267 {
1268 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH PKEY %s invalid in metadata\n", ecdh_enc_str);
1269 json_decref (root);
1270 return GNUNET_SYSERR;
1271 }
1272 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Using ECDH pubkey %s for metadata decryption\n", ecdh_enc_str);
1273 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (signature_enc_str,
1274 strlen (signature_enc_str),
1275 signature,
1276 sizeof (struct GNUNET_CRYPTO_EcdsaSignature)))
1277 {
1278 json_decref (root);
1279 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH signature invalid in metadata\n");
1280 return GNUNET_SYSERR;
1281 }
1282 enc_meta_len = GNUNET_STRINGS_base64_decode (enc_meta_str,
1283 strlen (enc_meta_str),
1284 &enc_meta);
1285
1286 if (GNUNET_OK != decrypt_meta_str (priv_key,
1287 ecdhe_pkey,
1288 enc_meta,
1289 enc_meta_len,
1290 signature,
1291 &meta_str))
1292 {
1293 GNUNET_free (enc_meta);
1294 json_decref(root);
1295 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Metadata decryption failed\n");
1296 return GNUNET_SYSERR;
1297 }
1298 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Metadata: %s\n", meta_str);
1299 json_decref (root);
1300 root = json_loads (meta_str, JSON_DECODE_ANY, &err_json);
1301 if (!root)
1302 {
1303 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1304 "Error parsing metadata: %s\n", err_json.text);
1305 GNUNET_free (enc_meta);
1306 return GNUNET_SYSERR;
1307 }
1308 label_json = json_object_get (root, "label");
1309 if (!json_is_string (label_json))
1310 {
1311 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1312 "Error parsing metadata: %s\n", err_json.text);
1313 json_decref (root);
1314 GNUNET_free (enc_meta);
1315 return GNUNET_SYSERR;
1316 }
1317
1318 label_str = json_string_value (label_json);
1319 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Found label: %s\n", label_str);
1320 GNUNET_asprintf (label, "%s", label_str);
1321
1322 identity_json = json_object_get (root, "identity");
1323 if (!json_is_string (identity_json))
1324 {
1325 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1326 "Error parsing metadata: %s\n", err_json.text);
1327 json_decref (root);
1328 GNUNET_free (enc_meta);
1329 return GNUNET_SYSERR;
1330 }
1331 identity_key_str = json_string_value (identity_json);
1332 GNUNET_STRINGS_string_to_data (identity_key_str,
1333 strlen (identity_key_str),
1334 id_pkey,
1335 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
1336
1337 GNUNET_free (enc_meta);
1338 json_decref (root);
1339 return GNUNET_OK;
1340
1341}
1342
1343
1041static void 1344static void
1042identity_master_cb (void *cls, 1345exchange_token_code_cb (void *cls,
1043 struct GNUNET_IDENTITY_Ego *ego, 1346 struct GNUNET_IDENTITY_Ego *ego,
1044 void **ctx, 1347 void **ctx,
1045 const char *name) 1348 const char *name)
1046{ 1349{
1350 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
1351
1047 struct GNUNET_CRYPTO_EcdsaPublicKey pkey; 1352 struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
1353 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
1354 struct GNUNET_CRYPTO_EcdsaSignature sig;
1355 struct GNUNET_CRYPTO_EcdhePublicKey echde_pkey;
1048 struct RequestHandle *handle = cls; 1356 struct RequestHandle *handle = cls;
1049 struct GNUNET_HashCode key; 1357 struct GNUNET_HashCode key;
1050 json_t *root;
1051 json_t *pkey_json;
1052 json_error_t err_json;
1053 const char* pkey_str;
1054 char* code; 1358 char* code;
1055 char* code_decoded; 1359 char* code_decoded;
1056 char * lookup_query; 1360 char* lookup_query;
1361 char* label;
1362 char* pub_key_str;
1057 1363
1058 handle->op = NULL; 1364 handle->op = NULL;
1059 1365
@@ -1064,8 +1370,8 @@ identity_master_cb (void *cls,
1064 return; 1370 return;
1065 } 1371 }
1066 1372
1067 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_OAUTH2_CODE, 1373 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_TOKEN_CODE,
1068 strlen (GNUNET_REST_JSONAPI_IDENTITY_OAUTH2_CODE), 1374 strlen (GNUNET_REST_JSONAPI_IDENTITY_TOKEN_CODE),
1069 &key); 1375 &key);
1070 1376
1071 if ( GNUNET_NO == 1377 if ( GNUNET_NO ==
@@ -1081,22 +1387,29 @@ identity_master_cb (void *cls,
1081 GNUNET_STRINGS_base64_decode (code, 1387 GNUNET_STRINGS_base64_decode (code,
1082 strlen (code), 1388 strlen (code),
1083 &code_decoded); 1389 &code_decoded);
1084 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1390
1085 "%s\n", code_decoded); 1391 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego);
1086 root = json_loads (code_decoded, JSON_DECODE_ANY, &err_json); 1392 GNUNET_IDENTITY_ego_get_public_key (ego, &pub_key);
1087 if (!root) 1393 pub_key_str = GNUNET_STRINGS_data_to_string_alloc (&pub_key, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
1394
1395 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Using private key corresponding to %s for ecdh\n", pub_key_str);
1396
1397 label = NULL;
1398
1399 if (GNUNET_SYSERR == extract_values_from_token_code (code,
1400 priv_key,
1401 &sig,
1402 &echde_pkey,
1403 &label,
1404 &pkey))
1088 { 1405 {
1089 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1406 handle->emsg = GNUNET_strdup ("Error extracting values from token code.");
1090 "%s\n", err_json.text); 1407 GNUNET_SCHEDULER_add_now (&do_error, handle);
1408 return;
1091 } 1409 }
1092 pkey_json = json_object_get (root, "identity"); 1410 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Looking for token under %s\n", label);
1093 pkey_str = json_string_value (pkey_json);
1094 GNUNET_CRYPTO_ecdsa_public_key_from_string (pkey_str,
1095 strlen (pkey_str),
1096 &pkey);
1097 json_decref (root);
1098 handle->gns_handle = GNUNET_GNS_connect (cfg); 1411 handle->gns_handle = GNUNET_GNS_connect (cfg);
1099 GNUNET_asprintf (&lookup_query, "%s.gnu", code); 1412 GNUNET_asprintf (&lookup_query, "%s.gnu", label);
1100 1413
1101 handle->lookup_request = GNUNET_GNS_lookup (handle->gns_handle, 1414 handle->lookup_request = GNUNET_GNS_lookup (handle->gns_handle,
1102 lookup_query, 1415 lookup_query,
@@ -1117,9 +1430,9 @@ identity_master_cb (void *cls,
1117 * @param cls the RequestHandle 1430 * @param cls the RequestHandle
1118 */ 1431 */
1119static void 1432static void
1120oauth_token_cont (struct RestConnectionDataHandle *con_handle, 1433exchange_token_code_cont (struct RestConnectionDataHandle *con_handle,
1121 const char* url, 1434 const char* url,
1122 void *cls) 1435 void *cls)
1123{ 1436{
1124 struct RequestHandle *handle = cls; 1437 struct RequestHandle *handle = cls;
1125 char* grant_type; 1438 char* grant_type;
@@ -1141,9 +1454,11 @@ oauth_token_cont (struct RestConnectionDataHandle *con_handle,
1141 //Get token from GNS 1454 //Get token from GNS
1142 handle->op = GNUNET_IDENTITY_get (handle->identity_handle, 1455 handle->op = GNUNET_IDENTITY_get (handle->identity_handle,
1143 "gns-master", 1456 "gns-master",
1144 &identity_master_cb, 1457 &exchange_token_code_cb,
1145 handle); 1458 handle);
1146 } 1459 }
1460
1461 //TODO fail here
1147} 1462}
1148 1463
1149/** 1464/**
@@ -1184,7 +1499,7 @@ init_cont (struct RequestHandle *handle)
1184 //{MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_TOKEN_CHECK, &check_token_cont}, 1499 //{MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_TOKEN_CHECK, &check_token_cont},
1185 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TOKEN, &list_token_cont}, 1500 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TOKEN, &list_token_cont},
1186 {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY_TOKEN, &options_cont}, 1501 {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY_TOKEN, &options_cont},
1187 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_OAUTH2_TOKEN, &oauth_token_cont}, 1502 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_OAUTH2_TOKEN, &exchange_token_code_cont},
1188 GNUNET_REST_HANDLER_END 1503 GNUNET_REST_HANDLER_END
1189 }; 1504 };
1190 1505
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h
index 33ad1af2b..2ec3b4d8d 100644
--- a/src/include/gnunet_crypto_lib.h
+++ b/src/include/gnunet_crypto_lib.h
@@ -1498,6 +1498,21 @@ GNUNET_CRYPTO_eddsa_ecdh (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
1498 const struct GNUNET_CRYPTO_EcdhePublicKey *pub, 1498 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
1499 struct GNUNET_HashCode *key_material); 1499 struct GNUNET_HashCode *key_material);
1500 1500
1501/**
1502 * @ingroup crypto
1503 * Derive key material from a ECDH public key and a private ECDSA key.
1504 * Dual to #GNUNET_CRRYPTO_ecdh_ecdsa.
1505 *
1506 * @param priv private key from ECDSA to use for the ECDH (x)
1507 * @param pub public key to use for the ECDH (yG)
1508 * @param key_material where to write the key material H(h(x)yG)
1509 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
1510 */
1511int
1512GNUNET_CRYPTO_ecdsa_ecdh (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
1513 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
1514 struct GNUNET_HashCode *key_material);
1515
1501 1516
1502/** 1517/**
1503 * @ingroup crypto 1518 * @ingroup crypto
@@ -1514,6 +1529,21 @@ GNUNET_CRYPTO_ecdh_eddsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1514 const struct GNUNET_CRYPTO_EddsaPublicKey *pub, 1529 const struct GNUNET_CRYPTO_EddsaPublicKey *pub,
1515 struct GNUNET_HashCode *key_material); 1530 struct GNUNET_HashCode *key_material);
1516 1531
1532/**
1533 * @ingroup crypto
1534 * Derive key material from a EcDSA public key and a private ECDH key.
1535 * Dual to #GNUNET_CRRYPTO_ecdsa_ecdh.
1536 *
1537 * @param priv private key to use for the ECDH (y)
1538 * @param pub public key from ECDSA to use for the ECDH (X=h(x)G)
1539 * @param key_material where to write the key material H(yX)=H(h(x)yG)
1540 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
1541 */
1542int
1543GNUNET_CRYPTO_ecdh_ecdsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1544 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
1545 struct GNUNET_HashCode *key_material);
1546
1517 1547
1518/** 1548/**
1519 * @ingroup crypto 1549 * @ingroup crypto
diff --git a/src/include/gnunet_signatures.h b/src/include/gnunet_signatures.h
index e9d5d05ed..dd6afbec5 100644
--- a/src/include/gnunet_signatures.h
+++ b/src/include/gnunet_signatures.h
@@ -181,7 +181,10 @@ extern "C"
181 */ 181 */
182#define GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN 26 182#define GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN 26
183 183
184 184/**
185 * Signature for a GNUid Token Reference
186 */
187#define GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN_CODE 27
185 188
186#if 0 /* keep Emacsens' auto-indent happy */ 189#if 0 /* keep Emacsens' auto-indent happy */
187{ 190{
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c
index bcc04fea5..c4e101369 100644
--- a/src/util/crypto_ecc.c
+++ b/src/util/crypto_ecc.c
@@ -1298,6 +1298,77 @@ GNUNET_CRYPTO_eddsa_ecdh (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
1298 return GNUNET_OK; 1298 return GNUNET_OK;
1299} 1299}
1300 1300
1301/**
1302 * @ingroup crypto
1303 * Derive key material from a ECDH public key and a private ECDSA key.
1304 * Dual to #GNUNET_CRRYPTO_ecdh_eddsa.
1305 *
1306 * @param priv private key from ECDSA to use for the ECDH (x)
1307 * @param pub public key to use for the ECDH (yG)
1308 * @param key_material where to write the key material H(h(x)yG)
1309 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
1310 */
1311int
1312GNUNET_CRYPTO_ecdsa_ecdh (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
1313 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
1314 struct GNUNET_HashCode *key_material)
1315{
1316 gcry_mpi_point_t result;
1317 gcry_mpi_point_t q;
1318 gcry_mpi_t d;
1319 gcry_ctx_t ctx;
1320 gcry_sexp_t pub_sexpr;
1321 gcry_mpi_t result_x;
1322 unsigned char xbuf[256 / 8];
1323 size_t rsize;
1324
1325 /* first, extract the q = dP value from the public key */
1326 if (0 != gcry_sexp_build (&pub_sexpr, NULL,
1327 "(public-key(ecc(curve " CURVE ")(q %b)))",
1328 (int)sizeof (pub->q_y), pub->q_y))
1329 return GNUNET_SYSERR;
1330 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
1331 gcry_sexp_release (pub_sexpr);
1332 q = gcry_mpi_ec_get_point ("q", ctx, 0);
1333
1334 /* second, extract the d value from our private key */
1335 GNUNET_CRYPTO_mpi_scan_unsigned (&d, priv->d, sizeof (priv->d));
1336
1337 /* then call the 'multiply' function, to compute the product */
1338 result = gcry_mpi_point_new (0);
1339 gcry_mpi_ec_mul (result, d, q, ctx);
1340 gcry_mpi_point_release (q);
1341 gcry_mpi_release (d);
1342
1343 /* finally, convert point to string for hashing */
1344 result_x = gcry_mpi_new (256);
1345 if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx))
1346 {
1347 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
1348 gcry_mpi_point_release (result);
1349 gcry_ctx_release (ctx);
1350 return GNUNET_SYSERR;
1351 }
1352 gcry_mpi_point_release (result);
1353 gcry_ctx_release (ctx);
1354
1355 rsize = sizeof (xbuf);
1356 GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
1357 /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
1358 as that does not include the sign bit; x should be a 255-bit
1359 value, so with the sign it should fit snugly into the 256-bit
1360 xbuf */
1361 GNUNET_assert (0 ==
1362 gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize,
1363 result_x));
1364 GNUNET_CRYPTO_hash (xbuf,
1365 rsize,
1366 key_material);
1367 gcry_mpi_release (result_x);
1368 return GNUNET_OK;
1369}
1370
1371
1301 1372
1302/** 1373/**
1303 * @ingroup crypto 1374 * @ingroup crypto
@@ -1369,6 +1440,24 @@ GNUNET_CRYPTO_ecdh_eddsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1369 return GNUNET_OK; 1440 return GNUNET_OK;
1370} 1441}
1371 1442
1372 1443/**
1444 * @ingroup crypto
1445 * Derive key material from a ECDSA public key and a private ECDH key.
1446 * Dual to #GNUNET_CRRYPTO_eddsa_ecdh.
1447 *
1448 * @param priv private key to use for the ECDH (y)
1449 * @param pub public key from ECDSA to use for the ECDH (X=h(x)G)
1450 * @param key_material where to write the key material H(yX)=H(h(x)yG)
1451 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
1452 */
1453int
1454GNUNET_CRYPTO_ecdh_ecdsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1455 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
1456 struct GNUNET_HashCode *key_material)
1457{
1458 return GNUNET_CRYPTO_ecdh_eddsa (priv,
1459 (const struct GNUNET_CRYPTO_EddsaPublicKey *)pub,
1460 key_material);
1461}
1373 1462
1374/* end of crypto_ecc.c */ 1463/* end of crypto_ecc.c */