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