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