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 #ifndef DISABLE_LEGACY
36 static bool mykeyused = false;
39 void send_key_changed(void) {
40 #ifndef DISABLE_LEGACY
41 send_request(everyone, "%d %x %s", KEY_CHANGED, rand(), myself->name);
43 /* Immediately send new keys to directly connected nodes to keep UDP mappings alive */
45 for list_each(connection_t, c, connection_list) {
46 if(c->edge && c->node && c->node->status.reachable && !c->node->status.sptps) {
47 send_ans_key(c->node);
53 /* Force key exchange for connections using SPTPS */
56 for splay_each(node_t, n, node_tree) {
57 if(n->status.reachable && n->status.validkey && n->status.sptps) {
58 sptps_force_kex(&n->sptps);
64 bool key_changed_h(connection_t *c, const char *request) {
65 char name[MAX_STRING_SIZE];
68 if(sscanf(request, "%*d %*x " MAX_STRING, name) != 1) {
69 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "KEY_CHANGED",
70 c->name, c->hostname);
74 if(seen_request(request)) {
78 n = lookup_node(name);
81 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist",
82 "KEY_CHANGED", c->name, c->hostname, name);
86 if(!n->status.sptps) {
87 n->status.validkey = false;
94 forward_request(c, request);
100 static bool send_sptps_data_myself(void *handle, uint8_t type, const void *data, size_t len) {
101 return send_sptps_data(handle, myself, type, data, len);
104 static bool send_initial_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
107 to->sptps.send_data = send_sptps_data_myself;
108 char buf[len * 4 / 3 + 5];
110 b64encode(data, buf, len);
112 return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_KEY, buf);
115 bool send_req_key(node_t *to) {
116 if(to->status.sptps) {
117 if(!node_read_ecdsa_public_key(to)) {
118 logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", to->name, to->hostname);
119 send_request(to->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, to->name, REQ_PUBKEY);
123 char label[25 + strlen(myself->name) + strlen(to->name)];
124 snprintf(label, sizeof(label), "tinc UDP key expansion %s %s", myself->name, to->name);
125 sptps_stop(&to->sptps);
126 to->status.validkey = false;
127 to->status.waitingforkey = true;
128 to->last_req_key = now.tv_sec;
129 to->incompression = myself->incompression;
130 return sptps_start(&to->sptps, to, true, true, myself->connection->ecdsa, to->ecdsa, label, sizeof(label), send_initial_sptps_data, receive_sptps_record);
133 return send_request(to->nexthop->connection, "%d %s %s", REQ_KEY, myself->name, to->name);
136 /* REQ_KEY is overloaded to allow arbitrary requests to be routed between two nodes. */
138 static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, node_t *to, int reqno) {
141 /* If this is a SPTPS packet, see if sending UDP info helps.
142 Note that we only do this if we're the destination or the static relay;
143 otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */
144 if((reqno == REQ_KEY || reqno == SPTPS_PACKET) && to->via == myself) {
145 send_udp_info(myself, from);
148 if(reqno == SPTPS_PACKET) {
149 /* This is a SPTPS data packet. */
151 char buf[MAX_STRING_SIZE];
154 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) {
155 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");
160 /* We don't just forward the request, because we want to use UDP if it's available. */
161 if(forwarding_mode == FMODE_INTERNAL) {
162 send_sptps_data(to, from, 0, buf, len);
166 /* The packet is for us */
167 if(!sptps_receive_data(&from->sptps, buf, len)) {
168 /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
169 so let's restart SPTPS in case that helps. But don't do that too often
170 to prevent storms. */
171 if(from->last_req_key < now.tv_sec - 10) {
172 logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
179 send_mtu_info(myself, from, MTU);
185 /* Requests that are not SPTPS data packets are forwarded as-is. */
188 return send_request(to->nexthop->connection, "%s", request);
191 /* The request is for us */
195 if(!node_read_ecdsa_public_key(from)) {
196 /* Request their key *before* we send our key back. Otherwise the first SPTPS packet from them will get dropped. */
197 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Preemptively requesting Ed25519 key for %s (%s)", from->name, from->hostname);
198 send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY);
201 char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa);
202 send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, from->name, ANS_PUBKEY, pubkey);
208 if(node_read_ecdsa_public_key(from)) {
209 logger(DEBUG_PROTOCOL, LOG_WARNING, "Got ANS_PUBKEY from %s (%s) even though we already have his pubkey", from->name, from->hostname);
213 char pubkey[MAX_STRING_SIZE];
215 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !(from->ecdsa = ecdsa_set_base64_public_key(pubkey))) {
216 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_PUBKEY", from->name, from->hostname, "invalid pubkey");
220 logger(DEBUG_PROTOCOL, LOG_INFO, "Learned Ed25519 public key from %s (%s)", from->name, from->hostname);
221 append_config_file(from->name, "Ed25519PublicKey", pubkey);
226 if(!node_read_ecdsa_public_key(from)) {
227 logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", from->name, from->hostname);
228 send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY);
232 if(from->sptps.label) {
233 logger(DEBUG_ALWAYS, LOG_DEBUG, "Got REQ_KEY from %s while we already started a SPTPS session!", from->name);
236 char buf[MAX_STRING_SIZE];
239 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) {
240 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS_START", from->name, from->hostname, "invalid SPTPS data");
244 char label[25 + strlen(from->name) + strlen(myself->name)];
245 snprintf(label, sizeof(label), "tinc UDP key expansion %s %s", from->name, myself->name);
246 sptps_stop(&from->sptps);
247 from->status.validkey = false;
248 from->status.waitingforkey = true;
249 from->last_req_key = now.tv_sec;
250 sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof(label), send_sptps_data_myself, receive_sptps_record);
251 sptps_receive_data(&from->sptps, buf, len);
252 send_mtu_info(myself, from, MTU);
257 logger(DEBUG_ALWAYS, LOG_ERR, "Unknown extended REQ_KEY request from %s (%s): %s", from->name, from->hostname, request);
262 bool req_key_h(connection_t *c, const char *request) {
263 char from_name[MAX_STRING_SIZE];
264 char to_name[MAX_STRING_SIZE];
268 if(sscanf(request, "%*d " MAX_STRING " " MAX_STRING " %d", from_name, to_name, &reqno) < 2) {
269 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "REQ_KEY", c->name,
274 if(!check_id(from_name) || !check_id(to_name)) {
275 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_KEY", c->name, c->hostname, "invalid name");
279 from = lookup_node(from_name);
282 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
283 "REQ_KEY", c->name, c->hostname, from_name);
287 to = lookup_node(to_name);
290 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
291 "REQ_KEY", c->name, c->hostname, to_name);
295 /* Check if this key request is for us */
297 if(to == myself) { /* Yes */
298 if(!from->status.reachable) {
299 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which is not reachable",
300 "REQ_KEY", c->name, c->hostname, from_name);
304 /* Is this an extended REQ_KEY message? */
305 if(experimental && reqno) {
306 return req_key_ext_h(c, request, from, to, reqno);
309 /* No, just send our key back */
316 if(!to->status.reachable) {
317 logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
318 "REQ_KEY", c->name, c->hostname, to_name);
322 /* Is this an extended REQ_KEY message? */
323 if(experimental && reqno) {
324 return req_key_ext_h(c, request, from, to, reqno);
327 send_request(to->nexthop->connection, "%s", request);
333 bool send_ans_key(node_t *to) {
334 if(to->status.sptps) {
338 #ifdef DISABLE_LEGACY
341 size_t keylen = myself->incipher ? cipher_keylength(myself->incipher) : 1;
342 char key[keylen * 2 + 1];
344 randomize(key, keylen);
346 cipher_close(to->incipher);
347 digest_close(to->indigest);
349 if(myself->incipher) {
350 to->incipher = cipher_open_by_nid(cipher_get_nid(myself->incipher));
356 if(!cipher_set_key(to->incipher, key, false)) {
361 if(myself->indigest) {
362 to->indigest = digest_open_by_nid(digest_get_nid(myself->indigest), digest_length(myself->indigest));
368 if(!digest_set_key(to->indigest, key, keylen)) {
373 to->incompression = myself->incompression;
375 bin2hex(key, key, keylen);
377 // Reset sequence number and late packet window
379 to->received_seqno = 0;
383 memset(to->late, 0, replaywin);
386 to->status.validkey_in = true;
388 return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY,
389 myself->name, to->name, key,
390 cipher_get_nid(to->incipher),
391 digest_get_nid(to->indigest),
392 (int)digest_length(to->indigest),
397 bool ans_key_h(connection_t *c, const char *request) {
398 char from_name[MAX_STRING_SIZE];
399 char to_name[MAX_STRING_SIZE];
400 char key[MAX_STRING_SIZE];
401 char address[MAX_STRING_SIZE] = "";
402 char port[MAX_STRING_SIZE] = "";
403 int cipher, digest, maclength, compression;
406 if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %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_close(from->outcipher);
464 digest_close(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.");
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.");
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 char buf[strlen(key)];
523 size_t len = b64decode(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 if(!(from->outcipher = cipher_open_by_nid(cipher))) {
560 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname);
564 from->outcipher = NULL;
568 if(!(from->outdigest = digest_open_by_nid(digest, maclength))) {
569 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname);
573 from->outdigest = NULL;
576 if((size_t)maclength != digest_length(from->outdigest)) {
577 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname);
583 size_t keylen = hex2bin(key, key, sizeof(key));
585 if(keylen != (from->outcipher ? cipher_keylength(from->outcipher) : 1)) {
586 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname);
590 /* Update our copy of the origin's packet key */
592 if(from->outcipher && !cipher_set_key(from->outcipher, key, true)) {
596 if(from->outdigest && !digest_set_key(from->outdigest, key, keylen)) {
600 from->status.validkey = true;
601 from->sent_seqno = 0;
603 if(*address && *port) {
604 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
605 sockaddr_t sa = str2sockaddr(address, port);
606 update_node_udp(from, &sa);