tls_gnutls.c 37 KB

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