diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-01-28 22:51:58 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-01-28 22:51:58 +0100 |
commit | d50ef7d2d9631f56be7ad0d74d21fd78ed9d4cc2 (patch) | |
tree | 99b6a300c9b8ee0b24e64bb726e364a8c6881098 /src/cadet/gnunet-service-cadet-new_tunnels.c | |
parent | 7b2e8cd1090059768603444aff364317f955874d (diff) | |
download | gnunet-d50ef7d2d9631f56be7ad0d74d21fd78ed9d4cc2.tar.gz gnunet-d50ef7d2d9631f56be7ad0d74d21fd78ed9d4cc2.zip |
complete new KX implementation, including KX_AUTH defense against KX-injection based reset attacks
Diffstat (limited to 'src/cadet/gnunet-service-cadet-new_tunnels.c')
-rw-r--r-- | src/cadet/gnunet-service-cadet-new_tunnels.c | 571 |
1 files changed, 445 insertions, 126 deletions
diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.c b/src/cadet/gnunet-service-cadet-new_tunnels.c index 4d4cdc2dc..f98f46b9b 100644 --- a/src/cadet/gnunet-service-cadet-new_tunnels.c +++ b/src/cadet/gnunet-service-cadet-new_tunnels.c | |||
@@ -24,10 +24,6 @@ | |||
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | * | 25 | * |
26 | * FIXME: | 26 | * FIXME: |
27 | * - KX: | ||
28 | * + clean up KX logic, including adding sender authentication | ||
29 | * + implement rekeying | ||
30 | * + check KX estate machine -- make sure it is never stuck! | ||
31 | * - connection management | 27 | * - connection management |
32 | * + properly (evaluate, kill old ones, search for new ones) | 28 | * + properly (evaluate, kill old ones, search for new ones) |
33 | * + when managing connections, distinguish those that | 29 | * + when managing connections, distinguish those that |
@@ -62,6 +58,12 @@ | |||
62 | #define IDLE_DESTROY_DELAY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 90) | 58 | #define IDLE_DESTROY_DELAY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 90) |
63 | 59 | ||
64 | /** | 60 | /** |
61 | * How long do we wait initially before retransmitting the KX? | ||
62 | * TODO: replace by 2 RTT if/once we have connection-level RTT data! | ||
63 | */ | ||
64 | #define INITIAL_KX_RETRY_DELAY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 250) | ||
65 | |||
66 | /** | ||
65 | * Maximum number of skipped keys we keep in memory per tunnel. | 67 | * Maximum number of skipped keys we keep in memory per tunnel. |
66 | */ | 68 | */ |
67 | #define MAX_SKIPPED_KEYS 64 | 69 | #define MAX_SKIPPED_KEYS 64 |
@@ -171,12 +173,16 @@ struct CadetTunnelAxolotl | |||
171 | struct GNUNET_CRYPTO_SymmetricSessionKey CKr; | 173 | struct GNUNET_CRYPTO_SymmetricSessionKey CKr; |
172 | 174 | ||
173 | /** | 175 | /** |
174 | * ECDH for key exchange (A0 / B0). | 176 | * ECDH for key exchange (A0 / B0). Note that for the |
177 | * 'unverified_ax', this member is an alias with the main | ||
178 | * 't->ax.kx_0' value, so do not free it! | ||
175 | */ | 179 | */ |
176 | struct GNUNET_CRYPTO_EcdhePrivateKey *kx_0; | 180 | struct GNUNET_CRYPTO_EcdhePrivateKey *kx_0; |
177 | 181 | ||
178 | /** | 182 | /** |
179 | * ECDH Ratchet key (our private key in the current DH). | 183 | * ECDH Ratchet key (our private key in the current DH). Note that |
184 | * for the 'unverified_ax', this member is an alias with the main | ||
185 | * 't->ax.kx_0' value, so do not free it! | ||
180 | */ | 186 | */ |
181 | struct GNUNET_CRYPTO_EcdhePrivateKey *DHRs; | 187 | struct GNUNET_CRYPTO_EcdhePrivateKey *DHRs; |
182 | 188 | ||
@@ -421,6 +427,11 @@ struct CadetTunnel | |||
421 | */ | 427 | */ |
422 | enum CadetTunnelEState estate; | 428 | enum CadetTunnelEState estate; |
423 | 429 | ||
430 | /** | ||
431 | * Force triggering KX_AUTH independent of @e estate. | ||
432 | */ | ||
433 | int kx_auth_requested; | ||
434 | |||
424 | }; | 435 | }; |
425 | 436 | ||
426 | 437 | ||
@@ -460,17 +471,24 @@ estate2s (enum CadetTunnelEState es) | |||
460 | 471 | ||
461 | switch (es) | 472 | switch (es) |
462 | { | 473 | { |
463 | case CADET_TUNNEL_KEY_UNINITIALIZED: | 474 | case CADET_TUNNEL_KEY_UNINITIALIZED: |
464 | return "CADET_TUNNEL_KEY_UNINITIALIZED"; | 475 | return "CADET_TUNNEL_KEY_UNINITIALIZED"; |
465 | case CADET_TUNNEL_KEY_SENT: | 476 | case CADET_TUNNEL_KEY_AX_RECV: |
466 | return "CADET_TUNNEL_KEY_SENT"; | 477 | return "CADET_TUNNEL_KEY_AX_RECV"; |
467 | case CADET_TUNNEL_KEY_PING: | 478 | case CADET_TUNNEL_KEY_AX_SENT: |
468 | return "CADET_TUNNEL_KEY_PING"; | 479 | return "CADET_TUNNEL_KEY_AX_SENT"; |
469 | case CADET_TUNNEL_KEY_OK: | 480 | case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: |
470 | return "CADET_TUNNEL_KEY_OK"; | 481 | return "CADET_TUNNEL_KEY_AX_SENT_AND_RECV"; |
471 | default: | 482 | case CADET_TUNNEL_KEY_AX_AUTH_SENT: |
472 | SPRINTF (buf, "%u (UNKNOWN STATE)", es); | 483 | return "CADET_TUNNEL_KEY_AX_AUTH_SENT"; |
473 | return buf; | 484 | case CADET_TUNNEL_KEY_OK: |
485 | return "CADET_TUNNEL_KEY_OK"; | ||
486 | default: | ||
487 | GNUNET_snprintf (buf, | ||
488 | sizeof (buf), | ||
489 | "%u (UNKNOWN STATE)", | ||
490 | es); | ||
491 | return buf; | ||
474 | } | 492 | } |
475 | } | 493 | } |
476 | 494 | ||
@@ -602,6 +620,8 @@ static void | |||
602 | new_ephemeral (struct CadetTunnelAxolotl *ax) | 620 | new_ephemeral (struct CadetTunnelAxolotl *ax) |
603 | { | 621 | { |
604 | GNUNET_free_non_null (ax->DHRs); | 622 | GNUNET_free_non_null (ax->DHRs); |
623 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
624 | "Creating new ephemeral ratchet key (DHRs)\n"); | ||
605 | ax->DHRs = GNUNET_CRYPTO_ecdhe_key_create (); | 625 | ax->DHRs = GNUNET_CRYPTO_ecdhe_key_create (); |
606 | } | 626 | } |
607 | 627 | ||
@@ -1227,10 +1247,10 @@ GCT_change_estate (struct CadetTunnel *t, | |||
1227 | 1247 | ||
1228 | t->estate = state; | 1248 | t->estate = state; |
1229 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1249 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1230 | "Tunnel %s estate changed from %d to %d\n", | 1250 | "%s estate changed from %s to %s\n", |
1231 | GCT_2s (t), | 1251 | GCT_2s (t), |
1232 | old, | 1252 | estate2s (old), |
1233 | state); | 1253 | estate2s (state)); |
1234 | 1254 | ||
1235 | if ( (CADET_TUNNEL_KEY_OK != old) && | 1255 | if ( (CADET_TUNNEL_KEY_OK != old) && |
1236 | (CADET_TUNNEL_KEY_OK == t->estate) ) | 1256 | (CADET_TUNNEL_KEY_OK == t->estate) ) |
@@ -1244,6 +1264,10 @@ GCT_change_estate (struct CadetTunnel *t, | |||
1244 | GNUNET_CONTAINER_multihashmap32_iterate (t->channels, | 1264 | GNUNET_CONTAINER_multihashmap32_iterate (t->channels, |
1245 | ¬ify_tunnel_up_cb, | 1265 | ¬ify_tunnel_up_cb, |
1246 | t); | 1266 | t); |
1267 | if (NULL != t->send_task) | ||
1268 | GNUNET_SCHEDULER_cancel (t->send_task); | ||
1269 | t->send_task = GNUNET_SCHEDULER_add_now (&trigger_transmissions, | ||
1270 | t); | ||
1247 | } | 1271 | } |
1248 | } | 1272 | } |
1249 | 1273 | ||
@@ -1251,16 +1275,12 @@ GCT_change_estate (struct CadetTunnel *t, | |||
1251 | /** | 1275 | /** |
1252 | * Send a KX message. | 1276 | * Send a KX message. |
1253 | * | 1277 | * |
1254 | * FIXME: does not take care of sender-authentication yet! | ||
1255 | * | ||
1256 | * @param t Tunnel on which to send it. | 1278 | * @param t Tunnel on which to send it. |
1257 | * @param ax axolotl key context to use | 1279 | * @param ax axolotl key context to use |
1258 | * @param force_reply Force the other peer to reply with a KX message. | ||
1259 | */ | 1280 | */ |
1260 | static void | 1281 | static void |
1261 | send_kx (struct CadetTunnel *t, | 1282 | send_kx (struct CadetTunnel *t, |
1262 | struct CadetTunnelAxolotl *ax, | 1283 | struct CadetTunnelAxolotl *ax) |
1263 | int force_reply) | ||
1264 | { | 1284 | { |
1265 | struct CadetTConnection *ct; | 1285 | struct CadetTConnection *ct; |
1266 | struct CadetConnection *cc; | 1286 | struct CadetConnection *cc; |
@@ -1272,22 +1292,21 @@ send_kx (struct CadetTunnel *t, | |||
1272 | if (NULL == ct) | 1292 | if (NULL == ct) |
1273 | { | 1293 | { |
1274 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1294 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1275 | "Wanted to send KX on tunnel %s, but no connection is ready, deferring\n", | 1295 | "Wanted to send KX on %s, but no connection is ready, deferring\n", |
1276 | GCT_2s (t)); | 1296 | GCT_2s (t)); |
1297 | t->next_kx_attempt = GNUNET_TIME_absolute_get (); | ||
1277 | return; | 1298 | return; |
1278 | } | 1299 | } |
1279 | cc = ct->cc; | 1300 | cc = ct->cc; |
1280 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1301 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1281 | "Sending KX on tunnel %s using connection %s\n", | 1302 | "Sending KX on %s using %s in state %s\n", |
1282 | GCT_2s (t), | 1303 | GCT_2s (t), |
1283 | GCC_2s (ct->cc)); | 1304 | GCC_2s (ct->cc), |
1305 | estate2s (t->estate)); | ||
1284 | 1306 | ||
1285 | // GNUNET_assert (GNUNET_NO == GCT_is_loopback (t)); | ||
1286 | env = GNUNET_MQ_msg (msg, | 1307 | env = GNUNET_MQ_msg (msg, |
1287 | GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX); | 1308 | GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX); |
1288 | flags = GNUNET_CADET_KX_FLAG_NONE; | 1309 | flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */ |
1289 | if (GNUNET_YES == force_reply) | ||
1290 | flags |= GNUNET_CADET_KX_FLAG_FORCE_REPLY; | ||
1291 | msg->flags = htonl (flags); | 1310 | msg->flags = htonl (flags); |
1292 | msg->cid = *GCC_get_id (cc); | 1311 | msg->cid = *GCC_get_id (cc); |
1293 | GNUNET_CRYPTO_ecdhe_key_get_public (ax->kx_0, | 1312 | GNUNET_CRYPTO_ecdhe_key_get_public (ax->kx_0, |
@@ -1295,13 +1314,88 @@ send_kx (struct CadetTunnel *t, | |||
1295 | GNUNET_CRYPTO_ecdhe_key_get_public (ax->DHRs, | 1314 | GNUNET_CRYPTO_ecdhe_key_get_public (ax->DHRs, |
1296 | &msg->ratchet_key); | 1315 | &msg->ratchet_key); |
1297 | ct->is_ready = GNUNET_NO; | 1316 | ct->is_ready = GNUNET_NO; |
1298 | GCC_transmit (cc, | ||
1299 | env); | ||
1300 | t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay); | 1317 | t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay); |
1301 | t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay); | 1318 | t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay); |
1302 | if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) | 1319 | if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) |
1303 | GCT_change_estate (t, | 1320 | GCT_change_estate (t, |
1304 | CADET_TUNNEL_KEY_SENT); | 1321 | CADET_TUNNEL_KEY_AX_SENT); |
1322 | else if (CADET_TUNNEL_KEY_AX_RECV == t->estate) | ||
1323 | GCT_change_estate (t, | ||
1324 | CADET_TUNNEL_KEY_AX_SENT_AND_RECV); | ||
1325 | GCC_transmit (cc, | ||
1326 | env); | ||
1327 | } | ||
1328 | |||
1329 | |||
1330 | /** | ||
1331 | * Send a KX_AUTH message. | ||
1332 | * | ||
1333 | * @param t Tunnel on which to send it. | ||
1334 | * @param ax axolotl key context to use | ||
1335 | * @param force_reply Force the other peer to reply with a KX_AUTH message | ||
1336 | * (set if we would like to transmit right now, but cannot) | ||
1337 | */ | ||
1338 | static void | ||
1339 | send_kx_auth (struct CadetTunnel *t, | ||
1340 | struct CadetTunnelAxolotl *ax, | ||
1341 | int force_reply) | ||
1342 | { | ||
1343 | struct CadetTConnection *ct; | ||
1344 | struct CadetConnection *cc; | ||
1345 | struct GNUNET_MQ_Envelope *env; | ||
1346 | struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg; | ||
1347 | enum GNUNET_CADET_KX_Flags flags; | ||
1348 | |||
1349 | ct = get_ready_connection (t); | ||
1350 | if (NULL == ct) | ||
1351 | { | ||
1352 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1353 | "Wanted to send KX_AUTH on %s, but no connection is ready, deferring\n", | ||
1354 | GCT_2s (t)); | ||
1355 | t->next_kx_attempt = GNUNET_TIME_absolute_get (); | ||
1356 | t->kx_auth_requested = GNUNET_YES; /* queue KX_AUTH independent of estate */ | ||
1357 | return; | ||
1358 | } | ||
1359 | t->kx_auth_requested = GNUNET_NO; /* clear flag */ | ||
1360 | cc = ct->cc; | ||
1361 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1362 | "Sending KX_AUTH on %s using %s\n", | ||
1363 | GCT_2s (t), | ||
1364 | GCC_2s (ct->cc)); | ||
1365 | |||
1366 | env = GNUNET_MQ_msg (msg, | ||
1367 | GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH); | ||
1368 | flags = GNUNET_CADET_KX_FLAG_NONE; | ||
1369 | if (GNUNET_YES == force_reply) | ||
1370 | flags |= GNUNET_CADET_KX_FLAG_FORCE_REPLY; | ||
1371 | msg->kx.flags = htonl (flags); | ||
1372 | msg->kx.cid = *GCC_get_id (cc); | ||
1373 | GNUNET_CRYPTO_ecdhe_key_get_public (ax->kx_0, | ||
1374 | &msg->kx.ephemeral_key); | ||
1375 | GNUNET_CRYPTO_ecdhe_key_get_public (ax->DHRs, | ||
1376 | &msg->kx.ratchet_key); | ||
1377 | /* Compute authenticator (this is the main difference to #send_kx()) */ | ||
1378 | GNUNET_CRYPTO_hash (&ax->RK, | ||
1379 | sizeof (ax->RK), | ||
1380 | &msg->auth); | ||
1381 | |||
1382 | /* Compute when to be triggered again; actual job will | ||
1383 | be scheduled via #connection_ready_cb() */ | ||
1384 | t->kx_retry_delay | ||
1385 | = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay); | ||
1386 | t->next_kx_attempt | ||
1387 | = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay); | ||
1388 | |||
1389 | /* Send via cc, mark it as unready */ | ||
1390 | ct->is_ready = GNUNET_NO; | ||
1391 | |||
1392 | /* Update state machine, unless we are already OK */ | ||
1393 | if (CADET_TUNNEL_KEY_OK != t->estate) | ||
1394 | GCT_change_estate (t, | ||
1395 | CADET_TUNNEL_KEY_AX_AUTH_SENT); | ||
1396 | |||
1397 | GCC_transmit (cc, | ||
1398 | env); | ||
1305 | } | 1399 | } |
1306 | 1400 | ||
1307 | 1401 | ||
@@ -1446,6 +1540,91 @@ update_ax_by_kx (struct CadetTunnelAxolotl *ax, | |||
1446 | 1540 | ||
1447 | 1541 | ||
1448 | /** | 1542 | /** |
1543 | * Try to redo the KX or KX_AUTH handshake, if we can. | ||
1544 | * | ||
1545 | * @param cls the `struct CadetTunnel` to do KX for. | ||
1546 | */ | ||
1547 | static void | ||
1548 | retry_kx (void *cls) | ||
1549 | { | ||
1550 | struct CadetTunnel *t = cls; | ||
1551 | struct CadetTunnelAxolotl *ax; | ||
1552 | |||
1553 | t->kx_task = NULL; | ||
1554 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1555 | "Trying to make KX progress on %s in state %s\n", | ||
1556 | GCT_2s (t), | ||
1557 | estate2s (t->estate)); | ||
1558 | switch (t->estate) | ||
1559 | { | ||
1560 | case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */ | ||
1561 | case CADET_TUNNEL_KEY_AX_SENT: /* trying again */ | ||
1562 | send_kx (t, | ||
1563 | &t->ax); | ||
1564 | break; | ||
1565 | case CADET_TUNNEL_KEY_AX_RECV: | ||
1566 | case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: | ||
1567 | /* We are responding, so only require reply | ||
1568 | if WE have a channel waiting. */ | ||
1569 | if (NULL != t->unverified_ax) | ||
1570 | { | ||
1571 | /* Send AX_AUTH so we might get this one verified */ | ||
1572 | ax = t->unverified_ax; | ||
1573 | } | ||
1574 | else | ||
1575 | { | ||
1576 | /* How can this be? */ | ||
1577 | GNUNET_break (0); | ||
1578 | ax = &t->ax; | ||
1579 | } | ||
1580 | send_kx_auth (t, | ||
1581 | ax, | ||
1582 | (0 == GCT_count_channels (t)) | ||
1583 | ? GNUNET_NO | ||
1584 | : GNUNET_YES); | ||
1585 | break; | ||
1586 | case CADET_TUNNEL_KEY_AX_AUTH_SENT: | ||
1587 | /* We are responding, so only require reply | ||
1588 | if WE have a channel waiting. */ | ||
1589 | if (NULL != t->unverified_ax) | ||
1590 | { | ||
1591 | /* Send AX_AUTH so we might get this one verified */ | ||
1592 | ax = t->unverified_ax; | ||
1593 | } | ||
1594 | else | ||
1595 | { | ||
1596 | /* How can this be? */ | ||
1597 | GNUNET_break (0); | ||
1598 | ax = &t->ax; | ||
1599 | } | ||
1600 | send_kx_auth (t, | ||
1601 | ax, | ||
1602 | (0 == GCT_count_channels (t)) | ||
1603 | ? GNUNET_NO | ||
1604 | : GNUNET_YES); | ||
1605 | break; | ||
1606 | case CADET_TUNNEL_KEY_OK: | ||
1607 | /* Must have been the *other* peer asking us to | ||
1608 | respond with a KX_AUTH. */ | ||
1609 | if (NULL != t->unverified_ax) | ||
1610 | { | ||
1611 | /* Sending AX_AUTH in response to AX so we might get this one verified */ | ||
1612 | ax = t->unverified_ax; | ||
1613 | } | ||
1614 | else | ||
1615 | { | ||
1616 | /* Sending AX_AUTH in response to AX_AUTH */ | ||
1617 | ax = &t->ax; | ||
1618 | } | ||
1619 | send_kx_auth (t, | ||
1620 | ax, | ||
1621 | GNUNET_NO); | ||
1622 | break; | ||
1623 | } | ||
1624 | } | ||
1625 | |||
1626 | |||
1627 | /** | ||
1449 | * Handle KX message that lacks authentication (and which will thus | 1628 | * Handle KX message that lacks authentication (and which will thus |
1450 | * only be considered authenticated after we respond with our own | 1629 | * only be considered authenticated after we respond with our own |
1451 | * KX_AUTH and finally successfully decrypt payload). | 1630 | * KX_AUTH and finally successfully decrypt payload). |
@@ -1461,50 +1640,62 @@ GCT_handle_kx (struct CadetTConnection *ct, | |||
1461 | struct CadetTunnelAxolotl *ax; | 1640 | struct CadetTunnelAxolotl *ax; |
1462 | int ret; | 1641 | int ret; |
1463 | 1642 | ||
1464 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1643 | if (0 == |
1465 | "Handling KX message for tunnel %s\n", | 1644 | memcmp (&t->ax.DHRr, |
1466 | GCT_2s (t)); | 1645 | &msg->ratchet_key, |
1646 | sizeof (msg->ratchet_key))) | ||
1647 | { | ||
1648 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1649 | "Got duplicate KX. Firing back KX_AUTH.\n"); | ||
1650 | send_kx_auth (t, | ||
1651 | &t->ax, | ||
1652 | GNUNET_NO); | ||
1653 | return; | ||
1654 | } | ||
1467 | 1655 | ||
1468 | /* We only keep ONE unverified KX around, so if there is an existing one, | 1656 | /* We only keep ONE unverified KX around, so if there is an existing one, |
1469 | clean it up. */ | 1657 | clean it up. */ |
1470 | if (NULL != t->unverified_ax) | 1658 | if (NULL != t->unverified_ax) |
1471 | { | 1659 | { |
1660 | if (0 == | ||
1661 | memcmp (&t->unverified_ax->DHRr, | ||
1662 | &msg->ratchet_key, | ||
1663 | sizeof (msg->ratchet_key))) | ||
1664 | { | ||
1665 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1666 | "Got duplicate unverified KX on %s. Fire back KX_AUTH again.\n", | ||
1667 | GCT_2s (t)); | ||
1668 | send_kx_auth (t, | ||
1669 | t->unverified_ax, | ||
1670 | GNUNET_NO); | ||
1671 | return; | ||
1672 | } | ||
1472 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1673 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1473 | "Dropping old unverified KX state, got a fresh one.\n", | 1674 | "Dropping old unverified KX state. Got a fresh KX for %s.\n", |
1474 | t->unverified_attempts); | 1675 | GCT_2s (t)); |
1475 | cleanup_ax (t->unverified_ax); | ||
1476 | memset (t->unverified_ax, | 1676 | memset (t->unverified_ax, |
1477 | 0, | 1677 | 0, |
1478 | sizeof (struct CadetTunnelAxolotl)); | 1678 | sizeof (struct CadetTunnelAxolotl)); |
1479 | new_ephemeral (t->unverified_ax); | 1679 | t->unverified_ax->DHRs = t->ax.DHRs; |
1480 | t->unverified_ax->kx_0 = GNUNET_CRYPTO_ecdhe_key_create (); | 1680 | t->unverified_ax->kx_0 = t->ax.kx_0; |
1481 | } | 1681 | } |
1482 | else | 1682 | else |
1483 | { | 1683 | { |
1684 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1685 | "Creating fresh unverified KX for %s.\n", | ||
1686 | GCT_2s (t)); | ||
1484 | t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl); | 1687 | t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl); |
1485 | new_ephemeral (t->unverified_ax); | 1688 | t->unverified_ax->DHRs = t->ax.DHRs; |
1486 | t->unverified_ax->kx_0 = GNUNET_CRYPTO_ecdhe_key_create (); | 1689 | t->unverified_ax->kx_0 = t->ax.kx_0; |
1487 | } | 1690 | } |
1488 | /* Set as the 'current' RK the one we are currently using, | 1691 | /* Set as the 'current' RK/DHRr the one we are currently using, |
1489 | so that the duplicate-detection logic of | 1692 | so that the duplicate-detection logic of |
1490 | #update_ax_by_kx can work. */ | 1693 | #update_ax_by_kx can work. */ |
1491 | t->unverified_ax->RK = t->ax.RK; | 1694 | t->unverified_ax->RK = t->ax.RK; |
1695 | t->unverified_ax->DHRr = t->ax.DHRr; | ||
1492 | t->unverified_attempts = 0; | 1696 | t->unverified_attempts = 0; |
1493 | ax = t->unverified_ax; | 1697 | ax = t->unverified_ax; |
1494 | 1698 | ||
1495 | /* FIXME: why this? Investigate use of kx_task! */ | ||
1496 | if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (msg->flags))) | ||
1497 | { | ||
1498 | if (NULL != t->kx_task) | ||
1499 | { | ||
1500 | GNUNET_SCHEDULER_cancel (t->kx_task); | ||
1501 | t->kx_task = NULL; | ||
1502 | } | ||
1503 | send_kx (t, | ||
1504 | ax, | ||
1505 | GNUNET_NO); | ||
1506 | } | ||
1507 | |||
1508 | /* Update 'ax' by the new key material */ | 1699 | /* Update 'ax' by the new key material */ |
1509 | ret = update_ax_by_kx (ax, | 1700 | ret = update_ax_by_kx (ax, |
1510 | GCP_get_id (t->destination), | 1701 | GCP_get_id (t->destination), |
@@ -1515,33 +1706,110 @@ GCT_handle_kx (struct CadetTConnection *ct, | |||
1515 | return; /* duplicate KX, nothing to do */ | 1706 | return; /* duplicate KX, nothing to do */ |
1516 | 1707 | ||
1517 | /* move ahead in our state machine */ | 1708 | /* move ahead in our state machine */ |
1709 | if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) | ||
1710 | GCT_change_estate (t, | ||
1711 | CADET_TUNNEL_KEY_AX_RECV); | ||
1712 | else if (CADET_TUNNEL_KEY_AX_SENT == t->estate) | ||
1713 | GCT_change_estate (t, | ||
1714 | CADET_TUNNEL_KEY_AX_SENT_AND_RECV); | ||
1715 | |||
1716 | /* KX is still not done, try again our end. */ | ||
1717 | if (CADET_TUNNEL_KEY_OK != t->estate) | ||
1718 | { | ||
1719 | if (NULL != t->kx_task) | ||
1720 | GNUNET_SCHEDULER_cancel (t->kx_task); | ||
1721 | t->kx_task | ||
1722 | = GNUNET_SCHEDULER_add_now (&retry_kx, | ||
1723 | t); | ||
1724 | } | ||
1725 | } | ||
1726 | |||
1727 | |||
1728 | /** | ||
1729 | * Handle KX_AUTH message. | ||
1730 | * | ||
1731 | * @param ct connection/tunnel combo that received encrypted message | ||
1732 | * @param msg the key exchange message | ||
1733 | */ | ||
1734 | void | ||
1735 | GCT_handle_kx_auth (struct CadetTConnection *ct, | ||
1736 | const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg) | ||
1737 | { | ||
1738 | struct CadetTunnel *t = ct->t; | ||
1739 | struct CadetTunnelAxolotl ax_tmp; | ||
1740 | struct GNUNET_HashCode kx_auth; | ||
1741 | int ret; | ||
1742 | |||
1743 | if ( (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) || | ||
1744 | (CADET_TUNNEL_KEY_AX_RECV == t->estate) ) | ||
1745 | { | ||
1746 | /* Confusing, we got a KX_AUTH before we even send our own | ||
1747 | KX. This should not happen. We'll send our own KX ASAP anyway, | ||
1748 | so let's ignore this here. */ | ||
1749 | GNUNET_break_op (0); | ||
1750 | return; | ||
1751 | } | ||
1752 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1753 | "Handling KX_AUTH message for %s\n", | ||
1754 | GCT_2s (t)); | ||
1755 | |||
1756 | /* We do everything in ax_tmp until we've checked the authentication | ||
1757 | so we don't clobber anything we care about by accident. */ | ||
1758 | ax_tmp = t->ax; | ||
1759 | |||
1760 | /* Update 'ax' by the new key material */ | ||
1761 | ret = update_ax_by_kx (&ax_tmp, | ||
1762 | GCP_get_id (t->destination), | ||
1763 | &msg->kx.ephemeral_key, | ||
1764 | &msg->kx.ratchet_key); | ||
1765 | GNUNET_break (GNUNET_OK == ret); | ||
1766 | GNUNET_CRYPTO_hash (&ax_tmp.RK, | ||
1767 | sizeof (ax_tmp.RK), | ||
1768 | &kx_auth); | ||
1769 | if (0 != memcmp (&kx_auth, | ||
1770 | &msg->auth, | ||
1771 | sizeof (kx_auth))) | ||
1772 | { | ||
1773 | /* This KX_AUTH is not using the latest KX/KX_AUTH data | ||
1774 | we transmitted to the sender, refuse it! */ | ||
1775 | GNUNET_break_op (0); | ||
1776 | return; | ||
1777 | } | ||
1778 | /* Yep, we're good. */ | ||
1779 | t->ax = ax_tmp; | ||
1780 | if (NULL != t->unverified_ax) | ||
1781 | { | ||
1782 | /* We got some "stale" KX before, drop that. */ | ||
1783 | t->unverified_ax->DHRs = NULL; /* aliased with ax.DHRs */ | ||
1784 | t->unverified_ax->kx_0 = NULL; /* aliased with ax.DHRs */ | ||
1785 | cleanup_ax (t->unverified_ax); | ||
1786 | GNUNET_free (t->unverified_ax); | ||
1787 | t->unverified_ax = NULL; | ||
1788 | } | ||
1789 | |||
1790 | /* move ahead in our state machine */ | ||
1518 | switch (t->estate) | 1791 | switch (t->estate) |
1519 | { | 1792 | { |
1520 | case CADET_TUNNEL_KEY_UNINITIALIZED: | 1793 | case CADET_TUNNEL_KEY_UNINITIALIZED: |
1521 | GCT_change_estate (t, | 1794 | case CADET_TUNNEL_KEY_AX_RECV: |
1522 | CADET_TUNNEL_KEY_PING); | 1795 | /* Checked above, this is impossible. */ |
1796 | GNUNET_assert (0); | ||
1523 | break; | 1797 | break; |
1524 | case CADET_TUNNEL_KEY_SENT: | 1798 | case CADET_TUNNEL_KEY_AX_SENT: /* This is the normal case */ |
1525 | /* Got a response to us sending our key; now | 1799 | case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: /* both peers started KX */ |
1526 | we can start transmitting! */ | 1800 | case CADET_TUNNEL_KEY_AX_AUTH_SENT: /* both peers now did KX_AUTH */ |
1527 | GCT_change_estate (t, | 1801 | GCT_change_estate (t, |
1528 | CADET_TUNNEL_KEY_OK); | 1802 | CADET_TUNNEL_KEY_OK); |
1529 | if (NULL != t->send_task) | ||
1530 | GNUNET_SCHEDULER_cancel (t->send_task); | ||
1531 | t->send_task = GNUNET_SCHEDULER_add_now (&trigger_transmissions, | ||
1532 | t); | ||
1533 | break; | ||
1534 | case CADET_TUNNEL_KEY_PING: | ||
1535 | /* Got a key yet again; need encrypted payload or KX_AUTH | ||
1536 | to advance to #CADET_TUNNEL_KEY_OK! */ | ||
1537 | break; | 1803 | break; |
1538 | case CADET_TUNNEL_KEY_OK: | 1804 | case CADET_TUNNEL_KEY_OK: |
1539 | /* Did not expect a key, but so what. */ | 1805 | /* Did not expect another KX_AUTH, but so what, still acceptable. |
1806 | Nothing to do here. */ | ||
1540 | break; | 1807 | break; |
1541 | } | 1808 | } |
1542 | } | 1809 | } |
1543 | 1810 | ||
1544 | 1811 | ||
1812 | |||
1545 | /* ************************************** end core crypto ***************************** */ | 1813 | /* ************************************** end core crypto ***************************** */ |
1546 | 1814 | ||
1547 | 1815 | ||
@@ -1603,11 +1871,33 @@ GCT_add_channel (struct CadetTunnel *t, | |||
1603 | ch, | 1871 | ch, |
1604 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | 1872 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); |
1605 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1873 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1606 | "Adding channel %s to tunnel %s\n", | 1874 | "Adding %s to %s\n", |
1607 | GCCH_2s (ch), | 1875 | GCCH_2s (ch), |
1608 | GCT_2s (t)); | 1876 | GCT_2s (t)); |
1609 | if (CADET_TUNNEL_KEY_OK == t->estate) | 1877 | switch (t->estate) |
1878 | { | ||
1879 | case CADET_TUNNEL_KEY_UNINITIALIZED: | ||
1880 | /* waiting for connection to start KX */ | ||
1881 | break; | ||
1882 | case CADET_TUNNEL_KEY_AX_RECV: | ||
1883 | case CADET_TUNNEL_KEY_AX_SENT: | ||
1884 | case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: | ||
1885 | /* we're currently waiting for KX to complete */ | ||
1886 | break; | ||
1887 | case CADET_TUNNEL_KEY_AX_AUTH_SENT: | ||
1888 | /* waiting for OTHER peer to send us data, | ||
1889 | we might need to prompt more aggressively! */ | ||
1890 | if (NULL == t->kx_task) | ||
1891 | t->kx_task | ||
1892 | = GNUNET_SCHEDULER_add_at (t->next_kx_attempt, | ||
1893 | &retry_kx, | ||
1894 | t); | ||
1895 | break; | ||
1896 | case CADET_TUNNEL_KEY_OK: | ||
1897 | /* We are ready. Tell the new channel that we are up. */ | ||
1610 | GCCH_tunnel_up (ch); | 1898 | GCCH_tunnel_up (ch); |
1899 | break; | ||
1900 | } | ||
1611 | return ctn; | 1901 | return ctn; |
1612 | } | 1902 | } |
1613 | 1903 | ||
@@ -1644,9 +1934,9 @@ destroy_tunnel (void *cls) | |||
1644 | 1934 | ||
1645 | t->destroy_task = NULL; | 1935 | t->destroy_task = NULL; |
1646 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1936 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1647 | "Destroying idle tunnel %s\n", | 1937 | "Destroying idle %s\n", |
1648 | GCT_2s (t)); | 1938 | GCT_2s (t)); |
1649 | GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap32_size (t->channels)); | 1939 | GNUNET_assert (0 == GCT_count_channels (t)); |
1650 | while (NULL != (ct = t->connection_head)) | 1940 | while (NULL != (ct = t->connection_head)) |
1651 | { | 1941 | { |
1652 | struct CadetConnection *cc; | 1942 | struct CadetConnection *cc; |
@@ -1682,12 +1972,14 @@ destroy_tunnel (void *cls) | |||
1682 | } | 1972 | } |
1683 | GNUNET_MST_destroy (t->mst); | 1973 | GNUNET_MST_destroy (t->mst); |
1684 | GNUNET_MQ_destroy (t->mq); | 1974 | GNUNET_MQ_destroy (t->mq); |
1685 | cleanup_ax (&t->ax); | ||
1686 | if (NULL != t->unverified_ax) | 1975 | if (NULL != t->unverified_ax) |
1687 | { | 1976 | { |
1977 | t->unverified_ax->DHRs = NULL; /* aliased with ax.DHRs */ | ||
1978 | t->unverified_ax->kx_0 = NULL; /* aliased with ax.DHRs */ | ||
1688 | cleanup_ax (t->unverified_ax); | 1979 | cleanup_ax (t->unverified_ax); |
1689 | GNUNET_free (t->unverified_ax); | 1980 | GNUNET_free (t->unverified_ax); |
1690 | } | 1981 | } |
1982 | cleanup_ax (&t->ax); | ||
1691 | GNUNET_free (t); | 1983 | GNUNET_free (t); |
1692 | } | 1984 | } |
1693 | 1985 | ||
@@ -1705,7 +1997,7 @@ GCT_remove_channel (struct CadetTunnel *t, | |||
1705 | struct GNUNET_CADET_ChannelTunnelNumber ctn) | 1997 | struct GNUNET_CADET_ChannelTunnelNumber ctn) |
1706 | { | 1998 | { |
1707 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1999 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1708 | "Removing channel %s from tunnel %s\n", | 2000 | "Removing %s from %s\n", |
1709 | GCCH_2s (ch), | 2001 | GCCH_2s (ch), |
1710 | GCT_2s (t)); | 2002 | GCT_2s (t)); |
1711 | GNUNET_assert (GNUNET_YES == | 2003 | GNUNET_assert (GNUNET_YES == |
@@ -1713,7 +2005,7 @@ GCT_remove_channel (struct CadetTunnel *t, | |||
1713 | ntohl (ctn.cn), | 2005 | ntohl (ctn.cn), |
1714 | ch)); | 2006 | ch)); |
1715 | if (0 == | 2007 | if (0 == |
1716 | GNUNET_CONTAINER_multihashmap32_size (t->channels)) | 2008 | GCT_count_channels (t)) |
1717 | { | 2009 | { |
1718 | t->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_DESTROY_DELAY, | 2010 | t->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_DESTROY_DELAY, |
1719 | &destroy_tunnel, | 2011 | &destroy_tunnel, |
@@ -1755,7 +2047,7 @@ GCT_destroy_tunnel_now (struct CadetTunnel *t) | |||
1755 | &destroy_remaining_channels, | 2047 | &destroy_remaining_channels, |
1756 | t); | 2048 | t); |
1757 | GNUNET_assert (0 == | 2049 | GNUNET_assert (0 == |
1758 | GNUNET_CONTAINER_multihashmap32_size (t->channels)); | 2050 | GCT_count_channels (t)); |
1759 | if (NULL != t->destroy_task) | 2051 | if (NULL != t->destroy_task) |
1760 | { | 2052 | { |
1761 | GNUNET_SCHEDULER_cancel (t->destroy_task); | 2053 | GNUNET_SCHEDULER_cancel (t->destroy_task); |
@@ -1766,26 +2058,6 @@ GCT_destroy_tunnel_now (struct CadetTunnel *t) | |||
1766 | 2058 | ||
1767 | 2059 | ||
1768 | /** | 2060 | /** |
1769 | * It's been a while, we should try to redo the KX, if we can. | ||
1770 | * | ||
1771 | * @param cls the `struct CadetTunnel` to do KX for. | ||
1772 | */ | ||
1773 | static void | ||
1774 | retry_kx (void *cls) | ||
1775 | { | ||
1776 | struct CadetTunnel *t = cls; | ||
1777 | |||
1778 | t->kx_task = NULL; | ||
1779 | send_kx (t, | ||
1780 | &t->ax, | ||
1781 | ( (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) || | ||
1782 | (CADET_TUNNEL_KEY_SENT == t->estate) ) | ||
1783 | ? GNUNET_YES | ||
1784 | : GNUNET_NO); | ||
1785 | } | ||
1786 | |||
1787 | |||
1788 | /** | ||
1789 | * Send normal payload from queue in @a t via connection @a ct. | 2061 | * Send normal payload from queue in @a t via connection @a ct. |
1790 | * Does nothing if our payload queue is empty. | 2062 | * Does nothing if our payload queue is empty. |
1791 | * | 2063 | * |
@@ -1847,7 +2119,7 @@ connection_ready_cb (void *cls, | |||
1847 | if (GNUNET_NO == is_ready) | 2119 | if (GNUNET_NO == is_ready) |
1848 | { | 2120 | { |
1849 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2121 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1850 | "Connection %s no longer ready for tunnel %s\n", | 2122 | "%s no longer ready for %s\n", |
1851 | GCC_2s (ct->cc), | 2123 | GCC_2s (ct->cc), |
1852 | GCT_2s (t)); | 2124 | GCT_2s (t)); |
1853 | ct->is_ready = GNUNET_NO; | 2125 | ct->is_ready = GNUNET_NO; |
@@ -1855,29 +2127,50 @@ connection_ready_cb (void *cls, | |||
1855 | } | 2127 | } |
1856 | ct->is_ready = GNUNET_YES; | 2128 | ct->is_ready = GNUNET_YES; |
1857 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2129 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1858 | "Connection %s now ready for tunnel %s in state %s\n", | 2130 | "%s now ready for %s in state %s\n", |
1859 | GCC_2s (ct->cc), | 2131 | GCC_2s (ct->cc), |
1860 | GCT_2s (t), | 2132 | GCT_2s (t), |
1861 | estate2s (t->estate)); | 2133 | estate2s (t->estate)); |
1862 | switch (t->estate) | 2134 | switch (t->estate) |
1863 | { | 2135 | { |
1864 | case CADET_TUNNEL_KEY_UNINITIALIZED: | 2136 | case CADET_TUNNEL_KEY_UNINITIALIZED: |
2137 | /* Do not begin KX if WE have no channels waiting! */ | ||
2138 | if (0 == GCT_count_channels (t)) | ||
2139 | return; | ||
2140 | /* We are uninitialized, just transmit immediately, | ||
2141 | without undue delay. */ | ||
2142 | if (NULL != t->kx_task) | ||
2143 | { | ||
2144 | GNUNET_SCHEDULER_cancel (t->kx_task); | ||
2145 | t->kx_task = NULL; | ||
2146 | } | ||
1865 | send_kx (t, | 2147 | send_kx (t, |
1866 | &t->ax, | 2148 | &t->ax); |
1867 | GNUNET_YES); | ||
1868 | break; | 2149 | break; |
1869 | case CADET_TUNNEL_KEY_SENT: | 2150 | case CADET_TUNNEL_KEY_AX_RECV: |
1870 | case CADET_TUNNEL_KEY_PING: | 2151 | case CADET_TUNNEL_KEY_AX_SENT: |
1871 | /* opportunity to #retry_kx() starts now, schedule job */ | 2152 | case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: |
2153 | case CADET_TUNNEL_KEY_AX_AUTH_SENT: | ||
2154 | /* we're currently waiting for KX to complete, schedule job */ | ||
1872 | if (NULL == t->kx_task) | 2155 | if (NULL == t->kx_task) |
1873 | { | ||
1874 | t->kx_task | 2156 | t->kx_task |
1875 | = GNUNET_SCHEDULER_add_at (t->next_kx_attempt, | 2157 | = GNUNET_SCHEDULER_add_at (t->next_kx_attempt, |
1876 | &retry_kx, | 2158 | &retry_kx, |
1877 | t); | 2159 | t); |
1878 | } | ||
1879 | break; | 2160 | break; |
1880 | case CADET_TUNNEL_KEY_OK: | 2161 | case CADET_TUNNEL_KEY_OK: |
2162 | if (GNUNET_YES == t->kx_auth_requested) | ||
2163 | { | ||
2164 | if (NULL != t->kx_task) | ||
2165 | { | ||
2166 | GNUNET_SCHEDULER_cancel (t->kx_task); | ||
2167 | t->kx_task = NULL; | ||
2168 | } | ||
2169 | send_kx_auth (t, | ||
2170 | &t->ax, | ||
2171 | GNUNET_NO); | ||
2172 | return; | ||
2173 | } | ||
1881 | try_send_normal_payload (t, | 2174 | try_send_normal_payload (t, |
1882 | ct); | 2175 | ct); |
1883 | break; | 2176 | break; |
@@ -1940,7 +2233,7 @@ consider_path_cb (void *cls, | |||
1940 | if (ps == path) | 2233 | if (ps == path) |
1941 | { | 2234 | { |
1942 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2235 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1943 | "Ignoring duplicate path %s for tunnel %s.\n", | 2236 | "Ignoring duplicate path %s for %s.\n", |
1944 | GCPP_2s (path), | 2237 | GCPP_2s (path), |
1945 | GCT_2s (t)); | 2238 | GCT_2s (t)); |
1946 | return GNUNET_YES; /* duplicate */ | 2239 | return GNUNET_YES; /* duplicate */ |
@@ -1998,7 +2291,7 @@ consider_path_cb (void *cls, | |||
1998 | ct); | 2291 | ct); |
1999 | t->num_connections++; | 2292 | t->num_connections++; |
2000 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2293 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2001 | "Found interesting path %s for tunnel %s, created connection %s\n", | 2294 | "Found interesting path %s for %s, created %s\n", |
2002 | GCPP_2s (path), | 2295 | GCPP_2s (path), |
2003 | GCT_2s (t), | 2296 | GCT_2s (t), |
2004 | GCC_2s (ct->cc)); | 2297 | GCC_2s (ct->cc)); |
@@ -2026,7 +2319,7 @@ maintain_connections_cb (void *cls) | |||
2026 | 2319 | ||
2027 | t->maintain_connections_task = NULL; | 2320 | t->maintain_connections_task = NULL; |
2028 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2321 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2029 | "Performing connection maintenance for tunnel %s.\n", | 2322 | "Performing connection maintenance for %s.\n", |
2030 | GCT_2s (t)); | 2323 | GCT_2s (t)); |
2031 | 2324 | ||
2032 | (void) GCP_iterate_paths (t->destination, | 2325 | (void) GCP_iterate_paths (t->destination, |
@@ -2069,7 +2362,7 @@ handle_plaintext_keepalive (void *cls, | |||
2069 | struct CadetTunnel *t = cls; | 2362 | struct CadetTunnel *t = cls; |
2070 | 2363 | ||
2071 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2364 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2072 | "Received KEEPALIVE on tunnel %s\n", | 2365 | "Received KEEPALIVE on %s\n", |
2073 | GCT_2s (t)); | 2366 | GCT_2s (t)); |
2074 | GNUNET_STATISTICS_update (stats, | 2367 | GNUNET_STATISTICS_update (stats, |
2075 | "# keepalives received", | 2368 | "# keepalives received", |
@@ -2370,6 +2663,7 @@ GCT_create_tunnel (struct CadetPeer *destination) | |||
2370 | GNUNET_MQ_handler_end () | 2663 | GNUNET_MQ_handler_end () |
2371 | }; | 2664 | }; |
2372 | 2665 | ||
2666 | t->kx_retry_delay = INITIAL_KX_RETRY_DELAY; | ||
2373 | new_ephemeral (&t->ax); | 2667 | new_ephemeral (&t->ax); |
2374 | t->ax.kx_0 = GNUNET_CRYPTO_ecdhe_key_create (); | 2668 | t->ax.kx_0 = GNUNET_CRYPTO_ecdhe_key_create (); |
2375 | t->destination = destination; | 2669 | t->destination = destination; |
@@ -2418,7 +2712,7 @@ GCT_add_inbound_connection (struct CadetTunnel *t, | |||
2418 | if (NULL == ct->cc) | 2712 | if (NULL == ct->cc) |
2419 | { | 2713 | { |
2420 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2714 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2421 | "Tunnel %s refused inbound connection %s (duplicate)\n", | 2715 | "%s refused inbound %s (duplicate)\n", |
2422 | GCT_2s (t), | 2716 | GCT_2s (t), |
2423 | GCC_2s (ct->cc)); | 2717 | GCC_2s (ct->cc)); |
2424 | GNUNET_free (ct); | 2718 | GNUNET_free (ct); |
@@ -2433,7 +2727,7 @@ GCT_add_inbound_connection (struct CadetTunnel *t, | |||
2433 | ct); | 2727 | ct); |
2434 | t->num_connections++; | 2728 | t->num_connections++; |
2435 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2729 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2436 | "Tunnel %s has new connection %s\n", | 2730 | "%s has new %s\n", |
2437 | GCT_2s (t), | 2731 | GCT_2s (t), |
2438 | GCC_2s (ct->cc)); | 2732 | GCC_2s (ct->cc)); |
2439 | return GNUNET_OK; | 2733 | return GNUNET_OK; |
@@ -2456,7 +2750,7 @@ GCT_handle_encrypted (struct CadetTConnection *ct, | |||
2456 | ssize_t decrypted_size; | 2750 | ssize_t decrypted_size; |
2457 | 2751 | ||
2458 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2752 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2459 | "Tunnel %s received %u bytes of encrypted data in state %d\n", | 2753 | "%s received %u bytes of encrypted data in state %d\n", |
2460 | GCT_2s (t), | 2754 | GCT_2s (t), |
2461 | (unsigned int) size, | 2755 | (unsigned int) size, |
2462 | t->estate); | 2756 | t->estate); |
@@ -2464,25 +2758,46 @@ GCT_handle_encrypted (struct CadetTConnection *ct, | |||
2464 | switch (t->estate) | 2758 | switch (t->estate) |
2465 | { | 2759 | { |
2466 | case CADET_TUNNEL_KEY_UNINITIALIZED: | 2760 | case CADET_TUNNEL_KEY_UNINITIALIZED: |
2761 | case CADET_TUNNEL_KEY_AX_RECV: | ||
2467 | /* We did not even SEND our KX, how can the other peer | 2762 | /* We did not even SEND our KX, how can the other peer |
2468 | send us encrypted data? */ | 2763 | send us encrypted data? */ |
2469 | GNUNET_break_op (0); | 2764 | GNUNET_break_op (0); |
2470 | return; | 2765 | return; |
2471 | case CADET_TUNNEL_KEY_SENT: | 2766 | case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: |
2767 | /* We send KX, and other peer send KX to us at the same time. | ||
2768 | Neither KX is AUTH'ed, so let's try KX_AUTH this time. */ | ||
2769 | GNUNET_STATISTICS_update (stats, | ||
2770 | "# received encrypted without KX_AUTH", | ||
2771 | 1, | ||
2772 | GNUNET_NO); | ||
2773 | if (NULL != t->kx_task) | ||
2774 | { | ||
2775 | GNUNET_SCHEDULER_cancel (t->kx_task); | ||
2776 | t->kx_task = NULL; | ||
2777 | } | ||
2778 | send_kx_auth (t, | ||
2779 | &t->ax, | ||
2780 | GNUNET_YES); | ||
2781 | return; | ||
2782 | case CADET_TUNNEL_KEY_AX_SENT: | ||
2472 | /* We did not get the KX of the other peer, but that | 2783 | /* We did not get the KX of the other peer, but that |
2473 | might have been lost. Ask for KX again. */ | 2784 | might have been lost. Send our KX again immediately. */ |
2474 | GNUNET_STATISTICS_update (stats, | 2785 | GNUNET_STATISTICS_update (stats, |
2475 | "# received encrypted without KX", | 2786 | "# received encrypted without KX", |
2476 | 1, | 2787 | 1, |
2477 | GNUNET_NO); | 2788 | GNUNET_NO); |
2478 | if (NULL != t->kx_task) | 2789 | if (NULL != t->kx_task) |
2790 | { | ||
2479 | GNUNET_SCHEDULER_cancel (t->kx_task); | 2791 | GNUNET_SCHEDULER_cancel (t->kx_task); |
2480 | t->kx_task = GNUNET_SCHEDULER_add_now (&retry_kx, | 2792 | t->kx_task = NULL; |
2481 | t); | 2793 | } |
2794 | send_kx (t, | ||
2795 | &t->ax); | ||
2482 | return; | 2796 | return; |
2483 | case CADET_TUNNEL_KEY_PING: | 2797 | case CADET_TUNNEL_KEY_AX_AUTH_SENT: |
2484 | /* Great, first payload, we might graduate to OK */ | 2798 | /* Great, first payload, we might graduate to OK! */ |
2485 | case CADET_TUNNEL_KEY_OK: | 2799 | case CADET_TUNNEL_KEY_OK: |
2800 | /* We are up and running, all good. */ | ||
2486 | break; | 2801 | break; |
2487 | } | 2802 | } |
2488 | 2803 | ||
@@ -2514,12 +2829,14 @@ GCT_handle_encrypted (struct CadetTConnection *ct, | |||
2514 | if (-1 != decrypted_size) | 2829 | if (-1 != decrypted_size) |
2515 | { | 2830 | { |
2516 | /* It worked! Treat this as authentication of the AX data! */ | 2831 | /* It worked! Treat this as authentication of the AX data! */ |
2832 | t->ax.DHRs = NULL; /* aliased with ax.DHRs */ | ||
2833 | t->ax.kx_0 = NULL; /* aliased with ax.DHRs */ | ||
2517 | cleanup_ax (&t->ax); | 2834 | cleanup_ax (&t->ax); |
2518 | t->ax = *t->unverified_ax; | 2835 | t->ax = *t->unverified_ax; |
2519 | GNUNET_free (t->unverified_ax); | 2836 | GNUNET_free (t->unverified_ax); |
2520 | t->unverified_ax = NULL; | 2837 | t->unverified_ax = NULL; |
2521 | } | 2838 | } |
2522 | if (CADET_TUNNEL_KEY_PING == t->estate) | 2839 | if (CADET_TUNNEL_KEY_AX_AUTH_SENT == t->estate) |
2523 | { | 2840 | { |
2524 | /* First time it worked, move tunnel into production! */ | 2841 | /* First time it worked, move tunnel into production! */ |
2525 | GCT_change_estate (t, | 2842 | GCT_change_estate (t, |
@@ -2544,6 +2861,8 @@ GCT_handle_encrypted (struct CadetTConnection *ct, | |||
2544 | t->unverified_attempts); | 2861 | t->unverified_attempts); |
2545 | if (t->unverified_attempts > MAX_UNVERIFIED_ATTEMPTS) | 2862 | if (t->unverified_attempts > MAX_UNVERIFIED_ATTEMPTS) |
2546 | { | 2863 | { |
2864 | t->unverified_ax->DHRs = NULL; /* aliased with ax.DHRs */ | ||
2865 | t->unverified_ax->kx_0 = NULL; /* aliased with ax.DHRs */ | ||
2547 | cleanup_ax (t->unverified_ax); | 2866 | cleanup_ax (t->unverified_ax); |
2548 | GNUNET_free (t->unverified_ax); | 2867 | GNUNET_free (t->unverified_ax); |
2549 | t->unverified_ax = NULL; | 2868 | t->unverified_ax = NULL; |
@@ -2555,7 +2874,7 @@ GCT_handle_encrypted (struct CadetTConnection *ct, | |||
2555 | /* Decryption failed for good, complain. */ | 2874 | /* Decryption failed for good, complain. */ |
2556 | GNUNET_break_op (0); | 2875 | GNUNET_break_op (0); |
2557 | LOG (GNUNET_ERROR_TYPE_WARNING, | 2876 | LOG (GNUNET_ERROR_TYPE_WARNING, |
2558 | "Tunnel %s failed to decrypt and validate encrypted data\n", | 2877 | "%s failed to decrypt and validate encrypted data\n", |
2559 | GCT_2s (t)); | 2878 | GCT_2s (t)); |
2560 | GNUNET_STATISTICS_update (stats, | 2879 | GNUNET_STATISTICS_update (stats, |
2561 | "# unable to decrypt", | 2880 | "# unable to decrypt", |
@@ -2602,7 +2921,7 @@ GCT_send (struct CadetTunnel *t, | |||
2602 | } | 2921 | } |
2603 | payload_size = ntohs (message->size); | 2922 | payload_size = ntohs (message->size); |
2604 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2923 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2605 | "Encrypting %u bytes for tunnel %s\n", | 2924 | "Encrypting %u bytes for %s\n", |
2606 | (unsigned int) payload_size, | 2925 | (unsigned int) payload_size, |
2607 | GCT_2s (t)); | 2926 | GCT_2s (t)); |
2608 | env = GNUNET_MQ_msg_extra (ax_msg, | 2927 | env = GNUNET_MQ_msg_extra (ax_msg, |