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"
35 void send_key_changed(void) {
36 #ifndef DISABLE_LEGACY
37 send_request(everyone, "%d %x %s", KEY_CHANGED, rand(), myself->name);
39 /* Immediately send new keys to directly connected nodes to keep UDP mappings alive */
41 for list_each(connection_t, c, connection_list) {
42 if(c->edge && c->node && c->node->status.reachable && !c->node->status.sptps) {
43 send_ans_key(c->node);
49 /* Force key exchange for connections using SPTPS */
52 for splay_each(node_t, n, node_tree) {
53 if(n->status.reachable && n->status.validkey && n->status.sptps) {
54 sptps_force_kex(&n->sptps);
60 bool key_changed_h(connection_t *c, const char *request) {
61 char name[MAX_STRING_SIZE];
64 if(sscanf(request, "%*d %*x " MAX_STRING, name) != 1) {
65 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "KEY_CHANGED",
66 c->name, c->hostname);
70 if(seen_request(request)) {
74 n = lookup_node(name);
77 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist",
78 "KEY_CHANGED", c->name, c->hostname, name);
82 if(!n->status.sptps) {
83 n->status.validkey = false;
90 forward_request(c, request);
96 static bool send_sptps_data_myself(void *handle, uint8_t type, const void *data, size_t len) {
97 return send_sptps_data(handle, myself, type, data, len);
100 static bool send_initial_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
103 to->sptps.send_data = send_sptps_data_myself;
104 char buf[len * 4 / 3 + 5];
106 b64encode(data, buf, len);
108 return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_KEY, buf);
111 bool send_req_key(node_t *to) {
112 if(to->status.sptps) {
113 if(!node_read_ecdsa_public_key(to)) {
114 logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", to->name, to->hostname);
115 send_request(to->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, to->name, REQ_PUBKEY);
119 char label[25 + strlen(myself->name) + strlen(to->name)];
120 snprintf(label, sizeof(label), "tinc UDP key expansion %s %s", myself->name, to->name);
121 sptps_stop(&to->sptps);
122 to->status.validkey = false;
123 to->status.waitingforkey = true;
124 to->last_req_key = now.tv_sec;
125 to->incompression = myself->incompression;
126 return sptps_start(&to->sptps, to, true, true, myself->connection->ecdsa, to->ecdsa, label, sizeof(label), send_initial_sptps_data, receive_sptps_record);
129 return send_request(to->nexthop->connection, "%d %s %s", REQ_KEY, myself->name, to->name);
132 /* REQ_KEY is overloaded to allow arbitrary requests to be routed between two nodes. */
134 static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, node_t *to, int reqno) {
137 /* If this is a SPTPS packet, see if sending UDP info helps.
138 Note that we only do this if we're the destination or the static relay;
139 otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */
140 if((reqno == REQ_KEY || reqno == SPTPS_PACKET) && to->via == myself) {
141 send_udp_info(myself, from);
144 if(reqno == SPTPS_PACKET) {
145 /* This is a SPTPS data packet. */
147 char buf[MAX_STRING_SIZE];
150 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) {
151 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");
156 /* We don't just forward the request, because we want to use UDP if it's available. */
157 if(forwarding_mode == FMODE_INTERNAL) {
158 send_sptps_data(to, from, 0, buf, len);
162 /* The packet is for us */
163 if(!sptps_receive_data(&from->sptps, buf, len)) {
164 /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
165 so let's restart SPTPS in case that helps. But don't do that too often
166 to prevent storms. */
167 if(from->last_req_key < now.tv_sec - 10) {
168 logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
175 send_mtu_info(myself, from, MTU);
181 /* Requests that are not SPTPS data packets are forwarded as-is. */
184 return send_request(to->nexthop->connection, "%s", request);
187 /* The request is for us */
191 if(!node_read_ecdsa_public_key(from)) {
192 /* Request their key *before* we send our key back. Otherwise the first SPTPS packet from them will get dropped. */
193 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Preemptively requesting Ed25519 key for %s (%s)", from->name, from->hostname);
194 send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY);
197 char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa);
198 send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, from->name, ANS_PUBKEY, pubkey);
204 if(node_read_ecdsa_public_key(from)) {
205 logger(DEBUG_PROTOCOL, LOG_WARNING, "Got ANS_PUBKEY from %s (%s) even though we already have his pubkey", from->name, from->hostname);
209 char pubkey[MAX_STRING_SIZE];
211 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !(from->ecdsa = ecdsa_set_base64_public_key(pubkey))) {
212 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_PUBKEY", from->name, from->hostname, "invalid pubkey");
216 logger(DEBUG_PROTOCOL, LOG_INFO, "Learned Ed25519 public key from %s (%s)", from->name, from->hostname);
217 append_config_file(from->name, "Ed25519PublicKey", pubkey);
222 if(!node_read_ecdsa_public_key(from)) {
223 logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", from->name, from->hostname);
224 send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY);
228 if(from->sptps.label) {
229 logger(DEBUG_ALWAYS, LOG_DEBUG, "Got REQ_KEY from %s while we already started a SPTPS session!", from->name);
232 char buf[MAX_STRING_SIZE];
235 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) {
236 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS_START", from->name, from->hostname, "invalid SPTPS data");
240 char label[25 + strlen(from->name) + strlen(myself->name)];
241 snprintf(label, sizeof(label), "tinc UDP key expansion %s %s", from->name, myself->name);
242 sptps_stop(&from->sptps);
243 from->status.validkey = false;
244 from->status.waitingforkey = true;
245 from->last_req_key = now.tv_sec;
246 sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof(label), send_sptps_data_myself, receive_sptps_record);
247 sptps_receive_data(&from->sptps, buf, len);
248 send_mtu_info(myself, from, MTU);
253 logger(DEBUG_ALWAYS, LOG_ERR, "Unknown extended REQ_KEY request from %s (%s): %s", from->name, from->hostname, request);
258 bool req_key_h(connection_t *c, const char *request) {
259 char from_name[MAX_STRING_SIZE];
260 char to_name[MAX_STRING_SIZE];
264 if(sscanf(request, "%*d " MAX_STRING " " MAX_STRING " %d", from_name, to_name, &reqno) < 2) {
265 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "REQ_KEY", c->name,
270 if(!check_id(from_name) || !check_id(to_name)) {
271 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_KEY", c->name, c->hostname, "invalid name");
275 from = lookup_node(from_name);
278 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
279 "REQ_KEY", c->name, c->hostname, from_name);
283 to = lookup_node(to_name);
286 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
287 "REQ_KEY", c->name, c->hostname, to_name);
291 /* Check if this key request is for us */
293 if(to == myself) { /* Yes */
294 if(!from->status.reachable) {
295 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which is not reachable",
296 "REQ_KEY", c->name, c->hostname, from_name);
300 /* Is this an extended REQ_KEY message? */
301 if(experimental && reqno) {
302 return req_key_ext_h(c, request, from, to, reqno);
305 /* No, just send our key back */
312 if(!to->status.reachable) {
313 logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
314 "REQ_KEY", c->name, c->hostname, to_name);
318 /* Is this an extended REQ_KEY message? */
319 if(experimental && reqno) {
320 return req_key_ext_h(c, request, from, to, reqno);
323 send_request(to->nexthop->connection, "%s", request);
329 bool send_ans_key(node_t *to) {
330 if(to->status.sptps) {
334 #ifdef DISABLE_LEGACY
337 size_t keylen = myself->incipher ? cipher_keylength(myself->incipher) : 1;
338 char key[keylen * 2 + 1];
340 randomize(key, keylen);
342 cipher_close(to->incipher);
343 digest_close(to->indigest);
345 if(myself->incipher) {
346 to->incipher = cipher_open_by_nid(cipher_get_nid(myself->incipher));
352 if(!cipher_set_key(to->incipher, key, false)) {
357 if(myself->indigest) {
358 to->indigest = digest_open_by_nid(digest_get_nid(myself->indigest), digest_length(myself->indigest));
364 if(!digest_set_key(to->indigest, key, keylen)) {
369 to->incompression = myself->incompression;
371 bin2hex(key, key, keylen);
373 // Reset sequence number and late packet window
374 to->received_seqno = 0;
378 memset(to->late, 0, replaywin);
381 to->status.validkey_in = true;
383 return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY,
384 myself->name, to->name, key,
385 cipher_get_nid(to->incipher),
386 digest_get_nid(to->indigest),
387 (int)digest_length(to->indigest),
392 bool ans_key_h(connection_t *c, const char *request) {
393 char from_name[MAX_STRING_SIZE];
394 char to_name[MAX_STRING_SIZE];
395 char key[MAX_STRING_SIZE];
396 char address[MAX_STRING_SIZE] = "";
397 char port[MAX_STRING_SIZE] = "";
398 int cipher, digest, maclength, compression;
401 if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d "MAX_STRING" "MAX_STRING,
402 from_name, to_name, key, &cipher, &digest, &maclength,
403 &compression, address, port) < 7) {
404 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name,
409 if(!check_id(from_name) || !check_id(to_name)) {
410 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_KEY", c->name, c->hostname, "invalid name");
414 from = lookup_node(from_name);
417 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
418 "ANS_KEY", c->name, c->hostname, from_name);
422 to = lookup_node(to_name);
425 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
426 "ANS_KEY", c->name, c->hostname, to_name);
430 /* Forward it if necessary */
437 if(!to->status.reachable) {
438 logger(DEBUG_ALWAYS, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
439 "ANS_KEY", c->name, c->hostname, to_name);
443 if(!*address && from->address.sa.sa_family != AF_UNSPEC && to->minmtu) {
444 char *address, *port;
445 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name);
446 sockaddr2str(&from->address, &address, &port);
447 send_request(to->nexthop->connection, "%s %s %s", request, address, port);
453 return send_request(to->nexthop->connection, "%s", request);
456 #ifndef DISABLE_LEGACY
457 /* Don't use key material until every check has passed. */
458 cipher_close(from->outcipher);
459 digest_close(from->outdigest);
462 if(!from->status.sptps) {
463 from->status.validkey = false;
466 switch(compression) {
471 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
472 logger(DEBUG_ALWAYS, LOG_ERR, "LZ4 compression is unavailable on this node.");
481 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
482 logger(DEBUG_ALWAYS, LOG_ERR, "LZO compression is unavailable on this node.");
498 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
499 logger(DEBUG_ALWAYS, LOG_ERR, "ZLIB compression is unavailable on this node.");
507 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
508 logger(DEBUG_ALWAYS, LOG_ERR, "Compression level %i is unrecognized by this node.", compression);
512 from->outcompression = compression;
514 /* SPTPS or old-style key exchange? */
516 if(from->status.sptps) {
517 char buf[strlen(key)];
518 size_t len = b64decode(key, buf, strlen(key));
520 if(!len || !sptps_receive_data(&from->sptps, buf, len)) {
521 /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
522 so let's restart SPTPS in case that helps. But don't do that too often
524 Note that simply relying on handshake timeout is not enough, because
525 that doesn't apply to key regeneration. */
526 if(from->last_req_key < now.tv_sec - 10) {
527 logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode handshake TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
534 if(from->status.validkey) {
535 if(*address && *port) {
536 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
537 sockaddr_t sa = str2sockaddr(address, port);
538 update_node_udp(from, &sa);
542 send_mtu_info(myself, from, MTU);
547 #ifdef DISABLE_LEGACY
548 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses legacy protocol!", from->name, from->hostname);
551 /* Check and lookup cipher and digest algorithms */
554 if(!(from->outcipher = cipher_open_by_nid(cipher))) {
555 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname);
559 from->outcipher = NULL;
563 if(!(from->outdigest = digest_open_by_nid(digest, maclength))) {
564 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname);
568 from->outdigest = NULL;
571 if((size_t)maclength != digest_length(from->outdigest)) {
572 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname);
578 size_t keylen = hex2bin(key, key, sizeof(key));
580 if(keylen != (from->outcipher ? cipher_keylength(from->outcipher) : 1)) {
581 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname);
585 /* Update our copy of the origin's packet key */
587 if(from->outcipher && !cipher_set_key(from->outcipher, key, true)) {
591 if(from->outdigest && !digest_set_key(from->outdigest, key, keylen)) {
595 from->status.validkey = true;
596 from->sent_seqno = 0;
598 if(*address && *port) {
599 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
600 sockaddr_t sa = str2sockaddr(address, port);
601 update_node_udp(from, &sa);