OLD | NEW |
---|---|
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 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 // This file includes code GetDefaultCertNickname(), derived from | 5 // This file includes code GetDefaultCertNickname(), derived from |
6 // nsNSSCertificate::defaultServerNickName() | 6 // nsNSSCertificate::defaultServerNickName() |
7 // in mozilla/security/manager/ssl/src/nsNSSCertificate.cpp | 7 // in mozilla/security/manager/ssl/src/nsNSSCertificate.cpp |
8 // and SSLClientSocketNSS::DoVerifyCertComplete() derived from | 8 // and SSLClientSocketNSS::DoVerifyCertComplete() derived from |
9 // AuthCertificateCallback() in | 9 // AuthCertificateCallback() in |
10 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. | 10 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
74 | 74 |
75 static const int kRecvBufferSize = 4096; | 75 static const int kRecvBufferSize = 4096; |
76 | 76 |
77 namespace net { | 77 namespace net { |
78 | 78 |
79 // State machines are easier to debug if you log state transitions. | 79 // State machines are easier to debug if you log state transitions. |
80 // Enable these if you want to see what's going on. | 80 // Enable these if you want to see what's going on. |
81 #if 1 | 81 #if 1 |
82 #define EnterFunction(x) | 82 #define EnterFunction(x) |
83 #define LeaveFunction(x) | 83 #define LeaveFunction(x) |
84 #define GotoState(s) next_state_ = s | 84 #define GotoState(s) next_handshake_state_ = s |
85 #define LogData(s, len) | 85 #define LogData(s, len) |
86 #else | 86 #else |
87 #define EnterFunction(x) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \ | 87 #define EnterFunction(x) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \ |
88 " enter " << x << "; next_state " << next_state_ | 88 " enter " << x << \ |
89 "; next_handshake_state " << next_handshake_state_ | |
89 #define LeaveFunction(x) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \ | 90 #define LeaveFunction(x) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \ |
90 " leave " << x << "; next_state " << next_state_ | 91 " leave " << x << \ |
92 "; next_handshake_state " << next_handshake_state_ | |
91 #define GotoState(s) do { LOG(INFO) << (void *)this << " " << __FUNCTION__ << \ | 93 #define GotoState(s) do { LOG(INFO) << (void *)this << " " << __FUNCTION__ << \ |
92 " jump to state " << s; next_state_ = s; } while (0) | 94 " jump to state " << s; \ |
95 next_handshake_state_ = s; } while (0) | |
93 #define LogData(s, len) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \ | 96 #define LogData(s, len) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \ |
94 " data [" << std::string(s, len) << "]"; | 97 " data [" << std::string(s, len) << "]"; |
95 | 98 |
96 #endif | 99 #endif |
97 | 100 |
98 namespace { | 101 namespace { |
99 | 102 |
100 // Gets default certificate nickname from cert. | 103 // Gets default certificate nickname from cert. |
101 // Derived from nsNSSCertificate::defaultServerNickname | 104 // Derived from nsNSSCertificate::defaultServerNickname |
102 // in mozilla/security/manager/ssl/src/nsNSSCertificate.cpp. | 105 // in mozilla/security/manager/ssl/src/nsNSSCertificate.cpp. |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
186 bool SSLClientSocketNSS::nss_options_initialized_ = false; | 189 bool SSLClientSocketNSS::nss_options_initialized_ = false; |
187 | 190 |
188 SSLClientSocketNSS::SSLClientSocketNSS(ClientSocket* transport_socket, | 191 SSLClientSocketNSS::SSLClientSocketNSS(ClientSocket* transport_socket, |
189 const std::string& hostname, | 192 const std::string& hostname, |
190 const SSLConfig& ssl_config) | 193 const SSLConfig& ssl_config) |
191 : | 194 : |
192 buffer_send_callback_(this, &SSLClientSocketNSS::BufferSendComplete), | 195 buffer_send_callback_(this, &SSLClientSocketNSS::BufferSendComplete), |
193 buffer_recv_callback_(this, &SSLClientSocketNSS::BufferRecvComplete), | 196 buffer_recv_callback_(this, &SSLClientSocketNSS::BufferRecvComplete), |
194 transport_send_busy_(false), | 197 transport_send_busy_(false), |
195 transport_recv_busy_(false), | 198 transport_recv_busy_(false), |
196 io_callback_(this, &SSLClientSocketNSS::OnIOComplete), | 199 handshake_io_callback_(this, &SSLClientSocketNSS::OnHandshakeIOComplete), |
197 transport_(transport_socket), | 200 transport_(transport_socket), |
198 hostname_(hostname), | 201 hostname_(hostname), |
199 ssl_config_(ssl_config), | 202 ssl_config_(ssl_config), |
200 user_connect_callback_(NULL), | 203 user_connect_callback_(NULL), |
201 user_callback_(NULL), | 204 user_read_callback_(NULL), |
202 user_buf_len_(0), | 205 user_write_callback_(NULL), |
206 user_read_buf_len_(0), | |
207 user_write_buf_len_(0), | |
203 completed_handshake_(false), | 208 completed_handshake_(false), |
204 next_state_(STATE_NONE), | 209 next_handshake_state_(STATE_NONE), |
205 nss_fd_(NULL), | 210 nss_fd_(NULL), |
206 nss_bufs_(NULL) { | 211 nss_bufs_(NULL) { |
207 EnterFunction(""); | 212 EnterFunction(""); |
208 } | 213 } |
209 | 214 |
210 SSLClientSocketNSS::~SSLClientSocketNSS() { | 215 SSLClientSocketNSS::~SSLClientSocketNSS() { |
211 EnterFunction(""); | 216 EnterFunction(""); |
212 Disconnect(); | 217 Disconnect(); |
213 LeaveFunction(""); | 218 LeaveFunction(""); |
214 } | 219 } |
215 | 220 |
216 int SSLClientSocketNSS::Init() { | 221 int SSLClientSocketNSS::Init() { |
217 EnterFunction(""); | 222 EnterFunction(""); |
218 // Initialize NSS in a threadsafe way. | 223 // Initialize NSS in a threadsafe way. |
219 base::EnsureNSSInit(); | 224 base::EnsureNSSInit(); |
220 // We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop | 225 // We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop |
221 // by MessageLoopForIO::current(). | 226 // by MessageLoopForIO::current(). |
222 // X509Certificate::Verify() runs on a worker thread of CertVerifier. | 227 // X509Certificate::Verify() runs on a worker thread of CertVerifier. |
223 EnsureOCSPInit(); | 228 EnsureOCSPInit(); |
224 | 229 |
225 LeaveFunction(""); | 230 LeaveFunction(""); |
226 return OK; | 231 return OK; |
227 } | 232 } |
228 | 233 |
229 int SSLClientSocketNSS::Connect(CompletionCallback* callback) { | 234 int SSLClientSocketNSS::Connect(CompletionCallback* callback) { |
230 EnterFunction(""); | 235 EnterFunction(""); |
231 DCHECK(transport_.get()); | 236 DCHECK(transport_.get()); |
232 DCHECK(next_state_ == STATE_NONE); | 237 DCHECK(next_handshake_state_ == STATE_NONE); |
233 DCHECK(!user_callback_); | 238 DCHECK(!user_read_callback_); |
239 DCHECK(!user_write_callback_); | |
234 DCHECK(!user_connect_callback_); | 240 DCHECK(!user_connect_callback_); |
235 DCHECK(!user_buf_); | 241 DCHECK(!user_read_buf_); |
242 DCHECK(!user_write_buf_); | |
236 | 243 |
237 if (Init() != OK) { | 244 if (Init() != OK) { |
238 NOTREACHED() << "Couldn't initialize nss"; | 245 NOTREACHED() << "Couldn't initialize nss"; |
239 } | 246 } |
240 | 247 |
241 // Transport connected, now hook it up to nss | 248 // Transport connected, now hook it up to nss |
242 // TODO(port): specify rx and tx buffer sizes separately | 249 // TODO(port): specify rx and tx buffer sizes separately |
243 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize); | 250 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize); |
244 if (nss_fd_ == NULL) { | 251 if (nss_fd_ == NULL) { |
245 return 9999; // TODO(port): real error | 252 return 9999; // TODO(port): real error |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
314 rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this); | 321 rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this); |
315 if (rv != SECSuccess) | 322 if (rv != SECSuccess) |
316 return ERR_UNEXPECTED; | 323 return ERR_UNEXPECTED; |
317 | 324 |
318 // Tell SSL the hostname we're trying to connect to. | 325 // Tell SSL the hostname we're trying to connect to. |
319 SSL_SetURL(nss_fd_, hostname_.c_str()); | 326 SSL_SetURL(nss_fd_, hostname_.c_str()); |
320 | 327 |
321 // Tell SSL we're a client; needed if not letting NSPR do socket I/O | 328 // Tell SSL we're a client; needed if not letting NSPR do socket I/O |
322 SSL_ResetHandshake(nss_fd_, 0); | 329 SSL_ResetHandshake(nss_fd_, 0); |
323 | 330 |
324 GotoState(STATE_HANDSHAKE_READ); | 331 GotoState(STATE_HANDSHAKE); |
325 rv = DoLoop(OK); | 332 rv = DoHandshakeLoop(OK); |
326 if (rv == ERR_IO_PENDING) | 333 if (rv == ERR_IO_PENDING) |
327 user_connect_callback_ = callback; | 334 user_connect_callback_ = callback; |
328 | 335 |
329 LeaveFunction(""); | 336 LeaveFunction(""); |
330 return rv > OK ? OK : rv; | 337 return rv > OK ? OK : rv; |
331 } | 338 } |
332 | 339 |
333 void SSLClientSocketNSS::InvalidateSessionIfBadCertificate() { | 340 void SSLClientSocketNSS::InvalidateSessionIfBadCertificate() { |
334 if (UpdateServerCert() != NULL && | 341 if (UpdateServerCert() != NULL && |
335 ssl_config_.IsAllowedBadCert(server_cert_)) { | 342 ssl_config_.IsAllowedBadCert(server_cert_)) { |
336 SSL_InvalidateSession(nss_fd_); | 343 SSL_InvalidateSession(nss_fd_); |
337 } | 344 } |
338 } | 345 } |
339 | 346 |
340 void SSLClientSocketNSS::Disconnect() { | 347 void SSLClientSocketNSS::Disconnect() { |
341 EnterFunction(""); | 348 EnterFunction(""); |
342 | 349 |
343 // TODO(wtc): Send SSL close_notify alert. | 350 // TODO(wtc): Send SSL close_notify alert. |
344 if (nss_fd_ != NULL) { | 351 if (nss_fd_ != NULL) { |
345 InvalidateSessionIfBadCertificate(); | 352 InvalidateSessionIfBadCertificate(); |
346 PR_Close(nss_fd_); | 353 PR_Close(nss_fd_); |
347 nss_fd_ = NULL; | 354 nss_fd_ = NULL; |
348 } | 355 } |
349 | 356 |
350 // Shut down anything that may call us back (through buffer_send_callback_, | 357 // Shut down anything that may call us back (through buffer_send_callback_, |
351 // buffer_recv_callback, or io_callback_). | 358 // buffer_recv_callback, or handshake_io_callback_). |
352 verifier_.reset(); | 359 verifier_.reset(); |
353 transport_->Disconnect(); | 360 transport_->Disconnect(); |
354 | 361 |
355 // Reset object state | 362 // Reset object state |
356 transport_send_busy_ = false; | 363 transport_send_busy_ = false; |
357 transport_recv_busy_ = false; | 364 transport_recv_busy_ = false; |
358 user_connect_callback_ = NULL; | 365 user_connect_callback_ = NULL; |
359 user_callback_ = NULL; | 366 user_read_callback_ = NULL; |
360 user_buf_ = NULL; | 367 user_write_callback_ = NULL; |
361 user_buf_len_ = 0; | 368 user_read_buf_ = NULL; |
369 user_read_buf_len_ = 0; | |
370 user_write_buf_ = NULL; | |
371 user_write_buf_len_ = 0; | |
362 server_cert_ = NULL; | 372 server_cert_ = NULL; |
363 server_cert_verify_result_.Reset(); | 373 server_cert_verify_result_.Reset(); |
364 completed_handshake_ = false; | 374 completed_handshake_ = false; |
365 nss_bufs_ = NULL; | 375 nss_bufs_ = NULL; |
366 | 376 |
367 LeaveFunction(""); | 377 LeaveFunction(""); |
368 } | 378 } |
369 | 379 |
370 bool SSLClientSocketNSS::IsConnected() const { | 380 bool SSLClientSocketNSS::IsConnected() const { |
371 // Ideally, we should also check if we have received the close_notify alert | 381 // Ideally, we should also check if we have received the close_notify alert |
(...skipping 19 matching lines...) Expand all Loading... | |
391 EnterFunction(""); | 401 EnterFunction(""); |
392 bool ret = completed_handshake_ && transport_->IsConnectedAndIdle(); | 402 bool ret = completed_handshake_ && transport_->IsConnectedAndIdle(); |
393 LeaveFunction(""); | 403 LeaveFunction(""); |
394 return ret; | 404 return ret; |
395 } | 405 } |
396 | 406 |
397 int SSLClientSocketNSS::Read(IOBuffer* buf, int buf_len, | 407 int SSLClientSocketNSS::Read(IOBuffer* buf, int buf_len, |
398 CompletionCallback* callback) { | 408 CompletionCallback* callback) { |
399 EnterFunction(buf_len); | 409 EnterFunction(buf_len); |
400 DCHECK(completed_handshake_); | 410 DCHECK(completed_handshake_); |
401 DCHECK(next_state_ == STATE_NONE); | 411 DCHECK(next_handshake_state_ == STATE_NONE); |
402 DCHECK(!user_callback_); | 412 DCHECK(!user_read_callback_); |
403 DCHECK(!user_connect_callback_); | 413 DCHECK(!user_connect_callback_); |
404 DCHECK(!user_buf_); | 414 DCHECK(!user_read_buf_); |
415 DCHECK(nss_bufs_); | |
405 | 416 |
406 user_buf_ = buf; | 417 user_read_buf_ = buf; |
407 user_buf_len_ = buf_len; | 418 user_read_buf_len_ = buf_len; |
408 | 419 |
409 GotoState(STATE_PAYLOAD_READ); | 420 int rv = DoReadLoop(OK); |
410 int rv = DoLoop(OK); | 421 |
411 if (rv == ERR_IO_PENDING) | 422 if (rv == ERR_IO_PENDING) |
wtc
2009/10/14 01:54:15
Please add braces {} to "if" when "else" has brace
| |
412 user_callback_ = callback; | 423 user_read_callback_ = callback; |
424 else { | |
425 user_read_buf_ = NULL; | |
426 user_read_buf_len_ = 0; | |
427 } | |
413 LeaveFunction(rv); | 428 LeaveFunction(rv); |
414 return rv; | 429 return rv; |
415 } | 430 } |
416 | 431 |
417 int SSLClientSocketNSS::Write(IOBuffer* buf, int buf_len, | 432 int SSLClientSocketNSS::Write(IOBuffer* buf, int buf_len, |
418 CompletionCallback* callback) { | 433 CompletionCallback* callback) { |
419 EnterFunction(buf_len); | 434 EnterFunction(buf_len); |
420 DCHECK(completed_handshake_); | 435 DCHECK(completed_handshake_); |
421 DCHECK(next_state_ == STATE_NONE); | 436 DCHECK(next_handshake_state_ == STATE_NONE); |
422 DCHECK(!user_callback_); | 437 DCHECK(!user_write_callback_); |
423 DCHECK(!user_connect_callback_); | 438 DCHECK(!user_connect_callback_); |
424 DCHECK(!user_buf_); | 439 DCHECK(!user_write_buf_); |
440 DCHECK(nss_bufs_); | |
425 | 441 |
426 user_buf_ = buf; | 442 user_write_buf_ = buf; |
427 user_buf_len_ = buf_len; | 443 user_write_buf_len_ = buf_len; |
428 | 444 |
429 GotoState(STATE_PAYLOAD_WRITE); | 445 int rv = DoWriteLoop(OK); |
430 int rv = DoLoop(OK); | 446 |
431 if (rv == ERR_IO_PENDING) | 447 if (rv == ERR_IO_PENDING) |
432 user_callback_ = callback; | 448 user_write_callback_ = callback; |
wtc
2009/10/14 01:54:15
Same here: both "if" and "else" should have braces
| |
449 else { | |
450 user_write_buf_ = NULL; | |
451 user_write_buf_len_ = 0; | |
452 } | |
433 LeaveFunction(rv); | 453 LeaveFunction(rv); |
434 return rv; | 454 return rv; |
435 } | 455 } |
436 | 456 |
437 bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) { | 457 bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) { |
438 return transport_->SetReceiveBufferSize(size); | 458 return transport_->SetReceiveBufferSize(size); |
439 } | 459 } |
440 | 460 |
441 bool SSLClientSocketNSS::SetSendBufferSize(int32 size) { | 461 bool SSLClientSocketNSS::SetSendBufferSize(int32 size) { |
442 return transport_->SetSendBufferSize(size); | 462 return transport_->SetSendBufferSize(size); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
484 DCHECK(server_cert_ != NULL); | 504 DCHECK(server_cert_ != NULL); |
485 ssl_info->cert = server_cert_; | 505 ssl_info->cert = server_cert_; |
486 LeaveFunction(""); | 506 LeaveFunction(""); |
487 } | 507 } |
488 | 508 |
489 void SSLClientSocketNSS::GetSSLCertRequestInfo( | 509 void SSLClientSocketNSS::GetSSLCertRequestInfo( |
490 SSLCertRequestInfo* cert_request_info) { | 510 SSLCertRequestInfo* cert_request_info) { |
491 // TODO(wtc): implement this. | 511 // TODO(wtc): implement this. |
492 } | 512 } |
493 | 513 |
494 void SSLClientSocketNSS::DoCallback(int rv) { | 514 void SSLClientSocketNSS::DoReadCallback(int rv) { |
495 EnterFunction(rv); | 515 EnterFunction(rv); |
496 DCHECK(rv != ERR_IO_PENDING); | 516 DCHECK(rv != ERR_IO_PENDING); |
497 DCHECK(user_callback_); | 517 DCHECK(user_read_callback_); |
498 | 518 |
499 // Since Run may result in Read being called, clear |user_callback_| up front. | 519 // Since Run may result in Read being called, clear |user_read_callback_| |
500 CompletionCallback* c = user_callback_; | 520 // up front. |
501 user_callback_ = NULL; | 521 CompletionCallback* c = user_read_callback_; |
502 user_buf_ = NULL; | 522 user_read_callback_ = NULL; |
523 user_read_buf_ = NULL; | |
524 user_read_buf_len_ = 0; | |
503 c->Run(rv); | 525 c->Run(rv); |
504 LeaveFunction(""); | 526 LeaveFunction(""); |
505 } | 527 } |
528 | |
529 void SSLClientSocketNSS::DoWriteCallback(int rv) { | |
530 EnterFunction(rv); | |
531 DCHECK(rv != ERR_IO_PENDING); | |
532 DCHECK(user_write_callback_); | |
533 | |
534 // Since Run may result in Write being called, clear |user_write_callback_| | |
535 // up front. | |
536 CompletionCallback* c = user_write_callback_; | |
537 user_write_callback_ = NULL; | |
538 user_write_buf_ = NULL; | |
539 user_write_buf_len_ = 0; | |
540 c->Run(rv); | |
541 LeaveFunction(""); | |
542 } | |
506 | 543 |
507 // As part of Connect(), the SSLClientSocketNSS object performs an SSL | 544 // As part of Connect(), the SSLClientSocketNSS object performs an SSL |
508 // handshake. This requires network IO, which in turn calls | 545 // handshake. This requires network IO, which in turn calls |
509 // BufferRecvComplete() with a non-zero byte count. This byte count eventually | 546 // BufferRecvComplete() with a non-zero byte count. This byte count eventually |
510 // winds its way through the state machine and ends up being passed to the | 547 // winds its way through the state machine and ends up being passed to the |
511 // callback. For Read() and Write(), that's what we want. But for Connect(), | 548 // callback. For Read() and Write(), that's what we want. But for Connect(), |
512 // the caller expects OK (i.e. 0) for success. | 549 // the caller expects OK (i.e. 0) for success. |
513 // | 550 // |
514 void SSLClientSocketNSS::DoConnectCallback(int rv) { | 551 void SSLClientSocketNSS::DoConnectCallback(int rv) { |
515 EnterFunction(rv); | 552 EnterFunction(rv); |
516 DCHECK_NE(rv, ERR_IO_PENDING); | 553 DCHECK_NE(rv, ERR_IO_PENDING); |
517 DCHECK(user_connect_callback_); | 554 DCHECK(user_connect_callback_); |
518 | 555 |
519 // Since Run may result in Read being called, clear |user_connect_callback_| | |
520 // up front. | |
521 CompletionCallback* c = user_connect_callback_; | 556 CompletionCallback* c = user_connect_callback_; |
522 user_connect_callback_ = NULL; | 557 user_connect_callback_ = NULL; |
523 c->Run(rv > OK ? OK : rv); | 558 c->Run(rv > OK ? OK : rv); |
524 LeaveFunction(""); | 559 LeaveFunction(""); |
525 } | 560 } |
526 | 561 |
527 void SSLClientSocketNSS::OnIOComplete(int result) { | 562 void SSLClientSocketNSS::OnHandshakeIOComplete(int result) { |
528 EnterFunction(result); | 563 EnterFunction(result); |
529 int rv = DoLoop(result); | 564 int rv = DoHandshakeLoop(result); |
530 if (rv != ERR_IO_PENDING) { | 565 if (rv != ERR_IO_PENDING) |
531 if (user_callback_) { | 566 DoConnectCallback(rv); |
532 DoCallback(rv); | |
533 } else if (user_connect_callback_) { | |
534 DoConnectCallback(rv); | |
535 } | |
536 } | |
537 LeaveFunction(""); | 567 LeaveFunction(""); |
538 } | 568 } |
539 | 569 |
570 void SSLClientSocketNSS::OnSendComplete(int result) { | |
571 EnterFunction(result); | |
572 if (next_handshake_state_ != STATE_NONE) { | |
573 // In handshake phase. | |
574 OnHandshakeIOComplete(result); | |
575 LeaveFunction(""); | |
576 return; | |
577 } | |
578 | |
579 // OnSendComplete may need to call DoPayloadRead while the renegotiation | |
580 // handshake is in progress. | |
581 int rv_read = ERR_IO_PENDING; | |
582 int rv_write = ERR_IO_PENDING; | |
583 bool network_moved; | |
584 do { | |
585 if (user_read_buf_) | |
586 rv_read = DoPayloadRead(); | |
587 if (user_write_buf_) | |
588 rv_write = DoPayloadWrite(); | |
589 network_moved = DoTransportIO(); | |
590 } while (rv_read == ERR_IO_PENDING && | |
591 rv_write == ERR_IO_PENDING && | |
592 network_moved); | |
593 | |
594 if (user_read_buf_ && rv_read != ERR_IO_PENDING) | |
595 DoReadCallback(rv_read); | |
596 if (user_write_buf_ && rv_write != ERR_IO_PENDING) | |
597 DoWriteCallback(rv_write); | |
598 | |
599 LeaveFunction(""); | |
600 } | |
601 | |
602 void SSLClientSocketNSS::OnRecvComplete(int result) { | |
603 EnterFunction(result); | |
604 if (next_handshake_state_ != STATE_NONE) { | |
605 // In handshake phase. | |
606 OnHandshakeIOComplete(result); | |
607 LeaveFunction(""); | |
608 return; | |
609 } | |
610 | |
611 // Network layer received some data, check if client requested to read | |
612 // decrypted data. | |
613 if (!user_read_buf_) { | |
614 LeaveFunction(""); | |
615 return; | |
616 } | |
617 | |
618 int rv = DoReadLoop(result); | |
619 if (rv != ERR_IO_PENDING) | |
620 DoReadCallback(rv); | |
621 LeaveFunction(""); | |
622 } | |
623 | |
540 // Map a Chromium net error code to an NSS error code | 624 // Map a Chromium net error code to an NSS error code |
541 // See _MD_unix_map_default_error in the NSS source | 625 // See _MD_unix_map_default_error in the NSS source |
542 // tree for inspiration. | 626 // tree for inspiration. |
543 static PRErrorCode MapErrorToNSS(int result) { | 627 static PRErrorCode MapErrorToNSS(int result) { |
544 if (result >=0) | 628 if (result >=0) |
545 return result; | 629 return result; |
546 // TODO(port): add real table | 630 // TODO(port): add real table |
547 LOG(ERROR) << "MapErrorToNSS " << result; | 631 LOG(ERROR) << "MapErrorToNSS " << result; |
548 return PR_UNKNOWN_ERROR; | 632 return PR_UNKNOWN_ERROR; |
549 } | 633 } |
550 | 634 |
551 // Do network I/O between the given buffer and the given socket. | 635 // Do network I/O between the given buffer and the given socket. |
636 // Return true if some I/O performed, false otherwise (error or ERR_IO_PENDING) | |
637 bool SSLClientSocketNSS::DoTransportIO() { | |
638 EnterFunction(""); | |
639 bool network_moved = false; | |
640 if (nss_bufs_ != NULL) { | |
641 int nsent = BufferSend(); | |
642 int nreceived = BufferRecv(); | |
643 network_moved = (nsent > 0 || nreceived >= 0); | |
644 } | |
645 LeaveFunction(network_moved); | |
646 return network_moved; | |
647 } | |
648 | |
552 // Return 0 for EOF, | 649 // Return 0 for EOF, |
553 // > 0 for bytes transferred immediately, | 650 // > 0 for bytes transferred immediately, |
554 // < 0 for error (or the non-error ERR_IO_PENDING). | 651 // < 0 for error (or the non-error ERR_IO_PENDING). |
555 int SSLClientSocketNSS::BufferSend(void) { | 652 int SSLClientSocketNSS::BufferSend(void) { |
556 if (transport_send_busy_) return ERR_IO_PENDING; | 653 if (transport_send_busy_) return ERR_IO_PENDING; |
557 | 654 |
558 const char *buf; | 655 const char *buf; |
559 int nb = memio_GetWriteParams(nss_bufs_, &buf); | 656 int nb = memio_GetWriteParams(nss_bufs_, &buf); |
560 EnterFunction(nb); | 657 EnterFunction(nb); |
561 | 658 |
(...skipping 11 matching lines...) Expand all Loading... | |
573 } | 670 } |
574 | 671 |
575 LeaveFunction(rv); | 672 LeaveFunction(rv); |
576 return rv; | 673 return rv; |
577 } | 674 } |
578 | 675 |
579 void SSLClientSocketNSS::BufferSendComplete(int result) { | 676 void SSLClientSocketNSS::BufferSendComplete(int result) { |
580 EnterFunction(result); | 677 EnterFunction(result); |
581 memio_PutWriteResult(nss_bufs_, result); | 678 memio_PutWriteResult(nss_bufs_, result); |
582 transport_send_busy_ = false; | 679 transport_send_busy_ = false; |
583 OnIOComplete(result); | 680 OnSendComplete(result); |
584 LeaveFunction(""); | 681 LeaveFunction(""); |
585 } | 682 } |
586 | 683 |
587 | 684 |
588 int SSLClientSocketNSS::BufferRecv(void) { | 685 int SSLClientSocketNSS::BufferRecv(void) { |
589 if (transport_recv_busy_) return ERR_IO_PENDING; | 686 if (transport_recv_busy_) return ERR_IO_PENDING; |
590 | 687 |
591 char *buf; | 688 char *buf; |
592 int nb = memio_GetReadParams(nss_bufs_, &buf); | 689 int nb = memio_GetReadParams(nss_bufs_, &buf); |
593 EnterFunction(nb); | 690 EnterFunction(nb); |
(...skipping 20 matching lines...) Expand all Loading... | |
614 void SSLClientSocketNSS::BufferRecvComplete(int result) { | 711 void SSLClientSocketNSS::BufferRecvComplete(int result) { |
615 EnterFunction(result); | 712 EnterFunction(result); |
616 if (result > 0) { | 713 if (result > 0) { |
617 char *buf; | 714 char *buf; |
618 memio_GetReadParams(nss_bufs_, &buf); | 715 memio_GetReadParams(nss_bufs_, &buf); |
619 memcpy(buf, recv_buffer_->data(), result); | 716 memcpy(buf, recv_buffer_->data(), result); |
620 } | 717 } |
621 recv_buffer_ = NULL; | 718 recv_buffer_ = NULL; |
622 memio_PutReadResult(nss_bufs_, result); | 719 memio_PutReadResult(nss_bufs_, result); |
623 transport_recv_busy_ = false; | 720 transport_recv_busy_ = false; |
624 OnIOComplete(result); | 721 OnRecvComplete(result); |
625 LeaveFunction(""); | 722 LeaveFunction(""); |
626 } | 723 } |
627 | 724 |
628 int SSLClientSocketNSS::DoLoop(int last_io_result) { | 725 int SSLClientSocketNSS::DoHandshakeLoop(int last_io_result) { |
629 EnterFunction(last_io_result); | 726 EnterFunction(last_io_result); |
630 bool network_moved; | 727 bool network_moved; |
631 int rv = last_io_result; | 728 int rv = last_io_result; |
632 do { | 729 do { |
633 network_moved = false; | |
634 // Default to STATE_NONE for next state. | 730 // Default to STATE_NONE for next state. |
635 // (This is a quirk carried over from the windows | 731 // (This is a quirk carried over from the windows |
636 // implementation. It makes reading the logs a bit harder.) | 732 // implementation. It makes reading the logs a bit harder.) |
637 // State handlers can and often do call GotoState just | 733 // State handlers can and often do call GotoState just |
638 // to stay in the current state. | 734 // to stay in the current state. |
639 State state = next_state_; | 735 State state = next_handshake_state_; |
640 GotoState(STATE_NONE); | 736 GotoState(STATE_NONE); |
641 switch (state) { | 737 switch (state) { |
642 case STATE_NONE: | 738 case STATE_NONE: |
643 // we're just pumping data between the buffer and the network | 739 // we're just pumping data between the buffer and the network |
644 break; | 740 break; |
645 case STATE_HANDSHAKE_READ: | 741 case STATE_HANDSHAKE: |
646 rv = DoHandshakeRead(); | 742 rv = DoHandshake(); |
647 break; | 743 break; |
648 case STATE_VERIFY_CERT: | 744 case STATE_VERIFY_CERT: |
649 DCHECK(rv == OK); | 745 DCHECK(rv == OK); |
650 rv = DoVerifyCert(rv); | 746 rv = DoVerifyCert(rv); |
651 break; | 747 break; |
652 case STATE_VERIFY_CERT_COMPLETE: | 748 case STATE_VERIFY_CERT_COMPLETE: |
653 rv = DoVerifyCertComplete(rv); | 749 rv = DoVerifyCertComplete(rv); |
654 break; | 750 break; |
655 case STATE_PAYLOAD_READ: | |
656 rv = DoPayloadRead(); | |
657 break; | |
658 case STATE_PAYLOAD_WRITE: | |
659 rv = DoPayloadWrite(); | |
660 break; | |
661 default: | 751 default: |
662 rv = ERR_UNEXPECTED; | 752 rv = ERR_UNEXPECTED; |
663 NOTREACHED() << "unexpected state"; | 753 NOTREACHED() << "unexpected state"; |
664 break; | 754 break; |
665 } | 755 } |
666 | 756 |
667 // Do the actual network I/O | 757 // Do the actual network I/O |
668 if (nss_bufs_ != NULL) { | 758 network_moved = DoTransportIO(); |
669 int nsent = BufferSend(); | |
670 int nreceived = BufferRecv(); | |
671 network_moved = (nsent > 0 || nreceived >= 0); | |
672 } | |
673 } while ((rv != ERR_IO_PENDING || network_moved) && | 759 } while ((rv != ERR_IO_PENDING || network_moved) && |
674 next_state_ != STATE_NONE); | 760 next_handshake_state_ != STATE_NONE); |
675 LeaveFunction(""); | 761 LeaveFunction(""); |
676 return rv; | 762 return rv; |
677 } | 763 } |
764 | |
765 int SSLClientSocketNSS::DoReadLoop(int result) { | |
766 EnterFunction(""); | |
767 DCHECK(completed_handshake_); | |
768 DCHECK(next_handshake_state_ == STATE_NONE); | |
769 | |
770 if (result < 0) | |
771 return result; | |
772 | |
773 if (!nss_bufs_) | |
774 return ERR_UNEXPECTED; | |
775 | |
776 bool network_moved; | |
777 int rv; | |
778 do { | |
779 rv = DoPayloadRead(); | |
780 network_moved = DoTransportIO(); | |
781 } while (rv == ERR_IO_PENDING && network_moved); | |
782 | |
783 LeaveFunction(""); | |
784 return rv; | |
785 } | |
786 | |
787 int SSLClientSocketNSS::DoWriteLoop(int result) { | |
788 EnterFunction(""); | |
789 DCHECK(completed_handshake_); | |
790 DCHECK(next_handshake_state_ == STATE_NONE); | |
791 | |
792 if (result < 0) | |
793 return result; | |
794 | |
795 if (!nss_bufs_) | |
796 return ERR_UNEXPECTED; | |
797 | |
798 bool network_moved; | |
799 int rv; | |
800 do { | |
801 rv = DoPayloadWrite(); | |
802 network_moved = DoTransportIO(); | |
803 } while (rv == ERR_IO_PENDING && network_moved); | |
804 | |
805 LeaveFunction(""); | |
806 return rv; | |
807 } | |
678 | 808 |
679 // static | 809 // static |
680 // NSS calls this if an incoming certificate needs to be verified. | 810 // NSS calls this if an incoming certificate needs to be verified. |
681 // Do nothing but return SECSuccess. | 811 // Do nothing but return SECSuccess. |
682 // This is called only in full handshake mode. | 812 // This is called only in full handshake mode. |
683 // Peer certificate is retrieved in HandshakeCallback() later, which is called | 813 // Peer certificate is retrieved in HandshakeCallback() later, which is called |
684 // in full handshake mode or in resumption handshake mode. | 814 // in full handshake mode or in resumption handshake mode. |
685 SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg, | 815 SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg, |
686 PRFileDesc* socket, | 816 PRFileDesc* socket, |
687 PRBool checksig, | 817 PRBool checksig, |
688 PRBool is_server) { | 818 PRBool is_server) { |
689 // Tell NSS to not verify the certificate. | 819 // Tell NSS to not verify the certificate. |
690 return SECSuccess; | 820 return SECSuccess; |
691 } | 821 } |
692 | 822 |
693 // static | 823 // static |
694 // NSS calls this when handshake is completed. | 824 // NSS calls this when handshake is completed. |
695 // After the SSL handshake is finished, use CertVerifier to verify | 825 // After the SSL handshake is finished, use CertVerifier to verify |
696 // the saved server certificate. | 826 // the saved server certificate. |
697 void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket, | 827 void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket, |
698 void* arg) { | 828 void* arg) { |
699 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); | 829 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); |
700 | 830 |
701 that->UpdateServerCert(); | 831 that->UpdateServerCert(); |
702 } | 832 } |
703 | 833 |
704 int SSLClientSocketNSS::DoHandshakeRead() { | 834 int SSLClientSocketNSS::DoHandshake() { |
705 EnterFunction(""); | 835 EnterFunction(""); |
706 int net_error = net::OK; | 836 int net_error = net::OK; |
707 int rv = SSL_ForceHandshake(nss_fd_); | 837 int rv = SSL_ForceHandshake(nss_fd_); |
708 | 838 |
709 if (rv == SECSuccess) { | 839 if (rv == SECSuccess) { |
710 // SSL handshake is completed. Let's verify the certificate. | 840 // SSL handshake is completed. Let's verify the certificate. |
711 GotoState(STATE_VERIFY_CERT); | 841 GotoState(STATE_VERIFY_CERT); |
712 // Done! | 842 // Done! |
713 } else { | 843 } else { |
714 PRErrorCode prerr = PR_GetError(); | 844 PRErrorCode prerr = PR_GetError(); |
715 | 845 |
716 // If the server closed on us, it is a protocol error. | 846 // If the server closed on us, it is a protocol error. |
717 // Some TLS-intolerant servers do this when we request TLS. | 847 // Some TLS-intolerant servers do this when we request TLS. |
718 if (prerr == PR_END_OF_FILE_ERROR) { | 848 if (prerr == PR_END_OF_FILE_ERROR) { |
719 net_error = ERR_SSL_PROTOCOL_ERROR; | 849 net_error = ERR_SSL_PROTOCOL_ERROR; |
720 } else { | 850 } else { |
721 net_error = NetErrorFromNSPRError(prerr); | 851 net_error = NetErrorFromNSPRError(prerr); |
722 } | 852 } |
723 | 853 |
724 // If not done, stay in this state | 854 // If not done, stay in this state |
725 if (net_error == ERR_IO_PENDING) { | 855 if (net_error == ERR_IO_PENDING) { |
726 GotoState(STATE_HANDSHAKE_READ); | 856 GotoState(STATE_HANDSHAKE); |
727 } else { | 857 } else { |
728 LOG(ERROR) << "handshake failed; NSS error code " << prerr | 858 LOG(ERROR) << "handshake failed; NSS error code " << prerr |
729 << ", net_error " << net_error; | 859 << ", net_error " << net_error; |
730 } | 860 } |
731 } | 861 } |
732 | 862 |
733 LeaveFunction(""); | 863 LeaveFunction(""); |
734 return net_error; | 864 return net_error; |
735 } | 865 } |
736 | 866 |
737 int SSLClientSocketNSS::DoVerifyCert(int result) { | 867 int SSLClientSocketNSS::DoVerifyCert(int result) { |
738 DCHECK(server_cert_); | 868 DCHECK(server_cert_); |
739 GotoState(STATE_VERIFY_CERT_COMPLETE); | 869 GotoState(STATE_VERIFY_CERT_COMPLETE); |
740 int flags = 0; | 870 int flags = 0; |
741 if (ssl_config_.rev_checking_enabled) | 871 if (ssl_config_.rev_checking_enabled) |
742 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED; | 872 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED; |
743 if (ssl_config_.verify_ev_cert) | 873 if (ssl_config_.verify_ev_cert) |
744 flags |= X509Certificate::VERIFY_EV_CERT; | 874 flags |= X509Certificate::VERIFY_EV_CERT; |
745 verifier_.reset(new CertVerifier); | 875 verifier_.reset(new CertVerifier); |
746 return verifier_->Verify(server_cert_, hostname_, flags, | 876 return verifier_->Verify(server_cert_, hostname_, flags, |
747 &server_cert_verify_result_, &io_callback_); | 877 &server_cert_verify_result_, |
878 &handshake_io_callback_); | |
748 } | 879 } |
749 | 880 |
750 // Derived from AuthCertificateCallback() in | 881 // Derived from AuthCertificateCallback() in |
751 // mozilla/source/security/manager/ssl/src/nsNSSCallbacks.cpp. | 882 // mozilla/source/security/manager/ssl/src/nsNSSCallbacks.cpp. |
752 int SSLClientSocketNSS::DoVerifyCertComplete(int result) { | 883 int SSLClientSocketNSS::DoVerifyCertComplete(int result) { |
753 DCHECK(verifier_.get()); | 884 DCHECK(verifier_.get()); |
754 verifier_.reset(); | 885 verifier_.reset(); |
755 | 886 |
756 if (result == OK) { | 887 if (result == OK) { |
757 // Remember the intermediate CA certs if the server sends them to us. | 888 // Remember the intermediate CA certs if the server sends them to us. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
798 if (IsCertificateError(result) && | 929 if (IsCertificateError(result) && |
799 ssl_config_.IsAllowedBadCert(server_cert_)) { | 930 ssl_config_.IsAllowedBadCert(server_cert_)) { |
800 LOG(INFO) << "accepting bad SSL certificate, as user told us to"; | 931 LOG(INFO) << "accepting bad SSL certificate, as user told us to"; |
801 result = OK; | 932 result = OK; |
802 } | 933 } |
803 | 934 |
804 completed_handshake_ = true; | 935 completed_handshake_ = true; |
805 // TODO(ukai): we may not need this call because it is now harmless to have an | 936 // TODO(ukai): we may not need this call because it is now harmless to have an |
806 // session with a bad cert. | 937 // session with a bad cert. |
807 InvalidateSessionIfBadCertificate(); | 938 InvalidateSessionIfBadCertificate(); |
808 // Exit DoLoop and return the result to the caller to Connect. | 939 // Exit DoHandshakeLoop and return the result to the caller to Connect. |
809 DCHECK(next_state_ == STATE_NONE); | 940 DCHECK(next_handshake_state_ == STATE_NONE); |
810 return result; | 941 return result; |
811 } | 942 } |
812 | 943 |
813 int SSLClientSocketNSS::DoPayloadRead() { | 944 int SSLClientSocketNSS::DoPayloadRead() { |
814 EnterFunction(user_buf_len_); | 945 EnterFunction(user_read_buf_len_); |
815 int rv = PR_Read(nss_fd_, user_buf_->data(), user_buf_len_); | 946 DCHECK(user_read_buf_); |
947 DCHECK(user_read_buf_len_ > 0); | |
948 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_); | |
816 if (rv >= 0) { | 949 if (rv >= 0) { |
817 LogData(user_buf_->data(), rv); | 950 LogData(user_read_buf_->data(), rv); |
818 user_buf_ = NULL; | |
819 LeaveFunction(""); | 951 LeaveFunction(""); |
820 return rv; | 952 return rv; |
821 } | 953 } |
822 PRErrorCode prerr = PR_GetError(); | 954 PRErrorCode prerr = PR_GetError(); |
823 if (prerr == PR_WOULD_BLOCK_ERROR) { | 955 if (prerr == PR_WOULD_BLOCK_ERROR) { |
824 GotoState(STATE_PAYLOAD_READ); | |
825 LeaveFunction(""); | 956 LeaveFunction(""); |
826 return ERR_IO_PENDING; | 957 return ERR_IO_PENDING; |
827 } | 958 } |
828 user_buf_ = NULL; | |
829 LeaveFunction(""); | 959 LeaveFunction(""); |
830 return NetErrorFromNSPRError(prerr); | 960 return NetErrorFromNSPRError(prerr); |
831 } | 961 } |
832 | 962 |
833 int SSLClientSocketNSS::DoPayloadWrite() { | 963 int SSLClientSocketNSS::DoPayloadWrite() { |
834 EnterFunction(user_buf_len_); | 964 EnterFunction(user_write_buf_len_); |
835 int rv = PR_Write(nss_fd_, user_buf_->data(), user_buf_len_); | 965 DCHECK(user_write_buf_); |
966 int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_); | |
836 if (rv >= 0) { | 967 if (rv >= 0) { |
837 LogData(user_buf_->data(), rv); | 968 LogData(user_write_buf_->data(), rv); |
838 user_buf_ = NULL; | |
839 LeaveFunction(""); | 969 LeaveFunction(""); |
840 return rv; | 970 return rv; |
841 } | 971 } |
842 PRErrorCode prerr = PR_GetError(); | 972 PRErrorCode prerr = PR_GetError(); |
843 if (prerr == PR_WOULD_BLOCK_ERROR) { | 973 if (prerr == PR_WOULD_BLOCK_ERROR) { |
844 GotoState(STATE_PAYLOAD_WRITE); | |
845 return ERR_IO_PENDING; | 974 return ERR_IO_PENDING; |
846 } | 975 } |
847 user_buf_ = NULL; | |
848 LeaveFunction(""); | 976 LeaveFunction(""); |
849 return NetErrorFromNSPRError(prerr); | 977 return NetErrorFromNSPRError(prerr); |
850 } | 978 } |
851 | 979 |
852 } // namespace net | 980 } // namespace net |
OLD | NEW |