2 * OpenConnect (SSL + DTLS) VPN client
4 * Copyright © 2008-2012 Intel Corporation.
6 * Author: David Woodhouse <dwmw2@infradead.org>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * version 2.1, as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to:
20 * Free Software Foundation, Inc.
21 * 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301 USA
26 #include <sys/types.h>
27 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <openssl/err.h>
32 #include <openssl/ssl.h>
36 #include "openconnect-internal.h"
38 #ifdef HAVE_DTLS1_STOP_TIMER
39 /* OpenSSL doesn't deliberately export this, but we need it to
40 workaround a DTLS bug in versions < 1.0.0e */
41 extern void dtls1_stop_timer (SSL *);
44 static unsigned char nybble(unsigned char n)
46 if (n >= '0' && n <= '9') return n - '0';
47 else if (n >= 'A' && n <= 'F') return n - ('A' - 10);
48 else if (n >= 'a' && n <= 'f') return n - ('a' - 10);
52 unsigned char unhex(const char *data)
54 return (nybble(data[0]) << 4) | nybble(data[1]);
57 #if defined (OPENCONNECT_OPENSSL) && defined (SSL_OP_CISCO_ANYCONNECT)
60 * Useful for catching test cases, where we want everything to be
61 * reproducible. *NEVER* do this in the wild.
63 time_t time(time_t *t)
65 time_t x = 0x3ab2d948;
70 int RAND_pseudo_bytes(char *buf, int len)
72 memset(buf, 0x5a, len);
73 printf("FAKE PSEUDO RANDOM!\n");
77 int RAND_bytes(char *buf, int len)
79 static int foo = 0x5b;
80 printf("FAKE RANDOM!\n");
81 memset(buf, foo, len);
87 * The master-secret is generated randomly by the client. The server
88 * responds with a DTLS Session-ID. These, done over the HTTPS
89 * connection, are enough to 'resume' a DTLS session, bypassing all
90 * the normal setup of a normal DTLS connection.
92 * Cisco use a version of the protocol which predates RFC4347, but
93 * isn't quite the same as the pre-RFC version of the protocol which
94 * was in OpenSSL 0.9.8e -- it includes backports of some later
97 * The openssl/ directory of this source tree should contain both a
98 * small patch against OpenSSL 0.9.8e to make it support Cisco's
99 * snapshot of the protocol, and a larger patch against newer OpenSSL
100 * which gives us an option to use the old protocol again.
102 * Cisco's server also seems to respond to the official version of the
103 * protocol, with a change in the ChangeCipherSpec packet which implies
104 * that it does know the difference and isn't just repeating the version
105 * number seen in the ClientHello. But although I can make the handshake
106 * complete by hacking tls1_mac() to use the _old_ protocol version
107 * number when calculating the MAC, the server still seems to be ignoring
108 * my subsequent data packets. So we use the old protocol, which is what
109 * their clients use anyway.
112 static int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd)
114 STACK_OF(SSL_CIPHER) *ciphers;
115 method_const SSL_METHOD *dtls_method;
116 SSL_CIPHER *dtls_cipher;
120 if (!vpninfo->dtls_ctx) {
121 dtls_method = DTLSv1_client_method();
122 vpninfo->dtls_ctx = SSL_CTX_new(dtls_method);
123 if (!vpninfo->dtls_ctx) {
124 vpn_progress(vpninfo, PRG_ERR,
125 _("Initialise DTLSv1 CTX failed\n"));
126 vpninfo->dtls_attempt_period = 0;
130 /* If we don't readahead, then we do short reads and throw
131 away the tail of data packets. */
132 SSL_CTX_set_read_ahead(vpninfo->dtls_ctx, 1);
134 if (!SSL_CTX_set_cipher_list(vpninfo->dtls_ctx, vpninfo->dtls_cipher)) {
135 vpn_progress(vpninfo, PRG_ERR,
136 _("Set DTLS cipher list failed\n"));
137 SSL_CTX_free(vpninfo->dtls_ctx);
138 vpninfo->dtls_ctx = NULL;
139 vpninfo->dtls_attempt_period = 0;
144 if (!vpninfo->dtls_session) {
145 /* We're going to "resume" a session which never existed. Fake it... */
146 vpninfo->dtls_session = SSL_SESSION_new();
147 if (!vpninfo->dtls_session) {
148 vpn_progress(vpninfo, PRG_ERR,
149 _("Initialise DTLSv1 session failed\n"));
150 vpninfo->dtls_attempt_period = 0;
153 vpninfo->dtls_session->ssl_version = 0x0100; /* DTLS1_BAD_VER */
156 /* Do this every time; it may have changed due to a rekey */
157 vpninfo->dtls_session->master_key_length = sizeof(vpninfo->dtls_secret);
158 memcpy(vpninfo->dtls_session->master_key, vpninfo->dtls_secret,
159 sizeof(vpninfo->dtls_secret));
161 vpninfo->dtls_session->session_id_length = sizeof(vpninfo->dtls_session_id);
162 memcpy(vpninfo->dtls_session->session_id, vpninfo->dtls_session_id,
163 sizeof(vpninfo->dtls_session_id));
165 dtls_ssl = SSL_new(vpninfo->dtls_ctx);
166 SSL_set_connect_state(dtls_ssl);
168 ciphers = SSL_get_ciphers(dtls_ssl);
169 if (sk_SSL_CIPHER_num(ciphers) != 1) {
170 vpn_progress(vpninfo, PRG_ERR, _("Not precisely one DTLS cipher\n"));
171 SSL_CTX_free(vpninfo->dtls_ctx);
173 SSL_SESSION_free(vpninfo->dtls_session);
174 vpninfo->dtls_ctx = NULL;
175 vpninfo->dtls_session = NULL;
176 vpninfo->dtls_attempt_period = 0;
179 dtls_cipher = sk_SSL_CIPHER_value(ciphers, 0);
181 /* Set the appropriate cipher on our session to be resumed */
182 vpninfo->dtls_session->cipher = dtls_cipher;
183 vpninfo->dtls_session->cipher_id = dtls_cipher->id;
185 /* Add the generated session to the SSL */
186 if (!SSL_set_session(dtls_ssl, vpninfo->dtls_session)) {
187 vpn_progress(vpninfo, PRG_ERR,
188 _("SSL_set_session() failed with old protocol version 0x%x\n"
189 "Are you using a version of OpenSSL older than 0.9.8m?\n"
190 "See http://rt.openssl.org/Ticket/Display.html?id=1751\n"
191 "Use the --no-dtls command line option to avoid this message\n"),
192 vpninfo->dtls_session->ssl_version);
193 vpninfo->dtls_attempt_period = 0;
197 dtls_bio = BIO_new_socket(dtls_fd, BIO_NOCLOSE);
198 /* Set non-blocking */
199 BIO_set_nbio(dtls_bio, 1);
200 SSL_set_bio(dtls_ssl, dtls_bio, dtls_bio);
202 SSL_set_options(dtls_ssl, SSL_OP_CISCO_ANYCONNECT);
204 vpninfo->new_dtls_ssl = dtls_ssl;
209 int dtls_try_handshake(struct openconnect_info *vpninfo)
211 int ret = SSL_do_handshake(vpninfo->new_dtls_ssl);
214 vpn_progress(vpninfo, PRG_INFO, _("Established DTLS connection\n"));
216 if (vpninfo->dtls_ssl) {
217 /* We are replacing an old connection */
218 SSL_free(vpninfo->dtls_ssl);
219 close(vpninfo->dtls_fd);
220 FD_CLR(vpninfo->dtls_fd, &vpninfo->select_rfds);
221 FD_CLR(vpninfo->dtls_fd, &vpninfo->select_wfds);
222 FD_CLR(vpninfo->dtls_fd, &vpninfo->select_efds);
224 vpninfo->dtls_ssl = vpninfo->new_dtls_ssl;
225 vpninfo->dtls_fd = vpninfo->new_dtls_fd;
227 vpninfo->new_dtls_ssl = NULL;
228 vpninfo->new_dtls_fd = -1;
230 vpninfo->dtls_times.last_rx = vpninfo->dtls_times.last_tx = time(NULL);
232 /* From about 8.4.1(11) onwards, the ASA seems to get
233 very unhappy if we resend ChangeCipherSpec messages
234 after the initial setup. This was "fixed" in OpenSSL
235 1.0.0e for RT#2505, but it's not clear if that was
236 the right fix. What happens if the original packet
237 *does* get lost? Surely we *wanted* the retransmits,
238 because without them the server will never be able
239 to decrypt anything we send?
240 Oh well, our retransmitted packets upset the server
241 because we don't get the Cisco-compatibility right
242 (this is one of the areas in which Cisco's DTLS differs
243 from the RFC4347 spec), and DPD should help us notice
244 if *nothing* is getting through. */
245 #if OPENSSL_VERSION_NUMBER >= 0x1000005fL
246 /* OpenSSL 1.0.0e or above doesn't resend anyway; do nothing.
247 However, if we were *built* against 1.0.0e or newer, but at
248 runtime we find that we are being run against an older
249 version, warn about it. */
250 if (SSLeay() < 0x1000005fL) {
251 vpn_progress(vpninfo, PRG_ERR,
252 _("Your OpenSSL is older than the one you built against, so DTLS may fail!"));
254 #elif defined (HAVE_DTLS1_STOP_TIMER)
256 * This works for any normal OpenSSL that supports
257 * Cisco DTLS compatibility (0.9.8m to 1.0.0d inclusive,
258 * and even later versions although it isn't needed there.
260 dtls1_stop_timer(vpninfo->dtls_ssl);
261 #elif defined (BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT)
263 * Debian restricts visibility of dtls1_stop_timer()
264 * so do it manually. This version also works on all
265 * sane versions of OpenSSL:
267 memset (&(vpninfo->dtls_ssl->d1->next_timeout), 0,
268 sizeof((vpninfo->dtls_ssl->d1->next_timeout)));
269 vpninfo->dtls_ssl->d1->timeout_duration = 1;
270 BIO_ctrl(SSL_get_rbio(vpninfo->dtls_ssl),
271 BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
272 &(vpninfo->dtls_ssl->d1->next_timeout));
273 #elif defined (BIO_CTRL_DGRAM_SET_TIMEOUT)
275 * OK, here it gets more fun... this shoul handle the case
276 * of older OpenSSL which has the Cisco DTLS compatibility
277 * backported, but *not* the fix for RT#1922.
279 BIO_ctrl(SSL_get_rbio(vpninfo->dtls_ssl),
280 BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL);
283 * And if they don't have any of the above, they probably
284 * don't have RT#1829 fixed either, but that's OK because
285 * that's the "fix" that *introduces* the timeout we're
286 * trying to disable. So do nothing...
292 ret = SSL_get_error(vpninfo->new_dtls_ssl, ret);
293 if (ret == SSL_ERROR_WANT_WRITE || ret == SSL_ERROR_WANT_READ) {
294 if (time(NULL) < vpninfo->new_dtls_started + 5)
296 vpn_progress(vpninfo, PRG_TRACE, _("DTLS handshake timed out\n"));
299 vpn_progress(vpninfo, PRG_ERR, _("DTLS handshake failed: %d\n"), ret);
300 openconnect_report_ssl_errors(vpninfo);
302 /* Kill the new (failed) connection... */
303 SSL_free(vpninfo->new_dtls_ssl);
304 FD_CLR(vpninfo->new_dtls_fd, &vpninfo->select_rfds);
305 FD_CLR(vpninfo->new_dtls_fd, &vpninfo->select_efds);
306 close(vpninfo->new_dtls_fd);
307 vpninfo->new_dtls_ssl = NULL;
308 vpninfo->new_dtls_fd = -1;
310 /* ... and kill the old one too. The only time there'll be a valid
311 existing session is when it was a rekey, and in that case it's
312 time for the old one to die. */
313 if (vpninfo->dtls_ssl) {
314 SSL_free(vpninfo->dtls_ssl);
315 close(vpninfo->dtls_fd);
316 FD_CLR(vpninfo->dtls_fd, &vpninfo->select_rfds);
317 FD_CLR(vpninfo->dtls_fd, &vpninfo->select_wfds);
318 FD_CLR(vpninfo->dtls_fd, &vpninfo->select_efds);
319 vpninfo->dtls_ssl = NULL;
320 vpninfo->dtls_fd = -1;
323 time(&vpninfo->new_dtls_started);
327 int connect_dtls_socket(struct openconnect_info *vpninfo)
331 if (!vpninfo->dtls_addr) {
332 vpn_progress(vpninfo, PRG_ERR, _("No DTLS address\n"));
333 vpninfo->dtls_attempt_period = 0;
337 if (!vpninfo->dtls_cipher) {
338 /* We probably didn't offer it any ciphers it liked */
339 vpn_progress(vpninfo, PRG_ERR, _("Server offered no DTLS cipher option\n"));
340 vpninfo->dtls_attempt_period = 0;
344 if (vpninfo->proxy) {
345 /* XXX: Theoretically, SOCKS5 proxies can do UDP too */
346 vpn_progress(vpninfo, PRG_ERR, _("No DTLS when connected via proxy\n"));
347 vpninfo->dtls_attempt_period = 0;
351 dtls_fd = socket(vpninfo->peer_addr->sa_family, SOCK_DGRAM, IPPROTO_UDP);
353 perror(_("Open UDP socket for DTLS:"));
357 if (connect(dtls_fd, vpninfo->dtls_addr, vpninfo->peer_addrlen)) {
358 perror(_("UDP (DTLS) connect:\n"));
363 fcntl(dtls_fd, F_SETFD, FD_CLOEXEC);
364 fcntl(dtls_fd, F_SETFL, fcntl(dtls_fd, F_GETFL) | O_NONBLOCK);
366 ret = start_dtls_handshake(vpninfo, dtls_fd);
372 vpninfo->new_dtls_fd = dtls_fd;
373 if (vpninfo->select_nfds <= dtls_fd)
374 vpninfo->select_nfds = dtls_fd + 1;
376 FD_SET(dtls_fd, &vpninfo->select_rfds);
377 FD_SET(dtls_fd, &vpninfo->select_efds);
379 time(&vpninfo->new_dtls_started);
381 return dtls_try_handshake(vpninfo);
384 static int dtls_restart(struct openconnect_info *vpninfo)
386 if (vpninfo->dtls_ssl) {
387 SSL_free(vpninfo->dtls_ssl);
388 close(vpninfo->dtls_fd);
389 FD_CLR(vpninfo->dtls_fd, &vpninfo->select_rfds);
390 FD_CLR(vpninfo->dtls_fd, &vpninfo->select_wfds);
391 FD_CLR(vpninfo->dtls_fd, &vpninfo->select_efds);
392 vpninfo->dtls_ssl = NULL;
393 vpninfo->dtls_fd = -1;
396 return connect_dtls_socket(vpninfo);
400 int setup_dtls(struct openconnect_info *vpninfo)
402 struct vpn_option *dtls_opt = vpninfo->dtls_options;
406 vpn_progress(vpninfo, PRG_TRACE,
407 _("DTLS option %s : %s\n"),
408 dtls_opt->option, dtls_opt->value);
410 if (!strcmp(dtls_opt->option + 7, "Port")) {
411 dtls_port = atol(dtls_opt->value);
412 } else if (!strcmp(dtls_opt->option + 7, "Keepalive")) {
413 vpninfo->dtls_times.keepalive = atol(dtls_opt->value);
414 } else if (!strcmp(dtls_opt->option + 7, "DPD")) {
415 int j = atol(dtls_opt->value);
416 if (j && (!vpninfo->dtls_times.dpd || j < vpninfo->dtls_times.dpd))
417 vpninfo->dtls_times.dpd = j;
418 } else if (!strcmp(dtls_opt->option + 7, "Rekey-Time")) {
419 vpninfo->dtls_times.rekey = atol(dtls_opt->value);
420 } else if (!strcmp(dtls_opt->option + 7, "CipherSuite")) {
421 vpninfo->dtls_cipher = strdup(dtls_opt->value);
424 dtls_opt = dtls_opt->next;
427 vpninfo->dtls_attempt_period = 0;
431 vpninfo->dtls_addr = malloc(vpninfo->peer_addrlen);
432 if (!vpninfo->dtls_addr) {
433 vpninfo->dtls_attempt_period = 0;
436 memcpy(vpninfo->dtls_addr, vpninfo->peer_addr, vpninfo->peer_addrlen);
438 if (vpninfo->peer_addr->sa_family == AF_INET) {
439 struct sockaddr_in *sin = (void *)vpninfo->dtls_addr;
440 sin->sin_port = htons(dtls_port);
441 } else if (vpninfo->peer_addr->sa_family == AF_INET6) {
442 struct sockaddr_in6 *sin = (void *)vpninfo->dtls_addr;
443 sin->sin6_port = htons(dtls_port);
445 vpn_progress(vpninfo, PRG_ERR,
446 _("Unknown protocol family %d. Cannot do DTLS\n"),
447 vpninfo->peer_addr->sa_family);
448 vpninfo->dtls_attempt_period = 0;
452 if (connect_dtls_socket(vpninfo))
455 vpn_progress(vpninfo, PRG_TRACE,
456 _("DTLS connected. DPD %d, Keepalive %d\n"),
457 vpninfo->dtls_times.dpd, vpninfo->dtls_times.keepalive);
462 static struct pkt *dtls_pkt;
464 int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout)
470 int len = vpninfo->mtu;
474 dtls_pkt = malloc(sizeof(struct pkt) + len);
476 vpn_progress(vpninfo, PRG_ERR, "Allocation failed\n");
481 buf = dtls_pkt->data - 1;
482 len = SSL_read(vpninfo->dtls_ssl, buf, len + 1);
486 vpn_progress(vpninfo, PRG_TRACE,
487 _("Received DTLS packet 0x%02x of %d bytes\n"),
490 vpninfo->dtls_times.last_rx = time(NULL);
494 dtls_pkt->len = len - 1;
495 queue_packet(&vpninfo->incoming_queue, dtls_pkt);
501 vpn_progress(vpninfo, PRG_TRACE, _("Got DTLS DPD request\n"));
503 /* FIXME: What if the packet doesn't get through? */
504 magic_pkt = AC_PKT_DPD_RESP;
505 if (SSL_write(vpninfo->dtls_ssl, &magic_pkt, 1) != 1)
506 vpn_progress(vpninfo, PRG_ERR,
507 _("Failed to send DPD response. Expect disconnect\n"));
510 case AC_PKT_DPD_RESP:
511 vpn_progress(vpninfo, PRG_TRACE, _("Got DTLS DPD response\n"));
514 case AC_PKT_KEEPALIVE:
515 vpn_progress(vpninfo, PRG_TRACE, _("Got DTLS Keepalive\n"));
519 vpn_progress(vpninfo, PRG_ERR,
520 _("Unknown DTLS packet type %02x, len %d\n"),
523 /* Some versions of OpenSSL have bugs with receiving out-of-order
524 * packets. Not only do they wrongly decide to drop packets if
525 * two packets get swapped in transit, but they also _fail_ to
526 * drop the packet in non-blocking mode; instead they return
527 * the appropriate length of garbage. So don't abort... for now. */
530 vpninfo->quit_reason = "Unknown packet received";
537 switch (keepalive_action(&vpninfo->dtls_times, timeout)) {
539 vpn_progress(vpninfo, PRG_INFO, _("DTLS rekey due\n"));
541 /* There ought to be a method of rekeying DTLS without tearing down
542 the CSTP session and restarting, but we don't (yet) know it */
543 if (cstp_reconnect(vpninfo)) {
544 vpn_progress(vpninfo, PRG_ERR, _("Reconnect failed\n"));
545 vpninfo->quit_reason = "CSTP reconnect failed";
549 if (dtls_restart(vpninfo)) {
550 vpn_progress(vpninfo, PRG_ERR, _("DTLS rekey failed\n"));
558 vpn_progress(vpninfo, PRG_ERR, _("DTLS Dead Peer Detection detected dead peer!\n"));
559 /* Fall back to SSL, and start a new DTLS connection */
560 dtls_restart(vpninfo);
564 vpn_progress(vpninfo, PRG_TRACE, _("Send DTLS DPD\n"));
566 magic_pkt = AC_PKT_DPD_OUT;
567 SSL_write(vpninfo->dtls_ssl, &magic_pkt, 1);
568 /* last_dpd will just have been set */
569 vpninfo->dtls_times.last_tx = vpninfo->dtls_times.last_dpd;
574 /* No need to send an explicit keepalive
575 if we have real data to send */
576 if (vpninfo->outgoing_queue)
579 vpn_progress(vpninfo, PRG_TRACE, _("Send DTLS Keepalive\n"));
581 magic_pkt = AC_PKT_KEEPALIVE;
582 SSL_write(vpninfo->dtls_ssl, &magic_pkt, 1);
583 time(&vpninfo->dtls_times.last_tx);
591 /* Service outgoing packet queue */
592 while (vpninfo->outgoing_queue) {
593 struct pkt *this = vpninfo->outgoing_queue;
596 vpninfo->outgoing_queue = this->next;
597 vpninfo->outgoing_qlen--;
599 /* One byte of header */
600 this->hdr[7] = AC_PKT_DATA;
602 ret = SSL_write(vpninfo->dtls_ssl, &this->hdr[7], this->len + 1);
604 ret = SSL_get_error(vpninfo->dtls_ssl, ret);
606 /* If it's a real error, kill the DTLS connection and
607 requeue the packet to be sent over SSL */
608 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE) {
609 vpn_progress(vpninfo, PRG_ERR,
610 _("DTLS got write error %d. Falling back to SSL\n"),
612 openconnect_report_ssl_errors(vpninfo);
613 dtls_restart(vpninfo);
614 vpninfo->outgoing_queue = this;
615 vpninfo->outgoing_qlen++;
619 time(&vpninfo->dtls_times.last_tx);
620 vpn_progress(vpninfo, PRG_TRACE,
621 _("Sent DTLS packet of %d bytes; SSL_write() returned %d\n"),
628 #else /* No DTLS support in OpenSSL */
629 #warning Your version of OpenSSL does not seem to support Cisco DTLS compatibility
630 int setup_dtls(struct openconnect_info *vpninfo)
632 vpn_progress(vpninfo, PRG_ERR,
633 _("Built against OpenSSL with no Cisco DTLS support\n"));