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