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"
38 void send_key_changed(void) {
39 #ifndef DISABLE_LEGACY
40 send_request(everyone, "%d %x %s", KEY_CHANGED, prng(UINT32_MAX), myself->name);
42 /* Immediately send new keys to directly connected nodes to keep UDP mappings alive */
44 for list_each(connection_t, c, &connection_list) {
45 if(c->edge && c->node && c->node->status.reachable && !c->node->status.sptps) {
46 send_ans_key(c->node);
52 /* Force key exchange for connections using SPTPS */
55 for splay_each(node_t, n, &node_tree) {
56 if(n->status.reachable && n->status.validkey && n->status.sptps) {
57 sptps_force_kex(&n->sptps);
63 bool key_changed_h(connection_t *c, const char *request) {
64 char name[MAX_STRING_SIZE];
67 if(sscanf(request, "%*d %*x " MAX_STRING, name) != 1) {
68 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "KEY_CHANGED",
69 c->name, c->hostname);
73 if(seen_request(request)) {
77 n = lookup_node(name);
80 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist",
81 "KEY_CHANGED", c->name, c->hostname, name);
85 if(!n->status.sptps) {
86 n->status.validkey = false;
93 forward_request(c, request);
99 static bool send_sptps_data_myself(void *handle, uint8_t type, const void *data, size_t len) {
100 return send_sptps_data(handle, myself, type, data, len);
103 static bool send_initial_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
106 to->sptps.send_data = send_sptps_data_myself;
108 char *buf = alloca(B64_SIZE(len));
109 b64encode_tinc(data, buf, len);
111 return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_KEY, buf);
114 bool send_req_key(node_t *to) {
115 if(to->status.sptps) {
116 if(!node_read_ecdsa_public_key(to)) {
117 logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", to->name, to->hostname);
118 send_request(to->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, to->name, REQ_PUBKEY);
122 const size_t labellen = 25 + strlen(myself->name) + strlen(to->name);
123 char *label = alloca(labellen);
124 snprintf(label, labellen, "tinc UDP key expansion %s %s", myself->name, to->name);
126 sptps_stop(&to->sptps);
127 to->status.validkey = false;
128 to->status.waitingforkey = true;
129 to->last_req_key = now.tv_sec;
130 to->incompression = myself->incompression;
132 sptps_params_t params = {
136 .mykey = myself->connection->ecdsa,
139 .labellen = sizeof(label),
140 .send_data = send_initial_sptps_data,
141 .receive_record = receive_sptps_record,
144 return sptps_start(&to->sptps, ¶ms);
147 return send_request(to->nexthop->connection, "%d %s %s", REQ_KEY, myself->name, to->name);
150 /* REQ_KEY is overloaded to allow arbitrary requests to be routed between two nodes. */
152 static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, node_t *to, int reqno) {
155 /* If this is a SPTPS packet, see if sending UDP info helps.
156 Note that we only do this if we're the destination or the static relay;
157 otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */
158 if((reqno == REQ_KEY || reqno == SPTPS_PACKET) && to->via == myself) {
159 send_udp_info(myself, from);
162 if(reqno == SPTPS_PACKET) {
163 /* This is a SPTPS data packet. */
165 char buf[MAX_STRING_SIZE];
168 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode_tinc(buf, buf, strlen(buf)))) {
169 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");
174 /* We don't just forward the request, because we want to use UDP if it's available. */
175 if(forwarding_mode == FMODE_INTERNAL) {
176 send_sptps_data(to, from, 0, buf, len);
180 /* The packet is for us */
181 if(!sptps_receive_data(&from->sptps, buf, len)) {
182 /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
183 so let's restart SPTPS in case that helps. But don't do that too often
184 to prevent storms. */
185 if(from->last_req_key < now.tv_sec - 10) {
186 logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
193 send_mtu_info(myself, from, MTU);
199 /* Requests that are not SPTPS data packets are forwarded as-is. */
202 return send_request(to->nexthop->connection, "%s", request);
205 /* The request is for us */
209 if(!node_read_ecdsa_public_key(from)) {
210 /* Request their key *before* we send our key back. Otherwise the first SPTPS packet from them will get dropped. */
211 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Preemptively requesting Ed25519 key for %s (%s)", from->name, from->hostname);
212 send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY);
215 char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa);
216 send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, from->name, ANS_PUBKEY, pubkey);
222 if(node_read_ecdsa_public_key(from)) {
223 logger(DEBUG_PROTOCOL, LOG_WARNING, "Got ANS_PUBKEY from %s (%s) even though we already have his pubkey", from->name, from->hostname);
227 char pubkey[MAX_STRING_SIZE];
229 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !(from->ecdsa = ecdsa_set_base64_public_key(pubkey))) {
230 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_PUBKEY", from->name, from->hostname, "invalid pubkey");
234 logger(DEBUG_PROTOCOL, LOG_INFO, "Learned Ed25519 public key from %s (%s)", from->name, from->hostname);
235 append_config_file(from->name, "Ed25519PublicKey", pubkey);
240 if(!node_read_ecdsa_public_key(from)) {
241 logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", from->name, from->hostname);
242 send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY);
246 if(from->sptps.label) {
247 logger(DEBUG_ALWAYS, LOG_DEBUG, "Got REQ_KEY from %s while we already started a SPTPS session!", from->name);
250 char buf[MAX_STRING_SIZE];
253 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode_tinc(buf, buf, strlen(buf)))) {
254 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS_START", from->name, from->hostname, "invalid SPTPS data");
258 const size_t labellen = 25 + strlen(from->name) + strlen(myself->name);
259 char *label = alloca(labellen);
260 snprintf(label, labellen, "tinc UDP key expansion %s %s", from->name, myself->name);
261 sptps_stop(&from->sptps);
262 from->status.validkey = false;
263 from->status.waitingforkey = true;
264 from->last_req_key = now.tv_sec;
266 sptps_params_t params = {
270 .mykey = myself->connection->ecdsa,
271 .hiskey = from->ecdsa,
273 .labellen = sizeof(label),
274 .send_data = send_sptps_data_myself,
275 .receive_record = receive_sptps_record,
278 sptps_start(&from->sptps, ¶ms);
279 sptps_receive_data(&from->sptps, buf, len);
280 send_mtu_info(myself, from, MTU);
285 logger(DEBUG_ALWAYS, LOG_ERR, "Unknown extended REQ_KEY request from %s (%s): %s", from->name, from->hostname, request);
290 bool req_key_h(connection_t *c, const char *request) {
291 char from_name[MAX_STRING_SIZE];
292 char to_name[MAX_STRING_SIZE];
296 if(sscanf(request, "%*d " MAX_STRING " " MAX_STRING " %d", from_name, to_name, &reqno) < 2) {
297 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "REQ_KEY", c->name,
302 if(!check_id(from_name) || !check_id(to_name)) {
303 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_KEY", c->name, c->hostname, "invalid name");
307 from = lookup_node(from_name);
310 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
311 "REQ_KEY", c->name, c->hostname, from_name);
315 to = lookup_node(to_name);
318 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
319 "REQ_KEY", c->name, c->hostname, to_name);
323 /* Check if this key request is for us */
325 if(to == myself) { /* Yes */
326 if(!from->status.reachable) {
327 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which is not reachable",
328 "REQ_KEY", c->name, c->hostname, from_name);
332 /* Is this an extended REQ_KEY message? */
333 if(experimental && reqno) {
334 return req_key_ext_h(c, request, from, to, reqno);
337 /* No, just send our key back */
344 if(!to->status.reachable) {
345 logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
346 "REQ_KEY", c->name, c->hostname, to_name);
350 /* Is this an extended REQ_KEY message? */
351 if(experimental && reqno) {
352 return req_key_ext_h(c, request, from, to, reqno);
355 send_request(to->nexthop->connection, "%s", request);
361 bool send_ans_key(node_t *to) {
362 if(to->status.sptps) {
366 #ifdef DISABLE_LEGACY
369 size_t keylen = myself->incipher ? cipher_keylength(myself->incipher) : 1;
370 size_t keyhexlen = HEX_SIZE(keylen);
371 char *key = alloca(keyhexlen);
373 randomize(key, keylen);
375 cipher_free(to->incipher);
378 digest_free(to->indigest);
381 if(myself->incipher) {
382 to->incipher = cipher_alloc();
384 if(!cipher_open_by_nid(to->incipher, cipher_get_nid(myself->incipher))) {
388 if(!cipher_set_key(to->incipher, key, false)) {
393 if(myself->indigest) {
394 to->indigest = digest_alloc();
396 if(!digest_open_by_nid(to->indigest,
397 digest_get_nid(myself->indigest),
398 digest_length(myself->indigest))) {
402 if(!digest_set_key(to->indigest, key, keylen)) {
407 to->incompression = myself->incompression;
409 bin2hex(key, key, keylen);
411 // Reset sequence number and late packet window
412 to->received_seqno = 0;
416 memset(to->late, 0, replaywin);
419 to->status.validkey_in = true;
421 bool sent = send_request(to->nexthop->connection, "%d %s %s %s %d %d %lu %d", ANS_KEY,
422 myself->name, to->name, key,
423 cipher_get_nid(to->incipher),
424 digest_get_nid(to->indigest),
425 (unsigned long)digest_length(to->indigest),
428 memzero(key, keyhexlen);
434 bool ans_key_h(connection_t *c, const char *request) {
435 char from_name[MAX_STRING_SIZE];
436 char to_name[MAX_STRING_SIZE];
437 char key[MAX_STRING_SIZE];
438 char address[MAX_STRING_SIZE] = "";
439 char port[MAX_STRING_SIZE] = "";
441 unsigned long maclength;
445 if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %lu %d "MAX_STRING" "MAX_STRING,
446 from_name, to_name, key, &cipher, &digest, &maclength,
447 &compression, address, port) < 7) {
448 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name,
453 if(!check_id(from_name) || !check_id(to_name)) {
454 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_KEY", c->name, c->hostname, "invalid name");
458 from = lookup_node(from_name);
461 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
462 "ANS_KEY", c->name, c->hostname, from_name);
466 to = lookup_node(to_name);
469 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
470 "ANS_KEY", c->name, c->hostname, to_name);
474 /* Forward it if necessary */
481 if(!to->status.reachable) {
482 logger(DEBUG_ALWAYS, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
483 "ANS_KEY", c->name, c->hostname, to_name);
487 if(!*address && from->address.sa.sa_family != AF_UNSPEC && to->minmtu) {
488 char *address, *port;
489 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name);
490 sockaddr2str(&from->address, &address, &port);
491 send_request(to->nexthop->connection, "%s %s %s", request, address, port);
497 return send_request(to->nexthop->connection, "%s", request);
500 #ifndef DISABLE_LEGACY
501 /* Don't use key material until every check has passed. */
502 cipher_free(from->outcipher);
503 from->outcipher = NULL;
505 digest_free(from->outdigest);
506 from->outdigest = NULL;
509 if(!from->status.sptps) {
510 from->status.validkey = false;
513 switch(compression) {
518 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
519 logger(DEBUG_ALWAYS, LOG_ERR, "LZ4 compression is unavailable on this node.");
523 case COMPRESS_LZO_HI:
524 case COMPRESS_LZO_LO:
528 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
529 logger(DEBUG_ALWAYS, LOG_ERR, "LZO compression is unavailable on this node.");
533 case COMPRESS_ZLIB_9:
534 case COMPRESS_ZLIB_8:
535 case COMPRESS_ZLIB_7:
536 case COMPRESS_ZLIB_6:
537 case COMPRESS_ZLIB_5:
538 case COMPRESS_ZLIB_4:
539 case COMPRESS_ZLIB_3:
540 case COMPRESS_ZLIB_2:
541 case COMPRESS_ZLIB_1:
545 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
546 logger(DEBUG_ALWAYS, LOG_ERR, "ZLIB compression is unavailable on this node.");
554 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
555 logger(DEBUG_ALWAYS, LOG_ERR, "Compression level %i is unrecognized by this node.", compression);
559 from->outcompression = compression;
561 /* SPTPS or old-style key exchange? */
563 if(from->status.sptps) {
564 const size_t buflen = strlen(key);
565 uint8_t *buf = alloca(buflen);
566 size_t len = b64decode_tinc(key, buf, buflen);
568 if(!len || !sptps_receive_data(&from->sptps, buf, len)) {
569 /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
570 so let's restart SPTPS in case that helps. But don't do that too often
572 Note that simply relying on handshake timeout is not enough, because
573 that doesn't apply to key regeneration. */
574 if(from->last_req_key < now.tv_sec - 10) {
575 logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode handshake TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
582 if(from->status.validkey) {
583 if(*address && *port) {
584 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
585 sockaddr_t sa = str2sockaddr(address, port);
586 update_node_udp(from, &sa);
590 send_mtu_info(myself, from, MTU);
595 #ifdef DISABLE_LEGACY
596 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses legacy protocol!", from->name, from->hostname);
599 /* Check and lookup cipher and digest algorithms */
602 from->outcipher = cipher_alloc();
604 if(!cipher_open_by_nid(from->outcipher, cipher)) {
605 cipher_free(from->outcipher);
606 from->outcipher = NULL;
607 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname);
611 from->outcipher = NULL;
615 from->outdigest = digest_alloc();
617 if(!digest_open_by_nid(from->outdigest, digest, maclength)) {
618 digest_free(from->outdigest);
619 from->outdigest = NULL;
620 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname);
624 from->outdigest = NULL;
627 if(maclength != digest_length(from->outdigest)) {
628 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname);
634 size_t keylen = hex2bin(key, key, sizeof(key));
636 if(keylen != (from->outcipher ? cipher_keylength(from->outcipher) : 1)) {
637 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname);
641 /* Update our copy of the origin's packet key */
643 if(from->outcipher && !cipher_set_key(from->outcipher, key, true)) {
647 if(from->outdigest && !digest_set_key(from->outdigest, key, keylen)) {
651 from->status.validkey = true;
652 from->sent_seqno = 0;
654 if(*address && *port) {
655 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
656 sockaddr_t sa = str2sockaddr(address, port);
657 update_node_udp(from, &sa);