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