diff options
author | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2019-12-27 15:12:45 +0900 |
---|---|---|
committer | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2019-12-27 15:12:45 +0900 |
commit | 44f0712f20579a9b22a4e93f92d771870382f20e (patch) | |
tree | 75e6ac7aa4ecee4f8c5a3bc730f3c5613a8b362e /src/transport/gnunet-communicator-tcp.c | |
parent | 852b6710fb70b3943e2b2f02252bfa58bca3ce45 (diff) | |
download | gnunet-44f0712f20579a9b22a4e93f92d771870382f20e.tar.gz gnunet-44f0712f20579a9b22a4e93f92d771870382f20e.zip |
actually fix rekey
Diffstat (limited to 'src/transport/gnunet-communicator-tcp.c')
-rw-r--r-- | src/transport/gnunet-communicator-tcp.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/src/transport/gnunet-communicator-tcp.c b/src/transport/gnunet-communicator-tcp.c index 107a37838..63e980204 100644 --- a/src/transport/gnunet-communicator-tcp.c +++ b/src/transport/gnunet-communicator-tcp.c | |||
@@ -866,7 +866,6 @@ static void | |||
866 | do_rekey (struct Queue *queue, const struct TCPRekey *rekey) | 866 | do_rekey (struct Queue *queue, const struct TCPRekey *rekey) |
867 | { | 867 | { |
868 | struct TcpHandshakeSignature thp; | 868 | struct TcpHandshakeSignature thp; |
869 | |||
870 | thp.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY); | 869 | thp.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY); |
871 | thp.purpose.size = htonl (sizeof(thp)); | 870 | thp.purpose.size = htonl (sizeof(thp)); |
872 | thp.sender = queue->target; | 871 | thp.sender = queue->target; |
@@ -943,7 +942,7 @@ try_handle_plaintext (struct Queue *queue) | |||
943 | rekeyz = *rekey; | 942 | rekeyz = *rekey; |
944 | memset (&rekeyz.hmac, 0, sizeof(rekeyz.hmac)); | 943 | memset (&rekeyz.hmac, 0, sizeof(rekeyz.hmac)); |
945 | calculate_hmac (&queue->in_hmac, &rekeyz, sizeof(rekeyz), &tmac); | 944 | calculate_hmac (&queue->in_hmac, &rekeyz, sizeof(rekeyz), &tmac); |
946 | if (0 != memcmp (&tmac, &box->hmac, sizeof(tmac))) | 945 | if (0 != memcmp (&tmac, &rekey->hmac, sizeof(tmac))) |
947 | { | 946 | { |
948 | GNUNET_break_op (0); | 947 | GNUNET_break_op (0); |
949 | queue_finish (queue); | 948 | queue_finish (queue); |
@@ -1027,6 +1026,7 @@ queue_read (void *cls) | |||
1027 | queue->cread_off); | 1026 | queue->cread_off); |
1028 | size_t done; | 1027 | size_t done; |
1029 | size_t total; | 1028 | size_t total; |
1029 | size_t old_pread_off = queue->pread_off; | ||
1030 | 1030 | ||
1031 | GNUNET_assert (0 == | 1031 | GNUNET_assert (0 == |
1032 | gcry_cipher_decrypt (queue->in_cipher, | 1032 | gcry_cipher_decrypt (queue->in_cipher, |
@@ -1036,8 +1036,7 @@ queue_read (void *cls) | |||
1036 | max)); | 1036 | max)); |
1037 | queue->pread_off += max; | 1037 | queue->pread_off += max; |
1038 | total = 0; | 1038 | total = 0; |
1039 | while ((GNUNET_NO == queue->rekeyed) && | 1039 | while (0 != (done = try_handle_plaintext (queue))) |
1040 | (0 != (done = try_handle_plaintext (queue)))) | ||
1041 | { | 1040 | { |
1042 | /* 'done' bytes of plaintext were used, shift buffer */ | 1041 | /* 'done' bytes of plaintext were used, shift buffer */ |
1043 | GNUNET_assert (done <= queue->pread_off); | 1042 | GNUNET_assert (done <= queue->pread_off); |
@@ -1049,16 +1048,22 @@ queue_read (void *cls) | |||
1049 | queue->pread_off - done); | 1048 | queue->pread_off - done); |
1050 | queue->pread_off -= done; | 1049 | queue->pread_off -= done; |
1051 | total += done; | 1050 | total += done; |
1051 | /* The last plaintext was a rekey, abort for now */ | ||
1052 | if (GNUNET_YES == queue->rekeyed) | ||
1053 | break; | ||
1052 | } | 1054 | } |
1053 | /* when we encounter a rekey message, the decryption above uses the | 1055 | /* when we encounter a rekey message, the decryption above uses the |
1054 | wrong key for everything after the rekey; in that case, we have | 1056 | wrong key for everything after the rekey; in that case, we have |
1055 | to re-do the decryption at 'total' instead of at 'max'. If there | 1057 | to re-do the decryption at 'total' instead of at 'max'. |
1056 | is no rekey and the last message is incomplete (max > total), | 1058 | However, we have to take into account that the plaintext buffer may have |
1059 | already contained data and not jumpt too far ahead in the ciphertext. | ||
1060 | If there is no rekey and the last message is incomplete (max > total), | ||
1057 | it is safe to keep the decryption so we shift by 'max' */ | 1061 | it is safe to keep the decryption so we shift by 'max' */ |
1058 | if (GNUNET_YES == queue->rekeyed) | 1062 | if (GNUNET_YES == queue->rekeyed) |
1059 | { | 1063 | { |
1060 | max = total; | 1064 | max = total - old_pread_off; |
1061 | queue->rekeyed = GNUNET_NO; | 1065 | queue->rekeyed = GNUNET_NO; |
1066 | queue->pread_off = 0; | ||
1062 | } | 1067 | } |
1063 | memmove (queue->cread_buf, &queue->cread_buf[max], queue->cread_off - max); | 1068 | memmove (queue->cread_buf, &queue->cread_buf[max], queue->cread_off - max); |
1064 | queue->cread_off -= max; | 1069 | queue->cread_off -= max; |
@@ -1278,6 +1283,7 @@ inject_rekey (struct Queue *queue) | |||
1278 | &thp.purpose, | 1283 | &thp.purpose, |
1279 | &rekey.sender_sig)); | 1284 | &rekey.sender_sig)); |
1280 | calculate_hmac (&queue->out_hmac, &rekey, sizeof(rekey), &rekey.hmac); | 1285 | calculate_hmac (&queue->out_hmac, &rekey, sizeof(rekey), &rekey.hmac); |
1286 | /* Encrypt rekey message with 'old' cipher */ | ||
1281 | GNUNET_assert (0 == | 1287 | GNUNET_assert (0 == |
1282 | gcry_cipher_encrypt (queue->out_cipher, | 1288 | gcry_cipher_encrypt (queue->out_cipher, |
1283 | &queue->cwrite_buf[queue->cwrite_off], | 1289 | &queue->cwrite_buf[queue->cwrite_off], |
@@ -1285,6 +1291,9 @@ inject_rekey (struct Queue *queue) | |||
1285 | &rekey, | 1291 | &rekey, |
1286 | sizeof(rekey))); | 1292 | sizeof(rekey))); |
1287 | queue->cwrite_off += sizeof(rekey); | 1293 | queue->cwrite_off += sizeof(rekey); |
1294 | /* Setup new cipher for successive messages */ | ||
1295 | gcry_cipher_close (queue->out_cipher); | ||
1296 | setup_out_cipher (queue); | ||
1288 | } | 1297 | } |
1289 | 1298 | ||
1290 | 1299 | ||
@@ -1351,8 +1360,6 @@ queue_write (void *cls) | |||
1351 | GNUNET_TIME_absolute_get_remaining (queue->rekey_time).rel_value_us))) | 1360 | GNUNET_TIME_absolute_get_remaining (queue->rekey_time).rel_value_us))) |
1352 | { | 1361 | { |
1353 | inject_rekey (queue); | 1362 | inject_rekey (queue); |
1354 | gcry_cipher_close (queue->out_cipher); | ||
1355 | setup_out_cipher (queue); | ||
1356 | } | 1363 | } |
1357 | if ((0 == queue->pwrite_off) && (! queue->finishing) && | 1364 | if ((0 == queue->pwrite_off) && (! queue->finishing) && |
1358 | (GNUNET_YES == queue->mq_awaits_continue)) | 1365 | (GNUNET_YES == queue->mq_awaits_continue)) |