29fe509081812799ba70cf96bae0b107a3318d97
[tinc] / src / protocol_key.c
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 "protocol.h"
31 #include "route.h"
32 #include "sptps.h"
33 #include "utils.h"
34 #include "compression.h"
35
36 void send_key_changed(void) {
37 #ifndef DISABLE_LEGACY
38         send_request(everyone, "%d %x %s", KEY_CHANGED, rand(), myself->name);
39
40         /* Immediately send new keys to directly connected nodes to keep UDP mappings alive */
41
42         for list_each(connection_t, c, connection_list) {
43                 if(c->edge && c->node && c->node->status.reachable && !c->node->status.sptps) {
44                         send_ans_key(c->node);
45                 }
46         }
47
48 #endif
49
50         /* Force key exchange for connections using SPTPS */
51
52         if(experimental) {
53                 for splay_each(node_t, n, node_tree) {
54                         if(n->status.reachable && n->status.validkey && n->status.sptps) {
55                                 sptps_force_kex(&n->sptps);
56                         }
57                 }
58         }
59 }
60
61 bool key_changed_h(connection_t *c, const char *request) {
62         char name[MAX_STRING_SIZE];
63         node_t *n;
64
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);
68                 return false;
69         }
70
71         if(seen_request(request)) {
72                 return true;
73         }
74
75         n = lookup_node(name);
76
77         if(!n) {
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);
80                 return true;
81         }
82
83         if(!n->status.sptps) {
84                 n->status.validkey = false;
85                 n->last_req_key = 0;
86         }
87
88         /* Tell the others */
89
90         if(!tunnelserver) {
91                 forward_request(c, request);
92         }
93
94         return true;
95 }
96
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);
99 }
100
101 static bool send_initial_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
102         (void)type;
103         node_t *to = handle;
104         to->sptps.send_data = send_sptps_data_myself;
105         char buf[len * 4 / 3 + 5];
106
107         b64encode(data, buf, len);
108
109         return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_KEY, buf);
110 }
111
112 bool send_req_key(node_t *to) {
113         if(to->status.sptps) {
114                 if(!node_read_ecdsa_public_key(to)) {
115                         logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", to->name, to->hostname);
116                         send_request(to->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, to->name, REQ_PUBKEY);
117                         return true;
118                 }
119
120                 char label[25 + strlen(myself->name) + strlen(to->name)];
121                 snprintf(label, sizeof(label), "tinc UDP key expansion %s %s", myself->name, to->name);
122                 sptps_stop(&to->sptps);
123                 to->status.validkey = false;
124                 to->status.waitingforkey = true;
125                 to->last_req_key = now.tv_sec;
126                 to->incompression = myself->incompression;
127                 return sptps_start(&to->sptps, to, true, true, myself->connection->ecdsa, to->ecdsa, label, sizeof(label), send_initial_sptps_data, receive_sptps_record);
128         }
129
130         return send_request(to->nexthop->connection, "%d %s %s", REQ_KEY, myself->name, to->name);
131 }
132
133 /* REQ_KEY is overloaded to allow arbitrary requests to be routed between two nodes. */
134
135 static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, node_t *to, int reqno) {
136         (void)c;
137
138         /* If this is a SPTPS packet, see if sending UDP info helps.
139            Note that we only do this if we're the destination or the static relay;
140            otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */
141         if((reqno == REQ_KEY || reqno == SPTPS_PACKET) && to->via == myself) {
142                 send_udp_info(myself, from);
143         }
144
145         if(reqno == SPTPS_PACKET) {
146                 /* This is a SPTPS data packet. */
147
148                 char buf[MAX_STRING_SIZE];
149                 size_t len;
150
151                 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) {
152                         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");
153                         return true;
154                 }
155
156                 if(to != myself) {
157                         /* We don't just forward the request, because we want to use UDP if it's available. */
158                         if(forwarding_mode == FMODE_INTERNAL) {
159                                 send_sptps_data(to, from, 0, buf, len);
160                                 try_tx(to, true);
161                         }
162                 } else {
163                         /* The packet is for us */
164                         if(!sptps_receive_data(&from->sptps, buf, len)) {
165                                 /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
166                                    so let's restart SPTPS in case that helps. But don't do that too often
167                                    to prevent storms. */
168                                 if(from->last_req_key < now.tv_sec - 10) {
169                                         logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
170                                         send_req_key(from);
171                                 }
172
173                                 return true;
174                         }
175
176                         send_mtu_info(myself, from, MTU);
177                 }
178
179                 return true;
180         }
181
182         /* Requests that are not SPTPS data packets are forwarded as-is. */
183
184         if(to != myself) {
185                 return send_request(to->nexthop->connection, "%s", request);
186         }
187
188         /* The request is for us */
189
190         switch(reqno) {
191         case REQ_PUBKEY: {
192                 if(!node_read_ecdsa_public_key(from)) {
193                         /* Request their key *before* we send our key back. Otherwise the first SPTPS packet from them will get dropped. */
194                         logger(DEBUG_PROTOCOL, LOG_DEBUG, "Preemptively requesting Ed25519 key for %s (%s)", from->name, from->hostname);
195                         send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY);
196                 }
197
198                 char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa);
199                 send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, from->name, ANS_PUBKEY, pubkey);
200                 free(pubkey);
201                 return true;
202         }
203
204         case ANS_PUBKEY: {
205                 if(node_read_ecdsa_public_key(from)) {
206                         logger(DEBUG_PROTOCOL, LOG_WARNING, "Got ANS_PUBKEY from %s (%s) even though we already have his pubkey", from->name, from->hostname);
207                         return true;
208                 }
209
210                 char pubkey[MAX_STRING_SIZE];
211
212                 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !(from->ecdsa = ecdsa_set_base64_public_key(pubkey))) {
213                         logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_PUBKEY", from->name, from->hostname, "invalid pubkey");
214                         return true;
215                 }
216
217                 logger(DEBUG_PROTOCOL, LOG_INFO, "Learned Ed25519 public key from %s (%s)", from->name, from->hostname);
218                 append_config_file(from->name, "Ed25519PublicKey", pubkey);
219                 return true;
220         }
221
222         case REQ_KEY: {
223                 if(!node_read_ecdsa_public_key(from)) {
224                         logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", from->name, from->hostname);
225                         send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY);
226                         return true;
227                 }
228
229                 if(from->sptps.label) {
230                         logger(DEBUG_ALWAYS, LOG_DEBUG, "Got REQ_KEY from %s while we already started a SPTPS session!", from->name);
231                 }
232
233                 char buf[MAX_STRING_SIZE];
234                 size_t len;
235
236                 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) {
237                         logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS_START", from->name, from->hostname, "invalid SPTPS data");
238                         return true;
239                 }
240
241                 char label[25 + strlen(from->name) + strlen(myself->name)];
242                 snprintf(label, sizeof(label), "tinc UDP key expansion %s %s", from->name, myself->name);
243                 sptps_stop(&from->sptps);
244                 from->status.validkey = false;
245                 from->status.waitingforkey = true;
246                 from->last_req_key = now.tv_sec;
247                 sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof(label), send_sptps_data_myself, receive_sptps_record);
248                 sptps_receive_data(&from->sptps, buf, len);
249                 send_mtu_info(myself, from, MTU);
250                 return true;
251         }
252
253         default:
254                 logger(DEBUG_ALWAYS, LOG_ERR, "Unknown extended REQ_KEY request from %s (%s): %s", from->name, from->hostname, request);
255                 return true;
256         }
257 }
258
259 bool req_key_h(connection_t *c, const char *request) {
260         char from_name[MAX_STRING_SIZE];
261         char to_name[MAX_STRING_SIZE];
262         node_t *from, *to;
263         int reqno = 0;
264
265         if(sscanf(request, "%*d " MAX_STRING " " MAX_STRING " %d", from_name, to_name, &reqno) < 2) {
266                 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "REQ_KEY", c->name,
267                        c->hostname);
268                 return false;
269         }
270
271         if(!check_id(from_name) || !check_id(to_name)) {
272                 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_KEY", c->name, c->hostname, "invalid name");
273                 return false;
274         }
275
276         from = lookup_node(from_name);
277
278         if(!from) {
279                 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
280                        "REQ_KEY", c->name, c->hostname, from_name);
281                 return true;
282         }
283
284         to = lookup_node(to_name);
285
286         if(!to) {
287                 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
288                        "REQ_KEY", c->name, c->hostname, to_name);
289                 return true;
290         }
291
292         /* Check if this key request is for us */
293
294         if(to == myself) {                      /* Yes */
295                 if(!from->status.reachable) {
296                         logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which is not reachable",
297                                "REQ_KEY", c->name, c->hostname, from_name);
298                         return true;
299                 }
300
301                 /* Is this an extended REQ_KEY message? */
302                 if(experimental && reqno) {
303                         return req_key_ext_h(c, request, from, to, reqno);
304                 }
305
306                 /* No, just send our key back */
307                 send_ans_key(from);
308         } else {
309                 if(tunnelserver) {
310                         return true;
311                 }
312
313                 if(!to->status.reachable) {
314                         logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
315                                "REQ_KEY", c->name, c->hostname, to_name);
316                         return true;
317                 }
318
319                 /* Is this an extended REQ_KEY message? */
320                 if(experimental && reqno) {
321                         return req_key_ext_h(c, request, from, to, reqno);
322                 }
323
324                 send_request(to->nexthop->connection, "%s", request);
325         }
326
327         return true;
328 }
329
330 bool send_ans_key(node_t *to) {
331         if(to->status.sptps) {
332                 abort();
333         }
334
335 #ifdef DISABLE_LEGACY
336         return false;
337 #else
338         size_t keylen = myself->incipher ? cipher_keylength(myself->incipher) : 1;
339         char key[keylen * 2 + 1];
340
341         randomize(key, keylen);
342
343         cipher_close(to->incipher);
344         digest_close(to->indigest);
345
346         if(myself->incipher) {
347                 to->incipher = cipher_open_by_nid(cipher_get_nid(myself->incipher));
348
349                 if(!to->incipher) {
350                         abort();
351                 }
352
353                 if(!cipher_set_key(to->incipher, key, false)) {
354                         abort();
355                 }
356         }
357
358         if(myself->indigest) {
359                 to->indigest = digest_open_by_nid(digest_get_nid(myself->indigest),
360                                                   digest_length(myself->indigest));
361
362                 if(!to->indigest) {
363                         abort();
364                 }
365
366                 if(!digest_set_key(to->indigest, key, keylen)) {
367                         abort();
368                 }
369         }
370
371         to->incompression = myself->incompression;
372
373         bin2hex(key, key, keylen);
374
375         // Reset sequence number and late packet window
376         to->received_seqno = 0;
377         to->received = 0;
378
379         if(replaywin) {
380                 memset(to->late, 0, replaywin);
381         }
382
383         to->status.validkey_in = true;
384
385         return send_request(to->nexthop->connection, "%d %s %s %s %d %d %zu %d", ANS_KEY,
386                             myself->name, to->name, key,
387                             cipher_get_nid(to->incipher),
388                             digest_get_nid(to->indigest),
389                             digest_length(to->indigest),
390                             to->incompression);
391 #endif
392 }
393
394 bool ans_key_h(connection_t *c, const char *request) {
395         char from_name[MAX_STRING_SIZE];
396         char to_name[MAX_STRING_SIZE];
397         char key[MAX_STRING_SIZE];
398         char address[MAX_STRING_SIZE] = "";
399         char port[MAX_STRING_SIZE] = "";
400         int cipher, digest;
401         size_t maclength;
402         int compression;
403         node_t *from, *to;
404
405         if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %zu %d "MAX_STRING" "MAX_STRING,
406                         from_name, to_name, key, &cipher, &digest, &maclength,
407                         &compression, address, port) < 7) {
408                 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name,
409                        c->hostname);
410                 return false;
411         }
412
413         if(!check_id(from_name) || !check_id(to_name)) {
414                 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_KEY", c->name, c->hostname, "invalid name");
415                 return false;
416         }
417
418         from = lookup_node(from_name);
419
420         if(!from) {
421                 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
422                        "ANS_KEY", c->name, c->hostname, from_name);
423                 return true;
424         }
425
426         to = lookup_node(to_name);
427
428         if(!to) {
429                 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
430                        "ANS_KEY", c->name, c->hostname, to_name);
431                 return true;
432         }
433
434         /* Forward it if necessary */
435
436         if(to != myself) {
437                 if(tunnelserver) {
438                         return true;
439                 }
440
441                 if(!to->status.reachable) {
442                         logger(DEBUG_ALWAYS, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
443                                "ANS_KEY", c->name, c->hostname, to_name);
444                         return true;
445                 }
446
447                 if(!*address && from->address.sa.sa_family != AF_UNSPEC && to->minmtu) {
448                         char *address, *port;
449                         logger(DEBUG_PROTOCOL, LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name);
450                         sockaddr2str(&from->address, &address, &port);
451                         send_request(to->nexthop->connection, "%s %s %s", request, address, port);
452                         free(address);
453                         free(port);
454                         return true;
455                 }
456
457                 return send_request(to->nexthop->connection, "%s", request);
458         }
459
460 #ifndef DISABLE_LEGACY
461         /* Don't use key material until every check has passed. */
462         cipher_close(from->outcipher);
463         digest_close(from->outdigest);
464 #endif
465
466         if(!from->status.sptps) {
467                 from->status.validkey = false;
468         }
469
470         switch(compression) {
471         case COMPRESS_LZ4:
472 #ifdef HAVE_LZ4
473                 break;
474 #else
475                 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
476                 logger(DEBUG_ALWAYS, LOG_ERR, "LZ4 compression is unavailable on this node.");
477                 return true;
478 #endif
479
480         case COMPRESS_LZO_HI:
481         case COMPRESS_LZO_LO:
482 #ifdef HAVE_LZO
483                 break;
484 #else
485                 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
486                 logger(DEBUG_ALWAYS, LOG_ERR, "LZO compression is unavailable on this node.");
487                 return true;
488 #endif
489
490         case COMPRESS_ZLIB_9:
491         case COMPRESS_ZLIB_8:
492         case COMPRESS_ZLIB_7:
493         case COMPRESS_ZLIB_6:
494         case COMPRESS_ZLIB_5:
495         case COMPRESS_ZLIB_4:
496         case COMPRESS_ZLIB_3:
497         case COMPRESS_ZLIB_2:
498         case COMPRESS_ZLIB_1:
499 #ifdef HAVE_ZLIB
500                 break;
501 #else
502                 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
503                 logger(DEBUG_ALWAYS, LOG_ERR, "ZLIB compression is unavailable on this node.");
504                 return true;
505 #endif
506
507         case COMPRESS_NONE:
508                 break;
509
510         default:
511                 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
512                 logger(DEBUG_ALWAYS, LOG_ERR, "Compression level %i is unrecognized by this node.", compression);
513                 return true;
514         }
515
516         from->outcompression = compression;
517
518         /* SPTPS or old-style key exchange? */
519
520         if(from->status.sptps) {
521                 uint8_t buf[strlen(key)];
522                 size_t len = b64decode(key, buf, strlen(key));
523
524                 if(!len || !sptps_receive_data(&from->sptps, buf, len)) {
525                         /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
526                            so let's restart SPTPS in case that helps. But don't do that too often
527                            to prevent storms.
528                            Note that simply relying on handshake timeout is not enough, because
529                            that doesn't apply to key regeneration. */
530                         if(from->last_req_key < now.tv_sec - 10) {
531                                 logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode handshake TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
532                                 send_req_key(from);
533                         }
534
535                         return true;
536                 }
537
538                 if(from->status.validkey) {
539                         if(*address && *port) {
540                                 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
541                                 sockaddr_t sa = str2sockaddr(address, port);
542                                 update_node_udp(from, &sa);
543                         }
544                 }
545
546                 send_mtu_info(myself, from, MTU);
547
548                 return true;
549         }
550
551 #ifdef DISABLE_LEGACY
552         logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses legacy protocol!", from->name, from->hostname);
553         return false;
554 #else
555         /* Check and lookup cipher and digest algorithms */
556
557         if(cipher) {
558                 if(!(from->outcipher = cipher_open_by_nid(cipher))) {
559                         logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname);
560                         return false;
561                 }
562         } else {
563                 from->outcipher = NULL;
564         }
565
566         if(digest) {
567                 if(!(from->outdigest = digest_open_by_nid(digest, maclength))) {
568                         logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname);
569                         return false;
570                 }
571         } else {
572                 from->outdigest = NULL;
573         }
574
575         if(maclength != digest_length(from->outdigest)) {
576                 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname);
577                 return false;
578         }
579
580         /* Process key */
581
582         size_t keylen = hex2bin(key, key, sizeof(key));
583
584         if(keylen != (from->outcipher ? cipher_keylength(from->outcipher) : 1)) {
585                 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname);
586                 return true;
587         }
588
589         /* Update our copy of the origin's packet key */
590
591         if(from->outcipher && !cipher_set_key(from->outcipher, key, true)) {
592                 return false;
593         }
594
595         if(from->outdigest && !digest_set_key(from->outdigest, key, keylen)) {
596                 return false;
597         }
598
599         from->status.validkey = true;
600         from->sent_seqno = 0;
601
602         if(*address && *port) {
603                 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
604                 sockaddr_t sa = str2sockaddr(address, port);
605                 update_node_udp(from, &sa);
606         }
607
608         return true;
609 #endif
610 }