tls_gnutls.c 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717
  1. /*
  2. * SSL/TLS interface functions for GnuTLS
  3. * Copyright (c) 2004-2017, 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. const char *err;
  280. char prio_buf[100];
  281. const char *prio = NULL;
  282. if (conn == NULL || params == NULL)
  283. return -1;
  284. if (params->flags & TLS_CONN_REQUIRE_OCSP_ALL) {
  285. wpa_printf(MSG_INFO,
  286. "GnuTLS: ocsp=3 not supported");
  287. return -1;
  288. }
  289. if (params->flags & TLS_CONN_EXT_CERT_CHECK) {
  290. wpa_printf(MSG_INFO,
  291. "GnuTLS: tls_ext_cert_check=1 not supported");
  292. return -1;
  293. }
  294. if (params->subject_match) {
  295. wpa_printf(MSG_INFO, "GnuTLS: subject_match not supported");
  296. return -1;
  297. }
  298. if (params->altsubject_match) {
  299. wpa_printf(MSG_INFO, "GnuTLS: altsubject_match not supported");
  300. return -1;
  301. }
  302. os_free(conn->suffix_match);
  303. conn->suffix_match = NULL;
  304. if (params->suffix_match) {
  305. conn->suffix_match = os_strdup(params->suffix_match);
  306. if (conn->suffix_match == NULL)
  307. return -1;
  308. }
  309. #if GNUTLS_VERSION_NUMBER >= 0x030300
  310. os_free(conn->domain_match);
  311. conn->domain_match = NULL;
  312. if (params->domain_match) {
  313. conn->domain_match = os_strdup(params->domain_match);
  314. if (conn->domain_match == NULL)
  315. return -1;
  316. }
  317. #else /* < 3.3.0 */
  318. if (params->domain_match) {
  319. wpa_printf(MSG_INFO, "GnuTLS: domain_match not supported");
  320. return -1;
  321. }
  322. #endif /* >= 3.3.0 */
  323. conn->flags = params->flags;
  324. if (params->flags & (TLS_CONN_DISABLE_TLSv1_0 |
  325. TLS_CONN_DISABLE_TLSv1_1 |
  326. TLS_CONN_DISABLE_TLSv1_2)) {
  327. os_snprintf(prio_buf, sizeof(prio_buf),
  328. "NORMAL:-VERS-SSL3.0%s%s%s",
  329. params->flags & TLS_CONN_DISABLE_TLSv1_0 ?
  330. ":-VERS-TLS1.0" : "",
  331. params->flags & TLS_CONN_DISABLE_TLSv1_1 ?
  332. ":-VERS-TLS1.1" : "",
  333. params->flags & TLS_CONN_DISABLE_TLSv1_2 ?
  334. ":-VERS-TLS1.2" : "");
  335. prio = prio_buf;
  336. }
  337. if (params->openssl_ciphers) {
  338. if (os_strcmp(params->openssl_ciphers, "SUITEB128") == 0) {
  339. prio = "SUITEB128";
  340. } else if (os_strcmp(params->openssl_ciphers,
  341. "SUITEB192") == 0) {
  342. prio = "SUITEB192";
  343. } else if ((params->flags & TLS_CONN_SUITEB) &&
  344. os_strcmp(params->openssl_ciphers,
  345. "ECDHE-RSA-AES256-GCM-SHA384") == 0) {
  346. prio = "NONE:+VERS-TLS1.2:+AEAD:+ECDHE-RSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL";
  347. } else if (os_strcmp(params->openssl_ciphers,
  348. "ECDHE-RSA-AES256-GCM-SHA384") == 0) {
  349. prio = "NONE:+VERS-TLS1.2:+AEAD:+ECDHE-RSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL";
  350. } else if (os_strcmp(params->openssl_ciphers,
  351. "DHE-RSA-AES256-GCM-SHA384") == 0) {
  352. prio = "NONE:+VERS-TLS1.2:+AEAD:+DHE-RSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL:%PROFILE_HIGH";
  353. } else if (os_strcmp(params->openssl_ciphers,
  354. "ECDHE-ECDSA-AES256-GCM-SHA384") == 0) {
  355. prio = "NONE:+VERS-TLS1.2:+AEAD:+ECDHE-ECDSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL";
  356. } else {
  357. wpa_printf(MSG_INFO,
  358. "GnuTLS: openssl_ciphers not supported");
  359. return -1;
  360. }
  361. } else if (params->flags & TLS_CONN_SUITEB) {
  362. prio = "NONE:+VERS-TLS1.2:+AEAD:+ECDHE-ECDSA:+ECDHE-RSA:+DHE-RSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL:%PROFILE_HIGH";
  363. }
  364. if (prio) {
  365. wpa_printf(MSG_DEBUG, "GnuTLS: Set priority string: %s", prio);
  366. ret = gnutls_priority_set_direct(conn->session, prio, &err);
  367. if (ret < 0) {
  368. wpa_printf(MSG_ERROR,
  369. "GnuTLS: Priority string failure at '%s'",
  370. err);
  371. return -1;
  372. }
  373. }
  374. /* TODO: gnutls_certificate_set_verify_flags(xcred, flags);
  375. * to force peer validation(?) */
  376. if (params->ca_cert) {
  377. wpa_printf(MSG_DEBUG, "GnuTLS: Try to parse %s in DER format",
  378. params->ca_cert);
  379. ret = gnutls_certificate_set_x509_trust_file(
  380. conn->xcred, params->ca_cert, GNUTLS_X509_FMT_DER);
  381. if (ret < 0) {
  382. wpa_printf(MSG_DEBUG,
  383. "GnuTLS: Failed to read CA cert '%s' in DER format (%s) - try in PEM format",
  384. params->ca_cert,
  385. gnutls_strerror(ret));
  386. ret = gnutls_certificate_set_x509_trust_file(
  387. conn->xcred, params->ca_cert,
  388. GNUTLS_X509_FMT_PEM);
  389. if (ret < 0) {
  390. wpa_printf(MSG_DEBUG,
  391. "Failed to read CA cert '%s' in PEM format: %s",
  392. params->ca_cert,
  393. gnutls_strerror(ret));
  394. return -1;
  395. }
  396. wpa_printf(MSG_DEBUG,
  397. "GnuTLS: Successfully read CA cert '%s' in PEM format",
  398. params->ca_cert);
  399. } else {
  400. wpa_printf(MSG_DEBUG,
  401. "GnuTLS: Successfully read CA cert '%s' in DER format",
  402. params->ca_cert);
  403. }
  404. } else if (params->ca_cert_blob) {
  405. gnutls_datum_t ca;
  406. ca.data = (unsigned char *) params->ca_cert_blob;
  407. ca.size = params->ca_cert_blob_len;
  408. ret = gnutls_certificate_set_x509_trust_mem(
  409. conn->xcred, &ca, GNUTLS_X509_FMT_DER);
  410. if (ret < 0) {
  411. wpa_printf(MSG_DEBUG,
  412. "Failed to parse CA cert in DER format: %s",
  413. gnutls_strerror(ret));
  414. ret = gnutls_certificate_set_x509_trust_mem(
  415. conn->xcred, &ca, GNUTLS_X509_FMT_PEM);
  416. if (ret < 0) {
  417. wpa_printf(MSG_DEBUG,
  418. "Failed to parse CA cert in PEM format: %s",
  419. gnutls_strerror(ret));
  420. return -1;
  421. }
  422. }
  423. } else if (params->ca_path) {
  424. wpa_printf(MSG_INFO, "GnuTLS: ca_path not supported");
  425. return -1;
  426. }
  427. conn->disable_time_checks = 0;
  428. if (params->ca_cert || params->ca_cert_blob) {
  429. conn->verify_peer = 1;
  430. gnutls_certificate_set_verify_function(
  431. conn->xcred, tls_connection_verify_peer);
  432. if (params->flags & TLS_CONN_ALLOW_SIGN_RSA_MD5) {
  433. gnutls_certificate_set_verify_flags(
  434. conn->xcred, GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5);
  435. }
  436. if (params->flags & TLS_CONN_DISABLE_TIME_CHECKS) {
  437. conn->disable_time_checks = 1;
  438. gnutls_certificate_set_verify_flags(
  439. conn->xcred,
  440. GNUTLS_VERIFY_DISABLE_TIME_CHECKS);
  441. }
  442. }
  443. if (params->client_cert && params->private_key) {
  444. wpa_printf(MSG_DEBUG,
  445. "GnuTLS: Try to parse client cert '%s' and key '%s' in DER format",
  446. params->client_cert, params->private_key);
  447. #if GNUTLS_VERSION_NUMBER >= 0x03010b
  448. ret = gnutls_certificate_set_x509_key_file2(
  449. conn->xcred, params->client_cert, params->private_key,
  450. GNUTLS_X509_FMT_DER, params->private_key_passwd, 0);
  451. #else
  452. /* private_key_passwd not (easily) supported here */
  453. ret = gnutls_certificate_set_x509_key_file(
  454. conn->xcred, params->client_cert, params->private_key,
  455. GNUTLS_X509_FMT_DER);
  456. #endif
  457. if (ret < 0) {
  458. wpa_printf(MSG_DEBUG,
  459. "GnuTLS: Failed to read client cert/key in DER format (%s) - try in PEM format",
  460. gnutls_strerror(ret));
  461. #if GNUTLS_VERSION_NUMBER >= 0x03010b
  462. ret = gnutls_certificate_set_x509_key_file2(
  463. conn->xcred, params->client_cert,
  464. params->private_key, GNUTLS_X509_FMT_PEM,
  465. params->private_key_passwd, 0);
  466. #else
  467. ret = gnutls_certificate_set_x509_key_file(
  468. conn->xcred, params->client_cert,
  469. params->private_key, GNUTLS_X509_FMT_PEM);
  470. #endif
  471. if (ret < 0) {
  472. wpa_printf(MSG_DEBUG, "Failed to read client "
  473. "cert/key in PEM format: %s",
  474. gnutls_strerror(ret));
  475. return ret;
  476. }
  477. wpa_printf(MSG_DEBUG,
  478. "GnuTLS: Successfully read client cert/key in PEM format");
  479. } else {
  480. wpa_printf(MSG_DEBUG,
  481. "GnuTLS: Successfully read client cert/key in DER format");
  482. }
  483. } else if (params->private_key) {
  484. int pkcs12_ok = 0;
  485. #ifdef PKCS12_FUNCS
  486. /* Try to load in PKCS#12 format */
  487. wpa_printf(MSG_DEBUG,
  488. "GnuTLS: Try to parse client cert/key '%s'in PKCS#12 DER format",
  489. params->private_key);
  490. ret = gnutls_certificate_set_x509_simple_pkcs12_file(
  491. conn->xcred, params->private_key, GNUTLS_X509_FMT_DER,
  492. params->private_key_passwd);
  493. if (ret != 0) {
  494. wpa_printf(MSG_DEBUG, "Failed to load private_key in "
  495. "PKCS#12 format: %s", gnutls_strerror(ret));
  496. return -1;
  497. } else
  498. pkcs12_ok = 1;
  499. #endif /* PKCS12_FUNCS */
  500. if (!pkcs12_ok) {
  501. wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not "
  502. "included");
  503. return -1;
  504. }
  505. } else if (params->client_cert_blob && params->private_key_blob) {
  506. gnutls_datum_t cert, key;
  507. cert.data = (unsigned char *) params->client_cert_blob;
  508. cert.size = params->client_cert_blob_len;
  509. key.data = (unsigned char *) params->private_key_blob;
  510. key.size = params->private_key_blob_len;
  511. #if GNUTLS_VERSION_NUMBER >= 0x03010b
  512. ret = gnutls_certificate_set_x509_key_mem2(
  513. conn->xcred, &cert, &key, GNUTLS_X509_FMT_DER,
  514. params->private_key_passwd, 0);
  515. #else
  516. /* private_key_passwd not (easily) supported here */
  517. ret = gnutls_certificate_set_x509_key_mem(
  518. conn->xcred, &cert, &key, GNUTLS_X509_FMT_DER);
  519. #endif
  520. if (ret < 0) {
  521. wpa_printf(MSG_DEBUG, "Failed to read client cert/key "
  522. "in DER format: %s", gnutls_strerror(ret));
  523. #if GNUTLS_VERSION_NUMBER >= 0x03010b
  524. ret = gnutls_certificate_set_x509_key_mem2(
  525. conn->xcred, &cert, &key, GNUTLS_X509_FMT_PEM,
  526. params->private_key_passwd, 0);
  527. #else
  528. /* private_key_passwd not (easily) supported here */
  529. ret = gnutls_certificate_set_x509_key_mem(
  530. conn->xcred, &cert, &key, GNUTLS_X509_FMT_PEM);
  531. #endif
  532. if (ret < 0) {
  533. wpa_printf(MSG_DEBUG, "Failed to read client "
  534. "cert/key in PEM format: %s",
  535. gnutls_strerror(ret));
  536. return ret;
  537. }
  538. }
  539. } else if (params->private_key_blob) {
  540. #ifdef PKCS12_FUNCS
  541. gnutls_datum_t key;
  542. key.data = (unsigned char *) params->private_key_blob;
  543. key.size = params->private_key_blob_len;
  544. /* Try to load in PKCS#12 format */
  545. ret = gnutls_certificate_set_x509_simple_pkcs12_mem(
  546. conn->xcred, &key, GNUTLS_X509_FMT_DER,
  547. params->private_key_passwd);
  548. if (ret != 0) {
  549. wpa_printf(MSG_DEBUG, "Failed to load private_key in "
  550. "PKCS#12 format: %s", gnutls_strerror(ret));
  551. return -1;
  552. }
  553. #else /* PKCS12_FUNCS */
  554. wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not included");
  555. return -1;
  556. #endif /* PKCS12_FUNCS */
  557. }
  558. #if GNUTLS_VERSION_NUMBER >= 0x030103
  559. if (params->flags & (TLS_CONN_REQUEST_OCSP | TLS_CONN_REQUIRE_OCSP)) {
  560. ret = gnutls_ocsp_status_request_enable_client(conn->session,
  561. NULL, 0, NULL);
  562. if (ret != GNUTLS_E_SUCCESS) {
  563. wpa_printf(MSG_INFO,
  564. "GnuTLS: Failed to enable OCSP client");
  565. return -1;
  566. }
  567. }
  568. #else /* 3.1.3 */
  569. if (params->flags & TLS_CONN_REQUIRE_OCSP) {
  570. wpa_printf(MSG_INFO,
  571. "GnuTLS: OCSP not supported by this version of GnuTLS");
  572. return -1;
  573. }
  574. #endif /* 3.1.3 */
  575. conn->params_set = 1;
  576. ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE,
  577. conn->xcred);
  578. if (ret < 0) {
  579. wpa_printf(MSG_INFO, "Failed to configure credentials: %s",
  580. gnutls_strerror(ret));
  581. }
  582. return ret;
  583. }
  584. #if GNUTLS_VERSION_NUMBER >= 0x030103
  585. static int server_ocsp_status_req(gnutls_session_t session, void *ptr,
  586. gnutls_datum_t *resp)
  587. {
  588. struct tls_global *global = ptr;
  589. char *cached;
  590. size_t len;
  591. if (!global->ocsp_stapling_response) {
  592. wpa_printf(MSG_DEBUG, "GnuTLS: OCSP status callback - no response configured");
  593. return GNUTLS_E_NO_CERTIFICATE_STATUS;
  594. }
  595. cached = os_readfile(global->ocsp_stapling_response, &len);
  596. if (!cached) {
  597. wpa_printf(MSG_DEBUG,
  598. "GnuTLS: OCSP status callback - could not read response file (%s)",
  599. global->ocsp_stapling_response);
  600. return GNUTLS_E_NO_CERTIFICATE_STATUS;
  601. }
  602. wpa_printf(MSG_DEBUG,
  603. "GnuTLS: OCSP status callback - send cached response");
  604. resp->data = gnutls_malloc(len);
  605. if (!resp->data) {
  606. os_free(resp);
  607. return GNUTLS_E_MEMORY_ERROR;
  608. }
  609. os_memcpy(resp->data, cached, len);
  610. resp->size = len;
  611. os_free(cached);
  612. return GNUTLS_E_SUCCESS;
  613. }
  614. #endif /* 3.1.3 */
  615. int tls_global_set_params(void *tls_ctx,
  616. const struct tls_connection_params *params)
  617. {
  618. struct tls_global *global = tls_ctx;
  619. int ret;
  620. /* Currently, global parameters are only set when running in server
  621. * mode. */
  622. global->server = 1;
  623. if (global->params_set) {
  624. gnutls_certificate_free_credentials(global->xcred);
  625. global->params_set = 0;
  626. }
  627. ret = gnutls_certificate_allocate_credentials(&global->xcred);
  628. if (ret) {
  629. wpa_printf(MSG_DEBUG, "Failed to allocate global credentials "
  630. "%s", gnutls_strerror(ret));
  631. return -1;
  632. }
  633. if (params->ca_cert) {
  634. ret = gnutls_certificate_set_x509_trust_file(
  635. global->xcred, params->ca_cert, GNUTLS_X509_FMT_DER);
  636. if (ret < 0) {
  637. wpa_printf(MSG_DEBUG, "Failed to read CA cert '%s' "
  638. "in DER format: %s", params->ca_cert,
  639. gnutls_strerror(ret));
  640. ret = gnutls_certificate_set_x509_trust_file(
  641. global->xcred, params->ca_cert,
  642. GNUTLS_X509_FMT_PEM);
  643. if (ret < 0) {
  644. wpa_printf(MSG_DEBUG, "Failed to read CA cert "
  645. "'%s' in PEM format: %s",
  646. params->ca_cert,
  647. gnutls_strerror(ret));
  648. goto fail;
  649. }
  650. }
  651. if (params->flags & TLS_CONN_ALLOW_SIGN_RSA_MD5) {
  652. gnutls_certificate_set_verify_flags(
  653. global->xcred,
  654. GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5);
  655. }
  656. if (params->flags & TLS_CONN_DISABLE_TIME_CHECKS) {
  657. gnutls_certificate_set_verify_flags(
  658. global->xcred,
  659. GNUTLS_VERIFY_DISABLE_TIME_CHECKS);
  660. }
  661. }
  662. if (params->client_cert && params->private_key) {
  663. /* TODO: private_key_passwd? */
  664. ret = gnutls_certificate_set_x509_key_file(
  665. global->xcred, params->client_cert,
  666. params->private_key, GNUTLS_X509_FMT_DER);
  667. if (ret < 0) {
  668. wpa_printf(MSG_DEBUG, "Failed to read client cert/key "
  669. "in DER format: %s", gnutls_strerror(ret));
  670. ret = gnutls_certificate_set_x509_key_file(
  671. global->xcred, params->client_cert,
  672. params->private_key, GNUTLS_X509_FMT_PEM);
  673. if (ret < 0) {
  674. wpa_printf(MSG_DEBUG, "Failed to read client "
  675. "cert/key in PEM format: %s",
  676. gnutls_strerror(ret));
  677. goto fail;
  678. }
  679. }
  680. } else if (params->private_key) {
  681. int pkcs12_ok = 0;
  682. #ifdef PKCS12_FUNCS
  683. /* Try to load in PKCS#12 format */
  684. ret = gnutls_certificate_set_x509_simple_pkcs12_file(
  685. global->xcred, params->private_key,
  686. GNUTLS_X509_FMT_DER, params->private_key_passwd);
  687. if (ret != 0) {
  688. wpa_printf(MSG_DEBUG, "Failed to load private_key in "
  689. "PKCS#12 format: %s", gnutls_strerror(ret));
  690. goto fail;
  691. } else
  692. pkcs12_ok = 1;
  693. #endif /* PKCS12_FUNCS */
  694. if (!pkcs12_ok) {
  695. wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not "
  696. "included");
  697. goto fail;
  698. }
  699. }
  700. #if GNUTLS_VERSION_NUMBER >= 0x030103
  701. os_free(global->ocsp_stapling_response);
  702. if (params->ocsp_stapling_response)
  703. global->ocsp_stapling_response =
  704. os_strdup(params->ocsp_stapling_response);
  705. else
  706. global->ocsp_stapling_response = NULL;
  707. gnutls_certificate_set_ocsp_status_request_function(
  708. global->xcred, server_ocsp_status_req, global);
  709. #endif /* 3.1.3 */
  710. global->params_set = 1;
  711. return 0;
  712. fail:
  713. gnutls_certificate_free_credentials(global->xcred);
  714. return -1;
  715. }
  716. int tls_global_set_verify(void *ssl_ctx, int check_crl)
  717. {
  718. /* TODO */
  719. return 0;
  720. }
  721. int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
  722. int verify_peer, unsigned int flags,
  723. const u8 *session_ctx, size_t session_ctx_len)
  724. {
  725. if (conn == NULL || conn->session == NULL)
  726. return -1;
  727. conn->verify_peer = verify_peer;
  728. gnutls_certificate_server_set_request(conn->session,
  729. verify_peer ? GNUTLS_CERT_REQUIRE
  730. : GNUTLS_CERT_REQUEST);
  731. return 0;
  732. }
  733. int tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn,
  734. struct tls_random *keys)
  735. {
  736. #if GNUTLS_VERSION_NUMBER >= 0x030012
  737. gnutls_datum_t client, server;
  738. if (conn == NULL || conn->session == NULL || keys == NULL)
  739. return -1;
  740. os_memset(keys, 0, sizeof(*keys));
  741. gnutls_session_get_random(conn->session, &client, &server);
  742. keys->client_random = client.data;
  743. keys->server_random = server.data;
  744. keys->client_random_len = client.size;
  745. keys->server_random_len = client.size;
  746. return 0;
  747. #else /* 3.0.18 */
  748. return -1;
  749. #endif /* 3.0.18 */
  750. }
  751. int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
  752. const char *label, u8 *out, size_t out_len)
  753. {
  754. if (conn == NULL || conn->session == NULL)
  755. return -1;
  756. return gnutls_prf(conn->session, os_strlen(label), label,
  757. 0 /* client_random first */, 0, NULL, out_len,
  758. (char *) out);
  759. }
  760. int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn,
  761. u8 *out, size_t out_len)
  762. {
  763. return -1;
  764. }
  765. static void gnutls_tls_fail_event(struct tls_connection *conn,
  766. const gnutls_datum_t *cert, int depth,
  767. const char *subject, const char *err_str,
  768. enum tls_fail_reason reason)
  769. {
  770. union tls_event_data ev;
  771. struct tls_global *global = conn->global;
  772. struct wpabuf *cert_buf = NULL;
  773. if (global->event_cb == NULL)
  774. return;
  775. os_memset(&ev, 0, sizeof(ev));
  776. ev.cert_fail.depth = depth;
  777. ev.cert_fail.subject = subject ? subject : "";
  778. ev.cert_fail.reason = reason;
  779. ev.cert_fail.reason_txt = err_str;
  780. if (cert) {
  781. cert_buf = wpabuf_alloc_copy(cert->data, cert->size);
  782. ev.cert_fail.cert = cert_buf;
  783. }
  784. global->event_cb(global->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev);
  785. wpabuf_free(cert_buf);
  786. }
  787. #if GNUTLS_VERSION_NUMBER < 0x030300
  788. static int server_eku_purpose(gnutls_x509_crt_t cert)
  789. {
  790. unsigned int i;
  791. for (i = 0; ; i++) {
  792. char oid[128];
  793. size_t oid_size = sizeof(oid);
  794. int res;
  795. res = gnutls_x509_crt_get_key_purpose_oid(cert, i, oid,
  796. &oid_size, NULL);
  797. if (res == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
  798. if (i == 0) {
  799. /* No EKU - assume any use allowed */
  800. return 1;
  801. }
  802. break;
  803. }
  804. if (res < 0) {
  805. wpa_printf(MSG_INFO, "GnuTLS: Failed to get EKU");
  806. return 0;
  807. }
  808. wpa_printf(MSG_DEBUG, "GnuTLS: Certificate purpose: %s", oid);
  809. if (os_strcmp(oid, GNUTLS_KP_TLS_WWW_SERVER) == 0 ||
  810. os_strcmp(oid, GNUTLS_KP_ANY) == 0)
  811. return 1;
  812. }
  813. return 0;
  814. }
  815. #endif /* < 3.3.0 */
  816. static int check_ocsp(struct tls_connection *conn, gnutls_session_t session,
  817. gnutls_alert_description_t *err)
  818. {
  819. #if GNUTLS_VERSION_NUMBER >= 0x030103
  820. gnutls_datum_t response, buf;
  821. gnutls_ocsp_resp_t resp;
  822. unsigned int cert_status;
  823. int res;
  824. if (!(conn->flags & (TLS_CONN_REQUEST_OCSP | TLS_CONN_REQUIRE_OCSP)))
  825. return 0;
  826. if (!gnutls_ocsp_status_request_is_checked(session, 0)) {
  827. if (conn->flags & TLS_CONN_REQUIRE_OCSP) {
  828. wpa_printf(MSG_INFO,
  829. "GnuTLS: No valid OCSP response received");
  830. goto ocsp_error;
  831. }
  832. wpa_printf(MSG_DEBUG,
  833. "GnuTLS: Valid OCSP response was not received - continue since OCSP was not required");
  834. return 0;
  835. }
  836. /*
  837. * GnuTLS has already verified the OCSP response in
  838. * check_ocsp_response() and rejected handshake if the certificate was
  839. * found to be revoked. However, if the response indicates that the
  840. * status is unknown, handshake continues and reaches here. We need to
  841. * re-import the OCSP response to check for unknown certificate status,
  842. * but we do not need to repeat gnutls_ocsp_resp_check_crt() and
  843. * gnutls_ocsp_resp_verify_direct() calls.
  844. */
  845. res = gnutls_ocsp_status_request_get(session, &response);
  846. if (res != GNUTLS_E_SUCCESS) {
  847. wpa_printf(MSG_INFO,
  848. "GnuTLS: OCSP response was received, but it was not valid");
  849. goto ocsp_error;
  850. }
  851. if (gnutls_ocsp_resp_init(&resp) != GNUTLS_E_SUCCESS)
  852. goto ocsp_error;
  853. res = gnutls_ocsp_resp_import(resp, &response);
  854. if (res != GNUTLS_E_SUCCESS) {
  855. wpa_printf(MSG_INFO,
  856. "GnuTLS: Could not parse received OCSP response: %s",
  857. gnutls_strerror(res));
  858. gnutls_ocsp_resp_deinit(resp);
  859. goto ocsp_error;
  860. }
  861. res = gnutls_ocsp_resp_print(resp, GNUTLS_OCSP_PRINT_FULL, &buf);
  862. if (res == GNUTLS_E_SUCCESS) {
  863. wpa_printf(MSG_DEBUG, "GnuTLS: %s", buf.data);
  864. gnutls_free(buf.data);
  865. }
  866. res = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL,
  867. NULL, &cert_status, NULL,
  868. NULL, NULL, NULL);
  869. gnutls_ocsp_resp_deinit(resp);
  870. if (res != GNUTLS_E_SUCCESS) {
  871. wpa_printf(MSG_INFO,
  872. "GnuTLS: Failed to extract OCSP information: %s",
  873. gnutls_strerror(res));
  874. goto ocsp_error;
  875. }
  876. if (cert_status == GNUTLS_OCSP_CERT_GOOD) {
  877. wpa_printf(MSG_DEBUG, "GnuTLS: OCSP cert status: good");
  878. } else if (cert_status == GNUTLS_OCSP_CERT_REVOKED) {
  879. wpa_printf(MSG_DEBUG,
  880. "GnuTLS: OCSP cert status: revoked");
  881. goto ocsp_error;
  882. } else {
  883. wpa_printf(MSG_DEBUG,
  884. "GnuTLS: OCSP cert status: unknown");
  885. if (conn->flags & TLS_CONN_REQUIRE_OCSP)
  886. goto ocsp_error;
  887. wpa_printf(MSG_DEBUG,
  888. "GnuTLS: OCSP was not required, so allow connection to continue");
  889. }
  890. return 0;
  891. ocsp_error:
  892. gnutls_tls_fail_event(conn, NULL, 0, NULL,
  893. "bad certificate status response",
  894. TLS_FAIL_REVOKED);
  895. *err = GNUTLS_A_CERTIFICATE_REVOKED;
  896. return -1;
  897. #else /* GnuTLS 3.1.3 or newer */
  898. return 0;
  899. #endif /* GnuTLS 3.1.3 or newer */
  900. }
  901. static int tls_connection_verify_peer(gnutls_session_t session)
  902. {
  903. struct tls_connection *conn;
  904. unsigned int status, num_certs, i;
  905. struct os_time now;
  906. const gnutls_datum_t *certs;
  907. gnutls_x509_crt_t cert;
  908. gnutls_alert_description_t err;
  909. int res;
  910. conn = gnutls_session_get_ptr(session);
  911. if (!conn->verify_peer) {
  912. wpa_printf(MSG_DEBUG,
  913. "GnuTLS: No peer certificate verification enabled");
  914. return 0;
  915. }
  916. wpa_printf(MSG_DEBUG, "GnuTSL: Verifying peer certificate");
  917. #if GNUTLS_VERSION_NUMBER >= 0x030300
  918. {
  919. gnutls_typed_vdata_st data[1];
  920. unsigned int elements = 0;
  921. os_memset(data, 0, sizeof(data));
  922. if (!conn->global->server) {
  923. data[elements].type = GNUTLS_DT_KEY_PURPOSE_OID;
  924. data[elements].data = (void *) GNUTLS_KP_TLS_WWW_SERVER;
  925. elements++;
  926. }
  927. res = gnutls_certificate_verify_peers(session, data, 1,
  928. &status);
  929. }
  930. #else /* < 3.3.0 */
  931. res = gnutls_certificate_verify_peers2(session, &status);
  932. #endif
  933. if (res < 0) {
  934. wpa_printf(MSG_INFO, "TLS: Failed to verify peer "
  935. "certificate chain");
  936. err = GNUTLS_A_INTERNAL_ERROR;
  937. goto out;
  938. }
  939. #if GNUTLS_VERSION_NUMBER >= 0x030104
  940. {
  941. gnutls_datum_t info;
  942. int ret, type;
  943. type = gnutls_certificate_type_get(session);
  944. ret = gnutls_certificate_verification_status_print(status, type,
  945. &info, 0);
  946. if (ret < 0) {
  947. wpa_printf(MSG_DEBUG,
  948. "GnuTLS: Failed to print verification status");
  949. err = GNUTLS_A_INTERNAL_ERROR;
  950. goto out;
  951. }
  952. wpa_printf(MSG_DEBUG, "GnuTLS: %s", info.data);
  953. gnutls_free(info.data);
  954. }
  955. #endif /* GnuTLS 3.1.4 or newer */
  956. certs = gnutls_certificate_get_peers(session, &num_certs);
  957. if (certs == NULL || num_certs == 0) {
  958. wpa_printf(MSG_INFO, "TLS: No peer certificate chain received");
  959. err = GNUTLS_A_UNKNOWN_CA;
  960. goto out;
  961. }
  962. if (conn->verify_peer && (status & GNUTLS_CERT_INVALID)) {
  963. wpa_printf(MSG_INFO, "TLS: Peer certificate not trusted");
  964. if (status & GNUTLS_CERT_INSECURE_ALGORITHM) {
  965. wpa_printf(MSG_INFO, "TLS: Certificate uses insecure "
  966. "algorithm");
  967. gnutls_tls_fail_event(conn, NULL, 0, NULL,
  968. "certificate uses insecure algorithm",
  969. TLS_FAIL_BAD_CERTIFICATE);
  970. err = GNUTLS_A_INSUFFICIENT_SECURITY;
  971. goto out;
  972. }
  973. if (status & GNUTLS_CERT_NOT_ACTIVATED) {
  974. wpa_printf(MSG_INFO, "TLS: Certificate not yet "
  975. "activated");
  976. gnutls_tls_fail_event(conn, NULL, 0, NULL,
  977. "certificate not yet valid",
  978. TLS_FAIL_NOT_YET_VALID);
  979. err = GNUTLS_A_CERTIFICATE_EXPIRED;
  980. goto out;
  981. }
  982. if (status & GNUTLS_CERT_EXPIRED) {
  983. wpa_printf(MSG_INFO, "TLS: Certificate expired");
  984. gnutls_tls_fail_event(conn, NULL, 0, NULL,
  985. "certificate has expired",
  986. TLS_FAIL_EXPIRED);
  987. err = GNUTLS_A_CERTIFICATE_EXPIRED;
  988. goto out;
  989. }
  990. gnutls_tls_fail_event(conn, NULL, 0, NULL,
  991. "untrusted certificate",
  992. TLS_FAIL_UNTRUSTED);
  993. err = GNUTLS_A_INTERNAL_ERROR;
  994. goto out;
  995. }
  996. if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) {
  997. wpa_printf(MSG_INFO, "TLS: Peer certificate does not have a "
  998. "known issuer");
  999. gnutls_tls_fail_event(conn, NULL, 0, NULL, "signed not found",
  1000. TLS_FAIL_UNTRUSTED);
  1001. err = GNUTLS_A_UNKNOWN_CA;
  1002. goto out;
  1003. }
  1004. if (status & GNUTLS_CERT_REVOKED) {
  1005. wpa_printf(MSG_INFO, "TLS: Peer certificate has been revoked");
  1006. gnutls_tls_fail_event(conn, NULL, 0, NULL,
  1007. "certificate revoked",
  1008. TLS_FAIL_REVOKED);
  1009. err = GNUTLS_A_CERTIFICATE_REVOKED;
  1010. goto out;
  1011. }
  1012. if (status != 0) {
  1013. wpa_printf(MSG_INFO, "TLS: Unknown verification status: %d",
  1014. status);
  1015. err = GNUTLS_A_INTERNAL_ERROR;
  1016. goto out;
  1017. }
  1018. if (check_ocsp(conn, session, &err))
  1019. goto out;
  1020. os_get_time(&now);
  1021. for (i = 0; i < num_certs; i++) {
  1022. char *buf;
  1023. size_t len;
  1024. if (gnutls_x509_crt_init(&cert) < 0) {
  1025. wpa_printf(MSG_INFO, "TLS: Certificate initialization "
  1026. "failed");
  1027. err = GNUTLS_A_BAD_CERTIFICATE;
  1028. goto out;
  1029. }
  1030. if (gnutls_x509_crt_import(cert, &certs[i],
  1031. GNUTLS_X509_FMT_DER) < 0) {
  1032. wpa_printf(MSG_INFO, "TLS: Could not parse peer "
  1033. "certificate %d/%d", i + 1, num_certs);
  1034. gnutls_x509_crt_deinit(cert);
  1035. err = GNUTLS_A_BAD_CERTIFICATE;
  1036. goto out;
  1037. }
  1038. gnutls_x509_crt_get_dn(cert, NULL, &len);
  1039. len++;
  1040. buf = os_malloc(len + 1);
  1041. if (buf) {
  1042. buf[0] = buf[len] = '\0';
  1043. gnutls_x509_crt_get_dn(cert, buf, &len);
  1044. }
  1045. wpa_printf(MSG_DEBUG, "TLS: Peer cert chain %d/%d: %s",
  1046. i + 1, num_certs, buf);
  1047. if (conn->global->event_cb) {
  1048. struct wpabuf *cert_buf = NULL;
  1049. union tls_event_data ev;
  1050. #ifdef CONFIG_SHA256
  1051. u8 hash[32];
  1052. const u8 *_addr[1];
  1053. size_t _len[1];
  1054. #endif /* CONFIG_SHA256 */
  1055. os_memset(&ev, 0, sizeof(ev));
  1056. if (conn->global->cert_in_cb) {
  1057. cert_buf = wpabuf_alloc_copy(certs[i].data,
  1058. certs[i].size);
  1059. ev.peer_cert.cert = cert_buf;
  1060. }
  1061. #ifdef CONFIG_SHA256
  1062. _addr[0] = certs[i].data;
  1063. _len[0] = certs[i].size;
  1064. if (sha256_vector(1, _addr, _len, hash) == 0) {
  1065. ev.peer_cert.hash = hash;
  1066. ev.peer_cert.hash_len = sizeof(hash);
  1067. }
  1068. #endif /* CONFIG_SHA256 */
  1069. ev.peer_cert.depth = i;
  1070. ev.peer_cert.subject = buf;
  1071. conn->global->event_cb(conn->global->cb_ctx,
  1072. TLS_PEER_CERTIFICATE, &ev);
  1073. wpabuf_free(cert_buf);
  1074. }
  1075. if (i == 0) {
  1076. if (conn->suffix_match &&
  1077. !gnutls_x509_crt_check_hostname(
  1078. cert, conn->suffix_match)) {
  1079. wpa_printf(MSG_WARNING,
  1080. "TLS: Domain suffix match '%s' not found",
  1081. conn->suffix_match);
  1082. gnutls_tls_fail_event(
  1083. conn, &certs[i], i, buf,
  1084. "Domain suffix mismatch",
  1085. TLS_FAIL_DOMAIN_SUFFIX_MISMATCH);
  1086. err = GNUTLS_A_BAD_CERTIFICATE;
  1087. gnutls_x509_crt_deinit(cert);
  1088. os_free(buf);
  1089. goto out;
  1090. }
  1091. #if GNUTLS_VERSION_NUMBER >= 0x030300
  1092. if (conn->domain_match &&
  1093. !gnutls_x509_crt_check_hostname2(
  1094. cert, conn->domain_match,
  1095. GNUTLS_VERIFY_DO_NOT_ALLOW_WILDCARDS)) {
  1096. wpa_printf(MSG_WARNING,
  1097. "TLS: Domain match '%s' not found",
  1098. conn->domain_match);
  1099. gnutls_tls_fail_event(
  1100. conn, &certs[i], i, buf,
  1101. "Domain mismatch",
  1102. TLS_FAIL_DOMAIN_MISMATCH);
  1103. err = GNUTLS_A_BAD_CERTIFICATE;
  1104. gnutls_x509_crt_deinit(cert);
  1105. os_free(buf);
  1106. goto out;
  1107. }
  1108. #endif /* >= 3.3.0 */
  1109. /* TODO: validate altsubject_match.
  1110. * For now, any such configuration is rejected in
  1111. * tls_connection_set_params() */
  1112. #if GNUTLS_VERSION_NUMBER < 0x030300
  1113. /*
  1114. * gnutls_certificate_verify_peers() not available, so
  1115. * need to check EKU separately.
  1116. */
  1117. if (!conn->global->server &&
  1118. !server_eku_purpose(cert)) {
  1119. wpa_printf(MSG_WARNING,
  1120. "GnuTLS: No server EKU");
  1121. gnutls_tls_fail_event(
  1122. conn, &certs[i], i, buf,
  1123. "No server EKU",
  1124. TLS_FAIL_BAD_CERTIFICATE);
  1125. err = GNUTLS_A_BAD_CERTIFICATE;
  1126. gnutls_x509_crt_deinit(cert);
  1127. os_free(buf);
  1128. goto out;
  1129. }
  1130. #endif /* < 3.3.0 */
  1131. }
  1132. if (!conn->disable_time_checks &&
  1133. (gnutls_x509_crt_get_expiration_time(cert) < now.sec ||
  1134. gnutls_x509_crt_get_activation_time(cert) > now.sec)) {
  1135. wpa_printf(MSG_INFO, "TLS: Peer certificate %d/%d is "
  1136. "not valid at this time",
  1137. i + 1, num_certs);
  1138. gnutls_tls_fail_event(
  1139. conn, &certs[i], i, buf,
  1140. "Certificate is not valid at this time",
  1141. TLS_FAIL_EXPIRED);
  1142. gnutls_x509_crt_deinit(cert);
  1143. os_free(buf);
  1144. err = GNUTLS_A_CERTIFICATE_EXPIRED;
  1145. goto out;
  1146. }
  1147. os_free(buf);
  1148. gnutls_x509_crt_deinit(cert);
  1149. }
  1150. if (conn->global->event_cb != NULL)
  1151. conn->global->event_cb(conn->global->cb_ctx,
  1152. TLS_CERT_CHAIN_SUCCESS, NULL);
  1153. return 0;
  1154. out:
  1155. conn->failed++;
  1156. gnutls_alert_send(session, GNUTLS_AL_FATAL, err);
  1157. return GNUTLS_E_CERTIFICATE_ERROR;
  1158. }
  1159. static struct wpabuf * gnutls_get_appl_data(struct tls_connection *conn)
  1160. {
  1161. int res;
  1162. struct wpabuf *ad;
  1163. wpa_printf(MSG_DEBUG, "GnuTLS: Check for possible Application Data");
  1164. ad = wpabuf_alloc((wpabuf_len(conn->pull_buf) + 500) * 3);
  1165. if (ad == NULL)
  1166. return NULL;
  1167. res = gnutls_record_recv(conn->session, wpabuf_mhead(ad),
  1168. wpabuf_size(ad));
  1169. wpa_printf(MSG_DEBUG, "GnuTLS: gnutls_record_recv: %d", res);
  1170. if (res < 0) {
  1171. wpa_printf(MSG_DEBUG, "%s - gnutls_record_recv failed: %d "
  1172. "(%s)", __func__, (int) res,
  1173. gnutls_strerror(res));
  1174. wpabuf_free(ad);
  1175. return NULL;
  1176. }
  1177. wpabuf_put(ad, res);
  1178. wpa_printf(MSG_DEBUG, "GnuTLS: Received %d bytes of Application Data",
  1179. res);
  1180. return ad;
  1181. }
  1182. struct wpabuf * tls_connection_handshake(void *tls_ctx,
  1183. struct tls_connection *conn,
  1184. const struct wpabuf *in_data,
  1185. struct wpabuf **appl_data)
  1186. {
  1187. struct tls_global *global = tls_ctx;
  1188. struct wpabuf *out_data;
  1189. int ret;
  1190. if (appl_data)
  1191. *appl_data = NULL;
  1192. if (in_data && wpabuf_len(in_data) > 0) {
  1193. if (conn->pull_buf) {
  1194. wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in "
  1195. "pull_buf", __func__,
  1196. (unsigned long) wpabuf_len(conn->pull_buf));
  1197. wpabuf_free(conn->pull_buf);
  1198. }
  1199. conn->pull_buf = wpabuf_dup(in_data);
  1200. if (conn->pull_buf == NULL)
  1201. return NULL;
  1202. conn->pull_buf_offset = wpabuf_head(conn->pull_buf);
  1203. }
  1204. ret = gnutls_handshake(conn->session);
  1205. if (ret < 0) {
  1206. gnutls_alert_description_t alert;
  1207. union tls_event_data ev;
  1208. switch (ret) {
  1209. case GNUTLS_E_AGAIN:
  1210. if (global->server && conn->established &&
  1211. conn->push_buf == NULL) {
  1212. /* Need to return something to trigger
  1213. * completion of EAP-TLS. */
  1214. conn->push_buf = wpabuf_alloc(0);
  1215. }
  1216. break;
  1217. case GNUTLS_E_DH_PRIME_UNACCEPTABLE:
  1218. wpa_printf(MSG_DEBUG, "GnuTLS: Unacceptable DH prime");
  1219. if (conn->global->event_cb) {
  1220. os_memset(&ev, 0, sizeof(ev));
  1221. ev.alert.is_local = 1;
  1222. ev.alert.type = "fatal";
  1223. ev.alert.description = "insufficient security";
  1224. conn->global->event_cb(conn->global->cb_ctx,
  1225. TLS_ALERT, &ev);
  1226. }
  1227. /*
  1228. * Could send a TLS Alert to the server, but for now,
  1229. * simply terminate handshake.
  1230. */
  1231. conn->failed++;
  1232. conn->write_alerts++;
  1233. break;
  1234. case GNUTLS_E_FATAL_ALERT_RECEIVED:
  1235. alert = gnutls_alert_get(conn->session);
  1236. wpa_printf(MSG_DEBUG, "%s - received fatal '%s' alert",
  1237. __func__, gnutls_alert_get_name(alert));
  1238. conn->read_alerts++;
  1239. if (conn->global->event_cb != NULL) {
  1240. os_memset(&ev, 0, sizeof(ev));
  1241. ev.alert.is_local = 0;
  1242. ev.alert.type = gnutls_alert_get_name(alert);
  1243. ev.alert.description = ev.alert.type;
  1244. conn->global->event_cb(conn->global->cb_ctx,
  1245. TLS_ALERT, &ev);
  1246. }
  1247. /* continue */
  1248. default:
  1249. wpa_printf(MSG_DEBUG, "%s - gnutls_handshake failed "
  1250. "-> %s", __func__, gnutls_strerror(ret));
  1251. conn->failed++;
  1252. }
  1253. } else {
  1254. size_t size;
  1255. wpa_printf(MSG_DEBUG, "TLS: Handshake completed successfully");
  1256. #if GNUTLS_VERSION_NUMBER >= 0x03010a
  1257. {
  1258. char *desc;
  1259. desc = gnutls_session_get_desc(conn->session);
  1260. if (desc) {
  1261. wpa_printf(MSG_DEBUG, "GnuTLS: %s", desc);
  1262. gnutls_free(desc);
  1263. }
  1264. }
  1265. #endif /* GnuTLS 3.1.10 or newer */
  1266. conn->established = 1;
  1267. if (conn->push_buf == NULL) {
  1268. /* Need to return something to get final TLS ACK. */
  1269. conn->push_buf = wpabuf_alloc(0);
  1270. }
  1271. gnutls_session_get_data(conn->session, NULL, &size);
  1272. if (global->session_data == NULL ||
  1273. global->session_data_size < size) {
  1274. os_free(global->session_data);
  1275. global->session_data = os_malloc(size);
  1276. }
  1277. if (global->session_data) {
  1278. global->session_data_size = size;
  1279. gnutls_session_get_data(conn->session,
  1280. global->session_data,
  1281. &global->session_data_size);
  1282. }
  1283. if (conn->pull_buf && appl_data)
  1284. *appl_data = gnutls_get_appl_data(conn);
  1285. }
  1286. out_data = conn->push_buf;
  1287. conn->push_buf = NULL;
  1288. return out_data;
  1289. }
  1290. struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
  1291. struct tls_connection *conn,
  1292. const struct wpabuf *in_data,
  1293. struct wpabuf **appl_data)
  1294. {
  1295. return tls_connection_handshake(tls_ctx, conn, in_data, appl_data);
  1296. }
  1297. struct wpabuf * tls_connection_encrypt(void *tls_ctx,
  1298. struct tls_connection *conn,
  1299. const struct wpabuf *in_data)
  1300. {
  1301. ssize_t res;
  1302. struct wpabuf *buf;
  1303. res = gnutls_record_send(conn->session, wpabuf_head(in_data),
  1304. wpabuf_len(in_data));
  1305. if (res < 0) {
  1306. wpa_printf(MSG_INFO, "%s: Encryption failed: %s",
  1307. __func__, gnutls_strerror(res));
  1308. return NULL;
  1309. }
  1310. buf = conn->push_buf;
  1311. conn->push_buf = NULL;
  1312. return buf;
  1313. }
  1314. struct wpabuf * tls_connection_decrypt(void *tls_ctx,
  1315. struct tls_connection *conn,
  1316. const struct wpabuf *in_data)
  1317. {
  1318. ssize_t res;
  1319. struct wpabuf *out;
  1320. if (conn->pull_buf) {
  1321. wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in "
  1322. "pull_buf", __func__,
  1323. (unsigned long) wpabuf_len(conn->pull_buf));
  1324. wpabuf_free(conn->pull_buf);
  1325. }
  1326. conn->pull_buf = wpabuf_dup(in_data);
  1327. if (conn->pull_buf == NULL)
  1328. return NULL;
  1329. conn->pull_buf_offset = wpabuf_head(conn->pull_buf);
  1330. /*
  1331. * Even though we try to disable TLS compression, it is possible that
  1332. * this cannot be done with all TLS libraries. Add extra buffer space
  1333. * to handle the possibility of the decrypted data being longer than
  1334. * input data.
  1335. */
  1336. out = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
  1337. if (out == NULL)
  1338. return NULL;
  1339. res = gnutls_record_recv(conn->session, wpabuf_mhead(out),
  1340. wpabuf_size(out));
  1341. if (res < 0) {
  1342. wpa_printf(MSG_DEBUG, "%s - gnutls_record_recv failed: %d "
  1343. "(%s)", __func__, (int) res, gnutls_strerror(res));
  1344. wpabuf_free(out);
  1345. return NULL;
  1346. }
  1347. wpabuf_put(out, res);
  1348. return out;
  1349. }
  1350. int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn)
  1351. {
  1352. if (conn == NULL)
  1353. return 0;
  1354. return gnutls_session_is_resumed(conn->session);
  1355. }
  1356. int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
  1357. u8 *ciphers)
  1358. {
  1359. /* TODO */
  1360. return -1;
  1361. }
  1362. int tls_get_version(void *ssl_ctx, struct tls_connection *conn,
  1363. char *buf, size_t buflen)
  1364. {
  1365. gnutls_protocol_t ver;
  1366. ver = gnutls_protocol_get_version(conn->session);
  1367. if (ver == GNUTLS_TLS1_0)
  1368. os_strlcpy(buf, "TLSv1", buflen);
  1369. else if (ver == GNUTLS_TLS1_1)
  1370. os_strlcpy(buf, "TLSv1.1", buflen);
  1371. else if (ver == GNUTLS_TLS1_2)
  1372. os_strlcpy(buf, "TLSv1.2", buflen);
  1373. else
  1374. return -1;
  1375. return 0;
  1376. }
  1377. int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn,
  1378. char *buf, size_t buflen)
  1379. {
  1380. gnutls_cipher_algorithm_t cipher;
  1381. gnutls_kx_algorithm_t kx;
  1382. gnutls_mac_algorithm_t mac;
  1383. const char *kx_str, *cipher_str, *mac_str;
  1384. int res;
  1385. cipher = gnutls_cipher_get(conn->session);
  1386. cipher_str = gnutls_cipher_get_name(cipher);
  1387. if (!cipher_str)
  1388. cipher_str = "";
  1389. kx = gnutls_kx_get(conn->session);
  1390. kx_str = gnutls_kx_get_name(kx);
  1391. if (!kx_str)
  1392. kx_str = "";
  1393. mac = gnutls_mac_get(conn->session);
  1394. mac_str = gnutls_mac_get_name(mac);
  1395. if (!mac_str)
  1396. mac_str = "";
  1397. if (kx == GNUTLS_KX_RSA)
  1398. res = os_snprintf(buf, buflen, "%s-%s", cipher_str, mac_str);
  1399. else
  1400. res = os_snprintf(buf, buflen, "%s-%s-%s",
  1401. kx_str, cipher_str, mac_str);
  1402. if (os_snprintf_error(buflen, res))
  1403. return -1;
  1404. return 0;
  1405. }
  1406. int tls_connection_enable_workaround(void *ssl_ctx,
  1407. struct tls_connection *conn)
  1408. {
  1409. gnutls_record_disable_padding(conn->session);
  1410. return 0;
  1411. }
  1412. int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
  1413. int ext_type, const u8 *data,
  1414. size_t data_len)
  1415. {
  1416. /* TODO */
  1417. return -1;
  1418. }
  1419. int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn)
  1420. {
  1421. if (conn == NULL)
  1422. return -1;
  1423. return conn->failed;
  1424. }
  1425. int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn)
  1426. {
  1427. if (conn == NULL)
  1428. return -1;
  1429. return conn->read_alerts;
  1430. }
  1431. int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn)
  1432. {
  1433. if (conn == NULL)
  1434. return -1;
  1435. return conn->write_alerts;
  1436. }
  1437. int tls_connection_set_session_ticket_cb(void *tls_ctx,
  1438. struct tls_connection *conn,
  1439. tls_session_ticket_cb cb, void *ctx)
  1440. {
  1441. return -1;
  1442. }
  1443. int tls_get_library_version(char *buf, size_t buf_len)
  1444. {
  1445. return os_snprintf(buf, buf_len, "GnuTLS build=%s run=%s",
  1446. GNUTLS_VERSION, gnutls_check_version(NULL));
  1447. }
  1448. void tls_connection_set_success_data(struct tls_connection *conn,
  1449. struct wpabuf *data)
  1450. {
  1451. }
  1452. void tls_connection_set_success_data_resumed(struct tls_connection *conn)
  1453. {
  1454. }
  1455. const struct wpabuf *
  1456. tls_connection_get_success_data(struct tls_connection *conn)
  1457. {
  1458. return NULL;
  1459. }
  1460. void tls_connection_remove_session(struct tls_connection *conn)
  1461. {
  1462. }