| 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) |
| 412 user_callback_ = callback; | 423 user_read_callback_ = callback; |
| 413 LeaveFunction(rv); | 424 LeaveFunction(rv); |
| 414 return rv; | 425 return rv; |
| 415 } | 426 } |
| 416 | 427 |
| 417 int SSLClientSocketNSS::Write(IOBuffer* buf, int buf_len, | 428 int SSLClientSocketNSS::Write(IOBuffer* buf, int buf_len, |
| 418 CompletionCallback* callback) { | 429 CompletionCallback* callback) { |
| 419 EnterFunction(buf_len); | 430 EnterFunction(buf_len); |
| 420 DCHECK(completed_handshake_); | 431 DCHECK(completed_handshake_); |
| 421 DCHECK(next_state_ == STATE_NONE); | 432 DCHECK(next_handshake_state_ == STATE_NONE); |
| 422 DCHECK(!user_callback_); | 433 DCHECK(!user_write_callback_); |
| 423 DCHECK(!user_connect_callback_); | 434 DCHECK(!user_connect_callback_); |
| 424 DCHECK(!user_buf_); | 435 DCHECK(!user_write_buf_); |
| 436 DCHECK(nss_bufs_); |
| 425 | 437 |
| 426 user_buf_ = buf; | 438 user_write_buf_ = buf; |
| 427 user_buf_len_ = buf_len; | 439 user_write_buf_len_ = buf_len; |
| 428 | 440 |
| 429 GotoState(STATE_PAYLOAD_WRITE); | 441 int rv = DoWriteLoop(OK); |
| 430 int rv = DoLoop(OK); | 442 |
| 431 if (rv == ERR_IO_PENDING) | 443 if (rv == ERR_IO_PENDING) |
| 432 user_callback_ = callback; | 444 user_write_callback_ = callback; |
| 433 LeaveFunction(rv); | 445 LeaveFunction(rv); |
| 434 return rv; | 446 return rv; |
| 435 } | 447 } |
| 436 | 448 |
| 437 bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) { | 449 bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) { |
| 438 return transport_->SetReceiveBufferSize(size); | 450 return transport_->SetReceiveBufferSize(size); |
| 439 } | 451 } |
| 440 | 452 |
| 441 bool SSLClientSocketNSS::SetSendBufferSize(int32 size) { | 453 bool SSLClientSocketNSS::SetSendBufferSize(int32 size) { |
| 442 return transport_->SetSendBufferSize(size); | 454 return transport_->SetSendBufferSize(size); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 484 DCHECK(server_cert_ != NULL); | 496 DCHECK(server_cert_ != NULL); |
| 485 ssl_info->cert = server_cert_; | 497 ssl_info->cert = server_cert_; |
| 486 LeaveFunction(""); | 498 LeaveFunction(""); |
| 487 } | 499 } |
| 488 | 500 |
| 489 void SSLClientSocketNSS::GetSSLCertRequestInfo( | 501 void SSLClientSocketNSS::GetSSLCertRequestInfo( |
| 490 SSLCertRequestInfo* cert_request_info) { | 502 SSLCertRequestInfo* cert_request_info) { |
| 491 // TODO(wtc): implement this. | 503 // TODO(wtc): implement this. |
| 492 } | 504 } |
| 493 | 505 |
| 494 void SSLClientSocketNSS::DoCallback(int rv) { | 506 void SSLClientSocketNSS::DoReadCallback(int rv) { |
| 495 EnterFunction(rv); | 507 EnterFunction(rv); |
| 496 DCHECK(rv != ERR_IO_PENDING); | 508 DCHECK(rv != ERR_IO_PENDING); |
| 497 DCHECK(user_callback_); | 509 DCHECK(user_read_callback_); |
| 498 | 510 |
| 499 // Since Run may result in Read being called, clear |user_callback_| up front. | 511 // Since Run may result in Read being called, clear |user_read_callback_| |
| 500 CompletionCallback* c = user_callback_; | 512 // up front. |
| 501 user_callback_ = NULL; | 513 CompletionCallback* c = user_read_callback_; |
| 502 user_buf_ = NULL; | 514 user_read_callback_ = NULL; |
| 503 c->Run(rv); | 515 c->Run(rv); |
| 504 LeaveFunction(""); | 516 LeaveFunction(""); |
| 505 } | 517 } |
| 518 |
| 519 void SSLClientSocketNSS::DoWriteCallback(int rv) { |
| 520 EnterFunction(rv); |
| 521 DCHECK(rv != ERR_IO_PENDING); |
| 522 DCHECK(user_write_callback_); |
| 523 |
| 524 // Since Run may result in Write being called, clear |user_write_callback_| |
| 525 // up front. |
| 526 CompletionCallback* c = user_write_callback_; |
| 527 user_write_callback_ = NULL; |
| 528 c->Run(rv); |
| 529 LeaveFunction(""); |
| 530 } |
| 506 | 531 |
| 507 // As part of Connect(), the SSLClientSocketNSS object performs an SSL | 532 // As part of Connect(), the SSLClientSocketNSS object performs an SSL |
| 508 // handshake. This requires network IO, which in turn calls | 533 // handshake. This requires network IO, which in turn calls |
| 509 // BufferRecvComplete() with a non-zero byte count. This byte count eventually | 534 // 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 | 535 // 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(), | 536 // callback. For Read() and Write(), that's what we want. But for Connect(), |
| 512 // the caller expects OK (i.e. 0) for success. | 537 // the caller expects OK (i.e. 0) for success. |
| 513 // | 538 // |
| 514 void SSLClientSocketNSS::DoConnectCallback(int rv) { | 539 void SSLClientSocketNSS::DoConnectCallback(int rv) { |
| 515 EnterFunction(rv); | 540 EnterFunction(rv); |
| 516 DCHECK_NE(rv, ERR_IO_PENDING); | 541 DCHECK_NE(rv, ERR_IO_PENDING); |
| 517 DCHECK(user_connect_callback_); | 542 DCHECK(user_connect_callback_); |
| 518 | 543 |
| 519 // Since Run may result in Read being called, clear |user_connect_callback_| | |
| 520 // up front. | |
| 521 CompletionCallback* c = user_connect_callback_; | 544 CompletionCallback* c = user_connect_callback_; |
| 522 user_connect_callback_ = NULL; | 545 user_connect_callback_ = NULL; |
| 523 c->Run(rv > OK ? OK : rv); | 546 c->Run(rv > OK ? OK : rv); |
| 524 LeaveFunction(""); | 547 LeaveFunction(""); |
| 525 } | 548 } |
| 526 | 549 |
| 527 void SSLClientSocketNSS::OnIOComplete(int result) { | 550 void SSLClientSocketNSS::OnHandshakeIOComplete(int result) { |
| 528 EnterFunction(result); | 551 EnterFunction(result); |
| 529 int rv = DoLoop(result); | 552 int rv = DoHandshakeLoop(result); |
| 530 if (rv != ERR_IO_PENDING) { | 553 DCHECK(user_connect_callback_); |
| 531 if (user_callback_) { | 554 if (rv != ERR_IO_PENDING) |
| 532 DoCallback(rv); | 555 DoConnectCallback(rv); |
| 533 } else if (user_connect_callback_) { | |
| 534 DoConnectCallback(rv); | |
| 535 } | |
| 536 } | |
| 537 LeaveFunction(""); | 556 LeaveFunction(""); |
| 538 } | 557 } |
| 539 | 558 |
| 559 void SSLClientSocketNSS::OnSendComplete(int result) { |
| 560 EnterFunction(result); |
| 561 if (next_handshake_state_ != STATE_NONE) { |
| 562 // In handshake phase. |
| 563 OnHandshakeIOComplete(result); |
| 564 LeaveFunction(""); |
| 565 return; |
| 566 } |
| 567 |
| 568 // Network layer sent some data, check if client requested to write |
| 569 // more data. |
| 570 if (!user_write_buf_) { |
| 571 LeaveFunction(""); |
| 572 return; |
| 573 } |
| 574 |
| 575 int rv = DoWriteLoop(result); |
| 576 if (rv != ERR_IO_PENDING) |
| 577 DoWriteCallback(rv); |
| 578 LeaveFunction(""); |
| 579 } |
| 580 |
| 581 void SSLClientSocketNSS::OnRecvComplete(int result) { |
| 582 EnterFunction(result); |
| 583 if (next_handshake_state_ != STATE_NONE) { |
| 584 // In handshake phase. |
| 585 OnHandshakeIOComplete(result); |
| 586 LeaveFunction(""); |
| 587 return; |
| 588 } |
| 589 |
| 590 // Network layer received some data, check if client requested to read |
| 591 // decrypted data. |
| 592 if (!user_read_buf_) { |
| 593 LeaveFunction(""); |
| 594 return; |
| 595 } |
| 596 |
| 597 int rv = DoReadLoop(result); |
| 598 if (rv != ERR_IO_PENDING) |
| 599 DoReadCallback(rv); |
| 600 LeaveFunction(""); |
| 601 } |
| 602 |
| 540 // Map a Chromium net error code to an NSS error code | 603 // Map a Chromium net error code to an NSS error code |
| 541 // See _MD_unix_map_default_error in the NSS source | 604 // See _MD_unix_map_default_error in the NSS source |
| 542 // tree for inspiration. | 605 // tree for inspiration. |
| 543 static PRErrorCode MapErrorToNSS(int result) { | 606 static PRErrorCode MapErrorToNSS(int result) { |
| 544 if (result >=0) | 607 if (result >=0) |
| 545 return result; | 608 return result; |
| 546 // TODO(port): add real table | 609 // TODO(port): add real table |
| 547 LOG(ERROR) << "MapErrorToNSS " << result; | 610 LOG(ERROR) << "MapErrorToNSS " << result; |
| 548 return PR_UNKNOWN_ERROR; | 611 return PR_UNKNOWN_ERROR; |
| 549 } | 612 } |
| 550 | 613 |
| 551 // Do network I/O between the given buffer and the given socket. | 614 // Do network I/O between the given buffer and the given socket. |
| 615 // Return true if some I/O performed, false otherwise (error or ERR_IO_PENDING) |
| 616 bool SSLClientSocketNSS::DoTransportIO() { |
| 617 bool network_moved = false; |
| 618 if (nss_bufs_ != NULL) { |
| 619 int nsent = BufferSend(); |
| 620 int nreceived = BufferRecv(); |
| 621 network_moved = (nsent > 0 || nreceived >= 0); |
| 622 } |
| 623 return network_moved; |
| 624 } |
| 625 |
| 552 // Return 0 for EOF, | 626 // Return 0 for EOF, |
| 553 // > 0 for bytes transferred immediately, | 627 // > 0 for bytes transferred immediately, |
| 554 // < 0 for error (or the non-error ERR_IO_PENDING). | 628 // < 0 for error (or the non-error ERR_IO_PENDING). |
| 555 int SSLClientSocketNSS::BufferSend(void) { | 629 int SSLClientSocketNSS::BufferSend(void) { |
| 556 if (transport_send_busy_) return ERR_IO_PENDING; | 630 if (transport_send_busy_) return ERR_IO_PENDING; |
| 557 | 631 |
| 558 const char *buf; | 632 const char *buf; |
| 559 int nb = memio_GetWriteParams(nss_bufs_, &buf); | 633 int nb = memio_GetWriteParams(nss_bufs_, &buf); |
| 560 EnterFunction(nb); | 634 EnterFunction(nb); |
| 561 | 635 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 573 } | 647 } |
| 574 | 648 |
| 575 LeaveFunction(rv); | 649 LeaveFunction(rv); |
| 576 return rv; | 650 return rv; |
| 577 } | 651 } |
| 578 | 652 |
| 579 void SSLClientSocketNSS::BufferSendComplete(int result) { | 653 void SSLClientSocketNSS::BufferSendComplete(int result) { |
| 580 EnterFunction(result); | 654 EnterFunction(result); |
| 581 memio_PutWriteResult(nss_bufs_, result); | 655 memio_PutWriteResult(nss_bufs_, result); |
| 582 transport_send_busy_ = false; | 656 transport_send_busy_ = false; |
| 583 OnIOComplete(result); | 657 OnSendComplete(result); |
| 584 LeaveFunction(""); | 658 LeaveFunction(""); |
| 585 } | 659 } |
| 586 | 660 |
| 587 | 661 |
| 588 int SSLClientSocketNSS::BufferRecv(void) { | 662 int SSLClientSocketNSS::BufferRecv(void) { |
| 589 if (transport_recv_busy_) return ERR_IO_PENDING; | 663 if (transport_recv_busy_) return ERR_IO_PENDING; |
| 590 | 664 |
| 591 char *buf; | 665 char *buf; |
| 592 int nb = memio_GetReadParams(nss_bufs_, &buf); | 666 int nb = memio_GetReadParams(nss_bufs_, &buf); |
| 593 EnterFunction(nb); | 667 EnterFunction(nb); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 614 void SSLClientSocketNSS::BufferRecvComplete(int result) { | 688 void SSLClientSocketNSS::BufferRecvComplete(int result) { |
| 615 EnterFunction(result); | 689 EnterFunction(result); |
| 616 if (result > 0) { | 690 if (result > 0) { |
| 617 char *buf; | 691 char *buf; |
| 618 memio_GetReadParams(nss_bufs_, &buf); | 692 memio_GetReadParams(nss_bufs_, &buf); |
| 619 memcpy(buf, recv_buffer_->data(), result); | 693 memcpy(buf, recv_buffer_->data(), result); |
| 620 } | 694 } |
| 621 recv_buffer_ = NULL; | 695 recv_buffer_ = NULL; |
| 622 memio_PutReadResult(nss_bufs_, result); | 696 memio_PutReadResult(nss_bufs_, result); |
| 623 transport_recv_busy_ = false; | 697 transport_recv_busy_ = false; |
| 624 OnIOComplete(result); | 698 OnRecvComplete(result); |
| 625 LeaveFunction(""); | 699 LeaveFunction(""); |
| 626 } | 700 } |
| 627 | 701 |
| 628 int SSLClientSocketNSS::DoLoop(int last_io_result) { | 702 int SSLClientSocketNSS::DoHandshakeLoop(int last_io_result) { |
| 629 EnterFunction(last_io_result); | 703 EnterFunction(last_io_result); |
| 630 bool network_moved; | 704 bool network_moved; |
| 631 int rv = last_io_result; | 705 int rv = last_io_result; |
| 632 do { | 706 do { |
| 633 network_moved = false; | 707 network_moved = false; |
| 634 // Default to STATE_NONE for next state. | 708 // Default to STATE_NONE for next state. |
| 635 // (This is a quirk carried over from the windows | 709 // (This is a quirk carried over from the windows |
| 636 // implementation. It makes reading the logs a bit harder.) | 710 // implementation. It makes reading the logs a bit harder.) |
| 637 // State handlers can and often do call GotoState just | 711 // State handlers can and often do call GotoState just |
| 638 // to stay in the current state. | 712 // to stay in the current state. |
| 639 State state = next_state_; | 713 State state = next_handshake_state_; |
| 640 GotoState(STATE_NONE); | 714 GotoState(STATE_NONE); |
| 641 switch (state) { | 715 switch (state) { |
| 642 case STATE_NONE: | 716 case STATE_NONE: |
| 643 // we're just pumping data between the buffer and the network | 717 // we're just pumping data between the buffer and the network |
| 644 break; | 718 break; |
| 645 case STATE_HANDSHAKE_READ: | 719 case STATE_HANDSHAKE: |
| 646 rv = DoHandshakeRead(); | 720 rv = DoHandshake(); |
| 647 break; | 721 break; |
| 648 case STATE_VERIFY_CERT: | 722 case STATE_VERIFY_CERT: |
| 649 DCHECK(rv == OK); | 723 DCHECK(rv == OK); |
| 650 rv = DoVerifyCert(rv); | 724 rv = DoVerifyCert(rv); |
| 651 break; | 725 break; |
| 652 case STATE_VERIFY_CERT_COMPLETE: | 726 case STATE_VERIFY_CERT_COMPLETE: |
| 653 rv = DoVerifyCertComplete(rv); | 727 rv = DoVerifyCertComplete(rv); |
| 654 break; | 728 break; |
| 655 case STATE_PAYLOAD_READ: | |
| 656 rv = DoPayloadRead(); | |
| 657 break; | |
| 658 case STATE_PAYLOAD_WRITE: | |
| 659 rv = DoPayloadWrite(); | |
| 660 break; | |
| 661 default: | 729 default: |
| 662 rv = ERR_UNEXPECTED; | 730 rv = ERR_UNEXPECTED; |
| 663 NOTREACHED() << "unexpected state"; | 731 NOTREACHED() << "unexpected state"; |
| 664 break; | 732 break; |
| 665 } | 733 } |
| 666 | 734 |
| 667 // Do the actual network I/O | 735 // Do the actual network I/O |
| 668 if (nss_bufs_ != NULL) { | 736 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) && | 737 } while ((rv != ERR_IO_PENDING || network_moved) && |
| 674 next_state_ != STATE_NONE); | 738 next_handshake_state_ != STATE_NONE); |
| 675 LeaveFunction(""); | 739 LeaveFunction(""); |
| 676 return rv; | 740 return rv; |
| 677 } | 741 } |
| 742 |
| 743 int SSLClientSocketNSS::DoReadLoop(int result) { |
| 744 EnterFunction(""); |
| 745 DCHECK(completed_handshake_); |
| 746 DCHECK(next_handshake_state_ == STATE_NONE); |
| 747 |
| 748 if (result < 0) |
| 749 return result; |
| 750 |
| 751 if (!nss_bufs_) |
| 752 return ERR_UNEXPECTED; |
| 753 |
| 754 while (DoTransportIO()) continue; |
| 755 bool network_moved; |
| 756 int rv; |
| 757 do { |
| 758 network_moved = false; |
| 759 rv = DoPayloadRead(); |
| 760 if (rv != ERR_IO_PENDING) |
| 761 break; |
| 762 network_moved = DoTransportIO(); |
| 763 } while (network_moved); |
| 764 |
| 765 LeaveFunction(""); |
| 766 return rv; |
| 767 } |
| 768 |
| 769 int SSLClientSocketNSS::DoWriteLoop(int result) { |
| 770 EnterFunction(""); |
| 771 DCHECK(completed_handshake_); |
| 772 DCHECK(next_handshake_state_ == STATE_NONE); |
| 773 |
| 774 if (result < 0) |
| 775 return result; |
| 776 |
| 777 if (!nss_bufs_) |
| 778 return ERR_UNEXPECTED; |
| 779 |
| 780 bool network_moved; |
| 781 int rv; |
| 782 do { |
| 783 network_moved = false; |
| 784 rv = DoPayloadWrite(); |
| 785 if (rv != ERR_IO_PENDING) |
| 786 break; |
| 787 network_moved = DoTransportIO(); |
| 788 } while (network_moved); |
| 789 while (DoTransportIO()) continue; |
| 790 |
| 791 LeaveFunction(""); |
| 792 return rv; |
| 793 } |
| 678 | 794 |
| 679 // static | 795 // static |
| 680 // NSS calls this if an incoming certificate needs to be verified. | 796 // NSS calls this if an incoming certificate needs to be verified. |
| 681 // Do nothing but return SECSuccess. | 797 // Do nothing but return SECSuccess. |
| 682 // This is called only in full handshake mode. | 798 // This is called only in full handshake mode. |
| 683 // Peer certificate is retrieved in HandshakeCallback() later, which is called | 799 // Peer certificate is retrieved in HandshakeCallback() later, which is called |
| 684 // in full handshake mode or in resumption handshake mode. | 800 // in full handshake mode or in resumption handshake mode. |
| 685 SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg, | 801 SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg, |
| 686 PRFileDesc* socket, | 802 PRFileDesc* socket, |
| 687 PRBool checksig, | 803 PRBool checksig, |
| 688 PRBool is_server) { | 804 PRBool is_server) { |
| 689 // Tell NSS to not verify the certificate. | 805 // Tell NSS to not verify the certificate. |
| 690 return SECSuccess; | 806 return SECSuccess; |
| 691 } | 807 } |
| 692 | 808 |
| 693 // static | 809 // static |
| 694 // NSS calls this when handshake is completed. | 810 // NSS calls this when handshake is completed. |
| 695 // After the SSL handshake is finished, use CertVerifier to verify | 811 // After the SSL handshake is finished, use CertVerifier to verify |
| 696 // the saved server certificate. | 812 // the saved server certificate. |
| 697 void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket, | 813 void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket, |
| 698 void* arg) { | 814 void* arg) { |
| 699 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); | 815 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); |
| 700 | 816 |
| 701 that->UpdateServerCert(); | 817 that->UpdateServerCert(); |
| 702 } | 818 } |
| 703 | 819 |
| 704 int SSLClientSocketNSS::DoHandshakeRead() { | 820 int SSLClientSocketNSS::DoHandshake() { |
| 705 EnterFunction(""); | 821 EnterFunction(""); |
| 706 int net_error = net::OK; | 822 int net_error = net::OK; |
| 707 int rv = SSL_ForceHandshake(nss_fd_); | 823 int rv = SSL_ForceHandshake(nss_fd_); |
| 708 | 824 |
| 709 if (rv == SECSuccess) { | 825 if (rv == SECSuccess) { |
| 710 // SSL handshake is completed. Let's verify the certificate. | 826 // SSL handshake is completed. Let's verify the certificate. |
| 711 GotoState(STATE_VERIFY_CERT); | 827 GotoState(STATE_VERIFY_CERT); |
| 712 // Done! | 828 // Done! |
| 713 } else { | 829 } else { |
| 714 PRErrorCode prerr = PR_GetError(); | 830 PRErrorCode prerr = PR_GetError(); |
| 715 | 831 |
| 716 // If the server closed on us, it is a protocol error. | 832 // If the server closed on us, it is a protocol error. |
| 717 // Some TLS-intolerant servers do this when we request TLS. | 833 // Some TLS-intolerant servers do this when we request TLS. |
| 718 if (prerr == PR_END_OF_FILE_ERROR) { | 834 if (prerr == PR_END_OF_FILE_ERROR) { |
| 719 net_error = ERR_SSL_PROTOCOL_ERROR; | 835 net_error = ERR_SSL_PROTOCOL_ERROR; |
| 720 } else { | 836 } else { |
| 721 net_error = NetErrorFromNSPRError(prerr); | 837 net_error = NetErrorFromNSPRError(prerr); |
| 722 } | 838 } |
| 723 | 839 |
| 724 // If not done, stay in this state | 840 // If not done, stay in this state |
| 725 if (net_error == ERR_IO_PENDING) { | 841 if (net_error == ERR_IO_PENDING) { |
| 726 GotoState(STATE_HANDSHAKE_READ); | 842 GotoState(STATE_HANDSHAKE); |
| 727 } else { | 843 } else { |
| 728 LOG(ERROR) << "handshake failed; NSS error code " << prerr | 844 LOG(ERROR) << "handshake failed; NSS error code " << prerr |
| 729 << ", net_error " << net_error; | 845 << ", net_error " << net_error; |
| 730 } | 846 } |
| 731 } | 847 } |
| 732 | 848 |
| 733 LeaveFunction(""); | 849 LeaveFunction(""); |
| 734 return net_error; | 850 return net_error; |
| 735 } | 851 } |
| 736 | 852 |
| 737 int SSLClientSocketNSS::DoVerifyCert(int result) { | 853 int SSLClientSocketNSS::DoVerifyCert(int result) { |
| 738 DCHECK(server_cert_); | 854 DCHECK(server_cert_); |
| 739 GotoState(STATE_VERIFY_CERT_COMPLETE); | 855 GotoState(STATE_VERIFY_CERT_COMPLETE); |
| 740 int flags = 0; | 856 int flags = 0; |
| 741 if (ssl_config_.rev_checking_enabled) | 857 if (ssl_config_.rev_checking_enabled) |
| 742 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED; | 858 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED; |
| 743 if (ssl_config_.verify_ev_cert) | 859 if (ssl_config_.verify_ev_cert) |
| 744 flags |= X509Certificate::VERIFY_EV_CERT; | 860 flags |= X509Certificate::VERIFY_EV_CERT; |
| 745 verifier_.reset(new CertVerifier); | 861 verifier_.reset(new CertVerifier); |
| 746 return verifier_->Verify(server_cert_, hostname_, flags, | 862 return verifier_->Verify(server_cert_, hostname_, flags, |
| 747 &server_cert_verify_result_, &io_callback_); | 863 &server_cert_verify_result_, |
| 864 &handshake_io_callback_); |
| 748 } | 865 } |
| 749 | 866 |
| 750 // Derived from AuthCertificateCallback() in | 867 // Derived from AuthCertificateCallback() in |
| 751 // mozilla/source/security/manager/ssl/src/nsNSSCallbacks.cpp. | 868 // mozilla/source/security/manager/ssl/src/nsNSSCallbacks.cpp. |
| 752 int SSLClientSocketNSS::DoVerifyCertComplete(int result) { | 869 int SSLClientSocketNSS::DoVerifyCertComplete(int result) { |
| 753 DCHECK(verifier_.get()); | 870 DCHECK(verifier_.get()); |
| 754 verifier_.reset(); | 871 verifier_.reset(); |
| 755 | 872 |
| 756 if (result == OK) { | 873 if (result == OK) { |
| 757 // Remember the intermediate CA certs if the server sends them to us. | 874 // 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) && | 915 if (IsCertificateError(result) && |
| 799 ssl_config_.IsAllowedBadCert(server_cert_)) { | 916 ssl_config_.IsAllowedBadCert(server_cert_)) { |
| 800 LOG(INFO) << "accepting bad SSL certificate, as user told us to"; | 917 LOG(INFO) << "accepting bad SSL certificate, as user told us to"; |
| 801 result = OK; | 918 result = OK; |
| 802 } | 919 } |
| 803 | 920 |
| 804 completed_handshake_ = true; | 921 completed_handshake_ = true; |
| 805 // TODO(ukai): we may not need this call because it is now harmless to have an | 922 // TODO(ukai): we may not need this call because it is now harmless to have an |
| 806 // session with a bad cert. | 923 // session with a bad cert. |
| 807 InvalidateSessionIfBadCertificate(); | 924 InvalidateSessionIfBadCertificate(); |
| 808 // Exit DoLoop and return the result to the caller to Connect. | 925 // Exit DoHandshakeLoop and return the result to the caller to Connect. |
| 809 DCHECK(next_state_ == STATE_NONE); | 926 DCHECK(next_handshake_state_ == STATE_NONE); |
| 810 return result; | 927 return result; |
| 811 } | 928 } |
| 812 | 929 |
| 813 int SSLClientSocketNSS::DoPayloadRead() { | 930 int SSLClientSocketNSS::DoPayloadRead() { |
| 814 EnterFunction(user_buf_len_); | 931 EnterFunction(user_read_buf_len_); |
| 815 int rv = PR_Read(nss_fd_, user_buf_->data(), user_buf_len_); | 932 DCHECK(user_read_buf_); |
| 933 DCHECK(user_read_buf_len_ > 0); |
| 934 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_); |
| 816 if (rv >= 0) { | 935 if (rv >= 0) { |
| 817 LogData(user_buf_->data(), rv); | 936 LogData(user_read_buf_->data(), rv); |
| 818 user_buf_ = NULL; | 937 user_read_buf_ = NULL; |
| 938 user_read_buf_len_ = 0; |
| 819 LeaveFunction(""); | 939 LeaveFunction(""); |
| 820 return rv; | 940 return rv; |
| 821 } | 941 } |
| 822 PRErrorCode prerr = PR_GetError(); | 942 PRErrorCode prerr = PR_GetError(); |
| 823 if (prerr == PR_WOULD_BLOCK_ERROR) { | 943 if (prerr == PR_WOULD_BLOCK_ERROR) { |
| 824 GotoState(STATE_PAYLOAD_READ); | |
| 825 LeaveFunction(""); | 944 LeaveFunction(""); |
| 826 return ERR_IO_PENDING; | 945 return ERR_IO_PENDING; |
| 827 } | 946 } |
| 828 user_buf_ = NULL; | 947 user_read_buf_ = NULL; |
| 948 user_read_buf_len_ = 0; |
| 829 LeaveFunction(""); | 949 LeaveFunction(""); |
| 830 return NetErrorFromNSPRError(prerr); | 950 return NetErrorFromNSPRError(prerr); |
| 831 } | 951 } |
| 832 | 952 |
| 833 int SSLClientSocketNSS::DoPayloadWrite() { | 953 int SSLClientSocketNSS::DoPayloadWrite() { |
| 834 EnterFunction(user_buf_len_); | 954 EnterFunction(user_write_buf_len_); |
| 835 int rv = PR_Write(nss_fd_, user_buf_->data(), user_buf_len_); | 955 if (!user_write_buf_) |
| 956 return OK; |
| 957 int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_); |
| 836 if (rv >= 0) { | 958 if (rv >= 0) { |
| 837 LogData(user_buf_->data(), rv); | 959 LogData(user_write_buf_->data(), rv); |
| 838 user_buf_ = NULL; | 960 user_write_buf_ = NULL; |
| 961 user_write_buf_len_ = 0; |
| 839 LeaveFunction(""); | 962 LeaveFunction(""); |
| 840 return rv; | 963 return rv; |
| 841 } | 964 } |
| 842 PRErrorCode prerr = PR_GetError(); | 965 PRErrorCode prerr = PR_GetError(); |
| 843 if (prerr == PR_WOULD_BLOCK_ERROR) { | 966 if (prerr == PR_WOULD_BLOCK_ERROR) { |
| 844 GotoState(STATE_PAYLOAD_WRITE); | |
| 845 return ERR_IO_PENDING; | 967 return ERR_IO_PENDING; |
| 846 } | 968 } |
| 847 user_buf_ = NULL; | 969 user_write_buf_ = NULL; |
| 970 user_write_buf_len_ = 0; |
| 848 LeaveFunction(""); | 971 LeaveFunction(""); |
| 849 return NetErrorFromNSPRError(prerr); | 972 return NetErrorFromNSPRError(prerr); |
| 850 } | 973 } |
| 851 | 974 |
| 852 } // namespace net | 975 } // namespace net |
| OLD | NEW |