| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/base/ssl_client_socket_nss.h" | 5 #include "net/base/ssl_client_socket_nss.h" |
| 6 | 6 |
| 7 #include <nspr.h> | 7 #include <nspr.h> |
| 8 #include <nss.h> | 8 #include <nss.h> |
| 9 #include <secerr.h> | 9 #include <secerr.h> |
| 10 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424 | 10 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424 |
| 11 // until NSS 3.12.2 comes out and we update to it. | 11 // until NSS 3.12.2 comes out and we update to it. |
| 12 #define Lock FOO_NSS_Lock | 12 #define Lock FOO_NSS_Lock |
| 13 #include <ssl.h> | 13 #include <ssl.h> |
| 14 #include <sslerr.h> | 14 #include <sslerr.h> |
| 15 #include <pk11pub.h> | 15 #include <pk11pub.h> |
| 16 #undef Lock | 16 #undef Lock |
| 17 | 17 |
| 18 #include "base/logging.h" | 18 #include "base/logging.h" |
| 19 #include "base/nss_init.h" | 19 #include "base/nss_init.h" |
| 20 #include "base/string_util.h" | 20 #include "base/string_util.h" |
| 21 #include "net/base/net_errors.h" | 21 #include "net/base/net_errors.h" |
| 22 #include "net/base/ssl_info.h" | 22 #include "net/base/ssl_info.h" |
| 23 | 23 |
| 24 static const int kRecvBufferSize = 4096; | 24 static const int kRecvBufferSize = 4096; |
| 25 | 25 |
| 26 // nss calls this if an incoming certificate is invalid. | 26 namespace { |
| 27 static SECStatus ownBadCertHandler(void* arg, PRFileDesc* socket) { | 27 |
| 28 // NSS calls this if an incoming certificate is invalid. |
| 29 SECStatus OwnBadCertHandler(void* arg, PRFileDesc* socket) { |
| 28 PRErrorCode err = PR_GetError(); | 30 PRErrorCode err = PR_GetError(); |
| 29 LOG(INFO) << "server certificate is invalid; NSS error code " << err; | 31 LOG(INFO) << "server certificate is invalid; NSS error code " << err; |
| 30 // Return SECSuccess to override the problem, | 32 // Return SECSuccess to override the problem, |
| 31 // or SECFailure to let the original function fail | 33 // or SECFailure to let the original function fail |
| 32 // Chromium wants it to fail here, and may retry it later. | 34 // Chromium wants it to fail here, and may retry it later. |
| 33 return SECFailure; | 35 LOG(WARNING) << "TODO(dkegel): return SECFailure here"; |
| 36 return SECSuccess; |
| 34 } | 37 } |
| 35 | 38 |
| 39 } // anonymous namespace |
| 36 | 40 |
| 37 namespace net { | 41 namespace net { |
| 38 | 42 |
| 39 // State machines are easier to debug if you log state transitions. | 43 // State machines are easier to debug if you log state transitions. |
| 40 // Enable these if you want to see what's going on. | 44 // Enable these if you want to see what's going on. |
| 41 #if 1 | 45 #if 1 |
| 42 #define EnterFunction(x) | 46 #define EnterFunction(x) |
| 43 #define LeaveFunction(x) | 47 #define LeaveFunction(x) |
| 44 #define GotoState(s) next_state_ = s | 48 #define GotoState(s) next_state_ = s |
| 45 #define LogData(s, len) | 49 #define LogData(s, len) |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 LeaveFunction(rv); | 246 LeaveFunction(rv); |
| 243 return rv; | 247 return rv; |
| 244 } | 248 } |
| 245 | 249 |
| 246 void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) { | 250 void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) { |
| 247 EnterFunction(""); | 251 EnterFunction(""); |
| 248 ssl_info->Reset(); | 252 ssl_info->Reset(); |
| 249 SSLChannelInfo channel_info; | 253 SSLChannelInfo channel_info; |
| 250 SECStatus ok = SSL_GetChannelInfo(nss_fd_, | 254 SECStatus ok = SSL_GetChannelInfo(nss_fd_, |
| 251 &channel_info, sizeof(channel_info)); | 255 &channel_info, sizeof(channel_info)); |
| 252 if (ok == SECSuccess) { | 256 if (ok == SECSuccess && |
| 257 channel_info.length == sizeof(channel_info) && |
| 258 channel_info.cipherSuite) { |
| 253 SSLCipherSuiteInfo cipher_info; | 259 SSLCipherSuiteInfo cipher_info; |
| 254 ok = SSL_GetCipherSuiteInfo(channel_info.cipherSuite, | 260 ok = SSL_GetCipherSuiteInfo(channel_info.cipherSuite, |
| 255 &cipher_info, sizeof(cipher_info)); | 261 &cipher_info, sizeof(cipher_info)); |
| 256 if (ok == SECSuccess) { | 262 if (ok == SECSuccess) { |
| 257 ssl_info->security_bits = cipher_info.effectiveKeyBits; | 263 ssl_info->security_bits = cipher_info.effectiveKeyBits; |
| 258 } else { | 264 } else { |
| 259 ssl_info->security_bits = -1; | 265 ssl_info->security_bits = -1; |
| 260 NOTREACHED(); | 266 LOG(DFATAL) << "SSL_GetCipherSuiteInfo returned " << PR_GetError() |
| 267 << " for cipherSuite " << channel_info.cipherSuite; |
| 261 } | 268 } |
| 262 } | 269 } |
| 263 ssl_info->cert_status = server_cert_status_; | 270 ssl_info->cert_status = server_cert_status_; |
| 264 // TODO(port): implement X509Certificate so we can set the cert field! | 271 // TODO(port): implement X509Certificate so we can set the cert field! |
| 265 // CERTCertificate *nssCert = SSL_PeerCertificate(nss_fd_); | 272 // CERTCertificate *nssCert = SSL_PeerCertificate(nss_fd_); |
| 266 LeaveFunction(""); | 273 LeaveFunction(""); |
| 267 } | 274 } |
| 268 | 275 |
| 269 void SSLClientSocketNSS::DoCallback(int rv) { | 276 void SSLClientSocketNSS::DoCallback(int rv) { |
| 270 EnterFunction(rv); | 277 EnterFunction(rv); |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 if (rv != SECSuccess) | 497 if (rv != SECSuccess) |
| 491 LOG(INFO) << "SSL_ENABLE_SESSION_TICKETS failed. Old system nss?"; | 498 LOG(INFO) << "SSL_ENABLE_SESSION_TICKETS failed. Old system nss?"; |
| 492 #else | 499 #else |
| 493 #error "You need to install NSS-3.12 or later to build chromium" | 500 #error "You need to install NSS-3.12 or later to build chromium" |
| 494 #endif | 501 #endif |
| 495 | 502 |
| 496 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); | 503 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); |
| 497 if (rv != SECSuccess) | 504 if (rv != SECSuccess) |
| 498 return ERR_UNEXPECTED; | 505 return ERR_UNEXPECTED; |
| 499 | 506 |
| 500 rv = SSL_BadCertHook(nss_fd_, ownBadCertHandler, NULL); | 507 rv = SSL_BadCertHook(nss_fd_, OwnBadCertHandler, NULL); |
| 501 if (rv != SECSuccess) | 508 if (rv != SECSuccess) |
| 502 return ERR_UNEXPECTED; | 509 return ERR_UNEXPECTED; |
| 503 | 510 |
| 504 // Tell SSL the hostname we're trying to connect to. | 511 // Tell SSL the hostname we're trying to connect to. |
| 505 SSL_SetURL(nss_fd_, hostname_.c_str()); | 512 SSL_SetURL(nss_fd_, hostname_.c_str()); |
| 506 | 513 |
| 507 // Tell SSL we're a client; needed if not letting NSPR do socket I/O | 514 // Tell SSL we're a client; needed if not letting NSPR do socket I/O |
| 508 SSL_ResetHandshake(nss_fd_, 0); | 515 SSL_ResetHandshake(nss_fd_, 0); |
| 509 GotoState(STATE_HANDSHAKE_READ); | 516 GotoState(STATE_HANDSHAKE_READ); |
| 510 // Return OK so DoLoop tries handshaking | 517 // Return OK so DoLoop tries handshaking |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 GotoState(STATE_PAYLOAD_WRITE); | 583 GotoState(STATE_PAYLOAD_WRITE); |
| 577 return ERR_IO_PENDING; | 584 return ERR_IO_PENDING; |
| 578 } | 585 } |
| 579 user_buf_ = NULL; | 586 user_buf_ = NULL; |
| 580 LeaveFunction(""); | 587 LeaveFunction(""); |
| 581 return NetErrorFromNSPRError(prerr); | 588 return NetErrorFromNSPRError(prerr); |
| 582 } | 589 } |
| 583 | 590 |
| 584 } // namespace net | 591 } // namespace net |
| 585 | 592 |
| OLD | NEW |