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"
37 #ifndef DISABLE_LEGACY
38 static bool mykeyused = false;
41 void send_key_changed(void) {
42 #ifndef DISABLE_LEGACY
43 send_request(everyone, "%d %x %s", KEY_CHANGED, rand(), myself->name);
45 /* Immediately send new keys to directly connected nodes to keep UDP mappings alive */
47 for list_each(connection_t, c, connection_list) {
48 if(c->edge && c->node && c->node->status.reachable && !c->node->status.sptps) {
49 send_ans_key(c->node);
55 /* Force key exchange for connections using SPTPS */
58 for splay_each(node_t, n, node_tree) {
59 if(n->status.reachable && n->status.validkey && n->status.sptps) {
60 sptps_force_kex(&n->sptps);
66 bool key_changed_h(connection_t *c, const char *request) {
67 char name[MAX_STRING_SIZE];
70 if(sscanf(request, "%*d %*x " MAX_STRING, name) != 1) {
71 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "KEY_CHANGED",
72 c->name, c->hostname);
76 if(seen_request(request)) {
80 n = lookup_node(name);
83 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist",
84 "KEY_CHANGED", c->name, c->hostname, name);
88 if(!n->status.sptps) {
89 n->status.validkey = false;
96 forward_request(c, request);
102 static bool send_sptps_data_myself(void *handle, uint8_t type, const void *data, size_t len) {
103 return send_sptps_data(handle, myself, type, data, len);
106 static bool send_initial_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
109 to->sptps.send_data = send_sptps_data_myself;
110 char buf[len * 4 / 3 + 5];
112 b64encode(data, buf, len);
114 return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_KEY, buf);
117 bool send_req_key(node_t *to) {
118 if(to->status.sptps) {
119 if(!node_read_ecdsa_public_key(to)) {
120 logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", to->name, to->hostname);
121 send_request(to->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, to->name, REQ_PUBKEY);
125 char label[25 + strlen(myself->name) + strlen(to->name)];
126 snprintf(label, sizeof(label), "tinc UDP key expansion %s %s", myself->name, to->name);
127 sptps_stop(&to->sptps);
128 to->status.validkey = false;
129 to->status.waitingforkey = true;
130 to->last_req_key = now.tv_sec;
131 to->incompression = myself->incompression;
132 return sptps_start(&to->sptps, to, true, true, myself->connection->ecdsa, to->ecdsa, label, sizeof(label), send_initial_sptps_data, receive_sptps_record);
135 return send_request(to->nexthop->connection, "%d %s %s", REQ_KEY, myself->name, to->name);
138 /* REQ_KEY is overloaded to allow arbitrary requests to be routed between two nodes. */
140 static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, node_t *to, int reqno) {
143 /* If this is a SPTPS packet, see if sending UDP info helps.
144 Note that we only do this if we're the destination or the static relay;
145 otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */
146 if((reqno == REQ_KEY || reqno == SPTPS_PACKET) && to->via == myself) {
147 send_udp_info(myself, from);
150 if(reqno == SPTPS_PACKET) {
151 /* This is a SPTPS data packet. */
153 char buf[MAX_STRING_SIZE];
156 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) {
157 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");
162 /* We don't just forward the request, because we want to use UDP if it's available. */
163 if(forwarding_mode == FMODE_INTERNAL) {
164 send_sptps_data(to, from, 0, buf, len);
168 /* The packet is for us */
169 if(!sptps_receive_data(&from->sptps, buf, len)) {
170 /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
171 so let's restart SPTPS in case that helps. But don't do that too often
172 to prevent storms. */
173 if(from->last_req_key < now.tv_sec - 10) {
174 logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
181 send_mtu_info(myself, from, MTU);
187 /* Requests that are not SPTPS data packets are forwarded as-is. */
190 return send_request(to->nexthop->connection, "%s", request);
193 /* The request is for us */
197 if(!node_read_ecdsa_public_key(from)) {
198 /* Request their key *before* we send our key back. Otherwise the first SPTPS packet from them will get dropped. */
199 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Preemptively requesting Ed25519 key for %s (%s)", from->name, from->hostname);
200 send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY);
203 char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa);
204 send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, from->name, ANS_PUBKEY, pubkey);
210 if(node_read_ecdsa_public_key(from)) {
211 logger(DEBUG_PROTOCOL, LOG_WARNING, "Got ANS_PUBKEY from %s (%s) even though we already have his pubkey", from->name, from->hostname);
215 char pubkey[MAX_STRING_SIZE];
217 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !(from->ecdsa = ecdsa_set_base64_public_key(pubkey))) {
218 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_PUBKEY", from->name, from->hostname, "invalid pubkey");
222 logger(DEBUG_PROTOCOL, LOG_INFO, "Learned Ed25519 public key from %s (%s)", from->name, from->hostname);
223 append_config_file(from->name, "Ed25519PublicKey", pubkey);
228 if(!node_read_ecdsa_public_key(from)) {
229 logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", from->name, from->hostname);
230 send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY);
234 if(from->sptps.label) {
235 logger(DEBUG_ALWAYS, LOG_DEBUG, "Got REQ_KEY from %s while we already started a SPTPS session!", from->name);
238 char buf[MAX_STRING_SIZE];
241 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) {
242 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS_START", from->name, from->hostname, "invalid SPTPS data");
246 char label[25 + strlen(from->name) + strlen(myself->name)];
247 snprintf(label, sizeof(label), "tinc UDP key expansion %s %s", from->name, myself->name);
248 sptps_stop(&from->sptps);
249 from->status.validkey = false;
250 from->status.waitingforkey = true;
251 from->last_req_key = now.tv_sec;
252 sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof(label), send_sptps_data_myself, receive_sptps_record);
253 sptps_receive_data(&from->sptps, buf, len);
254 send_mtu_info(myself, from, MTU);
259 logger(DEBUG_ALWAYS, LOG_ERR, "Unknown extended REQ_KEY request from %s (%s): %s", from->name, from->hostname, request);
264 bool req_key_h(connection_t *c, const char *request) {
265 char from_name[MAX_STRING_SIZE];
266 char to_name[MAX_STRING_SIZE];
270 if(sscanf(request, "%*d " MAX_STRING " " MAX_STRING " %d", from_name, to_name, &reqno) < 2) {
271 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "REQ_KEY", c->name,
276 if(!check_id(from_name) || !check_id(to_name)) {
277 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_KEY", c->name, c->hostname, "invalid name");
281 from = lookup_node(from_name);
284 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
285 "REQ_KEY", c->name, c->hostname, from_name);
289 to = lookup_node(to_name);
292 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
293 "REQ_KEY", c->name, c->hostname, to_name);
297 /* Check if this key request is for us */
299 if(to == myself) { /* Yes */
300 if(!from->status.reachable) {
301 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which is not reachable",
302 "REQ_KEY", c->name, c->hostname, from_name);
306 /* Is this an extended REQ_KEY message? */
307 if(experimental && reqno) {
308 return req_key_ext_h(c, request, from, to, reqno);
311 /* No, just send our key back */
318 if(!to->status.reachable) {
319 logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
320 "REQ_KEY", c->name, c->hostname, to_name);
324 /* Is this an extended REQ_KEY message? */
325 if(experimental && reqno) {
326 return req_key_ext_h(c, request, from, to, reqno);
329 send_request(to->nexthop->connection, "%s", request);
335 bool send_ans_key(node_t *to) {
336 if(to->status.sptps) {
340 #ifdef DISABLE_LEGACY
343 size_t keylen = myself->incipher ? cipher_keylength(myself->incipher) : 1;
344 char key[keylen * 2 + 1];
346 randomize(key, keylen);
348 cipher_close(to->incipher);
349 digest_close(to->indigest);
351 if(myself->incipher) {
352 to->incipher = cipher_open_by_nid(cipher_get_nid(myself->incipher));
358 if(!cipher_set_key(to->incipher, key, false)) {
363 if(myself->indigest) {
364 to->indigest = digest_open_by_nid(digest_get_nid(myself->indigest), digest_length(myself->indigest));
370 if(!digest_set_key(to->indigest, key, keylen)) {
375 to->incompression = myself->incompression;
377 bin2hex(key, key, keylen);
379 // Reset sequence number and late packet window
381 to->received_seqno = 0;
385 memset(to->late, 0, replaywin);
388 to->status.validkey_in = true;
390 return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY,
391 myself->name, to->name, key,
392 cipher_get_nid(to->incipher),
393 digest_get_nid(to->indigest),
394 (int)digest_length(to->indigest),
399 bool ans_key_h(connection_t *c, const char *request) {
400 char from_name[MAX_STRING_SIZE];
401 char to_name[MAX_STRING_SIZE];
402 char key[MAX_STRING_SIZE];
403 char address[MAX_STRING_SIZE] = "";
404 char port[MAX_STRING_SIZE] = "";
405 int cipher, digest, maclength, compression;
408 if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d "MAX_STRING" "MAX_STRING,
409 from_name, to_name, key, &cipher, &digest, &maclength,
410 &compression, address, port) < 7) {
411 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name,
416 if(!check_id(from_name) || !check_id(to_name)) {
417 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_KEY", c->name, c->hostname, "invalid name");
421 from = lookup_node(from_name);
424 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
425 "ANS_KEY", c->name, c->hostname, from_name);
429 to = lookup_node(to_name);
432 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
433 "ANS_KEY", c->name, c->hostname, to_name);
437 /* Forward it if necessary */
444 if(!to->status.reachable) {
445 logger(DEBUG_ALWAYS, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
446 "ANS_KEY", c->name, c->hostname, to_name);
450 if(!*address && from->address.sa.sa_family != AF_UNSPEC && to->minmtu) {
451 char *address, *port;
452 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name);
453 sockaddr2str(&from->address, &address, &port);
454 send_request(to->nexthop->connection, "%s %s %s", request, address, port);
460 return send_request(to->nexthop->connection, "%s", request);
463 #ifndef DISABLE_LEGACY
464 /* Don't use key material until every check has passed. */
465 cipher_close(from->outcipher);
466 digest_close(from->outdigest);
469 if(!from->status.sptps) {
470 from->status.validkey = false;
473 switch(compression) {
478 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
479 logger(DEBUG_ALWAYS, LOG_ERR, "LZ4 compression is unavailable on this node.");
488 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
489 logger(DEBUG_ALWAYS, LOG_ERR, "LZO compression is unavailable on this node.");
505 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
506 logger(DEBUG_ALWAYS, LOG_ERR, "ZLIB compression is unavailable on this node.");
514 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
515 logger(DEBUG_ALWAYS, LOG_ERR, "Compression level %i is unrecognized by this node.", compression);
519 from->outcompression = compression;
521 /* SPTPS or old-style key exchange? */
523 if(from->status.sptps) {
524 char buf[strlen(key)];
525 size_t len = b64decode(key, buf, strlen(key));
527 if(!len || !sptps_receive_data(&from->sptps, buf, len)) {
528 /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
529 so let's restart SPTPS in case that helps. But don't do that too often
531 Note that simply relying on handshake timeout is not enough, because
532 that doesn't apply to key regeneration. */
533 if(from->last_req_key < now.tv_sec - 10) {
534 logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode handshake TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
541 if(from->status.validkey) {
542 if(*address && *port) {
543 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
544 sockaddr_t sa = str2sockaddr(address, port);
545 update_node_udp(from, &sa);
549 send_mtu_info(myself, from, MTU);
554 #ifdef DISABLE_LEGACY
555 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses legacy protocol!", from->name, from->hostname);
558 /* Check and lookup cipher and digest algorithms */
561 if(!(from->outcipher = cipher_open_by_nid(cipher))) {
562 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname);
566 from->outcipher = NULL;
570 if(!(from->outdigest = digest_open_by_nid(digest, maclength))) {
571 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname);
575 from->outdigest = NULL;
578 if((size_t)maclength != digest_length(from->outdigest)) {
579 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname);
585 size_t keylen = hex2bin(key, key, sizeof(key));
587 if(keylen != (from->outcipher ? cipher_keylength(from->outcipher) : 1)) {
588 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname);
592 /* Update our copy of the origin's packet key */
594 if(from->outcipher && !cipher_set_key(from->outcipher, key, true)) {
598 if(from->outdigest && !digest_set_key(from->outdigest, key, keylen)) {
602 from->status.validkey = true;
603 from->sent_seqno = 0;
605 if(*address && *port) {
606 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
607 sockaddr_t sa = str2sockaddr(address, port);
608 update_node_udp(from, &sa);