OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/socket/ssl_server_socket_nss.h" | 5 #include "net/socket/ssl_server_socket_nss.h" |
6 | 6 |
7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
8 #include <winsock2.h> | 8 #include <winsock2.h> |
9 #endif | 9 #endif |
10 | 10 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 CHECK(key_.get()); | 83 CHECK(key_.get()); |
84 } | 84 } |
85 | 85 |
86 SSLServerSocketNSS::~SSLServerSocketNSS() { | 86 SSLServerSocketNSS::~SSLServerSocketNSS() { |
87 if (nss_fd_ != NULL) { | 87 if (nss_fd_ != NULL) { |
88 PR_Close(nss_fd_); | 88 PR_Close(nss_fd_); |
89 nss_fd_ = NULL; | 89 nss_fd_ = NULL; |
90 } | 90 } |
91 } | 91 } |
92 | 92 |
93 int SSLServerSocketNSS::Init() { | |
94 // Initialize the NSS SSL library in a threadsafe way. This also | |
95 // initializes the NSS base library. | |
96 EnsureNSSSSLInit(); | |
97 if (!NSS_IsInitialized()) | |
98 return ERR_UNEXPECTED; | |
99 #if !defined(OS_MACOSX) && !defined(OS_WIN) | |
100 // We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop | |
101 // by MessageLoopForIO::current(). | |
102 // X509Certificate::Verify() runs on a worker thread of CertVerifier. | |
103 EnsureOCSPInit(); | |
104 #endif | |
105 | |
106 return OK; | |
107 } | |
108 | |
109 int SSLServerSocketNSS::Accept(CompletionCallback* callback) { | 93 int SSLServerSocketNSS::Accept(CompletionCallback* callback) { |
110 net_log_.BeginEvent(NetLog::TYPE_SSL_ACCEPT, NULL); | 94 net_log_.BeginEvent(NetLog::TYPE_SSL_ACCEPT, NULL); |
111 | 95 |
112 int rv = Init(); | 96 int rv = Init(); |
113 if (rv != OK) { | 97 if (rv != OK) { |
114 LOG(ERROR) << "Failed to initialize NSS"; | 98 LOG(ERROR) << "Failed to initialize NSS"; |
115 net_log_.EndEvent(NetLog::TYPE_SSL_ACCEPT, NULL); | 99 net_log_.EndEvent(NetLog::TYPE_SSL_ACCEPT, NULL); |
116 return rv; | 100 return rv; |
117 } | 101 } |
118 | 102 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 | 160 |
177 if (rv == ERR_IO_PENDING) { | 161 if (rv == ERR_IO_PENDING) { |
178 user_write_callback_ = callback; | 162 user_write_callback_ = callback; |
179 } else { | 163 } else { |
180 user_write_buf_ = NULL; | 164 user_write_buf_ = NULL; |
181 user_write_buf_len_ = 0; | 165 user_write_buf_len_ = 0; |
182 } | 166 } |
183 return rv; | 167 return rv; |
184 } | 168 } |
185 | 169 |
186 // static | 170 bool SSLServerSocketNSS::SetReceiveBufferSize(int32 size) { |
187 // NSS calls this if an incoming certificate needs to be verified. | 171 return false; |
188 // Do nothing but return SECSuccess. | |
189 // This is called only in full handshake mode. | |
190 // Peer certificate is retrieved in HandshakeCallback() later, which is called | |
191 // in full handshake mode or in resumption handshake mode. | |
192 SECStatus SSLServerSocketNSS::OwnAuthCertHandler(void* arg, | |
193 PRFileDesc* socket, | |
194 PRBool checksig, | |
195 PRBool is_server) { | |
196 // TODO(hclam): Implement. | |
197 // Tell NSS to not verify the certificate. | |
198 return SECSuccess; | |
199 } | 172 } |
200 | 173 |
201 // static | 174 bool SSLServerSocketNSS::SetSendBufferSize(int32 size) { |
202 // NSS calls this when handshake is completed. | 175 return false; |
203 // After the SSL handshake is finished we need to verify the certificate. | |
204 void SSLServerSocketNSS::HandshakeCallback(PRFileDesc* socket, | |
205 void* arg) { | |
206 // TODO(hclam): Implement. | |
207 } | 176 } |
208 | 177 |
209 int SSLServerSocketNSS::InitializeSSLOptions() { | 178 int SSLServerSocketNSS::InitializeSSLOptions() { |
210 // Transport connected, now hook it up to nss | 179 // Transport connected, now hook it up to nss |
211 // TODO(port): specify rx and tx buffer sizes separately | 180 // TODO(port): specify rx and tx buffer sizes separately |
212 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize); | 181 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize); |
213 if (nss_fd_ == NULL) { | 182 if (nss_fd_ == NULL) { |
214 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR error code. | 183 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR error code. |
215 } | 184 } |
216 | 185 |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 // Tell SSL we're a server; needed if not letting NSPR do socket I/O | 343 // Tell SSL we're a server; needed if not letting NSPR do socket I/O |
375 rv = SSL_ResetHandshake(nss_fd_, PR_TRUE); | 344 rv = SSL_ResetHandshake(nss_fd_, PR_TRUE); |
376 if (rv != SECSuccess) { | 345 if (rv != SECSuccess) { |
377 LogFailedNSSFunction(net_log_, "SSL_ResetHandshake", ""); | 346 LogFailedNSSFunction(net_log_, "SSL_ResetHandshake", ""); |
378 return ERR_UNEXPECTED; | 347 return ERR_UNEXPECTED; |
379 } | 348 } |
380 | 349 |
381 return OK; | 350 return OK; |
382 } | 351 } |
383 | 352 |
| 353 void SSLServerSocketNSS::OnSendComplete(int result) { |
| 354 if (next_handshake_state_ == STATE_HANDSHAKE) { |
| 355 // In handshake phase. |
| 356 OnHandshakeIOComplete(result); |
| 357 return; |
| 358 } |
| 359 |
| 360 if (!user_write_buf_ || !completed_handshake_) |
| 361 return; |
| 362 |
| 363 int rv = DoWriteLoop(result); |
| 364 if (rv != ERR_IO_PENDING) |
| 365 DoWriteCallback(rv); |
| 366 } |
| 367 |
| 368 void SSLServerSocketNSS::OnRecvComplete(int result) { |
| 369 if (next_handshake_state_ == STATE_HANDSHAKE) { |
| 370 // In handshake phase. |
| 371 OnHandshakeIOComplete(result); |
| 372 return; |
| 373 } |
| 374 |
| 375 // Network layer received some data, check if client requested to read |
| 376 // decrypted data. |
| 377 if (!user_read_buf_ || !completed_handshake_) |
| 378 return; |
| 379 |
| 380 int rv = DoReadLoop(result); |
| 381 if (rv != ERR_IO_PENDING) |
| 382 DoReadCallback(rv); |
| 383 } |
| 384 |
| 385 void SSLServerSocketNSS::OnHandshakeIOComplete(int result) { |
| 386 int rv = DoHandshakeLoop(result); |
| 387 if (rv != ERR_IO_PENDING) { |
| 388 net_log_.EndEvent(net::NetLog::TYPE_SSL_ACCEPT, NULL); |
| 389 if (user_accept_callback_) |
| 390 DoAcceptCallback(rv); |
| 391 } |
| 392 } |
| 393 |
384 // Return 0 for EOF, | 394 // Return 0 for EOF, |
385 // > 0 for bytes transferred immediately, | 395 // > 0 for bytes transferred immediately, |
386 // < 0 for error (or the non-error ERR_IO_PENDING). | 396 // < 0 for error (or the non-error ERR_IO_PENDING). |
387 int SSLServerSocketNSS::BufferSend(void) { | 397 int SSLServerSocketNSS::BufferSend(void) { |
388 if (transport_send_busy_) | 398 if (transport_send_busy_) |
389 return ERR_IO_PENDING; | 399 return ERR_IO_PENDING; |
390 | 400 |
391 const char* buf1; | 401 const char* buf1; |
392 const char* buf2; | 402 const char* buf2; |
393 unsigned int len1, len2; | 403 unsigned int len1, len2; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 char *buf; | 456 char *buf; |
447 memio_GetReadParams(nss_bufs_, &buf); | 457 memio_GetReadParams(nss_bufs_, &buf); |
448 memcpy(buf, recv_buffer_->data(), result); | 458 memcpy(buf, recv_buffer_->data(), result); |
449 } | 459 } |
450 recv_buffer_ = NULL; | 460 recv_buffer_ = NULL; |
451 memio_PutReadResult(nss_bufs_, MapErrorToNSS(result)); | 461 memio_PutReadResult(nss_bufs_, MapErrorToNSS(result)); |
452 transport_recv_busy_ = false; | 462 transport_recv_busy_ = false; |
453 OnRecvComplete(result); | 463 OnRecvComplete(result); |
454 } | 464 } |
455 | 465 |
456 void SSLServerSocketNSS::OnSendComplete(int result) { | |
457 if (next_handshake_state_ == STATE_HANDSHAKE) { | |
458 // In handshake phase. | |
459 OnHandshakeIOComplete(result); | |
460 return; | |
461 } | |
462 | |
463 if (!user_write_buf_ || !completed_handshake_) | |
464 return; | |
465 | |
466 int rv = DoWriteLoop(result); | |
467 if (rv != ERR_IO_PENDING) | |
468 DoWriteCallback(rv); | |
469 } | |
470 | |
471 void SSLServerSocketNSS::OnRecvComplete(int result) { | |
472 if (next_handshake_state_ == STATE_HANDSHAKE) { | |
473 // In handshake phase. | |
474 OnHandshakeIOComplete(result); | |
475 return; | |
476 } | |
477 | |
478 // Network layer received some data, check if client requested to read | |
479 // decrypted data. | |
480 if (!user_read_buf_ || !completed_handshake_) | |
481 return; | |
482 | |
483 int rv = DoReadLoop(result); | |
484 if (rv != ERR_IO_PENDING) | |
485 DoReadCallback(rv); | |
486 } | |
487 | |
488 void SSLServerSocketNSS::OnHandshakeIOComplete(int result) { | |
489 int rv = DoHandshakeLoop(result); | |
490 if (rv != ERR_IO_PENDING) { | |
491 net_log_.EndEvent(net::NetLog::TYPE_SSL_ACCEPT, NULL); | |
492 if (user_accept_callback_) | |
493 DoAcceptCallback(rv); | |
494 } | |
495 } | |
496 | |
497 void SSLServerSocketNSS::DoAcceptCallback(int rv) { | |
498 DCHECK_NE(rv, ERR_IO_PENDING); | |
499 | |
500 CompletionCallback* c = user_accept_callback_; | |
501 user_accept_callback_ = NULL; | |
502 c->Run(rv > OK ? OK : rv); | |
503 } | |
504 | |
505 void SSLServerSocketNSS::DoReadCallback(int rv) { | |
506 DCHECK(rv != ERR_IO_PENDING); | |
507 DCHECK(user_read_callback_); | |
508 | |
509 // Since Run may result in Read being called, clear |user_read_callback_| | |
510 // up front. | |
511 CompletionCallback* c = user_read_callback_; | |
512 user_read_callback_ = NULL; | |
513 user_read_buf_ = NULL; | |
514 user_read_buf_len_ = 0; | |
515 c->Run(rv); | |
516 } | |
517 | |
518 void SSLServerSocketNSS::DoWriteCallback(int rv) { | |
519 DCHECK(rv != ERR_IO_PENDING); | |
520 DCHECK(user_write_callback_); | |
521 | |
522 // Since Run may result in Write being called, clear |user_write_callback_| | |
523 // up front. | |
524 CompletionCallback* c = user_write_callback_; | |
525 user_write_callback_ = NULL; | |
526 user_write_buf_ = NULL; | |
527 user_write_buf_len_ = 0; | |
528 c->Run(rv); | |
529 } | |
530 | |
531 // Do network I/O between the given buffer and the given socket. | 466 // Do network I/O between the given buffer and the given socket. |
532 // Return true if some I/O performed, false otherwise (error or ERR_IO_PENDING) | 467 // Return true if some I/O performed, false otherwise (error or ERR_IO_PENDING) |
533 bool SSLServerSocketNSS::DoTransportIO() { | 468 bool SSLServerSocketNSS::DoTransportIO() { |
534 bool network_moved = false; | 469 bool network_moved = false; |
535 if (nss_bufs_ != NULL) { | 470 if (nss_bufs_ != NULL) { |
536 int nsent = BufferSend(); | 471 int nsent = BufferSend(); |
537 int nreceived = BufferRecv(); | 472 int nreceived = BufferRecv(); |
538 network_moved = (nsent > 0 || nreceived >= 0); | 473 network_moved = (nsent > 0 || nreceived >= 0); |
539 } | 474 } |
540 return network_moved; | 475 return network_moved; |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
667 LOG(ERROR) << "handshake failed; NSS error code " << prerr | 602 LOG(ERROR) << "handshake failed; NSS error code " << prerr |
668 << ", net_error " << net_error; | 603 << ", net_error " << net_error; |
669 net_log_.AddEvent( | 604 net_log_.AddEvent( |
670 NetLog::TYPE_SSL_HANDSHAKE_ERROR, | 605 NetLog::TYPE_SSL_HANDSHAKE_ERROR, |
671 make_scoped_refptr(new SSLErrorParams(net_error, prerr))); | 606 make_scoped_refptr(new SSLErrorParams(net_error, prerr))); |
672 } | 607 } |
673 } | 608 } |
674 return net_error; | 609 return net_error; |
675 } | 610 } |
676 | 611 |
| 612 void SSLServerSocketNSS::DoAcceptCallback(int rv) { |
| 613 DCHECK_NE(rv, ERR_IO_PENDING); |
| 614 |
| 615 CompletionCallback* c = user_accept_callback_; |
| 616 user_accept_callback_ = NULL; |
| 617 c->Run(rv > OK ? OK : rv); |
| 618 } |
| 619 |
| 620 void SSLServerSocketNSS::DoReadCallback(int rv) { |
| 621 DCHECK(rv != ERR_IO_PENDING); |
| 622 DCHECK(user_read_callback_); |
| 623 |
| 624 // Since Run may result in Read being called, clear |user_read_callback_| |
| 625 // up front. |
| 626 CompletionCallback* c = user_read_callback_; |
| 627 user_read_callback_ = NULL; |
| 628 user_read_buf_ = NULL; |
| 629 user_read_buf_len_ = 0; |
| 630 c->Run(rv); |
| 631 } |
| 632 |
| 633 void SSLServerSocketNSS::DoWriteCallback(int rv) { |
| 634 DCHECK(rv != ERR_IO_PENDING); |
| 635 DCHECK(user_write_callback_); |
| 636 |
| 637 // Since Run may result in Write being called, clear |user_write_callback_| |
| 638 // up front. |
| 639 CompletionCallback* c = user_write_callback_; |
| 640 user_write_callback_ = NULL; |
| 641 user_write_buf_ = NULL; |
| 642 user_write_buf_len_ = 0; |
| 643 c->Run(rv); |
| 644 } |
| 645 |
| 646 // static |
| 647 // NSS calls this if an incoming certificate needs to be verified. |
| 648 // Do nothing but return SECSuccess. |
| 649 // This is called only in full handshake mode. |
| 650 // Peer certificate is retrieved in HandshakeCallback() later, which is called |
| 651 // in full handshake mode or in resumption handshake mode. |
| 652 SECStatus SSLServerSocketNSS::OwnAuthCertHandler(void* arg, |
| 653 PRFileDesc* socket, |
| 654 PRBool checksig, |
| 655 PRBool is_server) { |
| 656 // TODO(hclam): Implement. |
| 657 // Tell NSS to not verify the certificate. |
| 658 return SECSuccess; |
| 659 } |
| 660 |
| 661 // static |
| 662 // NSS calls this when handshake is completed. |
| 663 // After the SSL handshake is finished we need to verify the certificate. |
| 664 void SSLServerSocketNSS::HandshakeCallback(PRFileDesc* socket, |
| 665 void* arg) { |
| 666 // TODO(hclam): Implement. |
| 667 } |
| 668 |
| 669 int SSLServerSocketNSS::Init() { |
| 670 // Initialize the NSS SSL library in a threadsafe way. This also |
| 671 // initializes the NSS base library. |
| 672 EnsureNSSSSLInit(); |
| 673 if (!NSS_IsInitialized()) |
| 674 return ERR_UNEXPECTED; |
| 675 #if !defined(OS_MACOSX) && !defined(OS_WIN) |
| 676 // We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop |
| 677 // by MessageLoopForIO::current(). |
| 678 // X509Certificate::Verify() runs on a worker thread of CertVerifier. |
| 679 EnsureOCSPInit(); |
| 680 #endif |
| 681 |
| 682 return OK; |
| 683 } |
| 684 |
677 } // namespace net | 685 } // namespace net |
OLD | NEW |