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