diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-01-19 11:05:34 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-01-19 11:05:34 +0100 |
commit | bd3147503e27ddefcb6ba0dcb99c2b32947622a4 (patch) | |
tree | 2e4455b4ebd3be44ebd79dff789277fc2a3611f2 | |
parent | dfde8ea01a08a32340a47df29ffc2571c031488b (diff) | |
download | gnunet-bd3147503e27ddefcb6ba0dcb99c2b32947622a4.tar.gz gnunet-bd3147503e27ddefcb6ba0dcb99c2b32947622a4.zip |
baby steps towards KX
-rw-r--r-- | src/cadet/gnunet-service-cadet-new_channel.c | 21 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet-new_channel.h | 18 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet-new_tunnels.c | 234 |
3 files changed, 257 insertions, 16 deletions
diff --git a/src/cadet/gnunet-service-cadet-new_channel.c b/src/cadet/gnunet-service-cadet-new_channel.c index dcbc5614f..92ab61543 100644 --- a/src/cadet/gnunet-service-cadet-new_channel.c +++ b/src/cadet/gnunet-service-cadet-new_channel.c | |||
@@ -722,6 +722,27 @@ GCCH_channel_incoming_destroy (struct CadetChannel *ch) | |||
722 | 722 | ||
723 | 723 | ||
724 | /** | 724 | /** |
725 | * Destroy channel, based on the other peer closing the | ||
726 | * connection. Also needs to remove this channel from | ||
727 | * the tunnel. | ||
728 | * | ||
729 | * FIXME: need to make it possible to defer destruction until we have | ||
730 | * received all messages up to the destroy, and right now the destroy | ||
731 | * message (and this API) fails to give is the information we need! | ||
732 | * | ||
733 | * FIXME: also need to know if the other peer got a destroy from | ||
734 | * us before! | ||
735 | * | ||
736 | * @param ch channel to destroy | ||
737 | */ | ||
738 | void | ||
739 | GCCH_channel_remote_destroy (struct CadetChannel *ch) | ||
740 | { | ||
741 | GNUNET_break (0); // FIXME! | ||
742 | } | ||
743 | |||
744 | |||
745 | /** | ||
725 | * Function called once the tunnel has sent one of our messages. | 746 | * Function called once the tunnel has sent one of our messages. |
726 | * If the message is unreliable, simply frees the `crm`. If the | 747 | * If the message is unreliable, simply frees the `crm`. If the |
727 | * message was reliable, calculate retransmission time and | 748 | * message was reliable, calculate retransmission time and |
diff --git a/src/cadet/gnunet-service-cadet-new_channel.h b/src/cadet/gnunet-service-cadet-new_channel.h index 85302ea0a..8caa254d1 100644 --- a/src/cadet/gnunet-service-cadet-new_channel.h +++ b/src/cadet/gnunet-service-cadet-new_channel.h | |||
@@ -146,6 +146,24 @@ GCCH_channel_incoming_destroy (struct CadetChannel *ch); | |||
146 | 146 | ||
147 | 147 | ||
148 | /** | 148 | /** |
149 | * Destroy channel, based on the other peer closing the | ||
150 | * connection. Also needs to remove this channel from | ||
151 | * the tunnel. | ||
152 | * | ||
153 | * FIXME: need to make it possible to defer destruction until we have | ||
154 | * received all messages up to the destroy, and right now the destroy | ||
155 | * message (and this API) fails to give is the information we need! | ||
156 | * | ||
157 | * FIXME: also need to know if the other peer got a destroy from | ||
158 | * us before! | ||
159 | * | ||
160 | * @param ch channel to destroy | ||
161 | */ | ||
162 | void | ||
163 | GCCH_channel_remote_destroy (struct CadetChannel *ch); | ||
164 | |||
165 | |||
166 | /** | ||
149 | * Handle data given by a client. | 167 | * Handle data given by a client. |
150 | * | 168 | * |
151 | * Check whether the client is allowed to send in this tunnel, save if | 169 | * Check whether the client is allowed to send in this tunnel, save if |
diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.c b/src/cadet/gnunet-service-cadet-new_tunnels.c index 67af76109..9161c41f7 100644 --- a/src/cadet/gnunet-service-cadet-new_tunnels.c +++ b/src/cadet/gnunet-service-cadet-new_tunnels.c | |||
@@ -476,6 +476,22 @@ GCT_count_channels (struct CadetTunnel *t) | |||
476 | 476 | ||
477 | 477 | ||
478 | /** | 478 | /** |
479 | * Lookup a channel by its @a chid. | ||
480 | * | ||
481 | * @param t tunnel to look in | ||
482 | * @param chid number of channel to find | ||
483 | * @return NULL if channel does not exist | ||
484 | */ | ||
485 | struct CadetChannel * | ||
486 | lookup_channel (struct CadetTunnel *t, | ||
487 | struct GNUNET_CADET_ChannelTunnelNumber chid) | ||
488 | { | ||
489 | return GNUNET_CONTAINER_multihashmap32_get (t->channels, | ||
490 | ntohl (chid.cn)); | ||
491 | } | ||
492 | |||
493 | |||
494 | /** | ||
479 | * Count all created connections of a tunnel. Not necessarily ready connections! | 495 | * Count all created connections of a tunnel. Not necessarily ready connections! |
480 | * | 496 | * |
481 | * @param t Tunnel on which to count. | 497 | * @param t Tunnel on which to count. |
@@ -1127,6 +1143,202 @@ t_ax_decrypt_and_validate (struct CadetTunnel *t, | |||
1127 | } | 1143 | } |
1128 | 1144 | ||
1129 | 1145 | ||
1146 | /** | ||
1147 | * Send a KX message. | ||
1148 | * | ||
1149 | * FIXME: does not take care of sender-authentication yet! | ||
1150 | * | ||
1151 | * @param t Tunnel on which to send it. | ||
1152 | * @param force_reply Force the other peer to reply with a KX message. | ||
1153 | */ | ||
1154 | static void | ||
1155 | send_kx (struct CadetTunnel *t, | ||
1156 | int force_reply) | ||
1157 | { | ||
1158 | struct CadetTunnelAxolotl *ax = &t->ax; | ||
1159 | struct CadetConnection *c; | ||
1160 | struct GNUNET_MQ_Envelope *env; | ||
1161 | struct GNUNET_CADET_TunnelKeyExchangeMessage *msg; | ||
1162 | enum GNUNET_CADET_KX_Flags flags; | ||
1163 | |||
1164 | #if FIXME | ||
1165 | if (NULL != t->ephm_h) | ||
1166 | { | ||
1167 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
1168 | " already queued, nop\n"); | ||
1169 | return; | ||
1170 | } | ||
1171 | #endif | ||
1172 | c = NULL; // FIXME: figure out where to transmit... | ||
1173 | |||
1174 | // GNUNET_assert (GNUNET_NO == GCT_is_loopback (t)); | ||
1175 | env = GNUNET_MQ_msg (msg, | ||
1176 | GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX); | ||
1177 | flags = GNUNET_CADET_KX_FLAG_NONE; | ||
1178 | if (GNUNET_YES == force_reply) | ||
1179 | flags |= GNUNET_CADET_KX_FLAG_FORCE_REPLY; | ||
1180 | msg->flags = htonl (flags); | ||
1181 | msg->cid = *GCC_get_id (c); | ||
1182 | GNUNET_CRYPTO_ecdhe_key_get_public (ax->kx_0, | ||
1183 | &msg->ephemeral_key); | ||
1184 | GNUNET_CRYPTO_ecdhe_key_get_public (ax->DHRs, | ||
1185 | &msg->ratchet_key); | ||
1186 | |||
1187 | // FIXME: send 'env'. | ||
1188 | #if FIXME | ||
1189 | t->ephm_h = GCC_send_prebuilt_message (&msg.header, | ||
1190 | UINT16_MAX, | ||
1191 | zero, | ||
1192 | c, | ||
1193 | GCC_is_origin (c, GNUNET_YES), | ||
1194 | GNUNET_YES, &ephm_sent, t); | ||
1195 | if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) | ||
1196 | GCT_change_estate (t, CADET_TUNNEL_KEY_SENT); | ||
1197 | #endif | ||
1198 | } | ||
1199 | |||
1200 | |||
1201 | /** | ||
1202 | * Handle KX message. | ||
1203 | * | ||
1204 | * FIXME: sender-authentication in KX is missing! | ||
1205 | * | ||
1206 | * @param ct connection/tunnel combo that received encrypted message | ||
1207 | * @param msg the key exchange message | ||
1208 | */ | ||
1209 | void | ||
1210 | GCT_handle_kx (struct CadetTConnection *ct, | ||
1211 | const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg) | ||
1212 | { | ||
1213 | struct CadetTunnel *t = ct->t; | ||
1214 | struct CadetTunnelAxolotl *ax = &t->ax; | ||
1215 | struct GNUNET_HashCode key_material[3]; | ||
1216 | struct GNUNET_CRYPTO_SymmetricSessionKey keys[5]; | ||
1217 | const char salt[] = "CADET Axolotl salt"; | ||
1218 | const struct GNUNET_PeerIdentity *pid; | ||
1219 | int am_I_alice; | ||
1220 | |||
1221 | pid = GCP_get_id (t->destination); | ||
1222 | if (0 > GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, | ||
1223 | pid)) | ||
1224 | am_I_alice = GNUNET_YES; | ||
1225 | else if (0 < GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, | ||
1226 | pid)) | ||
1227 | am_I_alice = GNUNET_NO; | ||
1228 | else | ||
1229 | { | ||
1230 | GNUNET_break_op (0); | ||
1231 | return; | ||
1232 | } | ||
1233 | |||
1234 | if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (msg->flags))) | ||
1235 | { | ||
1236 | if (NULL != t->rekey_task) | ||
1237 | { | ||
1238 | GNUNET_SCHEDULER_cancel (t->rekey_task); | ||
1239 | t->rekey_task = NULL; | ||
1240 | } | ||
1241 | send_kx (t, | ||
1242 | GNUNET_NO); | ||
1243 | } | ||
1244 | |||
1245 | if (0 == memcmp (&ax->DHRr, | ||
1246 | &msg->ratchet_key, | ||
1247 | sizeof (msg->ratchet_key))) | ||
1248 | { | ||
1249 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
1250 | " known ratchet key, exit\n"); | ||
1251 | return; | ||
1252 | } | ||
1253 | |||
1254 | ax->DHRr = msg->ratchet_key; | ||
1255 | |||
1256 | /* ECDH A B0 */ | ||
1257 | if (GNUNET_YES == am_I_alice) | ||
1258 | { | ||
1259 | GNUNET_CRYPTO_eddsa_ecdh (my_private_key, /* A */ | ||
1260 | &msg->ephemeral_key, /* B0 */ | ||
1261 | &key_material[0]); | ||
1262 | } | ||
1263 | else | ||
1264 | { | ||
1265 | GNUNET_CRYPTO_ecdh_eddsa (ax->kx_0, /* B0 */ | ||
1266 | &pid->public_key, /* A */ | ||
1267 | &key_material[0]); | ||
1268 | } | ||
1269 | |||
1270 | /* ECDH A0 B */ | ||
1271 | if (GNUNET_YES == am_I_alice) | ||
1272 | { | ||
1273 | GNUNET_CRYPTO_ecdh_eddsa (ax->kx_0, /* A0 */ | ||
1274 | &pid->public_key, /* B */ | ||
1275 | &key_material[1]); | ||
1276 | } | ||
1277 | else | ||
1278 | { | ||
1279 | GNUNET_CRYPTO_eddsa_ecdh (my_private_key, /* A */ | ||
1280 | &msg->ephemeral_key, /* B0 */ | ||
1281 | &key_material[1]); | ||
1282 | |||
1283 | |||
1284 | } | ||
1285 | |||
1286 | /* ECDH A0 B0 */ | ||
1287 | /* (This is the triple-DH, we could probably safely skip this, | ||
1288 | as A0/B0 are already in the key material.) */ | ||
1289 | GNUNET_CRYPTO_ecc_ecdh (ax->kx_0, /* A0 or B0 */ | ||
1290 | &msg->ephemeral_key, /* B0 or A0 */ | ||
1291 | &key_material[2]); | ||
1292 | |||
1293 | /* KDF */ | ||
1294 | GNUNET_CRYPTO_kdf (keys, sizeof (keys), | ||
1295 | salt, sizeof (salt), | ||
1296 | &key_material, sizeof (key_material), | ||
1297 | NULL); | ||
1298 | |||
1299 | if (0 == memcmp (&ax->RK, | ||
1300 | &keys[0], | ||
1301 | sizeof (ax->RK))) | ||
1302 | { | ||
1303 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
1304 | " known handshake key, exit\n"); | ||
1305 | return; | ||
1306 | } | ||
1307 | ax->RK = keys[0]; | ||
1308 | if (GNUNET_YES == am_I_alice) | ||
1309 | { | ||
1310 | ax->HKr = keys[1]; | ||
1311 | ax->NHKs = keys[2]; | ||
1312 | ax->NHKr = keys[3]; | ||
1313 | ax->CKr = keys[4]; | ||
1314 | ax->ratchet_flag = GNUNET_YES; | ||
1315 | } | ||
1316 | else | ||
1317 | { | ||
1318 | ax->HKs = keys[1]; | ||
1319 | ax->NHKr = keys[2]; | ||
1320 | ax->NHKs = keys[3]; | ||
1321 | ax->CKs = keys[4]; | ||
1322 | ax->ratchet_flag = GNUNET_NO; | ||
1323 | ax->ratchet_allowed = GNUNET_NO; | ||
1324 | ax->ratchet_counter = 0; | ||
1325 | ax->ratchet_expiration | ||
1326 | = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), | ||
1327 | ratchet_time); | ||
1328 | } | ||
1329 | ax->PNs = 0; | ||
1330 | ax->Nr = 0; | ||
1331 | ax->Ns = 0; | ||
1332 | |||
1333 | #if FIXME | ||
1334 | /* After KX is done, update state machine and begin transmissions... */ | ||
1335 | GCT_change_estate (t, | ||
1336 | CADET_TUNNEL_KEY_PING); | ||
1337 | send_queued_data (t); | ||
1338 | #endif | ||
1339 | } | ||
1340 | |||
1341 | |||
1130 | /* ************************************** end core crypto ***************************** */ | 1342 | /* ************************************** end core crypto ***************************** */ |
1131 | 1343 | ||
1132 | 1344 | ||
@@ -1493,7 +1705,8 @@ handle_plaintext_channel_ack (void *cls, | |||
1493 | 1705 | ||
1494 | 1706 | ||
1495 | /** | 1707 | /** |
1496 | * | 1708 | * We received a message saying that a channel should be destroyed. |
1709 | * Pass it on to the correct channel. | ||
1497 | * | 1710 | * |
1498 | * @param cls the `struct CadetTunnel` for which we decrypted the message | 1711 | * @param cls the `struct CadetTunnel` for which we decrypted the message |
1499 | * @param cm the message we received on the tunnel | 1712 | * @param cm the message we received on the tunnel |
@@ -1503,7 +1716,10 @@ handle_plaintext_channel_destroy (void *cls, | |||
1503 | const struct GNUNET_CADET_ChannelManageMessage *cm) | 1716 | const struct GNUNET_CADET_ChannelManageMessage *cm) |
1504 | { | 1717 | { |
1505 | struct CadetTunnel *t = cls; | 1718 | struct CadetTunnel *t = cls; |
1506 | GNUNET_break (0); // FIXME! | 1719 | struct CadetChannel *cc = lookup_channel (t, |
1720 | cm->chid); | ||
1721 | |||
1722 | GCCH_channel_remote_destroy (cc); | ||
1507 | } | 1723 | } |
1508 | 1724 | ||
1509 | 1725 | ||
@@ -1706,20 +1922,6 @@ GCT_add_inbound_connection (struct CadetTunnel *t, | |||
1706 | 1922 | ||
1707 | 1923 | ||
1708 | /** | 1924 | /** |
1709 | * Handle KX message. | ||
1710 | * | ||
1711 | * @param ct connection/tunnel combo that received encrypted message | ||
1712 | * @param msg the key exchange message | ||
1713 | */ | ||
1714 | void | ||
1715 | GCT_handle_kx (struct CadetTConnection *ct, | ||
1716 | const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg) | ||
1717 | { | ||
1718 | GNUNET_break (0); // not implemented | ||
1719 | } | ||
1720 | |||
1721 | |||
1722 | /** | ||
1723 | * Handle encrypted message. | 1925 | * Handle encrypted message. |
1724 | * | 1926 | * |
1725 | * @param ct connection/tunnel combo that received encrypted message | 1927 | * @param ct connection/tunnel combo that received encrypted message |