diff options
author | Christian Fuchs <christian.fuchs@cfuchs.net> | 2013-09-17 10:15:12 +0000 |
---|---|---|
committer | Christian Fuchs <christian.fuchs@cfuchs.net> | 2013-09-17 10:15:12 +0000 |
commit | 16cb1e9317ff4456da1ee93f2c4cb7ee8ad14816 (patch) | |
tree | a6df83b9fcfacca33a96d6709a8a65f3abd5d8bb /src/scalarproduct | |
parent | 42a97ce7e8473b5e8fb31e05a9fa71bb32133982 (diff) | |
download | gnunet-16cb1e9317ff4456da1ee93f2c4cb7ee8ad14816.tar.gz gnunet-16cb1e9317ff4456da1ee93f2c4cb7ee8ad14816.zip |
scalar product service now terminates correctly again, an if got into the wrong loop.
Diffstat (limited to 'src/scalarproduct')
-rw-r--r-- | src/scalarproduct/gnunet-service-scalarproduct.c | 1449 |
1 files changed, 736 insertions, 713 deletions
diff --git a/src/scalarproduct/gnunet-service-scalarproduct.c b/src/scalarproduct/gnunet-service-scalarproduct.c index 7eac76c20..ebc953624 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct.c +++ b/src/scalarproduct/gnunet-service-scalarproduct.c | |||
@@ -44,14 +44,14 @@ | |||
44 | */ | 44 | */ |
45 | enum SessionState | 45 | enum SessionState |
46 | { | 46 | { |
47 | CLIENT_REQUEST_RECEIVED, | 47 | CLIENT_REQUEST_RECEIVED, |
48 | WAITING_FOR_BOBS_CONNECT, | 48 | WAITING_FOR_BOBS_CONNECT, |
49 | CLIENT_RESPONSE_RECEIVED, | 49 | CLIENT_RESPONSE_RECEIVED, |
50 | WAITING_FOR_SERVICE_REQUEST, | 50 | WAITING_FOR_SERVICE_REQUEST, |
51 | WAITING_FOR_SERVICE_RESPONSE, | 51 | WAITING_FOR_SERVICE_RESPONSE, |
52 | SERVICE_REQUEST_RECEIVED, | 52 | SERVICE_REQUEST_RECEIVED, |
53 | SERVICE_RESPONSE_RECEIVED, | 53 | SERVICE_RESPONSE_RECEIVED, |
54 | FINALIZED | 54 | FINALIZED |
55 | }; | 55 | }; |
56 | 56 | ||
57 | /** | 57 | /** |
@@ -59,11 +59,10 @@ enum SessionState | |||
59 | */ | 59 | */ |
60 | enum PeerRole | 60 | enum PeerRole |
61 | { | 61 | { |
62 | ALICE, | 62 | ALICE, |
63 | BOB | 63 | BOB |
64 | }; | 64 | }; |
65 | 65 | ||
66 | |||
67 | /** | 66 | /** |
68 | * A scalarproduct session which tracks: | 67 | * A scalarproduct session which tracks: |
69 | * | 68 | * |
@@ -73,105 +72,105 @@ enum PeerRole | |||
73 | */ | 72 | */ |
74 | struct ServiceSession | 73 | struct ServiceSession |
75 | { | 74 | { |
76 | /** | 75 | /** |
77 | * the role this peer has | 76 | * the role this peer has |
78 | */ | 77 | */ |
79 | enum PeerRole role; | 78 | enum PeerRole role; |
80 | 79 | ||
81 | /** | 80 | /** |
82 | * session information is kept in a DLL | 81 | * session information is kept in a DLL |
83 | */ | 82 | */ |
84 | struct ServiceSession *next; | 83 | struct ServiceSession *next; |
85 | 84 | ||
86 | /** | 85 | /** |
87 | * session information is kept in a DLL | 86 | * session information is kept in a DLL |
88 | */ | 87 | */ |
89 | struct ServiceSession *prev; | 88 | struct ServiceSession *prev; |
90 | 89 | ||
91 | /** | 90 | /** |
92 | * (hopefully) unique transaction ID | 91 | * (hopefully) unique transaction ID |
93 | */ | 92 | */ |
94 | struct GNUNET_HashCode key; | 93 | struct GNUNET_HashCode key; |
95 | 94 | ||
96 | /** | 95 | /** |
97 | * state of the session | 96 | * state of the session |
98 | */ | 97 | */ |
99 | enum SessionState state; | 98 | enum SessionState state; |
100 | 99 | ||
101 | /** | 100 | /** |
102 | * Alice or Bob's peerID | 101 | * Alice or Bob's peerID |
103 | */ | 102 | */ |
104 | struct GNUNET_PeerIdentity peer; | 103 | struct GNUNET_PeerIdentity peer; |
105 | 104 | ||
106 | /** | 105 | /** |
107 | * the client this request is related to | 106 | * the client this request is related to |
108 | */ | 107 | */ |
109 | struct GNUNET_SERVER_Client * client; | 108 | struct GNUNET_SERVER_Client * client; |
110 | 109 | ||
111 | /** | 110 | /** |
112 | * The message to send | 111 | * The message to send |
113 | */ | 112 | */ |
114 | struct GNUNET_MessageHeader * msg; | 113 | struct GNUNET_MessageHeader * msg; |
115 | 114 | ||
116 | /** | 115 | /** |
117 | * how many elements we were supplied with from the client | 116 | * how many elements we were supplied with from the client |
118 | */ | 117 | */ |
119 | uint32_t element_count; | 118 | uint32_t element_count; |
120 | 119 | ||
121 | /** | 120 | /** |
122 | * how many elements actually are used after applying the mask | 121 | * how many elements actually are used after applying the mask |
123 | */ | 122 | */ |
124 | uint32_t used_element_count; | 123 | uint32_t used_element_count; |
125 | 124 | ||
126 | /** | 125 | /** |
127 | * how many bytes the mask is long. | 126 | * how many bytes the mask is long. |
128 | * just for convenience so we don't have to re-re-re calculate it each time | 127 | * just for convenience so we don't have to re-re-re calculate it each time |
129 | */ | 128 | */ |
130 | uint32_t mask_length; | 129 | uint32_t mask_length; |
131 | 130 | ||
132 | /** | 131 | /** |
133 | * all the vector elements we received | 132 | * all the vector elements we received |
134 | */ | 133 | */ |
135 | int32_t * vector; | 134 | int32_t * vector; |
136 | 135 | ||
137 | /** | 136 | /** |
138 | * mask of which elements to check | 137 | * mask of which elements to check |
139 | */ | 138 | */ |
140 | unsigned char * mask; | 139 | unsigned char * mask; |
141 | 140 | ||
142 | /** | 141 | /** |
143 | * Public key of the remote service, only used by bob | 142 | * Public key of the remote service, only used by bob |
144 | */ | 143 | */ |
145 | gcry_sexp_t remote_pubkey; | 144 | gcry_sexp_t remote_pubkey; |
146 | 145 | ||
147 | /** | 146 | /** |
148 | * E(ai)(Bob) or ai(Alice) after applying the mask | 147 | * E(ai)(Bob) or ai(Alice) after applying the mask |
149 | */ | 148 | */ |
150 | gcry_mpi_t * a; | 149 | gcry_mpi_t * a; |
151 | 150 | ||
152 | /** | 151 | /** |
153 | * The computed scalar | 152 | * The computed scalar |
154 | */ | 153 | */ |
155 | gcry_mpi_t product; | 154 | gcry_mpi_t product; |
156 | 155 | ||
157 | /** | 156 | /** |
158 | * My transmit handle for the current message to a alice/bob | 157 | * My transmit handle for the current message to a alice/bob |
159 | */ | 158 | */ |
160 | struct GNUNET_MESH_TransmitHandle * service_transmit_handle; | 159 | struct GNUNET_MESH_TransmitHandle * service_transmit_handle; |
161 | 160 | ||
162 | /** | 161 | /** |
163 | * My transmit handle for the current message to the client | 162 | * My transmit handle for the current message to the client |
164 | */ | 163 | */ |
165 | struct GNUNET_SERVER_TransmitHandle * client_transmit_handle; | 164 | struct GNUNET_SERVER_TransmitHandle * client_transmit_handle; |
166 | 165 | ||
167 | /** | 166 | /** |
168 | * tunnel-handle associated with our mesh handle | 167 | * tunnel-handle associated with our mesh handle |
169 | */ | 168 | */ |
170 | struct GNUNET_MESH_Tunnel * tunnel; | 169 | struct GNUNET_MESH_Tunnel * tunnel; |
171 | 170 | ||
172 | GNUNET_SCHEDULER_TaskIdentifier client_notification_task; | 171 | GNUNET_SCHEDULER_TaskIdentifier client_notification_task; |
173 | 172 | ||
174 | GNUNET_SCHEDULER_TaskIdentifier service_request_task; | 173 | GNUNET_SCHEDULER_TaskIdentifier service_request_task; |
175 | }; | 174 | }; |
176 | 175 | ||
177 | /////////////////////////////////////////////////////////////////////////////// | 176 | /////////////////////////////////////////////////////////////////////////////// |
@@ -265,6 +264,7 @@ static int do_shutdown; | |||
265 | // Helper Functions | 264 | // Helper Functions |
266 | /////////////////////////////////////////////////////////////////////////////// | 265 | /////////////////////////////////////////////////////////////////////////////// |
267 | 266 | ||
267 | |||
268 | /** | 268 | /** |
269 | * Generates an Paillier private/public keyset and extracts the values using libgrcypt only | 269 | * Generates an Paillier private/public keyset and extracts the values using libgrcypt only |
270 | */ | 270 | */ |
@@ -324,27 +324,27 @@ generate_keyset () | |||
324 | // generate a g | 324 | // generate a g |
325 | gcry_mpi_mul (my_nsquare, my_n, my_n); | 325 | gcry_mpi_mul (my_nsquare, my_n, my_n); |
326 | do | 326 | do |
327 | { | ||
328 | // find a matching g | ||
329 | do | ||
327 | { | 330 | { |
328 | // find a matching g | 331 | gcry_mpi_randomize (my_g, KEYBITS * 2, GCRY_WEAK_RANDOM); |
329 | do | 332 | // g must be smaller than n^2 |
330 | { | 333 | if (0 >= gcry_mpi_cmp (my_g, my_nsquare)) |
331 | gcry_mpi_randomize (my_g, KEYBITS * 2, GCRY_WEAK_RANDOM); | 334 | continue; |
332 | // g must be smaller than n^2 | 335 | |
333 | if (0 >= gcry_mpi_cmp (my_g, my_nsquare)) | 336 | // g must have gcd == 1 with n^2 |
334 | continue; | 337 | gcry_mpi_gcd (gcd, my_g, my_nsquare); |
335 | |||
336 | // g must have gcd == 1 with n^2 | ||
337 | gcry_mpi_gcd (gcd, my_g, my_nsquare); | ||
338 | } | ||
339 | while (gcry_mpi_cmp_ui (gcd, 1)); | ||
340 | |||
341 | // is this a valid g? | ||
342 | // if so, gcd(((g^lambda mod n^2)-1 )/n, n) = 1 | ||
343 | gcry_mpi_powm (tmp1, my_g, my_lambda, my_nsquare); | ||
344 | gcry_mpi_sub_ui (tmp1, tmp1, 1); | ||
345 | gcry_mpi_div (tmp1, NULL, tmp1, my_n, 0); | ||
346 | gcry_mpi_gcd (gcd, tmp1, my_n); | ||
347 | } | 338 | } |
339 | while (gcry_mpi_cmp_ui (gcd, 1)); | ||
340 | |||
341 | // is this a valid g? | ||
342 | // if so, gcd(((g^lambda mod n^2)-1 )/n, n) = 1 | ||
343 | gcry_mpi_powm (tmp1, my_g, my_lambda, my_nsquare); | ||
344 | gcry_mpi_sub_ui (tmp1, tmp1, 1); | ||
345 | gcry_mpi_div (tmp1, NULL, tmp1, my_n, 0); | ||
346 | gcry_mpi_gcd (gcd, tmp1, my_n); | ||
347 | } | ||
348 | while (gcry_mpi_cmp_ui (gcd, 1)); | 348 | while (gcry_mpi_cmp_ui (gcd, 1)); |
349 | 349 | ||
350 | // calculate our mu based on g and n. | 350 | // calculate our mu based on g and n. |
@@ -371,12 +371,12 @@ generate_keyset () | |||
371 | my_pubkey_external_length); | 371 | my_pubkey_external_length); |
372 | 372 | ||
373 | gcry_sexp_release (key); | 373 | gcry_sexp_release (key); |
374 | 374 | ||
375 | // offset has to be sufficiently small to allow computation of: | 375 | // offset has to be sufficiently small to allow computation of: |
376 | // m1+m2 mod n == (S + a) + (S + b) mod n, | 376 | // m1+m2 mod n == (S + a) + (S + b) mod n, |
377 | // if we have more complex operations, this factor needs to be lowered | 377 | // if we have more complex operations, this factor needs to be lowered |
378 | my_offset = gcry_mpi_new(KEYBITS/3); | 378 | my_offset = gcry_mpi_new (KEYBITS / 3); |
379 | gcry_mpi_set_bit(my_offset, KEYBITS/3); | 379 | gcry_mpi_set_bit (my_offset, KEYBITS / 3); |
380 | 380 | ||
381 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Generated key set with key length %d bits.\n"), KEYBITS); | 381 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Generated key set with key length %d bits.\n"), KEYBITS); |
382 | } | 382 | } |
@@ -395,10 +395,10 @@ static void | |||
395 | adjust (unsigned char *buf, size_t size, size_t target) | 395 | adjust (unsigned char *buf, size_t size, size_t target) |
396 | { | 396 | { |
397 | if (size < target) | 397 | if (size < target) |
398 | { | 398 | { |
399 | memmove (&buf[target - size], buf, size); | 399 | memmove (&buf[target - size], buf, size); |
400 | memset (buf, 0, target - size); | 400 | memset (buf, 0, target - size); |
401 | } | 401 | } |
402 | } | 402 | } |
403 | 403 | ||
404 | 404 | ||
@@ -419,10 +419,10 @@ encrypt_element (gcry_mpi_t c, gcry_mpi_t m, gcry_mpi_t g, gcry_mpi_t n, gcry_mp | |||
419 | GNUNET_assert (tmp = gcry_mpi_new (0)); | 419 | GNUNET_assert (tmp = gcry_mpi_new (0)); |
420 | 420 | ||
421 | while (0 >= gcry_mpi_cmp_ui (tmp, 1)) | 421 | while (0 >= gcry_mpi_cmp_ui (tmp, 1)) |
422 | { | 422 | { |
423 | gcry_mpi_randomize (tmp, KEYBITS / 3, GCRY_WEAK_RANDOM); | 423 | gcry_mpi_randomize (tmp, KEYBITS / 3, GCRY_WEAK_RANDOM); |
424 | // r must be 1 < r < n | 424 | // r must be 1 < r < n |
425 | } | 425 | } |
426 | 426 | ||
427 | gcry_mpi_powm (c, g, m, n_square); | 427 | gcry_mpi_powm (c, g, m, n_square); |
428 | gcry_mpi_powm (tmp, tmp, n, n_square); | 428 | gcry_mpi_powm (tmp, tmp, n, n_square); |
@@ -431,6 +431,7 @@ encrypt_element (gcry_mpi_t c, gcry_mpi_t m, gcry_mpi_t g, gcry_mpi_t n, gcry_mp | |||
431 | gcry_mpi_release (tmp); | 431 | gcry_mpi_release (tmp); |
432 | } | 432 | } |
433 | 433 | ||
434 | |||
434 | /** | 435 | /** |
435 | * decrypts an element using the paillier crypto system | 436 | * decrypts an element using the paillier crypto system |
436 | * | 437 | * |
@@ -470,10 +471,10 @@ compute_square_sum (gcry_mpi_t * vector, uint32_t length) | |||
470 | 471 | ||
471 | // calculare E(sum (ai ^ 2), publickey) | 472 | // calculare E(sum (ai ^ 2), publickey) |
472 | for (i = 0; i < length; i++) | 473 | for (i = 0; i < length; i++) |
473 | { | 474 | { |
474 | gcry_mpi_mul (elem, vector[i], vector[i]); | 475 | gcry_mpi_mul (elem, vector[i], vector[i]); |
475 | gcry_mpi_add (sum, sum, elem); | 476 | gcry_mpi_add (sum, sum, elem); |
476 | } | 477 | } |
477 | gcry_mpi_release (elem); | 478 | gcry_mpi_release (elem); |
478 | 479 | ||
479 | return sum; | 480 | return sum; |
@@ -499,26 +500,27 @@ do_send_message (void *cls, size_t size, void *buf) | |||
499 | GNUNET_assert (buf); | 500 | GNUNET_assert (buf); |
500 | 501 | ||
501 | if (ntohs (session->msg->size) == size) | 502 | if (ntohs (session->msg->size) == size) |
502 | { | 503 | { |
503 | memcpy (buf, session->msg, size); | 504 | memcpy (buf, session->msg, size); |
504 | written = size; | 505 | written = size; |
505 | } | 506 | } |
506 | 507 | ||
507 | switch (ntohs(session->msg->type)){ | 508 | switch (ntohs (session->msg->type)) |
508 | case GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SERVICE_TO_CLIENT: | 509 | { |
509 | session->state = FINALIZED; | 510 | case GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SERVICE_TO_CLIENT: |
510 | session->client_transmit_handle = NULL; | 511 | session->state = FINALIZED; |
511 | break; | 512 | session->client_transmit_handle = NULL; |
512 | default: | 513 | break; |
513 | session->service_transmit_handle = NULL; | 514 | default: |
514 | } | 515 | session->service_transmit_handle = NULL; |
515 | 516 | } | |
516 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 517 | |
517 | "Sent a message of type %hu.\n", | 518 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
518 | ntohs (session->msg->type)); | 519 | "Sent a message of type %hu.\n", |
519 | GNUNET_free(session->msg); | 520 | ntohs (session->msg->type)); |
521 | GNUNET_free (session->msg); | ||
520 | session->msg = NULL; | 522 | session->msg = NULL; |
521 | 523 | ||
522 | return written; | 524 | return written; |
523 | } | 525 | } |
524 | 526 | ||
@@ -585,17 +587,17 @@ generate_random_vector (uint32_t length) | |||
585 | 587 | ||
586 | random_vector = initialize_mpi_vector (length); | 588 | random_vector = initialize_mpi_vector (length); |
587 | for (i = 0; i < length; i++) | 589 | for (i = 0; i < length; i++) |
588 | { | 590 | { |
589 | value = (int32_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX); | 591 | value = (int32_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX); |
590 | 592 | ||
591 | // long to gcry_mpi_t | 593 | // long to gcry_mpi_t |
592 | if (value < 0) | 594 | if (value < 0) |
593 | gcry_mpi_sub_ui (random_vector[i], | 595 | gcry_mpi_sub_ui (random_vector[i], |
594 | random_vector[i], | 596 | random_vector[i], |
595 | -value); | 597 | -value); |
596 | else | 598 | else |
597 | random_vector[i] = gcry_mpi_set_ui (random_vector[i], value); | 599 | random_vector[i] = gcry_mpi_set_ui (random_vector[i], value); |
598 | } | 600 | } |
599 | 601 | ||
600 | return random_vector; | 602 | return random_vector; |
601 | } | 603 | } |
@@ -620,22 +622,22 @@ find_matching_session (struct ServiceSession * tail, | |||
620 | struct ServiceSession * curr; | 622 | struct ServiceSession * curr; |
621 | 623 | ||
622 | for (curr = tail; NULL != curr; curr = curr->prev) | 624 | for (curr = tail; NULL != curr; curr = curr->prev) |
625 | { | ||
626 | // if the key matches, and the element_count is same | ||
627 | if ((!memcmp (&curr->key, key, sizeof (struct GNUNET_HashCode))) | ||
628 | && (curr->element_count == element_count)) | ||
623 | { | 629 | { |
624 | // if the key matches, and the element_count is same | 630 | // if incoming state is NULL OR is same as state of the queued request |
625 | if ((!memcmp (&curr->key, key, sizeof (struct GNUNET_HashCode))) | 631 | if ((NULL == state) || (curr->state == *state)) |
626 | && (curr->element_count == element_count)) | 632 | { |
627 | { | 633 | // if peerid is NULL OR same as the peer Id in the queued request |
628 | // if incoming state is NULL OR is same as state of the queued request | 634 | if ((NULL == peerid) |
629 | if ((NULL == state) || (curr->state == *state)) | 635 | || (!memcmp (&curr->peer, peerid, sizeof (struct GNUNET_PeerIdentity)))) |
630 | { | 636 | // matches and is not an already terminated session |
631 | // if peerid is NULL OR same as the peer Id in the queued request | 637 | return curr; |
632 | if ((NULL == peerid) | 638 | } |
633 | || (!memcmp (&curr->peer, peerid, sizeof (struct GNUNET_PeerIdentity)))) | ||
634 | // matches and is not an already terminated session | ||
635 | return curr; | ||
636 | } | ||
637 | } | ||
638 | } | 639 | } |
640 | } | ||
639 | 641 | ||
640 | return NULL; | 642 | return NULL; |
641 | } | 643 | } |
@@ -666,6 +668,7 @@ free_session (struct ServiceSession * session) | |||
666 | // Event and Message Handlers | 668 | // Event and Message Handlers |
667 | /////////////////////////////////////////////////////////////////////////////// | 669 | /////////////////////////////////////////////////////////////////////////////// |
668 | 670 | ||
671 | |||
669 | /** | 672 | /** |
670 | * A client disconnected. | 673 | * A client disconnected. |
671 | * | 674 | * |
@@ -681,39 +684,39 @@ handle_client_disconnect (void *cls, | |||
681 | struct GNUNET_SERVER_Client *client) | 684 | struct GNUNET_SERVER_Client *client) |
682 | { | 685 | { |
683 | struct ServiceSession *session; | 686 | struct ServiceSession *session; |
684 | 687 | ||
685 | if (client == NULL) | 688 | if (client == NULL) |
686 | return; | 689 | return; |
687 | session = GNUNET_SERVER_client_get_user_context (client, struct ServiceSession); | 690 | session = GNUNET_SERVER_client_get_user_context (client, struct ServiceSession); |
688 | if (NULL == session) | 691 | if (NULL == session) |
689 | return; | 692 | return; |
690 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 693 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
691 | _ ("Client (%p) disconnected from us.\n"), client); | 694 | _ ("Client (%p) disconnected from us.\n"), client); |
692 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session); | 695 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session); |
693 | 696 | ||
694 | if (!(session->role == BOB && session->state == FINALIZED)) | 697 | if (!(session->role == BOB && session->state == FINALIZED)) |
695 | { | 698 | { |
696 | //we MUST terminate any client message underway | 699 | //we MUST terminate any client message underway |
697 | if (session->service_transmit_handle && session->tunnel) | 700 | if (session->service_transmit_handle && session->tunnel) |
698 | GNUNET_MESH_notify_transmit_ready_cancel (session->service_transmit_handle); | 701 | GNUNET_MESH_notify_transmit_ready_cancel (session->service_transmit_handle); |
699 | if (session->tunnel && session->state == WAITING_FOR_SERVICE_RESPONSE) | 702 | if (session->tunnel && session->state == WAITING_FOR_SERVICE_RESPONSE) |
700 | GNUNET_MESH_tunnel_destroy (session->tunnel); | 703 | GNUNET_MESH_tunnel_destroy (session->tunnel); |
701 | } | 704 | } |
702 | if (GNUNET_SCHEDULER_NO_TASK != session->client_notification_task) | 705 | if (GNUNET_SCHEDULER_NO_TASK != session->client_notification_task) |
703 | { | 706 | { |
704 | GNUNET_SCHEDULER_cancel (session->client_notification_task); | 707 | GNUNET_SCHEDULER_cancel (session->client_notification_task); |
705 | session->client_notification_task = GNUNET_SCHEDULER_NO_TASK; | 708 | session->client_notification_task = GNUNET_SCHEDULER_NO_TASK; |
706 | } | 709 | } |
707 | if (GNUNET_SCHEDULER_NO_TASK != session->service_request_task) | 710 | if (GNUNET_SCHEDULER_NO_TASK != session->service_request_task) |
708 | { | 711 | { |
709 | GNUNET_SCHEDULER_cancel (session->service_request_task); | 712 | GNUNET_SCHEDULER_cancel (session->service_request_task); |
710 | session->service_request_task = GNUNET_SCHEDULER_NO_TASK; | 713 | session->service_request_task = GNUNET_SCHEDULER_NO_TASK; |
711 | } | 714 | } |
712 | if (NULL != session->client_transmit_handle) | 715 | if (NULL != session->client_transmit_handle) |
713 | { | 716 | { |
714 | GNUNET_SERVER_notify_transmit_ready_cancel (session->client_transmit_handle); | 717 | GNUNET_SERVER_notify_transmit_ready_cancel (session->client_transmit_handle); |
715 | session->client_transmit_handle = NULL; | 718 | session->client_transmit_handle = NULL; |
716 | } | 719 | } |
717 | free_session (session); | 720 | free_session (session); |
718 | } | 721 | } |
719 | 722 | ||
@@ -734,7 +737,7 @@ prepare_client_end_notification (void * cls, | |||
734 | { | 737 | { |
735 | struct ServiceSession * session = cls; | 738 | struct ServiceSession * session = cls; |
736 | struct GNUNET_SCALARPRODUCT_client_response * msg; | 739 | struct GNUNET_SCALARPRODUCT_client_response * msg; |
737 | 740 | ||
738 | session->client_notification_task = GNUNET_SCHEDULER_NO_TASK; | 741 | session->client_notification_task = GNUNET_SCHEDULER_NO_TASK; |
739 | 742 | ||
740 | msg = GNUNET_new (struct GNUNET_SCALARPRODUCT_client_response); | 743 | msg = GNUNET_new (struct GNUNET_SCALARPRODUCT_client_response); |
@@ -744,8 +747,8 @@ prepare_client_end_notification (void * cls, | |||
744 | msg->header.size = htons (sizeof (struct GNUNET_SCALARPRODUCT_client_response)); | 747 | msg->header.size = htons (sizeof (struct GNUNET_SCALARPRODUCT_client_response)); |
745 | // signal error if not signalized, positive result-range field but zero length. | 748 | // signal error if not signalized, positive result-range field but zero length. |
746 | msg->product_length = htonl (0); | 749 | msg->product_length = htonl (0); |
747 | msg->range = (session->state == FINALIZED)? 0 : -1; | 750 | msg->range = (session->state == FINALIZED) ? 0 : -1; |
748 | 751 | ||
749 | session->msg = &msg->header; | 752 | session->msg = &msg->header; |
750 | 753 | ||
751 | //transmit this message to our client | 754 | //transmit this message to our client |
@@ -757,16 +760,16 @@ prepare_client_end_notification (void * cls, | |||
757 | session); | 760 | session); |
758 | 761 | ||
759 | // if we could not even queue our request, something is wrong | 762 | // if we could not even queue our request, something is wrong |
760 | if ( NULL == session->client_transmit_handle) | 763 | if (NULL == session->client_transmit_handle) |
761 | { | 764 | { |
762 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Could not send message to client (%p)!\n"), session->client); | 765 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Could not send message to client (%p)!\n"), session->client); |
763 | // usually gets freed by do_send_message | 766 | // usually gets freed by do_send_message |
764 | session->msg = NULL; | 767 | session->msg = NULL; |
765 | GNUNET_free (msg); | 768 | GNUNET_free (msg); |
766 | } | 769 | } |
767 | else | 770 | else |
768 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Sending session-end notification to client (%p) for session %s\n"), &session->client, GNUNET_h2s (&session->key)); | 771 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Sending session-end notification to client (%p) for session %s\n"), &session->client, GNUNET_h2s (&session->key)); |
769 | 772 | ||
770 | } | 773 | } |
771 | 774 | ||
772 | 775 | ||
@@ -848,58 +851,58 @@ prepare_service_response (gcry_mpi_t * r, | |||
848 | 851 | ||
849 | // convert kp[] | 852 | // convert kp[] |
850 | for (i = 0; i < request->used_element_count; i++) | 853 | for (i = 0; i < request->used_element_count; i++) |
851 | { | 854 | { |
852 | element_exported = GNUNET_malloc (PAILLIER_ELEMENT_LENGTH); | 855 | element_exported = GNUNET_malloc (PAILLIER_ELEMENT_LENGTH); |
853 | GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, | 856 | GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, |
854 | element_exported, PAILLIER_ELEMENT_LENGTH, | 857 | element_exported, PAILLIER_ELEMENT_LENGTH, |
855 | &element_length, | 858 | &element_length, |
856 | r[i])); | 859 | r[i])); |
857 | adjust (element_exported, element_length, PAILLIER_ELEMENT_LENGTH); | 860 | adjust (element_exported, element_length, PAILLIER_ELEMENT_LENGTH); |
858 | memcpy (current, element_exported, PAILLIER_ELEMENT_LENGTH); | 861 | memcpy (current, element_exported, PAILLIER_ELEMENT_LENGTH); |
859 | GNUNET_free (element_exported); | 862 | GNUNET_free (element_exported); |
860 | current += PAILLIER_ELEMENT_LENGTH; | 863 | current += PAILLIER_ELEMENT_LENGTH; |
861 | } | 864 | } |
862 | 865 | ||
863 | 866 | ||
864 | // convert kq[] | 867 | // convert kq[] |
865 | for (i = 0; i < request->used_element_count; i++) | 868 | for (i = 0; i < request->used_element_count; i++) |
866 | { | 869 | { |
867 | element_exported = GNUNET_malloc (PAILLIER_ELEMENT_LENGTH); | 870 | element_exported = GNUNET_malloc (PAILLIER_ELEMENT_LENGTH); |
868 | GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, | 871 | GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, |
869 | element_exported, PAILLIER_ELEMENT_LENGTH, | 872 | element_exported, PAILLIER_ELEMENT_LENGTH, |
870 | &element_length, | 873 | &element_length, |
871 | r_prime[i])); | 874 | r_prime[i])); |
872 | adjust (element_exported, element_length, PAILLIER_ELEMENT_LENGTH); | 875 | adjust (element_exported, element_length, PAILLIER_ELEMENT_LENGTH); |
873 | memcpy (current, element_exported, PAILLIER_ELEMENT_LENGTH); | 876 | memcpy (current, element_exported, PAILLIER_ELEMENT_LENGTH); |
874 | GNUNET_free (element_exported); | 877 | GNUNET_free (element_exported); |
875 | current += PAILLIER_ELEMENT_LENGTH; | 878 | current += PAILLIER_ELEMENT_LENGTH; |
876 | } | 879 | } |
877 | 880 | ||
878 | if (GNUNET_SERVER_MAX_MESSAGE_SIZE >= msg_length) | 881 | if (GNUNET_SERVER_MAX_MESSAGE_SIZE >= msg_length) |
879 | { | 882 | { |
880 | request->msg = (struct GNUNET_MessageHeader *) msg; | 883 | request->msg = (struct GNUNET_MessageHeader *) msg; |
881 | request->service_transmit_handle = | 884 | request->service_transmit_handle = |
882 | GNUNET_MESH_notify_transmit_ready (request->tunnel, | 885 | GNUNET_MESH_notify_transmit_ready (request->tunnel, |
883 | GNUNET_YES, | 886 | GNUNET_YES, |
884 | GNUNET_TIME_UNIT_FOREVER_REL, | 887 | GNUNET_TIME_UNIT_FOREVER_REL, |
885 | msg_length, | 888 | msg_length, |
886 | &do_send_message, | 889 | &do_send_message, |
887 | request); | 890 | request); |
888 | request->state = FINALIZED; | 891 | request->state = FINALIZED; |
889 | } | 892 | } |
890 | else | 893 | else |
891 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Message too large, fragmentation is currently not supported!)\n")); | 894 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Message too large, fragmentation is currently not supported!)\n")); |
892 | 895 | ||
893 | //disconnect our client | 896 | //disconnect our client |
894 | if ( NULL == request->service_transmit_handle) | 897 | if (NULL == request->service_transmit_handle) |
895 | { | 898 | { |
896 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Could not send service-response message via mesh!)\n")); | 899 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Could not send service-response message via mesh!)\n")); |
897 | 900 | ||
898 | response->client_notification_task = | 901 | response->client_notification_task = |
899 | GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, | 902 | GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, |
900 | response); | 903 | response); |
901 | return GNUNET_NO; | 904 | return GNUNET_NO; |
902 | } | 905 | } |
903 | return GNUNET_OK; | 906 | return GNUNET_OK; |
904 | } | 907 | } |
905 | 908 | ||
@@ -955,61 +958,61 @@ compute_service_response (struct ServiceSession * request, | |||
955 | 958 | ||
956 | // convert responder session to from long to mpi | 959 | // convert responder session to from long to mpi |
957 | for (i = 0, j = 0; i < response->element_count && j < count; i++) | 960 | for (i = 0, j = 0; i < response->element_count && j < count; i++) |
961 | { | ||
962 | if (request->mask[i / 8] & (1 << (i % 8))) | ||
958 | { | 963 | { |
959 | if (request->mask[i / 8] & (1 << (i % 8))) | 964 | value = response->vector[i] >= 0 ? response->vector[i] : -response->vector[i]; |
960 | { | 965 | // long to gcry_mpi_t |
961 | value = response->vector[i] >= 0 ? response->vector[i] : -response->vector[i]; | 966 | if (0 > response->vector[i]) |
962 | // long to gcry_mpi_t | 967 | { |
963 | if (0 > response->vector[i]) | 968 | b[j] = gcry_mpi_new (0); |
964 | { | 969 | gcry_mpi_sub_ui (b[j], b[j], value); |
965 | b[j] = gcry_mpi_new (0); | 970 | } |
966 | gcry_mpi_sub_ui (b[j], b[j], value); | 971 | else |
967 | } | 972 | { |
968 | else | 973 | b[j] = gcry_mpi_set_ui (NULL, value); |
969 | { | 974 | } |
970 | b[j] = gcry_mpi_set_ui (NULL, value); | 975 | j++; |
971 | } | ||
972 | j++; | ||
973 | } | ||
974 | } | 976 | } |
977 | } | ||
975 | GNUNET_free (response->vector); | 978 | GNUNET_free (response->vector); |
976 | response->vector = NULL; | 979 | response->vector = NULL; |
977 | 980 | ||
978 | tmp_exp = gcry_sexp_find_token (request->remote_pubkey, "n", 0); | 981 | tmp_exp = gcry_sexp_find_token (request->remote_pubkey, "n", 0); |
979 | if ( ! tmp_exp) | 982 | if (!tmp_exp) |
980 | { | 983 | { |
981 | GNUNET_break_op (0); | 984 | GNUNET_break_op (0); |
982 | gcry_sexp_release (request->remote_pubkey); | 985 | gcry_sexp_release (request->remote_pubkey); |
983 | request->remote_pubkey = NULL; | 986 | request->remote_pubkey = NULL; |
984 | goto except; | 987 | goto except; |
985 | } | 988 | } |
986 | remote_n = gcry_sexp_nth_mpi (tmp_exp, 1, GCRYMPI_FMT_USG); | 989 | remote_n = gcry_sexp_nth_mpi (tmp_exp, 1, GCRYMPI_FMT_USG); |
987 | if ( ! remote_n) | 990 | if (!remote_n) |
988 | { | 991 | { |
989 | GNUNET_break (0); | 992 | GNUNET_break (0); |
990 | gcry_sexp_release (tmp_exp); | 993 | gcry_sexp_release (tmp_exp); |
991 | goto except; | 994 | goto except; |
992 | } | 995 | } |
993 | remote_nsquare = gcry_mpi_new (KEYBITS + 1); | 996 | remote_nsquare = gcry_mpi_new (KEYBITS + 1); |
994 | gcry_mpi_mul (remote_nsquare, remote_n, remote_n); | 997 | gcry_mpi_mul (remote_nsquare, remote_n, remote_n); |
995 | gcry_sexp_release (tmp_exp); | 998 | gcry_sexp_release (tmp_exp); |
996 | tmp_exp = gcry_sexp_find_token (request->remote_pubkey, "g", 0); | 999 | tmp_exp = gcry_sexp_find_token (request->remote_pubkey, "g", 0); |
997 | gcry_sexp_release (request->remote_pubkey); | 1000 | gcry_sexp_release (request->remote_pubkey); |
998 | request->remote_pubkey = NULL; | 1001 | request->remote_pubkey = NULL; |
999 | if ( ! tmp_exp) | 1002 | if (!tmp_exp) |
1000 | { | 1003 | { |
1001 | GNUNET_break_op (0); | 1004 | GNUNET_break_op (0); |
1002 | gcry_mpi_release (remote_n); | 1005 | gcry_mpi_release (remote_n); |
1003 | goto except; | 1006 | goto except; |
1004 | } | 1007 | } |
1005 | remote_g = gcry_sexp_nth_mpi (tmp_exp, 1, GCRYMPI_FMT_USG); | 1008 | remote_g = gcry_sexp_nth_mpi (tmp_exp, 1, GCRYMPI_FMT_USG); |
1006 | if ( ! remote_g) | 1009 | if (!remote_g) |
1007 | { | 1010 | { |
1008 | GNUNET_break (0); | 1011 | GNUNET_break (0); |
1009 | gcry_mpi_release (remote_n); | 1012 | gcry_mpi_release (remote_n); |
1010 | gcry_sexp_release (tmp_exp); | 1013 | gcry_sexp_release (tmp_exp); |
1011 | goto except; | 1014 | goto except; |
1012 | } | 1015 | } |
1013 | gcry_sexp_release (tmp_exp); | 1016 | gcry_sexp_release (tmp_exp); |
1014 | 1017 | ||
1015 | // generate r, p and q | 1018 | // generate r, p and q |
@@ -1041,29 +1044,29 @@ compute_service_response (struct ServiceSession * request, | |||
1041 | // however, ap/aq are not absolutely necessary but are just abstraction | 1044 | // however, ap/aq are not absolutely necessary but are just abstraction |
1042 | // Calculate Kp = E(S + a_pi) (+) E(S - r_pi - b_pi) | 1045 | // Calculate Kp = E(S + a_pi) (+) E(S - r_pi - b_pi) |
1043 | for (i = 0; i < count; i++) | 1046 | for (i = 0; i < count; i++) |
1044 | { | 1047 | { |
1045 | // E(S - r_pi - b_pi) | 1048 | // E(S - r_pi - b_pi) |
1046 | gcry_mpi_sub (r[i], my_offset, rand_pi[i]); | 1049 | gcry_mpi_sub (r[i], my_offset, rand_pi[i]); |
1047 | gcry_mpi_sub (r[i], r[i], b_pi[i]); | 1050 | gcry_mpi_sub (r[i], r[i], b_pi[i]); |
1048 | encrypt_element (r[i], r[i], remote_g, remote_n, remote_nsquare); | 1051 | encrypt_element (r[i], r[i], remote_g, remote_n, remote_nsquare); |
1049 | 1052 | ||
1050 | // E(S - r_pi - b_pi) * E(S + a_pi) == E(2*S + a - r - b) | 1053 | // E(S - r_pi - b_pi) * E(S + a_pi) == E(2*S + a - r - b) |
1051 | gcry_mpi_mulm (r[i], r[i], a_pi[i], remote_nsquare); | 1054 | gcry_mpi_mulm (r[i], r[i], a_pi[i], remote_nsquare); |
1052 | } | 1055 | } |
1053 | GNUNET_free (a_pi); | 1056 | GNUNET_free (a_pi); |
1054 | GNUNET_free (b_pi); | 1057 | GNUNET_free (b_pi); |
1055 | GNUNET_free (rand_pi); | 1058 | GNUNET_free (rand_pi); |
1056 | 1059 | ||
1057 | // Calculate Kq = E(S + a_qi) (+) E(S - r_qi) | 1060 | // Calculate Kq = E(S + a_qi) (+) E(S - r_qi) |
1058 | for (i = 0; i < count; i++) | 1061 | for (i = 0; i < count; i++) |
1059 | { | 1062 | { |
1060 | // E(S - r_qi) | 1063 | // E(S - r_qi) |
1061 | gcry_mpi_sub (r_prime[i], my_offset, rand_pi_prime[i]); | 1064 | gcry_mpi_sub (r_prime[i], my_offset, rand_pi_prime[i]); |
1062 | encrypt_element (r_prime[i], r_prime[i], remote_g, remote_n, remote_nsquare); | 1065 | encrypt_element (r_prime[i], r_prime[i], remote_g, remote_n, remote_nsquare); |
1063 | 1066 | ||
1064 | // E(S - r_qi) * E(S + a_qi) == E(2*S + a_qi - r_qi) | 1067 | // E(S - r_qi) * E(S + a_qi) == E(2*S + a_qi - r_qi) |
1065 | gcry_mpi_mulm (r_prime[i], r_prime[i], a_pi_prime[i], remote_nsquare); | 1068 | gcry_mpi_mulm (r_prime[i], r_prime[i], a_pi_prime[i], remote_nsquare); |
1066 | } | 1069 | } |
1067 | GNUNET_free (a_pi_prime); | 1070 | GNUNET_free (a_pi_prime); |
1068 | GNUNET_free (rand_pi_prime); | 1071 | GNUNET_free (rand_pi_prime); |
1069 | 1072 | ||
@@ -1073,9 +1076,9 @@ compute_service_response (struct ServiceSession * request, | |||
1073 | 1076 | ||
1074 | // Calculate S = E(SUM( (r_i + b_i)^2 )) | 1077 | // Calculate S = E(SUM( (r_i + b_i)^2 )) |
1075 | for (i = 0; i < count; i++) | 1078 | for (i = 0; i < count; i++) |
1076 | { | 1079 | { |
1077 | gcry_mpi_add (rand[i], rand[i], b[i]); | 1080 | gcry_mpi_add (rand[i], rand[i], b[i]); |
1078 | } | 1081 | } |
1079 | s = compute_square_sum (rand, count); | 1082 | s = compute_square_sum (rand, count); |
1080 | encrypt_element (s, s, remote_g, remote_n, remote_nsquare); | 1083 | encrypt_element (s, s, remote_g, remote_n, remote_nsquare); |
1081 | gcry_mpi_release (remote_n); | 1084 | gcry_mpi_release (remote_n); |
@@ -1089,26 +1092,26 @@ compute_service_response (struct ServiceSession * request, | |||
1089 | 1092 | ||
1090 | // copy the Kp[], Kq[], S and Stick into a new message | 1093 | // copy the Kp[], Kq[], S and Stick into a new message |
1091 | if (GNUNET_YES != prepare_service_response (r, r_prime, s, s_prime, request, response)) | 1094 | if (GNUNET_YES != prepare_service_response (r, r_prime, s, s_prime, request, response)) |
1092 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Failed to communicate with `%s', scalar product calculation aborted.\n"), | 1095 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Failed to communicate with `%s', scalar product calculation aborted.\n"), |
1093 | GNUNET_i2s (&request->peer)); | 1096 | GNUNET_i2s (&request->peer)); |
1094 | else | 1097 | else |
1095 | ret = GNUNET_OK; | 1098 | ret = GNUNET_OK; |
1096 | 1099 | ||
1097 | for (i = 0; i < count; i++) | 1100 | for (i = 0; i < count; i++) |
1098 | { | 1101 | { |
1099 | gcry_mpi_release (r_prime[i]); | 1102 | gcry_mpi_release (r_prime[i]); |
1100 | gcry_mpi_release (r[i]); | 1103 | gcry_mpi_release (r[i]); |
1101 | } | 1104 | } |
1102 | 1105 | ||
1103 | gcry_mpi_release (s); | 1106 | gcry_mpi_release (s); |
1104 | gcry_mpi_release (s_prime); | 1107 | gcry_mpi_release (s_prime); |
1105 | 1108 | ||
1106 | except: | 1109 | except: |
1107 | for (i = 0; i < count; i++) | 1110 | for (i = 0; i < count; i++) |
1108 | { | 1111 | { |
1109 | gcry_mpi_release (b[i]); | 1112 | gcry_mpi_release (b[i]); |
1110 | gcry_mpi_release (request->a[i]); | 1113 | gcry_mpi_release (request->a[i]); |
1111 | } | 1114 | } |
1112 | 1115 | ||
1113 | GNUNET_free (b); | 1116 | GNUNET_free (b); |
1114 | GNUNET_free (request->a); | 1117 | GNUNET_free (request->a); |
@@ -1139,28 +1142,28 @@ prepare_service_request (void *cls, | |||
1139 | size_t element_length = 0; // initialized by gcry_mpi_print, but the compiler doesn't know that | 1142 | size_t element_length = 0; // initialized by gcry_mpi_print, but the compiler doesn't know that |
1140 | gcry_mpi_t a; | 1143 | gcry_mpi_t a; |
1141 | uint32_t value; | 1144 | uint32_t value; |
1142 | 1145 | ||
1143 | session->service_request_task = GNUNET_SCHEDULER_NO_TASK; | 1146 | session->service_request_task = GNUNET_SCHEDULER_NO_TASK; |
1144 | 1147 | ||
1145 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Successfully created new tunnel to peer (%s)!\n"), GNUNET_i2s (&session->peer)); | 1148 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Successfully created new tunnel to peer (%s)!\n"), GNUNET_i2s (&session->peer)); |
1146 | 1149 | ||
1147 | msg_length = sizeof (struct GNUNET_SCALARPRODUCT_service_request) | 1150 | msg_length = sizeof (struct GNUNET_SCALARPRODUCT_service_request) |
1148 | + session->used_element_count * PAILLIER_ELEMENT_LENGTH | 1151 | +session->used_element_count * PAILLIER_ELEMENT_LENGTH |
1149 | + session->mask_length | 1152 | + session->mask_length |
1150 | + my_pubkey_external_length; | 1153 | + my_pubkey_external_length; |
1151 | 1154 | ||
1152 | if (GNUNET_SERVER_MAX_MESSAGE_SIZE < sizeof (struct GNUNET_SCALARPRODUCT_service_request) | 1155 | if (GNUNET_SERVER_MAX_MESSAGE_SIZE < sizeof (struct GNUNET_SCALARPRODUCT_service_request) |
1153 | + session->used_element_count * PAILLIER_ELEMENT_LENGTH | 1156 | +session->used_element_count * PAILLIER_ELEMENT_LENGTH |
1154 | + session->mask_length | 1157 | + session->mask_length |
1155 | + my_pubkey_external_length) | 1158 | + my_pubkey_external_length) |
1156 | { | 1159 | { |
1157 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Message too large, fragmentation is currently not supported!\n")); | 1160 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Message too large, fragmentation is currently not supported!\n")); |
1158 | session->client_notification_task = | 1161 | session->client_notification_task = |
1159 | GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, | 1162 | GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, |
1160 | session); | 1163 | session); |
1161 | return; | 1164 | return; |
1162 | } | 1165 | } |
1163 | 1166 | ||
1164 | msg = GNUNET_malloc (msg_length); | 1167 | msg = GNUNET_malloc (msg_length); |
1165 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_TO_BOB); | 1168 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_TO_BOB); |
1166 | memcpy (&msg->key, &session->key, sizeof (struct GNUNET_HashCode)); | 1169 | memcpy (&msg->key, &session->key, sizeof (struct GNUNET_HashCode)); |
@@ -1178,49 +1181,49 @@ prepare_service_request (void *cls, | |||
1178 | current += session->mask_length; | 1181 | current += session->mask_length; |
1179 | memcpy (current, my_pubkey_external, my_pubkey_external_length); | 1182 | memcpy (current, my_pubkey_external, my_pubkey_external_length); |
1180 | current += my_pubkey_external_length; | 1183 | current += my_pubkey_external_length; |
1181 | 1184 | ||
1182 | // now copy over the element vector | 1185 | // now copy over the element vector |
1183 | session->a = GNUNET_malloc (sizeof (gcry_mpi_t) * session->used_element_count); | 1186 | session->a = GNUNET_malloc (sizeof (gcry_mpi_t) * session->used_element_count); |
1184 | a = gcry_mpi_new (KEYBITS * 2); | 1187 | a = gcry_mpi_new (KEYBITS * 2); |
1185 | // encrypt our vector and generate string representations | 1188 | // encrypt our vector and generate string representations |
1186 | for (i = 0, j = 0; i < session->element_count; i++) | 1189 | for (i = 0, j = 0; i < session->element_count; i++) |
1190 | { | ||
1191 | // if this is a used element... | ||
1192 | if (session->mask[i / 8] & 1 << (i % 8)) | ||
1187 | { | 1193 | { |
1188 | // if this is a used element... | 1194 | unsigned char * element_exported = GNUNET_malloc (PAILLIER_ELEMENT_LENGTH); |
1189 | if (session->mask[i / 8] & 1 << (i % 8)) | 1195 | value = session->vector[i] >= 0 ? session->vector[i] : -session->vector[i]; |
1190 | { | 1196 | |
1191 | unsigned char * element_exported = GNUNET_malloc (PAILLIER_ELEMENT_LENGTH); | 1197 | a = gcry_mpi_set_ui (a, 0); |
1192 | value = session->vector[i] >= 0 ? session->vector[i] : -session->vector[i]; | 1198 | // long to gcry_mpi_t |
1193 | 1199 | if (session->vector[i] < 0) | |
1194 | a = gcry_mpi_set_ui (a, 0); | 1200 | gcry_mpi_sub_ui (a, a, value); |
1195 | // long to gcry_mpi_t | 1201 | else |
1196 | if (session->vector[i] < 0) | 1202 | gcry_mpi_add_ui (a, a, value); |
1197 | gcry_mpi_sub_ui (a, a, value); | 1203 | |
1198 | else | 1204 | session->a[j++] = gcry_mpi_set (NULL, a); |
1199 | gcry_mpi_add_ui (a, a, value); | 1205 | gcry_mpi_add (a, a, my_offset); |
1200 | 1206 | encrypt_element (a, a, my_g, my_n, my_nsquare); | |
1201 | session->a[j++] = gcry_mpi_set (NULL, a); | 1207 | |
1202 | gcry_mpi_add (a, a, my_offset); | 1208 | // get representation as string |
1203 | encrypt_element (a, a, my_g, my_n, my_nsquare); | 1209 | // we always supply some value, so gcry_mpi_print fails only if it can't reserve memory |
1204 | 1210 | GNUNET_assert (!gcry_mpi_print (GCRYMPI_FMT_USG, | |
1205 | // get representation as string | 1211 | element_exported, PAILLIER_ELEMENT_LENGTH, |
1206 | // we always supply some value, so gcry_mpi_print fails only if it can't reserve memory | 1212 | &element_length, |
1207 | GNUNET_assert ( ! gcry_mpi_print (GCRYMPI_FMT_USG, | 1213 | a)); |
1208 | element_exported, PAILLIER_ELEMENT_LENGTH, | 1214 | |
1209 | &element_length, | 1215 | // move buffer content to the end of the buffer so it can easily be read by libgcrypt. also this now has fixed size |
1210 | a)); | 1216 | adjust (element_exported, element_length, PAILLIER_ELEMENT_LENGTH); |
1211 | 1217 | ||
1212 | // move buffer content to the end of the buffer so it can easily be read by libgcrypt. also this now has fixed size | 1218 | // copy over to the message |
1213 | adjust (element_exported, element_length, PAILLIER_ELEMENT_LENGTH); | 1219 | memcpy (current, element_exported, PAILLIER_ELEMENT_LENGTH); |
1214 | 1220 | current += PAILLIER_ELEMENT_LENGTH; | |
1215 | // copy over to the message | ||
1216 | memcpy (current, element_exported, PAILLIER_ELEMENT_LENGTH); | ||
1217 | current += PAILLIER_ELEMENT_LENGTH; | ||
1218 | } | ||
1219 | } | 1221 | } |
1222 | } | ||
1220 | gcry_mpi_release (a); | 1223 | gcry_mpi_release (a); |
1221 | 1224 | ||
1222 | session->msg = (struct GNUNET_MessageHeader *) msg; | 1225 | session->msg = (struct GNUNET_MessageHeader *) msg; |
1223 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Transmitting service request.\n")); | 1226 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Transmitting service request.\n")); |
1224 | 1227 | ||
1225 | //transmit via mesh messaging | 1228 | //transmit via mesh messaging |
1226 | session->service_transmit_handle = GNUNET_MESH_notify_transmit_ready (session->tunnel, GNUNET_YES, | 1229 | session->service_transmit_handle = GNUNET_MESH_notify_transmit_ready (session->tunnel, GNUNET_YES, |
@@ -1228,19 +1231,20 @@ prepare_service_request (void *cls, | |||
1228 | msg_length, | 1231 | msg_length, |
1229 | &do_send_message, | 1232 | &do_send_message, |
1230 | session); | 1233 | session); |
1231 | if ( ! session->service_transmit_handle) | 1234 | if (!session->service_transmit_handle) |
1232 | { | 1235 | { |
1233 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not send mutlicast message to tunnel!\n")); | 1236 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Could not send mutlicast message to tunnel!\n")); |
1234 | GNUNET_free (msg); | 1237 | GNUNET_free (msg); |
1235 | session->msg = NULL; | 1238 | session->msg = NULL; |
1236 | session->client_notification_task = | 1239 | session->client_notification_task = |
1237 | GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, | 1240 | GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, |
1238 | session); | 1241 | session); |
1239 | return; | 1242 | return; |
1240 | } | 1243 | } |
1241 | session->state = WAITING_FOR_SERVICE_RESPONSE; | 1244 | session->state = WAITING_FOR_SERVICE_RESPONSE; |
1242 | } | 1245 | } |
1243 | 1246 | ||
1247 | |||
1244 | /** | 1248 | /** |
1245 | * Handler for a client request message. | 1249 | * Handler for a client request message. |
1246 | * Can either be type A or B | 1250 | * Can either be type A or B |
@@ -1266,51 +1270,53 @@ handle_client_request (void *cls, | |||
1266 | 1270 | ||
1267 | // only one concurrent session per client connection allowed, simplifies logics a lot... | 1271 | // only one concurrent session per client connection allowed, simplifies logics a lot... |
1268 | session = GNUNET_SERVER_client_get_user_context (client, struct ServiceSession); | 1272 | session = GNUNET_SERVER_client_get_user_context (client, struct ServiceSession); |
1269 | if ((NULL != session) && (session->state != FINALIZED)){ | 1273 | if ((NULL != session) && (session->state != FINALIZED)) |
1274 | { | ||
1270 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1275 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
1271 | return; | 1276 | return; |
1272 | } | 1277 | } |
1273 | else if(NULL != session){ | 1278 | else if (NULL != session) |
1279 | { | ||
1274 | // old session is already completed, clean it up | 1280 | // old session is already completed, clean it up |
1275 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session); | 1281 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session); |
1276 | free_session(session); | 1282 | free_session (session); |
1277 | } | 1283 | } |
1278 | 1284 | ||
1279 | //we need at least a peer and one message id to compare | 1285 | //we need at least a peer and one message id to compare |
1280 | if (sizeof (struct GNUNET_SCALARPRODUCT_client_request) > ntohs (msg->header.size)) | 1286 | if (sizeof (struct GNUNET_SCALARPRODUCT_client_request) > ntohs (msg->header.size)) |
1281 | { | 1287 | { |
1282 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1288 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1283 | _ ("Too short message received from client!\n")); | 1289 | _ ("Too short message received from client!\n")); |
1284 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 1290 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
1285 | return; | 1291 | return; |
1286 | } | 1292 | } |
1287 | 1293 | ||
1288 | msg_type = ntohs (msg->header.type); | 1294 | msg_type = ntohs (msg->header.type); |
1289 | element_count = ntohl (msg->element_count); | 1295 | element_count = ntohl (msg->element_count); |
1290 | mask_length = ntohl (msg->mask_length); | 1296 | mask_length = ntohl (msg->mask_length); |
1291 | 1297 | ||
1292 | //sanity check: is the message as long as the message_count fields suggests? | 1298 | //sanity check: is the message as long as the message_count fields suggests? |
1293 | if (( ntohs (msg->header.size) != (sizeof (struct GNUNET_SCALARPRODUCT_client_request) + element_count * sizeof (int32_t) + mask_length)) | 1299 | if ((ntohs (msg->header.size) != (sizeof (struct GNUNET_SCALARPRODUCT_client_request) +element_count * sizeof (int32_t) + mask_length)) |
1294 | || (0 == element_count)) | 1300 | || (0 == element_count)) |
1295 | { | 1301 | { |
1296 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1302 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1297 | _ ("Invalid message received from client, session information incorrect!\n")); | 1303 | _ ("Invalid message received from client, session information incorrect!\n")); |
1298 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 1304 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
1299 | return; | 1305 | return; |
1300 | } | 1306 | } |
1301 | 1307 | ||
1302 | // do we have a duplicate session here already? | 1308 | // do we have a duplicate session here already? |
1303 | if (NULL != find_matching_session (from_client_tail, | 1309 | if (NULL != find_matching_session (from_client_tail, |
1304 | &msg->key, | 1310 | &msg->key, |
1305 | element_count, | 1311 | element_count, |
1306 | NULL, NULL)) | 1312 | NULL, NULL)) |
1307 | { | 1313 | { |
1308 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1314 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1309 | _ ("Duplicate session information received, cannot create new session with key `%s'\n"), | 1315 | _ ("Duplicate session information received, cannot create new session with key `%s'\n"), |
1310 | GNUNET_h2s (&msg->key)); | 1316 | GNUNET_h2s (&msg->key)); |
1311 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 1317 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
1312 | return; | 1318 | return; |
1313 | } | 1319 | } |
1314 | 1320 | ||
1315 | session = GNUNET_new (struct ServiceSession); | 1321 | session = GNUNET_new (struct ServiceSession); |
1316 | session->service_request_task = GNUNET_SCHEDULER_NO_TASK; | 1322 | session->service_request_task = GNUNET_SCHEDULER_NO_TASK; |
@@ -1325,108 +1331,109 @@ handle_client_request (void *cls, | |||
1325 | vector = (int32_t *) & msg[1]; | 1331 | vector = (int32_t *) & msg[1]; |
1326 | 1332 | ||
1327 | if (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_ALICE == msg_type) | 1333 | if (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_ALICE == msg_type) |
1334 | { | ||
1335 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1336 | _ ("Got client-request-session with key %s, preparing tunnel to remote service.\n"), | ||
1337 | GNUNET_h2s (&session->key)); | ||
1338 | |||
1339 | session->role = ALICE; | ||
1340 | // fill in the mask | ||
1341 | session->mask = GNUNET_malloc (mask_length); | ||
1342 | memcpy (session->mask, &vector[element_count], mask_length); | ||
1343 | |||
1344 | // copy over the elements | ||
1345 | session->used_element_count = 0; | ||
1346 | for (i = 0; i < element_count; i++) | ||
1328 | { | 1347 | { |
1329 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1348 | session->vector[i] = ntohl (vector[i]); |
1330 | _ ("Got client-request-session with key %s, preparing tunnel to remote service.\n"), | 1349 | if (session->vector[i] == 0) |
1331 | GNUNET_h2s (&session->key)); | 1350 | session->mask[i / 8] &= ~(1 << (i % 8)); |
1332 | 1351 | if (session->mask[i / 8] & (1 << (i % 8))) | |
1333 | session->role = ALICE; | 1352 | session->used_element_count++; |
1334 | // fill in the mask | ||
1335 | session->mask = GNUNET_malloc (mask_length); | ||
1336 | memcpy (session->mask, &vector[element_count], mask_length); | ||
1337 | |||
1338 | // copy over the elements | ||
1339 | session->used_element_count = 0; | ||
1340 | for (i = 0; i < element_count; i++) | ||
1341 | { | ||
1342 | session->vector[i] = ntohl (vector[i]); | ||
1343 | if (session->vector[i] == 0) | ||
1344 | session->mask[i / 8] &= ~(1 << (i % 8)); | ||
1345 | if (session->mask[i / 8] & (1 << (i % 8))) | ||
1346 | session->used_element_count++; | ||
1347 | } | ||
1348 | |||
1349 | if ( 0 == session->used_element_count) | ||
1350 | { | ||
1351 | GNUNET_break_op (0); | ||
1352 | GNUNET_free (session->vector); | ||
1353 | GNUNET_free (session); | ||
1354 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
1355 | return; | ||
1356 | } | ||
1357 | //session with ourself makes no sense! | ||
1358 | if ( ! memcmp (&msg->peer, &me, sizeof (struct GNUNET_PeerIdentity))) | ||
1359 | { | ||
1360 | GNUNET_break (0); | ||
1361 | GNUNET_free (session->vector); | ||
1362 | GNUNET_free (session); | ||
1363 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
1364 | return; | ||
1365 | } | ||
1366 | // get our peer ID | ||
1367 | memcpy (&session->peer, &msg->peer, sizeof (struct GNUNET_PeerIdentity)); | ||
1368 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1369 | _ ("Creating new tunnel to for session with key %s.\n"), | ||
1370 | GNUNET_h2s (&session->key)); | ||
1371 | session->tunnel = GNUNET_MESH_tunnel_create (my_mesh, session, | ||
1372 | &session->peer, | ||
1373 | GNUNET_APPLICATION_TYPE_SCALARPRODUCT, | ||
1374 | GNUNET_NO, | ||
1375 | GNUNET_YES); | ||
1376 | //prepare_service_request, tunnel_peer_disconnect_handler, | ||
1377 | if ( ! session->tunnel) | ||
1378 | { | ||
1379 | GNUNET_break (0); | ||
1380 | GNUNET_free (session->vector); | ||
1381 | GNUNET_free (session); | ||
1382 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
1383 | return; | ||
1384 | } | ||
1385 | GNUNET_SERVER_client_set_user_context (client, session); | ||
1386 | GNUNET_CONTAINER_DLL_insert (from_client_head, from_client_tail, session); | ||
1387 | |||
1388 | session->state = CLIENT_REQUEST_RECEIVED; | ||
1389 | session->service_request_task = | ||
1390 | GNUNET_SCHEDULER_add_now (&prepare_service_request, | ||
1391 | session); | ||
1392 | |||
1393 | } | 1353 | } |
1354 | |||
1355 | if (0 == session->used_element_count) | ||
1356 | { | ||
1357 | GNUNET_break_op (0); | ||
1358 | GNUNET_free (session->vector); | ||
1359 | GNUNET_free (session); | ||
1360 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
1361 | return; | ||
1362 | } | ||
1363 | //session with ourself makes no sense! | ||
1364 | if (!memcmp (&msg->peer, &me, sizeof (struct GNUNET_PeerIdentity))) | ||
1365 | { | ||
1366 | GNUNET_break (0); | ||
1367 | GNUNET_free (session->vector); | ||
1368 | GNUNET_free (session); | ||
1369 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
1370 | return; | ||
1371 | } | ||
1372 | // get our peer ID | ||
1373 | memcpy (&session->peer, &msg->peer, sizeof (struct GNUNET_PeerIdentity)); | ||
1374 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1375 | _ ("Creating new tunnel to for session with key %s.\n"), | ||
1376 | GNUNET_h2s (&session->key)); | ||
1377 | session->tunnel = GNUNET_MESH_tunnel_create (my_mesh, session, | ||
1378 | &session->peer, | ||
1379 | GNUNET_APPLICATION_TYPE_SCALARPRODUCT, | ||
1380 | GNUNET_NO, | ||
1381 | GNUNET_YES); | ||
1382 | //prepare_service_request, tunnel_peer_disconnect_handler, | ||
1383 | if (!session->tunnel) | ||
1384 | { | ||
1385 | GNUNET_break (0); | ||
1386 | GNUNET_free (session->vector); | ||
1387 | GNUNET_free (session); | ||
1388 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
1389 | return; | ||
1390 | } | ||
1391 | GNUNET_SERVER_client_set_user_context (client, session); | ||
1392 | GNUNET_CONTAINER_DLL_insert (from_client_head, from_client_tail, session); | ||
1393 | |||
1394 | session->state = CLIENT_REQUEST_RECEIVED; | ||
1395 | session->service_request_task = | ||
1396 | GNUNET_SCHEDULER_add_now (&prepare_service_request, | ||
1397 | session); | ||
1398 | |||
1399 | } | ||
1394 | else | 1400 | else |
1401 | { | ||
1402 | struct ServiceSession * requesting_session; | ||
1403 | enum SessionState needed_state = SERVICE_REQUEST_RECEIVED; | ||
1404 | |||
1405 | session->role = BOB; | ||
1406 | session->mask = NULL; | ||
1407 | // copy over the elements | ||
1408 | session->used_element_count = element_count; | ||
1409 | for (i = 0; i < element_count; i++) | ||
1410 | session->vector[i] = ntohl (vector[i]); | ||
1411 | session->state = CLIENT_RESPONSE_RECEIVED; | ||
1412 | |||
1413 | GNUNET_SERVER_client_set_user_context (client, session); | ||
1414 | GNUNET_CONTAINER_DLL_insert (from_client_head, from_client_tail, session); | ||
1415 | |||
1416 | //check if service queue contains a matching request | ||
1417 | requesting_session = find_matching_session (from_service_tail, | ||
1418 | &session->key, | ||
1419 | session->element_count, | ||
1420 | &needed_state, NULL); | ||
1421 | if (NULL != requesting_session) | ||
1395 | { | 1422 | { |
1396 | struct ServiceSession * requesting_session; | 1423 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Got client-responder-session with key %s and a matching service-request-session set, processing.\n"), GNUNET_h2s (&session->key)); |
1397 | enum SessionState needed_state = SERVICE_REQUEST_RECEIVED; | 1424 | if (GNUNET_OK != compute_service_response (requesting_session, session)) |
1398 | 1425 | session->client_notification_task = | |
1399 | session->role = BOB; | 1426 | GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, |
1400 | session->mask = NULL; | 1427 | session); |
1401 | // copy over the elements | 1428 | |
1402 | session->used_element_count = element_count; | ||
1403 | for (i = 0; i < element_count; i++) | ||
1404 | session->vector[i] = ntohl (vector[i]); | ||
1405 | session->state = CLIENT_RESPONSE_RECEIVED; | ||
1406 | |||
1407 | GNUNET_SERVER_client_set_user_context (client, session); | ||
1408 | GNUNET_CONTAINER_DLL_insert (from_client_head, from_client_tail, session); | ||
1409 | |||
1410 | //check if service queue contains a matching request | ||
1411 | requesting_session = find_matching_session (from_service_tail, | ||
1412 | &session->key, | ||
1413 | session->element_count, | ||
1414 | &needed_state, NULL); | ||
1415 | if (NULL != requesting_session) | ||
1416 | { | ||
1417 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Got client-responder-session with key %s and a matching service-request-session set, processing.\n"), GNUNET_h2s (&session->key)); | ||
1418 | if (GNUNET_OK != compute_service_response (requesting_session, session)) | ||
1419 | session->client_notification_task = | ||
1420 | GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, | ||
1421 | session); | ||
1422 | |||
1423 | } | ||
1424 | else{ | ||
1425 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Got client-responder-session with key %s but NO matching service-request-session set, queuing element for later use.\n"), GNUNET_h2s (&session->key)); | ||
1426 | // no matching session exists yet, store the response | ||
1427 | // for later processing by handle_service_request() | ||
1428 | } | ||
1429 | } | 1429 | } |
1430 | else | ||
1431 | { | ||
1432 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Got client-responder-session with key %s but NO matching service-request-session set, queuing element for later use.\n"), GNUNET_h2s (&session->key)); | ||
1433 | // no matching session exists yet, store the response | ||
1434 | // for later processing by handle_service_request() | ||
1435 | } | ||
1436 | } | ||
1430 | GNUNET_SERVER_receive_done (client, GNUNET_YES); | 1437 | GNUNET_SERVER_receive_done (client, GNUNET_YES); |
1431 | } | 1438 | } |
1432 | 1439 | ||
@@ -1442,7 +1449,7 @@ handle_client_request (void *cls, | |||
1442 | * (can be NULL -- that's not an error) | 1449 | * (can be NULL -- that's not an error) |
1443 | */ | 1450 | */ |
1444 | static void * | 1451 | static void * |
1445 | tunnel_incoming_handler (void *cls, | 1452 | tunnel_incoming_handler (void *cls, |
1446 | struct GNUNET_MESH_Tunnel *tunnel, | 1453 | struct GNUNET_MESH_Tunnel *tunnel, |
1447 | const struct GNUNET_PeerIdentity *initiator, | 1454 | const struct GNUNET_PeerIdentity *initiator, |
1448 | uint32_t port) | 1455 | uint32_t port) |
@@ -1476,24 +1483,26 @@ tunnel_destruction_handler (void *cls, | |||
1476 | struct ServiceSession * session = tunnel_ctx; | 1483 | struct ServiceSession * session = tunnel_ctx; |
1477 | struct ServiceSession * client_session; | 1484 | struct ServiceSession * client_session; |
1478 | struct ServiceSession * curr; | 1485 | struct ServiceSession * curr; |
1479 | 1486 | ||
1480 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1487 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1481 | _("Peer disconnected, terminating session %s with peer (%s)\n"), | 1488 | _ ("Peer disconnected, terminating session %s with peer (%s)\n"), |
1482 | GNUNET_h2s (&session->key), | 1489 | GNUNET_h2s (&session->key), |
1483 | GNUNET_i2s (&session->peer)); | 1490 | GNUNET_i2s (&session->peer)); |
1484 | if (ALICE == session->role) { | 1491 | if (ALICE == session->role) |
1492 | { | ||
1485 | // as we have only one peer connected in each session, just remove the session | 1493 | // as we have only one peer connected in each session, just remove the session |
1486 | 1494 | ||
1487 | if ((SERVICE_RESPONSE_RECEIVED > session->state) && (!do_shutdown)) | 1495 | if ((SERVICE_RESPONSE_RECEIVED > session->state) && (!do_shutdown)) |
1488 | { | 1496 | { |
1489 | session->tunnel = NULL; | 1497 | session->tunnel = NULL; |
1490 | // if this happened before we received the answer, we must terminate the session | 1498 | // if this happened before we received the answer, we must terminate the session |
1491 | session->client_notification_task = | 1499 | session->client_notification_task = |
1492 | GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, | 1500 | GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, |
1493 | session); | 1501 | session); |
1494 | } | 1502 | } |
1495 | } | 1503 | } |
1496 | else { //(BOB == session->role) service session | 1504 | else |
1505 | { //(BOB == session->role) service session | ||
1497 | // remove the session, unless it has already been dequeued, but somehow still active | 1506 | // remove the session, unless it has already been dequeued, but somehow still active |
1498 | // this could bug without the IF in case the queue is empty and the service session was the only one know to the service | 1507 | // this could bug without the IF in case the queue is empty and the service session was the only one know to the service |
1499 | // scenario: disconnect before alice can send her message to bob. | 1508 | // scenario: disconnect before alice can send her message to bob. |
@@ -1516,7 +1525,7 @@ tunnel_destruction_handler (void *cls, | |||
1516 | if (client_session && (!do_shutdown)) | 1525 | if (client_session && (!do_shutdown)) |
1517 | { | 1526 | { |
1518 | client_session->state = FINALIZED; | 1527 | client_session->state = FINALIZED; |
1519 | client_session->client_notification_task = | 1528 | client_session->client_notification_task = |
1520 | GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, | 1529 | GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, |
1521 | client_session); | 1530 | client_session); |
1522 | } | 1531 | } |
@@ -1557,14 +1566,14 @@ compute_scalar_product (struct ServiceSession * session, | |||
1557 | // from the E(a_pi)(+)E(-b_pi-r_pi) and E(a_qi)(+)E(-r_qi) twice each, | 1566 | // from the E(a_pi)(+)E(-b_pi-r_pi) and E(a_qi)(+)E(-r_qi) twice each, |
1558 | // the result is E((S + a_pi) + (S -b_pi-r_pi)) and E(S + a_qi + S - r_qi) | 1567 | // the result is E((S + a_pi) + (S -b_pi-r_pi)) and E(S + a_qi + S - r_qi) |
1559 | for (i = 0; i < count; i++) | 1568 | for (i = 0; i < count; i++) |
1560 | { | 1569 | { |
1561 | decrypt_element (r[i], r[i], my_mu, my_lambda, my_n, my_nsquare); | 1570 | decrypt_element (r[i], r[i], my_mu, my_lambda, my_n, my_nsquare); |
1562 | gcry_mpi_sub(r[i],r[i],my_offset); | 1571 | gcry_mpi_sub (r[i], r[i], my_offset); |
1563 | gcry_mpi_sub(r[i],r[i],my_offset); | 1572 | gcry_mpi_sub (r[i], r[i], my_offset); |
1564 | decrypt_element (r_prime[i], r_prime[i], my_mu, my_lambda, my_n, my_nsquare); | 1573 | decrypt_element (r_prime[i], r_prime[i], my_mu, my_lambda, my_n, my_nsquare); |
1565 | gcry_mpi_sub(r_prime[i],r_prime[i],my_offset); | 1574 | gcry_mpi_sub (r_prime[i], r_prime[i], my_offset); |
1566 | gcry_mpi_sub(r_prime[i],r_prime[i],my_offset); | 1575 | gcry_mpi_sub (r_prime[i], r_prime[i], my_offset); |
1567 | } | 1576 | } |
1568 | 1577 | ||
1569 | // calculate t = sum(ai) | 1578 | // calculate t = sum(ai) |
1570 | t = compute_square_sum (session->a, count); | 1579 | t = compute_square_sum (session->a, count); |
@@ -1586,7 +1595,7 @@ compute_scalar_product (struct ServiceSession * session, | |||
1586 | // compute P | 1595 | // compute P |
1587 | decrypt_element (s, s, my_mu, my_lambda, my_n, my_nsquare); | 1596 | decrypt_element (s, s, my_mu, my_lambda, my_n, my_nsquare); |
1588 | decrypt_element (s_prime, s_prime, my_mu, my_lambda, my_n, my_nsquare); | 1597 | decrypt_element (s_prime, s_prime, my_mu, my_lambda, my_n, my_nsquare); |
1589 | 1598 | ||
1590 | // compute P | 1599 | // compute P |
1591 | gcry_mpi_add (p, s, t); | 1600 | gcry_mpi_add (p, s, t); |
1592 | gcry_mpi_add (p, p, u); | 1601 | gcry_mpi_add (p, p, u); |
@@ -1610,7 +1619,7 @@ compute_scalar_product (struct ServiceSession * session, | |||
1610 | gcry_mpi_release (session->a[i]); | 1619 | gcry_mpi_release (session->a[i]); |
1611 | GNUNET_free (session->a); | 1620 | GNUNET_free (session->a); |
1612 | session->a = NULL; | 1621 | session->a = NULL; |
1613 | 1622 | ||
1614 | return p; | 1623 | return p; |
1615 | } | 1624 | } |
1616 | 1625 | ||
@@ -1633,79 +1642,83 @@ prepare_client_response (void *cls, | |||
1633 | int8_t range = -1; | 1642 | int8_t range = -1; |
1634 | gcry_error_t rc; | 1643 | gcry_error_t rc; |
1635 | int sign; | 1644 | int sign; |
1636 | 1645 | ||
1637 | session->client_notification_task = GNUNET_SCHEDULER_NO_TASK; | 1646 | session->client_notification_task = GNUNET_SCHEDULER_NO_TASK; |
1638 | 1647 | ||
1639 | if (session->product) | 1648 | if (session->product) |
1649 | { | ||
1650 | gcry_mpi_t value = gcry_mpi_new (0); | ||
1651 | |||
1652 | sign = gcry_mpi_cmp_ui (session->product, 0); | ||
1653 | // libgcrypt can not handle a print of a negative number | ||
1654 | // if (a->sign) return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */ | ||
1655 | if (0 > sign) | ||
1640 | { | 1656 | { |
1641 | gcry_mpi_t value = gcry_mpi_new(0); | 1657 | gcry_mpi_sub (value, value, session->product); |
1642 | |||
1643 | sign = gcry_mpi_cmp_ui(session->product, 0); | ||
1644 | // libgcrypt can not handle a print of a negative number | ||
1645 | // if (a->sign) return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */ | ||
1646 | if (0 > sign){ | ||
1647 | gcry_mpi_sub(value, value, session->product); | ||
1648 | } | ||
1649 | else if(0 < sign){ | ||
1650 | range = 1; | ||
1651 | gcry_mpi_add(value, value, session->product); | ||
1652 | } | ||
1653 | else | ||
1654 | range = 0; | ||
1655 | |||
1656 | gcry_mpi_release (session->product); | ||
1657 | session->product = NULL; | ||
1658 | |||
1659 | // get representation as string | ||
1660 | if (range | ||
1661 | && (0 != (rc = gcry_mpi_aprint (GCRYMPI_FMT_STD, | ||
1662 | &product_exported, | ||
1663 | &product_length, | ||
1664 | value)))){ | ||
1665 | LOG_GCRY(GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); | ||
1666 | product_length = 0; | ||
1667 | range = -1; // signal error with product-length = 0 and range = -1 | ||
1668 | } | ||
1669 | gcry_mpi_release (value); | ||
1670 | } | 1658 | } |
1659 | else if (0 < sign) | ||
1660 | { | ||
1661 | range = 1; | ||
1662 | gcry_mpi_add (value, value, session->product); | ||
1663 | } | ||
1664 | else | ||
1665 | range = 0; | ||
1666 | |||
1667 | gcry_mpi_release (session->product); | ||
1668 | session->product = NULL; | ||
1669 | |||
1670 | // get representation as string | ||
1671 | if (range | ||
1672 | && (0 != (rc = gcry_mpi_aprint (GCRYMPI_FMT_STD, | ||
1673 | &product_exported, | ||
1674 | &product_length, | ||
1675 | value)))) | ||
1676 | { | ||
1677 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); | ||
1678 | product_length = 0; | ||
1679 | range = -1; // signal error with product-length = 0 and range = -1 | ||
1680 | } | ||
1681 | gcry_mpi_release (value); | ||
1682 | } | ||
1671 | 1683 | ||
1672 | msg_length = sizeof (struct GNUNET_SCALARPRODUCT_client_response) + product_length; | 1684 | msg_length = sizeof (struct GNUNET_SCALARPRODUCT_client_response) +product_length; |
1673 | msg = GNUNET_malloc (msg_length); | 1685 | msg = GNUNET_malloc (msg_length); |
1674 | memcpy (&msg->key, &session->key, sizeof (struct GNUNET_HashCode)); | 1686 | memcpy (&msg->key, &session->key, sizeof (struct GNUNET_HashCode)); |
1675 | memcpy (&msg->peer, &session->peer, sizeof ( struct GNUNET_PeerIdentity)); | 1687 | memcpy (&msg->peer, &session->peer, sizeof ( struct GNUNET_PeerIdentity)); |
1676 | if (product_exported != NULL){ | 1688 | if (product_exported != NULL) |
1689 | { | ||
1677 | memcpy (&msg[1], product_exported, product_length); | 1690 | memcpy (&msg[1], product_exported, product_length); |
1678 | GNUNET_free(product_exported); | 1691 | GNUNET_free (product_exported); |
1679 | } | 1692 | } |
1680 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SERVICE_TO_CLIENT); | 1693 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SERVICE_TO_CLIENT); |
1681 | msg->header.size = htons (msg_length); | 1694 | msg->header.size = htons (msg_length); |
1682 | msg->range = range; | 1695 | msg->range = range; |
1683 | msg->product_length = htonl (product_length); | 1696 | msg->product_length = htonl (product_length); |
1684 | 1697 | ||
1685 | session->msg = (struct GNUNET_MessageHeader *) msg; | 1698 | session->msg = (struct GNUNET_MessageHeader *) msg; |
1686 | //transmit this message to our client | 1699 | //transmit this message to our client |
1687 | session->client_transmit_handle = | 1700 | session->client_transmit_handle = |
1688 | GNUNET_SERVER_notify_transmit_ready (session->client, | 1701 | GNUNET_SERVER_notify_transmit_ready (session->client, |
1689 | msg_length, | 1702 | msg_length, |
1690 | GNUNET_TIME_UNIT_FOREVER_REL, | 1703 | GNUNET_TIME_UNIT_FOREVER_REL, |
1691 | &do_send_message, | 1704 | &do_send_message, |
1692 | session); | 1705 | session); |
1693 | if ( NULL == session->client_transmit_handle) | 1706 | if (NULL == session->client_transmit_handle) |
1694 | { | 1707 | { |
1695 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1708 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1696 | _ ("Could not send message to client (%p)!\n"), | 1709 | _ ("Could not send message to client (%p)!\n"), |
1697 | session->client); | 1710 | session->client); |
1698 | session->client = NULL; | 1711 | session->client = NULL; |
1699 | // callback was not called! | 1712 | // callback was not called! |
1700 | GNUNET_free (msg); | 1713 | GNUNET_free (msg); |
1701 | session->msg = NULL; | 1714 | session->msg = NULL; |
1702 | } | 1715 | } |
1703 | else | 1716 | else |
1704 | // gracefully sent message, just terminate session structure | 1717 | // gracefully sent message, just terminate session structure |
1705 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1718 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1706 | _ ("Sent result to client (%p), this session (%s) has ended!\n"), | 1719 | _ ("Sent result to client (%p), this session (%s) has ended!\n"), |
1707 | session->client, | 1720 | session->client, |
1708 | GNUNET_h2s (&session->key)); | 1721 | GNUNET_h2s (&session->key)); |
1709 | } | 1722 | } |
1710 | 1723 | ||
1711 | 1724 | ||
@@ -1740,58 +1753,59 @@ handle_service_request (void *cls, | |||
1740 | enum SessionState needed_state; | 1753 | enum SessionState needed_state; |
1741 | 1754 | ||
1742 | session = (struct ServiceSession *) * tunnel_ctx; | 1755 | session = (struct ServiceSession *) * tunnel_ctx; |
1743 | if (BOB != session->role){ | 1756 | if (BOB != session->role) |
1744 | GNUNET_break_op(0); | 1757 | { |
1758 | GNUNET_break_op (0); | ||
1745 | return GNUNET_SYSERR; | 1759 | return GNUNET_SYSERR; |
1746 | } | 1760 | } |
1747 | // is this tunnel already in use? | 1761 | // is this tunnel already in use? |
1748 | if ( (session->next) || (from_service_head == session)) | 1762 | if ((session->next) || (from_service_head == session)) |
1749 | { | 1763 | { |
1750 | GNUNET_break_op(0); | 1764 | GNUNET_break_op (0); |
1751 | return GNUNET_SYSERR; | 1765 | return GNUNET_SYSERR; |
1752 | } | 1766 | } |
1753 | // Check if message was sent by me, which would be bad! | 1767 | // Check if message was sent by me, which would be bad! |
1754 | if ( ! memcmp (&session->peer, &me, sizeof (struct GNUNET_PeerIdentity))) | 1768 | if (!memcmp (&session->peer, &me, sizeof (struct GNUNET_PeerIdentity))) |
1755 | { | 1769 | { |
1756 | GNUNET_free (session); | 1770 | GNUNET_free (session); |
1757 | GNUNET_break (0); | 1771 | GNUNET_break (0); |
1758 | return GNUNET_SYSERR; | 1772 | return GNUNET_SYSERR; |
1759 | } | 1773 | } |
1760 | 1774 | ||
1761 | //we need at least a peer and one message id to compare | 1775 | //we need at least a peer and one message id to compare |
1762 | if (ntohs (msg->header.size) < sizeof (struct GNUNET_SCALARPRODUCT_service_request)) | 1776 | if (ntohs (msg->header.size) < sizeof (struct GNUNET_SCALARPRODUCT_service_request)) |
1763 | { | 1777 | { |
1764 | GNUNET_free (session); | 1778 | GNUNET_free (session); |
1765 | GNUNET_break_op(0); | 1779 | GNUNET_break_op (0); |
1766 | return GNUNET_SYSERR; | 1780 | return GNUNET_SYSERR; |
1767 | } | 1781 | } |
1768 | mask_length = ntohl (msg->mask_length); | 1782 | mask_length = ntohl (msg->mask_length); |
1769 | pk_length = ntohl (msg->pk_length); | 1783 | pk_length = ntohl (msg->pk_length); |
1770 | used_elements = ntohl (msg->used_element_count); | 1784 | used_elements = ntohl (msg->used_element_count); |
1771 | element_count = ntohl (msg->element_count); | 1785 | element_count = ntohl (msg->element_count); |
1772 | msg_length = sizeof (struct GNUNET_SCALARPRODUCT_service_request) | 1786 | msg_length = sizeof (struct GNUNET_SCALARPRODUCT_service_request) |
1773 | + mask_length + pk_length + used_elements * PAILLIER_ELEMENT_LENGTH; | 1787 | +mask_length + pk_length + used_elements * PAILLIER_ELEMENT_LENGTH; |
1774 | 1788 | ||
1775 | //sanity check: is the message as long as the message_count fields suggests? | 1789 | //sanity check: is the message as long as the message_count fields suggests? |
1776 | if ((ntohs (msg->header.size) != msg_length) || (element_count < used_elements) | 1790 | if ((ntohs (msg->header.size) != msg_length) || (element_count < used_elements) |
1777 | || (used_elements == 0) || (mask_length != (element_count / 8 + (element_count % 8 ? 1 : 0))) | 1791 | || (used_elements == 0) || (mask_length != (element_count / 8 + (element_count % 8 ? 1 : 0))) |
1778 | ) | 1792 | ) |
1779 | { | 1793 | { |
1780 | GNUNET_free (session); | 1794 | GNUNET_free (session); |
1781 | GNUNET_break_op(0); | 1795 | GNUNET_break_op (0); |
1782 | return GNUNET_SYSERR; | 1796 | return GNUNET_SYSERR; |
1783 | } | 1797 | } |
1784 | if (find_matching_session (from_service_tail, | 1798 | if (find_matching_session (from_service_tail, |
1785 | &msg->key, | 1799 | &msg->key, |
1786 | element_count, | 1800 | element_count, |
1787 | NULL, | 1801 | NULL, |
1788 | NULL)) | 1802 | NULL)) |
1789 | { | 1803 | { |
1790 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Got message with duplicate session key (`%s'), ignoring service request.\n"), (const char *) &(msg->key)); | 1804 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Got message with duplicate session key (`%s'), ignoring service request.\n"), (const char *) &(msg->key)); |
1791 | GNUNET_free (session); | 1805 | GNUNET_free (session); |
1792 | return GNUNET_SYSERR; | 1806 | return GNUNET_SYSERR; |
1793 | } | 1807 | } |
1794 | 1808 | ||
1795 | memcpy (&session->peer, &session->peer, sizeof (struct GNUNET_PeerIdentity)); | 1809 | memcpy (&session->peer, &session->peer, sizeof (struct GNUNET_PeerIdentity)); |
1796 | session->state = SERVICE_REQUEST_RECEIVED; | 1810 | session->state = SERVICE_REQUEST_RECEIVED; |
1797 | session->element_count = ntohl (msg->element_count); | 1811 | session->element_count = ntohl (msg->element_count); |
@@ -1809,12 +1823,12 @@ handle_service_request (void *cls, | |||
1809 | 1823 | ||
1810 | //convert the publickey to sexp | 1824 | //convert the publickey to sexp |
1811 | if (gcry_sexp_new (&session->remote_pubkey, current, pk_length, 1)) | 1825 | if (gcry_sexp_new (&session->remote_pubkey, current, pk_length, 1)) |
1812 | { | 1826 | { |
1813 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Could not translate remote public key to sexpression!\n")); | 1827 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Could not translate remote public key to sexpression!\n")); |
1814 | GNUNET_free (session->mask); | 1828 | GNUNET_free (session->mask); |
1815 | GNUNET_free (session); | 1829 | GNUNET_free (session); |
1816 | return GNUNET_SYSERR; | 1830 | return GNUNET_SYSERR; |
1817 | } | 1831 | } |
1818 | 1832 | ||
1819 | current += pk_length; | 1833 | current += pk_length; |
1820 | 1834 | ||
@@ -1831,48 +1845,48 @@ handle_service_request (void *cls, | |||
1831 | +pk_length | 1845 | +pk_length |
1832 | + mask_length | 1846 | + mask_length |
1833 | + used_elements * PAILLIER_ELEMENT_LENGTH) | 1847 | + used_elements * PAILLIER_ELEMENT_LENGTH) |
1848 | { | ||
1849 | gcry_error_t ret = 0; | ||
1850 | session->a = GNUNET_malloc (sizeof (gcry_mpi_t) * used_elements); | ||
1851 | // Convert each vector element to MPI_value | ||
1852 | for (i = 0; i < used_elements; i++) | ||
1834 | { | 1853 | { |
1835 | gcry_error_t ret = 0; | 1854 | size_t read = 0; |
1836 | session->a = GNUNET_malloc (sizeof (gcry_mpi_t) * used_elements); | 1855 | |
1837 | // Convert each vector element to MPI_value | 1856 | ret = gcry_mpi_scan (&session->a[i], |
1838 | for (i = 0; i < used_elements; i++) | 1857 | GCRYMPI_FMT_USG, |
1839 | { | 1858 | ¤t[i * PAILLIER_ELEMENT_LENGTH], |
1840 | size_t read = 0; | 1859 | PAILLIER_ELEMENT_LENGTH, |
1841 | 1860 | &read); | |
1842 | ret = gcry_mpi_scan (&session->a[i], | 1861 | if (ret) |
1843 | GCRYMPI_FMT_USG, | 1862 | { |
1844 | ¤t[i * PAILLIER_ELEMENT_LENGTH], | 1863 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Could not translate E[a%d] to MPI!\n%s/%s\n"), |
1845 | PAILLIER_ELEMENT_LENGTH, | 1864 | i, gcry_strsource (ret), gcry_strerror (ret)); |
1846 | &read); | 1865 | goto except; |
1847 | if (ret) | 1866 | } |
1848 | { | ||
1849 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Could not translate E[a%d] to MPI!\n%s/%s\n"), | ||
1850 | i, gcry_strsource (ret), gcry_strerror (ret)); | ||
1851 | goto except; | ||
1852 | } | ||
1853 | } | ||
1854 | GNUNET_CONTAINER_DLL_insert (from_service_head, from_service_tail, session); | ||
1855 | if (responder_session) | ||
1856 | { | ||
1857 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Got session with key %s and a matching element set, processing.\n"), GNUNET_h2s (&session->key)); | ||
1858 | if (GNUNET_OK != compute_service_response (session, responder_session)) | ||
1859 | { | ||
1860 | //something went wrong, remove it again... | ||
1861 | GNUNET_CONTAINER_DLL_remove (from_service_head, from_service_tail, session); | ||
1862 | goto except; | ||
1863 | } | ||
1864 | } | ||
1865 | else | ||
1866 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Got session with key %s without a matching element set, queueing.\n"), GNUNET_h2s (&session->key)); | ||
1867 | |||
1868 | return GNUNET_OK; | ||
1869 | } | 1867 | } |
1870 | else | 1868 | GNUNET_CONTAINER_DLL_insert (from_service_head, from_service_tail, session); |
1869 | if (responder_session) | ||
1871 | { | 1870 | { |
1872 | // TODO FEATURE: fallback to fragmentation, in case the message is too long | 1871 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Got session with key %s and a matching element set, processing.\n"), GNUNET_h2s (&session->key)); |
1873 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Message too large, fragmentation is currently not supported!\n")); | 1872 | if (GNUNET_OK != compute_service_response (session, responder_session)) |
1874 | goto except; | 1873 | { |
1874 | //something went wrong, remove it again... | ||
1875 | GNUNET_CONTAINER_DLL_remove (from_service_head, from_service_tail, session); | ||
1876 | goto except; | ||
1877 | } | ||
1875 | } | 1878 | } |
1879 | else | ||
1880 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Got session with key %s without a matching element set, queueing.\n"), GNUNET_h2s (&session->key)); | ||
1881 | |||
1882 | return GNUNET_OK; | ||
1883 | } | ||
1884 | else | ||
1885 | { | ||
1886 | // TODO FEATURE: fallback to fragmentation, in case the message is too long | ||
1887 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Message too large, fragmentation is currently not supported!\n")); | ||
1888 | goto except; | ||
1889 | } | ||
1876 | except: | 1890 | except: |
1877 | for (i = 0; i < used_elements; i++) | 1891 | for (i = 0; i < used_elements; i++) |
1878 | if (session->a[i]) | 1892 | if (session->a[i]) |
@@ -1884,10 +1898,10 @@ except: | |||
1884 | free_session (session); | 1898 | free_session (session); |
1885 | // and notify our client-session that we could not complete the session | 1899 | // and notify our client-session that we could not complete the session |
1886 | if (responder_session) | 1900 | if (responder_session) |
1887 | // we just found the responder session in this queue | 1901 | // we just found the responder session in this queue |
1888 | responder_session->client_notification_task = | 1902 | responder_session->client_notification_task = |
1889 | GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, | 1903 | GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, |
1890 | responder_session); | 1904 | responder_session); |
1891 | return GNUNET_SYSERR; | 1905 | return GNUNET_SYSERR; |
1892 | } | 1906 | } |
1893 | 1907 | ||
@@ -1926,82 +1940,83 @@ handle_service_response (void *cls, | |||
1926 | 1940 | ||
1927 | GNUNET_assert (NULL != message); | 1941 | GNUNET_assert (NULL != message); |
1928 | session = (struct ServiceSession *) * tunnel_ctx; | 1942 | session = (struct ServiceSession *) * tunnel_ctx; |
1929 | if (ALICE != session->role){ | 1943 | if (ALICE != session->role) |
1930 | GNUNET_break_op(0); | 1944 | { |
1945 | GNUNET_break_op (0); | ||
1931 | return GNUNET_SYSERR; | 1946 | return GNUNET_SYSERR; |
1932 | } | 1947 | } |
1933 | 1948 | ||
1934 | count = session->used_element_count; | 1949 | count = session->used_element_count; |
1935 | session->product = NULL; | 1950 | session->product = NULL; |
1936 | session->state = SERVICE_RESPONSE_RECEIVED; | 1951 | session->state = SERVICE_RESPONSE_RECEIVED; |
1937 | 1952 | ||
1938 | //we need at least a peer and one message id to compare | 1953 | //we need at least a peer and one message id to compare |
1939 | if (sizeof (struct GNUNET_SCALARPRODUCT_service_response) > ntohs (msg->header.size)) | 1954 | if (sizeof (struct GNUNET_SCALARPRODUCT_service_response) > ntohs (msg->header.size)) |
1940 | { | 1955 | { |
1941 | GNUNET_break_op (0); | 1956 | GNUNET_break_op (0); |
1942 | goto invalid_msg; | 1957 | goto invalid_msg; |
1943 | } | 1958 | } |
1944 | used_element_count = ntohl (msg->used_element_count); | 1959 | used_element_count = ntohl (msg->used_element_count); |
1945 | msg_size = sizeof (struct GNUNET_SCALARPRODUCT_service_response) | 1960 | msg_size = sizeof (struct GNUNET_SCALARPRODUCT_service_response) |
1946 | + 2 * used_element_count * PAILLIER_ELEMENT_LENGTH | 1961 | + 2 * used_element_count * PAILLIER_ELEMENT_LENGTH |
1947 | + 2 * PAILLIER_ELEMENT_LENGTH; | 1962 | + 2 * PAILLIER_ELEMENT_LENGTH; |
1948 | //sanity check: is the message as long as the message_count fields suggests? | 1963 | //sanity check: is the message as long as the message_count fields suggests? |
1949 | if ((ntohs (msg->header.size) != msg_size) || (count != used_element_count)) | 1964 | if ((ntohs (msg->header.size) != msg_size) || (count != used_element_count)) |
1950 | { | 1965 | { |
1951 | GNUNET_break_op (0); | 1966 | GNUNET_break_op (0); |
1952 | goto invalid_msg; | 1967 | goto invalid_msg; |
1953 | } | 1968 | } |
1954 | 1969 | ||
1955 | //convert s | 1970 | //convert s |
1956 | current = (unsigned char *) &msg[1]; | 1971 | current = (unsigned char *) &msg[1]; |
1957 | if (0 != (rc = gcry_mpi_scan (&s, GCRYMPI_FMT_USG, current, | 1972 | if (0 != (rc = gcry_mpi_scan (&s, GCRYMPI_FMT_USG, current, |
1958 | PAILLIER_ELEMENT_LENGTH, &read))) | 1973 | PAILLIER_ELEMENT_LENGTH, &read))) |
1959 | { | 1974 | { |
1960 | LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc); | 1975 | LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc); |
1961 | GNUNET_break_op (0); | 1976 | GNUNET_break_op (0); |
1962 | goto invalid_msg; | 1977 | goto invalid_msg; |
1963 | } | 1978 | } |
1964 | current += PAILLIER_ELEMENT_LENGTH; | 1979 | current += PAILLIER_ELEMENT_LENGTH; |
1965 | //convert stick | 1980 | //convert stick |
1966 | if (0 != (rc = gcry_mpi_scan (&s_prime, GCRYMPI_FMT_USG, current, | 1981 | if (0 != (rc = gcry_mpi_scan (&s_prime, GCRYMPI_FMT_USG, current, |
1967 | PAILLIER_ELEMENT_LENGTH, &read))) | 1982 | PAILLIER_ELEMENT_LENGTH, &read))) |
1968 | { | 1983 | { |
1969 | LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc); | 1984 | LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc); |
1970 | GNUNET_break_op (0); | 1985 | GNUNET_break_op (0); |
1971 | goto invalid_msg; | 1986 | goto invalid_msg; |
1972 | } | 1987 | } |
1973 | current += PAILLIER_ELEMENT_LENGTH; | 1988 | current += PAILLIER_ELEMENT_LENGTH; |
1974 | 1989 | ||
1975 | r = GNUNET_malloc (sizeof (gcry_mpi_t) * count); | 1990 | r = GNUNET_malloc (sizeof (gcry_mpi_t) * count); |
1976 | // Convert each kp[] to its MPI_value | 1991 | // Convert each kp[] to its MPI_value |
1977 | for (i = 0; i < count; i++) | 1992 | for (i = 0; i < count; i++) |
1993 | { | ||
1994 | if (0 != (rc = gcry_mpi_scan (&r[i], GCRYMPI_FMT_USG, current, | ||
1995 | PAILLIER_ELEMENT_LENGTH, &read))) | ||
1978 | { | 1996 | { |
1979 | if (0 != (rc = gcry_mpi_scan (&r[i], GCRYMPI_FMT_USG, current, | 1997 | LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc); |
1980 | PAILLIER_ELEMENT_LENGTH, &read))) | 1998 | GNUNET_break_op (0); |
1981 | { | 1999 | goto invalid_msg; |
1982 | LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc); | ||
1983 | GNUNET_break_op (0); | ||
1984 | goto invalid_msg; | ||
1985 | } | ||
1986 | current += PAILLIER_ELEMENT_LENGTH; | ||
1987 | } | 2000 | } |
2001 | current += PAILLIER_ELEMENT_LENGTH; | ||
2002 | } | ||
1988 | 2003 | ||
1989 | 2004 | ||
1990 | r_prime = GNUNET_malloc (sizeof (gcry_mpi_t) * count); | 2005 | r_prime = GNUNET_malloc (sizeof (gcry_mpi_t) * count); |
1991 | // Convert each kq[] to its MPI_value | 2006 | // Convert each kq[] to its MPI_value |
1992 | for (i = 0; i < count; i++) | 2007 | for (i = 0; i < count; i++) |
2008 | { | ||
2009 | if (0 != (rc = gcry_mpi_scan (&r_prime[i], GCRYMPI_FMT_USG, current, | ||
2010 | PAILLIER_ELEMENT_LENGTH, &read))) | ||
1993 | { | 2011 | { |
1994 | if (0 != (rc = gcry_mpi_scan (&r_prime[i], GCRYMPI_FMT_USG, current, | 2012 | LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc); |
1995 | PAILLIER_ELEMENT_LENGTH, &read))) | 2013 | GNUNET_break_op (0); |
1996 | { | 2014 | goto invalid_msg; |
1997 | LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc); | ||
1998 | GNUNET_break_op (0); | ||
1999 | goto invalid_msg; | ||
2000 | } | ||
2001 | current += PAILLIER_ELEMENT_LENGTH; | ||
2002 | } | 2015 | } |
2016 | current += PAILLIER_ELEMENT_LENGTH; | ||
2017 | } | ||
2003 | session->product = compute_scalar_product (session, r, r_prime, s, s_prime); | 2018 | session->product = compute_scalar_product (session, r, r_prime, s, s_prime); |
2004 | 2019 | ||
2005 | invalid_msg: | 2020 | invalid_msg: |
2006 | if (s) | 2021 | if (s) |
2007 | gcry_mpi_release (s); | 2022 | gcry_mpi_release (s); |
@@ -2013,18 +2028,19 @@ invalid_msg: | |||
2013 | if (r_prime[i]) gcry_mpi_release (r_prime[i]); | 2028 | if (r_prime[i]) gcry_mpi_release (r_prime[i]); |
2014 | GNUNET_free_non_null (r); | 2029 | GNUNET_free_non_null (r); |
2015 | GNUNET_free_non_null (r_prime); | 2030 | GNUNET_free_non_null (r_prime); |
2016 | 2031 | ||
2017 | session->tunnel = NULL; | 2032 | session->tunnel = NULL; |
2018 | // send message with product to client | 2033 | // send message with product to client |
2019 | session->client_notification_task = | 2034 | session->client_notification_task = |
2020 | GNUNET_SCHEDULER_add_now (&prepare_client_response, | 2035 | GNUNET_SCHEDULER_add_now (&prepare_client_response, |
2021 | session); | 2036 | session); |
2022 | // the tunnel has done its job, terminate our connection and the tunnel | 2037 | // the tunnel has done its job, terminate our connection and the tunnel |
2023 | // the peer will be notified that the tunnel was destroyed via tunnel_destruction_handler | 2038 | // the peer will be notified that the tunnel was destroyed via tunnel_destruction_handler |
2024 | // just close the connection, as recommended by Christian | 2039 | // just close the connection, as recommended by Christian |
2025 | return GNUNET_SYSERR; | 2040 | return GNUNET_SYSERR; |
2026 | } | 2041 | } |
2027 | 2042 | ||
2043 | |||
2028 | /** | 2044 | /** |
2029 | * Task run during shutdown. | 2045 | * Task run during shutdown. |
2030 | * | 2046 | * |
@@ -2043,8 +2059,10 @@ shutdown_task (void *cls, | |||
2043 | // terminate all owned open tunnels. | 2059 | // terminate all owned open tunnels. |
2044 | for (session = from_client_head; NULL != session; session = session->next) | 2060 | for (session = from_client_head; NULL != session; session = session->next) |
2045 | { | 2061 | { |
2046 | if (FINALIZED != session->state) | 2062 | if ((FINALIZED != session->state) && (NULL != session->tunnel)){ |
2047 | GNUNET_MESH_tunnel_destroy (session->tunnel); | 2063 | GNUNET_MESH_tunnel_destroy (session->tunnel); |
2064 | session->tunnel = NULL; | ||
2065 | } | ||
2048 | if (GNUNET_SCHEDULER_NO_TASK != session->client_notification_task) | 2066 | if (GNUNET_SCHEDULER_NO_TASK != session->client_notification_task) |
2049 | { | 2067 | { |
2050 | GNUNET_SCHEDULER_cancel (session->client_notification_task); | 2068 | GNUNET_SCHEDULER_cancel (session->client_notification_task); |
@@ -2055,18 +2073,23 @@ shutdown_task (void *cls, | |||
2055 | GNUNET_SCHEDULER_cancel (session->service_request_task); | 2073 | GNUNET_SCHEDULER_cancel (session->service_request_task); |
2056 | session->service_request_task = GNUNET_SCHEDULER_NO_TASK; | 2074 | session->service_request_task = GNUNET_SCHEDULER_NO_TASK; |
2057 | } | 2075 | } |
2058 | if (NULL != session->client){ | 2076 | if (NULL != session->client) |
2059 | GNUNET_SERVER_client_disconnect(session->client); | 2077 | { |
2078 | GNUNET_SERVER_client_disconnect (session->client); | ||
2060 | session->client = NULL; | 2079 | session->client = NULL; |
2061 | } | 2080 | } |
2062 | } | 2081 | } |
2063 | for (session = from_service_head; NULL != session; session = session->next) | 2082 | for (session = from_service_head; NULL != session; session = from_service_head) |
2064 | 2083 | if (NULL != session->tunnel){ | |
2065 | if (my_mesh) | 2084 | GNUNET_MESH_tunnel_destroy (session->tunnel); |
2066 | { | 2085 | session->tunnel = NULL; |
2067 | GNUNET_MESH_disconnect (my_mesh); | ||
2068 | my_mesh = NULL; | ||
2069 | } | 2086 | } |
2087 | |||
2088 | if (my_mesh) | ||
2089 | { | ||
2090 | GNUNET_MESH_disconnect (my_mesh); | ||
2091 | my_mesh = NULL; | ||
2092 | } | ||
2070 | } | 2093 | } |
2071 | 2094 | ||
2072 | 2095 | ||
@@ -2105,18 +2128,18 @@ run (void *cls, | |||
2105 | &handle_client_disconnect, | 2128 | &handle_client_disconnect, |
2106 | NULL); | 2129 | NULL); |
2107 | GNUNET_break (GNUNET_OK == | 2130 | GNUNET_break (GNUNET_OK == |
2108 | GNUNET_CRYPTO_get_host_identity (c, | 2131 | GNUNET_CRYPTO_get_host_identity (c, |
2109 | &me)); | 2132 | &me)); |
2110 | my_mesh = GNUNET_MESH_connect (c, NULL, | 2133 | my_mesh = GNUNET_MESH_connect (c, NULL, |
2111 | &tunnel_incoming_handler, | 2134 | &tunnel_incoming_handler, |
2112 | &tunnel_destruction_handler, | 2135 | &tunnel_destruction_handler, |
2113 | mesh_handlers, ports); | 2136 | mesh_handlers, ports); |
2114 | if (!my_mesh) | 2137 | if (!my_mesh) |
2115 | { | 2138 | { |
2116 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Connect to MESH failed\n")); | 2139 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Connect to MESH failed\n")); |
2117 | GNUNET_SCHEDULER_shutdown (); | 2140 | GNUNET_SCHEDULER_shutdown (); |
2118 | return; | 2141 | return; |
2119 | } | 2142 | } |
2120 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Mesh initialized\n")); | 2143 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Mesh initialized\n")); |
2121 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, | 2144 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, |
2122 | &shutdown_task, | 2145 | &shutdown_task, |