/
esp.c
525 lines (458 loc) · 15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
* OpenConnect (SSL + DTLS) VPN client
*
* Copyright © 2008-2015 Intel Corporation.
*
* Author: David Woodhouse <dwmw2@infradead.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
#include <config.h>
20
21
22
23
24
25
#include "openconnect-internal.h"
#include "lzo.h"
#include <unistd.h>
26
27
28
29
30
31
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
32
33
34
35
36
37
38
int print_esp_keys(struct openconnect_info *vpninfo, const char *name, struct esp *esp)
{
int i;
const char *enctype, *mactype;
char enckey[256], mackey[256];
switch(vpninfo->esp_enc) {
39
case ENC_AES_128_CBC:
40
41
enctype = "AES-128-CBC (RFC3602)";
break;
42
case ENC_AES_256_CBC:
43
44
45
46
47
48
enctype = "AES-256-CBC (RFC3602)";
break;
default:
return -EINVAL;
}
switch(vpninfo->esp_hmac) {
49
case HMAC_MD5:
50
51
mactype = "HMAC-MD5-96 (RFC2403)";
break;
52
case HMAC_SHA1:
53
54
mactype = "HMAC-SHA-1-96 (RFC2404)";
break;
55
56
57
case HMAC_SHA256:
mactype = "HMAC-SHA-256-128 (RFC4868)";
break;
58
59
60
61
default:
return -EINVAL;
}
62
63
64
65
for (i = 0; i < vpninfo->enc_key_len; i++)
sprintf(enckey + (2 * i), "%02x", esp->enc_key[i]);
for (i = 0; i < vpninfo->hmac_key_len; i++)
sprintf(mackey + (2 * i), "%02x", esp->hmac_key[i]);
66
67
68
vpn_progress(vpninfo, PRG_TRACE,
_("Parameters for %s ESP: SPI 0x%08x\n"),
69
name, (unsigned)ntohl(esp->spi));
70
71
72
73
74
75
76
77
vpn_progress(vpninfo, PRG_TRACE,
_("ESP encryption type %s key 0x%s\n"),
enctype, enckey);
vpn_progress(vpninfo, PRG_TRACE,
_("ESP authentication type %s key 0x%s\n"),
mactype, mackey);
return 0;
}
78
79
int esp_setup(struct openconnect_info *vpninfo)
80
{
81
82
if (vpninfo->dtls_state == DTLS_DISABLED ||
vpninfo->dtls_state == DTLS_NOSECRET)
83
84
return -EINVAL;
85
86
87
88
89
90
91
/* XX: set ESP DPD interval if not already set */
if (!vpninfo->dtls_times.dpd) {
if (vpninfo->esp_ssl_fallback)
vpninfo->dtls_times.dpd = vpninfo->esp_ssl_fallback;
else
vpninfo->dtls_times.dpd = vpninfo->dtls_attempt_period;
}
92
93
print_esp_keys(vpninfo, _("incoming"), &vpninfo->esp_in[vpninfo->current_esp_in]);
94
95
print_esp_keys(vpninfo, _("outgoing"), &vpninfo->esp_out);
96
vpn_progress(vpninfo, PRG_DEBUG, _("Send ESP probes\n"));
97
98
if (vpninfo->proto->udp_send_probes)
vpninfo->proto->udp_send_probes(vpninfo);
99
100
return 0;
101
102
}
103
int construct_esp_packet(struct openconnect_info *vpninfo, struct pkt *pkt, uint8_t next_hdr)
104
105
106
107
{
const int blksize = 16;
int i, padlen, ret;
108
109
110
111
112
113
114
if (!next_hdr) {
if ((pkt->data[0] & 0xf0) == 0x60) /* iph->ip_v */
next_hdr = IPPROTO_IPV6;
else
next_hdr = IPPROTO_IPIP;
}
115
116
117
118
119
120
121
122
/* This gets much more fun if the IV is variable-length */
pkt->esp.spi = vpninfo->esp_out.spi;
pkt->esp.seq = htonl(vpninfo->esp_out.seq++);
padlen = blksize - 1 - ((pkt->len + 1) % blksize);
for (i=0; i<padlen; i++)
pkt->data[pkt->len + i] = i + 1;
pkt->data[pkt->len + padlen] = padlen;
123
pkt->data[pkt->len + padlen + 1] = next_hdr;
124
125
126
127
128
129
130
131
132
133
memcpy(pkt->esp.iv, vpninfo->esp_out.iv, sizeof(pkt->esp.iv));
ret = encrypt_esp_packet(vpninfo, pkt, pkt->len + padlen + 2);
if (ret)
return ret;
return sizeof(pkt->esp) + pkt->len + padlen + 2 + vpninfo->hmac_out_len;
}
134
int esp_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable)
135
{
136
137
struct esp *esp = &vpninfo->esp_in[vpninfo->current_esp_in];
struct esp *old_esp = &vpninfo->esp_in[vpninfo->current_esp_in ^ 1];
138
struct pkt *this;
139
140
141
int work_done = 0;
int ret;
142
143
144
145
146
/* Some servers send us packets that are larger than negotiated
MTU, or lack the ability to negotiate MTU (see gpst.c). We
reserve some extra space to handle that */
int receive_mtu = MAX(2048, vpninfo->ip_info.mtu + 256);
147
while (readable && vpninfo->dtls_fd != -1) {
148
int len = receive_mtu + vpninfo->pkt_trailer;
149
int i;
150
151
152
struct pkt *pkt;
if (!vpninfo->dtls_pkt) {
153
vpninfo->dtls_pkt = alloc_pkt(vpninfo, len);
154
155
156
157
158
159
if (!vpninfo->dtls_pkt) {
vpn_progress(vpninfo, PRG_ERR, _("Allocation failed\n"));
break;
}
}
pkt = vpninfo->dtls_pkt;
160
len = recv(vpninfo->dtls_fd, (void *)&pkt->esp, len + sizeof(pkt->esp), 0);
161
162
163
164
165
166
if (!len)
break;
if (len < 0) {
#ifdef _WIN32
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK)
167
168
break;
169
170
171
172
173
174
175
176
177
178
179
180
char *errstr = openconnect__win32_strerror(err);
vpn_progress(vpninfo, PRG_ERR,
_("ESP receive error: %s\n"),
errstr);
free(errstr);
#else
if (errno == EAGAIN || errno == EWOULDBLOCK)
break;
vpn_progress(vpninfo, PRG_ERR,
_("ESP receive error: %s\n"),
strerror(errno));
#endif
181
182
183
184
/* On *real* errors, close the UDP socket and try again later. */
vpninfo->proto->udp_close(vpninfo);
return 0;
}
185
186
187
work_done = 1;
188
/* both supported algos (SHA1 and MD5) have 12-byte MAC lengths (RFC2403 and RFC2404) */
189
if (len <= sizeof(pkt->esp) + vpninfo->hmac_out_len)
190
191
continue;
192
len -= sizeof(pkt->esp) + vpninfo->hmac_out_len;
193
194
pkt->len = len;
195
196
197
198
199
200
if (pkt->esp.spi == esp->spi) {
if (decrypt_esp_packet(vpninfo, esp, pkt))
continue;
} else if (pkt->esp.spi == old_esp->spi &&
ntohl(pkt->esp.seq) + esp->seq < vpninfo->old_esp_maxseq) {
vpn_progress(vpninfo, PRG_TRACE,
201
_("Received ESP packet from old SPI 0x%x, seq %u\n"),
202
(unsigned)ntohl(old_esp->spi), (unsigned)ntohl(pkt->esp.seq));
203
204
205
206
207
if (decrypt_esp_packet(vpninfo, old_esp, pkt))
continue;
} else {
vpn_progress(vpninfo, PRG_DEBUG,
_("Received ESP packet with invalid SPI 0x%08x\n"),
208
(unsigned)ntohl(pkt->esp.spi));
209
continue;
210
}
211
212
213
214
/* Possible values of the Next Header field are:
0x04: IP[v4]-in-IP
0x05: supposed to mean Internet Stream Protocol
215
(XXX: but used for LZO compressed IPv4 packets by Juniper)
216
0x29: IPv6 encapsulation */
217
218
219
220
221
222
223
224
225
226
if (pkt->data[len - 1] == 0x04)
vpn_progress(vpninfo, PRG_TRACE, _("Received ESP Legacy IP packet of %d bytes\n"),
len);
else if (pkt->data[len - 1] == 0x05)
vpn_progress(vpninfo, PRG_TRACE, _("Received ESP Legacy IP packet of %d bytes (LZO-compressed)\n"),
len);
else if (pkt->data[len - 1] == 0x29)
vpn_progress(vpninfo, PRG_TRACE, _("Received ESP IPv6 packet of %d bytes\n"),
len);
else {
227
vpn_progress(vpninfo, PRG_ERR,
228
229
_("Received ESP packet of %d bytes with unrecognised payload type %02x\n"),
len, pkt->data[len-1]);
230
231
232
233
234
235
236
237
238
239
continue;
}
if (len <= 2 + pkt->data[len - 2]) {
vpn_progress(vpninfo, PRG_ERR,
_("Invalid padding length %02x in ESP\n"),
pkt->data[len - 2]);
continue;
}
pkt->len = len - 2 - pkt->data[len - 2];
240
241
242
243
244
245
246
247
248
249
for (i = 0 ; i < pkt->data[len - 2]; i++) {
if (pkt->data[pkt->len + i] != i + 1)
break; /* We can't just 'continue' here because it
* would only break out of this 'for' loop */
}
if (i != pkt->data[len - 2]) {
vpn_progress(vpninfo, PRG_ERR,
_("Invalid padding bytes in ESP\n"));
continue; /* We can here, though */
}
250
vpninfo->dtls_times.last_rx = time(NULL);
251
252
253
254
255
256
if (vpninfo->proto->udp_catch_probe) {
if (vpninfo->proto->udp_catch_probe(vpninfo, pkt)) {
if (vpninfo->dtls_state == DTLS_SLEEPING) {
vpn_progress(vpninfo, PRG_INFO,
_("ESP session established with server\n"));
257
vpninfo->dtls_state = DTLS_CONNECTED;
258
259
}
continue;
260
}
261
}
262
if (pkt->data[len - 1] == 0x05) {
263
struct pkt *newpkt = alloc_pkt(vpninfo, receive_mtu + vpninfo->pkt_trailer);
264
int newlen = receive_mtu;
265
266
267
268
269
270
271
272
273
if (!newpkt) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to allocate memory to decrypt ESP packet\n"));
continue;
}
if (av_lzo1x_decode(newpkt->data, &newlen,
pkt->data, &pkt->len) || pkt->len) {
vpn_progress(vpninfo, PRG_ERR,
_("LZO decompression of ESP packet failed\n"));
274
free_pkt(vpninfo, newpkt);
275
276
continue;
}
277
newpkt->len = receive_mtu - newlen;
278
279
280
281
282
283
284
285
vpn_progress(vpninfo, PRG_TRACE,
_("LZO decompressed %d bytes into %d\n"),
len - 2 - pkt->data[len-2], newpkt->len);
queue_packet(&vpninfo->incoming_queue, newpkt);
} else {
queue_packet(&vpninfo->incoming_queue, pkt);
vpninfo->dtls_pkt = NULL;
}
286
287
}
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
if (vpninfo->dtls_need_reconnect) {
need_reconnect:
if (vpninfo->proto->udp_close)
vpninfo->proto->udp_close(vpninfo);
}
if (vpninfo->dtls_state == DTLS_SLEEPING) {
time_t now = time(NULL);
/* Send 5 probes a second apart, then give up until the next attempt */
if (vpninfo->udp_probes_sent <= 5 &&
ka_check_deadline(timeout, now, vpninfo->dtls_times.last_tx + 1)) {
/* Send repeat probe */
vpninfo->udp_probes_sent++;
} else if (vpninfo->dtls_need_reconnect ||
ka_check_deadline(timeout, now, vpninfo->new_dtls_started +
vpninfo->dtls_attempt_period)) {
/* New attempt */
vpninfo->dtls_need_reconnect = 0;
vpninfo->udp_probes_sent = 1;
vpninfo->new_dtls_started = now;
if (*timeout > 1000)
*timeout = 1000;
} else {
return work_done;
}
vpn_progress(vpninfo, PRG_DEBUG, _("Send ESP probes\n"));
if (vpninfo->proto->udp_send_probes)
vpninfo->proto->udp_send_probes(vpninfo);
vpninfo->dtls_times.last_tx = now;
}
322
if (vpninfo->dtls_state != DTLS_ESTABLISHED)
323
324
return 0;
325
326
327
328
329
330
331
switch (keepalive_action(&vpninfo->dtls_times, timeout)) {
case KA_REKEY:
vpn_progress(vpninfo, PRG_ERR, _("Rekey not implemented for ESP\n"));
break;
case KA_DPD_DEAD:
vpn_progress(vpninfo, PRG_ERR, _("ESP detected dead peer\n"));
332
goto need_reconnect;
333
334
335
case KA_DPD:
vpn_progress(vpninfo, PRG_DEBUG, _("Send ESP probes for DPD\n"));
336
337
if (vpninfo->proto->udp_send_probes) {
vpninfo->udp_probes_sent++;
338
vpninfo->proto->udp_send_probes(vpninfo);
339
}
340
341
342
343
344
345
346
347
348
349
work_done = 1;
break;
case KA_KEEPALIVE:
vpn_progress(vpninfo, PRG_ERR, _("Keepalive not implemented for ESP\n"));
break;
case KA_NONE:
break;
}
350
while (1) {
351
int len;
352
int ip_version;
353
354
355
356
if (vpninfo->deflate_pkt) {
this = vpninfo->deflate_pkt;
len = this->len;
357
ip_version = this->data[0] >> 4;
358
359
360
361
} else {
this = dequeue_packet(&vpninfo->outgoing_queue);
if (!this)
break;
362
ip_version = this->data[0] >> 4;
363
364
if (vpninfo->proto->proto == PROTO_PULSE && !vpninfo->pulse_esp_unstupid) {
365
366
uint8_t dontsend;
367
/* Pulse can only accept ESP of the same protocol as the one
368
369
370
* you connected to it with. The other has to go over IF-T/TLS.
* Newer Pulse servers can finally disable this protocol-layering
* malpractice with the pulse_esp_unstupid flag. */
371
if (vpninfo->dtls_addr->sa_family == AF_INET6)
372
dontsend = 4;
373
else
374
dontsend = 6;
375
376
if (ip_version == dontsend) {
377
378
379
store_be32(&this->pulse.vendor, 0xa4c);
store_be32(&this->pulse.type, 4);
store_be32(&this->pulse.len, this->len + 16);
380
queue_packet(&vpninfo->tcp_control_queue, this);
381
382
383
work_done = 1;
continue;
}
384
385
386
387
388
389
390
391
392
} else if (vpninfo->proto->proto == PROTO_NC &&
vpninfo->dtls_addr->sa_family == AF_INET6) {
/* Juniper/NC cannot do ESP-over-IPv6, and it cannot send
* tunneled IPv6 packets at all; they just get dropped.
* It shouldn't even send any ESP options/keys when connecting
* to the server via IPv6. This should never happen.
*/
vpninfo->quit_reason = "Juniper/NC ESP tunnel over IPv6 should never happen.";
return 1;
393
}
394
395
396
397
398
399
400
401
/* XX: Must precede in-place encryption of the packet, because
IP header fields (version and TOS) are garbled afterward.
If TOS optname is set, we want to copy the TOS/TCLASS header
to the outer UDP packet */
if (vpninfo->dtls_tos_optname)
udp_tos_update(vpninfo, this);
402
len = construct_esp_packet(vpninfo, this, 0);
403
if (len < 0) {
404
/* Should we disable ESP? */
405
free_pkt(vpninfo, this);
406
407
408
409
410
411
412
413
414
415
416
417
418
work_done = 1;
continue;
}
}
ret = send(vpninfo->dtls_fd, (void *)&this->esp, len, 0);
if (ret < 0) {
/* Not that this is likely to happen with UDP, but... */
if (errno == ENOBUFS || errno == EAGAIN || errno == EWOULDBLOCK) {
vpninfo->deflate_pkt = this;
this->len = len;
vpn_progress(vpninfo, PRG_DEBUG,
_("Requeueing failed ESP send: %s\n"),
419
strerror(errno));
420
421
422
423
424
425
426
monitor_write_fd(vpninfo, dtls);
return work_done;
} else {
/* A real error in sending. Fall back to TCP? */
vpn_progress(vpninfo, PRG_ERR,
_("Failed to send ESP packet: %s\n"),
strerror(errno));
427
}
428
} else {
429
430
vpninfo->dtls_times.last_tx = time(NULL);
431
432
vpn_progress(vpninfo, PRG_TRACE, _("Sent ESP IPv%d packet of %d bytes\n"),
ip_version, len);
433
434
435
436
}
if (this == vpninfo->deflate_pkt) {
unmonitor_write_fd(vpninfo, dtls);
vpninfo->deflate_pkt = NULL;
437
}
438
free_pkt(vpninfo, this);
439
440
441
442
work_done = 1;
}
return work_done;
443
444
445
446
}
void esp_close(struct openconnect_info *vpninfo)
{
447
448
449
/* We close and reopen the socket in case we roamed and our
local IP address has changed. */
if (vpninfo->dtls_fd != -1) {
450
unmonitor_fd(vpninfo, dtls);
451
closesocket(vpninfo->dtls_fd);
452
vpninfo->dtls_fd = -1;
453
}
454
455
if (vpninfo->dtls_state > DTLS_DISABLED)
vpninfo->dtls_state = DTLS_SLEEPING;
456
if (vpninfo->deflate_pkt) {
457
free_pkt(vpninfo, vpninfo->deflate_pkt);
458
459
vpninfo->deflate_pkt = NULL;
}
460
461
462
463
}
void esp_shutdown(struct openconnect_info *vpninfo)
{
464
465
466
destroy_esp_ciphers(&vpninfo->esp_in[0]);
destroy_esp_ciphers(&vpninfo->esp_in[1]);
destroy_esp_ciphers(&vpninfo->esp_out);
467
468
if (vpninfo->proto->udp_close)
vpninfo->proto->udp_close(vpninfo);
469
470
if (vpninfo->dtls_state != DTLS_DISABLED)
vpninfo->dtls_state = DTLS_NOSECRET;
471
}
472
473
474
475
476
477
478
479
480
481
482
int openconnect_setup_esp_keys(struct openconnect_info *vpninfo, int new_keys)
{
struct esp *esp_in;
int ret;
if (vpninfo->dtls_state == DTLS_DISABLED)
return -EOPNOTSUPP;
if (!vpninfo->dtls_addr)
return -EINVAL;
483
484
485
486
487
if (vpninfo->esp_hmac == HMAC_SHA256)
vpninfo->hmac_out_len = 16;
else /* MD5 and SHA1 */
vpninfo->hmac_out_len = 12;
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
if (new_keys) {
vpninfo->old_esp_maxseq = vpninfo->esp_in[vpninfo->current_esp_in].seq + 32;
vpninfo->current_esp_in ^= 1;
}
esp_in = &vpninfo->esp_in[vpninfo->current_esp_in];
if (new_keys) {
if (openconnect_random(&esp_in->spi, sizeof(esp_in->spi)) ||
openconnect_random((void *)&esp_in->enc_key, vpninfo->enc_key_len) ||
openconnect_random((void *)&esp_in->hmac_key, vpninfo->hmac_key_len)) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to generate random keys for ESP\n"));
return -EIO;
}
}
if (openconnect_random(vpninfo->esp_out.iv, sizeof(vpninfo->esp_out.iv))) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to generate initial IV for ESP\n"));
return -EIO;
}
/* This is the minimum; some implementations may increase it */
512
vpninfo->pkt_trailer = MAX_ESP_PAD + MAX_IV_SIZE + MAX_HMAC_SIZE;
513
514
515
516
517
518
519
520
521
522
523
524
525
vpninfo->esp_out.seq = vpninfo->esp_out.seq_backlog = 0;
esp_in->seq = esp_in->seq_backlog = 0;
ret = init_esp_ciphers(vpninfo, &vpninfo->esp_out, esp_in);
if (ret)
return ret;
if (vpninfo->dtls_state == DTLS_NOSECRET)
vpninfo->dtls_state = DTLS_SECRET;
return 0;
}