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"
34 #include "compression.h"
36 void send_key_changed(void) {
37 #ifndef DISABLE_LEGACY
38 send_request(everyone, "%d %x %s", KEY_CHANGED, rand(), myself->name);
40 /* Immediately send new keys to directly connected nodes to keep UDP mappings alive */
42 for list_each(connection_t, c, connection_list) {
43 if(c->edge && c->node && c->node->status.reachable && !c->node->status.sptps) {
44 send_ans_key(c->node);
50 /* Force key exchange for connections using SPTPS */
53 for splay_each(node_t, n, node_tree) {
54 if(n->status.reachable && n->status.validkey && n->status.sptps) {
55 sptps_force_kex(&n->sptps);
61 bool key_changed_h(connection_t *c, const char *request) {
62 char name[MAX_STRING_SIZE];
65 if(sscanf(request, "%*d %*x " MAX_STRING, name) != 1) {
66 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "KEY_CHANGED",
67 c->name, c->hostname);
71 if(seen_request(request)) {
75 n = lookup_node(name);
78 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist",
79 "KEY_CHANGED", c->name, c->hostname, name);
83 if(!n->status.sptps) {
84 n->status.validkey = false;
91 forward_request(c, request);
97 static bool send_sptps_data_myself(void *handle, uint8_t type, const void *data, size_t len) {
98 return send_sptps_data(handle, myself, type, data, len);
101 static bool send_initial_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
104 to->sptps.send_data = send_sptps_data_myself;
105 char buf[len * 4 / 3 + 5];
107 b64encode(data, buf, len);
109 return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_KEY, buf);
112 bool send_req_key(node_t *to) {
113 if(to->status.sptps) {
114 if(!node_read_ecdsa_public_key(to)) {
115 logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", to->name, to->hostname);
116 send_request(to->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, to->name, REQ_PUBKEY);
120 char label[25 + strlen(myself->name) + strlen(to->name)];
121 snprintf(label, sizeof(label), "tinc UDP key expansion %s %s", myself->name, to->name);
122 sptps_stop(&to->sptps);
123 to->status.validkey = false;
124 to->status.waitingforkey = true;
125 to->last_req_key = now.tv_sec;
126 to->incompression = myself->incompression;
127 return sptps_start(&to->sptps, to, true, true, myself->connection->ecdsa, to->ecdsa, label, sizeof(label), send_initial_sptps_data, receive_sptps_record);
130 return send_request(to->nexthop->connection, "%d %s %s", REQ_KEY, myself->name, to->name);
133 /* REQ_KEY is overloaded to allow arbitrary requests to be routed between two nodes. */
135 static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, node_t *to, int reqno) {
138 /* If this is a SPTPS packet, see if sending UDP info helps.
139 Note that we only do this if we're the destination or the static relay;
140 otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */
141 if((reqno == REQ_KEY || reqno == SPTPS_PACKET) && to->via == myself) {
142 send_udp_info(myself, from);
145 if(reqno == SPTPS_PACKET) {
146 /* This is a SPTPS data packet. */
148 char buf[MAX_STRING_SIZE];
151 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) {
152 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");
157 /* We don't just forward the request, because we want to use UDP if it's available. */
158 if(forwarding_mode == FMODE_INTERNAL) {
159 send_sptps_data(to, from, 0, buf, len);
163 /* The packet is for us */
164 if(!sptps_receive_data(&from->sptps, buf, len)) {
165 /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
166 so let's restart SPTPS in case that helps. But don't do that too often
167 to prevent storms. */
168 if(from->last_req_key < now.tv_sec - 10) {
169 logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
176 send_mtu_info(myself, from, MTU);
182 /* Requests that are not SPTPS data packets are forwarded as-is. */
185 return send_request(to->nexthop->connection, "%s", request);
188 /* The request is for us */
192 if(!node_read_ecdsa_public_key(from)) {
193 /* Request their key *before* we send our key back. Otherwise the first SPTPS packet from them will get dropped. */
194 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Preemptively requesting Ed25519 key for %s (%s)", from->name, from->hostname);
195 send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY);
198 char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa);
199 send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, from->name, ANS_PUBKEY, pubkey);
205 if(node_read_ecdsa_public_key(from)) {
206 logger(DEBUG_PROTOCOL, LOG_WARNING, "Got ANS_PUBKEY from %s (%s) even though we already have his pubkey", from->name, from->hostname);
210 char pubkey[MAX_STRING_SIZE];
212 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !(from->ecdsa = ecdsa_set_base64_public_key(pubkey))) {
213 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_PUBKEY", from->name, from->hostname, "invalid pubkey");
217 logger(DEBUG_PROTOCOL, LOG_INFO, "Learned Ed25519 public key from %s (%s)", from->name, from->hostname);
218 append_config_file(from->name, "Ed25519PublicKey", pubkey);
223 if(!node_read_ecdsa_public_key(from)) {
224 logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", from->name, from->hostname);
225 send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY);
229 if(from->sptps.label) {
230 logger(DEBUG_ALWAYS, LOG_DEBUG, "Got REQ_KEY from %s while we already started a SPTPS session!", from->name);
233 char buf[MAX_STRING_SIZE];
236 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) {
237 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS_START", from->name, from->hostname, "invalid SPTPS data");
241 char label[25 + strlen(from->name) + strlen(myself->name)];
242 snprintf(label, sizeof(label), "tinc UDP key expansion %s %s", from->name, myself->name);
243 sptps_stop(&from->sptps);
244 from->status.validkey = false;
245 from->status.waitingforkey = true;
246 from->last_req_key = now.tv_sec;
247 sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof(label), send_sptps_data_myself, receive_sptps_record);
248 sptps_receive_data(&from->sptps, buf, len);
249 send_mtu_info(myself, from, MTU);
254 logger(DEBUG_ALWAYS, LOG_ERR, "Unknown extended REQ_KEY request from %s (%s): %s", from->name, from->hostname, request);
259 bool req_key_h(connection_t *c, const char *request) {
260 char from_name[MAX_STRING_SIZE];
261 char to_name[MAX_STRING_SIZE];
265 if(sscanf(request, "%*d " MAX_STRING " " MAX_STRING " %d", from_name, to_name, &reqno) < 2) {
266 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "REQ_KEY", c->name,
271 if(!check_id(from_name) || !check_id(to_name)) {
272 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_KEY", c->name, c->hostname, "invalid name");
276 from = lookup_node(from_name);
279 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
280 "REQ_KEY", c->name, c->hostname, from_name);
284 to = lookup_node(to_name);
287 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
288 "REQ_KEY", c->name, c->hostname, to_name);
292 /* Check if this key request is for us */
294 if(to == myself) { /* Yes */
295 if(!from->status.reachable) {
296 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which is not reachable",
297 "REQ_KEY", c->name, c->hostname, from_name);
301 /* Is this an extended REQ_KEY message? */
302 if(experimental && reqno) {
303 return req_key_ext_h(c, request, from, to, reqno);
306 /* No, just send our key back */
313 if(!to->status.reachable) {
314 logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
315 "REQ_KEY", c->name, c->hostname, to_name);
319 /* Is this an extended REQ_KEY message? */
320 if(experimental && reqno) {
321 return req_key_ext_h(c, request, from, to, reqno);
324 send_request(to->nexthop->connection, "%s", request);
330 bool send_ans_key(node_t *to) {
331 if(to->status.sptps) {
335 #ifdef DISABLE_LEGACY
338 size_t keylen = myself->incipher ? cipher_keylength(myself->incipher) : 1;
339 char key[keylen * 2 + 1];
341 randomize(key, keylen);
343 cipher_close(to->incipher);
344 digest_close(to->indigest);
346 if(myself->incipher) {
347 to->incipher = cipher_open_by_nid(cipher_get_nid(myself->incipher));
353 if(!cipher_set_key(to->incipher, key, false)) {
358 if(myself->indigest) {
359 to->indigest = digest_open_by_nid(digest_get_nid(myself->indigest),
360 digest_length(myself->indigest));
366 if(!digest_set_key(to->indigest, key, keylen)) {
371 to->incompression = myself->incompression;
373 bin2hex(key, key, keylen);
375 // Reset sequence number and late packet window
376 to->received_seqno = 0;
380 memset(to->late, 0, replaywin);
383 to->status.validkey_in = true;
385 return send_request(to->nexthop->connection, "%d %s %s %s %d %d %zu %d", ANS_KEY,
386 myself->name, to->name, key,
387 cipher_get_nid(to->incipher),
388 digest_get_nid(to->indigest),
389 digest_length(to->indigest),
394 bool ans_key_h(connection_t *c, const char *request) {
395 char from_name[MAX_STRING_SIZE];
396 char to_name[MAX_STRING_SIZE];
397 char key[MAX_STRING_SIZE];
398 char address[MAX_STRING_SIZE] = "";
399 char port[MAX_STRING_SIZE] = "";
405 if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %zu %d "MAX_STRING" "MAX_STRING,
406 from_name, to_name, key, &cipher, &digest, &maclength,
407 &compression, address, port) < 7) {
408 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name,
413 if(!check_id(from_name) || !check_id(to_name)) {
414 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_KEY", c->name, c->hostname, "invalid name");
418 from = lookup_node(from_name);
421 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
422 "ANS_KEY", c->name, c->hostname, from_name);
426 to = lookup_node(to_name);
429 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
430 "ANS_KEY", c->name, c->hostname, to_name);
434 /* Forward it if necessary */
441 if(!to->status.reachable) {
442 logger(DEBUG_ALWAYS, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
443 "ANS_KEY", c->name, c->hostname, to_name);
447 if(!*address && from->address.sa.sa_family != AF_UNSPEC && to->minmtu) {
448 char *address, *port;
449 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name);
450 sockaddr2str(&from->address, &address, &port);
451 send_request(to->nexthop->connection, "%s %s %s", request, address, port);
457 return send_request(to->nexthop->connection, "%s", request);
460 #ifndef DISABLE_LEGACY
461 /* Don't use key material until every check has passed. */
462 cipher_close(from->outcipher);
463 digest_close(from->outdigest);
466 if(!from->status.sptps) {
467 from->status.validkey = false;
470 switch(compression) {
475 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
476 logger(DEBUG_ALWAYS, LOG_ERR, "LZ4 compression is unavailable on this node.");
480 case COMPRESS_LZO_HI:
481 case COMPRESS_LZO_LO:
485 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
486 logger(DEBUG_ALWAYS, LOG_ERR, "LZO compression is unavailable on this node.");
490 case COMPRESS_ZLIB_9:
491 case COMPRESS_ZLIB_8:
492 case COMPRESS_ZLIB_7:
493 case COMPRESS_ZLIB_6:
494 case COMPRESS_ZLIB_5:
495 case COMPRESS_ZLIB_4:
496 case COMPRESS_ZLIB_3:
497 case COMPRESS_ZLIB_2:
498 case COMPRESS_ZLIB_1:
502 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
503 logger(DEBUG_ALWAYS, LOG_ERR, "ZLIB compression is unavailable on this node.");
511 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
512 logger(DEBUG_ALWAYS, LOG_ERR, "Compression level %i is unrecognized by this node.", compression);
516 from->outcompression = compression;
518 /* SPTPS or old-style key exchange? */
520 if(from->status.sptps) {
521 uint8_t buf[strlen(key)];
522 size_t len = b64decode(key, buf, strlen(key));
524 if(!len || !sptps_receive_data(&from->sptps, buf, len)) {
525 /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
526 so let's restart SPTPS in case that helps. But don't do that too often
528 Note that simply relying on handshake timeout is not enough, because
529 that doesn't apply to key regeneration. */
530 if(from->last_req_key < now.tv_sec - 10) {
531 logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode handshake TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
538 if(from->status.validkey) {
539 if(*address && *port) {
540 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
541 sockaddr_t sa = str2sockaddr(address, port);
542 update_node_udp(from, &sa);
546 send_mtu_info(myself, from, MTU);
551 #ifdef DISABLE_LEGACY
552 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses legacy protocol!", from->name, from->hostname);
555 /* Check and lookup cipher and digest algorithms */
558 if(!(from->outcipher = cipher_open_by_nid(cipher))) {
559 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname);
563 from->outcipher = NULL;
567 if(!(from->outdigest = digest_open_by_nid(digest, maclength))) {
568 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname);
572 from->outdigest = NULL;
575 if(maclength != digest_length(from->outdigest)) {
576 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname);
582 size_t keylen = hex2bin(key, key, sizeof(key));
584 if(keylen != (from->outcipher ? cipher_keylength(from->outcipher) : 1)) {
585 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname);
589 /* Update our copy of the origin's packet key */
591 if(from->outcipher && !cipher_set_key(from->outcipher, key, true)) {
595 if(from->outdigest && !digest_set_key(from->outdigest, key, keylen)) {
599 from->status.validkey = true;
600 from->sent_seqno = 0;
602 if(*address && *port) {
603 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
604 sockaddr_t sa = str2sockaddr(address, port);
605 update_node_udp(from, &sa);