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