2 protocol_key.c -- handle the meta-protocol, key exchange
3 Copyright (C) 1999-2005 Ivo Timmermans,
4 2000-2017 Guus Sliepen <guus@tinc-vpn.org>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include "connection.h"
37 #ifndef DISABLE_LEGACY
38 static bool mykeyused = false;
41 void send_key_changed(void) {
42 #ifndef DISABLE_LEGACY
43 send_request(everyone, "%d %x %s", KEY_CHANGED, rand(), myself->name);
45 /* Immediately send new keys to directly connected nodes to keep UDP mappings alive */
47 for list_each(connection_t, c, connection_list) {
48 if(c->edge && c->node && c->node->status.reachable && !c->node->status.sptps) {
49 send_ans_key(c->node);
55 /* Force key exchange for connections using SPTPS */
58 for splay_each(node_t, n, node_tree) {
59 if(n->status.reachable && n->status.validkey && n->status.sptps) {
60 sptps_force_kex(&n->sptps);
66 bool key_changed_h(connection_t *c, const char *request) {
67 char name[MAX_STRING_SIZE];
70 if(sscanf(request, "%*d %*x " MAX_STRING, name) != 1) {
71 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "KEY_CHANGED",
72 c->name, c->hostname);
76 if(seen_request(request)) {
80 n = lookup_node(name);
83 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist",
84 "KEY_CHANGED", c->name, c->hostname, name);
88 if(!n->status.sptps) {
89 n->status.validkey = false;
96 forward_request(c, request);
102 static bool send_sptps_data_myself(void *handle, uint8_t type, const void *data, size_t len) {
103 return send_sptps_data(handle, myself, type, data, len);
106 static bool send_initial_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
109 to->sptps.send_data = send_sptps_data_myself;
110 char buf[len * 4 / 3 + 5];
112 b64encode(data, buf, len);
114 return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_KEY, buf);
117 bool send_req_key(node_t *to) {
118 if(to->status.sptps) {
119 if(!node_read_ecdsa_public_key(to)) {
120 logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", to->name, to->hostname);
121 send_request(to->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, to->name, REQ_PUBKEY);
125 char label[25 + strlen(myself->name) + strlen(to->name)];
126 snprintf(label, sizeof(label), "tinc UDP key expansion %s %s", myself->name, to->name);
127 sptps_stop(&to->sptps);
128 to->status.validkey = false;
129 to->status.waitingforkey = true;
130 to->last_req_key = now.tv_sec;
131 to->incompression = myself->incompression;
132 return sptps_start(&to->sptps, to, true, true, myself->connection->ecdsa, to->ecdsa, label, sizeof(label), send_initial_sptps_data, receive_sptps_record);
135 return send_request(to->nexthop->connection, "%d %s %s", REQ_KEY, myself->name, to->name);
138 /* REQ_KEY is overloaded to allow arbitrary requests to be routed between two nodes. */
140 static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, node_t *to, int reqno) {
143 /* If this is a SPTPS packet, see if sending UDP info helps.
144 Note that we only do this if we're the destination or the static relay;
145 otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */
146 if((reqno == REQ_KEY || reqno == SPTPS_PACKET) && to->via == myself) {
147 send_udp_info(myself, from);
150 if(reqno == SPTPS_PACKET) {
151 /* This is a SPTPS data packet. */
153 char buf[MAX_STRING_SIZE];
156 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) {
157 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s) to %s (%s): %s", "SPTPS_PACKET", from->name, from->hostname, to->name, to->hostname, "invalid SPTPS data");
162 /* We don't just forward the request, because we want to use UDP if it's available. */
163 if(forwarding_mode == FMODE_INTERNAL) {
164 send_sptps_data(to, from, 0, buf, len);
168 /* The packet is for us */
169 if(!sptps_receive_data(&from->sptps, buf, len)) {
170 /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
171 so let's restart SPTPS in case that helps. But don't do that too often
172 to prevent storms. */
173 if(from->last_req_key < now.tv_sec - 10) {
174 logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
181 send_mtu_info(myself, from, MTU);
187 /* Requests that are not SPTPS data packets are forwarded as-is. */
190 return send_request(to->nexthop->connection, "%s", request);
193 /* The request is for us */
197 if(!node_read_ecdsa_public_key(from)) {
198 /* Request their key *before* we send our key back. Otherwise the first SPTPS packet from them will get dropped. */
199 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Preemptively requesting Ed25519 key for %s (%s)", from->name, from->hostname);
200 send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY);
203 char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa);
204 send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, from->name, ANS_PUBKEY, pubkey);
210 if(node_read_ecdsa_public_key(from)) {
211 logger(DEBUG_PROTOCOL, LOG_WARNING, "Got ANS_PUBKEY from %s (%s) even though we already have his pubkey", from->name, from->hostname);
215 char pubkey[MAX_STRING_SIZE];
217 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !(from->ecdsa = ecdsa_set_base64_public_key(pubkey))) {
218 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_PUBKEY", from->name, from->hostname, "invalid pubkey");
222 logger(DEBUG_PROTOCOL, LOG_INFO, "Learned Ed25519 public key from %s (%s)", from->name, from->hostname);
223 append_config_file(from->name, "Ed25519PublicKey", pubkey);
228 if(!node_read_ecdsa_public_key(from)) {
229 logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", from->name, from->hostname);
230 send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY);
234 if(from->sptps.label) {
235 logger(DEBUG_ALWAYS, LOG_DEBUG, "Got REQ_KEY from %s while we already started a SPTPS session!", from->name);
238 char buf[MAX_STRING_SIZE];
241 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) {
242 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS_START", from->name, from->hostname, "invalid SPTPS data");
246 char label[25 + strlen(from->name) + strlen(myself->name)];
247 snprintf(label, sizeof(label), "tinc UDP key expansion %s %s", from->name, myself->name);
248 sptps_stop(&from->sptps);
249 from->status.validkey = false;
250 from->status.waitingforkey = true;
251 from->last_req_key = now.tv_sec;
252 sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof(label), send_sptps_data_myself, receive_sptps_record);
253 sptps_receive_data(&from->sptps, buf, len);
254 send_mtu_info(myself, from, MTU);
259 logger(DEBUG_ALWAYS, LOG_ERR, "Unknown extended REQ_KEY request from %s (%s): %s", from->name, from->hostname, request);
264 bool req_key_h(connection_t *c, const char *request) {
265 char from_name[MAX_STRING_SIZE];
266 char to_name[MAX_STRING_SIZE];
270 if(sscanf(request, "%*d " MAX_STRING " " MAX_STRING " %d", from_name, to_name, &reqno) < 2) {
271 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "REQ_KEY", c->name,
276 if(!check_id(from_name) || !check_id(to_name)) {
277 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_KEY", c->name, c->hostname, "invalid name");
281 from = lookup_node(from_name);
284 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
285 "REQ_KEY", c->name, c->hostname, from_name);
289 to = lookup_node(to_name);
292 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
293 "REQ_KEY", c->name, c->hostname, to_name);
297 /* Check if this key request is for us */
299 if(to == myself) { /* Yes */
300 if(!from->status.reachable) {
301 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which is not reachable",
302 "REQ_KEY", c->name, c->hostname, from_name);
305 /* Is this an extended REQ_KEY message? */
306 if(experimental && reqno) {
307 return req_key_ext_h(c, request, from, to, reqno);
310 /* No, just send our key back */
317 if(!to->status.reachable) {
318 logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
319 "REQ_KEY", c->name, c->hostname, to_name);
323 /* Is this an extended REQ_KEY message? */
324 if(experimental && reqno) {
325 return req_key_ext_h(c, request, from, to, reqno);
328 send_request(to->nexthop->connection, "%s", request);
334 bool send_ans_key(node_t *to) {
335 if(to->status.sptps) {
339 #ifdef DISABLE_LEGACY
342 size_t keylen = myself->incipher ? cipher_keylength(myself->incipher) : 1;
343 char key[keylen * 2 + 1];
345 randomize(key, keylen);
347 cipher_close(to->incipher);
348 digest_close(to->indigest);
350 if(myself->incipher) {
351 to->incipher = cipher_open_by_nid(cipher_get_nid(myself->incipher));
357 if(!cipher_set_key(to->incipher, key, false)) {
362 if(myself->indigest) {
363 to->indigest = digest_open_by_nid(digest_get_nid(myself->indigest), digest_length(myself->indigest));
369 if(!digest_set_key(to->indigest, key, keylen)) {
374 to->incompression = myself->incompression;
376 bin2hex(key, key, keylen);
378 // Reset sequence number and late packet window
380 to->received_seqno = 0;
384 memset(to->late, 0, replaywin);
387 to->status.validkey_in = true;
389 return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY,
390 myself->name, to->name, key,
391 cipher_get_nid(to->incipher),
392 digest_get_nid(to->indigest),
393 (int)digest_length(to->indigest),
398 bool ans_key_h(connection_t *c, const char *request) {
399 char from_name[MAX_STRING_SIZE];
400 char to_name[MAX_STRING_SIZE];
401 char key[MAX_STRING_SIZE];
402 char address[MAX_STRING_SIZE] = "";
403 char port[MAX_STRING_SIZE] = "";
404 int cipher, digest, maclength, compression;
407 if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d "MAX_STRING" "MAX_STRING,
408 from_name, to_name, key, &cipher, &digest, &maclength,
409 &compression, address, port) < 7) {
410 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name,
415 if(!check_id(from_name) || !check_id(to_name)) {
416 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_KEY", c->name, c->hostname, "invalid name");
420 from = lookup_node(from_name);
423 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
424 "ANS_KEY", c->name, c->hostname, from_name);
428 to = lookup_node(to_name);
431 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
432 "ANS_KEY", c->name, c->hostname, to_name);
436 /* Forward it if necessary */
443 if(!to->status.reachable) {
444 logger(DEBUG_ALWAYS, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
445 "ANS_KEY", c->name, c->hostname, to_name);
449 if(!*address && from->address.sa.sa_family != AF_UNSPEC && to->minmtu) {
450 char *address, *port;
451 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name);
452 sockaddr2str(&from->address, &address, &port);
453 send_request(to->nexthop->connection, "%s %s %s", request, address, port);
459 return send_request(to->nexthop->connection, "%s", request);
462 #ifndef DISABLE_LEGACY
463 /* Don't use key material until every check has passed. */
464 cipher_close(from->outcipher);
465 digest_close(from->outdigest);
468 if(!from->status.sptps) {
469 from->status.validkey = false;
472 switch(compression) {
477 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
478 logger(DEBUG_ALWAYS, LOG_ERR, "LZ4 compression is unavailable on this node.");
487 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
488 logger(DEBUG_ALWAYS, LOG_ERR, "LZO compression is unavailable on this node.");
504 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
505 logger(DEBUG_ALWAYS, LOG_ERR, "ZLIB compression is unavailable on this node.");
513 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
514 logger(DEBUG_ALWAYS, LOG_ERR, "Compression level %i is unrecognized by this node.", compression);
518 from->outcompression = compression;
520 /* SPTPS or old-style key exchange? */
522 if(from->status.sptps) {
523 char buf[strlen(key)];
524 size_t len = b64decode(key, buf, strlen(key));
526 if(!len || !sptps_receive_data(&from->sptps, buf, len)) {
527 /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
528 so let's restart SPTPS in case that helps. But don't do that too often
530 Note that simply relying on handshake timeout is not enough, because
531 that doesn't apply to key regeneration. */
532 if(from->last_req_key < now.tv_sec - 10) {
533 logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode handshake TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
540 if(from->status.validkey) {
541 if(*address && *port) {
542 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
543 sockaddr_t sa = str2sockaddr(address, port);
544 update_node_udp(from, &sa);
548 send_mtu_info(myself, from, MTU);
553 #ifdef DISABLE_LEGACY
554 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses legacy protocol!", from->name, from->hostname);
557 /* Check and lookup cipher and digest algorithms */
560 if(!(from->outcipher = cipher_open_by_nid(cipher))) {
561 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname);
565 from->outcipher = NULL;
569 if(!(from->outdigest = digest_open_by_nid(digest, maclength))) {
570 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname);
574 from->outdigest = NULL;
577 if((size_t)maclength != digest_length(from->outdigest)) {
578 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname);
584 size_t keylen = hex2bin(key, key, sizeof(key));
586 if(keylen != (from->outcipher ? cipher_keylength(from->outcipher) : 1)) {
587 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname);
591 /* Update our copy of the origin's packet key */
593 if(from->outcipher && !cipher_set_key(from->outcipher, key, true)) {
597 if(from->outdigest && !digest_set_key(from->outdigest, key, keylen)) {
601 from->status.validkey = true;
602 from->sent_seqno = 0;
604 if(*address && *port) {
605 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
606 sockaddr_t sa = str2sockaddr(address, port);
607 update_node_udp(from, &sa);