gnutls-dtls.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. /*
  2. * OpenConnect (SSL + DTLS) VPN client
  3. *
  4. * Copyright © 2008-2016 Intel Corporation.
  5. *
  6. * Author: David Woodhouse <dwmw2@infradead.org>
  7. *
  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.
  11. *
  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.
  16. */
  17. #include <config.h>
  18. #include "gnutls.h"
  19. #include <gnutls/dtls.h>
  20. #include <unistd.h>
  21. #include <fcntl.h>
  22. #include <sys/types.h>
  23. #ifndef _WIN32
  24. #include <netinet/in.h>
  25. #include <sys/socket.h>
  26. #endif
  27. #include <errno.h>
  28. #include <string.h>
  29. #include <stdlib.h>
  30. #include <stdio.h>
  31. #if GNUTLS_VERSION_NUMBER < 0x030400
  32. # define GNUTLS_CIPHER_CHACHA20_POLY1305 23
  33. #endif
  34. /* sets the DTLS MTU and returns the actual tunnel MTU */
  35. unsigned dtls_set_mtu(struct openconnect_info *vpninfo, unsigned mtu)
  36. {
  37. gnutls_dtls_set_mtu(vpninfo->dtls_ssl, mtu);
  38. return gnutls_dtls_get_data_mtu(vpninfo->dtls_ssl);
  39. }
  40. struct {
  41. const char *name;
  42. gnutls_protocol_t version;
  43. gnutls_cipher_algorithm_t cipher;
  44. gnutls_kx_algorithm_t kx;
  45. gnutls_mac_algorithm_t mac;
  46. const char *prio;
  47. const char *min_gnutls_version;
  48. int cisco_dtls12;
  49. } gnutls_dtls_ciphers[] = {
  50. { "DHE-RSA-AES128-SHA", GNUTLS_DTLS0_9, GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_RSA, GNUTLS_MAC_SHA1,
  51. "NONE:+VERS-DTLS0.9:+COMP-NULL:+AES-128-CBC:+SHA1:+DHE-RSA:+SIGN-ALL:%COMPAT", "3.0.0" },
  52. { "DHE-RSA-AES256-SHA", GNUTLS_DTLS0_9, GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_RSA, GNUTLS_MAC_SHA1,
  53. "NONE:+VERS-DTLS0.9:+COMP-NULL:+AES-256-CBC:+SHA1:+DHE-RSA:+SIGN-ALL:%COMPAT", "3.0.0" },
  54. { "AES128-SHA", GNUTLS_DTLS0_9, GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_RSA, GNUTLS_MAC_SHA1,
  55. "NONE:+VERS-DTLS0.9:+COMP-NULL:+AES-128-CBC:+SHA1:+RSA:+SIGN-ALL:%COMPAT", "3.0.0" },
  56. { "AES256-SHA", GNUTLS_DTLS0_9, GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_RSA, GNUTLS_MAC_SHA1,
  57. "NONE:+VERS-DTLS0.9:+COMP-NULL:+AES-256-CBC:+SHA1:+RSA:+SIGN-ALL:%COMPAT", "3.0.0" },
  58. { "DES-CBC3-SHA", GNUTLS_DTLS0_9, GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_RSA, GNUTLS_MAC_SHA1,
  59. "NONE:+VERS-DTLS0.9:+COMP-NULL:+3DES-CBC:+SHA1:+RSA:+SIGN-ALL:%COMPAT", "3.0.0" },
  60. { "OC-DTLS1_2-AES128-GCM", GNUTLS_DTLS1_2, GNUTLS_CIPHER_AES_128_GCM, GNUTLS_KX_RSA, GNUTLS_MAC_AEAD,
  61. "NONE:+VERS-DTLS1.2:+COMP-NULL:+AES-128-GCM:+AEAD:+RSA:%COMPAT:+SIGN-ALL", "3.2.7" },
  62. { "OC-DTLS1_2-AES256-GCM", GNUTLS_DTLS1_2, GNUTLS_CIPHER_AES_256_GCM, GNUTLS_KX_RSA, GNUTLS_MAC_AEAD,
  63. "NONE:+VERS-DTLS1.2:+COMP-NULL:+AES-256-GCM:+AEAD:+RSA:%COMPAT:+SIGN-ALL", "3.2.7" },
  64. { "OC2-DTLS1_2-CHACHA20-POLY1305", GNUTLS_DTLS1_2, GNUTLS_CIPHER_CHACHA20_POLY1305, GNUTLS_KX_PSK, GNUTLS_MAC_AEAD,
  65. "NONE:+VERS-DTLS1.2:+COMP-NULL:+CHACHA20-POLY1305:+AEAD:+PSK:%COMPAT:+SIGN-ALL", "3.4.8" },
  66. /* Cisco X-DTLS12-CipherSuite: values */
  67. { "DHE-RSA-AES128-SHA", GNUTLS_DTLS1_2, GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_RSA, GNUTLS_MAC_SHA1,
  68. "NONE:+VERS-DTLS1.2:+COMP-NULL:+AES-128-CBC:+SHA1:+DHE-RSA:+SIGN-ALL:%COMPAT", "3.0.0", 1 },
  69. { "DHE-RSA-AES256-SHA", GNUTLS_DTLS1_2, GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_RSA, GNUTLS_MAC_SHA1,
  70. "NONE:+VERS-DTLS1.2:+COMP-NULL:+AES-256-CBC:+SHA1:+DHE-RSA:+SIGN-ALL:%COMPAT", "3.0.0", 1 },
  71. { "AES128-SHA", GNUTLS_DTLS1_2, GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_RSA, GNUTLS_MAC_SHA1,
  72. "NONE:+VERS-DTLS1.2:+COMP-NULL:+AES-128-CBC:+SHA1:+RSA:+SIGN-ALL:%COMPAT", "3.0.0", 1 },
  73. { "AES256-SHA", GNUTLS_DTLS1_2, GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_RSA, GNUTLS_MAC_SHA1,
  74. "NONE:+VERS-DTLS1.2:+COMP-NULL:+AES-256-CBC:+SHA1:+RSA:+SIGN-ALL:%COMPAT", "3.0.0", 1 },
  75. { "ECDHE-RSA-AES256-GCM-SHA384", GNUTLS_DTLS1_2, GNUTLS_CIPHER_AES_256_GCM, GNUTLS_KX_ECDHE_RSA, GNUTLS_MAC_AEAD,
  76. "NONE:+VERS-DTLS1.2:+COMP-NULL:+AES-256-GCM:+AEAD:+ECDHE-RSA:+SIGN-ALL:%COMPAT", "3.2.7", 1 },
  77. { "ECDHE-RSA-AES128-GCM-SHA256", GNUTLS_DTLS1_2, GNUTLS_CIPHER_AES_128_GCM, GNUTLS_KX_ECDHE_RSA, GNUTLS_MAC_AEAD,
  78. "NONE:+VERS-DTLS1.2:+COMP-NULL:+AES-128-GCM:+AEAD:+ECDHE-RSA:+SIGN-ALL:%COMPAT", "3.2.7", 1 },
  79. { "AES128-GCM-SHA256", GNUTLS_DTLS1_2, GNUTLS_CIPHER_AES_128_GCM, GNUTLS_KX_RSA, GNUTLS_MAC_AEAD,
  80. "NONE:+VERS-DTLS1.2:+COMP-NULL:+AES-128-GCM:+AEAD:+RSA:+SIGN-ALL:%COMPAT", "3.2.7", 1 },
  81. { "AES256-GCM-SHA384", GNUTLS_DTLS1_2, GNUTLS_CIPHER_AES_256_GCM, GNUTLS_KX_RSA, GNUTLS_MAC_AEAD,
  82. "NONE:+VERS-DTLS1.2:+COMP-NULL:+AES-256-GCM:+AEAD:+RSA:+SIGN-ALL:%COMPAT", "3.2.7", 1 },
  83. /* NB. We agreed that any new cipher suites probably shouldn't use
  84. * Cisco's session resume hack (which ties us to a specific version
  85. * of DTLS). Instead, we'll use GNUTLS_KX_PSK and let it negotiate
  86. * the session properly. We might want to wait for
  87. * draft-jay-tls-psk-identity-extension before we do that. */
  88. };
  89. #if GNUTLS_VERSION_NUMBER < 0x030009
  90. void gather_dtls_ciphers(struct openconnect_info *vpninfo, struct oc_text_buf *buf,
  91. struct oc_text_buf *buf12)
  92. {
  93. int i, first = 1;
  94. for (i = 0; i < ARRAY_SIZE(gnutls_dtls_ciphers); i++) {
  95. if (!gnutls_dtls_ciphers[i].cisco_dtls12 &&
  96. gnutls_check_version(gnutls_dtls_ciphers[i].min_gnutls_version)) {
  97. buf_append(buf, "%s%s", first ? "" : ":",
  98. gnutls_dtls_ciphers[i].name);
  99. first = 0;
  100. }
  101. }
  102. }
  103. #else
  104. void gather_dtls_ciphers(struct openconnect_info *vpninfo, struct oc_text_buf *buf,
  105. struct oc_text_buf *buf12)
  106. {
  107. /* only enable the ciphers that would have been negotiated in the TLS channel */
  108. unsigned i, j;
  109. int ret;
  110. unsigned idx;
  111. gnutls_cipher_algorithm_t cipher;
  112. gnutls_mac_algorithm_t mac;
  113. gnutls_priority_t cache;
  114. uint32_t used = 0;
  115. buf_append(buf, "PSK-NEGOTIATE");
  116. ret = gnutls_priority_init(&cache, vpninfo->ciphersuite_config, NULL);
  117. if (ret < 0) {
  118. buf->error = -EIO;
  119. return;
  120. }
  121. for (j=0; ; j++) {
  122. ret = gnutls_priority_get_cipher_suite_index(cache, j, &idx);
  123. if (ret == GNUTLS_E_UNKNOWN_CIPHER_SUITE)
  124. continue;
  125. else if (ret < 0)
  126. break;
  127. if (gnutls_cipher_suite_info(idx, NULL, NULL, &cipher, &mac, NULL) != NULL) {
  128. for (i = 0; i < ARRAY_SIZE(gnutls_dtls_ciphers); i++) {
  129. if (used & (1 << i))
  130. continue;
  131. if (gnutls_dtls_ciphers[i].mac == mac && gnutls_dtls_ciphers[i].cipher == cipher) {
  132. /* This cipher can be supported. Decide whether which list it lives
  133. * in. Cisco's DTLSv1.2 options need to go into a separate
  134. * into a separate X-DTLS12-CipherSuite header for some reason... */
  135. struct oc_text_buf *list;
  136. if (gnutls_dtls_ciphers[i].cisco_dtls12)
  137. list = buf12;
  138. else
  139. list = buf;
  140. if (list && list->pos)
  141. buf_append(list, ":%s", gnutls_dtls_ciphers[i].name);
  142. else
  143. buf_append(list, "%s", gnutls_dtls_ciphers[i].name);
  144. used |= (1 << i);
  145. break;
  146. }
  147. }
  148. }
  149. }
  150. gnutls_priority_deinit(cache);
  151. }
  152. #endif
  153. /* This enables a DTLS protocol negotiation. The new negotiation is as follows:
  154. *
  155. * If the client's X-DTLS-CipherSuite contains the "PSK-NEGOTIATE" keyword,
  156. * the server will reply with "X-DTLS-CipherSuite: PSK-NEGOTIATE" and will
  157. * enable DTLS-PSK negotiation on the DTLS channel. This allows the protocol
  158. * to use new DTLS versions, as well as new DTLS ciphersuites, as long as
  159. * they are also permitted by the system crypto policy in use.
  160. *
  161. * That change still requires to client to pretend it is resuming by setting
  162. * in the TLS ClientHello the session ID provided by the X-DTLS-Session-ID
  163. * header. That is, because there is no TLS extension we can use to set an
  164. * identifier in the client hello (draft-jay-tls-psk-identity-extension
  165. * could be used in the future). The session is not actually resumed.
  166. */
  167. static int start_dtls_psk_handshake(struct openconnect_info *vpninfo, gnutls_session_t dtls_ssl)
  168. {
  169. gnutls_datum_t key;
  170. struct oc_text_buf *prio;
  171. int err;
  172. if (!vpninfo->https_sess) {
  173. vpn_progress(vpninfo, PRG_INFO,
  174. _("Deferring DTLS resumption until CSTP generates a PSK\n"));
  175. return -EAGAIN;
  176. }
  177. prio = buf_alloc();
  178. buf_append(prio, "%s:-VERS-TLS-ALL:+VERS-DTLS-ALL:-KX-ALL:+PSK", vpninfo->ciphersuite_config);
  179. if (buf_error(prio)) {
  180. vpn_progress(vpninfo, PRG_ERR,
  181. _("Failed to generate DTLS priority string\n"));
  182. return buf_free(prio);
  183. }
  184. err = gnutls_priority_set_direct(dtls_ssl, prio->data, NULL);
  185. if (err) {
  186. vpn_progress(vpninfo, PRG_ERR,
  187. _("Failed to set DTLS priority: '%s': %s\n"),
  188. prio->data, gnutls_strerror(err));
  189. goto fail;
  190. }
  191. /* set our session identifier match the application ID; we do that in addition
  192. * to the extension which contains the same information in order to deprecate
  193. * the latter. The reason is that the session ID field is a field not used
  194. * with TLS1.3 (and DTLS1.3), and as such we can rely on it being available to
  195. * us, while avoiding a custom extension which requires standardization.
  196. */
  197. if (vpninfo->dtls_app_id_size > 0) {
  198. gnutls_datum_t id = {vpninfo->dtls_app_id, vpninfo->dtls_app_id_size};
  199. gnutls_session_set_id(dtls_ssl, &id);
  200. }
  201. /* set PSK credentials */
  202. err = gnutls_psk_allocate_client_credentials(&vpninfo->psk_cred);
  203. if (err < 0) {
  204. vpn_progress(vpninfo, PRG_ERR,
  205. _("Failed to allocate credentials: %s\n"),
  206. gnutls_strerror(err));
  207. goto fail;
  208. }
  209. /* generate key */
  210. /* we should have used gnutls_prf_rfc5705() but since we don't use
  211. * the RFC5705 context, the output is identical with gnutls_prf(). The
  212. * latter is available in much earlier versions of gnutls. */
  213. err = gnutls_prf(vpninfo->https_sess, PSK_LABEL_SIZE, PSK_LABEL,
  214. 0, 0, 0, PSK_KEY_SIZE, (char *)vpninfo->dtls_secret);
  215. if (err < 0) {
  216. vpn_progress(vpninfo, PRG_ERR,
  217. _("Failed to generate DTLS key: %s\n"),
  218. gnutls_strerror(err));
  219. goto fail;
  220. }
  221. key.data = vpninfo->dtls_secret;
  222. key.size = PSK_KEY_SIZE;
  223. /* we set an arbitrary username here. We cannot take advantage of the
  224. * username field to send our ID to the server, since the username in TLS-PSK
  225. * is sent after the server-hello. */
  226. err = gnutls_psk_set_client_credentials(vpninfo->psk_cred, "psk", &key, 0);
  227. if (err < 0) {
  228. vpn_progress(vpninfo, PRG_ERR,
  229. _("Failed to set DTLS key: %s\n"),
  230. gnutls_strerror(err));
  231. goto fail;
  232. }
  233. err = gnutls_credentials_set(dtls_ssl, GNUTLS_CRD_PSK, vpninfo->psk_cred);
  234. if (err) {
  235. vpn_progress(vpninfo, PRG_ERR,
  236. _("Failed to set DTLS PSK credentials: %s\n"),
  237. gnutls_strerror(err));
  238. goto fail;
  239. }
  240. buf_free(prio);
  241. return 0;
  242. fail:
  243. buf_free(prio);
  244. gnutls_psk_free_client_credentials(vpninfo->psk_cred);
  245. vpninfo->psk_cred = NULL;
  246. return -EINVAL;
  247. }
  248. static int start_dtls_resume_handshake(struct openconnect_info *vpninfo, gnutls_session_t dtls_ssl)
  249. {
  250. gnutls_datum_t master_secret, session_id;
  251. int err;
  252. int cipher;
  253. for (cipher = 0; cipher < ARRAY_SIZE(gnutls_dtls_ciphers); cipher++) {
  254. if (gnutls_dtls_ciphers[cipher].cisco_dtls12 != vpninfo->dtls12 ||
  255. gnutls_check_version(gnutls_dtls_ciphers[cipher].min_gnutls_version) == NULL)
  256. continue;
  257. if (!strcmp(vpninfo->dtls_cipher, gnutls_dtls_ciphers[cipher].name))
  258. goto found_cipher;
  259. }
  260. vpn_progress(vpninfo, PRG_ERR, _("Unknown DTLS parameters for requested CipherSuite '%s'\n"),
  261. vpninfo->dtls_cipher);
  262. return -EINVAL;
  263. found_cipher:
  264. err = gnutls_priority_set_direct(dtls_ssl,
  265. gnutls_dtls_ciphers[cipher].prio,
  266. NULL);
  267. if (err) {
  268. vpn_progress(vpninfo, PRG_ERR,
  269. _("Failed to set DTLS priority: '%s': %s\n"),
  270. gnutls_dtls_ciphers[cipher].prio, gnutls_strerror(err));
  271. return -EINVAL;
  272. }
  273. gnutls_record_disable_padding(dtls_ssl);
  274. master_secret.data = vpninfo->dtls_secret;
  275. master_secret.size = sizeof(vpninfo->dtls_secret);
  276. session_id.data = vpninfo->dtls_session_id;
  277. session_id.size = sizeof(vpninfo->dtls_session_id);
  278. err = gnutls_session_set_premaster(dtls_ssl, GNUTLS_CLIENT, gnutls_dtls_ciphers[cipher].version,
  279. gnutls_dtls_ciphers[cipher].kx, gnutls_dtls_ciphers[cipher].cipher,
  280. gnutls_dtls_ciphers[cipher].mac, GNUTLS_COMP_NULL,
  281. &master_secret, &session_id);
  282. if (err) {
  283. vpn_progress(vpninfo, PRG_ERR,
  284. _("Failed to set DTLS session parameters: %s\n"),
  285. gnutls_strerror(err));
  286. return -EINVAL;
  287. }
  288. return 0;
  289. }
  290. static int start_dtls_anon_handshake(struct openconnect_info *vpninfo, gnutls_session_t dtls_ssl)
  291. {
  292. char *prio = vpninfo->ciphersuite_config;
  293. int ret;
  294. /*
  295. * Use the same cred store as for the HTTPS session. That has
  296. * our own verify_peer() callback installed, and will validate
  297. * just like we do for the HTTPS service.
  298. *
  299. * There is also perhaps a case to be made for *only* accepting
  300. * precisely the same cert that we get from the HTTPS service,
  301. * but we tried that for EAP-TTLS in the Pulse protocol and the
  302. * theory was disproven, so we ended up doing this there too.
  303. */
  304. gnutls_credentials_set(dtls_ssl, GNUTLS_CRD_CERTIFICATE, vpninfo->https_cred);
  305. /* The F5 BIG-IP server before v16, will crap itself if we
  306. * even *try* to do DTLSv1.2 */
  307. if (!vpninfo->dtls12 &&
  308. asprintf(&prio, "%s:-VERS-DTLS1.2:+VERS-DTLS1.0",
  309. vpninfo->ciphersuite_config) < 0)
  310. return -ENOMEM;
  311. ret = gnutls_priority_set_direct(dtls_ssl, prio ? : vpninfo->ciphersuite_config,
  312. NULL);
  313. if (ret) {
  314. vpn_progress(vpninfo, PRG_ERR,
  315. _("Failed to set DTLS priority: '%s': %s\n"),
  316. prio, gnutls_strerror(ret));
  317. }
  318. if (prio != vpninfo->ciphersuite_config)
  319. free(prio);
  320. return ret;
  321. }
  322. /*
  323. * GnuTLS version between 3.6.3 and 3.6.12 send zero'ed ClientHello. Make sure
  324. * we are not hitting that bug. Adapted from:
  325. * https://gitlab.com/gnutls/gnutls/-/blob/3.6.13/tests/tls_hello_random_value.c
  326. */
  327. static int check_client_hello_random(gnutls_session_t ttls_sess, unsigned int type,
  328. unsigned hook, unsigned int incoming, const gnutls_datum_t *msg)
  329. {
  330. unsigned non_zero = 0, i;
  331. struct openconnect_info *vpninfo = (struct openconnect_info *)gnutls_session_get_ptr(ttls_sess);
  332. if (type == GNUTLS_HANDSHAKE_CLIENT_HELLO && hook == GNUTLS_HOOK_POST) {
  333. gnutls_datum_t buf;
  334. gnutls_session_get_random(ttls_sess, &buf, NULL);
  335. if (buf.size != 32) {
  336. vpn_progress(vpninfo, PRG_ERR,
  337. _("GnuTLS used %d ClientHello random bytes; this should never happen\n"),
  338. buf.size);
  339. return GNUTLS_E_INVALID_REQUEST;
  340. }
  341. for (i = 0; i < buf.size; ++i) {
  342. if (buf.data[i] != 0) {
  343. non_zero++;
  344. }
  345. }
  346. /* The GnuTLS bug was that *all* bytes were zero, but as part of the unit test
  347. * they also slipped in a coincidental check on how well the random number
  348. * generator is behaving. Eight or more zeroes is a bad thing whatever the
  349. * reason for it. So we have the same check. */
  350. if (non_zero <= 8) {
  351. /* TODO: mention CVE number in log message once it's assigned */
  352. vpn_progress(vpninfo, PRG_ERR,
  353. _("GnuTLS sent insecure ClientHello random. Upgrade to 3.6.13 or newer.\n"));
  354. return GNUTLS_E_INVALID_REQUEST;
  355. }
  356. }
  357. return 0;
  358. }
  359. int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd)
  360. {
  361. gnutls_session_t dtls_ssl;
  362. int err, ret;
  363. err = gnutls_init(&dtls_ssl, GNUTLS_CLIENT|GNUTLS_DATAGRAM|GNUTLS_NONBLOCK|GNUTLS_NO_EXTENSIONS);
  364. if (err) {
  365. vpn_progress(vpninfo, PRG_ERR,
  366. _("Failed to initialize DTLS: %s\n"),
  367. gnutls_strerror(err));
  368. return -EINVAL;
  369. }
  370. gnutls_session_set_ptr(dtls_ssl, (void *) vpninfo);
  371. gnutls_transport_set_ptr(dtls_ssl,
  372. (gnutls_transport_ptr_t)(intptr_t)dtls_fd);
  373. if (!vpninfo->dtls_cipher) {
  374. /* Anonymous DTLS (PPP protocols) */
  375. ret = start_dtls_anon_handshake(vpninfo, dtls_ssl);
  376. } else if (!strcmp(vpninfo->dtls_cipher, "PSK-NEGOTIATE")) {
  377. /* For OpenConnect/ocserv protocol */
  378. ret = start_dtls_psk_handshake(vpninfo, dtls_ssl);
  379. } else {
  380. /* Nonexistent session resume hack (Cisco AnyConnect) */
  381. ret = start_dtls_resume_handshake(vpninfo, dtls_ssl);
  382. }
  383. if (ret) {
  384. if (ret != -EAGAIN)
  385. vpninfo->dtls_attempt_period = 0;
  386. gnutls_deinit(dtls_ssl);
  387. return ret;
  388. }
  389. if (gnutls_check_version_numeric(3,6,3) && !gnutls_check_version_numeric(3,6,13)) {
  390. gnutls_handshake_set_hook_function(dtls_ssl, GNUTLS_HANDSHAKE_CLIENT_HELLO,
  391. GNUTLS_HOOK_POST, check_client_hello_random);
  392. }
  393. vpninfo->dtls_ssl = dtls_ssl;
  394. return 0;
  395. }
  396. int dtls_try_handshake(struct openconnect_info *vpninfo, int *timeout)
  397. {
  398. int err = gnutls_handshake(vpninfo->dtls_ssl);
  399. char *str;
  400. if (!err) {
  401. if (!vpninfo->dtls_cipher) {
  402. /* Anonymous DTLS (PPP protocols) will set vpninfo->ip_info.mtu
  403. * in PPP negotiation.
  404. *
  405. * XX: Needs forthcoming overhaul to detect MTU correctly and offer
  406. * reasonable MRU values during PPP negotiation.
  407. */
  408. int data_mtu = vpninfo->cstp_basemtu = 1500;
  409. if (vpninfo->peer_addr->sa_family == IPPROTO_IPV6)
  410. data_mtu -= 40; /* IPv6 header */
  411. else
  412. data_mtu -= 20; /* Legacy IP header */
  413. data_mtu -= 8; /* UDP header */
  414. dtls_set_mtu(vpninfo, data_mtu);
  415. } else if (!strcmp(vpninfo->dtls_cipher, "PSK-NEGOTIATE")) {
  416. /* For PSK-NEGOTIATE (OpenConnect/ocserv protocol)
  417. * we have to determine the tunnel MTU
  418. * for ourselves based on the base MTU */
  419. int data_mtu = vpninfo->cstp_basemtu;
  420. if (vpninfo->peer_addr->sa_family == IPPROTO_IPV6)
  421. data_mtu -= 40; /* IPv6 header */
  422. else
  423. data_mtu -= 20; /* Legacy IP header */
  424. data_mtu -= 8; /* UDP header */
  425. if (data_mtu < 0) {
  426. vpn_progress(vpninfo, PRG_ERR,
  427. _("Peer MTU %d too small to allow DTLS\n"),
  428. vpninfo->cstp_basemtu);
  429. goto nodtls;
  430. }
  431. /* Reduce it by one because that's the payload header *inside*
  432. * the encryption */
  433. data_mtu = dtls_set_mtu(vpninfo, data_mtu) - 1;
  434. if (data_mtu < vpninfo->ip_info.mtu) {
  435. vpn_progress(vpninfo, PRG_INFO,
  436. _("DTLS MTU reduced to %d\n"),
  437. data_mtu);
  438. vpninfo->ip_info.mtu = data_mtu;
  439. }
  440. } else {
  441. /* Nonexistent session resume hack (Cisco AnyConnect) */
  442. if (!gnutls_session_is_resumed(vpninfo->dtls_ssl)) {
  443. /* Someone attempting to hijack the DTLS session?
  444. * A real server would never allow a full session
  445. * establishment instead of the agreed resume. */
  446. vpn_progress(vpninfo, PRG_ERR,
  447. _("DTLS session resume failed; possible MITM attack. Disabling DTLS.\n"));
  448. nodtls:
  449. dtls_close(vpninfo);
  450. vpninfo->dtls_attempt_period = 0;
  451. vpninfo->dtls_state = DTLS_DISABLED;
  452. return -EIO;
  453. }
  454. /* Make sure GnuTLS's idea of the MTU is sufficient to take
  455. a full VPN MTU (with 1-byte header) in a data record. */
  456. err = gnutls_dtls_set_data_mtu(vpninfo->dtls_ssl, vpninfo->ip_info.mtu + 1);
  457. if (err) {
  458. vpn_progress(vpninfo, PRG_ERR,
  459. _("Failed to set DTLS MTU: %s\n"),
  460. gnutls_strerror(err));
  461. goto error;
  462. }
  463. }
  464. vpninfo->dtls_state = DTLS_CONNECTED;
  465. str = get_gnutls_cipher(vpninfo->dtls_ssl);
  466. if (str) {
  467. const char *c;
  468. vpn_progress(vpninfo, PRG_INFO,
  469. _("Established DTLS connection (using GnuTLS). Ciphersuite %s.\n"),
  470. str);
  471. gnutls_free(str);
  472. c = openconnect_get_dtls_compression(vpninfo);
  473. if (c) {
  474. vpn_progress(vpninfo, PRG_INFO,
  475. _("DTLS connection compression using %s.\n"), c);
  476. }
  477. }
  478. vpninfo->dtls_times.last_rekey = vpninfo->dtls_times.last_rx =
  479. vpninfo->dtls_times.last_tx = time(NULL);
  480. dtls_detect_mtu(vpninfo);
  481. /* XXX: For OpenSSL we explicitly prevent retransmits here. */
  482. return 0;
  483. }
  484. if (err == GNUTLS_E_AGAIN || err == GNUTLS_E_INTERRUPTED) {
  485. int quit_time = vpninfo->new_dtls_started + 12 - time(NULL);
  486. if (quit_time > 0) {
  487. if (timeout) {
  488. unsigned next_resend = gnutls_dtls_get_timeout(vpninfo->dtls_ssl);
  489. if (next_resend && *timeout > next_resend)
  490. *timeout = next_resend;
  491. if (*timeout > quit_time * 1000)
  492. *timeout = quit_time * 1000;
  493. }
  494. return 0;
  495. }
  496. vpn_progress(vpninfo, PRG_DEBUG, _("DTLS handshake timed out\n"));
  497. }
  498. vpn_progress(vpninfo, PRG_ERR, _("DTLS handshake failed: %s\n"),
  499. gnutls_strerror(err));
  500. if (err == GNUTLS_E_PUSH_ERROR)
  501. vpn_progress(vpninfo, PRG_ERR,
  502. _("(Is a firewall preventing you from sending UDP packets?)\n"));
  503. error:
  504. dtls_close(vpninfo);
  505. vpninfo->dtls_state = DTLS_SLEEPING;
  506. time(&vpninfo->new_dtls_started);
  507. if (timeout && *timeout > vpninfo->dtls_attempt_period * 1000)
  508. *timeout = vpninfo->dtls_attempt_period * 1000;
  509. return -EINVAL;
  510. }
  511. void dtls_shutdown(struct openconnect_info *vpninfo)
  512. {
  513. dtls_close(vpninfo);
  514. }
  515. void dtls_ssl_free(struct openconnect_info *vpninfo)
  516. {
  517. gnutls_deinit(vpninfo->dtls_ssl);
  518. if (vpninfo->psk_cred) {
  519. gnutls_psk_free_client_credentials(vpninfo->psk_cred);
  520. vpninfo->psk_cred = NULL;
  521. }
  522. }