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, prng(UINT32_MAX), 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;
106 char buf[B64_SIZE(len)];
107 b64encode_tinc(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_tinc(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_tinc(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_free(&to->incipher);
344 digest_free(&to->indigest);
346 if(myself->incipher) {
347 to->incipher = cipher_alloc();
349 if(!cipher_open_by_nid(to->incipher, cipher_get_nid(myself->incipher))) {
353 if(!cipher_set_key(to->incipher, key, false)) {
358 if(myself->indigest) {
359 to->indigest = digest_alloc();
361 if(!digest_open_by_nid(to->indigest,
362 digest_get_nid(myself->indigest),
363 digest_length(myself->indigest))) {
367 if(!digest_set_key(to->indigest, key, keylen)) {
372 to->incompression = myself->incompression;
374 bin2hex(key, key, keylen);
376 // Reset sequence number and late packet window
377 to->received_seqno = 0;
381 memset(to->late, 0, replaywin);
384 to->status.validkey_in = true;
386 return send_request(to->nexthop->connection, "%d %s %s %s %d %d %lu %d", ANS_KEY,
387 myself->name, to->name, key,
388 cipher_get_nid(to->incipher),
389 digest_get_nid(to->indigest),
390 (unsigned long)digest_length(to->indigest),
395 bool ans_key_h(connection_t *c, const char *request) {
396 char from_name[MAX_STRING_SIZE];
397 char to_name[MAX_STRING_SIZE];
398 char key[MAX_STRING_SIZE];
399 char address[MAX_STRING_SIZE] = "";
400 char port[MAX_STRING_SIZE] = "";
402 unsigned long maclength;
406 if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %lu %d "MAX_STRING" "MAX_STRING,
407 from_name, to_name, key, &cipher, &digest, &maclength,
408 &compression, address, port) < 7) {
409 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name,
414 if(!check_id(from_name) || !check_id(to_name)) {
415 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_KEY", c->name, c->hostname, "invalid name");
419 from = lookup_node(from_name);
422 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
423 "ANS_KEY", c->name, c->hostname, from_name);
427 to = lookup_node(to_name);
430 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
431 "ANS_KEY", c->name, c->hostname, to_name);
435 /* Forward it if necessary */
442 if(!to->status.reachable) {
443 logger(DEBUG_ALWAYS, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
444 "ANS_KEY", c->name, c->hostname, to_name);
448 if(!*address && from->address.sa.sa_family != AF_UNSPEC && to->minmtu) {
449 char *address, *port;
450 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name);
451 sockaddr2str(&from->address, &address, &port);
452 send_request(to->nexthop->connection, "%s %s %s", request, address, port);
458 return send_request(to->nexthop->connection, "%s", request);
461 #ifndef DISABLE_LEGACY
462 /* Don't use key material until every check has passed. */
463 cipher_free(&from->outcipher);
464 digest_free(&from->outdigest);
467 if(!from->status.sptps) {
468 from->status.validkey = false;
471 switch(compression) {
476 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
477 logger(DEBUG_ALWAYS, LOG_ERR, "LZ4 compression is unavailable on this node.");
481 case COMPRESS_LZO_HI:
482 case COMPRESS_LZO_LO:
486 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
487 logger(DEBUG_ALWAYS, LOG_ERR, "LZO compression is unavailable on this node.");
491 case COMPRESS_ZLIB_9:
492 case COMPRESS_ZLIB_8:
493 case COMPRESS_ZLIB_7:
494 case COMPRESS_ZLIB_6:
495 case COMPRESS_ZLIB_5:
496 case COMPRESS_ZLIB_4:
497 case COMPRESS_ZLIB_3:
498 case COMPRESS_ZLIB_2:
499 case COMPRESS_ZLIB_1:
503 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
504 logger(DEBUG_ALWAYS, LOG_ERR, "ZLIB compression is unavailable on this node.");
512 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
513 logger(DEBUG_ALWAYS, LOG_ERR, "Compression level %i is unrecognized by this node.", compression);
517 from->outcompression = compression;
519 /* SPTPS or old-style key exchange? */
521 if(from->status.sptps) {
522 uint8_t buf[strlen(key)];
523 size_t len = b64decode_tinc(key, buf, strlen(key));
525 if(!len || !sptps_receive_data(&from->sptps, buf, len)) {
526 /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
527 so let's restart SPTPS in case that helps. But don't do that too often
529 Note that simply relying on handshake timeout is not enough, because
530 that doesn't apply to key regeneration. */
531 if(from->last_req_key < now.tv_sec - 10) {
532 logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode handshake TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
539 if(from->status.validkey) {
540 if(*address && *port) {
541 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
542 sockaddr_t sa = str2sockaddr(address, port);
543 update_node_udp(from, &sa);
547 send_mtu_info(myself, from, MTU);
552 #ifdef DISABLE_LEGACY
553 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses legacy protocol!", from->name, from->hostname);
556 /* Check and lookup cipher and digest algorithms */
559 from->outcipher = cipher_alloc();
561 if(!cipher_open_by_nid(from->outcipher, cipher)) {
562 cipher_free(&from->outcipher);
563 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname);
567 from->outcipher = NULL;
571 from->outdigest = digest_alloc();
573 if(!digest_open_by_nid(from->outdigest, digest, maclength)) {
574 digest_free(&from->outdigest);
575 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname);
579 from->outdigest = NULL;
582 if(maclength != digest_length(from->outdigest)) {
583 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname);
589 size_t keylen = hex2bin(key, key, sizeof(key));
591 if(keylen != (from->outcipher ? cipher_keylength(from->outcipher) : 1)) {
592 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname);
596 /* Update our copy of the origin's packet key */
598 if(from->outcipher && !cipher_set_key(from->outcipher, key, true)) {
602 if(from->outdigest && !digest_set_key(from->outdigest, key, keylen)) {
606 from->status.validkey = true;
607 from->sent_seqno = 0;
609 if(*address && *port) {
610 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
611 sockaddr_t sa = str2sockaddr(address, port);
612 update_node_udp(from, &sa);