tls_nss.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. /*
  2. * SSL/TLS interface functions for NSS
  3. * Copyright (c) 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. #include "includes.h"
  15. #include <nspr/prtypes.h>
  16. #include <nspr/plarenas.h>
  17. #include <nspr/plhash.h>
  18. #include <nspr/prio.h>
  19. #include <nspr/prclist.h>
  20. #include <nspr/prlock.h>
  21. #include <nspr/prinit.h>
  22. #include <nspr/prerror.h>
  23. #include <nspr/prmem.h>
  24. #include <nss/nss.h>
  25. #include <nss/nssilckt.h>
  26. #include <nss/ssl.h>
  27. #include <nss/pk11func.h>
  28. #include <nss/secerr.h>
  29. #include "common.h"
  30. #include "tls.h"
  31. static int tls_nss_ref_count = 0;
  32. static PRDescIdentity nss_layer_id;
  33. struct tls_connection {
  34. PRFileDesc *fd;
  35. int established;
  36. int verify_peer;
  37. u8 *push_buf, *pull_buf, *pull_buf_offset;
  38. size_t push_buf_len, pull_buf_len;
  39. };
  40. static PRStatus nss_io_close(PRFileDesc *fd)
  41. {
  42. wpa_printf(MSG_DEBUG, "NSS: I/O close");
  43. return PR_SUCCESS;
  44. }
  45. static PRInt32 nss_io_read(PRFileDesc *fd, void *buf, PRInt32 amount)
  46. {
  47. wpa_printf(MSG_DEBUG, "NSS: I/O read(%d)", amount);
  48. return PR_FAILURE;
  49. }
  50. static PRInt32 nss_io_write(PRFileDesc *fd, const void *buf, PRInt32 amount)
  51. {
  52. wpa_printf(MSG_DEBUG, "NSS: I/O write(%d)", amount);
  53. return PR_FAILURE;
  54. }
  55. static PRInt32 nss_io_writev(PRFileDesc *fd, const PRIOVec *iov,
  56. PRInt32 iov_size, PRIntervalTime timeout)
  57. {
  58. wpa_printf(MSG_DEBUG, "NSS: I/O writev(%d)", iov_size);
  59. return PR_FAILURE;
  60. }
  61. static PRInt32 nss_io_recv(PRFileDesc *fd, void *buf, PRInt32 amount,
  62. PRIntn flags, PRIntervalTime timeout)
  63. {
  64. struct tls_connection *conn = (struct tls_connection *) fd->secret;
  65. u8 *end;
  66. wpa_printf(MSG_DEBUG, "NSS: I/O recv(%d)", amount);
  67. if (conn->pull_buf == NULL) {
  68. wpa_printf(MSG_DEBUG, "NSS: No data available to be read yet");
  69. return PR_FAILURE;
  70. }
  71. end = conn->pull_buf + conn->pull_buf_len;
  72. if (end - conn->pull_buf_offset < amount)
  73. amount = end - conn->pull_buf_offset;
  74. os_memcpy(buf, conn->pull_buf_offset, amount);
  75. conn->pull_buf_offset += amount;
  76. if (conn->pull_buf_offset == end) {
  77. wpa_printf(MSG_DEBUG, "%s - pull_buf consumed", __func__);
  78. os_free(conn->pull_buf);
  79. conn->pull_buf = conn->pull_buf_offset = NULL;
  80. conn->pull_buf_len = 0;
  81. } else {
  82. wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in pull_buf",
  83. __func__,
  84. (unsigned long) (end - conn->pull_buf_offset));
  85. }
  86. return amount;
  87. }
  88. static PRInt32 nss_io_send(PRFileDesc *fd, const void *buf, PRInt32 amount,
  89. PRIntn flags, PRIntervalTime timeout)
  90. {
  91. struct tls_connection *conn = (struct tls_connection *) fd->secret;
  92. u8 *nbuf;
  93. wpa_printf(MSG_DEBUG, "NSS: I/O %s", __func__);
  94. wpa_hexdump(MSG_MSGDUMP, "NSS: I/O send data", buf, amount);
  95. nbuf = os_realloc(conn->push_buf, conn->push_buf_len + amount);
  96. if (nbuf == NULL) {
  97. wpa_printf(MSG_ERROR, "NSS: Failed to allocate memory for the "
  98. "data to be sent");
  99. return PR_FAILURE;
  100. }
  101. os_memcpy(nbuf + conn->push_buf_len, buf, amount);
  102. conn->push_buf = nbuf;
  103. conn->push_buf_len += amount;
  104. return amount;
  105. }
  106. static PRInt32 nss_io_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount,
  107. PRIntn flags, PRNetAddr *addr,
  108. PRIntervalTime timeout)
  109. {
  110. wpa_printf(MSG_DEBUG, "NSS: I/O %s", __func__);
  111. return PR_FAILURE;
  112. }
  113. static PRInt32 nss_io_sendto(PRFileDesc *fd, const void *buf, PRInt32 amount,
  114. PRIntn flags, const PRNetAddr *addr,
  115. PRIntervalTime timeout)
  116. {
  117. wpa_printf(MSG_DEBUG, "NSS: I/O %s", __func__);
  118. return PR_FAILURE;
  119. }
  120. static PRStatus nss_io_getpeername(PRFileDesc *fd, PRNetAddr *addr)
  121. {
  122. wpa_printf(MSG_DEBUG, "NSS: I/O getpeername");
  123. /*
  124. * It Looks like NSS only supports IPv4 and IPv6 TCP sockets. Provide a
  125. * fake IPv4 address to work around this even though we are not really
  126. * using TCP.
  127. */
  128. os_memset(addr, 0, sizeof(*addr));
  129. addr->inet.family = PR_AF_INET;
  130. return PR_SUCCESS;
  131. }
  132. static PRStatus nss_io_getsocketoption(PRFileDesc *fd,
  133. PRSocketOptionData *data)
  134. {
  135. switch (data->option) {
  136. case PR_SockOpt_Nonblocking:
  137. wpa_printf(MSG_DEBUG, "NSS: I/O getsocketoption(Nonblocking)");
  138. data->value.non_blocking = PR_TRUE;
  139. return PR_SUCCESS;
  140. default:
  141. wpa_printf(MSG_DEBUG, "NSS: I/O getsocketoption(%d)",
  142. data->option);
  143. return PR_FAILURE;
  144. }
  145. }
  146. static const PRIOMethods nss_io = {
  147. PR_DESC_LAYERED,
  148. nss_io_close,
  149. nss_io_read,
  150. nss_io_write,
  151. NULL /* available */,
  152. NULL /* available64 */,
  153. NULL /* fsync */,
  154. NULL /* fseek */,
  155. NULL /* fseek64 */,
  156. NULL /* fileinfo */,
  157. NULL /* fileinfo64 */,
  158. nss_io_writev,
  159. NULL /* connect */,
  160. NULL /* accept */,
  161. NULL /* bind */,
  162. NULL /* listen */,
  163. NULL /* shutdown */,
  164. nss_io_recv,
  165. nss_io_send,
  166. nss_io_recvfrom,
  167. nss_io_sendto,
  168. NULL /* poll */,
  169. NULL /* acceptread */,
  170. NULL /* transmitfile */,
  171. NULL /* getsockname */,
  172. nss_io_getpeername,
  173. NULL /* reserved_fn_6 */,
  174. NULL /* reserved_fn_5 */,
  175. nss_io_getsocketoption,
  176. NULL /* setsocketoption */,
  177. NULL /* sendfile */,
  178. NULL /* connectcontinue */,
  179. NULL /* reserved_fn_3 */,
  180. NULL /* reserved_fn_2 */,
  181. NULL /* reserved_fn_1 */,
  182. NULL /* reserved_fn_0 */
  183. };
  184. static char * nss_password_cb(PK11SlotInfo *slot, PRBool retry, void *arg)
  185. {
  186. wpa_printf(MSG_ERROR, "NSS: TODO - %s", __func__);
  187. return NULL;
  188. }
  189. void * tls_init(const struct tls_config *conf)
  190. {
  191. char *dir;
  192. tls_nss_ref_count++;
  193. if (tls_nss_ref_count > 1)
  194. return (void *) 1;
  195. PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
  196. nss_layer_id = PR_GetUniqueIdentity("wpa_supplicant");
  197. PK11_SetPasswordFunc(nss_password_cb);
  198. dir = getenv("SSL_DIR");
  199. if (dir) {
  200. if (NSS_Init(dir) != SECSuccess) {
  201. wpa_printf(MSG_ERROR, "NSS: NSS_Init(cert_dir=%s) "
  202. "failed", dir);
  203. return NULL;
  204. }
  205. } else {
  206. if (NSS_NoDB_Init(NULL) != SECSuccess) {
  207. wpa_printf(MSG_ERROR, "NSS: NSS_NoDB_Init(NULL) "
  208. "failed");
  209. return NULL;
  210. }
  211. }
  212. if (SSL_OptionSetDefault(SSL_V2_COMPATIBLE_HELLO, PR_FALSE) !=
  213. SECSuccess ||
  214. SSL_OptionSetDefault(SSL_ENABLE_SSL3, PR_FALSE) != SECSuccess ||
  215. SSL_OptionSetDefault(SSL_ENABLE_SSL2, PR_FALSE) != SECSuccess ||
  216. SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE) != SECSuccess) {
  217. wpa_printf(MSG_ERROR, "NSS: SSL_OptionSetDefault failed");
  218. return NULL;
  219. }
  220. if (NSS_SetDomesticPolicy() != SECSuccess) {
  221. wpa_printf(MSG_ERROR, "NSS: NSS_SetDomesticPolicy() failed");
  222. return NULL;
  223. }
  224. return (void *) 1;
  225. }
  226. void tls_deinit(void *ssl_ctx)
  227. {
  228. tls_nss_ref_count--;
  229. if (tls_nss_ref_count == 0) {
  230. if (NSS_Shutdown() != SECSuccess)
  231. wpa_printf(MSG_ERROR, "NSS: NSS_Shutdown() failed");
  232. }
  233. }
  234. int tls_get_errors(void *tls_ctx)
  235. {
  236. return 0;
  237. }
  238. static SECStatus nss_bad_cert_cb(void *arg, PRFileDesc *fd)
  239. {
  240. struct tls_connection *conn = arg;
  241. SECStatus res = SECSuccess;
  242. PRErrorCode err;
  243. CERTCertificate *cert;
  244. char *subject, *issuer;
  245. err = PR_GetError();
  246. if (IS_SEC_ERROR(err))
  247. wpa_printf(MSG_DEBUG, "NSS: Bad Server Certificate (sec err "
  248. "%d)", err - SEC_ERROR_BASE);
  249. else
  250. wpa_printf(MSG_DEBUG, "NSS: Bad Server Certificate (err %d)",
  251. err);
  252. cert = SSL_PeerCertificate(fd);
  253. subject = CERT_NameToAscii(&cert->subject);
  254. issuer = CERT_NameToAscii(&cert->issuer);
  255. wpa_printf(MSG_DEBUG, "NSS: Peer certificate subject='%s' issuer='%s'",
  256. subject, issuer);
  257. CERT_DestroyCertificate(cert);
  258. PR_Free(subject);
  259. PR_Free(issuer);
  260. if (conn->verify_peer)
  261. res = SECFailure;
  262. return res;
  263. }
  264. static void nss_handshake_cb(PRFileDesc *fd, void *client_data)
  265. {
  266. struct tls_connection *conn = client_data;
  267. wpa_printf(MSG_DEBUG, "NSS: Handshake completed");
  268. conn->established = 1;
  269. }
  270. struct tls_connection * tls_connection_init(void *tls_ctx)
  271. {
  272. struct tls_connection *conn;
  273. conn = os_zalloc(sizeof(*conn));
  274. if (conn == NULL)
  275. return NULL;
  276. conn->fd = PR_CreateIOLayerStub(nss_layer_id, &nss_io);
  277. if (conn->fd == NULL) {
  278. os_free(conn);
  279. return NULL;
  280. }
  281. conn->fd->secret = (void *) conn;
  282. conn->fd = SSL_ImportFD(NULL, conn->fd);
  283. if (conn->fd == NULL) {
  284. os_free(conn);
  285. return NULL;
  286. }
  287. if (SSL_OptionSet(conn->fd, SSL_SECURITY, PR_TRUE) != SECSuccess ||
  288. SSL_OptionSet(conn->fd, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE) !=
  289. SECSuccess ||
  290. SSL_OptionSet(conn->fd, SSL_HANDSHAKE_AS_SERVER, PR_FALSE) !=
  291. SECSuccess ||
  292. SSL_OptionSet(conn->fd, SSL_ENABLE_TLS, PR_TRUE) != SECSuccess ||
  293. SSL_BadCertHook(conn->fd, nss_bad_cert_cb, conn) != SECSuccess ||
  294. SSL_HandshakeCallback(conn->fd, nss_handshake_cb, conn) !=
  295. SECSuccess) {
  296. wpa_printf(MSG_ERROR, "NSS: Failed to set options");
  297. PR_Close(conn->fd);
  298. os_free(conn);
  299. return NULL;
  300. }
  301. SSL_ResetHandshake(conn->fd, PR_FALSE);
  302. return conn;
  303. }
  304. void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn)
  305. {
  306. PR_Close(conn->fd);
  307. os_free(conn->push_buf);
  308. os_free(conn->pull_buf);
  309. os_free(conn);
  310. }
  311. int tls_connection_established(void *tls_ctx, struct tls_connection *conn)
  312. {
  313. return conn->established;
  314. }
  315. int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn)
  316. {
  317. return -1;
  318. }
  319. int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
  320. const struct tls_connection_params *params)
  321. {
  322. wpa_printf(MSG_ERROR, "NSS: TODO - %s", __func__);
  323. return 0;
  324. }
  325. int tls_global_set_params(void *tls_ctx,
  326. const struct tls_connection_params *params)
  327. {
  328. return -1;
  329. }
  330. int tls_global_set_verify(void *tls_ctx, int check_crl)
  331. {
  332. return -1;
  333. }
  334. int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn,
  335. int verify_peer)
  336. {
  337. conn->verify_peer = verify_peer;
  338. return 0;
  339. }
  340. int tls_connection_set_ia(void *tls_ctx, struct tls_connection *conn,
  341. int tls_ia)
  342. {
  343. return -1;
  344. }
  345. int tls_connection_get_keys(void *tls_ctx, struct tls_connection *conn,
  346. struct tls_keys *keys)
  347. {
  348. /* NSS does not export master secret or client/server random. */
  349. return -1;
  350. }
  351. int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
  352. const char *label, int server_random_first,
  353. u8 *out, size_t out_len)
  354. {
  355. if (conn == NULL || server_random_first) {
  356. wpa_printf(MSG_INFO, "NSS: Unsupported PRF request "
  357. "(server_random_first=%d)",
  358. server_random_first);
  359. return -1;
  360. }
  361. if (SSL_ExportKeyingMaterial(conn->fd, label, NULL, 0, out, out_len) !=
  362. SECSuccess) {
  363. wpa_printf(MSG_INFO, "NSS: Failed to use TLS extractor "
  364. "(label='%s' out_len=%d", label, (int) out_len);
  365. return -1;
  366. }
  367. return 0;
  368. }
  369. struct wpabuf * tls_connection_handshake(void *tls_ctx,
  370. struct tls_connection *conn,
  371. const struct wpabuf *in_data,
  372. struct wpabuf **appl_data)
  373. {
  374. struct wpabuf *out_data;
  375. wpa_printf(MSG_DEBUG, "NSS: handshake: in_len=%u",
  376. in_data ? (unsigned int) wpabuf_len(in_data) : 0);
  377. if (appl_data)
  378. *appl_data = NULL;
  379. if (in_data && wpabuf_len(in_data) > 0) {
  380. if (conn->pull_buf) {
  381. wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in "
  382. "pull_buf", __func__,
  383. (unsigned long) conn->pull_buf_len);
  384. os_free(conn->pull_buf);
  385. }
  386. conn->pull_buf = os_malloc(wpabuf_len(in_data));
  387. if (conn->pull_buf == NULL)
  388. return NULL;
  389. os_memcpy(conn->pull_buf, wpabuf_head(in_data),
  390. wpabuf_len(in_data));
  391. conn->pull_buf_offset = conn->pull_buf;
  392. conn->pull_buf_len = wpabuf_len(in_data);
  393. }
  394. SSL_ForceHandshake(conn->fd);
  395. if (conn->established && conn->push_buf == NULL) {
  396. /* Need to return something to get final TLS ACK. */
  397. conn->push_buf = os_malloc(1);
  398. }
  399. if (conn->push_buf == NULL)
  400. return NULL;
  401. out_data = wpabuf_alloc_ext_data(conn->push_buf, conn->push_buf_len);
  402. if (out_data == NULL)
  403. os_free(conn->push_buf);
  404. conn->push_buf = NULL;
  405. conn->push_buf_len = 0;
  406. return out_data;
  407. }
  408. struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
  409. struct tls_connection *conn,
  410. const struct wpabuf *in_data,
  411. struct wpabuf **appl_data)
  412. {
  413. return NULL;
  414. }
  415. struct wpabuf * tls_connection_encrypt(void *tls_ctx,
  416. struct tls_connection *conn,
  417. const struct wpabuf *in_data)
  418. {
  419. PRInt32 res;
  420. struct wpabuf *buf;
  421. wpa_printf(MSG_DEBUG, "NSS: encrypt %d bytes",
  422. (int) wpabuf_len(in_data));
  423. res = PR_Send(conn->fd, wpabuf_head(in_data), wpabuf_len(in_data), 0,
  424. 0);
  425. if (res < 0) {
  426. wpa_printf(MSG_ERROR, "NSS: Encryption failed");
  427. return NULL;
  428. }
  429. if (conn->push_buf == NULL)
  430. return NULL;
  431. buf = wpabuf_alloc_ext_data(conn->push_buf, conn->push_buf_len);
  432. if (buf == NULL)
  433. os_free(conn->push_buf);
  434. conn->push_buf = NULL;
  435. conn->push_buf_len = 0;
  436. return buf;
  437. }
  438. struct wpabuf * tls_connection_decrypt(void *tls_ctx,
  439. struct tls_connection *conn,
  440. const struct wpabuf *in_data)
  441. {
  442. PRInt32 res;
  443. struct wpabuf *out;
  444. wpa_printf(MSG_DEBUG, "NSS: decrypt %d bytes",
  445. (int) wpabuf_len(in_data));
  446. if (conn->pull_buf) {
  447. wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in "
  448. "pull_buf", __func__,
  449. (unsigned long) conn->pull_buf_len);
  450. os_free(conn->pull_buf);
  451. }
  452. conn->pull_buf = os_malloc(wpabuf_len(in_data));
  453. if (conn->pull_buf == NULL)
  454. return NULL;
  455. os_memcpy(conn->pull_buf, wpabuf_head(in_data), wpabuf_len(in_data));
  456. conn->pull_buf_offset = conn->pull_buf;
  457. conn->pull_buf_len = wpabuf_len(in_data);
  458. /*
  459. * Even though we try to disable TLS compression, it is possible that
  460. * this cannot be done with all TLS libraries. Add extra buffer space
  461. * to handle the possibility of the decrypted data being longer than
  462. * input data.
  463. */
  464. out = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
  465. if (out == NULL)
  466. return NULL;
  467. res = PR_Recv(conn->fd, wpabuf_mhead(out), wpabuf_size(out), 0, 0);
  468. wpa_printf(MSG_DEBUG, "NSS: PR_Recv: %d", res);
  469. if (res < 0) {
  470. wpabuf_free(out);
  471. return NULL;
  472. }
  473. wpabuf_put(out, res);
  474. return out;
  475. }
  476. int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn)
  477. {
  478. return 0;
  479. }
  480. int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
  481. u8 *ciphers)
  482. {
  483. return -1;
  484. }
  485. int tls_get_cipher(void *tls_ctx, struct tls_connection *conn,
  486. char *buf, size_t buflen)
  487. {
  488. return -1;
  489. }
  490. int tls_connection_enable_workaround(void *tls_ctx,
  491. struct tls_connection *conn)
  492. {
  493. return -1;
  494. }
  495. int tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn,
  496. int ext_type, const u8 *data,
  497. size_t data_len)
  498. {
  499. return -1;
  500. }
  501. int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn)
  502. {
  503. return 0;
  504. }
  505. int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn)
  506. {
  507. return 0;
  508. }
  509. int tls_connection_get_write_alerts(void *tls_ctx,
  510. struct tls_connection *conn)
  511. {
  512. return 0;
  513. }
  514. int tls_connection_get_keyblock_size(void *tls_ctx,
  515. struct tls_connection *conn)
  516. {
  517. return -1;
  518. }
  519. unsigned int tls_capabilities(void *tls_ctx)
  520. {
  521. return 0;
  522. }
  523. struct wpabuf * tls_connection_ia_send_phase_finished(
  524. void *tls_ctx, struct tls_connection *conn, int final)
  525. {
  526. return NULL;
  527. }
  528. int tls_connection_ia_final_phase_finished(void *tls_ctx,
  529. struct tls_connection *conn)
  530. {
  531. return -1;
  532. }
  533. int tls_connection_ia_permute_inner_secret(void *tls_ctx,
  534. struct tls_connection *conn,
  535. const u8 *key, size_t key_len)
  536. {
  537. return -1;
  538. }
  539. int tls_connection_set_session_ticket_cb(void *tls_ctx,
  540. struct tls_connection *conn,
  541. tls_session_ticket_cb cb,
  542. void *ctx)
  543. {
  544. return -1;
  545. }