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