Rename base64 funcs to show they're not RFC-compliant.
[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
106         char buf[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                 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_tinc(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_tinc(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_free(&to->incipher);
344         digest_free(&to->indigest);
345
346         if(myself->incipher) {
347                 to->incipher = cipher_alloc();
348
349                 if(!cipher_open_by_nid(to->incipher, cipher_get_nid(myself->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_alloc();
360
361                 if(!digest_open_by_nid(to->indigest,
362                                        digest_get_nid(myself->indigest),
363                                        digest_length(myself->indigest))) {
364                         abort();
365                 }
366
367                 if(!digest_set_key(to->indigest, key, keylen)) {
368                         abort();
369                 }
370         }
371
372         to->incompression = myself->incompression;
373
374         bin2hex(key, key, keylen);
375
376         // Reset sequence number and late packet window
377         to->received_seqno = 0;
378         to->received = 0;
379
380         if(replaywin) {
381                 memset(to->late, 0, replaywin);
382         }
383
384         to->status.validkey_in = true;
385
386         return send_request(to->nexthop->connection, "%d %s %s %s %d %d %zu %d", ANS_KEY,
387                             myself->name, to->name, key,
388                             cipher_get_nid(to->incipher),
389                             digest_get_nid(to->indigest),
390                             digest_length(to->indigest),
391                             to->incompression);
392 #endif
393 }
394
395 bool ans_key_h(connection_t *c, const char *request) {
396         char from_name[MAX_STRING_SIZE];
397         char to_name[MAX_STRING_SIZE];
398         char key[MAX_STRING_SIZE];
399         char address[MAX_STRING_SIZE] = "";
400         char port[MAX_STRING_SIZE] = "";
401         int cipher, digest;
402         size_t maclength;
403         int compression;
404         node_t *from, *to;
405
406         if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %zu %d "MAX_STRING" "MAX_STRING,
407                         from_name, to_name, key, &cipher, &digest, &maclength,
408                         &compression, address, port) < 7) {
409                 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name,
410                        c->hostname);
411                 return false;
412         }
413
414         if(!check_id(from_name) || !check_id(to_name)) {
415                 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_KEY", c->name, c->hostname, "invalid name");
416                 return false;
417         }
418
419         from = lookup_node(from_name);
420
421         if(!from) {
422                 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
423                        "ANS_KEY", c->name, c->hostname, from_name);
424                 return true;
425         }
426
427         to = lookup_node(to_name);
428
429         if(!to) {
430                 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
431                        "ANS_KEY", c->name, c->hostname, to_name);
432                 return true;
433         }
434
435         /* Forward it if necessary */
436
437         if(to != myself) {
438                 if(tunnelserver) {
439                         return true;
440                 }
441
442                 if(!to->status.reachable) {
443                         logger(DEBUG_ALWAYS, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
444                                "ANS_KEY", c->name, c->hostname, to_name);
445                         return true;
446                 }
447
448                 if(!*address && from->address.sa.sa_family != AF_UNSPEC && to->minmtu) {
449                         char *address, *port;
450                         logger(DEBUG_PROTOCOL, LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name);
451                         sockaddr2str(&from->address, &address, &port);
452                         send_request(to->nexthop->connection, "%s %s %s", request, address, port);
453                         free(address);
454                         free(port);
455                         return true;
456                 }
457
458                 return send_request(to->nexthop->connection, "%s", request);
459         }
460
461 #ifndef DISABLE_LEGACY
462         /* Don't use key material until every check has passed. */
463         cipher_free(&from->outcipher);
464         digest_free(&from->outdigest);
465 #endif
466
467         if(!from->status.sptps) {
468                 from->status.validkey = false;
469         }
470
471         switch(compression) {
472         case COMPRESS_LZ4:
473 #ifdef HAVE_LZ4
474                 break;
475 #else
476                 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
477                 logger(DEBUG_ALWAYS, LOG_ERR, "LZ4 compression is unavailable on this node.");
478                 return true;
479 #endif
480
481         case COMPRESS_LZO_HI:
482         case COMPRESS_LZO_LO:
483 #ifdef HAVE_LZO
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, "LZO compression is unavailable on this node.");
488                 return true;
489 #endif
490
491         case COMPRESS_ZLIB_9:
492         case COMPRESS_ZLIB_8:
493         case COMPRESS_ZLIB_7:
494         case COMPRESS_ZLIB_6:
495         case COMPRESS_ZLIB_5:
496         case COMPRESS_ZLIB_4:
497         case COMPRESS_ZLIB_3:
498         case COMPRESS_ZLIB_2:
499         case COMPRESS_ZLIB_1:
500 #ifdef HAVE_ZLIB
501                 break;
502 #else
503                 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
504                 logger(DEBUG_ALWAYS, LOG_ERR, "ZLIB compression is unavailable on this node.");
505                 return true;
506 #endif
507
508         case COMPRESS_NONE:
509                 break;
510
511         default:
512                 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
513                 logger(DEBUG_ALWAYS, LOG_ERR, "Compression level %i is unrecognized by this node.", compression);
514                 return true;
515         }
516
517         from->outcompression = compression;
518
519         /* SPTPS or old-style key exchange? */
520
521         if(from->status.sptps) {
522                 uint8_t buf[strlen(key)];
523                 size_t len = b64decode_tinc(key, buf, strlen(key));
524
525                 if(!len || !sptps_receive_data(&from->sptps, buf, len)) {
526                         /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
527                            so let's restart SPTPS in case that helps. But don't do that too often
528                            to prevent storms.
529                            Note that simply relying on handshake timeout is not enough, because
530                            that doesn't apply to key regeneration. */
531                         if(from->last_req_key < now.tv_sec - 10) {
532                                 logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode handshake TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
533                                 send_req_key(from);
534                         }
535
536                         return true;
537                 }
538
539                 if(from->status.validkey) {
540                         if(*address && *port) {
541                                 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
542                                 sockaddr_t sa = str2sockaddr(address, port);
543                                 update_node_udp(from, &sa);
544                         }
545                 }
546
547                 send_mtu_info(myself, from, MTU);
548
549                 return true;
550         }
551
552 #ifdef DISABLE_LEGACY
553         logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses legacy protocol!", from->name, from->hostname);
554         return false;
555 #else
556         /* Check and lookup cipher and digest algorithms */
557
558         if(cipher) {
559                 from->outcipher = cipher_alloc();
560
561                 if(!cipher_open_by_nid(from->outcipher, cipher)) {
562                         cipher_free(&from->outcipher);
563                         logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname);
564                         return false;
565                 }
566         } else {
567                 from->outcipher = NULL;
568         }
569
570         if(digest) {
571                 from->outdigest = digest_alloc();
572
573                 if(!digest_open_by_nid(from->outdigest, digest, maclength)) {
574                         digest_free(&from->outdigest);
575                         logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname);
576                         return false;
577                 }
578         } else {
579                 from->outdigest = NULL;
580         }
581
582         if(maclength != digest_length(from->outdigest)) {
583                 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname);
584                 return false;
585         }
586
587         /* Process key */
588
589         size_t keylen = hex2bin(key, key, sizeof(key));
590
591         if(keylen != (from->outcipher ? cipher_keylength(from->outcipher) : 1)) {
592                 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname);
593                 return true;
594         }
595
596         /* Update our copy of the origin's packet key */
597
598         if(from->outcipher && !cipher_set_key(from->outcipher, key, true)) {
599                 return false;
600         }
601
602         if(from->outdigest && !digest_set_key(from->outdigest, key, keylen)) {
603                 return false;
604         }
605
606         from->status.validkey = true;
607         from->sent_seqno = 0;
608
609         if(*address && *port) {
610                 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
611                 sockaddr_t sa = str2sockaddr(address, port);
612                 update_node_udp(from, &sa);
613         }
614
615         return true;
616 #endif
617 }