diff options
author | Martin Schanzenbach <schanzen@gnunet.org> | 2023-07-30 16:54:35 +0200 |
---|---|---|
committer | Martin Schanzenbach <schanzen@gnunet.org> | 2023-07-30 16:54:35 +0200 |
commit | bb4036824c1ae6712aea506a2fa4c77cad053fb1 (patch) | |
tree | 3c479c52f3004c62e560e5a481b31127cf4c3c3e /src/transport/gnunet-communicator-udp.c | |
parent | 8e62ce85d4e6b0d8b63dab3d63488f000d01c0d0 (diff) | |
download | gnunet-bb4036824c1ae6712aea506a2fa4c77cad053fb1.tar.gz gnunet-bb4036824c1ae6712aea506a2fa4c77cad053fb1.zip |
TNG: UDP communicator. Improve shared secret management.
Diffstat (limited to 'src/transport/gnunet-communicator-udp.c')
-rw-r--r-- | src/transport/gnunet-communicator-udp.c | 102 |
1 files changed, 50 insertions, 52 deletions
diff --git a/src/transport/gnunet-communicator-udp.c b/src/transport/gnunet-communicator-udp.c index ab8dd6816..eef6634b7 100644 --- a/src/transport/gnunet-communicator-udp.c +++ b/src/transport/gnunet-communicator-udp.c | |||
@@ -997,19 +997,15 @@ kce_generate (struct SharedSecret *ss, uint32_t seq) | |||
997 | * @param withoutKce If GNUNET_YES shared secrets with kce will not be destroyed. | 997 | * @param withoutKce If GNUNET_YES shared secrets with kce will not be destroyed. |
998 | */ | 998 | */ |
999 | static int | 999 | static int |
1000 | secret_destroy (struct SharedSecret *ss, int withoutKce) | 1000 | secret_destroy (struct SharedSecret *ss) |
1001 | { | 1001 | { |
1002 | struct SenderAddress *sender; | 1002 | struct SenderAddress *sender; |
1003 | struct ReceiverAddress *receiver; | 1003 | struct ReceiverAddress *receiver; |
1004 | struct KeyCacheEntry *kce; | 1004 | struct KeyCacheEntry *kce; |
1005 | 1005 | ||
1006 | if (withoutKce && (ss->sequence_allowed > 0)) | ||
1007 | return GNUNET_NO; | ||
1008 | |||
1009 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1006 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1010 | "secret %s destroy %u %u\n", | 1007 | "secret %s destroy %u\n", |
1011 | GNUNET_h2s (&ss->master), | 1008 | GNUNET_h2s (&ss->master), |
1012 | withoutKce, | ||
1013 | ss->sequence_allowed); | 1009 | ss->sequence_allowed); |
1014 | if (NULL != (sender = ss->sender)) | 1010 | if (NULL != (sender = ss->sender)) |
1015 | { | 1011 | { |
@@ -1369,62 +1365,37 @@ setup_shared_secret_ephemeral (struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral, | |||
1369 | static void | 1365 | static void |
1370 | setup_receiver_mq (struct ReceiverAddress *receiver); | 1366 | setup_receiver_mq (struct ReceiverAddress *receiver); |
1371 | 1367 | ||
1368 | |||
1372 | /** | 1369 | /** |
1373 | * Destroying all secrets. Depending on parameter we keep those secrets having a kce. | 1370 | * Best effort try to purge some secrets. |
1371 | * Ideally those, not ACKed. | ||
1374 | * | 1372 | * |
1375 | * @param ss The secret we will not destroy. | 1373 | * @param ss_list_tail the oldest secret in the list of interest. |
1376 | * @param withoutKce If GNUNET_YES shared secrets with kce will not be destroyed. | 1374 | * @return GNUNET_YES if any secret was deleted. |
1377 | */ | 1375 | */ |
1378 | static void | 1376 | static enum GNUNET_GenericReturnValue |
1379 | destroy_all_secrets (struct SharedSecret *ss, int withoutKce) | 1377 | purge_secrets (struct SharedSecret *ss_list_tail) |
1380 | { | 1378 | { |
1381 | struct SenderAddress *sender; | ||
1382 | struct ReceiverAddress *receiver; | ||
1383 | struct SharedSecret *ss_to_destroy; | ||
1384 | struct SharedSecret *ss_start; | ||
1385 | struct SharedSecret *pos; | 1379 | struct SharedSecret *pos; |
1386 | int at_least_one_destroyed = GNUNET_NO; | 1380 | struct SharedSecret *ss_to_purge; |
1387 | 1381 | int deleted = 0; | |
1388 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1389 | "Starting destroy all withoutKce: %u.\n", | ||
1390 | withoutKce); | ||
1391 | |||
1392 | if (NULL != (sender = ss->sender)) | ||
1393 | { | ||
1394 | ss_start = sender->ss_head; | ||
1395 | } | ||
1396 | else if (NULL != (receiver = ss->receiver)) | ||
1397 | { | ||
1398 | ss_start = receiver->ss_head; | ||
1399 | } | ||
1400 | else | ||
1401 | { | ||
1402 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1403 | "Shared secret has no sender or receiver!\n"); | ||
1404 | return; | ||
1405 | } | ||
1406 | 1382 | ||
1407 | pos = ss_start; | 1383 | pos = ss_list_tail; |
1408 | while (NULL != pos) | 1384 | while (NULL != pos) |
1409 | { | 1385 | { |
1410 | ss_to_destroy = pos; | 1386 | ss_to_purge = pos; |
1411 | pos = pos->next; | 1387 | pos = pos->prev; |
1412 | 1388 | ||
1413 | // FIXME This is broken. the variable gets overwritten and it is unclear | 1389 | if ((NULL == ss_to_purge->kce_head) || |
1414 | // what this is supposed to achieve. | 1390 | (rekey_max_bytes <= ss_to_purge->bytes_sent)) |
1415 | if (ss != ss_to_destroy) | 1391 | { |
1416 | at_least_one_destroyed = secret_destroy (ss_to_destroy, withoutKce); | 1392 | secret_destroy (ss_to_purge); |
1417 | } | 1393 | deleted++; |
1418 | 1394 | } | |
1419 | if ((ss != ss_start) && ! at_least_one_destroyed) | ||
1420 | { | ||
1421 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1422 | "Really destroying all.\n"); | ||
1423 | destroy_all_secrets (ss_start, GNUNET_NO); | ||
1424 | } | 1395 | } |
1425 | 1396 | ||
1426 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1397 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1427 | "Finished destroy all.\n"); | 1398 | "Finished purging all.\n"); |
1428 | } | 1399 | } |
1429 | 1400 | ||
1430 | 1401 | ||
@@ -1468,7 +1439,6 @@ add_acks (struct SharedSecret *ss, int acks_to_add) | |||
1468 | 1439 | ||
1469 | GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss); | 1440 | GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss); |
1470 | GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss); | 1441 | GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss); |
1471 | // destroy_all_secrets (ss, GNUNET_YES); | ||
1472 | } | 1442 | } |
1473 | 1443 | ||
1474 | 1444 | ||
@@ -1683,6 +1653,14 @@ try_handle_plaintext (struct SenderAddress *sender, | |||
1683 | buf_pos += ntohs (hdr->size); | 1653 | buf_pos += ntohs (hdr->size); |
1684 | bytes_remaining -= ntohs (hdr->size); | 1654 | bytes_remaining -= ntohs (hdr->size); |
1685 | pass_plaintext_to_core (sender, buf_pos, bytes_remaining); | 1655 | pass_plaintext_to_core (sender, buf_pos, bytes_remaining); |
1656 | if (sender->num_secrets > MAX_SECRETS) | ||
1657 | { | ||
1658 | if (GNUNET_NO == purge_secrets (sender->ss_tail)) | ||
1659 | { | ||
1660 | // No secret purged. Delete oldest. | ||
1661 | secret_destroy (sender->ss_tail); | ||
1662 | } | ||
1663 | } | ||
1686 | break; | 1664 | break; |
1687 | case GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK: | 1665 | case GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK: |
1688 | /* lookup master secret by 'cmac', then update sequence_max */ | 1666 | /* lookup master secret by 'cmac', then update sequence_max */ |
@@ -2138,6 +2116,14 @@ sock_read (void *cls) | |||
2138 | 1, | 2116 | 1, |
2139 | GNUNET_NO); | 2117 | GNUNET_NO); |
2140 | try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc)); | 2118 | try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc)); |
2119 | if (sender->num_secrets > MAX_SECRETS) | ||
2120 | { | ||
2121 | if (GNUNET_NO == purge_secrets (sender->ss_tail)) | ||
2122 | { | ||
2123 | // No secret purged. Delete oldest. | ||
2124 | secret_destroy (sender->ss_tail); | ||
2125 | } | ||
2126 | } | ||
2141 | } | 2127 | } |
2142 | } | 2128 | } |
2143 | } | 2129 | } |
@@ -2333,7 +2319,11 @@ send_msg_with_kx (const struct GNUNET_MessageHeader *msg, struct | |||
2333 | 2319 | ||
2334 | if (receiver->num_secrets > MAX_SECRETS) | 2320 | if (receiver->num_secrets > MAX_SECRETS) |
2335 | { | 2321 | { |
2336 | destroy_all_secrets (ss, GNUNET_YES); | 2322 | if (GNUNET_NO == purge_secrets (receiver->ss_tail)) |
2323 | { | ||
2324 | // No secret purged. Delete oldest. | ||
2325 | secret_destroy (receiver->ss_tail); | ||
2326 | } | ||
2337 | } | 2327 | } |
2338 | 2328 | ||
2339 | setup_cipher (&ss->master, 0, &out_cipher); | 2329 | setup_cipher (&ss->master, 0, &out_cipher); |
@@ -2468,6 +2458,14 @@ mq_send_d (struct GNUNET_MQ_Handle *mq, | |||
2468 | } | 2458 | } |
2469 | reschedule_receiver_timeout (receiver); | 2459 | reschedule_receiver_timeout (receiver); |
2470 | 2460 | ||
2461 | if (receiver->num_secrets > MAX_SECRETS) | ||
2462 | { | ||
2463 | if (GNUNET_NO == purge_secrets (receiver->ss_tail)) | ||
2464 | { | ||
2465 | // No secret purged. Delete oldest. | ||
2466 | secret_destroy (receiver->ss_tail); | ||
2467 | } | ||
2468 | } | ||
2471 | /* begin "BOX" encryption method, scan for ACKs from tail! */ | 2469 | /* begin "BOX" encryption method, scan for ACKs from tail! */ |
2472 | for (ss = receiver->ss_tail; NULL != ss; ss = ss->prev) | 2470 | for (ss = receiver->ss_tail; NULL != ss; ss = ss->prev) |
2473 | { | 2471 | { |