1efeaa837eec3020765867be6d4e7f02cd7ca345
[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, prng(UINT32_MAX), 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
106         char *buf = alloca(B64_SIZE(len));
107         b64encode_tinc(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                 const size_t labellen = 25 + strlen(myself->name) + strlen(to->name);
121                 char *label = alloca(labellen);
122                 snprintf(label, labellen, "tinc UDP key expansion %s %s", myself->name, to->name);
123
124                 sptps_stop(&to->sptps);
125                 to->status.validkey = false;
126                 to->status.waitingforkey = true;
127                 to->last_req_key = now.tv_sec;
128                 to->incompression = myself->incompression;
129                 return sptps_start(&to->sptps, to, true, true, myself->connection->ecdsa, to->ecdsa, label, labellen, send_initial_sptps_data, receive_sptps_record);
130         }
131
132         return send_request(to->nexthop->connection, "%d %s %s", REQ_KEY, myself->name, to->name);
133 }
134
135 /* REQ_KEY is overloaded to allow arbitrary requests to be routed between two nodes. */
136
137 static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, node_t *to, int reqno) {
138         (void)c;
139
140         /* If this is a SPTPS packet, see if sending UDP info helps.
141            Note that we only do this if we're the destination or the static relay;
142            otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */
143         if((reqno == REQ_KEY || reqno == SPTPS_PACKET) && to->via == myself) {
144                 send_udp_info(myself, from);
145         }
146
147         if(reqno == SPTPS_PACKET) {
148                 /* This is a SPTPS data packet. */
149
150                 char buf[MAX_STRING_SIZE];
151                 size_t len;
152
153                 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode_tinc(buf, buf, strlen(buf)))) {
154                         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");
155                         return true;
156                 }
157
158                 if(to != myself) {
159                         /* We don't just forward the request, because we want to use UDP if it's available. */
160                         if(forwarding_mode == FMODE_INTERNAL) {
161                                 send_sptps_data(to, from, 0, buf, len);
162                                 try_tx(to, true);
163                         }
164                 } else {
165                         /* The packet is for us */
166                         if(!sptps_receive_data(&from->sptps, buf, len)) {
167                                 /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
168                                    so let's restart SPTPS in case that helps. But don't do that too often
169                                    to prevent storms. */
170                                 if(from->last_req_key < now.tv_sec - 10) {
171                                         logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
172                                         send_req_key(from);
173                                 }
174
175                                 return true;
176                         }
177
178                         send_mtu_info(myself, from, MTU);
179                 }
180
181                 return true;
182         }
183
184         /* Requests that are not SPTPS data packets are forwarded as-is. */
185
186         if(to != myself) {
187                 return send_request(to->nexthop->connection, "%s", request);
188         }
189
190         /* The request is for us */
191
192         switch(reqno) {
193         case REQ_PUBKEY: {
194                 if(!node_read_ecdsa_public_key(from)) {
195                         /* Request their key *before* we send our key back. Otherwise the first SPTPS packet from them will get dropped. */
196                         logger(DEBUG_PROTOCOL, LOG_DEBUG, "Preemptively requesting Ed25519 key for %s (%s)", from->name, from->hostname);
197                         send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY);
198                 }
199
200                 char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa);
201                 send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, from->name, ANS_PUBKEY, pubkey);
202                 free(pubkey);
203                 return true;
204         }
205
206         case ANS_PUBKEY: {
207                 if(node_read_ecdsa_public_key(from)) {
208                         logger(DEBUG_PROTOCOL, LOG_WARNING, "Got ANS_PUBKEY from %s (%s) even though we already have his pubkey", from->name, from->hostname);
209                         return true;
210                 }
211
212                 char pubkey[MAX_STRING_SIZE];
213
214                 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !(from->ecdsa = ecdsa_set_base64_public_key(pubkey))) {
215                         logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_PUBKEY", from->name, from->hostname, "invalid pubkey");
216                         return true;
217                 }
218
219                 logger(DEBUG_PROTOCOL, LOG_INFO, "Learned Ed25519 public key from %s (%s)", from->name, from->hostname);
220                 append_config_file(from->name, "Ed25519PublicKey", pubkey);
221                 return true;
222         }
223
224         case REQ_KEY: {
225                 if(!node_read_ecdsa_public_key(from)) {
226                         logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", from->name, from->hostname);
227                         send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY);
228                         return true;
229                 }
230
231                 if(from->sptps.label) {
232                         logger(DEBUG_ALWAYS, LOG_DEBUG, "Got REQ_KEY from %s while we already started a SPTPS session!", from->name);
233                 }
234
235                 char buf[MAX_STRING_SIZE];
236                 size_t len;
237
238                 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode_tinc(buf, buf, strlen(buf)))) {
239                         logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS_START", from->name, from->hostname, "invalid SPTPS data");
240                         return true;
241                 }
242
243                 const size_t labellen = 25 + strlen(from->name) + strlen(myself->name);
244                 char *label = alloca(labellen);
245                 snprintf(label, labellen, "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, labellen, 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
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                 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);
301                         return true;
302                 }
303
304                 /* Is this an extended REQ_KEY message? */
305                 if(experimental && reqno) {
306                         return req_key_ext_h(c, request, from, to, reqno);
307                 }
308
309                 /* No, just send our key back */
310                 send_ans_key(from);
311         } else {
312                 if(tunnelserver) {
313                         return true;
314                 }
315
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);
319                         return true;
320                 }
321
322                 /* Is this an extended REQ_KEY message? */
323                 if(experimental && reqno) {
324                         return req_key_ext_h(c, request, from, to, reqno);
325                 }
326
327                 send_request(to->nexthop->connection, "%s", request);
328         }
329
330         return true;
331 }
332
333 bool send_ans_key(node_t *to) {
334         if(to->status.sptps) {
335                 abort();
336         }
337
338 #ifdef DISABLE_LEGACY
339         return false;
340 #else
341         size_t keylen = myself->incipher ? cipher_keylength(myself->incipher) : 1;
342         char *key = alloca(keylen * 2 + 1);
343
344         randomize(key, keylen);
345
346         cipher_free(&to->incipher);
347         digest_free(&to->indigest);
348
349         if(myself->incipher) {
350                 to->incipher = cipher_alloc();
351
352                 if(!cipher_open_by_nid(to->incipher, cipher_get_nid(myself->incipher))) {
353                         abort();
354                 }
355
356                 if(!cipher_set_key(to->incipher, key, false)) {
357                         abort();
358                 }
359         }
360
361         if(myself->indigest) {
362                 to->indigest = digest_alloc();
363
364                 if(!digest_open_by_nid(to->indigest,
365                                        digest_get_nid(myself->indigest),
366                                        digest_length(myself->indigest))) {
367                         abort();
368                 }
369
370                 if(!digest_set_key(to->indigest, key, keylen)) {
371                         abort();
372                 }
373         }
374
375         to->incompression = myself->incompression;
376
377         bin2hex(key, key, keylen);
378
379         // Reset sequence number and late packet window
380         to->received_seqno = 0;
381         to->received = 0;
382
383         if(replaywin) {
384                 memset(to->late, 0, replaywin);
385         }
386
387         to->status.validkey_in = true;
388
389         return send_request(to->nexthop->connection, "%d %s %s %s %d %d %lu %d", ANS_KEY,
390                             myself->name, to->name, key,
391                             cipher_get_nid(to->incipher),
392                             digest_get_nid(to->indigest),
393                             (unsigned long)digest_length(to->indigest),
394                             to->incompression);
395 #endif
396 }
397
398 bool ans_key_h(connection_t *c, const char *request) {
399         char from_name[MAX_STRING_SIZE];
400         char to_name[MAX_STRING_SIZE];
401         char key[MAX_STRING_SIZE];
402         char address[MAX_STRING_SIZE] = "";
403         char port[MAX_STRING_SIZE] = "";
404         int cipher, digest;
405         unsigned long maclength;
406         int compression;
407         node_t *from, *to;
408
409         if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %lu %d "MAX_STRING" "MAX_STRING,
410                         from_name, to_name, key, &cipher, &digest, &maclength,
411                         &compression, address, port) < 7) {
412                 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name,
413                        c->hostname);
414                 return false;
415         }
416
417         if(!check_id(from_name) || !check_id(to_name)) {
418                 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_KEY", c->name, c->hostname, "invalid name");
419                 return false;
420         }
421
422         from = lookup_node(from_name);
423
424         if(!from) {
425                 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
426                        "ANS_KEY", c->name, c->hostname, from_name);
427                 return true;
428         }
429
430         to = lookup_node(to_name);
431
432         if(!to) {
433                 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
434                        "ANS_KEY", c->name, c->hostname, to_name);
435                 return true;
436         }
437
438         /* Forward it if necessary */
439
440         if(to != myself) {
441                 if(tunnelserver) {
442                         return true;
443                 }
444
445                 if(!to->status.reachable) {
446                         logger(DEBUG_ALWAYS, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
447                                "ANS_KEY", c->name, c->hostname, to_name);
448                         return true;
449                 }
450
451                 if(!*address && from->address.sa.sa_family != AF_UNSPEC && to->minmtu) {
452                         char *address, *port;
453                         logger(DEBUG_PROTOCOL, LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name);
454                         sockaddr2str(&from->address, &address, &port);
455                         send_request(to->nexthop->connection, "%s %s %s", request, address, port);
456                         free(address);
457                         free(port);
458                         return true;
459                 }
460
461                 return send_request(to->nexthop->connection, "%s", request);
462         }
463
464 #ifndef DISABLE_LEGACY
465         /* Don't use key material until every check has passed. */
466         cipher_free(&from->outcipher);
467         digest_free(&from->outdigest);
468 #endif
469
470         if(!from->status.sptps) {
471                 from->status.validkey = false;
472         }
473
474         switch(compression) {
475         case COMPRESS_LZ4:
476 #ifdef HAVE_LZ4
477                 break;
478 #else
479                 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
480                 logger(DEBUG_ALWAYS, LOG_ERR, "LZ4 compression is unavailable on this node.");
481                 return true;
482 #endif
483
484         case COMPRESS_LZO_HI:
485         case COMPRESS_LZO_LO:
486 #ifdef HAVE_LZO
487                 break;
488 #else
489                 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
490                 logger(DEBUG_ALWAYS, LOG_ERR, "LZO compression is unavailable on this node.");
491                 return true;
492 #endif
493
494         case COMPRESS_ZLIB_9:
495         case COMPRESS_ZLIB_8:
496         case COMPRESS_ZLIB_7:
497         case COMPRESS_ZLIB_6:
498         case COMPRESS_ZLIB_5:
499         case COMPRESS_ZLIB_4:
500         case COMPRESS_ZLIB_3:
501         case COMPRESS_ZLIB_2:
502         case COMPRESS_ZLIB_1:
503 #ifdef HAVE_ZLIB
504                 break;
505 #else
506                 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
507                 logger(DEBUG_ALWAYS, LOG_ERR, "ZLIB compression is unavailable on this node.");
508                 return true;
509 #endif
510
511         case COMPRESS_NONE:
512                 break;
513
514         default:
515                 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
516                 logger(DEBUG_ALWAYS, LOG_ERR, "Compression level %i is unrecognized by this node.", compression);
517                 return true;
518         }
519
520         from->outcompression = compression;
521
522         /* SPTPS or old-style key exchange? */
523
524         if(from->status.sptps) {
525                 const size_t buflen = strlen(key);
526                 uint8_t *buf = alloca(buflen);
527                 size_t len = b64decode_tinc(key, buf, buflen);
528
529                 if(!len || !sptps_receive_data(&from->sptps, buf, len)) {
530                         /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
531                            so let's restart SPTPS in case that helps. But don't do that too often
532                            to prevent storms.
533                            Note that simply relying on handshake timeout is not enough, because
534                            that doesn't apply to key regeneration. */
535                         if(from->last_req_key < now.tv_sec - 10) {
536                                 logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode handshake TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
537                                 send_req_key(from);
538                         }
539
540                         return true;
541                 }
542
543                 if(from->status.validkey) {
544                         if(*address && *port) {
545                                 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
546                                 sockaddr_t sa = str2sockaddr(address, port);
547                                 update_node_udp(from, &sa);
548                         }
549                 }
550
551                 send_mtu_info(myself, from, MTU);
552
553                 return true;
554         }
555
556 #ifdef DISABLE_LEGACY
557         logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses legacy protocol!", from->name, from->hostname);
558         return false;
559 #else
560         /* Check and lookup cipher and digest algorithms */
561
562         if(cipher) {
563                 from->outcipher = cipher_alloc();
564
565                 if(!cipher_open_by_nid(from->outcipher, cipher)) {
566                         cipher_free(&from->outcipher);
567                         logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname);
568                         return false;
569                 }
570         } else {
571                 from->outcipher = NULL;
572         }
573
574         if(digest) {
575                 from->outdigest = digest_alloc();
576
577                 if(!digest_open_by_nid(from->outdigest, digest, maclength)) {
578                         digest_free(&from->outdigest);
579                         logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname);
580                         return false;
581                 }
582         } else {
583                 from->outdigest = NULL;
584         }
585
586         if(maclength != digest_length(from->outdigest)) {
587                 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname);
588                 return false;
589         }
590
591         /* Process key */
592
593         size_t keylen = hex2bin(key, key, sizeof(key));
594
595         if(keylen != (from->outcipher ? cipher_keylength(from->outcipher) : 1)) {
596                 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname);
597                 return true;
598         }
599
600         /* Update our copy of the origin's packet key */
601
602         if(from->outcipher && !cipher_set_key(from->outcipher, key, true)) {
603                 return false;
604         }
605
606         if(from->outdigest && !digest_set_key(from->outdigest, key, keylen)) {
607                 return false;
608         }
609
610         from->status.validkey = true;
611         from->sent_seqno = 0;
612
613         if(*address && *port) {
614                 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
615                 sockaddr_t sa = str2sockaddr(address, port);
616                 update_node_udp(from, &sa);
617         }
618
619         return true;
620 #endif
621 }