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"
36 static bool mykeyused = false;
38 void send_key_changed(void) {
39 #ifndef DISABLE_LEGACY
40 send_request(everyone, "%d %x %s", KEY_CHANGED, rand(), 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);
51 /* Force key exchange for connections using SPTPS */
54 for splay_each(node_t, n, node_tree)
55 if(n->status.reachable && n->status.validkey && n->status.sptps) {
56 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) {
103 to->sptps.send_data = send_sptps_data_myself;
104 char buf[len * 4 / 3 + 5];
105 b64encode(data, buf, len);
106 return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_KEY, buf);
109 bool send_req_key(node_t *to) {
110 if(to->status.sptps) {
111 if(!node_read_ecdsa_public_key(to)) {
112 logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", to->name, to->hostname);
113 send_request(to->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, to->name, REQ_PUBKEY);
117 char label[25 + strlen(myself->name) + strlen(to->name)];
118 snprintf(label, sizeof(label), "tinc UDP key expansion %s %s", myself->name, to->name);
119 sptps_stop(&to->sptps);
120 to->status.validkey = false;
121 to->status.waitingforkey = true;
122 to->last_req_key = now.tv_sec;
123 to->incompression = myself->incompression;
124 return sptps_start(&to->sptps, to, true, true, myself->connection->ecdsa, to->ecdsa, label, sizeof(label), send_initial_sptps_data, receive_sptps_record);
127 return send_request(to->nexthop->connection, "%d %s %s", REQ_KEY, myself->name, to->name);
130 /* REQ_KEY is overloaded to allow arbitrary requests to be routed between two nodes. */
132 static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, node_t *to, int reqno) {
133 /* If this is a SPTPS packet, see if sending UDP info helps.
134 Note that we only do this if we're the destination or the static relay;
135 otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */
136 if((reqno == REQ_KEY || reqno == SPTPS_PACKET) && to->via == myself) {
137 send_udp_info(myself, from);
140 if(reqno == SPTPS_PACKET) {
141 /* This is a SPTPS data packet. */
143 char buf[MAX_STRING_SIZE];
146 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) {
147 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");
152 /* We don't just forward the request, because we want to use UDP if it's available. */
153 send_sptps_data(to, from, 0, buf, len);
156 /* The packet is for us */
157 if(!sptps_receive_data(&from->sptps, buf, len)) {
158 /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
159 so let's restart SPTPS in case that helps. But don't do that too often
160 to prevent storms. */
161 if(from->last_req_key < now.tv_sec - 10) {
162 logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
169 send_mtu_info(myself, from, MTU);
175 /* Requests that are not SPTPS data packets are forwarded as-is. */
178 return send_request(to->nexthop->connection, "%s", request);
181 /* The request is for us */
185 if(!node_read_ecdsa_public_key(from)) {
186 /* Request their key *before* we send our key back. Otherwise the first SPTPS packet from them will get dropped. */
187 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Preemptively requesting Ed25519 key for %s (%s)", from->name, from->hostname);
188 send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY);
191 char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa);
192 send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, from->name, ANS_PUBKEY, pubkey);
198 if(node_read_ecdsa_public_key(from)) {
199 logger(DEBUG_PROTOCOL, LOG_WARNING, "Got ANS_PUBKEY from %s (%s) even though we already have his pubkey", from->name, from->hostname);
203 char pubkey[MAX_STRING_SIZE];
205 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !(from->ecdsa = ecdsa_set_base64_public_key(pubkey))) {
206 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_PUBKEY", from->name, from->hostname, "invalid pubkey");
210 logger(DEBUG_PROTOCOL, LOG_INFO, "Learned Ed25519 public key from %s (%s)", from->name, from->hostname);
211 append_config_file(from->name, "Ed25519PublicKey", pubkey);
216 if(!node_read_ecdsa_public_key(from)) {
217 logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", from->name, from->hostname);
218 send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY);
222 if(from->sptps.label) {
223 logger(DEBUG_ALWAYS, LOG_DEBUG, "Got REQ_KEY from %s while we already started a SPTPS session!", from->name);
226 char buf[MAX_STRING_SIZE];
229 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) {
230 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS_START", from->name, from->hostname, "invalid SPTPS data");
234 char label[25 + strlen(from->name) + strlen(myself->name)];
235 snprintf(label, sizeof(label), "tinc UDP key expansion %s %s", from->name, myself->name);
236 sptps_stop(&from->sptps);
237 from->status.validkey = false;
238 from->status.waitingforkey = true;
239 from->last_req_key = now.tv_sec;
240 sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof(label), send_sptps_data_myself, receive_sptps_record);
241 sptps_receive_data(&from->sptps, buf, len);
242 send_mtu_info(myself, from, MTU);
247 logger(DEBUG_ALWAYS, LOG_ERR, "Unknown extended REQ_KEY request from %s (%s): %s", from->name, from->hostname, request);
252 bool req_key_h(connection_t *c, const char *request) {
253 char from_name[MAX_STRING_SIZE];
254 char to_name[MAX_STRING_SIZE];
258 if(sscanf(request, "%*d " MAX_STRING " " MAX_STRING " %d", from_name, to_name, &reqno) < 2) {
259 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "REQ_KEY", c->name,
264 if(!check_id(from_name) || !check_id(to_name)) {
265 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_KEY", c->name, c->hostname, "invalid name");
269 from = lookup_node(from_name);
272 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
273 "REQ_KEY", c->name, c->hostname, from_name);
277 to = lookup_node(to_name);
280 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
281 "REQ_KEY", c->name, c->hostname, to_name);
285 /* Check if this key request is for us */
287 if(to == myself) { /* Yes */
288 /* Is this an extended REQ_KEY message? */
289 if(experimental && reqno) {
290 return req_key_ext_h(c, request, from, to, reqno);
293 /* No, just send our key back */
300 if(!to->status.reachable) {
301 logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
302 "REQ_KEY", c->name, c->hostname, to_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 send_request(to->nexthop->connection, "%s", request);
317 bool send_ans_key(node_t *to) {
318 if(to->status.sptps) {
322 #ifdef DISABLE_LEGACY
325 size_t keylen = myself->incipher ? cipher_keylength(myself->incipher) : 1;
326 char key[keylen * 2 + 1];
328 randomize(key, keylen);
330 cipher_close(to->incipher);
331 digest_close(to->indigest);
333 if(myself->incipher) {
334 to->incipher = cipher_open_by_nid(cipher_get_nid(myself->incipher));
340 if(!cipher_set_key(to->incipher, key, false)) {
345 if(myself->indigest) {
346 to->indigest = digest_open_by_nid(digest_get_nid(myself->indigest), digest_length(myself->indigest));
352 if(!digest_set_key(to->indigest, key, keylen)) {
357 to->incompression = myself->incompression;
359 bin2hex(key, key, keylen);
361 // Reset sequence number and late packet window
363 to->received_seqno = 0;
367 memset(to->late, 0, replaywin);
370 to->status.validkey_in = true;
372 return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY,
373 myself->name, to->name, key,
374 cipher_get_nid(to->incipher),
375 digest_get_nid(to->indigest),
376 (int)digest_length(to->indigest),
381 bool ans_key_h(connection_t *c, const char *request) {
382 char from_name[MAX_STRING_SIZE];
383 char to_name[MAX_STRING_SIZE];
384 char key[MAX_STRING_SIZE];
385 char address[MAX_STRING_SIZE] = "";
386 char port[MAX_STRING_SIZE] = "";
387 int cipher, digest, maclength, compression;
390 if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d "MAX_STRING" "MAX_STRING,
391 from_name, to_name, key, &cipher, &digest, &maclength,
392 &compression, address, port) < 7) {
393 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name,
398 if(!check_id(from_name) || !check_id(to_name)) {
399 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_KEY", c->name, c->hostname, "invalid name");
403 from = lookup_node(from_name);
406 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
407 "ANS_KEY", c->name, c->hostname, from_name);
411 to = lookup_node(to_name);
414 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
415 "ANS_KEY", c->name, c->hostname, to_name);
419 /* Forward it if necessary */
426 if(!to->status.reachable) {
427 logger(DEBUG_ALWAYS, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
428 "ANS_KEY", c->name, c->hostname, to_name);
432 if(!*address && from->address.sa.sa_family != AF_UNSPEC && to->minmtu) {
433 char *address, *port;
434 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name);
435 sockaddr2str(&from->address, &address, &port);
436 send_request(to->nexthop->connection, "%s %s %s", request, address, port);
442 return send_request(to->nexthop->connection, "%s", request);
445 #ifndef DISABLE_LEGACY
446 /* Don't use key material until every check has passed. */
447 cipher_close(from->outcipher);
448 digest_close(from->outdigest);
451 if(!from->status.sptps) {
452 from->status.validkey = false;
455 if(compression < 0 || compression > 11) {
456 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
460 from->outcompression = compression;
462 /* SPTPS or old-style key exchange? */
464 if(from->status.sptps) {
465 char buf[strlen(key)];
466 int len = b64decode(key, buf, strlen(key));
468 if(!len || !sptps_receive_data(&from->sptps, buf, len)) {
469 /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
470 so let's restart SPTPS in case that helps. But don't do that too often
472 Note that simply relying on handshake timeout is not enough, because
473 that doesn't apply to key regeneration. */
474 if(from->last_req_key < now.tv_sec - 10) {
475 logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode handshake TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
482 if(from->status.validkey) {
483 if(*address && *port) {
484 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
485 sockaddr_t sa = str2sockaddr(address, port);
486 update_node_udp(from, &sa);
490 send_mtu_info(myself, from, MTU);
495 #ifdef DISABLE_LEGACY
496 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses legacy protocol!", from->name, from->hostname);
499 /* Check and lookup cipher and digest algorithms */
502 if(!(from->outcipher = cipher_open_by_nid(cipher))) {
503 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname);
507 from->outcipher = NULL;
511 if(!(from->outdigest = digest_open_by_nid(digest, maclength))) {
512 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname);
516 from->outdigest = NULL;
519 if(maclength != digest_length(from->outdigest)) {
520 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname);
526 int keylen = hex2bin(key, key, sizeof(key));
528 if(keylen != (from->outcipher ? cipher_keylength(from->outcipher) : 1)) {
529 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname);
533 /* Update our copy of the origin's packet key */
535 if(from->outcipher && !cipher_set_key(from->outcipher, key, true)) {
539 if(from->outdigest && !digest_set_key(from->outdigest, key, keylen)) {
543 from->status.validkey = true;
544 from->sent_seqno = 0;
546 if(*address && *port) {
547 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
548 sockaddr_t sa = str2sockaddr(address, port);
549 update_node_udp(from, &sa);