Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(369)

Side by Side Diff: net/socket/ssl_server_socket_nss.cc

Issue 5746003: Defines SSLServerSocket and implements SSLServerSocketNSS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: convert cert and key Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/socket/ssl_server_socket_nss.h ('k') | net/socket/ssl_server_socket_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "net/socket/ssl_server_socket_nss.h"
6
7 #if defined(OS_WIN)
8 #include <winsock2.h>
9 #endif
10
11 #if defined(USE_SYSTEM_SSL)
12 #include <dlfcn.h>
13 #endif
14 #if defined(OS_MACOSX)
15 #include <Security/Security.h>
16 #endif
17 #include <certdb.h>
18 #include <cryptohi.h>
19 #include <hasht.h>
20 #include <keyhi.h>
21 #include <nspr.h>
22 #include <nss.h>
23 #include <pk11pub.h>
24 #include <secerr.h>
25 #include <sechash.h>
26 #include <ssl.h>
27 #include <sslerr.h>
28 #include <sslproto.h>
29
30 #include <limits>
31
32 #include "base/crypto/rsa_private_key.h"
33 #include "base/nss_util_internal.h"
34 #include "base/ref_counted.h"
35 #include "net/base/io_buffer.h"
36 #include "net/base/net_errors.h"
37 #include "net/base/net_log.h"
38 #include "net/ocsp/nss_ocsp.h"
39 #include "net/socket/nss_ssl_util.h"
40 #include "net/socket/ssl_error_params.h"
41
42 static const int kRecvBufferSize = 4096;
43
44 #define GotoState(s) next_handshake_state_ = s
45
46 namespace net {
47
48 SSLServerSocket* CreateSSLServerSocket(
49 Socket* socket, X509Certificate* cert, base::RSAPrivateKey* key,
50 const SSLConfig& ssl_config) {
51 return new SSLServerSocketNSS(socket, cert, key, ssl_config);
52 }
53
54 SSLServerSocketNSS::SSLServerSocketNSS(
55 Socket* transport_socket,
56 scoped_refptr<X509Certificate> cert,
57 base::RSAPrivateKey* key,
58 const SSLConfig& ssl_config)
59 : ALLOW_THIS_IN_INITIALIZER_LIST(buffer_send_callback_(
60 this, &SSLServerSocketNSS::BufferSendComplete)),
61 ALLOW_THIS_IN_INITIALIZER_LIST(buffer_recv_callback_(
62 this, &SSLServerSocketNSS::BufferRecvComplete)),
63 transport_send_busy_(false),
64 transport_recv_busy_(false),
65 user_accept_callback_(NULL),
66 user_read_callback_(NULL),
67 user_write_callback_(NULL),
68 nss_fd_(NULL),
69 nss_bufs_(NULL),
70 transport_socket_(transport_socket),
71 ssl_config_(ssl_config),
72 cert_(cert),
73 next_handshake_state_(STATE_NONE),
74 completed_handshake_(false) {
75 ssl_config_.false_start_enabled = false;
76 ssl_config_.ssl3_enabled = true;
77 ssl_config_.tls1_enabled = true;
78
79 // TODO(hclam): Need a better way to clone a key.
80 std::vector<uint8> key_bytes;
81 CHECK(key->ExportPrivateKey(&key_bytes));
82 key_.reset(base::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes));
83 CHECK(key_.get());
84 }
85
86 SSLServerSocketNSS::~SSLServerSocketNSS() {
87 if (nss_fd_ != NULL) {
88 PR_Close(nss_fd_);
89 nss_fd_ = NULL;
90 }
91 }
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) {
110 net_log_.BeginEvent(NetLog::TYPE_SSL_ACCEPT, NULL);
111
112 int rv = Init();
113 if (rv != OK) {
114 LOG(ERROR) << "Failed to initialize NSS";
115 net_log_.EndEvent(NetLog::TYPE_SSL_ACCEPT, NULL);
116 return rv;
117 }
118
119 rv = InitializeSSLOptions();
120 if (rv != OK) {
121 LOG(ERROR) << "Failed to initialize SSL options";
122 net_log_.EndEvent(NetLog::TYPE_SSL_ACCEPT, NULL);
123 return rv;
124 }
125
126 // Set peer address. TODO(hclam): This should be in a separate method.
127 PRNetAddr peername;
128 memset(&peername, 0, sizeof(peername));
129 peername.raw.family = AF_INET;
130 memio_SetPeerName(nss_fd_, &peername);
131
132 GotoState(STATE_HANDSHAKE);
133 rv = DoHandshakeLoop(net::OK);
134 if (rv == ERR_IO_PENDING) {
135 user_accept_callback_ = callback;
136 } else {
137 net_log_.EndEvent(NetLog::TYPE_SSL_ACCEPT, NULL);
138 }
139
140 return rv > OK ? OK : rv;
141 }
142
143 int SSLServerSocketNSS::Read(IOBuffer* buf, int buf_len,
144 CompletionCallback* callback) {
145 DCHECK(!user_read_callback_);
146 DCHECK(!user_accept_callback_);
147 DCHECK(!user_read_buf_);
148 DCHECK(nss_bufs_);
149
150 user_read_buf_ = buf;
151 user_read_buf_len_ = buf_len;
152
153 DCHECK(completed_handshake_);
154
155 int rv = DoReadLoop(OK);
156
157 if (rv == ERR_IO_PENDING) {
158 user_read_callback_ = callback;
159 } else {
160 user_read_buf_ = NULL;
161 user_read_buf_len_ = 0;
162 }
163 return rv;
164 }
165
166 int SSLServerSocketNSS::Write(IOBuffer* buf, int buf_len,
167 CompletionCallback* callback) {
168 DCHECK(!user_write_callback_);
169 DCHECK(!user_write_buf_);
170 DCHECK(nss_bufs_);
171
172 user_write_buf_ = buf;
173 user_write_buf_len_ = buf_len;
174
175 int rv = DoWriteLoop(OK);
176
177 if (rv == ERR_IO_PENDING) {
178 user_write_callback_ = callback;
179 } else {
180 user_write_buf_ = NULL;
181 user_write_buf_len_ = 0;
182 }
183 return rv;
184 }
185
186 // static
187 // NSS calls this if an incoming certificate needs to be verified.
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 }
200
201 // static
202 // NSS calls this when handshake is completed.
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 }
208
209 int SSLServerSocketNSS::InitializeSSLOptions() {
210 // Transport connected, now hook it up to nss
211 // TODO(port): specify rx and tx buffer sizes separately
212 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize);
213 if (nss_fd_ == NULL) {
214 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR error code.
215 }
216
217 // Grab pointer to buffers
218 nss_bufs_ = memio_GetSecret(nss_fd_);
219
220 /* Create SSL state machine */
221 /* Push SSL onto our fake I/O socket */
222 nss_fd_ = SSL_ImportFD(NULL, nss_fd_);
223 if (nss_fd_ == NULL) {
224 LogFailedNSSFunction(net_log_, "SSL_ImportFD", "");
225 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR/NSS error code.
226 }
227 // TODO(port): set more ssl options! Check errors!
228
229 int rv;
230
231 rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE);
232 if (rv != SECSuccess) {
233 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_SECURITY");
234 return ERR_UNEXPECTED;
235 }
236
237 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL2, PR_FALSE);
238 if (rv != SECSuccess) {
239 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL2");
240 return ERR_UNEXPECTED;
241 }
242
243 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL3, PR_TRUE);
244 if (rv != SECSuccess) {
245 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL3");
246 return ERR_UNEXPECTED;
247 }
248
249 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_TLS, ssl_config_.tls1_enabled);
250 if (rv != SECSuccess) {
251 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_TLS");
252 return ERR_UNEXPECTED;
253 }
254
255 for (std::vector<uint16>::const_iterator it =
256 ssl_config_.disabled_cipher_suites.begin();
257 it != ssl_config_.disabled_cipher_suites.end(); ++it) {
258 // This will fail if the specified cipher is not implemented by NSS, but
259 // the failure is harmless.
260 SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE);
261 }
262
263 // Server socket doesn't need session tickets.
264 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_FALSE);
265 if (rv != SECSuccess) {
266 LogFailedNSSFunction(
267 net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS");
268 }
269
270 // Doing this will force PR_Accept perform handshake as server.
271 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_FALSE);
272 if (rv != SECSuccess) {
273 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT");
274 return ERR_UNEXPECTED;
275 }
276
277 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_SERVER, PR_TRUE);
278 if (rv != SECSuccess) {
279 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_SERVER");
280 return ERR_UNEXPECTED;
281 }
282
283 rv = SSL_OptionSet(nss_fd_, SSL_REQUEST_CERTIFICATE, PR_FALSE);
284 if (rv != SECSuccess) {
285 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_REQUEST_CERTIFICATE");
286 return ERR_UNEXPECTED;
287 }
288
289 rv = SSL_OptionSet(nss_fd_, SSL_REQUIRE_CERTIFICATE, PR_FALSE);
290 if (rv != SECSuccess) {
291 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_REQUIRE_CERTIFICATE");
292 return ERR_UNEXPECTED;
293 }
294
295 rv = SSL_OptionSet(nss_fd_, SSL_NO_CACHE, PR_TRUE);
296 if (rv != SECSuccess) {
297 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_NO_CACHE");
298 return ERR_UNEXPECTED;
299 }
300
301 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this);
302 if (rv != SECSuccess) {
303 LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", "");
304 return ERR_UNEXPECTED;
305 }
306
307 rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this);
308 if (rv != SECSuccess) {
309 LogFailedNSSFunction(net_log_, "SSL_HandshakeCallback", "");
310 return ERR_UNEXPECTED;
311 }
312
313 // Get a certificate of CERTCertificate structure.
314 std::string der_string;
315 if (!cert_->GetDEREncoded(&der_string))
316 return ERR_UNEXPECTED;
317
318 SECItem der_cert;
319 der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(
320 der_string.data()));
321 der_cert.len = der_string.length();
322 der_cert.type = siDERCertBuffer;
323
324 // Parse into a CERTCertificate structure.
325 CERTCertificate* cert = CERT_NewTempCertificate(
326 CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE);
327
328 // Get a key of SECKEYPrivateKey* structure.
329 std::vector<uint8> key_vector;
330 if (!key_->ExportPrivateKey(&key_vector)) {
331 CERT_DestroyCertificate(cert);
332 return ERR_UNEXPECTED;
333 }
334
335 SECKEYPrivateKeyStr* private_key = NULL;
336 PK11SlotInfo *slot = base::GetDefaultNSSKeySlot();
337 if (!slot) {
338 CERT_DestroyCertificate(cert);
339 return ERR_UNEXPECTED;
340 }
341
342 SECItem der_private_key_info;
343 der_private_key_info.data =
344 const_cast<unsigned char*>(&key_vector.front());
345 der_private_key_info.len = key_vector.size();
346 rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
347 slot, &der_private_key_info, NULL, NULL, PR_FALSE, PR_FALSE,
348 KU_DIGITAL_SIGNATURE, &private_key, NULL);
349 PK11_FreeSlot(slot);
350 if (rv != SECSuccess) {
351 CERT_DestroyCertificate(cert);
352 return ERR_UNEXPECTED;
353 }
354
355 // Assign server certificate and private key.
356 SSLKEAType cert_kea = NSS_FindCertKEAType(cert);
357 rv = SSL_ConfigSecureServer(nss_fd_, cert, private_key, cert_kea);
358 CERT_DestroyCertificate(cert);
359 SECKEY_DestroyPrivateKey(private_key);
360
361 if (rv != SECSuccess) {
362 PRErrorCode prerr = PR_GetError();
363 LOG(ERROR) << "Failed to config SSL server: " << prerr;
364 LogFailedNSSFunction(net_log_, "SSL_ConfigureSecureServer", "");
365 return ERR_UNEXPECTED;
366 }
367
368 // Tell SSL we're a server; needed if not letting NSPR do socket I/O
369 rv = SSL_ResetHandshake(nss_fd_, PR_TRUE);
370 if (rv != SECSuccess) {
371 LogFailedNSSFunction(net_log_, "SSL_ResetHandshake", "");
372 return ERR_UNEXPECTED;
373 }
374
375 return OK;
376 }
377
378 // Return 0 for EOF,
379 // > 0 for bytes transferred immediately,
380 // < 0 for error (or the non-error ERR_IO_PENDING).
381 int SSLServerSocketNSS::BufferSend(void) {
382 if (transport_send_busy_)
383 return ERR_IO_PENDING;
384
385 const char* buf1;
386 const char* buf2;
387 unsigned int len1, len2;
388 memio_GetWriteParams(nss_bufs_, &buf1, &len1, &buf2, &len2);
389 const unsigned int len = len1 + len2;
390
391 int rv = 0;
392 if (len) {
393 scoped_refptr<IOBuffer> send_buffer(new IOBuffer(len));
394 memcpy(send_buffer->data(), buf1, len1);
395 memcpy(send_buffer->data() + len1, buf2, len2);
396 rv = transport_socket_->Write(send_buffer, len,
397 &buffer_send_callback_);
398 if (rv == ERR_IO_PENDING) {
399 transport_send_busy_ = true;
400 } else {
401 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv));
402 }
403 }
404
405 return rv;
406 }
407
408 void SSLServerSocketNSS::BufferSendComplete(int result) {
409 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(result));
410 transport_send_busy_ = false;
411 OnSendComplete(result);
412 }
413
414 int SSLServerSocketNSS::BufferRecv(void) {
415 if (transport_recv_busy_) return ERR_IO_PENDING;
416
417 char *buf;
418 int nb = memio_GetReadParams(nss_bufs_, &buf);
419 int rv;
420 if (!nb) {
421 // buffer too full to read into, so no I/O possible at moment
422 rv = ERR_IO_PENDING;
423 } else {
424 recv_buffer_ = new IOBuffer(nb);
425 rv = transport_socket_->Read(recv_buffer_, nb, &buffer_recv_callback_);
426 if (rv == ERR_IO_PENDING) {
427 transport_recv_busy_ = true;
428 } else {
429 if (rv > 0)
430 memcpy(buf, recv_buffer_->data(), rv);
431 memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv));
432 recv_buffer_ = NULL;
433 }
434 }
435 return rv;
436 }
437
438 void SSLServerSocketNSS::BufferRecvComplete(int result) {
439 if (result > 0) {
440 char *buf;
441 memio_GetReadParams(nss_bufs_, &buf);
442 memcpy(buf, recv_buffer_->data(), result);
443 }
444 recv_buffer_ = NULL;
445 memio_PutReadResult(nss_bufs_, MapErrorToNSS(result));
446 transport_recv_busy_ = false;
447 OnRecvComplete(result);
448 }
449
450 void SSLServerSocketNSS::OnSendComplete(int result) {
451 if (next_handshake_state_ == STATE_HANDSHAKE) {
452 // In handshake phase.
453 OnHandshakeIOComplete(result);
454 return;
455 }
456
457 if (!user_write_buf_ || !completed_handshake_)
458 return;
459
460 int rv = DoWriteLoop(result);
461 if (rv != ERR_IO_PENDING)
462 DoWriteCallback(rv);
463 }
464
465 void SSLServerSocketNSS::OnRecvComplete(int result) {
466 if (next_handshake_state_ == STATE_HANDSHAKE) {
467 // In handshake phase.
468 OnHandshakeIOComplete(result);
469 return;
470 }
471
472 // Network layer received some data, check if client requested to read
473 // decrypted data.
474 if (!user_read_buf_ || !completed_handshake_)
475 return;
476
477 int rv = DoReadLoop(result);
478 if (rv != ERR_IO_PENDING)
479 DoReadCallback(rv);
480 }
481
482 void SSLServerSocketNSS::OnHandshakeIOComplete(int result) {
483 int rv = DoHandshakeLoop(result);
484 if (rv != ERR_IO_PENDING) {
485 net_log_.EndEvent(net::NetLog::TYPE_SSL_ACCEPT, NULL);
486 if (user_accept_callback_)
487 DoAcceptCallback(rv);
488 }
489 }
490
491 void SSLServerSocketNSS::DoAcceptCallback(int rv) {
492 DCHECK_NE(rv, ERR_IO_PENDING);
493
494 CompletionCallback* c = user_accept_callback_;
495 user_accept_callback_ = NULL;
496 c->Run(rv > OK ? OK : rv);
497 }
498
499 void SSLServerSocketNSS::DoReadCallback(int rv) {
500 DCHECK(rv != ERR_IO_PENDING);
501 DCHECK(user_read_callback_);
502
503 // Since Run may result in Read being called, clear |user_read_callback_|
504 // up front.
505 CompletionCallback* c = user_read_callback_;
506 user_read_callback_ = NULL;
507 user_read_buf_ = NULL;
508 user_read_buf_len_ = 0;
509 c->Run(rv);
510 }
511
512 void SSLServerSocketNSS::DoWriteCallback(int rv) {
513 DCHECK(rv != ERR_IO_PENDING);
514 DCHECK(user_write_callback_);
515
516 // Since Run may result in Write being called, clear |user_write_callback_|
517 // up front.
518 CompletionCallback* c = user_write_callback_;
519 user_write_callback_ = NULL;
520 user_write_buf_ = NULL;
521 user_write_buf_len_ = 0;
522 c->Run(rv);
523 }
524
525 // Do network I/O between the given buffer and the given socket.
526 // Return true if some I/O performed, false otherwise (error or ERR_IO_PENDING)
527 bool SSLServerSocketNSS::DoTransportIO() {
528 bool network_moved = false;
529 if (nss_bufs_ != NULL) {
530 int nsent = BufferSend();
531 int nreceived = BufferRecv();
532 network_moved = (nsent > 0 || nreceived >= 0);
533 }
534 return network_moved;
535 }
536
537 int SSLServerSocketNSS::DoPayloadRead() {
538 DCHECK(user_read_buf_);
539 DCHECK_GT(user_read_buf_len_, 0);
540 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_);
541 if (rv >= 0)
542 return rv;
543 PRErrorCode prerr = PR_GetError();
544 if (prerr == PR_WOULD_BLOCK_ERROR) {
545 return ERR_IO_PENDING;
546 }
547 rv = MapNSSError(prerr);
548 net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR,
549 make_scoped_refptr(new SSLErrorParams(rv, prerr)));
550 return rv;
551 }
552
553 int SSLServerSocketNSS::DoPayloadWrite() {
554 DCHECK(user_write_buf_);
555 int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_);
556 if (rv >= 0)
557 return rv;
558 PRErrorCode prerr = PR_GetError();
559 if (prerr == PR_WOULD_BLOCK_ERROR) {
560 return ERR_IO_PENDING;
561 }
562 rv = MapNSSError(prerr);
563 net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR,
564 make_scoped_refptr(new SSLErrorParams(rv, prerr)));
565 return rv;
566 }
567
568 int SSLServerSocketNSS::DoHandshakeLoop(int last_io_result) {
569 bool network_moved;
570 int rv = last_io_result;
571 do {
572 // Default to STATE_NONE for next state.
573 // (This is a quirk carried over from the windows
574 // implementation. It makes reading the logs a bit harder.)
575 // State handlers can and often do call GotoState just
576 // to stay in the current state.
577 State state = next_handshake_state_;
578 GotoState(STATE_NONE);
579 switch (state) {
580 case STATE_NONE:
581 // we're just pumping data between the buffer and the network
582 break;
583 case STATE_HANDSHAKE:
584 rv = DoHandshake();
585 break;
586 default:
587 rv = ERR_UNEXPECTED;
588 LOG(DFATAL) << "unexpected state " << state;
589 break;
590 }
591
592 // Do the actual network I/O
593 network_moved = DoTransportIO();
594 } while ((rv != ERR_IO_PENDING || network_moved) &&
595 next_handshake_state_ != STATE_NONE);
596 return rv;
597 }
598
599 int SSLServerSocketNSS::DoReadLoop(int result) {
600 DCHECK(completed_handshake_);
601 DCHECK(next_handshake_state_ == STATE_NONE);
602
603 if (result < 0)
604 return result;
605
606 if (!nss_bufs_) {
607 LOG(DFATAL) << "!nss_bufs_";
608 int rv = ERR_UNEXPECTED;
609 net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR,
610 make_scoped_refptr(new SSLErrorParams(rv, 0)));
611 return rv;
612 }
613
614 bool network_moved;
615 int rv;
616 do {
617 rv = DoPayloadRead();
618 network_moved = DoTransportIO();
619 } while (rv == ERR_IO_PENDING && network_moved);
620 return rv;
621 }
622
623 int SSLServerSocketNSS::DoWriteLoop(int result) {
624 DCHECK(completed_handshake_);
625 DCHECK(next_handshake_state_ == STATE_NONE);
626
627 if (result < 0)
628 return result;
629
630 if (!nss_bufs_) {
631 LOG(DFATAL) << "!nss_bufs_";
632 int rv = ERR_UNEXPECTED;
633 net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR,
634 make_scoped_refptr(new SSLErrorParams(rv, 0)));
635 return rv;
636 }
637
638 bool network_moved;
639 int rv;
640 do {
641 rv = DoPayloadWrite();
642 network_moved = DoTransportIO();
643 } while (rv == ERR_IO_PENDING && network_moved);
644 return rv;
645 }
646
647 int SSLServerSocketNSS::DoHandshake() {
648 int net_error = net::OK;
649 SECStatus rv = SSL_ForceHandshake(nss_fd_);
650
651 if (rv == SECSuccess) {
652 completed_handshake_ = true;
653 } else {
654 PRErrorCode prerr = PR_GetError();
655 net_error = MapNSSHandshakeError(prerr);
656
657 // If not done, stay in this state
658 if (net_error == ERR_IO_PENDING) {
659 GotoState(STATE_HANDSHAKE);
660 } else {
661 LOG(ERROR) << "handshake failed; NSS error code " << prerr
662 << ", net_error " << net_error;
663 net_log_.AddEvent(
664 NetLog::TYPE_SSL_HANDSHAKE_ERROR,
665 make_scoped_refptr(new SSLErrorParams(net_error, prerr)));
666 }
667 }
668 return net_error;
669 }
670
671 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/ssl_server_socket_nss.h ('k') | net/socket/ssl_server_socket_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698