| Index: net/base/ssl_client_socket_nss.cc
|
| ===================================================================
|
| --- net/base/ssl_client_socket_nss.cc (revision 9822)
|
| +++ net/base/ssl_client_socket_nss.cc (working copy)
|
| @@ -23,21 +23,6 @@
|
|
|
| static const int kRecvBufferSize = 4096;
|
|
|
| -namespace {
|
| -
|
| -// NSS calls this if an incoming certificate is invalid.
|
| -SECStatus OwnBadCertHandler(void* arg, PRFileDesc* socket) {
|
| - PRErrorCode err = PR_GetError();
|
| - LOG(INFO) << "server certificate is invalid; NSS error code " << err;
|
| - // Return SECSuccess to override the problem,
|
| - // or SECFailure to let the original function fail
|
| - // Chromium wants it to fail here, and may retry it later.
|
| - LOG(WARNING) << "TODO(dkegel): return SECFailure here";
|
| - return SECSuccess;
|
| -}
|
| -
|
| -} // anonymous namespace
|
| -
|
| namespace net {
|
|
|
| // State machines are easier to debug if you log state transitions.
|
| @@ -79,6 +64,8 @@
|
| case SEC_ERROR_REVOKED_KEY:
|
| return ERR_CERT_REVOKED;
|
| case SEC_ERROR_UNKNOWN_ISSUER:
|
| + case SEC_ERROR_UNTRUSTED_CERT:
|
| + case SEC_ERROR_UNTRUSTED_ISSUER:
|
| return ERR_CERT_AUTHORITY_INVALID;
|
|
|
| default: {
|
| @@ -119,7 +106,7 @@
|
| user_callback_(NULL),
|
| user_buf_(NULL),
|
| user_buf_len_(0),
|
| - server_cert_status_(0),
|
| + server_cert_error_(0),
|
| completed_handshake_(false),
|
| next_state_(STATE_NONE),
|
| nss_fd_(NULL),
|
| @@ -242,9 +229,12 @@
|
| << " for cipherSuite " << channel_info.cipherSuite;
|
| }
|
| }
|
| - ssl_info->cert_status = server_cert_status_;
|
| - // TODO(port): implement X509Certificate so we can set the cert field!
|
| - // CERTCertificate *nssCert = SSL_PeerCertificate(nss_fd_);
|
| + if (server_cert_error_ != net::OK)
|
| + ssl_info->SetCertError(server_cert_error_);
|
| + X509Certificate::OSCertHandle nss_cert = SSL_PeerCertificate(nss_fd_);
|
| + if (nss_cert)
|
| + ssl_info->cert = X509Certificate::CreateFromHandle(nss_cert,
|
| + X509Certificate::SOURCE_FROM_NETWORK);
|
| LeaveFunction("");
|
| }
|
|
|
| @@ -401,6 +391,19 @@
|
| return transport_->Connect(&io_callback_);
|
| }
|
|
|
| +// static
|
| +// NSS calls this if an incoming certificate is invalid.
|
| +SECStatus SSLClientSocketNSS::OwnBadCertHandler(void* arg, PRFileDesc* socket) {
|
| + SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
|
| + PRErrorCode prerr = PR_GetError();
|
| + that->server_cert_error_ = NetErrorFromNSPRError(prerr);
|
| + LOG(INFO) << "server certificate is invalid; NSS error code " << prerr
|
| + << ", net error " << that->server_cert_error_;
|
| + // Return SECSuccess to override the problem.
|
| + // Chromium wants it to succeed here, and may abort the connection later.
|
| + return SECSuccess;
|
| +}
|
| +
|
| int SSLClientSocketNSS::DoConnectComplete(int result) {
|
| EnterFunction(result);
|
| if (result < 0)
|
| @@ -479,7 +482,7 @@
|
| if (rv != SECSuccess)
|
| return ERR_UNEXPECTED;
|
|
|
| - rv = SSL_BadCertHook(nss_fd_, OwnBadCertHandler, NULL);
|
| + rv = SSL_BadCertHook(nss_fd_, OwnBadCertHandler, this);
|
| if (rv != SECSuccess)
|
| return ERR_UNEXPECTED;
|
|
|
| @@ -500,11 +503,10 @@
|
| int rv = SSL_ForceHandshake(nss_fd_);
|
|
|
| if (rv == SECSuccess) {
|
| - net_error = OK;
|
| + net_error = server_cert_error_;
|
| // there's a callback for this, too
|
| completed_handshake_ = true;
|
| - // Indicate we're ready to handle I/O. Badly named?
|
| - GotoState(STATE_NONE);
|
| + // Done!
|
| } else {
|
| PRErrorCode prerr = PR_GetError();
|
| net_error = NetErrorFromNSPRError(prerr);
|
| @@ -513,10 +515,9 @@
|
| if (net_error == ERR_IO_PENDING) {
|
| GotoState(STATE_HANDSHAKE_READ);
|
| } else {
|
| - server_cert_status_ = MapNetErrorToCertStatus(net_error);
|
| + server_cert_error_ = net_error;
|
| LOG(ERROR) << "handshake failed; NSS error code " << prerr
|
| - << ", net_error " << net_error << ", server_cert_status "
|
| - << server_cert_status_;
|
| + << ", net_error " << net_error;
|
| }
|
| }
|
|
|
|
|