aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/transport/gnunet-communicator-tcp.c25
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
866do_rekey (struct Queue *queue, const struct TCPRekey *rekey) 866do_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))