1 /*
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>
5 
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.
10 
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.
15 
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.
19 */
20 
21 #include "system.h"
22 
23 #include "cipher.h"
24 #include "connection.h"
25 #include "crypto.h"
26 #include "logger.h"
27 #include "net.h"
28 #include "netutl.h"
29 #include "node.h"
30 #include "prf.h"
31 #include "protocol.h"
32 #include "route.h"
33 #include "sptps.h"
34 #include "utils.h"
35 #include "xalloc.h"
36 
37 #ifndef DISABLE_LEGACY
38 static bool mykeyused = false;
39 #endif
40 
send_key_changed(void)41 void send_key_changed(void) {
42 #ifndef DISABLE_LEGACY
43 	send_request(everyone, "%d %x %s", KEY_CHANGED, rand(), myself->name);
44 
45 	/* Immediately send new keys to directly connected nodes to keep UDP mappings alive */
46 
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);
50 		}
51 
52 #endif
53 
54 	/* Force key exchange for connections using SPTPS */
55 
56 	if(experimental) {
57 		for splay_each(node_t, n, node_tree)
58 			if(n->status.reachable && n->status.validkey && n->status.sptps) {
59 				sptps_force_kex(&n->sptps);
60 			}
61 	}
62 }
63 
key_changed_h(connection_t * c,const char * request)64 bool key_changed_h(connection_t *c, const char *request) {
65 	char name[MAX_STRING_SIZE];
66 	node_t *n;
67 
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);
71 		return false;
72 	}
73 
74 	if(seen_request(request)) {
75 		return true;
76 	}
77 
78 	n = lookup_node(name);
79 
80 	if(!n) {
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);
83 		return true;
84 	}
85 
86 	if(!n->status.sptps) {
87 		n->status.validkey = false;
88 		n->last_req_key = 0;
89 	}
90 
91 	/* Tell the others */
92 
93 	if(!tunnelserver) {
94 		forward_request(c, request);
95 	}
96 
97 	return true;
98 }
99 
send_sptps_data_myself(void * handle,uint8_t type,const void * data,size_t len)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);
102 }
103 
send_initial_sptps_data(void * handle,uint8_t type,const void * data,size_t len)104 static bool send_initial_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
105 	(void)type;
106 	node_t *to = handle;
107 	to->sptps.send_data = send_sptps_data_myself;
108 	char buf[len * 4 / 3 + 5];
109 
110 	b64encode(data, buf, len);
111 
112 	return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_KEY, buf);
113 }
114 
send_req_key(node_t * to)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);
120 			return true;
121 		}
122 
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);
131 	}
132 
133 	return send_request(to->nexthop->connection, "%d %s %s", REQ_KEY, myself->name, to->name);
134 }
135 
136 /* REQ_KEY is overloaded to allow arbitrary requests to be routed between two nodes. */
137 
req_key_ext_h(connection_t * c,const char * request,node_t * from,node_t * to,int reqno)138 static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, node_t *to, int reqno) {
139 	(void)c;
140 
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);
146 	}
147 
148 	if(reqno == SPTPS_PACKET) {
149 		/* This is a SPTPS data packet. */
150 
151 		char buf[MAX_STRING_SIZE];
152 		int len;
153 
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");
156 			return true;
157 		}
158 
159 		if(to != myself) {
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);
163 				try_tx(to, true);
164 			}
165 		} else {
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);
173 					send_req_key(from);
174 				}
175 
176 				return true;
177 			}
178 
179 			send_mtu_info(myself, from, MTU);
180 		}
181 
182 		return true;
183 	}
184 
185 	/* Requests that are not SPTPS data packets are forwarded as-is. */
186 
187 	if(to != myself) {
188 		return send_request(to->nexthop->connection, "%s", request);
189 	}
190 
191 	/* The request is for us */
192 
193 	switch(reqno) {
194 	case REQ_PUBKEY: {
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);
199 		}
200 
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);
203 		free(pubkey);
204 		return true;
205 	}
206 
207 	case ANS_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);
210 			return true;
211 		}
212 
213 		char pubkey[MAX_STRING_SIZE];
214 
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");
217 			return true;
218 		}
219 
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);
222 		return true;
223 	}
224 
225 	case REQ_KEY: {
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);
229 			return true;
230 		}
231 
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);
234 		}
235 
236 		char buf[MAX_STRING_SIZE];
237 		size_t len;
238 
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");
241 			return true;
242 		}
243 
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);
253 		return true;
254 	}
255 
256 	default:
257 		logger(DEBUG_ALWAYS, LOG_ERR, "Unknown extended REQ_KEY request from %s (%s): %s", from->name, from->hostname, request);
258 		return true;
259 	}
260 }
261 
req_key_h(connection_t * c,const char * 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];
265 	node_t *from, *to;
266 	int reqno = 0;
267 
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,
270 		       c->hostname);
271 		return false;
272 	}
273 
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");
276 		return false;
277 	}
278 
279 	from = lookup_node(from_name);
280 
281 	if(!from) {
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);
284 		return true;
285 	}
286 
287 	to = lookup_node(to_name);
288 
289 	if(!to) {
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);
292 		return true;
293 	}
294 
295 	/* Check if this key request is for us */
296 
297 	if(to == myself) {                      /* Yes */
298 		/* Is this an extended REQ_KEY message? */
299 		if(experimental && reqno) {
300 			return req_key_ext_h(c, request, from, to, reqno);
301 		}
302 
303 		/* No, just send our key back */
304 		send_ans_key(from);
305 	} else {
306 		if(tunnelserver) {
307 			return true;
308 		}
309 
310 		if(!to->status.reachable) {
311 			logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
312 			       "REQ_KEY", c->name, c->hostname, to_name);
313 			return true;
314 		}
315 
316 		/* Is this an extended REQ_KEY message? */
317 		if(experimental && reqno) {
318 			return req_key_ext_h(c, request, from, to, reqno);
319 		}
320 
321 		send_request(to->nexthop->connection, "%s", request);
322 	}
323 
324 	return true;
325 }
326 
send_ans_key(node_t * to)327 bool send_ans_key(node_t *to) {
328 	if(to->status.sptps) {
329 		abort();
330 	}
331 
332 #ifdef DISABLE_LEGACY
333 	return false;
334 #else
335 	size_t keylen = myself->incipher ? cipher_keylength(myself->incipher) : 1;
336 	char key[keylen * 2 + 1];
337 
338 	randomize(key, keylen);
339 
340 	cipher_close(to->incipher);
341 	digest_close(to->indigest);
342 
343 	if(myself->incipher) {
344 		to->incipher = cipher_open_by_nid(cipher_get_nid(myself->incipher));
345 
346 		if(!to->incipher) {
347 			abort();
348 		}
349 
350 		if(!cipher_set_key(to->incipher, key, false)) {
351 			abort();
352 		}
353 	}
354 
355 	if(myself->indigest) {
356 		to->indigest = digest_open_by_nid(digest_get_nid(myself->indigest), digest_length(myself->indigest));
357 
358 		if(!to->indigest) {
359 			abort();
360 		}
361 
362 		if(!digest_set_key(to->indigest, key, keylen)) {
363 			abort();
364 		}
365 	}
366 
367 	to->incompression = myself->incompression;
368 
369 	bin2hex(key, key, keylen);
370 
371 	// Reset sequence number and late packet window
372 	mykeyused = true;
373 	to->received_seqno = 0;
374 	to->received = 0;
375 
376 	if(replaywin) {
377 		memset(to->late, 0, replaywin);
378 	}
379 
380 	to->status.validkey_in = true;
381 
382 	return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY,
383 	                    myself->name, to->name, key,
384 	                    cipher_get_nid(to->incipher),
385 	                    digest_get_nid(to->indigest),
386 	                    (int)digest_length(to->indigest),
387 	                    to->incompression);
388 #endif
389 }
390 
ans_key_h(connection_t * c,const char * request)391 bool ans_key_h(connection_t *c, const char *request) {
392 	char from_name[MAX_STRING_SIZE];
393 	char to_name[MAX_STRING_SIZE];
394 	char key[MAX_STRING_SIZE];
395 	char address[MAX_STRING_SIZE] = "";
396 	char port[MAX_STRING_SIZE] = "";
397 	int cipher, digest, maclength, compression;
398 	node_t *from, *to;
399 
400 	if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d "MAX_STRING" "MAX_STRING,
401 	                from_name, to_name, key, &cipher, &digest, &maclength,
402 	                &compression, address, port) < 7) {
403 		logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name,
404 		       c->hostname);
405 		return false;
406 	}
407 
408 	if(!check_id(from_name) || !check_id(to_name)) {
409 		logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_KEY", c->name, c->hostname, "invalid name");
410 		return false;
411 	}
412 
413 	from = lookup_node(from_name);
414 
415 	if(!from) {
416 		logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
417 		       "ANS_KEY", c->name, c->hostname, from_name);
418 		return true;
419 	}
420 
421 	to = lookup_node(to_name);
422 
423 	if(!to) {
424 		logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
425 		       "ANS_KEY", c->name, c->hostname, to_name);
426 		return true;
427 	}
428 
429 	/* Forward it if necessary */
430 
431 	if(to != myself) {
432 		if(tunnelserver) {
433 			return true;
434 		}
435 
436 		if(!to->status.reachable) {
437 			logger(DEBUG_ALWAYS, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
438 			       "ANS_KEY", c->name, c->hostname, to_name);
439 			return true;
440 		}
441 
442 		if(!*address && from->address.sa.sa_family != AF_UNSPEC && to->minmtu) {
443 			char *address, *port;
444 			logger(DEBUG_PROTOCOL, LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name);
445 			sockaddr2str(&from->address, &address, &port);
446 			send_request(to->nexthop->connection, "%s %s %s", request, address, port);
447 			free(address);
448 			free(port);
449 			return true;
450 		}
451 
452 		return send_request(to->nexthop->connection, "%s", request);
453 	}
454 
455 #ifndef DISABLE_LEGACY
456 	/* Don't use key material until every check has passed. */
457 	cipher_close(from->outcipher);
458 	digest_close(from->outdigest);
459 #endif
460 
461 	if(!from->status.sptps) {
462 		from->status.validkey = false;
463 	}
464 
465 	if(compression < 0 || compression > 11) {
466 		logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
467 		return true;
468 	}
469 
470 	from->outcompression = compression;
471 
472 	/* SPTPS or old-style key exchange? */
473 
474 	if(from->status.sptps) {
475 		char buf[strlen(key)];
476 		size_t len = b64decode(key, buf, strlen(key));
477 
478 		if(!len || !sptps_receive_data(&from->sptps, buf, len)) {
479 			/* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
480 			   so let's restart SPTPS in case that helps. But don't do that too often
481 			   to prevent storms.
482 			   Note that simply relying on handshake timeout is not enough, because
483 			   that doesn't apply to key regeneration. */
484 			if(from->last_req_key < now.tv_sec - 10) {
485 				logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode handshake TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
486 				send_req_key(from);
487 			}
488 
489 			return true;
490 		}
491 
492 		if(from->status.validkey) {
493 			if(*address && *port) {
494 				logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
495 				sockaddr_t sa = str2sockaddr(address, port);
496 				update_node_udp(from, &sa);
497 			}
498 		}
499 
500 		send_mtu_info(myself, from, MTU);
501 
502 		return true;
503 	}
504 
505 #ifdef DISABLE_LEGACY
506 	logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses legacy protocol!", from->name, from->hostname);
507 	return false;
508 #else
509 	/* Check and lookup cipher and digest algorithms */
510 
511 	if(cipher) {
512 		if(!(from->outcipher = cipher_open_by_nid(cipher))) {
513 			logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname);
514 			return false;
515 		}
516 	} else {
517 		from->outcipher = NULL;
518 	}
519 
520 	if(digest) {
521 		if(!(from->outdigest = digest_open_by_nid(digest, maclength))) {
522 			logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname);
523 			return false;
524 		}
525 	} else {
526 		from->outdigest = NULL;
527 	}
528 
529 	if((size_t)maclength != digest_length(from->outdigest)) {
530 		logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname);
531 		return false;
532 	}
533 
534 	/* Process key */
535 
536 	size_t keylen = hex2bin(key, key, sizeof(key));
537 
538 	if(keylen != (from->outcipher ? cipher_keylength(from->outcipher) : 1)) {
539 		logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname);
540 		return true;
541 	}
542 
543 	/* Update our copy of the origin's packet key */
544 
545 	if(from->outcipher && !cipher_set_key(from->outcipher, key, true)) {
546 		return false;
547 	}
548 
549 	if(from->outdigest && !digest_set_key(from->outdigest, key, keylen)) {
550 		return false;
551 	}
552 
553 	from->status.validkey = true;
554 	from->sent_seqno = 0;
555 
556 	if(*address && *port) {
557 		logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
558 		sockaddr_t sa = str2sockaddr(address, port);
559 		update_node_udp(from, &sa);
560 	}
561 
562 	return true;
563 #endif
564 }
565