00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "includes.h"
00016 #include <nspr/prtypes.h>
00017 #include <nspr/plarenas.h>
00018 #include <nspr/plhash.h>
00019 #include <nspr/prio.h>
00020 #include <nspr/prclist.h>
00021 #include <nspr/prlock.h>
00022 #include <nspr/prinit.h>
00023 #include <nspr/prerror.h>
00024 #include <nspr/prmem.h>
00025 #include <nss/nss.h>
00026 #include <nss/nssilckt.h>
00027 #include <nss/ssl.h>
00028 #include <nss/pk11func.h>
00029 #include <nss/secerr.h>
00030
00031 #include "common.h"
00032 #include "tls.h"
00033
00034 static int tls_nss_ref_count = 0;
00035
00036 static PRDescIdentity nss_layer_id;
00037
00038
00039 struct tls_connection {
00040 PRFileDesc *fd;
00041
00042 int established;
00043 int verify_peer;
00044 u8 *push_buf, *pull_buf, *pull_buf_offset;
00045 size_t push_buf_len, pull_buf_len;
00046 };
00047
00048
00049 static PRStatus nss_io_close(PRFileDesc *fd)
00050 {
00051 wpa_printf(MSG_DEBUG, "NSS: I/O close");
00052 return PR_SUCCESS;
00053 }
00054
00055
00056 static PRInt32 nss_io_read(PRFileDesc *fd, void *buf, PRInt32 amount)
00057 {
00058 wpa_printf(MSG_DEBUG, "NSS: I/O read(%d)", amount);
00059 return PR_FAILURE;
00060 }
00061
00062
00063 static PRInt32 nss_io_write(PRFileDesc *fd, const void *buf, PRInt32 amount)
00064 {
00065 wpa_printf(MSG_DEBUG, "NSS: I/O write(%d)", amount);
00066 return PR_FAILURE;
00067 }
00068
00069
00070 static PRInt32 nss_io_writev(PRFileDesc *fd, const PRIOVec *iov,
00071 PRInt32 iov_size, PRIntervalTime timeout)
00072 {
00073 wpa_printf(MSG_DEBUG, "NSS: I/O writev(%d)", iov_size);
00074 return PR_FAILURE;
00075 }
00076
00077
00078 static PRInt32 nss_io_recv(PRFileDesc *fd, void *buf, PRInt32 amount,
00079 PRIntn flags, PRIntervalTime timeout)
00080 {
00081 struct tls_connection *conn = (struct tls_connection *) fd->secret;
00082 u8 *end;
00083
00084 wpa_printf(MSG_DEBUG, "NSS: I/O recv(%d)", amount);
00085
00086 if (conn->pull_buf == NULL) {
00087 wpa_printf(MSG_DEBUG, "NSS: No data available to be read yet");
00088 return PR_FAILURE;
00089 }
00090
00091 end = conn->pull_buf + conn->pull_buf_len;
00092 if (end - conn->pull_buf_offset < amount)
00093 amount = end - conn->pull_buf_offset;
00094 os_memcpy(buf, conn->pull_buf_offset, amount);
00095 conn->pull_buf_offset += amount;
00096 if (conn->pull_buf_offset == end) {
00097 wpa_printf(MSG_DEBUG, "%s - pull_buf consumed", __func__);
00098 os_free(conn->pull_buf);
00099 conn->pull_buf = conn->pull_buf_offset = NULL;
00100 conn->pull_buf_len = 0;
00101 } else {
00102 wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in pull_buf",
00103 __func__,
00104 (unsigned long) (end - conn->pull_buf_offset));
00105 }
00106 return amount;
00107 }
00108
00109
00110 static PRInt32 nss_io_send(PRFileDesc *fd, const void *buf, PRInt32 amount,
00111 PRIntn flags, PRIntervalTime timeout)
00112 {
00113 struct tls_connection *conn = (struct tls_connection *) fd->secret;
00114 u8 *nbuf;
00115
00116 wpa_printf(MSG_DEBUG, "NSS: I/O %s", __func__);
00117 wpa_hexdump(MSG_MSGDUMP, "NSS: I/O send data", buf, amount);
00118
00119 nbuf = os_realloc(conn->push_buf, conn->push_buf_len + amount);
00120 if (nbuf == NULL) {
00121 wpa_printf(MSG_ERROR, "NSS: Failed to allocate memory for the "
00122 "data to be sent");
00123 return PR_FAILURE;
00124 }
00125 os_memcpy(nbuf + conn->push_buf_len, buf, amount);
00126 conn->push_buf = nbuf;
00127 conn->push_buf_len += amount;
00128
00129 return amount;
00130 }
00131
00132
00133 static PRInt32 nss_io_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount,
00134 PRIntn flags, PRNetAddr *addr,
00135 PRIntervalTime timeout)
00136 {
00137 wpa_printf(MSG_DEBUG, "NSS: I/O %s", __func__);
00138 return PR_FAILURE;
00139 }
00140
00141
00142 static PRInt32 nss_io_sendto(PRFileDesc *fd, const void *buf, PRInt32 amount,
00143 PRIntn flags, const PRNetAddr *addr,
00144 PRIntervalTime timeout)
00145 {
00146 wpa_printf(MSG_DEBUG, "NSS: I/O %s", __func__);
00147 return PR_FAILURE;
00148 }
00149
00150
00151 static PRStatus nss_io_getpeername(PRFileDesc *fd, PRNetAddr *addr)
00152 {
00153 wpa_printf(MSG_DEBUG, "NSS: I/O getpeername");
00154
00155
00156
00157
00158
00159
00160 os_memset(addr, 0, sizeof(*addr));
00161 addr->inet.family = PR_AF_INET;
00162
00163 return PR_SUCCESS;
00164 }
00165
00166
00167 static PRStatus nss_io_getsocketoption(PRFileDesc *fd,
00168 PRSocketOptionData *data)
00169 {
00170 switch (data->option) {
00171 case PR_SockOpt_Nonblocking:
00172 wpa_printf(MSG_DEBUG, "NSS: I/O getsocketoption(Nonblocking)");
00173 data->value.non_blocking = PR_TRUE;
00174 return PR_SUCCESS;
00175 default:
00176 wpa_printf(MSG_DEBUG, "NSS: I/O getsocketoption(%d)",
00177 data->option);
00178 return PR_FAILURE;
00179 }
00180 }
00181
00182
00183 static const PRIOMethods nss_io = {
00184 PR_DESC_LAYERED,
00185 nss_io_close,
00186 nss_io_read,
00187 nss_io_write,
00188 NULL ,
00189 NULL ,
00190 NULL ,
00191 NULL ,
00192 NULL ,
00193 NULL ,
00194 NULL ,
00195 nss_io_writev,
00196 NULL ,
00197 NULL ,
00198 NULL ,
00199 NULL ,
00200 NULL ,
00201 nss_io_recv,
00202 nss_io_send,
00203 nss_io_recvfrom,
00204 nss_io_sendto,
00205 NULL ,
00206 NULL ,
00207 NULL ,
00208 NULL ,
00209 nss_io_getpeername,
00210 NULL ,
00211 NULL ,
00212 nss_io_getsocketoption,
00213 NULL ,
00214 NULL ,
00215 NULL ,
00216 NULL ,
00217 NULL ,
00218 NULL ,
00219 NULL
00220 };
00221
00222
00223 static char * nss_password_cb(PK11SlotInfo *slot, PRBool retry, void *arg)
00224 {
00225 wpa_printf(MSG_ERROR, "NSS: TODO - %s", __func__);
00226 return NULL;
00227 }
00228
00229
00230 void * tls_init(const struct tls_config *conf)
00231 {
00232 char *dir;
00233
00234 tls_nss_ref_count++;
00235 if (tls_nss_ref_count > 1)
00236 return (void *) 1;
00237
00238 PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
00239
00240 nss_layer_id = PR_GetUniqueIdentity("wpa_supplicant");
00241
00242 PK11_SetPasswordFunc(nss_password_cb);
00243
00244 dir = getenv("SSL_DIR");
00245 if (dir) {
00246 if (NSS_Init(dir) != SECSuccess) {
00247 wpa_printf(MSG_ERROR, "NSS: NSS_Init(cert_dir=%s) "
00248 "failed", dir);
00249 return NULL;
00250 }
00251 } else {
00252 if (NSS_NoDB_Init(NULL) != SECSuccess) {
00253 wpa_printf(MSG_ERROR, "NSS: NSS_NoDB_Init(NULL) "
00254 "failed");
00255 return NULL;
00256 }
00257 }
00258
00259 if (SSL_OptionSetDefault(SSL_V2_COMPATIBLE_HELLO, PR_FALSE) !=
00260 SECSuccess ||
00261 SSL_OptionSetDefault(SSL_ENABLE_SSL3, PR_FALSE) != SECSuccess ||
00262 SSL_OptionSetDefault(SSL_ENABLE_SSL2, PR_FALSE) != SECSuccess ||
00263 SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE) != SECSuccess) {
00264 wpa_printf(MSG_ERROR, "NSS: SSL_OptionSetDefault failed");
00265 return NULL;
00266 }
00267
00268 if (NSS_SetDomesticPolicy() != SECSuccess) {
00269 wpa_printf(MSG_ERROR, "NSS: NSS_SetDomesticPolicy() failed");
00270 return NULL;
00271 }
00272
00273 return (void *) 1;
00274 }
00275
00276 void tls_deinit(void *ssl_ctx)
00277 {
00278 tls_nss_ref_count--;
00279 if (tls_nss_ref_count == 0) {
00280 if (NSS_Shutdown() != SECSuccess)
00281 wpa_printf(MSG_ERROR, "NSS: NSS_Shutdown() failed");
00282 }
00283 }
00284
00285
00286 int tls_get_errors(void *tls_ctx)
00287 {
00288 return 0;
00289 }
00290
00291
00292 static SECStatus nss_bad_cert_cb(void *arg, PRFileDesc *fd)
00293 {
00294 struct tls_connection *conn = arg;
00295 SECStatus res = SECSuccess;
00296 PRErrorCode err;
00297 CERTCertificate *cert;
00298 char *subject, *issuer;
00299
00300 err = PR_GetError();
00301 if (IS_SEC_ERROR(err))
00302 wpa_printf(MSG_DEBUG, "NSS: Bad Server Certificate (sec err "
00303 "%d)", err - SEC_ERROR_BASE);
00304 else
00305 wpa_printf(MSG_DEBUG, "NSS: Bad Server Certificate (err %d)",
00306 err);
00307 cert = SSL_PeerCertificate(fd);
00308 subject = CERT_NameToAscii(&cert->subject);
00309 issuer = CERT_NameToAscii(&cert->issuer);
00310 wpa_printf(MSG_DEBUG, "NSS: Peer certificate subject='%s' issuer='%s'",
00311 subject, issuer);
00312 CERT_DestroyCertificate(cert);
00313 PR_Free(subject);
00314 PR_Free(issuer);
00315 if (conn->verify_peer)
00316 res = SECFailure;
00317
00318 return res;
00319 }
00320
00321
00322 static void nss_handshake_cb(PRFileDesc *fd, void *client_data)
00323 {
00324 struct tls_connection *conn = client_data;
00325 wpa_printf(MSG_DEBUG, "NSS: Handshake completed");
00326 conn->established = 1;
00327 }
00328
00329
00330 struct tls_connection * tls_connection_init(void *tls_ctx)
00331 {
00332 struct tls_connection *conn;
00333
00334 conn = os_zalloc(sizeof(*conn));
00335 if (conn == NULL)
00336 return NULL;
00337
00338 conn->fd = PR_CreateIOLayerStub(nss_layer_id, &nss_io);
00339 if (conn->fd == NULL) {
00340 os_free(conn);
00341 return NULL;
00342 }
00343 conn->fd->secret = (void *) conn;
00344
00345 conn->fd = SSL_ImportFD(NULL, conn->fd);
00346 if (conn->fd == NULL) {
00347 os_free(conn);
00348 return NULL;
00349 }
00350
00351 if (SSL_OptionSet(conn->fd, SSL_SECURITY, PR_TRUE) != SECSuccess ||
00352 SSL_OptionSet(conn->fd, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE) !=
00353 SECSuccess ||
00354 SSL_OptionSet(conn->fd, SSL_HANDSHAKE_AS_SERVER, PR_FALSE) !=
00355 SECSuccess ||
00356 SSL_OptionSet(conn->fd, SSL_ENABLE_TLS, PR_TRUE) != SECSuccess ||
00357 SSL_BadCertHook(conn->fd, nss_bad_cert_cb, conn) != SECSuccess ||
00358 SSL_HandshakeCallback(conn->fd, nss_handshake_cb, conn) !=
00359 SECSuccess) {
00360 wpa_printf(MSG_ERROR, "NSS: Failed to set options");
00361 PR_Close(conn->fd);
00362 os_free(conn);
00363 return NULL;
00364 }
00365
00366 SSL_ResetHandshake(conn->fd, PR_FALSE);
00367
00368 return conn;
00369 }
00370
00371
00372 void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn)
00373 {
00374 PR_Close(conn->fd);
00375 os_free(conn->push_buf);
00376 os_free(conn->pull_buf);
00377 os_free(conn);
00378 }
00379
00380
00381 int tls_connection_established(void *tls_ctx, struct tls_connection *conn)
00382 {
00383 return conn->established;
00384 }
00385
00386
00387 int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn)
00388 {
00389 return -1;
00390 }
00391
00392
00393 int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
00394 const struct tls_connection_params *params)
00395 {
00396 wpa_printf(MSG_ERROR, "NSS: TODO - %s", __func__);
00397 return 0;
00398 }
00399
00400
00401 int tls_global_set_params(void *tls_ctx,
00402 const struct tls_connection_params *params)
00403 {
00404 return -1;
00405 }
00406
00407
00408 int tls_global_set_verify(void *tls_ctx, int check_crl)
00409 {
00410 return -1;
00411 }
00412
00413
00414 int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn,
00415 int verify_peer)
00416 {
00417 conn->verify_peer = verify_peer;
00418 return 0;
00419 }
00420
00421
00422 int tls_connection_set_ia(void *tls_ctx, struct tls_connection *conn,
00423 int tls_ia)
00424 {
00425 return -1;
00426 }
00427
00428
00429 int tls_connection_get_keys(void *tls_ctx, struct tls_connection *conn,
00430 struct tls_keys *keys)
00431 {
00432
00433 return -1;
00434 }
00435
00436
00437 int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
00438 const char *label, int server_random_first,
00439 u8 *out, size_t out_len)
00440 {
00441 if (conn == NULL || server_random_first) {
00442 wpa_printf(MSG_INFO, "NSS: Unsupported PRF request "
00443 "(server_random_first=%d)",
00444 server_random_first);
00445 return -1;
00446 }
00447
00448 if (SSL_ExportKeyingMaterial(conn->fd, label, NULL, 0, out, out_len) !=
00449 SECSuccess) {
00450 wpa_printf(MSG_INFO, "NSS: Failed to use TLS extractor "
00451 "(label='%s' out_len=%d", label, (int) out_len);
00452 return -1;
00453 }
00454
00455 return 0;
00456 }
00457
00458
00459 struct wpabuf * tls_connection_handshake(void *tls_ctx,
00460 struct tls_connection *conn,
00461 const struct wpabuf *in_data,
00462 struct wpabuf **appl_data)
00463 {
00464 struct wpabuf *out_data;
00465
00466 wpa_printf(MSG_DEBUG, "NSS: handshake: in_len=%u",
00467 in_data ? (unsigned int) wpabuf_len(in_data) : 0);
00468
00469 if (appl_data)
00470 *appl_data = NULL;
00471
00472 if (in_data && wpabuf_len(in_data) > 0) {
00473 if (conn->pull_buf) {
00474 wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in "
00475 "pull_buf", __func__,
00476 (unsigned long) conn->pull_buf_len);
00477 os_free(conn->pull_buf);
00478 }
00479 conn->pull_buf = os_malloc(wpabuf_len(in_data));
00480 if (conn->pull_buf == NULL)
00481 return NULL;
00482 os_memcpy(conn->pull_buf, wpabuf_head(in_data),
00483 wpabuf_len(in_data));
00484 conn->pull_buf_offset = conn->pull_buf;
00485 conn->pull_buf_len = wpabuf_len(in_data);
00486 }
00487
00488 SSL_ForceHandshake(conn->fd);
00489
00490 if (conn->established && conn->push_buf == NULL) {
00491
00492 conn->push_buf = os_malloc(1);
00493 }
00494
00495 if (conn->push_buf == NULL)
00496 return NULL;
00497 out_data = wpabuf_alloc_ext_data(conn->push_buf, conn->push_buf_len);
00498 if (out_data == NULL)
00499 os_free(conn->push_buf);
00500 conn->push_buf = NULL;
00501 conn->push_buf_len = 0;
00502 return out_data;
00503 }
00504
00505
00506 struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
00507 struct tls_connection *conn,
00508 const struct wpabuf *in_data,
00509 struct wpabuf **appl_data)
00510 {
00511 return NULL;
00512 }
00513
00514
00515 struct wpabuf * tls_connection_encrypt(void *tls_ctx,
00516 struct tls_connection *conn,
00517 const struct wpabuf *in_data)
00518 {
00519 PRInt32 res;
00520 struct wpabuf *buf;
00521
00522 wpa_printf(MSG_DEBUG, "NSS: encrypt %d bytes",
00523 (int) wpabuf_len(in_data));
00524 res = PR_Send(conn->fd, wpabuf_head(in_data), wpabuf_len(in_data), 0,
00525 0);
00526 if (res < 0) {
00527 wpa_printf(MSG_ERROR, "NSS: Encryption failed");
00528 return NULL;
00529 }
00530 if (conn->push_buf == NULL)
00531 return NULL;
00532 buf = wpabuf_alloc_ext_data(conn->push_buf, conn->push_buf_len);
00533 if (buf == NULL)
00534 os_free(conn->push_buf);
00535 conn->push_buf = NULL;
00536 conn->push_buf_len = 0;
00537 return buf;
00538 }
00539
00540
00541 struct wpabuf * tls_connection_decrypt(void *tls_ctx,
00542 struct tls_connection *conn,
00543 const struct wpabuf *in_data)
00544 {
00545 PRInt32 res;
00546 struct wpabuf *out;
00547
00548 wpa_printf(MSG_DEBUG, "NSS: decrypt %d bytes",
00549 (int) wpabuf_len(in_data));
00550 if (conn->pull_buf) {
00551 wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in "
00552 "pull_buf", __func__,
00553 (unsigned long) conn->pull_buf_len);
00554 os_free(conn->pull_buf);
00555 }
00556 conn->pull_buf = os_malloc(wpabuf_len(in_data));
00557 if (conn->pull_buf == NULL)
00558 return NULL;
00559 os_memcpy(conn->pull_buf, wpabuf_head(in_data), wpabuf_len(in_data));
00560 conn->pull_buf_offset = conn->pull_buf;
00561 conn->pull_buf_len = wpabuf_len(in_data);
00562
00563
00564
00565
00566
00567
00568
00569 out = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
00570 if (out == NULL)
00571 return NULL;
00572
00573 res = PR_Recv(conn->fd, wpabuf_mhead(out), wpabuf_size(out), 0, 0);
00574 wpa_printf(MSG_DEBUG, "NSS: PR_Recv: %d", res);
00575 if (res < 0) {
00576 wpabuf_free(out);
00577 return NULL;
00578 }
00579 wpabuf_put(out, res);
00580
00581 return out;
00582 }
00583
00584
00585 int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn)
00586 {
00587 return 0;
00588 }
00589
00590
00591 int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
00592 u8 *ciphers)
00593 {
00594 return -1;
00595 }
00596
00597
00598 int tls_get_cipher(void *tls_ctx, struct tls_connection *conn,
00599 char *buf, size_t buflen)
00600 {
00601 return -1;
00602 }
00603
00604
00605 int tls_connection_enable_workaround(void *tls_ctx,
00606 struct tls_connection *conn)
00607 {
00608 return -1;
00609 }
00610
00611
00612 int tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn,
00613 int ext_type, const u8 *data,
00614 size_t data_len)
00615 {
00616 return -1;
00617 }
00618
00619
00620 int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn)
00621 {
00622 return 0;
00623 }
00624
00625
00626 int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn)
00627 {
00628 return 0;
00629 }
00630
00631
00632 int tls_connection_get_write_alerts(void *tls_ctx,
00633 struct tls_connection *conn)
00634 {
00635 return 0;
00636 }
00637
00638
00639 int tls_connection_get_keyblock_size(void *tls_ctx,
00640 struct tls_connection *conn)
00641 {
00642 return -1;
00643 }
00644
00645
00646 unsigned int tls_capabilities(void *tls_ctx)
00647 {
00648 return 0;
00649 }
00650
00651
00652 struct wpabuf * tls_connection_ia_send_phase_finished(
00653 void *tls_ctx, struct tls_connection *conn, int final)
00654 {
00655 return NULL;
00656 }
00657
00658
00659 int tls_connection_ia_final_phase_finished(void *tls_ctx,
00660 struct tls_connection *conn)
00661 {
00662 return -1;
00663 }
00664
00665
00666 int tls_connection_ia_permute_inner_secret(void *tls_ctx,
00667 struct tls_connection *conn,
00668 const u8 *key, size_t key_len)
00669 {
00670 return -1;
00671 }
00672
00673
00674 int tls_connection_set_session_ticket_cb(void *tls_ctx,
00675 struct tls_connection *conn,
00676 tls_session_ticket_cb cb,
00677 void *ctx)
00678 {
00679 return -1;
00680 }