tls_internal.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. /*
  2. * TLS interface functions and an internal TLS implementation
  3. * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * Alternatively, this software may be distributed under the terms of BSD
  10. * license.
  11. *
  12. * See README and COPYING for more details.
  13. *
  14. * This file interface functions for hostapd/wpa_supplicant to use the
  15. * integrated TLSv1 implementation.
  16. */
  17. #include "includes.h"
  18. #include "common.h"
  19. #include "tls.h"
  20. #include "tls/tlsv1_client.h"
  21. #include "tls/tlsv1_server.h"
  22. static int tls_ref_count = 0;
  23. struct tls_global {
  24. int server;
  25. struct tlsv1_credentials *server_cred;
  26. int check_crl;
  27. };
  28. struct tls_connection {
  29. struct tlsv1_client *client;
  30. struct tlsv1_server *server;
  31. };
  32. void * tls_init(const struct tls_config *conf)
  33. {
  34. struct tls_global *global;
  35. if (tls_ref_count == 0) {
  36. #ifdef CONFIG_TLS_INTERNAL_CLIENT
  37. if (tlsv1_client_global_init())
  38. return NULL;
  39. #endif /* CONFIG_TLS_INTERNAL_CLIENT */
  40. #ifdef CONFIG_TLS_INTERNAL_SERVER
  41. if (tlsv1_server_global_init())
  42. return NULL;
  43. #endif /* CONFIG_TLS_INTERNAL_SERVER */
  44. }
  45. tls_ref_count++;
  46. global = os_zalloc(sizeof(*global));
  47. if (global == NULL)
  48. return NULL;
  49. return global;
  50. }
  51. void tls_deinit(void *ssl_ctx)
  52. {
  53. struct tls_global *global = ssl_ctx;
  54. tls_ref_count--;
  55. if (tls_ref_count == 0) {
  56. #ifdef CONFIG_TLS_INTERNAL_CLIENT
  57. tlsv1_client_global_deinit();
  58. #endif /* CONFIG_TLS_INTERNAL_CLIENT */
  59. #ifdef CONFIG_TLS_INTERNAL_SERVER
  60. tlsv1_cred_free(global->server_cred);
  61. tlsv1_server_global_deinit();
  62. #endif /* CONFIG_TLS_INTERNAL_SERVER */
  63. }
  64. os_free(global);
  65. }
  66. int tls_get_errors(void *tls_ctx)
  67. {
  68. return 0;
  69. }
  70. struct tls_connection * tls_connection_init(void *tls_ctx)
  71. {
  72. struct tls_connection *conn;
  73. struct tls_global *global = tls_ctx;
  74. conn = os_zalloc(sizeof(*conn));
  75. if (conn == NULL)
  76. return NULL;
  77. #ifdef CONFIG_TLS_INTERNAL_CLIENT
  78. if (!global->server) {
  79. conn->client = tlsv1_client_init();
  80. if (conn->client == NULL) {
  81. os_free(conn);
  82. return NULL;
  83. }
  84. }
  85. #endif /* CONFIG_TLS_INTERNAL_CLIENT */
  86. #ifdef CONFIG_TLS_INTERNAL_SERVER
  87. if (global->server) {
  88. conn->server = tlsv1_server_init(global->server_cred);
  89. if (conn->server == NULL) {
  90. os_free(conn);
  91. return NULL;
  92. }
  93. }
  94. #endif /* CONFIG_TLS_INTERNAL_SERVER */
  95. return conn;
  96. }
  97. void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn)
  98. {
  99. if (conn == NULL)
  100. return;
  101. #ifdef CONFIG_TLS_INTERNAL_CLIENT
  102. if (conn->client)
  103. tlsv1_client_deinit(conn->client);
  104. #endif /* CONFIG_TLS_INTERNAL_CLIENT */
  105. #ifdef CONFIG_TLS_INTERNAL_SERVER
  106. if (conn->server)
  107. tlsv1_server_deinit(conn->server);
  108. #endif /* CONFIG_TLS_INTERNAL_SERVER */
  109. os_free(conn);
  110. }
  111. int tls_connection_established(void *tls_ctx, struct tls_connection *conn)
  112. {
  113. #ifdef CONFIG_TLS_INTERNAL_CLIENT
  114. if (conn->client)
  115. return tlsv1_client_established(conn->client);
  116. #endif /* CONFIG_TLS_INTERNAL_CLIENT */
  117. #ifdef CONFIG_TLS_INTERNAL_SERVER
  118. if (conn->server)
  119. return tlsv1_server_established(conn->server);
  120. #endif /* CONFIG_TLS_INTERNAL_SERVER */
  121. return 0;
  122. }
  123. int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn)
  124. {
  125. #ifdef CONFIG_TLS_INTERNAL_CLIENT
  126. if (conn->client)
  127. return tlsv1_client_shutdown(conn->client);
  128. #endif /* CONFIG_TLS_INTERNAL_CLIENT */
  129. #ifdef CONFIG_TLS_INTERNAL_SERVER
  130. if (conn->server)
  131. return tlsv1_server_shutdown(conn->server);
  132. #endif /* CONFIG_TLS_INTERNAL_SERVER */
  133. return -1;
  134. }
  135. int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
  136. const struct tls_connection_params *params)
  137. {
  138. #ifdef CONFIG_TLS_INTERNAL_CLIENT
  139. struct tlsv1_credentials *cred;
  140. if (conn->client == NULL)
  141. return -1;
  142. cred = tlsv1_cred_alloc();
  143. if (cred == NULL)
  144. return -1;
  145. if (tlsv1_set_ca_cert(cred, params->ca_cert,
  146. params->ca_cert_blob, params->ca_cert_blob_len,
  147. params->ca_path)) {
  148. wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA "
  149. "certificates");
  150. tlsv1_cred_free(cred);
  151. return -1;
  152. }
  153. if (tlsv1_set_cert(cred, params->client_cert,
  154. params->client_cert_blob,
  155. params->client_cert_blob_len)) {
  156. wpa_printf(MSG_INFO, "TLS: Failed to configure client "
  157. "certificate");
  158. tlsv1_cred_free(cred);
  159. return -1;
  160. }
  161. if (tlsv1_set_private_key(cred, params->private_key,
  162. params->private_key_passwd,
  163. params->private_key_blob,
  164. params->private_key_blob_len)) {
  165. wpa_printf(MSG_INFO, "TLS: Failed to load private key");
  166. tlsv1_cred_free(cred);
  167. return -1;
  168. }
  169. if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob,
  170. params->dh_blob_len)) {
  171. wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters");
  172. tlsv1_cred_free(cred);
  173. return -1;
  174. }
  175. if (tlsv1_client_set_cred(conn->client, cred) < 0) {
  176. tlsv1_cred_free(cred);
  177. return -1;
  178. }
  179. return 0;
  180. #else /* CONFIG_TLS_INTERNAL_CLIENT */
  181. return -1;
  182. #endif /* CONFIG_TLS_INTERNAL_CLIENT */
  183. }
  184. int tls_global_set_params(void *tls_ctx,
  185. const struct tls_connection_params *params)
  186. {
  187. #ifdef CONFIG_TLS_INTERNAL_SERVER
  188. struct tls_global *global = tls_ctx;
  189. struct tlsv1_credentials *cred;
  190. /* Currently, global parameters are only set when running in server
  191. * mode. */
  192. global->server = 1;
  193. tlsv1_cred_free(global->server_cred);
  194. global->server_cred = cred = tlsv1_cred_alloc();
  195. if (cred == NULL)
  196. return -1;
  197. if (tlsv1_set_ca_cert(cred, params->ca_cert, params->ca_cert_blob,
  198. params->ca_cert_blob_len, params->ca_path)) {
  199. wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA "
  200. "certificates");
  201. return -1;
  202. }
  203. if (tlsv1_set_cert(cred, params->client_cert, params->client_cert_blob,
  204. params->client_cert_blob_len)) {
  205. wpa_printf(MSG_INFO, "TLS: Failed to configure server "
  206. "certificate");
  207. return -1;
  208. }
  209. if (tlsv1_set_private_key(cred, params->private_key,
  210. params->private_key_passwd,
  211. params->private_key_blob,
  212. params->private_key_blob_len)) {
  213. wpa_printf(MSG_INFO, "TLS: Failed to load private key");
  214. return -1;
  215. }
  216. if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob,
  217. params->dh_blob_len)) {
  218. wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters");
  219. return -1;
  220. }
  221. return 0;
  222. #else /* CONFIG_TLS_INTERNAL_SERVER */
  223. return -1;
  224. #endif /* CONFIG_TLS_INTERNAL_SERVER */
  225. }
  226. int tls_global_set_verify(void *tls_ctx, int check_crl)
  227. {
  228. struct tls_global *global = tls_ctx;
  229. global->check_crl = check_crl;
  230. return 0;
  231. }
  232. int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn,
  233. int verify_peer)
  234. {
  235. #ifdef CONFIG_TLS_INTERNAL_SERVER
  236. if (conn->server)
  237. return tlsv1_server_set_verify(conn->server, verify_peer);
  238. #endif /* CONFIG_TLS_INTERNAL_SERVER */
  239. return -1;
  240. }
  241. int tls_connection_set_ia(void *tls_ctx, struct tls_connection *conn,
  242. int tls_ia)
  243. {
  244. return -1;
  245. }
  246. int tls_connection_get_keys(void *tls_ctx, struct tls_connection *conn,
  247. struct tls_keys *keys)
  248. {
  249. #ifdef CONFIG_TLS_INTERNAL_CLIENT
  250. if (conn->client)
  251. return tlsv1_client_get_keys(conn->client, keys);
  252. #endif /* CONFIG_TLS_INTERNAL_CLIENT */
  253. #ifdef CONFIG_TLS_INTERNAL_SERVER
  254. if (conn->server)
  255. return tlsv1_server_get_keys(conn->server, keys);
  256. #endif /* CONFIG_TLS_INTERNAL_SERVER */
  257. return -1;
  258. }
  259. int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
  260. const char *label, int server_random_first,
  261. u8 *out, size_t out_len)
  262. {
  263. #ifdef CONFIG_TLS_INTERNAL_CLIENT
  264. if (conn->client) {
  265. return tlsv1_client_prf(conn->client, label,
  266. server_random_first,
  267. out, out_len);
  268. }
  269. #endif /* CONFIG_TLS_INTERNAL_CLIENT */
  270. #ifdef CONFIG_TLS_INTERNAL_SERVER
  271. if (conn->server) {
  272. return tlsv1_server_prf(conn->server, label,
  273. server_random_first,
  274. out, out_len);
  275. }
  276. #endif /* CONFIG_TLS_INTERNAL_SERVER */
  277. return -1;
  278. }
  279. struct wpabuf * tls_connection_handshake(void *tls_ctx,
  280. struct tls_connection *conn,
  281. const struct wpabuf *in_data,
  282. struct wpabuf **appl_data)
  283. {
  284. #ifdef CONFIG_TLS_INTERNAL_CLIENT
  285. u8 *res, *ad;
  286. size_t res_len, ad_len;
  287. struct wpabuf *out;
  288. if (conn->client == NULL)
  289. return NULL;
  290. ad = NULL;
  291. res = tlsv1_client_handshake(conn->client,
  292. in_data ? wpabuf_head(in_data) : NULL,
  293. in_data ? wpabuf_len(in_data) : 0,
  294. &res_len, &ad, &ad_len);
  295. if (res == NULL)
  296. return NULL;
  297. out = wpabuf_alloc_ext_data(res, res_len);
  298. if (out == NULL) {
  299. os_free(res);
  300. os_free(ad);
  301. return NULL;
  302. }
  303. if (appl_data) {
  304. if (ad) {
  305. *appl_data = wpabuf_alloc_ext_data(ad, ad_len);
  306. if (*appl_data == NULL)
  307. os_free(ad);
  308. } else
  309. *appl_data = NULL;
  310. } else
  311. os_free(ad);
  312. return out;
  313. #else /* CONFIG_TLS_INTERNAL_CLIENT */
  314. return NULL;
  315. #endif /* CONFIG_TLS_INTERNAL_CLIENT */
  316. }
  317. struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
  318. struct tls_connection *conn,
  319. const struct wpabuf *in_data,
  320. struct wpabuf **appl_data)
  321. {
  322. #ifdef CONFIG_TLS_INTERNAL_SERVER
  323. u8 *res;
  324. size_t res_len;
  325. struct wpabuf *out;
  326. if (conn->server == NULL)
  327. return NULL;
  328. if (appl_data)
  329. *appl_data = NULL;
  330. res = tlsv1_server_handshake(conn->server, wpabuf_head(in_data),
  331. wpabuf_len(in_data), &res_len);
  332. if (res == NULL && tlsv1_server_established(conn->server))
  333. return wpabuf_alloc(0);
  334. if (res == NULL)
  335. return NULL;
  336. out = wpabuf_alloc_ext_data(res, res_len);
  337. if (out == NULL) {
  338. os_free(res);
  339. return NULL;
  340. }
  341. return out;
  342. #else /* CONFIG_TLS_INTERNAL_SERVER */
  343. return NULL;
  344. #endif /* CONFIG_TLS_INTERNAL_SERVER */
  345. }
  346. struct wpabuf * tls_connection_encrypt(void *tls_ctx,
  347. struct tls_connection *conn,
  348. const struct wpabuf *in_data)
  349. {
  350. #ifdef CONFIG_TLS_INTERNAL_CLIENT
  351. if (conn->client) {
  352. struct wpabuf *buf;
  353. int res;
  354. buf = wpabuf_alloc(wpabuf_len(in_data) + 300);
  355. if (buf == NULL)
  356. return NULL;
  357. res = tlsv1_client_encrypt(conn->client, wpabuf_head(in_data),
  358. wpabuf_len(in_data),
  359. wpabuf_mhead(buf),
  360. wpabuf_size(buf));
  361. if (res < 0) {
  362. wpabuf_free(buf);
  363. return NULL;
  364. }
  365. wpabuf_put(buf, res);
  366. return buf;
  367. }
  368. #endif /* CONFIG_TLS_INTERNAL_CLIENT */
  369. #ifdef CONFIG_TLS_INTERNAL_SERVER
  370. if (conn->server) {
  371. struct wpabuf *buf;
  372. int res;
  373. buf = wpabuf_alloc(wpabuf_len(in_data) + 300);
  374. if (buf == NULL)
  375. return NULL;
  376. res = tlsv1_server_encrypt(conn->server, wpabuf_head(in_data),
  377. wpabuf_len(in_data),
  378. wpabuf_mhead(buf),
  379. wpabuf_size(buf));
  380. if (res < 0) {
  381. wpabuf_free(buf);
  382. return NULL;
  383. }
  384. wpabuf_put(buf, res);
  385. return buf;
  386. }
  387. #endif /* CONFIG_TLS_INTERNAL_SERVER */
  388. return NULL;
  389. }
  390. struct wpabuf * tls_connection_decrypt(void *tls_ctx,
  391. struct tls_connection *conn,
  392. const struct wpabuf *in_data)
  393. {
  394. #ifdef CONFIG_TLS_INTERNAL_CLIENT
  395. if (conn->client) {
  396. struct wpabuf *buf;
  397. int res;
  398. buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
  399. if (buf == NULL)
  400. return NULL;
  401. res = tlsv1_client_decrypt(conn->client, wpabuf_head(in_data),
  402. wpabuf_len(in_data),
  403. wpabuf_mhead(buf),
  404. wpabuf_size(buf));
  405. if (res < 0) {
  406. wpabuf_free(buf);
  407. return NULL;
  408. }
  409. wpabuf_put(buf, res);
  410. return buf;
  411. }
  412. #endif /* CONFIG_TLS_INTERNAL_CLIENT */
  413. #ifdef CONFIG_TLS_INTERNAL_SERVER
  414. if (conn->server) {
  415. struct wpabuf *buf;
  416. int res;
  417. buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
  418. if (buf == NULL)
  419. return NULL;
  420. res = tlsv1_server_decrypt(conn->server, wpabuf_head(in_data),
  421. wpabuf_len(in_data),
  422. wpabuf_mhead(buf),
  423. wpabuf_size(buf));
  424. if (res < 0) {
  425. wpabuf_free(buf);
  426. return NULL;
  427. }
  428. wpabuf_put(buf, res);
  429. return buf;
  430. }
  431. #endif /* CONFIG_TLS_INTERNAL_SERVER */
  432. return NULL;
  433. }
  434. int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn)
  435. {
  436. #ifdef CONFIG_TLS_INTERNAL_CLIENT
  437. if (conn->client)
  438. return tlsv1_client_resumed(conn->client);
  439. #endif /* CONFIG_TLS_INTERNAL_CLIENT */
  440. #ifdef CONFIG_TLS_INTERNAL_SERVER
  441. if (conn->server)
  442. return tlsv1_server_resumed(conn->server);
  443. #endif /* CONFIG_TLS_INTERNAL_SERVER */
  444. return -1;
  445. }
  446. int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
  447. u8 *ciphers)
  448. {
  449. #ifdef CONFIG_TLS_INTERNAL_CLIENT
  450. if (conn->client)
  451. return tlsv1_client_set_cipher_list(conn->client, ciphers);
  452. #endif /* CONFIG_TLS_INTERNAL_CLIENT */
  453. #ifdef CONFIG_TLS_INTERNAL_SERVER
  454. if (conn->server)
  455. return tlsv1_server_set_cipher_list(conn->server, ciphers);
  456. #endif /* CONFIG_TLS_INTERNAL_SERVER */
  457. return -1;
  458. }
  459. int tls_get_cipher(void *tls_ctx, struct tls_connection *conn,
  460. char *buf, size_t buflen)
  461. {
  462. if (conn == NULL)
  463. return -1;
  464. #ifdef CONFIG_TLS_INTERNAL_CLIENT
  465. if (conn->client)
  466. return tlsv1_client_get_cipher(conn->client, buf, buflen);
  467. #endif /* CONFIG_TLS_INTERNAL_CLIENT */
  468. #ifdef CONFIG_TLS_INTERNAL_SERVER
  469. if (conn->server)
  470. return tlsv1_server_get_cipher(conn->server, buf, buflen);
  471. #endif /* CONFIG_TLS_INTERNAL_SERVER */
  472. return -1;
  473. }
  474. int tls_connection_enable_workaround(void *tls_ctx,
  475. struct tls_connection *conn)
  476. {
  477. return -1;
  478. }
  479. int tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn,
  480. int ext_type, const u8 *data,
  481. size_t data_len)
  482. {
  483. #ifdef CONFIG_TLS_INTERNAL_CLIENT
  484. if (conn->client) {
  485. return tlsv1_client_hello_ext(conn->client, ext_type,
  486. data, data_len);
  487. }
  488. #endif /* CONFIG_TLS_INTERNAL_CLIENT */
  489. return -1;
  490. }
  491. int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn)
  492. {
  493. return 0;
  494. }
  495. int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn)
  496. {
  497. return 0;
  498. }
  499. int tls_connection_get_write_alerts(void *tls_ctx,
  500. struct tls_connection *conn)
  501. {
  502. return 0;
  503. }
  504. int tls_connection_get_keyblock_size(void *tls_ctx,
  505. struct tls_connection *conn)
  506. {
  507. #ifdef CONFIG_TLS_INTERNAL_CLIENT
  508. if (conn->client)
  509. return tlsv1_client_get_keyblock_size(conn->client);
  510. #endif /* CONFIG_TLS_INTERNAL_CLIENT */
  511. #ifdef CONFIG_TLS_INTERNAL_SERVER
  512. if (conn->server)
  513. return tlsv1_server_get_keyblock_size(conn->server);
  514. #endif /* CONFIG_TLS_INTERNAL_SERVER */
  515. return -1;
  516. }
  517. unsigned int tls_capabilities(void *tls_ctx)
  518. {
  519. return 0;
  520. }
  521. struct wpabuf * tls_connection_ia_send_phase_finished(
  522. void *tls_ctx, struct tls_connection *conn, int final)
  523. {
  524. return NULL;
  525. }
  526. int tls_connection_ia_final_phase_finished(void *tls_ctx,
  527. struct tls_connection *conn)
  528. {
  529. return -1;
  530. }
  531. int tls_connection_ia_permute_inner_secret(void *tls_ctx,
  532. struct tls_connection *conn,
  533. const u8 *key, size_t key_len)
  534. {
  535. return -1;
  536. }
  537. int tls_connection_set_session_ticket_cb(void *tls_ctx,
  538. struct tls_connection *conn,
  539. tls_session_ticket_cb cb,
  540. void *ctx)
  541. {
  542. #ifdef CONFIG_TLS_INTERNAL_CLIENT
  543. if (conn->client) {
  544. tlsv1_client_set_session_ticket_cb(conn->client, cb, ctx);
  545. return 0;
  546. }
  547. #endif /* CONFIG_TLS_INTERNAL_CLIENT */
  548. #ifdef CONFIG_TLS_INTERNAL_SERVER
  549. if (conn->server) {
  550. tlsv1_server_set_session_ticket_cb(conn->server, cb, ctx);
  551. return 0;
  552. }
  553. #endif /* CONFIG_TLS_INTERNAL_SERVER */
  554. return -1;
  555. }