tls_gnutls.c 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594
  1. /*
  2. * SSL/TLS interface functions for GnuTLS
  3. * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi>
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. */
  8. #include "includes.h"
  9. #include <gnutls/gnutls.h>
  10. #include <gnutls/x509.h>
  11. #ifdef PKCS12_FUNCS
  12. #include <gnutls/pkcs12.h>
  13. #endif /* PKCS12_FUNCS */
  14. #if GNUTLS_VERSION_NUMBER >= 0x030103
  15. #include <gnutls/ocsp.h>
  16. #endif /* 3.1.3 */
  17. #include "common.h"
  18. #include "crypto/crypto.h"
  19. #include "tls.h"
  20. static int tls_gnutls_ref_count = 0;
  21. struct tls_global {
  22. /* Data for session resumption */
  23. void *session_data;
  24. size_t session_data_size;
  25. int server;
  26. int params_set;
  27. gnutls_certificate_credentials_t xcred;
  28. void (*event_cb)(void *ctx, enum tls_event ev,
  29. union tls_event_data *data);
  30. void *cb_ctx;
  31. int cert_in_cb;
  32. char *ocsp_stapling_response;
  33. };
  34. struct tls_connection {
  35. struct tls_global *global;
  36. gnutls_session_t session;
  37. int read_alerts, write_alerts, failed;
  38. u8 *pre_shared_secret;
  39. size_t pre_shared_secret_len;
  40. int established;
  41. int verify_peer;
  42. unsigned int disable_time_checks:1;
  43. struct wpabuf *push_buf;
  44. struct wpabuf *pull_buf;
  45. const u8 *pull_buf_offset;
  46. int params_set;
  47. gnutls_certificate_credentials_t xcred;
  48. char *suffix_match;
  49. char *domain_match;
  50. unsigned int flags;
  51. };
  52. static int tls_connection_verify_peer(gnutls_session_t session);
  53. static void tls_log_func(int level, const char *msg)
  54. {
  55. char *s, *pos;
  56. if (level == 6 || level == 7) {
  57. /* These levels seem to be mostly I/O debug and msg dumps */
  58. return;
  59. }
  60. s = os_strdup(msg);
  61. if (s == NULL)
  62. return;
  63. pos = s;
  64. while (*pos != '\0') {
  65. if (*pos == '\n') {
  66. *pos = '\0';
  67. break;
  68. }
  69. pos++;
  70. }
  71. wpa_printf(level > 3 ? MSG_MSGDUMP : MSG_DEBUG,
  72. "gnutls<%d> %s", level, s);
  73. os_free(s);
  74. }
  75. void * tls_init(const struct tls_config *conf)
  76. {
  77. struct tls_global *global;
  78. if (tls_gnutls_ref_count == 0) {
  79. wpa_printf(MSG_DEBUG,
  80. "GnuTLS: Library version %s (runtime) - %s (build)",
  81. gnutls_check_version(NULL), GNUTLS_VERSION);
  82. }
  83. global = os_zalloc(sizeof(*global));
  84. if (global == NULL)
  85. return NULL;
  86. if (tls_gnutls_ref_count == 0 && gnutls_global_init() < 0) {
  87. os_free(global);
  88. return NULL;
  89. }
  90. tls_gnutls_ref_count++;
  91. gnutls_global_set_log_function(tls_log_func);
  92. if (wpa_debug_show_keys)
  93. gnutls_global_set_log_level(11);
  94. if (conf) {
  95. global->event_cb = conf->event_cb;
  96. global->cb_ctx = conf->cb_ctx;
  97. global->cert_in_cb = conf->cert_in_cb;
  98. }
  99. return global;
  100. }
  101. void tls_deinit(void *ssl_ctx)
  102. {
  103. struct tls_global *global = ssl_ctx;
  104. if (global) {
  105. if (global->params_set)
  106. gnutls_certificate_free_credentials(global->xcred);
  107. os_free(global->session_data);
  108. os_free(global->ocsp_stapling_response);
  109. os_free(global);
  110. }
  111. tls_gnutls_ref_count--;
  112. if (tls_gnutls_ref_count == 0)
  113. gnutls_global_deinit();
  114. }
  115. int tls_get_errors(void *ssl_ctx)
  116. {
  117. return 0;
  118. }
  119. static ssize_t tls_pull_func(gnutls_transport_ptr_t ptr, void *buf,
  120. size_t len)
  121. {
  122. struct tls_connection *conn = (struct tls_connection *) ptr;
  123. const u8 *end;
  124. if (conn->pull_buf == NULL) {
  125. errno = EWOULDBLOCK;
  126. return -1;
  127. }
  128. end = wpabuf_head_u8(conn->pull_buf) + wpabuf_len(conn->pull_buf);
  129. if ((size_t) (end - conn->pull_buf_offset) < len)
  130. len = end - conn->pull_buf_offset;
  131. os_memcpy(buf, conn->pull_buf_offset, len);
  132. conn->pull_buf_offset += len;
  133. if (conn->pull_buf_offset == end) {
  134. wpa_printf(MSG_DEBUG, "%s - pull_buf consumed", __func__);
  135. wpabuf_free(conn->pull_buf);
  136. conn->pull_buf = NULL;
  137. conn->pull_buf_offset = NULL;
  138. } else {
  139. wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in pull_buf",
  140. __func__,
  141. (unsigned long) (end - conn->pull_buf_offset));
  142. }
  143. return len;
  144. }
  145. static ssize_t tls_push_func(gnutls_transport_ptr_t ptr, const void *buf,
  146. size_t len)
  147. {
  148. struct tls_connection *conn = (struct tls_connection *) ptr;
  149. if (wpabuf_resize(&conn->push_buf, len) < 0) {
  150. errno = ENOMEM;
  151. return -1;
  152. }
  153. wpabuf_put_data(conn->push_buf, buf, len);
  154. return len;
  155. }
  156. static int tls_gnutls_init_session(struct tls_global *global,
  157. struct tls_connection *conn)
  158. {
  159. const char *err;
  160. int ret;
  161. ret = gnutls_init(&conn->session,
  162. global->server ? GNUTLS_SERVER : GNUTLS_CLIENT);
  163. if (ret < 0) {
  164. wpa_printf(MSG_INFO, "TLS: Failed to initialize new TLS "
  165. "connection: %s", gnutls_strerror(ret));
  166. return -1;
  167. }
  168. ret = gnutls_set_default_priority(conn->session);
  169. if (ret < 0)
  170. goto fail;
  171. ret = gnutls_priority_set_direct(conn->session, "NORMAL:-VERS-SSL3.0",
  172. &err);
  173. if (ret < 0) {
  174. wpa_printf(MSG_ERROR, "GnuTLS: Priority string failure at "
  175. "'%s'", err);
  176. goto fail;
  177. }
  178. gnutls_transport_set_pull_function(conn->session, tls_pull_func);
  179. gnutls_transport_set_push_function(conn->session, tls_push_func);
  180. gnutls_transport_set_ptr(conn->session, (gnutls_transport_ptr_t) conn);
  181. gnutls_session_set_ptr(conn->session, conn);
  182. return 0;
  183. fail:
  184. wpa_printf(MSG_INFO, "TLS: Failed to setup new TLS connection: %s",
  185. gnutls_strerror(ret));
  186. gnutls_deinit(conn->session);
  187. return -1;
  188. }
  189. struct tls_connection * tls_connection_init(void *ssl_ctx)
  190. {
  191. struct tls_global *global = ssl_ctx;
  192. struct tls_connection *conn;
  193. int ret;
  194. conn = os_zalloc(sizeof(*conn));
  195. if (conn == NULL)
  196. return NULL;
  197. conn->global = global;
  198. if (tls_gnutls_init_session(global, conn)) {
  199. os_free(conn);
  200. return NULL;
  201. }
  202. if (global->params_set) {
  203. ret = gnutls_credentials_set(conn->session,
  204. GNUTLS_CRD_CERTIFICATE,
  205. global->xcred);
  206. if (ret < 0) {
  207. wpa_printf(MSG_INFO, "Failed to configure "
  208. "credentials: %s", gnutls_strerror(ret));
  209. os_free(conn);
  210. return NULL;
  211. }
  212. }
  213. if (gnutls_certificate_allocate_credentials(&conn->xcred)) {
  214. os_free(conn);
  215. return NULL;
  216. }
  217. return conn;
  218. }
  219. void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn)
  220. {
  221. if (conn == NULL)
  222. return;
  223. gnutls_certificate_free_credentials(conn->xcred);
  224. gnutls_deinit(conn->session);
  225. os_free(conn->pre_shared_secret);
  226. wpabuf_free(conn->push_buf);
  227. wpabuf_free(conn->pull_buf);
  228. os_free(conn->suffix_match);
  229. os_free(conn->domain_match);
  230. os_free(conn);
  231. }
  232. int tls_connection_established(void *ssl_ctx, struct tls_connection *conn)
  233. {
  234. return conn ? conn->established : 0;
  235. }
  236. int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn)
  237. {
  238. struct tls_global *global = ssl_ctx;
  239. int ret;
  240. if (conn == NULL)
  241. return -1;
  242. /* Shutdown previous TLS connection without notifying the peer
  243. * because the connection was already terminated in practice
  244. * and "close notify" shutdown alert would confuse AS. */
  245. gnutls_bye(conn->session, GNUTLS_SHUT_RDWR);
  246. wpabuf_free(conn->push_buf);
  247. conn->push_buf = NULL;
  248. conn->established = 0;
  249. gnutls_deinit(conn->session);
  250. if (tls_gnutls_init_session(global, conn)) {
  251. wpa_printf(MSG_INFO, "GnuTLS: Failed to preparare new session "
  252. "for session resumption use");
  253. return -1;
  254. }
  255. ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE,
  256. conn->params_set ? conn->xcred :
  257. global->xcred);
  258. if (ret < 0) {
  259. wpa_printf(MSG_INFO, "GnuTLS: Failed to configure credentials "
  260. "for session resumption: %s", gnutls_strerror(ret));
  261. return -1;
  262. }
  263. if (global->session_data) {
  264. ret = gnutls_session_set_data(conn->session,
  265. global->session_data,
  266. global->session_data_size);
  267. if (ret < 0) {
  268. wpa_printf(MSG_INFO, "GnuTLS: Failed to set session "
  269. "data: %s", gnutls_strerror(ret));
  270. return -1;
  271. }
  272. }
  273. return 0;
  274. }
  275. int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
  276. const struct tls_connection_params *params)
  277. {
  278. int ret;
  279. if (conn == NULL || params == NULL)
  280. return -1;
  281. if (params->flags & TLS_CONN_REQUIRE_OCSP_ALL) {
  282. wpa_printf(MSG_INFO,
  283. "GnuTLS: ocsp=3 not supported");
  284. return -1;
  285. }
  286. if (params->flags & TLS_CONN_EXT_CERT_CHECK) {
  287. wpa_printf(MSG_INFO,
  288. "GnuTLS: tls_ext_cert_check=1 not supported");
  289. return -1;
  290. }
  291. if (params->subject_match) {
  292. wpa_printf(MSG_INFO, "GnuTLS: subject_match not supported");
  293. return -1;
  294. }
  295. if (params->altsubject_match) {
  296. wpa_printf(MSG_INFO, "GnuTLS: altsubject_match not supported");
  297. return -1;
  298. }
  299. os_free(conn->suffix_match);
  300. conn->suffix_match = NULL;
  301. if (params->suffix_match) {
  302. conn->suffix_match = os_strdup(params->suffix_match);
  303. if (conn->suffix_match == NULL)
  304. return -1;
  305. }
  306. #if GNUTLS_VERSION_NUMBER >= 0x030300
  307. os_free(conn->domain_match);
  308. conn->domain_match = NULL;
  309. if (params->domain_match) {
  310. conn->domain_match = os_strdup(params->domain_match);
  311. if (conn->domain_match == NULL)
  312. return -1;
  313. }
  314. #else /* < 3.3.0 */
  315. if (params->domain_match) {
  316. wpa_printf(MSG_INFO, "GnuTLS: domain_match not supported");
  317. return -1;
  318. }
  319. #endif /* >= 3.3.0 */
  320. conn->flags = params->flags;
  321. if (params->openssl_ciphers) {
  322. wpa_printf(MSG_INFO, "GnuTLS: openssl_ciphers not supported");
  323. return -1;
  324. }
  325. /* TODO: gnutls_certificate_set_verify_flags(xcred, flags);
  326. * to force peer validation(?) */
  327. if (params->ca_cert) {
  328. wpa_printf(MSG_DEBUG, "GnuTLS: Try to parse %s in DER format",
  329. params->ca_cert);
  330. ret = gnutls_certificate_set_x509_trust_file(
  331. conn->xcred, params->ca_cert, GNUTLS_X509_FMT_DER);
  332. if (ret < 0) {
  333. wpa_printf(MSG_DEBUG,
  334. "GnuTLS: Failed to read CA cert '%s' in DER format (%s) - try in PEM format",
  335. params->ca_cert,
  336. gnutls_strerror(ret));
  337. ret = gnutls_certificate_set_x509_trust_file(
  338. conn->xcred, params->ca_cert,
  339. GNUTLS_X509_FMT_PEM);
  340. if (ret < 0) {
  341. wpa_printf(MSG_DEBUG,
  342. "Failed to read CA cert '%s' in PEM format: %s",
  343. params->ca_cert,
  344. gnutls_strerror(ret));
  345. return -1;
  346. }
  347. }
  348. } else if (params->ca_cert_blob) {
  349. gnutls_datum_t ca;
  350. ca.data = (unsigned char *) params->ca_cert_blob;
  351. ca.size = params->ca_cert_blob_len;
  352. ret = gnutls_certificate_set_x509_trust_mem(
  353. conn->xcred, &ca, GNUTLS_X509_FMT_DER);
  354. if (ret < 0) {
  355. wpa_printf(MSG_DEBUG,
  356. "Failed to parse CA cert in DER format: %s",
  357. gnutls_strerror(ret));
  358. ret = gnutls_certificate_set_x509_trust_mem(
  359. conn->xcred, &ca, GNUTLS_X509_FMT_PEM);
  360. if (ret < 0) {
  361. wpa_printf(MSG_DEBUG,
  362. "Failed to parse CA cert in PEM format: %s",
  363. gnutls_strerror(ret));
  364. return -1;
  365. }
  366. }
  367. } else if (params->ca_path) {
  368. wpa_printf(MSG_INFO, "GnuTLS: ca_path not supported");
  369. return -1;
  370. }
  371. conn->disable_time_checks = 0;
  372. if (params->ca_cert || params->ca_cert_blob) {
  373. conn->verify_peer = 1;
  374. gnutls_certificate_set_verify_function(
  375. conn->xcred, tls_connection_verify_peer);
  376. if (params->flags & TLS_CONN_ALLOW_SIGN_RSA_MD5) {
  377. gnutls_certificate_set_verify_flags(
  378. conn->xcred, GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5);
  379. }
  380. if (params->flags & TLS_CONN_DISABLE_TIME_CHECKS) {
  381. conn->disable_time_checks = 1;
  382. gnutls_certificate_set_verify_flags(
  383. conn->xcred,
  384. GNUTLS_VERIFY_DISABLE_TIME_CHECKS);
  385. }
  386. }
  387. if (params->client_cert && params->private_key) {
  388. #if GNUTLS_VERSION_NUMBER >= 0x03010b
  389. ret = gnutls_certificate_set_x509_key_file2(
  390. conn->xcred, params->client_cert, params->private_key,
  391. GNUTLS_X509_FMT_DER, params->private_key_passwd, 0);
  392. #else
  393. /* private_key_passwd not (easily) supported here */
  394. ret = gnutls_certificate_set_x509_key_file(
  395. conn->xcred, params->client_cert, params->private_key,
  396. GNUTLS_X509_FMT_DER);
  397. #endif
  398. if (ret < 0) {
  399. wpa_printf(MSG_DEBUG, "Failed to read client cert/key "
  400. "in DER format: %s", gnutls_strerror(ret));
  401. #if GNUTLS_VERSION_NUMBER >= 0x03010b
  402. ret = gnutls_certificate_set_x509_key_file2(
  403. conn->xcred, params->client_cert,
  404. params->private_key, GNUTLS_X509_FMT_PEM,
  405. params->private_key_passwd, 0);
  406. #else
  407. ret = gnutls_certificate_set_x509_key_file(
  408. conn->xcred, params->client_cert,
  409. params->private_key, GNUTLS_X509_FMT_PEM);
  410. #endif
  411. if (ret < 0) {
  412. wpa_printf(MSG_DEBUG, "Failed to read client "
  413. "cert/key in PEM format: %s",
  414. gnutls_strerror(ret));
  415. return ret;
  416. }
  417. }
  418. } else if (params->private_key) {
  419. int pkcs12_ok = 0;
  420. #ifdef PKCS12_FUNCS
  421. /* Try to load in PKCS#12 format */
  422. ret = gnutls_certificate_set_x509_simple_pkcs12_file(
  423. conn->xcred, params->private_key, GNUTLS_X509_FMT_DER,
  424. params->private_key_passwd);
  425. if (ret != 0) {
  426. wpa_printf(MSG_DEBUG, "Failed to load private_key in "
  427. "PKCS#12 format: %s", gnutls_strerror(ret));
  428. return -1;
  429. } else
  430. pkcs12_ok = 1;
  431. #endif /* PKCS12_FUNCS */
  432. if (!pkcs12_ok) {
  433. wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not "
  434. "included");
  435. return -1;
  436. }
  437. } else if (params->client_cert_blob && params->private_key_blob) {
  438. gnutls_datum_t cert, key;
  439. cert.data = (unsigned char *) params->client_cert_blob;
  440. cert.size = params->client_cert_blob_len;
  441. key.data = (unsigned char *) params->private_key_blob;
  442. key.size = params->private_key_blob_len;
  443. #if GNUTLS_VERSION_NUMBER >= 0x03010b
  444. ret = gnutls_certificate_set_x509_key_mem2(
  445. conn->xcred, &cert, &key, GNUTLS_X509_FMT_DER,
  446. params->private_key_passwd, 0);
  447. #else
  448. /* private_key_passwd not (easily) supported here */
  449. ret = gnutls_certificate_set_x509_key_mem(
  450. conn->xcred, &cert, &key, GNUTLS_X509_FMT_DER);
  451. #endif
  452. if (ret < 0) {
  453. wpa_printf(MSG_DEBUG, "Failed to read client cert/key "
  454. "in DER format: %s", gnutls_strerror(ret));
  455. #if GNUTLS_VERSION_NUMBER >= 0x03010b
  456. ret = gnutls_certificate_set_x509_key_mem2(
  457. conn->xcred, &cert, &key, GNUTLS_X509_FMT_PEM,
  458. params->private_key_passwd, 0);
  459. #else
  460. /* private_key_passwd not (easily) supported here */
  461. ret = gnutls_certificate_set_x509_key_mem(
  462. conn->xcred, &cert, &key, GNUTLS_X509_FMT_PEM);
  463. #endif
  464. if (ret < 0) {
  465. wpa_printf(MSG_DEBUG, "Failed to read client "
  466. "cert/key in PEM format: %s",
  467. gnutls_strerror(ret));
  468. return ret;
  469. }
  470. }
  471. } else if (params->private_key_blob) {
  472. #ifdef PKCS12_FUNCS
  473. gnutls_datum_t key;
  474. key.data = (unsigned char *) params->private_key_blob;
  475. key.size = params->private_key_blob_len;
  476. /* Try to load in PKCS#12 format */
  477. ret = gnutls_certificate_set_x509_simple_pkcs12_mem(
  478. conn->xcred, &key, GNUTLS_X509_FMT_DER,
  479. params->private_key_passwd);
  480. if (ret != 0) {
  481. wpa_printf(MSG_DEBUG, "Failed to load private_key in "
  482. "PKCS#12 format: %s", gnutls_strerror(ret));
  483. return -1;
  484. }
  485. #else /* PKCS12_FUNCS */
  486. wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not included");
  487. return -1;
  488. #endif /* PKCS12_FUNCS */
  489. }
  490. #if GNUTLS_VERSION_NUMBER >= 0x030103
  491. if (params->flags & (TLS_CONN_REQUEST_OCSP | TLS_CONN_REQUIRE_OCSP)) {
  492. ret = gnutls_ocsp_status_request_enable_client(conn->session,
  493. NULL, 0, NULL);
  494. if (ret != GNUTLS_E_SUCCESS) {
  495. wpa_printf(MSG_INFO,
  496. "GnuTLS: Failed to enable OCSP client");
  497. return -1;
  498. }
  499. }
  500. #else /* 3.1.3 */
  501. if (params->flags & TLS_CONN_REQUIRE_OCSP) {
  502. wpa_printf(MSG_INFO,
  503. "GnuTLS: OCSP not supported by this version of GnuTLS");
  504. return -1;
  505. }
  506. #endif /* 3.1.3 */
  507. conn->params_set = 1;
  508. ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE,
  509. conn->xcred);
  510. if (ret < 0) {
  511. wpa_printf(MSG_INFO, "Failed to configure credentials: %s",
  512. gnutls_strerror(ret));
  513. }
  514. return ret;
  515. }
  516. #if GNUTLS_VERSION_NUMBER >= 0x030103
  517. static int server_ocsp_status_req(gnutls_session_t session, void *ptr,
  518. gnutls_datum_t *resp)
  519. {
  520. struct tls_global *global = ptr;
  521. char *cached;
  522. size_t len;
  523. if (!global->ocsp_stapling_response) {
  524. wpa_printf(MSG_DEBUG, "GnuTLS: OCSP status callback - no response configured");
  525. return GNUTLS_E_NO_CERTIFICATE_STATUS;
  526. }
  527. cached = os_readfile(global->ocsp_stapling_response, &len);
  528. if (!cached) {
  529. wpa_printf(MSG_DEBUG,
  530. "GnuTLS: OCSP status callback - could not read response file (%s)",
  531. global->ocsp_stapling_response);
  532. return GNUTLS_E_NO_CERTIFICATE_STATUS;
  533. }
  534. wpa_printf(MSG_DEBUG,
  535. "GnuTLS: OCSP status callback - send cached response");
  536. resp->data = gnutls_malloc(len);
  537. if (!resp->data) {
  538. os_free(resp);
  539. return GNUTLS_E_MEMORY_ERROR;
  540. }
  541. os_memcpy(resp->data, cached, len);
  542. resp->size = len;
  543. os_free(cached);
  544. return GNUTLS_E_SUCCESS;
  545. }
  546. #endif /* 3.1.3 */
  547. int tls_global_set_params(void *tls_ctx,
  548. const struct tls_connection_params *params)
  549. {
  550. struct tls_global *global = tls_ctx;
  551. int ret;
  552. /* Currently, global parameters are only set when running in server
  553. * mode. */
  554. global->server = 1;
  555. if (global->params_set) {
  556. gnutls_certificate_free_credentials(global->xcred);
  557. global->params_set = 0;
  558. }
  559. ret = gnutls_certificate_allocate_credentials(&global->xcred);
  560. if (ret) {
  561. wpa_printf(MSG_DEBUG, "Failed to allocate global credentials "
  562. "%s", gnutls_strerror(ret));
  563. return -1;
  564. }
  565. if (params->ca_cert) {
  566. ret = gnutls_certificate_set_x509_trust_file(
  567. global->xcred, params->ca_cert, GNUTLS_X509_FMT_DER);
  568. if (ret < 0) {
  569. wpa_printf(MSG_DEBUG, "Failed to read CA cert '%s' "
  570. "in DER format: %s", params->ca_cert,
  571. gnutls_strerror(ret));
  572. ret = gnutls_certificate_set_x509_trust_file(
  573. global->xcred, params->ca_cert,
  574. GNUTLS_X509_FMT_PEM);
  575. if (ret < 0) {
  576. wpa_printf(MSG_DEBUG, "Failed to read CA cert "
  577. "'%s' in PEM format: %s",
  578. params->ca_cert,
  579. gnutls_strerror(ret));
  580. goto fail;
  581. }
  582. }
  583. if (params->flags & TLS_CONN_ALLOW_SIGN_RSA_MD5) {
  584. gnutls_certificate_set_verify_flags(
  585. global->xcred,
  586. GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5);
  587. }
  588. if (params->flags & TLS_CONN_DISABLE_TIME_CHECKS) {
  589. gnutls_certificate_set_verify_flags(
  590. global->xcred,
  591. GNUTLS_VERIFY_DISABLE_TIME_CHECKS);
  592. }
  593. }
  594. if (params->client_cert && params->private_key) {
  595. /* TODO: private_key_passwd? */
  596. ret = gnutls_certificate_set_x509_key_file(
  597. global->xcred, params->client_cert,
  598. params->private_key, GNUTLS_X509_FMT_DER);
  599. if (ret < 0) {
  600. wpa_printf(MSG_DEBUG, "Failed to read client cert/key "
  601. "in DER format: %s", gnutls_strerror(ret));
  602. ret = gnutls_certificate_set_x509_key_file(
  603. global->xcred, params->client_cert,
  604. params->private_key, GNUTLS_X509_FMT_PEM);
  605. if (ret < 0) {
  606. wpa_printf(MSG_DEBUG, "Failed to read client "
  607. "cert/key in PEM format: %s",
  608. gnutls_strerror(ret));
  609. goto fail;
  610. }
  611. }
  612. } else if (params->private_key) {
  613. int pkcs12_ok = 0;
  614. #ifdef PKCS12_FUNCS
  615. /* Try to load in PKCS#12 format */
  616. ret = gnutls_certificate_set_x509_simple_pkcs12_file(
  617. global->xcred, params->private_key,
  618. GNUTLS_X509_FMT_DER, params->private_key_passwd);
  619. if (ret != 0) {
  620. wpa_printf(MSG_DEBUG, "Failed to load private_key in "
  621. "PKCS#12 format: %s", gnutls_strerror(ret));
  622. goto fail;
  623. } else
  624. pkcs12_ok = 1;
  625. #endif /* PKCS12_FUNCS */
  626. if (!pkcs12_ok) {
  627. wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not "
  628. "included");
  629. goto fail;
  630. }
  631. }
  632. #if GNUTLS_VERSION_NUMBER >= 0x030103
  633. os_free(global->ocsp_stapling_response);
  634. if (params->ocsp_stapling_response)
  635. global->ocsp_stapling_response =
  636. os_strdup(params->ocsp_stapling_response);
  637. else
  638. global->ocsp_stapling_response = NULL;
  639. gnutls_certificate_set_ocsp_status_request_function(
  640. global->xcred, server_ocsp_status_req, global);
  641. #endif /* 3.1.3 */
  642. global->params_set = 1;
  643. return 0;
  644. fail:
  645. gnutls_certificate_free_credentials(global->xcred);
  646. return -1;
  647. }
  648. int tls_global_set_verify(void *ssl_ctx, int check_crl)
  649. {
  650. /* TODO */
  651. return 0;
  652. }
  653. int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
  654. int verify_peer, unsigned int flags,
  655. const u8 *session_ctx, size_t session_ctx_len)
  656. {
  657. if (conn == NULL || conn->session == NULL)
  658. return -1;
  659. conn->verify_peer = verify_peer;
  660. gnutls_certificate_server_set_request(conn->session,
  661. verify_peer ? GNUTLS_CERT_REQUIRE
  662. : GNUTLS_CERT_REQUEST);
  663. return 0;
  664. }
  665. int tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn,
  666. struct tls_random *keys)
  667. {
  668. #if GNUTLS_VERSION_NUMBER >= 0x030012
  669. gnutls_datum_t client, server;
  670. if (conn == NULL || conn->session == NULL || keys == NULL)
  671. return -1;
  672. os_memset(keys, 0, sizeof(*keys));
  673. gnutls_session_get_random(conn->session, &client, &server);
  674. keys->client_random = client.data;
  675. keys->server_random = server.data;
  676. keys->client_random_len = client.size;
  677. keys->server_random_len = client.size;
  678. return 0;
  679. #else /* 3.0.18 */
  680. return -1;
  681. #endif /* 3.0.18 */
  682. }
  683. int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
  684. const char *label, u8 *out, size_t out_len)
  685. {
  686. if (conn == NULL || conn->session == NULL)
  687. return -1;
  688. return gnutls_prf(conn->session, os_strlen(label), label,
  689. 0 /* client_random first */, 0, NULL, out_len,
  690. (char *) out);
  691. }
  692. int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn,
  693. u8 *out, size_t out_len)
  694. {
  695. return -1;
  696. }
  697. static void gnutls_tls_fail_event(struct tls_connection *conn,
  698. const gnutls_datum_t *cert, int depth,
  699. const char *subject, const char *err_str,
  700. enum tls_fail_reason reason)
  701. {
  702. union tls_event_data ev;
  703. struct tls_global *global = conn->global;
  704. struct wpabuf *cert_buf = NULL;
  705. if (global->event_cb == NULL)
  706. return;
  707. os_memset(&ev, 0, sizeof(ev));
  708. ev.cert_fail.depth = depth;
  709. ev.cert_fail.subject = subject ? subject : "";
  710. ev.cert_fail.reason = reason;
  711. ev.cert_fail.reason_txt = err_str;
  712. if (cert) {
  713. cert_buf = wpabuf_alloc_copy(cert->data, cert->size);
  714. ev.cert_fail.cert = cert_buf;
  715. }
  716. global->event_cb(global->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev);
  717. wpabuf_free(cert_buf);
  718. }
  719. #if GNUTLS_VERSION_NUMBER < 0x030300
  720. static int server_eku_purpose(gnutls_x509_crt_t cert)
  721. {
  722. unsigned int i;
  723. for (i = 0; ; i++) {
  724. char oid[128];
  725. size_t oid_size = sizeof(oid);
  726. int res;
  727. res = gnutls_x509_crt_get_key_purpose_oid(cert, i, oid,
  728. &oid_size, NULL);
  729. if (res == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
  730. if (i == 0) {
  731. /* No EKU - assume any use allowed */
  732. return 1;
  733. }
  734. break;
  735. }
  736. if (res < 0) {
  737. wpa_printf(MSG_INFO, "GnuTLS: Failed to get EKU");
  738. return 0;
  739. }
  740. wpa_printf(MSG_DEBUG, "GnuTLS: Certificate purpose: %s", oid);
  741. if (os_strcmp(oid, GNUTLS_KP_TLS_WWW_SERVER) == 0 ||
  742. os_strcmp(oid, GNUTLS_KP_ANY) == 0)
  743. return 1;
  744. }
  745. return 0;
  746. }
  747. #endif /* < 3.3.0 */
  748. static int check_ocsp(struct tls_connection *conn, gnutls_session_t session,
  749. gnutls_alert_description_t *err)
  750. {
  751. #if GNUTLS_VERSION_NUMBER >= 0x030103
  752. gnutls_datum_t response, buf;
  753. gnutls_ocsp_resp_t resp;
  754. unsigned int cert_status;
  755. int res;
  756. if (!(conn->flags & (TLS_CONN_REQUEST_OCSP | TLS_CONN_REQUIRE_OCSP)))
  757. return 0;
  758. if (!gnutls_ocsp_status_request_is_checked(session, 0)) {
  759. if (conn->flags & TLS_CONN_REQUIRE_OCSP) {
  760. wpa_printf(MSG_INFO,
  761. "GnuTLS: No valid OCSP response received");
  762. goto ocsp_error;
  763. }
  764. wpa_printf(MSG_DEBUG,
  765. "GnuTLS: Valid OCSP response was not received - continue since OCSP was not required");
  766. return 0;
  767. }
  768. /*
  769. * GnuTLS has already verified the OCSP response in
  770. * check_ocsp_response() and rejected handshake if the certificate was
  771. * found to be revoked. However, if the response indicates that the
  772. * status is unknown, handshake continues and reaches here. We need to
  773. * re-import the OCSP response to check for unknown certificate status,
  774. * but we do not need to repeat gnutls_ocsp_resp_check_crt() and
  775. * gnutls_ocsp_resp_verify_direct() calls.
  776. */
  777. res = gnutls_ocsp_status_request_get(session, &response);
  778. if (res != GNUTLS_E_SUCCESS) {
  779. wpa_printf(MSG_INFO,
  780. "GnuTLS: OCSP response was received, but it was not valid");
  781. goto ocsp_error;
  782. }
  783. if (gnutls_ocsp_resp_init(&resp) != GNUTLS_E_SUCCESS)
  784. goto ocsp_error;
  785. res = gnutls_ocsp_resp_import(resp, &response);
  786. if (res != GNUTLS_E_SUCCESS) {
  787. wpa_printf(MSG_INFO,
  788. "GnuTLS: Could not parse received OCSP response: %s",
  789. gnutls_strerror(res));
  790. gnutls_ocsp_resp_deinit(resp);
  791. goto ocsp_error;
  792. }
  793. res = gnutls_ocsp_resp_print(resp, GNUTLS_OCSP_PRINT_FULL, &buf);
  794. if (res == GNUTLS_E_SUCCESS) {
  795. wpa_printf(MSG_DEBUG, "GnuTLS: %s", buf.data);
  796. gnutls_free(buf.data);
  797. }
  798. res = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL,
  799. NULL, &cert_status, NULL,
  800. NULL, NULL, NULL);
  801. gnutls_ocsp_resp_deinit(resp);
  802. if (res != GNUTLS_E_SUCCESS) {
  803. wpa_printf(MSG_INFO,
  804. "GnuTLS: Failed to extract OCSP information: %s",
  805. gnutls_strerror(res));
  806. goto ocsp_error;
  807. }
  808. if (cert_status == GNUTLS_OCSP_CERT_GOOD) {
  809. wpa_printf(MSG_DEBUG, "GnuTLS: OCSP cert status: good");
  810. } else if (cert_status == GNUTLS_OCSP_CERT_REVOKED) {
  811. wpa_printf(MSG_DEBUG,
  812. "GnuTLS: OCSP cert status: revoked");
  813. goto ocsp_error;
  814. } else {
  815. wpa_printf(MSG_DEBUG,
  816. "GnuTLS: OCSP cert status: unknown");
  817. if (conn->flags & TLS_CONN_REQUIRE_OCSP)
  818. goto ocsp_error;
  819. wpa_printf(MSG_DEBUG,
  820. "GnuTLS: OCSP was not required, so allow connection to continue");
  821. }
  822. return 0;
  823. ocsp_error:
  824. gnutls_tls_fail_event(conn, NULL, 0, NULL,
  825. "bad certificate status response",
  826. TLS_FAIL_REVOKED);
  827. *err = GNUTLS_A_CERTIFICATE_REVOKED;
  828. return -1;
  829. #else /* GnuTLS 3.1.3 or newer */
  830. return 0;
  831. #endif /* GnuTLS 3.1.3 or newer */
  832. }
  833. static int tls_connection_verify_peer(gnutls_session_t session)
  834. {
  835. struct tls_connection *conn;
  836. unsigned int status, num_certs, i;
  837. struct os_time now;
  838. const gnutls_datum_t *certs;
  839. gnutls_x509_crt_t cert;
  840. gnutls_alert_description_t err;
  841. int res;
  842. conn = gnutls_session_get_ptr(session);
  843. if (!conn->verify_peer) {
  844. wpa_printf(MSG_DEBUG,
  845. "GnuTLS: No peer certificate verification enabled");
  846. return 0;
  847. }
  848. wpa_printf(MSG_DEBUG, "GnuTSL: Verifying peer certificate");
  849. #if GNUTLS_VERSION_NUMBER >= 0x030300
  850. {
  851. gnutls_typed_vdata_st data[1];
  852. unsigned int elements = 0;
  853. os_memset(data, 0, sizeof(data));
  854. if (!conn->global->server) {
  855. data[elements].type = GNUTLS_DT_KEY_PURPOSE_OID;
  856. data[elements].data = (void *) GNUTLS_KP_TLS_WWW_SERVER;
  857. elements++;
  858. }
  859. res = gnutls_certificate_verify_peers(session, data, 1,
  860. &status);
  861. }
  862. #else /* < 3.3.0 */
  863. res = gnutls_certificate_verify_peers2(session, &status);
  864. #endif
  865. if (res < 0) {
  866. wpa_printf(MSG_INFO, "TLS: Failed to verify peer "
  867. "certificate chain");
  868. err = GNUTLS_A_INTERNAL_ERROR;
  869. goto out;
  870. }
  871. #if GNUTLS_VERSION_NUMBER >= 0x030104
  872. {
  873. gnutls_datum_t info;
  874. int ret, type;
  875. type = gnutls_certificate_type_get(session);
  876. ret = gnutls_certificate_verification_status_print(status, type,
  877. &info, 0);
  878. if (ret < 0) {
  879. wpa_printf(MSG_DEBUG,
  880. "GnuTLS: Failed to print verification status");
  881. err = GNUTLS_A_INTERNAL_ERROR;
  882. goto out;
  883. }
  884. wpa_printf(MSG_DEBUG, "GnuTLS: %s", info.data);
  885. gnutls_free(info.data);
  886. }
  887. #endif /* GnuTLS 3.1.4 or newer */
  888. certs = gnutls_certificate_get_peers(session, &num_certs);
  889. if (certs == NULL || num_certs == 0) {
  890. wpa_printf(MSG_INFO, "TLS: No peer certificate chain received");
  891. err = GNUTLS_A_UNKNOWN_CA;
  892. goto out;
  893. }
  894. if (conn->verify_peer && (status & GNUTLS_CERT_INVALID)) {
  895. wpa_printf(MSG_INFO, "TLS: Peer certificate not trusted");
  896. if (status & GNUTLS_CERT_INSECURE_ALGORITHM) {
  897. wpa_printf(MSG_INFO, "TLS: Certificate uses insecure "
  898. "algorithm");
  899. gnutls_tls_fail_event(conn, NULL, 0, NULL,
  900. "certificate uses insecure algorithm",
  901. TLS_FAIL_BAD_CERTIFICATE);
  902. err = GNUTLS_A_INSUFFICIENT_SECURITY;
  903. goto out;
  904. }
  905. if (status & GNUTLS_CERT_NOT_ACTIVATED) {
  906. wpa_printf(MSG_INFO, "TLS: Certificate not yet "
  907. "activated");
  908. gnutls_tls_fail_event(conn, NULL, 0, NULL,
  909. "certificate not yet valid",
  910. TLS_FAIL_NOT_YET_VALID);
  911. err = GNUTLS_A_CERTIFICATE_EXPIRED;
  912. goto out;
  913. }
  914. if (status & GNUTLS_CERT_EXPIRED) {
  915. wpa_printf(MSG_INFO, "TLS: Certificate expired");
  916. gnutls_tls_fail_event(conn, NULL, 0, NULL,
  917. "certificate has expired",
  918. TLS_FAIL_EXPIRED);
  919. err = GNUTLS_A_CERTIFICATE_EXPIRED;
  920. goto out;
  921. }
  922. gnutls_tls_fail_event(conn, NULL, 0, NULL,
  923. "untrusted certificate",
  924. TLS_FAIL_UNTRUSTED);
  925. err = GNUTLS_A_INTERNAL_ERROR;
  926. goto out;
  927. }
  928. if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) {
  929. wpa_printf(MSG_INFO, "TLS: Peer certificate does not have a "
  930. "known issuer");
  931. gnutls_tls_fail_event(conn, NULL, 0, NULL, "signed not found",
  932. TLS_FAIL_UNTRUSTED);
  933. err = GNUTLS_A_UNKNOWN_CA;
  934. goto out;
  935. }
  936. if (status & GNUTLS_CERT_REVOKED) {
  937. wpa_printf(MSG_INFO, "TLS: Peer certificate has been revoked");
  938. gnutls_tls_fail_event(conn, NULL, 0, NULL,
  939. "certificate revoked",
  940. TLS_FAIL_REVOKED);
  941. err = GNUTLS_A_CERTIFICATE_REVOKED;
  942. goto out;
  943. }
  944. if (status != 0) {
  945. wpa_printf(MSG_INFO, "TLS: Unknown verification status: %d",
  946. status);
  947. err = GNUTLS_A_INTERNAL_ERROR;
  948. goto out;
  949. }
  950. if (check_ocsp(conn, session, &err))
  951. goto out;
  952. os_get_time(&now);
  953. for (i = 0; i < num_certs; i++) {
  954. char *buf;
  955. size_t len;
  956. if (gnutls_x509_crt_init(&cert) < 0) {
  957. wpa_printf(MSG_INFO, "TLS: Certificate initialization "
  958. "failed");
  959. err = GNUTLS_A_BAD_CERTIFICATE;
  960. goto out;
  961. }
  962. if (gnutls_x509_crt_import(cert, &certs[i],
  963. GNUTLS_X509_FMT_DER) < 0) {
  964. wpa_printf(MSG_INFO, "TLS: Could not parse peer "
  965. "certificate %d/%d", i + 1, num_certs);
  966. gnutls_x509_crt_deinit(cert);
  967. err = GNUTLS_A_BAD_CERTIFICATE;
  968. goto out;
  969. }
  970. gnutls_x509_crt_get_dn(cert, NULL, &len);
  971. len++;
  972. buf = os_malloc(len + 1);
  973. if (buf) {
  974. buf[0] = buf[len] = '\0';
  975. gnutls_x509_crt_get_dn(cert, buf, &len);
  976. }
  977. wpa_printf(MSG_DEBUG, "TLS: Peer cert chain %d/%d: %s",
  978. i + 1, num_certs, buf);
  979. if (conn->global->event_cb) {
  980. struct wpabuf *cert_buf = NULL;
  981. union tls_event_data ev;
  982. #ifdef CONFIG_SHA256
  983. u8 hash[32];
  984. const u8 *_addr[1];
  985. size_t _len[1];
  986. #endif /* CONFIG_SHA256 */
  987. os_memset(&ev, 0, sizeof(ev));
  988. if (conn->global->cert_in_cb) {
  989. cert_buf = wpabuf_alloc_copy(certs[i].data,
  990. certs[i].size);
  991. ev.peer_cert.cert = cert_buf;
  992. }
  993. #ifdef CONFIG_SHA256
  994. _addr[0] = certs[i].data;
  995. _len[0] = certs[i].size;
  996. if (sha256_vector(1, _addr, _len, hash) == 0) {
  997. ev.peer_cert.hash = hash;
  998. ev.peer_cert.hash_len = sizeof(hash);
  999. }
  1000. #endif /* CONFIG_SHA256 */
  1001. ev.peer_cert.depth = i;
  1002. ev.peer_cert.subject = buf;
  1003. conn->global->event_cb(conn->global->cb_ctx,
  1004. TLS_PEER_CERTIFICATE, &ev);
  1005. wpabuf_free(cert_buf);
  1006. }
  1007. if (i == 0) {
  1008. if (conn->suffix_match &&
  1009. !gnutls_x509_crt_check_hostname(
  1010. cert, conn->suffix_match)) {
  1011. wpa_printf(MSG_WARNING,
  1012. "TLS: Domain suffix match '%s' not found",
  1013. conn->suffix_match);
  1014. gnutls_tls_fail_event(
  1015. conn, &certs[i], i, buf,
  1016. "Domain suffix mismatch",
  1017. TLS_FAIL_DOMAIN_SUFFIX_MISMATCH);
  1018. err = GNUTLS_A_BAD_CERTIFICATE;
  1019. gnutls_x509_crt_deinit(cert);
  1020. os_free(buf);
  1021. goto out;
  1022. }
  1023. #if GNUTLS_VERSION_NUMBER >= 0x030300
  1024. if (conn->domain_match &&
  1025. !gnutls_x509_crt_check_hostname2(
  1026. cert, conn->domain_match,
  1027. GNUTLS_VERIFY_DO_NOT_ALLOW_WILDCARDS)) {
  1028. wpa_printf(MSG_WARNING,
  1029. "TLS: Domain match '%s' not found",
  1030. conn->domain_match);
  1031. gnutls_tls_fail_event(
  1032. conn, &certs[i], i, buf,
  1033. "Domain mismatch",
  1034. TLS_FAIL_DOMAIN_MISMATCH);
  1035. err = GNUTLS_A_BAD_CERTIFICATE;
  1036. gnutls_x509_crt_deinit(cert);
  1037. os_free(buf);
  1038. goto out;
  1039. }
  1040. #endif /* >= 3.3.0 */
  1041. /* TODO: validate altsubject_match.
  1042. * For now, any such configuration is rejected in
  1043. * tls_connection_set_params() */
  1044. #if GNUTLS_VERSION_NUMBER < 0x030300
  1045. /*
  1046. * gnutls_certificate_verify_peers() not available, so
  1047. * need to check EKU separately.
  1048. */
  1049. if (!conn->global->server &&
  1050. !server_eku_purpose(cert)) {
  1051. wpa_printf(MSG_WARNING,
  1052. "GnuTLS: No server EKU");
  1053. gnutls_tls_fail_event(
  1054. conn, &certs[i], i, buf,
  1055. "No server EKU",
  1056. TLS_FAIL_BAD_CERTIFICATE);
  1057. err = GNUTLS_A_BAD_CERTIFICATE;
  1058. gnutls_x509_crt_deinit(cert);
  1059. os_free(buf);
  1060. goto out;
  1061. }
  1062. #endif /* < 3.3.0 */
  1063. }
  1064. if (!conn->disable_time_checks &&
  1065. (gnutls_x509_crt_get_expiration_time(cert) < now.sec ||
  1066. gnutls_x509_crt_get_activation_time(cert) > now.sec)) {
  1067. wpa_printf(MSG_INFO, "TLS: Peer certificate %d/%d is "
  1068. "not valid at this time",
  1069. i + 1, num_certs);
  1070. gnutls_tls_fail_event(
  1071. conn, &certs[i], i, buf,
  1072. "Certificate is not valid at this time",
  1073. TLS_FAIL_EXPIRED);
  1074. gnutls_x509_crt_deinit(cert);
  1075. os_free(buf);
  1076. err = GNUTLS_A_CERTIFICATE_EXPIRED;
  1077. goto out;
  1078. }
  1079. os_free(buf);
  1080. gnutls_x509_crt_deinit(cert);
  1081. }
  1082. if (conn->global->event_cb != NULL)
  1083. conn->global->event_cb(conn->global->cb_ctx,
  1084. TLS_CERT_CHAIN_SUCCESS, NULL);
  1085. return 0;
  1086. out:
  1087. conn->failed++;
  1088. gnutls_alert_send(session, GNUTLS_AL_FATAL, err);
  1089. return GNUTLS_E_CERTIFICATE_ERROR;
  1090. }
  1091. static struct wpabuf * gnutls_get_appl_data(struct tls_connection *conn)
  1092. {
  1093. int res;
  1094. struct wpabuf *ad;
  1095. wpa_printf(MSG_DEBUG, "GnuTLS: Check for possible Application Data");
  1096. ad = wpabuf_alloc((wpabuf_len(conn->pull_buf) + 500) * 3);
  1097. if (ad == NULL)
  1098. return NULL;
  1099. res = gnutls_record_recv(conn->session, wpabuf_mhead(ad),
  1100. wpabuf_size(ad));
  1101. wpa_printf(MSG_DEBUG, "GnuTLS: gnutls_record_recv: %d", res);
  1102. if (res < 0) {
  1103. wpa_printf(MSG_DEBUG, "%s - gnutls_record_recv failed: %d "
  1104. "(%s)", __func__, (int) res,
  1105. gnutls_strerror(res));
  1106. wpabuf_free(ad);
  1107. return NULL;
  1108. }
  1109. wpabuf_put(ad, res);
  1110. wpa_printf(MSG_DEBUG, "GnuTLS: Received %d bytes of Application Data",
  1111. res);
  1112. return ad;
  1113. }
  1114. struct wpabuf * tls_connection_handshake(void *tls_ctx,
  1115. struct tls_connection *conn,
  1116. const struct wpabuf *in_data,
  1117. struct wpabuf **appl_data)
  1118. {
  1119. struct tls_global *global = tls_ctx;
  1120. struct wpabuf *out_data;
  1121. int ret;
  1122. if (appl_data)
  1123. *appl_data = NULL;
  1124. if (in_data && wpabuf_len(in_data) > 0) {
  1125. if (conn->pull_buf) {
  1126. wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in "
  1127. "pull_buf", __func__,
  1128. (unsigned long) wpabuf_len(conn->pull_buf));
  1129. wpabuf_free(conn->pull_buf);
  1130. }
  1131. conn->pull_buf = wpabuf_dup(in_data);
  1132. if (conn->pull_buf == NULL)
  1133. return NULL;
  1134. conn->pull_buf_offset = wpabuf_head(conn->pull_buf);
  1135. }
  1136. ret = gnutls_handshake(conn->session);
  1137. if (ret < 0) {
  1138. gnutls_alert_description_t alert;
  1139. switch (ret) {
  1140. case GNUTLS_E_AGAIN:
  1141. if (global->server && conn->established &&
  1142. conn->push_buf == NULL) {
  1143. /* Need to return something to trigger
  1144. * completion of EAP-TLS. */
  1145. conn->push_buf = wpabuf_alloc(0);
  1146. }
  1147. break;
  1148. case GNUTLS_E_FATAL_ALERT_RECEIVED:
  1149. alert = gnutls_alert_get(conn->session);
  1150. wpa_printf(MSG_DEBUG, "%s - received fatal '%s' alert",
  1151. __func__, gnutls_alert_get_name(alert));
  1152. conn->read_alerts++;
  1153. if (conn->global->event_cb != NULL) {
  1154. union tls_event_data ev;
  1155. os_memset(&ev, 0, sizeof(ev));
  1156. ev.alert.is_local = 0;
  1157. ev.alert.type = gnutls_alert_get_name(alert);
  1158. ev.alert.description = ev.alert.type;
  1159. conn->global->event_cb(conn->global->cb_ctx,
  1160. TLS_ALERT, &ev);
  1161. }
  1162. /* continue */
  1163. default:
  1164. wpa_printf(MSG_DEBUG, "%s - gnutls_handshake failed "
  1165. "-> %s", __func__, gnutls_strerror(ret));
  1166. conn->failed++;
  1167. }
  1168. } else {
  1169. size_t size;
  1170. wpa_printf(MSG_DEBUG, "TLS: Handshake completed successfully");
  1171. #if GNUTLS_VERSION_NUMBER >= 0x03010a
  1172. {
  1173. char *desc;
  1174. desc = gnutls_session_get_desc(conn->session);
  1175. if (desc) {
  1176. wpa_printf(MSG_DEBUG, "GnuTLS: %s", desc);
  1177. gnutls_free(desc);
  1178. }
  1179. }
  1180. #endif /* GnuTLS 3.1.10 or newer */
  1181. conn->established = 1;
  1182. if (conn->push_buf == NULL) {
  1183. /* Need to return something to get final TLS ACK. */
  1184. conn->push_buf = wpabuf_alloc(0);
  1185. }
  1186. gnutls_session_get_data(conn->session, NULL, &size);
  1187. if (global->session_data == NULL ||
  1188. global->session_data_size < size) {
  1189. os_free(global->session_data);
  1190. global->session_data = os_malloc(size);
  1191. }
  1192. if (global->session_data) {
  1193. global->session_data_size = size;
  1194. gnutls_session_get_data(conn->session,
  1195. global->session_data,
  1196. &global->session_data_size);
  1197. }
  1198. if (conn->pull_buf && appl_data)
  1199. *appl_data = gnutls_get_appl_data(conn);
  1200. }
  1201. out_data = conn->push_buf;
  1202. conn->push_buf = NULL;
  1203. return out_data;
  1204. }
  1205. struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
  1206. struct tls_connection *conn,
  1207. const struct wpabuf *in_data,
  1208. struct wpabuf **appl_data)
  1209. {
  1210. return tls_connection_handshake(tls_ctx, conn, in_data, appl_data);
  1211. }
  1212. struct wpabuf * tls_connection_encrypt(void *tls_ctx,
  1213. struct tls_connection *conn,
  1214. const struct wpabuf *in_data)
  1215. {
  1216. ssize_t res;
  1217. struct wpabuf *buf;
  1218. res = gnutls_record_send(conn->session, wpabuf_head(in_data),
  1219. wpabuf_len(in_data));
  1220. if (res < 0) {
  1221. wpa_printf(MSG_INFO, "%s: Encryption failed: %s",
  1222. __func__, gnutls_strerror(res));
  1223. return NULL;
  1224. }
  1225. buf = conn->push_buf;
  1226. conn->push_buf = NULL;
  1227. return buf;
  1228. }
  1229. struct wpabuf * tls_connection_decrypt(void *tls_ctx,
  1230. struct tls_connection *conn,
  1231. const struct wpabuf *in_data)
  1232. {
  1233. ssize_t res;
  1234. struct wpabuf *out;
  1235. if (conn->pull_buf) {
  1236. wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in "
  1237. "pull_buf", __func__,
  1238. (unsigned long) wpabuf_len(conn->pull_buf));
  1239. wpabuf_free(conn->pull_buf);
  1240. }
  1241. conn->pull_buf = wpabuf_dup(in_data);
  1242. if (conn->pull_buf == NULL)
  1243. return NULL;
  1244. conn->pull_buf_offset = wpabuf_head(conn->pull_buf);
  1245. /*
  1246. * Even though we try to disable TLS compression, it is possible that
  1247. * this cannot be done with all TLS libraries. Add extra buffer space
  1248. * to handle the possibility of the decrypted data being longer than
  1249. * input data.
  1250. */
  1251. out = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
  1252. if (out == NULL)
  1253. return NULL;
  1254. res = gnutls_record_recv(conn->session, wpabuf_mhead(out),
  1255. wpabuf_size(out));
  1256. if (res < 0) {
  1257. wpa_printf(MSG_DEBUG, "%s - gnutls_record_recv failed: %d "
  1258. "(%s)", __func__, (int) res, gnutls_strerror(res));
  1259. wpabuf_free(out);
  1260. return NULL;
  1261. }
  1262. wpabuf_put(out, res);
  1263. return out;
  1264. }
  1265. int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn)
  1266. {
  1267. if (conn == NULL)
  1268. return 0;
  1269. return gnutls_session_is_resumed(conn->session);
  1270. }
  1271. int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
  1272. u8 *ciphers)
  1273. {
  1274. /* TODO */
  1275. return -1;
  1276. }
  1277. int tls_get_version(void *ssl_ctx, struct tls_connection *conn,
  1278. char *buf, size_t buflen)
  1279. {
  1280. /* TODO */
  1281. return -1;
  1282. }
  1283. int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn,
  1284. char *buf, size_t buflen)
  1285. {
  1286. /* TODO */
  1287. buf[0] = '\0';
  1288. return 0;
  1289. }
  1290. int tls_connection_enable_workaround(void *ssl_ctx,
  1291. struct tls_connection *conn)
  1292. {
  1293. gnutls_record_disable_padding(conn->session);
  1294. return 0;
  1295. }
  1296. int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
  1297. int ext_type, const u8 *data,
  1298. size_t data_len)
  1299. {
  1300. /* TODO */
  1301. return -1;
  1302. }
  1303. int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn)
  1304. {
  1305. if (conn == NULL)
  1306. return -1;
  1307. return conn->failed;
  1308. }
  1309. int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn)
  1310. {
  1311. if (conn == NULL)
  1312. return -1;
  1313. return conn->read_alerts;
  1314. }
  1315. int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn)
  1316. {
  1317. if (conn == NULL)
  1318. return -1;
  1319. return conn->write_alerts;
  1320. }
  1321. int tls_connection_set_session_ticket_cb(void *tls_ctx,
  1322. struct tls_connection *conn,
  1323. tls_session_ticket_cb cb, void *ctx)
  1324. {
  1325. return -1;
  1326. }
  1327. int tls_get_library_version(char *buf, size_t buf_len)
  1328. {
  1329. return os_snprintf(buf, buf_len, "GnuTLS build=%s run=%s",
  1330. GNUTLS_VERSION, gnutls_check_version(NULL));
  1331. }
  1332. void tls_connection_set_success_data(struct tls_connection *conn,
  1333. struct wpabuf *data)
  1334. {
  1335. }
  1336. void tls_connection_set_success_data_resumed(struct tls_connection *conn)
  1337. {
  1338. }
  1339. const struct wpabuf *
  1340. tls_connection_get_success_data(struct tls_connection *conn)
  1341. {
  1342. return NULL;
  1343. }
  1344. void tls_connection_remove_session(struct tls_connection *conn)
  1345. {
  1346. }