| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 SSLClientSocketNSS::DoVerifyCertComplete() derived | 5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived |
| 6 // from AuthCertificateCallback() in | 6 // from AuthCertificateCallback() in |
| 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. | 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. |
| 8 | 8 |
| 9 /* ***** BEGIN LICENSE BLOCK ***** | 9 /* ***** BEGIN LICENSE BLOCK ***** |
| 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 | 129 |
| 130 namespace net { | 130 namespace net { |
| 131 | 131 |
| 132 // State machines are easier to debug if you log state transitions. | 132 // State machines are easier to debug if you log state transitions. |
| 133 // Enable these if you want to see what's going on. | 133 // Enable these if you want to see what's going on. |
| 134 #if 1 | 134 #if 1 |
| 135 #define EnterFunction(x) | 135 #define EnterFunction(x) |
| 136 #define LeaveFunction(x) | 136 #define LeaveFunction(x) |
| 137 #define GotoState(s) next_handshake_state_ = s | 137 #define GotoState(s) next_handshake_state_ = s |
| 138 #else | 138 #else |
| 139 #define EnterFunction(x)\ | 139 #define EnterFunction(x) \ |
| 140 VLOG(1) << (void *)this << " " << __FUNCTION__ << " enter " << x\ | 140 VLOG(1) << (void*) this << " " << __FUNCTION__ << " enter " << x \ |
| 141 << "; next_handshake_state " << next_handshake_state_ | 141 << "; next_handshake_state " << next_handshake_state_ |
| 142 #define LeaveFunction(x)\ | 142 #define LeaveFunction(x) \ |
| 143 VLOG(1) << (void *)this << " " << __FUNCTION__ << " leave " << x\ | 143 VLOG(1) << (void*) this << " " << __FUNCTION__ << " leave " << x \ |
| 144 << "; next_handshake_state " << next_handshake_state_ | 144 << "; next_handshake_state " << next_handshake_state_ |
| 145 #define GotoState(s)\ | 145 #define GotoState(s) \ |
| 146 do {\ | 146 do { \ |
| 147 VLOG(1) << (void *)this << " " << __FUNCTION__ << " jump to state " << s;\ | 147 VLOG(1) << (void*) this << " " << __FUNCTION__ << " jump to state " << s; \ |
| 148 next_handshake_state_ = s;\ | 148 next_handshake_state_ = s; \ |
| 149 } while (0) | 149 } while (0) |
| 150 #endif | 150 #endif |
| 151 | 151 |
| 152 namespace { | 152 namespace { |
| 153 | 153 |
| 154 // SSL plaintext fragments are shorter than 16KB. Although the record layer | 154 // SSL plaintext fragments are shorter than 16KB. Although the record layer |
| 155 // overhead is allowed to be 2K + 5 bytes, in practice the overhead is much | 155 // overhead is allowed to be 2K + 5 bytes, in practice the overhead is much |
| 156 // smaller than 1KB. So a 17KB buffer should be large enough to hold an | 156 // smaller than 1KB. So a 17KB buffer should be large enough to hold an |
| 157 // entire SSL record. | 157 // entire SSL record. |
| 158 const int kRecvBufferSize = 17 * 1024; | 158 const int kRecvBufferSize = 17 * 1024; |
| 159 const int kSendBufferSize = 17 * 1024; | 159 const int kSendBufferSize = 17 * 1024; |
| 160 | 160 |
| 161 // Used by SSLClientSocketNSS::Core to indicate there is no read result | 161 // Used by SSLClientSocketNSS::Core to indicate there is no read result |
| 162 // obtained by a previous operation waiting to be returned to the caller. | 162 // obtained by a previous operation waiting to be returned to the caller. |
| 163 // This constant can be any non-negative/non-zero value (eg: it does not | 163 // This constant can be any non-negative/non-zero value (eg: it does not |
| 164 // overlap with any value of the net::Error range, including net::OK). | 164 // overlap with any value of the net::Error range, including net::OK). |
| 165 const int kNoPendingReadResult = 1; | 165 const int kNoPendingReadResult = 1; |
| 166 | 166 |
| 167 #if defined(OS_WIN) | 167 #if defined(OS_WIN) |
| 168 // CERT_OCSP_RESPONSE_PROP_ID is only implemented on Vista+, but it can be | 168 // CERT_OCSP_RESPONSE_PROP_ID is only implemented on Vista+, but it can be |
| 169 // set on Windows XP without error. There is some overhead from the server | 169 // set on Windows XP without error. There is some overhead from the server |
| 170 // sending the OCSP response if it supports the extension, for the subset of | 170 // sending the OCSP response if it supports the extension, for the subset of |
| 171 // XP clients who will request it but be unable to use it, but this is an | 171 // XP clients who will request it but be unable to use it, but this is an |
| 172 // acceptable trade-off for simplicity of implementation. | 172 // acceptable trade-off for simplicity of implementation. |
| 173 bool IsOCSPStaplingSupported() { | 173 bool IsOCSPStaplingSupported() { |
| 174 return true; | 174 return true; |
| 175 } | 175 } |
| 176 #elif defined(USE_NSS) | 176 #elif defined(USE_NSS) |
| 177 typedef SECStatus | 177 typedef SECStatus (*CacheOCSPResponseFromSideChannelFunction)( |
| 178 (*CacheOCSPResponseFromSideChannelFunction)( | 178 CERTCertDBHandle* handle, |
| 179 CERTCertDBHandle *handle, CERTCertificate *cert, PRTime time, | 179 CERTCertificate* cert, |
| 180 SECItem *encodedResponse, void *pwArg); | 180 PRTime time, |
| 181 SECItem* encodedResponse, |
| 182 void* pwArg); |
| 181 | 183 |
| 182 // On Linux, we dynamically link against the system version of libnss3.so. In | 184 // On Linux, we dynamically link against the system version of libnss3.so. In |
| 183 // order to continue working on systems without up-to-date versions of NSS we | 185 // order to continue working on systems without up-to-date versions of NSS we |
| 184 // lookup CERT_CacheOCSPResponseFromSideChannel with dlsym. | 186 // lookup CERT_CacheOCSPResponseFromSideChannel with dlsym. |
| 185 | 187 |
| 186 // RuntimeLibNSSFunctionPointers is a singleton which caches the results of any | 188 // RuntimeLibNSSFunctionPointers is a singleton which caches the results of any |
| 187 // runtime symbol resolution that we need. | 189 // runtime symbol resolution that we need. |
| 188 class RuntimeLibNSSFunctionPointers { | 190 class RuntimeLibNSSFunctionPointers { |
| 189 public: | 191 public: |
| 190 CacheOCSPResponseFromSideChannelFunction | 192 CacheOCSPResponseFromSideChannelFunction |
| 191 GetCacheOCSPResponseFromSideChannelFunction() { | 193 GetCacheOCSPResponseFromSideChannelFunction() { |
| 192 return cache_ocsp_response_from_side_channel_; | 194 return cache_ocsp_response_from_side_channel_; |
| 193 } | 195 } |
| 194 | 196 |
| 195 static RuntimeLibNSSFunctionPointers* GetInstance() { | 197 static RuntimeLibNSSFunctionPointers* GetInstance() { |
| 196 return Singleton<RuntimeLibNSSFunctionPointers>::get(); | 198 return Singleton<RuntimeLibNSSFunctionPointers>::get(); |
| 197 } | 199 } |
| 198 | 200 |
| 199 private: | 201 private: |
| 200 friend struct DefaultSingletonTraits<RuntimeLibNSSFunctionPointers>; | 202 friend struct DefaultSingletonTraits<RuntimeLibNSSFunctionPointers>; |
| 201 | 203 |
| 202 RuntimeLibNSSFunctionPointers() { | 204 RuntimeLibNSSFunctionPointers() { |
| 203 cache_ocsp_response_from_side_channel_ = | 205 cache_ocsp_response_from_side_channel_ = |
| 204 (CacheOCSPResponseFromSideChannelFunction) | 206 (CacheOCSPResponseFromSideChannelFunction)dlsym( |
| 205 dlsym(RTLD_DEFAULT, "CERT_CacheOCSPResponseFromSideChannel"); | 207 RTLD_DEFAULT, "CERT_CacheOCSPResponseFromSideChannel"); |
| 206 } | 208 } |
| 207 | 209 |
| 208 CacheOCSPResponseFromSideChannelFunction | 210 CacheOCSPResponseFromSideChannelFunction |
| 209 cache_ocsp_response_from_side_channel_; | 211 cache_ocsp_response_from_side_channel_; |
| 210 }; | 212 }; |
| 211 | 213 |
| 212 CacheOCSPResponseFromSideChannelFunction | 214 CacheOCSPResponseFromSideChannelFunction |
| 213 GetCacheOCSPResponseFromSideChannelFunction() { | 215 GetCacheOCSPResponseFromSideChannelFunction() { |
| 214 return RuntimeLibNSSFunctionPointers::GetInstance() | 216 return RuntimeLibNSSFunctionPointers::GetInstance() |
| 215 ->GetCacheOCSPResponseFromSideChannelFunction(); | 217 ->GetCacheOCSPResponseFromSideChannelFunction(); |
| 216 } | 218 } |
| 217 | 219 |
| 218 bool IsOCSPStaplingSupported() { | 220 bool IsOCSPStaplingSupported() { |
| 219 return GetCacheOCSPResponseFromSideChannelFunction() != NULL; | 221 return GetCacheOCSPResponseFromSideChannelFunction() != NULL; |
| 220 } | 222 } |
| 221 #else | 223 #else |
| 222 // TODO(agl): Figure out if we can plumb the OCSP response into Mac's system | 224 // TODO(agl): Figure out if we can plumb the OCSP response into Mac's system |
| 223 // certificate validation functions. | 225 // certificate validation functions. |
| 224 bool IsOCSPStaplingSupported() { | 226 bool IsOCSPStaplingSupported() { |
| 225 return false; | 227 return false; |
| 226 } | 228 } |
| 227 #endif | 229 #endif |
| 228 | 230 |
| 229 #if defined(OS_WIN) | 231 #if defined(OS_WIN) |
| 230 | 232 |
| 231 // This callback is intended to be used with CertFindChainInStore. In addition | 233 // This callback is intended to be used with CertFindChainInStore. In addition |
| 232 // to filtering by extended/enhanced key usage, we do not show expired | 234 // to filtering by extended/enhanced key usage, we do not show expired |
| 233 // certificates and require digital signature usage in the key usage | 235 // certificates and require digital signature usage in the key usage |
| 234 // extension. | 236 // extension. |
| 235 // | 237 // |
| 236 // This matches our behavior on Mac OS X and that of NSS. It also matches the | 238 // This matches our behavior on Mac OS X and that of NSS. It also matches the |
| 237 // default behavior of IE8. See http://support.microsoft.com/kb/890326 and | 239 // default behavior of IE8. See http://support.microsoft.com/kb/890326 and |
| 238 // http://blogs.msdn.com/b/askie/archive/2009/06/09/my-expired-client-certificat
es-no-longer-display-when-connecting-to-my-web-server-using-ie8.aspx | 240 // http://blogs.msdn.com/b/askie/archive/2009/06/09/my-expired-client-certificat
es-no-longer-display-when-connecting-to-my-web-server-using-ie8.aspx |
| 239 BOOL WINAPI ClientCertFindCallback(PCCERT_CONTEXT cert_context, | 241 BOOL WINAPI |
| 240 void* find_arg) { | 242 ClientCertFindCallback(PCCERT_CONTEXT cert_context, void* find_arg) { |
| 241 VLOG(1) << "Calling ClientCertFindCallback from _nss"; | 243 VLOG(1) << "Calling ClientCertFindCallback from _nss"; |
| 242 // Verify the certificate's KU is good. | 244 // Verify the certificate's KU is good. |
| 243 BYTE key_usage; | 245 BYTE key_usage; |
| 244 if (CertGetIntendedKeyUsage(X509_ASN_ENCODING, cert_context->pCertInfo, | 246 if (CertGetIntendedKeyUsage( |
| 245 &key_usage, 1)) { | 247 X509_ASN_ENCODING, cert_context->pCertInfo, &key_usage, 1)) { |
| 246 if (!(key_usage & CERT_DIGITAL_SIGNATURE_KEY_USAGE)) | 248 if (!(key_usage & CERT_DIGITAL_SIGNATURE_KEY_USAGE)) |
| 247 return FALSE; | 249 return FALSE; |
| 248 } else { | 250 } else { |
| 249 DWORD err = GetLastError(); | 251 DWORD err = GetLastError(); |
| 250 // If |err| is non-zero, it's an actual error. Otherwise the extension | 252 // If |err| is non-zero, it's an actual error. Otherwise the extension |
| 251 // just isn't present, and we treat it as if everything was allowed. | 253 // just isn't present, and we treat it as if everything was allowed. |
| 252 if (err) { | 254 if (err) { |
| 253 DLOG(ERROR) << "CertGetIntendedKeyUsage failed: " << err; | 255 DLOG(ERROR) << "CertGetIntendedKeyUsage failed: " << err; |
| 254 return FALSE; | 256 return FALSE; |
| 255 } | 257 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 // Helper function to make it easier to call BoundNetLog::AddByteTransferEvent | 295 // Helper function to make it easier to call BoundNetLog::AddByteTransferEvent |
| 294 // from within the SSLClientSocketNSS::Core. | 296 // from within the SSLClientSocketNSS::Core. |
| 295 // AddByteTransferEvent expects to receive a const char*, which within the | 297 // AddByteTransferEvent expects to receive a const char*, which within the |
| 296 // Core is backed by an IOBuffer. If the "const char*" is bound via | 298 // Core is backed by an IOBuffer. If the "const char*" is bound via |
| 297 // base::Bind and posted to another thread, and the IOBuffer that backs that | 299 // base::Bind and posted to another thread, and the IOBuffer that backs that |
| 298 // pointer then goes out of scope on the origin thread, this would result in | 300 // pointer then goes out of scope on the origin thread, this would result in |
| 299 // an invalid read of a stale pointer. | 301 // an invalid read of a stale pointer. |
| 300 // Instead, provide a signature that accepts an IOBuffer*, so that a reference | 302 // Instead, provide a signature that accepts an IOBuffer*, so that a reference |
| 301 // to the owning IOBuffer can be bound to the Callback. This ensures that the | 303 // to the owning IOBuffer can be bound to the Callback. This ensures that the |
| 302 // IOBuffer will stay alive long enough to cross threads if needed. | 304 // IOBuffer will stay alive long enough to cross threads if needed. |
| 303 void LogByteTransferEvent( | 305 void LogByteTransferEvent(const base::WeakPtr<BoundNetLog>& net_log, |
| 304 const base::WeakPtr<BoundNetLog>& net_log, NetLog::EventType event_type, | 306 NetLog::EventType event_type, |
| 305 int len, IOBuffer* buffer) { | 307 int len, |
| 308 IOBuffer* buffer) { |
| 306 if (!net_log) | 309 if (!net_log) |
| 307 return; | 310 return; |
| 308 net_log->AddByteTransferEvent(event_type, len, buffer->data()); | 311 net_log->AddByteTransferEvent(event_type, len, buffer->data()); |
| 309 } | 312 } |
| 310 | 313 |
| 311 // PeerCertificateChain is a helper object which extracts the certificate | 314 // PeerCertificateChain is a helper object which extracts the certificate |
| 312 // chain, as given by the server, from an NSS socket and performs the needed | 315 // chain, as given by the server, from an NSS socket and performs the needed |
| 313 // resource management. The first element of the chain is the leaf certificate | 316 // resource management. The first element of the chain is the leaf certificate |
| 314 // and the other elements are in the order given by the server. | 317 // and the other elements are in the order given by the server. |
| 315 class PeerCertificateChain { | 318 class PeerCertificateChain { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 333 | 336 |
| 334 CERTCertificate* operator[](size_t index) const { | 337 CERTCertificate* operator[](size_t index) const { |
| 335 DCHECK_LT(index, certs_.size()); | 338 DCHECK_LT(index, certs_.size()); |
| 336 return certs_[index]; | 339 return certs_[index]; |
| 337 } | 340 } |
| 338 | 341 |
| 339 private: | 342 private: |
| 340 std::vector<CERTCertificate*> certs_; | 343 std::vector<CERTCertificate*> certs_; |
| 341 }; | 344 }; |
| 342 | 345 |
| 343 PeerCertificateChain::PeerCertificateChain( | 346 PeerCertificateChain::PeerCertificateChain(const PeerCertificateChain& other) { |
| 344 const PeerCertificateChain& other) { | |
| 345 *this = other; | 347 *this = other; |
| 346 } | 348 } |
| 347 | 349 |
| 348 PeerCertificateChain::~PeerCertificateChain() { | 350 PeerCertificateChain::~PeerCertificateChain() { |
| 349 Reset(NULL); | 351 Reset(NULL); |
| 350 } | 352 } |
| 351 | 353 |
| 352 PeerCertificateChain& PeerCertificateChain::operator=( | 354 PeerCertificateChain& PeerCertificateChain::operator=( |
| 353 const PeerCertificateChain& other) { | 355 const PeerCertificateChain& other) { |
| 354 if (this == &other) | 356 if (this == &other) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 369 | 371 |
| 370 if (nss_fd == NULL) | 372 if (nss_fd == NULL) |
| 371 return; | 373 return; |
| 372 | 374 |
| 373 CERTCertList* list = SSL_PeerCertificateChain(nss_fd); | 375 CERTCertList* list = SSL_PeerCertificateChain(nss_fd); |
| 374 // The handshake on |nss_fd| may not have completed. | 376 // The handshake on |nss_fd| may not have completed. |
| 375 if (list == NULL) | 377 if (list == NULL) |
| 376 return; | 378 return; |
| 377 | 379 |
| 378 for (CERTCertListNode* node = CERT_LIST_HEAD(list); | 380 for (CERTCertListNode* node = CERT_LIST_HEAD(list); |
| 379 !CERT_LIST_END(node, list); node = CERT_LIST_NEXT(node)) { | 381 !CERT_LIST_END(node, list); |
| 382 node = CERT_LIST_NEXT(node)) { |
| 380 certs_.push_back(CERT_DupCertificate(node->cert)); | 383 certs_.push_back(CERT_DupCertificate(node->cert)); |
| 381 } | 384 } |
| 382 CERT_DestroyCertList(list); | 385 CERT_DestroyCertList(list); |
| 383 } | 386 } |
| 384 | 387 |
| 385 std::vector<base::StringPiece> | 388 std::vector<base::StringPiece> PeerCertificateChain::AsStringPieceVector() |
| 386 PeerCertificateChain::AsStringPieceVector() const { | 389 const { |
| 387 std::vector<base::StringPiece> v(certs_.size()); | 390 std::vector<base::StringPiece> v(certs_.size()); |
| 388 for (unsigned i = 0; i < certs_.size(); i++) { | 391 for (unsigned i = 0; i < certs_.size(); i++) { |
| 389 v[i] = base::StringPiece( | 392 v[i] = base::StringPiece( |
| 390 reinterpret_cast<const char*>(certs_[i]->derCert.data), | 393 reinterpret_cast<const char*>(certs_[i]->derCert.data), |
| 391 certs_[i]->derCert.len); | 394 certs_[i]->derCert.len); |
| 392 } | 395 } |
| 393 | 396 |
| 394 return v; | 397 return v; |
| 395 } | 398 } |
| 396 | 399 |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 // is verified afterwards. | 674 // is verified afterwards. |
| 672 // This behaviour is an artifact of the original SSLClientSocketWin | 675 // This behaviour is an artifact of the original SSLClientSocketWin |
| 673 // implementation, which could not verify the peer's certificate until after | 676 // implementation, which could not verify the peer's certificate until after |
| 674 // the handshake had completed, as well as bugs in NSS that prevent | 677 // the handshake had completed, as well as bugs in NSS that prevent |
| 675 // SSL_RestartHandshakeAfterCertReq from working. | 678 // SSL_RestartHandshakeAfterCertReq from working. |
| 676 static SECStatus OwnAuthCertHandler(void* arg, | 679 static SECStatus OwnAuthCertHandler(void* arg, |
| 677 PRFileDesc* socket, | 680 PRFileDesc* socket, |
| 678 PRBool checksig, | 681 PRBool checksig, |
| 679 PRBool is_server); | 682 PRBool is_server); |
| 680 | 683 |
| 681 // Callbacks called by NSS when the peer requests client certificate | 684 // Callbacks called by NSS when the peer requests client certificate |
| 682 // authentication. | 685 // authentication. |
| 683 // See the documentation in third_party/nss/ssl/ssl.h for the meanings of | 686 // See the documentation in third_party/nss/ssl/ssl.h for the meanings of |
| 684 // the arguments. | 687 // the arguments. |
| 685 #if defined(NSS_PLATFORM_CLIENT_AUTH) | 688 #if defined(NSS_PLATFORM_CLIENT_AUTH) |
| 686 // When NSS has been integrated with awareness of the underlying system | 689 // When NSS has been integrated with awareness of the underlying system |
| 687 // cryptographic libraries, this callback allows the caller to supply a | 690 // cryptographic libraries, this callback allows the caller to supply a |
| 688 // native platform certificate and key for use by NSS. At most, one of | 691 // native platform certificate and key for use by NSS. At most, one of |
| 689 // either (result_certs, result_private_key) or (result_nss_certificate, | 692 // either (result_certs, result_private_key) or (result_nss_certificate, |
| 690 // result_nss_private_key) should be set. | 693 // result_nss_private_key) should be set. |
| 691 // |arg| contains a pointer to the current SSLClientSocketNSS::Core. | 694 // |arg| contains a pointer to the current SSLClientSocketNSS::Core. |
| 692 static SECStatus PlatformClientAuthHandler( | 695 static SECStatus PlatformClientAuthHandler( |
| 693 void* arg, | 696 void* arg, |
| 694 PRFileDesc* socket, | 697 PRFileDesc* socket, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 737 int BufferSend(); | 740 int BufferSend(); |
| 738 | 741 |
| 739 void OnRecvComplete(int result); | 742 void OnRecvComplete(int result); |
| 740 void OnSendComplete(int result); | 743 void OnSendComplete(int result); |
| 741 | 744 |
| 742 void DoConnectCallback(int result); | 745 void DoConnectCallback(int result); |
| 743 void DoReadCallback(int result); | 746 void DoReadCallback(int result); |
| 744 void DoWriteCallback(int result); | 747 void DoWriteCallback(int result); |
| 745 | 748 |
| 746 // Client channel ID handler. | 749 // Client channel ID handler. |
| 747 static SECStatus ClientChannelIDHandler( | 750 static SECStatus ClientChannelIDHandler(void* arg, |
| 748 void* arg, | 751 PRFileDesc* socket, |
| 749 PRFileDesc* socket, | 752 SECKEYPublicKey** out_public_key, |
| 750 SECKEYPublicKey **out_public_key, | 753 SECKEYPrivateKey** out_private_key); |
| 751 SECKEYPrivateKey **out_private_key); | |
| 752 | 754 |
| 753 // ImportChannelIDKeys is a helper function for turning a DER-encoded cert and | 755 // ImportChannelIDKeys is a helper function for turning a DER-encoded cert and |
| 754 // key into a SECKEYPublicKey and SECKEYPrivateKey. Returns OK upon success | 756 // key into a SECKEYPublicKey and SECKEYPrivateKey. Returns OK upon success |
| 755 // and an error code otherwise. | 757 // and an error code otherwise. |
| 756 // Requires |domain_bound_private_key_| and |domain_bound_cert_| to have been | 758 // Requires |domain_bound_private_key_| and |domain_bound_cert_| to have been |
| 757 // set by a call to ServerBoundCertService->GetDomainBoundCert. The caller | 759 // set by a call to ServerBoundCertService->GetDomainBoundCert. The caller |
| 758 // takes ownership of the |*cert| and |*key|. | 760 // takes ownership of the |*cert| and |*key|. |
| 759 int ImportChannelIDKeys(SECKEYPublicKey** public_key, SECKEYPrivateKey** key); | 761 int ImportChannelIDKeys(SECKEYPublicKey** public_key, SECKEYPrivateKey** key); |
| 760 | 762 |
| 761 // Updates the NSS and platform specific certificates. | 763 // Updates the NSS and platform specific certificates. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 781 //////////////////////////////////////////////////////////////////////////// | 783 //////////////////////////////////////////////////////////////////////////// |
| 782 int DoBufferRecv(IOBuffer* buffer, int len); | 784 int DoBufferRecv(IOBuffer* buffer, int len); |
| 783 int DoBufferSend(IOBuffer* buffer, int len); | 785 int DoBufferSend(IOBuffer* buffer, int len); |
| 784 int DoGetDomainBoundCert(const std::string& host); | 786 int DoGetDomainBoundCert(const std::string& host); |
| 785 | 787 |
| 786 void OnGetDomainBoundCertComplete(int result); | 788 void OnGetDomainBoundCertComplete(int result); |
| 787 void OnHandshakeStateUpdated(const HandshakeState& state); | 789 void OnHandshakeStateUpdated(const HandshakeState& state); |
| 788 void OnNSSBufferUpdated(int amount_in_read_buffer); | 790 void OnNSSBufferUpdated(int amount_in_read_buffer); |
| 789 void DidNSSRead(int result); | 791 void DidNSSRead(int result); |
| 790 void DidNSSWrite(int result); | 792 void DidNSSWrite(int result); |
| 791 void RecordChannelIDSupportOnNetworkTaskRunner( | 793 void RecordChannelIDSupportOnNetworkTaskRunner(bool negotiated_channel_id, |
| 792 bool negotiated_channel_id, | 794 bool channel_id_enabled, |
| 793 bool channel_id_enabled, | 795 bool supports_ecc) const; |
| 794 bool supports_ecc) const; | |
| 795 | 796 |
| 796 //////////////////////////////////////////////////////////////////////////// | 797 //////////////////////////////////////////////////////////////////////////// |
| 797 // Methods that are called on both the network task runner and the NSS | 798 // Methods that are called on both the network task runner and the NSS |
| 798 // task runner. | 799 // task runner. |
| 799 //////////////////////////////////////////////////////////////////////////// | 800 //////////////////////////////////////////////////////////////////////////// |
| 800 void OnHandshakeIOComplete(int result); | 801 void OnHandshakeIOComplete(int result); |
| 801 void BufferRecvComplete(IOBuffer* buffer, int result); | 802 void BufferRecvComplete(IOBuffer* buffer, int result); |
| 802 void BufferSendComplete(int result); | 803 void BufferSendComplete(int result); |
| 803 | 804 |
| 804 // PostOrRunCallback is a helper function to ensure that |callback| is | 805 // PostOrRunCallback is a helper function to ensure that |callback| is |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 977 DCHECK(!nss_fd_); | 978 DCHECK(!nss_fd_); |
| 978 DCHECK(!nss_bufs_); | 979 DCHECK(!nss_bufs_); |
| 979 | 980 |
| 980 nss_fd_ = socket; | 981 nss_fd_ = socket; |
| 981 nss_bufs_ = buffers; | 982 nss_bufs_ = buffers; |
| 982 | 983 |
| 983 SECStatus rv = SECSuccess; | 984 SECStatus rv = SECSuccess; |
| 984 | 985 |
| 985 if (!ssl_config_.next_protos.empty()) { | 986 if (!ssl_config_.next_protos.empty()) { |
| 986 size_t wire_length = 0; | 987 size_t wire_length = 0; |
| 987 for (std::vector<std::string>::const_iterator | 988 for (std::vector<std::string>::const_iterator i = |
| 988 i = ssl_config_.next_protos.begin(); | 989 ssl_config_.next_protos.begin(); |
| 989 i != ssl_config_.next_protos.end(); ++i) { | 990 i != ssl_config_.next_protos.end(); |
| 991 ++i) { |
| 990 if (i->size() > 255) { | 992 if (i->size() > 255) { |
| 991 LOG(WARNING) << "Ignoring overlong NPN/ALPN protocol: " << *i; | 993 LOG(WARNING) << "Ignoring overlong NPN/ALPN protocol: " << *i; |
| 992 continue; | 994 continue; |
| 993 } | 995 } |
| 994 wire_length += i->size(); | 996 wire_length += i->size(); |
| 995 wire_length++; | 997 wire_length++; |
| 996 } | 998 } |
| 997 scoped_ptr<uint8[]> wire_protos(new uint8[wire_length]); | 999 scoped_ptr<uint8[]> wire_protos(new uint8[wire_length]); |
| 998 uint8* dst = wire_protos.get(); | 1000 uint8* dst = wire_protos.get(); |
| 999 for (std::vector<std::string>::const_iterator | 1001 for (std::vector<std::string>::const_iterator i = |
| 1000 i = ssl_config_.next_protos.begin(); | 1002 ssl_config_.next_protos.begin(); |
| 1001 i != ssl_config_.next_protos.end(); i++) { | 1003 i != ssl_config_.next_protos.end(); |
| 1004 i++) { |
| 1002 if (i->size() > 255) | 1005 if (i->size() > 255) |
| 1003 continue; | 1006 continue; |
| 1004 *dst++ = i->size(); | 1007 *dst++ = i->size(); |
| 1005 memcpy(dst, i->data(), i->size()); | 1008 memcpy(dst, i->data(), i->size()); |
| 1006 dst += i->size(); | 1009 dst += i->size(); |
| 1007 } | 1010 } |
| 1008 DCHECK_EQ(dst, wire_protos.get() + wire_length); | 1011 DCHECK_EQ(dst, wire_protos.get() + wire_length); |
| 1009 rv = SSL_SetNextProtoNego(nss_fd_, wire_protos.get(), wire_length); | 1012 rv = SSL_SetNextProtoNego(nss_fd_, wire_protos.get(), wire_length); |
| 1010 if (rv != SECSuccess) | 1013 if (rv != SECSuccess) |
| 1011 LogFailedNSSFunction(*weak_net_log_, "SSL_SetNextProtoNego", ""); | 1014 LogFailedNSSFunction(*weak_net_log_, "SSL_SetNextProtoNego", ""); |
| 1012 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_ALPN, PR_TRUE); | 1015 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_ALPN, PR_TRUE); |
| 1013 if (rv != SECSuccess) | 1016 if (rv != SECSuccess) |
| 1014 LogFailedNSSFunction(*weak_net_log_, "SSL_OptionSet", "SSL_ENABLE_ALPN"); | 1017 LogFailedNSSFunction(*weak_net_log_, "SSL_OptionSet", "SSL_ENABLE_ALPN"); |
| 1015 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_NPN, PR_TRUE); | 1018 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_NPN, PR_TRUE); |
| 1016 if (rv != SECSuccess) | 1019 if (rv != SECSuccess) |
| 1017 LogFailedNSSFunction(*weak_net_log_, "SSL_OptionSet", "SSL_ENABLE_NPN"); | 1020 LogFailedNSSFunction(*weak_net_log_, "SSL_OptionSet", "SSL_ENABLE_NPN"); |
| 1018 } | 1021 } |
| 1019 | 1022 |
| 1020 rv = SSL_AuthCertificateHook( | 1023 rv = SSL_AuthCertificateHook( |
| 1021 nss_fd_, SSLClientSocketNSS::Core::OwnAuthCertHandler, this); | 1024 nss_fd_, SSLClientSocketNSS::Core::OwnAuthCertHandler, this); |
| 1022 if (rv != SECSuccess) { | 1025 if (rv != SECSuccess) { |
| 1023 LogFailedNSSFunction(*weak_net_log_, "SSL_AuthCertificateHook", ""); | 1026 LogFailedNSSFunction(*weak_net_log_, "SSL_AuthCertificateHook", ""); |
| 1024 return false; | 1027 return false; |
| 1025 } | 1028 } |
| 1026 | 1029 |
| 1027 #if defined(NSS_PLATFORM_CLIENT_AUTH) | 1030 #if defined(NSS_PLATFORM_CLIENT_AUTH) |
| 1028 rv = SSL_GetPlatformClientAuthDataHook( | 1031 rv = SSL_GetPlatformClientAuthDataHook( |
| 1029 nss_fd_, SSLClientSocketNSS::Core::PlatformClientAuthHandler, | 1032 nss_fd_, SSLClientSocketNSS::Core::PlatformClientAuthHandler, this); |
| 1030 this); | |
| 1031 #else | 1033 #else |
| 1032 rv = SSL_GetClientAuthDataHook( | 1034 rv = SSL_GetClientAuthDataHook( |
| 1033 nss_fd_, SSLClientSocketNSS::Core::ClientAuthHandler, this); | 1035 nss_fd_, SSLClientSocketNSS::Core::ClientAuthHandler, this); |
| 1034 #endif | 1036 #endif |
| 1035 if (rv != SECSuccess) { | 1037 if (rv != SECSuccess) { |
| 1036 LogFailedNSSFunction(*weak_net_log_, "SSL_GetClientAuthDataHook", ""); | 1038 LogFailedNSSFunction(*weak_net_log_, "SSL_GetClientAuthDataHook", ""); |
| 1037 return false; | 1039 return false; |
| 1038 } | 1040 } |
| 1039 | 1041 |
| 1040 if (IsChannelIDEnabled(ssl_config_, server_bound_cert_service_)) { | 1042 if (IsChannelIDEnabled(ssl_config_, server_bound_cert_service_)) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1060 return false; | 1062 return false; |
| 1061 } | 1063 } |
| 1062 | 1064 |
| 1063 return true; | 1065 return true; |
| 1064 } | 1066 } |
| 1065 | 1067 |
| 1066 int SSLClientSocketNSS::Core::Connect(const CompletionCallback& callback) { | 1068 int SSLClientSocketNSS::Core::Connect(const CompletionCallback& callback) { |
| 1067 if (!OnNSSTaskRunner()) { | 1069 if (!OnNSSTaskRunner()) { |
| 1068 DCHECK(!detached_); | 1070 DCHECK(!detached_); |
| 1069 bool posted = nss_task_runner_->PostTask( | 1071 bool posted = nss_task_runner_->PostTask( |
| 1070 FROM_HERE, | 1072 FROM_HERE, base::Bind(IgnoreResult(&Core::Connect), this, callback)); |
| 1071 base::Bind(IgnoreResult(&Core::Connect), this, callback)); | |
| 1072 return posted ? ERR_IO_PENDING : ERR_ABORTED; | 1073 return posted ? ERR_IO_PENDING : ERR_ABORTED; |
| 1073 } | 1074 } |
| 1074 | 1075 |
| 1075 DCHECK(OnNSSTaskRunner()); | 1076 DCHECK(OnNSSTaskRunner()); |
| 1076 DCHECK_EQ(STATE_NONE, next_handshake_state_); | 1077 DCHECK_EQ(STATE_NONE, next_handshake_state_); |
| 1077 DCHECK(user_read_callback_.is_null()); | 1078 DCHECK(user_read_callback_.is_null()); |
| 1078 DCHECK(user_write_callback_.is_null()); | 1079 DCHECK(user_write_callback_.is_null()); |
| 1079 DCHECK(user_connect_callback_.is_null()); | 1080 DCHECK(user_connect_callback_.is_null()); |
| 1080 DCHECK(!user_read_buf_.get()); | 1081 DCHECK(!user_read_buf_.get()); |
| 1081 DCHECK(!user_write_buf_.get()); | 1082 DCHECK(!user_write_buf_.get()); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1100 | 1101 |
| 1101 detached_ = true; | 1102 detached_ = true; |
| 1102 transport_ = NULL; | 1103 transport_ = NULL; |
| 1103 weak_net_log_factory_.InvalidateWeakPtrs(); | 1104 weak_net_log_factory_.InvalidateWeakPtrs(); |
| 1104 | 1105 |
| 1105 network_handshake_state_.Reset(); | 1106 network_handshake_state_.Reset(); |
| 1106 | 1107 |
| 1107 domain_bound_cert_request_handle_.Cancel(); | 1108 domain_bound_cert_request_handle_.Cancel(); |
| 1108 } | 1109 } |
| 1109 | 1110 |
| 1110 int SSLClientSocketNSS::Core::Read(IOBuffer* buf, int buf_len, | 1111 int SSLClientSocketNSS::Core::Read(IOBuffer* buf, |
| 1112 int buf_len, |
| 1111 const CompletionCallback& callback) { | 1113 const CompletionCallback& callback) { |
| 1112 if (!OnNSSTaskRunner()) { | 1114 if (!OnNSSTaskRunner()) { |
| 1113 DCHECK(OnNetworkTaskRunner()); | 1115 DCHECK(OnNetworkTaskRunner()); |
| 1114 DCHECK(!detached_); | 1116 DCHECK(!detached_); |
| 1115 DCHECK(transport_); | 1117 DCHECK(transport_); |
| 1116 DCHECK(!nss_waiting_read_); | 1118 DCHECK(!nss_waiting_read_); |
| 1117 | 1119 |
| 1118 nss_waiting_read_ = true; | 1120 nss_waiting_read_ = true; |
| 1119 bool posted = nss_task_runner_->PostTask( | 1121 bool posted = |
| 1120 FROM_HERE, | 1122 nss_task_runner_->PostTask(FROM_HERE, |
| 1121 base::Bind(IgnoreResult(&Core::Read), this, make_scoped_refptr(buf), | 1123 base::Bind(IgnoreResult(&Core::Read), |
| 1122 buf_len, callback)); | 1124 this, |
| 1125 make_scoped_refptr(buf), |
| 1126 buf_len, |
| 1127 callback)); |
| 1123 if (!posted) { | 1128 if (!posted) { |
| 1124 nss_is_closed_ = true; | 1129 nss_is_closed_ = true; |
| 1125 nss_waiting_read_ = false; | 1130 nss_waiting_read_ = false; |
| 1126 } | 1131 } |
| 1127 return posted ? ERR_IO_PENDING : ERR_ABORTED; | 1132 return posted ? ERR_IO_PENDING : ERR_ABORTED; |
| 1128 } | 1133 } |
| 1129 | 1134 |
| 1130 DCHECK(OnNSSTaskRunner()); | 1135 DCHECK(OnNSSTaskRunner()); |
| 1131 DCHECK(false_started_ || handshake_callback_called_); | 1136 DCHECK(false_started_ || handshake_callback_called_); |
| 1132 DCHECK_EQ(STATE_NONE, next_handshake_state_); | 1137 DCHECK_EQ(STATE_NONE, next_handshake_state_); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1157 nss_is_closed_ = true; | 1162 nss_is_closed_ = true; |
| 1158 } else { | 1163 } else { |
| 1159 was_ever_used_ = true; | 1164 was_ever_used_ = true; |
| 1160 } | 1165 } |
| 1161 } | 1166 } |
| 1162 } | 1167 } |
| 1163 | 1168 |
| 1164 return rv; | 1169 return rv; |
| 1165 } | 1170 } |
| 1166 | 1171 |
| 1167 int SSLClientSocketNSS::Core::Write(IOBuffer* buf, int buf_len, | 1172 int SSLClientSocketNSS::Core::Write(IOBuffer* buf, |
| 1173 int buf_len, |
| 1168 const CompletionCallback& callback) { | 1174 const CompletionCallback& callback) { |
| 1169 if (!OnNSSTaskRunner()) { | 1175 if (!OnNSSTaskRunner()) { |
| 1170 DCHECK(OnNetworkTaskRunner()); | 1176 DCHECK(OnNetworkTaskRunner()); |
| 1171 DCHECK(!detached_); | 1177 DCHECK(!detached_); |
| 1172 DCHECK(transport_); | 1178 DCHECK(transport_); |
| 1173 DCHECK(!nss_waiting_write_); | 1179 DCHECK(!nss_waiting_write_); |
| 1174 | 1180 |
| 1175 nss_waiting_write_ = true; | 1181 nss_waiting_write_ = true; |
| 1176 bool posted = nss_task_runner_->PostTask( | 1182 bool posted = |
| 1177 FROM_HERE, | 1183 nss_task_runner_->PostTask(FROM_HERE, |
| 1178 base::Bind(IgnoreResult(&Core::Write), this, make_scoped_refptr(buf), | 1184 base::Bind(IgnoreResult(&Core::Write), |
| 1179 buf_len, callback)); | 1185 this, |
| 1186 make_scoped_refptr(buf), |
| 1187 buf_len, |
| 1188 callback)); |
| 1180 if (!posted) { | 1189 if (!posted) { |
| 1181 nss_is_closed_ = true; | 1190 nss_is_closed_ = true; |
| 1182 nss_waiting_write_ = false; | 1191 nss_waiting_write_ = false; |
| 1183 } | 1192 } |
| 1184 return posted ? ERR_IO_PENDING : ERR_ABORTED; | 1193 return posted ? ERR_IO_PENDING : ERR_ABORTED; |
| 1185 } | 1194 } |
| 1186 | 1195 |
| 1187 DCHECK(OnNSSTaskRunner()); | 1196 DCHECK(OnNSSTaskRunner()); |
| 1188 DCHECK(false_started_ || handshake_callback_called_); | 1197 DCHECK(false_started_ || handshake_callback_called_); |
| 1189 DCHECK_EQ(STATE_NONE, next_handshake_state_); | 1198 DCHECK_EQ(STATE_NONE, next_handshake_state_); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1267 | 1276 |
| 1268 bool SSLClientSocketNSS::Core::OnNSSTaskRunner() const { | 1277 bool SSLClientSocketNSS::Core::OnNSSTaskRunner() const { |
| 1269 return nss_task_runner_->RunsTasksOnCurrentThread(); | 1278 return nss_task_runner_->RunsTasksOnCurrentThread(); |
| 1270 } | 1279 } |
| 1271 | 1280 |
| 1272 bool SSLClientSocketNSS::Core::OnNetworkTaskRunner() const { | 1281 bool SSLClientSocketNSS::Core::OnNetworkTaskRunner() const { |
| 1273 return network_task_runner_->RunsTasksOnCurrentThread(); | 1282 return network_task_runner_->RunsTasksOnCurrentThread(); |
| 1274 } | 1283 } |
| 1275 | 1284 |
| 1276 // static | 1285 // static |
| 1277 SECStatus SSLClientSocketNSS::Core::OwnAuthCertHandler( | 1286 SECStatus SSLClientSocketNSS::Core::OwnAuthCertHandler(void* arg, |
| 1278 void* arg, | 1287 PRFileDesc* socket, |
| 1279 PRFileDesc* socket, | 1288 PRBool checksig, |
| 1280 PRBool checksig, | 1289 PRBool is_server) { |
| 1281 PRBool is_server) { | |
| 1282 Core* core = reinterpret_cast<Core*>(arg); | 1290 Core* core = reinterpret_cast<Core*>(arg); |
| 1283 if (core->handshake_callback_called_) { | 1291 if (core->handshake_callback_called_) { |
| 1284 // Disallow the server certificate to change in a renegotiation. | 1292 // Disallow the server certificate to change in a renegotiation. |
| 1285 CERTCertificate* old_cert = core->nss_handshake_state_.server_cert_chain[0]; | 1293 CERTCertificate* old_cert = core->nss_handshake_state_.server_cert_chain[0]; |
| 1286 ScopedCERTCertificate new_cert(SSL_PeerCertificate(socket)); | 1294 ScopedCERTCertificate new_cert(SSL_PeerCertificate(socket)); |
| 1287 if (new_cert->derCert.len != old_cert->derCert.len || | 1295 if (new_cert->derCert.len != old_cert->derCert.len || |
| 1288 memcmp(new_cert->derCert.data, old_cert->derCert.data, | 1296 memcmp(new_cert->derCert.data, |
| 1297 old_cert->derCert.data, |
| 1289 new_cert->derCert.len) != 0) { | 1298 new_cert->derCert.len) != 0) { |
| 1290 // NSS doesn't have an error code that indicates the server certificate | 1299 // NSS doesn't have an error code that indicates the server certificate |
| 1291 // changed. Borrow SSL_ERROR_WRONG_CERTIFICATE (which NSS isn't using) | 1300 // changed. Borrow SSL_ERROR_WRONG_CERTIFICATE (which NSS isn't using) |
| 1292 // for this purpose. | 1301 // for this purpose. |
| 1293 PORT_SetError(SSL_ERROR_WRONG_CERTIFICATE); | 1302 PORT_SetError(SSL_ERROR_WRONG_CERTIFICATE); |
| 1294 return SECFailure; | 1303 return SECFailure; |
| 1295 } | 1304 } |
| 1296 } | 1305 } |
| 1297 | 1306 |
| 1298 // Tell NSS to not verify the certificate. | 1307 // Tell NSS to not verify the certificate. |
| 1299 return SECSuccess; | 1308 return SECSuccess; |
| 1300 } | 1309 } |
| 1301 | 1310 |
| 1302 #if defined(NSS_PLATFORM_CLIENT_AUTH) | 1311 #if defined(NSS_PLATFORM_CLIENT_AUTH) |
| 1303 // static | 1312 // static |
| 1304 SECStatus SSLClientSocketNSS::Core::PlatformClientAuthHandler( | 1313 SECStatus SSLClientSocketNSS::Core::PlatformClientAuthHandler( |
| 1305 void* arg, | 1314 void* arg, |
| 1306 PRFileDesc* socket, | 1315 PRFileDesc* socket, |
| 1307 CERTDistNames* ca_names, | 1316 CERTDistNames* ca_names, |
| 1308 CERTCertList** result_certs, | 1317 CERTCertList** result_certs, |
| 1309 void** result_private_key, | 1318 void** result_private_key, |
| 1310 CERTCertificate** result_nss_certificate, | 1319 CERTCertificate** result_nss_certificate, |
| 1311 SECKEYPrivateKey** result_nss_private_key) { | 1320 SECKEYPrivateKey** result_nss_private_key) { |
| 1312 Core* core = reinterpret_cast<Core*>(arg); | 1321 Core* core = reinterpret_cast<Core*>(arg); |
| 1313 DCHECK(core->OnNSSTaskRunner()); | 1322 DCHECK(core->OnNSSTaskRunner()); |
| 1314 | 1323 |
| 1315 core->PostOrRunCallback( | 1324 core->PostOrRunCallback(FROM_HERE, |
| 1316 FROM_HERE, | 1325 base::Bind(&AddLogEvent, |
| 1317 base::Bind(&AddLogEvent, core->weak_net_log_, | 1326 core->weak_net_log_, |
| 1318 NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED)); | 1327 NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED)); |
| 1319 | 1328 |
| 1320 core->client_auth_cert_needed_ = !core->ssl_config_.send_client_cert; | 1329 core->client_auth_cert_needed_ = !core->ssl_config_.send_client_cert; |
| 1321 #if defined(OS_WIN) | 1330 #if defined(OS_WIN) |
| 1322 if (core->ssl_config_.send_client_cert) { | 1331 if (core->ssl_config_.send_client_cert) { |
| 1323 if (core->ssl_config_.client_cert) { | 1332 if (core->ssl_config_.client_cert) { |
| 1324 PCCERT_CONTEXT cert_context = | 1333 PCCERT_CONTEXT cert_context = |
| 1325 core->ssl_config_.client_cert->os_cert_handle(); | 1334 core->ssl_config_.client_cert->os_cert_handle(); |
| 1326 | 1335 |
| 1327 HCRYPTPROV_OR_NCRYPT_KEY_HANDLE crypt_prov = 0; | 1336 HCRYPTPROV_OR_NCRYPT_KEY_HANDLE crypt_prov = 0; |
| 1328 DWORD key_spec = 0; | 1337 DWORD key_spec = 0; |
| 1329 BOOL must_free = FALSE; | 1338 BOOL must_free = FALSE; |
| 1330 DWORD flags = 0; | 1339 DWORD flags = 0; |
| 1331 if (base::win::GetVersion() >= base::win::VERSION_VISTA) | 1340 if (base::win::GetVersion() >= base::win::VERSION_VISTA) |
| 1332 flags |= CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG; | 1341 flags |= CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG; |
| 1333 | 1342 |
| 1334 BOOL acquired_key = CryptAcquireCertificatePrivateKey( | 1343 BOOL acquired_key = CryptAcquireCertificatePrivateKey( |
| 1335 cert_context, flags, NULL, &crypt_prov, &key_spec, &must_free); | 1344 cert_context, flags, NULL, &crypt_prov, &key_spec, &must_free); |
| 1336 | 1345 |
| 1337 if (acquired_key) { | 1346 if (acquired_key) { |
| 1338 // Should never get a cached handle back - ownership must always be | 1347 // Should never get a cached handle back - ownership must always be |
| 1339 // transferred. | 1348 // transferred. |
| 1340 CHECK_EQ(must_free, TRUE); | 1349 CHECK_EQ(must_free, TRUE); |
| 1341 | 1350 |
| 1342 SECItem der_cert; | 1351 SECItem der_cert; |
| 1343 der_cert.type = siDERCertBuffer; | 1352 der_cert.type = siDERCertBuffer; |
| 1344 der_cert.data = cert_context->pbCertEncoded; | 1353 der_cert.data = cert_context->pbCertEncoded; |
| 1345 der_cert.len = cert_context->cbCertEncoded; | 1354 der_cert.len = cert_context->cbCertEncoded; |
| 1346 | 1355 |
| 1347 // TODO(rsleevi): Error checking for NSS allocation errors. | 1356 // TODO(rsleevi): Error checking for NSS allocation errors. |
| 1348 CERTCertDBHandle* db_handle = CERT_GetDefaultCertDB(); | 1357 CERTCertDBHandle* db_handle = CERT_GetDefaultCertDB(); |
| 1349 CERTCertificate* user_cert = CERT_NewTempCertificate( | 1358 CERTCertificate* user_cert = CERT_NewTempCertificate( |
| 1350 db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE); | 1359 db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE); |
| 1351 if (!user_cert) { | 1360 if (!user_cert) { |
| 1352 // Importing the certificate can fail for reasons including a serial | 1361 // Importing the certificate can fail for reasons including a serial |
| 1353 // number collision. See crbug.com/97355. | 1362 // number collision. See crbug.com/97355. |
| 1354 core->AddCertProvidedEvent(0); | 1363 core->AddCertProvidedEvent(0); |
| 1355 return SECFailure; | 1364 return SECFailure; |
| 1356 } | 1365 } |
| 1357 CERTCertList* cert_chain = CERT_NewCertList(); | 1366 CERTCertList* cert_chain = CERT_NewCertList(); |
| 1358 CERT_AddCertToListTail(cert_chain, user_cert); | 1367 CERT_AddCertToListTail(cert_chain, user_cert); |
| 1359 | 1368 |
| 1360 // Add the intermediates. | 1369 // Add the intermediates. |
| 1361 X509Certificate::OSCertHandles intermediates = | 1370 X509Certificate::OSCertHandles intermediates = |
| 1362 core->ssl_config_.client_cert->GetIntermediateCertificates(); | 1371 core->ssl_config_.client_cert->GetIntermediateCertificates(); |
| 1363 for (X509Certificate::OSCertHandles::const_iterator it = | 1372 for (X509Certificate::OSCertHandles::const_iterator it = |
| 1364 intermediates.begin(); it != intermediates.end(); ++it) { | 1373 intermediates.begin(); |
| 1374 it != intermediates.end(); |
| 1375 ++it) { |
| 1365 der_cert.data = (*it)->pbCertEncoded; | 1376 der_cert.data = (*it)->pbCertEncoded; |
| 1366 der_cert.len = (*it)->cbCertEncoded; | 1377 der_cert.len = (*it)->cbCertEncoded; |
| 1367 | 1378 |
| 1368 CERTCertificate* intermediate = CERT_NewTempCertificate( | 1379 CERTCertificate* intermediate = CERT_NewTempCertificate( |
| 1369 db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE); | 1380 db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE); |
| 1370 if (!intermediate) { | 1381 if (!intermediate) { |
| 1371 CERT_DestroyCertList(cert_chain); | 1382 CERT_DestroyCertList(cert_chain); |
| 1372 core->AddCertProvidedEvent(0); | 1383 core->AddCertProvidedEvent(0); |
| 1373 return SECFailure; | 1384 return SECFailure; |
| 1374 } | 1385 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1394 core->AddCertProvidedEvent(0); | 1405 core->AddCertProvidedEvent(0); |
| 1395 return SECFailure; | 1406 return SECFailure; |
| 1396 } | 1407 } |
| 1397 | 1408 |
| 1398 core->nss_handshake_state_.cert_authorities.clear(); | 1409 core->nss_handshake_state_.cert_authorities.clear(); |
| 1399 | 1410 |
| 1400 std::vector<CERT_NAME_BLOB> issuer_list(ca_names->nnames); | 1411 std::vector<CERT_NAME_BLOB> issuer_list(ca_names->nnames); |
| 1401 for (int i = 0; i < ca_names->nnames; ++i) { | 1412 for (int i = 0; i < ca_names->nnames; ++i) { |
| 1402 issuer_list[i].cbData = ca_names->names[i].len; | 1413 issuer_list[i].cbData = ca_names->names[i].len; |
| 1403 issuer_list[i].pbData = ca_names->names[i].data; | 1414 issuer_list[i].pbData = ca_names->names[i].data; |
| 1404 core->nss_handshake_state_.cert_authorities.push_back(std::string( | 1415 core->nss_handshake_state_.cert_authorities.push_back( |
| 1405 reinterpret_cast<const char*>(ca_names->names[i].data), | 1416 std::string(reinterpret_cast<const char*>(ca_names->names[i].data), |
| 1406 static_cast<size_t>(ca_names->names[i].len))); | 1417 static_cast<size_t>(ca_names->names[i].len))); |
| 1407 } | 1418 } |
| 1408 | 1419 |
| 1409 // Update the network task runner's view of the handshake state now that | 1420 // Update the network task runner's view of the handshake state now that |
| 1410 // server certificate request has been recorded. | 1421 // server certificate request has been recorded. |
| 1411 core->PostOrRunCallback( | 1422 core->PostOrRunCallback( |
| 1412 FROM_HERE, base::Bind(&Core::OnHandshakeStateUpdated, core, | 1423 FROM_HERE, |
| 1413 core->nss_handshake_state_)); | 1424 base::Bind( |
| 1425 &Core::OnHandshakeStateUpdated, core, core->nss_handshake_state_)); |
| 1414 | 1426 |
| 1415 // Tell NSS to suspend the client authentication. We will then abort the | 1427 // Tell NSS to suspend the client authentication. We will then abort the |
| 1416 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED. | 1428 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED. |
| 1417 return SECWouldBlock; | 1429 return SECWouldBlock; |
| 1418 #elif defined(OS_MACOSX) | 1430 #elif defined(OS_MACOSX) |
| 1419 if (core->ssl_config_.send_client_cert) { | 1431 if (core->ssl_config_.send_client_cert) { |
| 1420 if (core->ssl_config_.client_cert.get()) { | 1432 if (core->ssl_config_.client_cert.get()) { |
| 1421 OSStatus os_error = noErr; | 1433 OSStatus os_error = noErr; |
| 1422 SecIdentityRef identity = NULL; | 1434 SecIdentityRef identity = NULL; |
| 1423 SecKeyRef private_key = NULL; | 1435 SecKeyRef private_key = NULL; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1487 core->AddCertProvidedEvent(0); | 1499 core->AddCertProvidedEvent(0); |
| 1488 return SECFailure; | 1500 return SECFailure; |
| 1489 } | 1501 } |
| 1490 | 1502 |
| 1491 core->nss_handshake_state_.cert_authorities.clear(); | 1503 core->nss_handshake_state_.cert_authorities.clear(); |
| 1492 | 1504 |
| 1493 // Retrieve the cert issuers accepted by the server. | 1505 // Retrieve the cert issuers accepted by the server. |
| 1494 std::vector<CertPrincipal> valid_issuers; | 1506 std::vector<CertPrincipal> valid_issuers; |
| 1495 int n = ca_names->nnames; | 1507 int n = ca_names->nnames; |
| 1496 for (int i = 0; i < n; i++) { | 1508 for (int i = 0; i < n; i++) { |
| 1497 core->nss_handshake_state_.cert_authorities.push_back(std::string( | 1509 core->nss_handshake_state_.cert_authorities.push_back( |
| 1498 reinterpret_cast<const char*>(ca_names->names[i].data), | 1510 std::string(reinterpret_cast<const char*>(ca_names->names[i].data), |
| 1499 static_cast<size_t>(ca_names->names[i].len))); | 1511 static_cast<size_t>(ca_names->names[i].len))); |
| 1500 } | 1512 } |
| 1501 | 1513 |
| 1502 // Update the network task runner's view of the handshake state now that | 1514 // Update the network task runner's view of the handshake state now that |
| 1503 // server certificate request has been recorded. | 1515 // server certificate request has been recorded. |
| 1504 core->PostOrRunCallback( | 1516 core->PostOrRunCallback( |
| 1505 FROM_HERE, base::Bind(&Core::OnHandshakeStateUpdated, core, | 1517 FROM_HERE, |
| 1506 core->nss_handshake_state_)); | 1518 base::Bind( |
| 1519 &Core::OnHandshakeStateUpdated, core, core->nss_handshake_state_)); |
| 1507 | 1520 |
| 1508 // Tell NSS to suspend the client authentication. We will then abort the | 1521 // Tell NSS to suspend the client authentication. We will then abort the |
| 1509 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED. | 1522 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED. |
| 1510 return SECWouldBlock; | 1523 return SECWouldBlock; |
| 1511 #else | 1524 #else |
| 1512 return SECFailure; | 1525 return SECFailure; |
| 1513 #endif | 1526 #endif |
| 1514 } | 1527 } |
| 1515 | 1528 |
| 1516 #elif defined(OS_IOS) | 1529 #elif defined(OS_IOS) |
| 1517 | 1530 |
| 1518 SECStatus SSLClientSocketNSS::Core::ClientAuthHandler( | 1531 SECStatus SSLClientSocketNSS::Core::ClientAuthHandler( |
| 1519 void* arg, | 1532 void* arg, |
| 1520 PRFileDesc* socket, | 1533 PRFileDesc* socket, |
| 1521 CERTDistNames* ca_names, | 1534 CERTDistNames* ca_names, |
| 1522 CERTCertificate** result_certificate, | 1535 CERTCertificate** result_certificate, |
| 1523 SECKEYPrivateKey** result_private_key) { | 1536 SECKEYPrivateKey** result_private_key) { |
| 1524 Core* core = reinterpret_cast<Core*>(arg); | 1537 Core* core = reinterpret_cast<Core*>(arg); |
| 1525 DCHECK(core->OnNSSTaskRunner()); | 1538 DCHECK(core->OnNSSTaskRunner()); |
| 1526 | 1539 |
| 1527 core->PostOrRunCallback( | 1540 core->PostOrRunCallback(FROM_HERE, |
| 1528 FROM_HERE, | 1541 base::Bind(&AddLogEvent, |
| 1529 base::Bind(&AddLogEvent, core->weak_net_log_, | 1542 core->weak_net_log_, |
| 1530 NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED)); | 1543 NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED)); |
| 1531 | 1544 |
| 1532 // TODO(droger): Support client auth on iOS. See http://crbug.com/145954). | 1545 // TODO(droger): Support client auth on iOS. See http://crbug.com/145954). |
| 1533 LOG(WARNING) << "Client auth is not supported"; | 1546 LOG(WARNING) << "Client auth is not supported"; |
| 1534 | 1547 |
| 1535 // Never send a certificate. | 1548 // Never send a certificate. |
| 1536 core->AddCertProvidedEvent(0); | 1549 core->AddCertProvidedEvent(0); |
| 1537 return SECFailure; | 1550 return SECFailure; |
| 1538 } | 1551 } |
| 1539 | 1552 |
| 1540 #else // NSS_PLATFORM_CLIENT_AUTH | 1553 #else // NSS_PLATFORM_CLIENT_AUTH |
| 1541 | 1554 |
| 1542 // static | 1555 // static |
| 1543 // Based on Mozilla's NSS_GetClientAuthData. | 1556 // Based on Mozilla's NSS_GetClientAuthData. |
| 1544 SECStatus SSLClientSocketNSS::Core::ClientAuthHandler( | 1557 SECStatus SSLClientSocketNSS::Core::ClientAuthHandler( |
| 1545 void* arg, | 1558 void* arg, |
| 1546 PRFileDesc* socket, | 1559 PRFileDesc* socket, |
| 1547 CERTDistNames* ca_names, | 1560 CERTDistNames* ca_names, |
| 1548 CERTCertificate** result_certificate, | 1561 CERTCertificate** result_certificate, |
| 1549 SECKEYPrivateKey** result_private_key) { | 1562 SECKEYPrivateKey** result_private_key) { |
| 1550 Core* core = reinterpret_cast<Core*>(arg); | 1563 Core* core = reinterpret_cast<Core*>(arg); |
| 1551 DCHECK(core->OnNSSTaskRunner()); | 1564 DCHECK(core->OnNSSTaskRunner()); |
| 1552 | 1565 |
| 1553 core->PostOrRunCallback( | 1566 core->PostOrRunCallback(FROM_HERE, |
| 1554 FROM_HERE, | 1567 base::Bind(&AddLogEvent, |
| 1555 base::Bind(&AddLogEvent, core->weak_net_log_, | 1568 core->weak_net_log_, |
| 1556 NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED)); | 1569 NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED)); |
| 1557 | 1570 |
| 1558 // Regular client certificate requested. | 1571 // Regular client certificate requested. |
| 1559 core->client_auth_cert_needed_ = !core->ssl_config_.send_client_cert; | 1572 core->client_auth_cert_needed_ = !core->ssl_config_.send_client_cert; |
| 1560 void* wincx = SSL_RevealPinArg(socket); | 1573 void* wincx = SSL_RevealPinArg(socket); |
| 1561 | 1574 |
| 1562 if (core->ssl_config_.send_client_cert) { | 1575 if (core->ssl_config_.send_client_cert) { |
| 1563 // Second pass: a client certificate should have been selected. | 1576 // Second pass: a client certificate should have been selected. |
| 1564 if (core->ssl_config_.client_cert.get()) { | 1577 if (core->ssl_config_.client_cert.get()) { |
| 1565 CERTCertificate* cert = | 1578 CERTCertificate* cert = |
| 1566 CERT_DupCertificate(core->ssl_config_.client_cert->os_cert_handle()); | 1579 CERT_DupCertificate(core->ssl_config_.client_cert->os_cert_handle()); |
| 1567 SECKEYPrivateKey* privkey = PK11_FindKeyByAnyCert(cert, wincx); | 1580 SECKEYPrivateKey* privkey = PK11_FindKeyByAnyCert(cert, wincx); |
| 1568 if (privkey) { | 1581 if (privkey) { |
| 1569 // TODO(jsorianopastor): We should wait for server certificate | 1582 // TODO(jsorianopastor): We should wait for server certificate |
| 1570 // verification before sending our credentials. See | 1583 // verification before sending our credentials. See |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1583 core->AddCertProvidedEvent(0); | 1596 core->AddCertProvidedEvent(0); |
| 1584 return SECFailure; | 1597 return SECFailure; |
| 1585 } | 1598 } |
| 1586 | 1599 |
| 1587 // First pass: client certificate is needed. | 1600 // First pass: client certificate is needed. |
| 1588 core->nss_handshake_state_.cert_authorities.clear(); | 1601 core->nss_handshake_state_.cert_authorities.clear(); |
| 1589 | 1602 |
| 1590 // Retrieve the DER-encoded DistinguishedName of the cert issuers accepted by | 1603 // Retrieve the DER-encoded DistinguishedName of the cert issuers accepted by |
| 1591 // the server and save them in |cert_authorities|. | 1604 // the server and save them in |cert_authorities|. |
| 1592 for (int i = 0; i < ca_names->nnames; i++) { | 1605 for (int i = 0; i < ca_names->nnames; i++) { |
| 1593 core->nss_handshake_state_.cert_authorities.push_back(std::string( | 1606 core->nss_handshake_state_.cert_authorities.push_back( |
| 1594 reinterpret_cast<const char*>(ca_names->names[i].data), | 1607 std::string(reinterpret_cast<const char*>(ca_names->names[i].data), |
| 1595 static_cast<size_t>(ca_names->names[i].len))); | 1608 static_cast<size_t>(ca_names->names[i].len))); |
| 1596 } | 1609 } |
| 1597 | 1610 |
| 1598 // Update the network task runner's view of the handshake state now that | 1611 // Update the network task runner's view of the handshake state now that |
| 1599 // server certificate request has been recorded. | 1612 // server certificate request has been recorded. |
| 1600 core->PostOrRunCallback( | 1613 core->PostOrRunCallback( |
| 1601 FROM_HERE, base::Bind(&Core::OnHandshakeStateUpdated, core, | 1614 FROM_HERE, |
| 1602 core->nss_handshake_state_)); | 1615 base::Bind( |
| 1616 &Core::OnHandshakeStateUpdated, core, core->nss_handshake_state_)); |
| 1603 | 1617 |
| 1604 // Tell NSS to suspend the client authentication. We will then abort the | 1618 // Tell NSS to suspend the client authentication. We will then abort the |
| 1605 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED. | 1619 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED. |
| 1606 return SECWouldBlock; | 1620 return SECWouldBlock; |
| 1607 } | 1621 } |
| 1608 #endif // NSS_PLATFORM_CLIENT_AUTH | 1622 #endif // NSS_PLATFORM_CLIENT_AUTH |
| 1609 | 1623 |
| 1610 // static | 1624 // static |
| 1611 SECStatus SSLClientSocketNSS::Core::CanFalseStartCallback( | 1625 SECStatus SSLClientSocketNSS::Core::CanFalseStartCallback( |
| 1612 PRFileDesc* socket, | 1626 PRFileDesc* socket, |
| 1613 void* arg, | 1627 void* arg, |
| 1614 PRBool* can_false_start) { | 1628 PRBool* can_false_start) { |
| 1615 // If the server doesn't support NPN or ALPN, then we don't do False | 1629 // If the server doesn't support NPN or ALPN, then we don't do False |
| 1616 // Start with it. | 1630 // Start with it. |
| 1617 PRBool negotiated_extension; | 1631 PRBool negotiated_extension; |
| 1618 SECStatus rv = SSL_HandshakeNegotiatedExtension(socket, | 1632 SECStatus rv = SSL_HandshakeNegotiatedExtension( |
| 1619 ssl_app_layer_protocol_xtn, | 1633 socket, ssl_app_layer_protocol_xtn, &negotiated_extension); |
| 1620 &negotiated_extension); | |
| 1621 if (rv != SECSuccess || !negotiated_extension) { | 1634 if (rv != SECSuccess || !negotiated_extension) { |
| 1622 rv = SSL_HandshakeNegotiatedExtension(socket, | 1635 rv = SSL_HandshakeNegotiatedExtension( |
| 1623 ssl_next_proto_nego_xtn, | 1636 socket, ssl_next_proto_nego_xtn, &negotiated_extension); |
| 1624 &negotiated_extension); | |
| 1625 } | 1637 } |
| 1626 if (rv != SECSuccess || !negotiated_extension) { | 1638 if (rv != SECSuccess || !negotiated_extension) { |
| 1627 *can_false_start = PR_FALSE; | 1639 *can_false_start = PR_FALSE; |
| 1628 return SECSuccess; | 1640 return SECSuccess; |
| 1629 } | 1641 } |
| 1630 | 1642 |
| 1631 return SSL_RecommendedCanFalseStart(socket, can_false_start); | 1643 return SSL_RecommendedCanFalseStart(socket, can_false_start); |
| 1632 } | 1644 } |
| 1633 | 1645 |
| 1634 // static | 1646 // static |
| 1635 void SSLClientSocketNSS::Core::HandshakeCallback( | 1647 void SSLClientSocketNSS::Core::HandshakeCallback(PRFileDesc* socket, |
| 1636 PRFileDesc* socket, | 1648 void* arg) { |
| 1637 void* arg) { | |
| 1638 Core* core = reinterpret_cast<Core*>(arg); | 1649 Core* core = reinterpret_cast<Core*>(arg); |
| 1639 DCHECK(core->OnNSSTaskRunner()); | 1650 DCHECK(core->OnNSSTaskRunner()); |
| 1640 | 1651 |
| 1641 core->handshake_callback_called_ = true; | 1652 core->handshake_callback_called_ = true; |
| 1642 if (core->false_started_) { | 1653 if (core->false_started_) { |
| 1643 core->false_started_ = false; | 1654 core->false_started_ = false; |
| 1644 // If the connection was False Started, then at the time of this callback, | 1655 // If the connection was False Started, then at the time of this callback, |
| 1645 // the peer's certificate will have been verified or the caller will have | 1656 // the peer's certificate will have been verified or the caller will have |
| 1646 // accepted the error. | 1657 // accepted the error. |
| 1647 // This is guaranteed when using False Start because this callback will | 1658 // This is guaranteed when using False Start because this callback will |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1671 RecordChannelIDSupportOnNSSTaskRunner(); | 1682 RecordChannelIDSupportOnNSSTaskRunner(); |
| 1672 UpdateServerCert(); | 1683 UpdateServerCert(); |
| 1673 UpdateSignedCertTimestamps(); | 1684 UpdateSignedCertTimestamps(); |
| 1674 UpdateStapledOCSPResponse(); | 1685 UpdateStapledOCSPResponse(); |
| 1675 UpdateConnectionStatus(); | 1686 UpdateConnectionStatus(); |
| 1676 UpdateNextProto(); | 1687 UpdateNextProto(); |
| 1677 | 1688 |
| 1678 // Update the network task runners view of the handshake state whenever | 1689 // Update the network task runners view of the handshake state whenever |
| 1679 // a handshake has completed. | 1690 // a handshake has completed. |
| 1680 PostOrRunCallback( | 1691 PostOrRunCallback( |
| 1681 FROM_HERE, base::Bind(&Core::OnHandshakeStateUpdated, this, | 1692 FROM_HERE, |
| 1682 nss_handshake_state_)); | 1693 base::Bind(&Core::OnHandshakeStateUpdated, this, nss_handshake_state_)); |
| 1683 } | 1694 } |
| 1684 | 1695 |
| 1685 int SSLClientSocketNSS::Core::HandleNSSError(PRErrorCode nss_error, | 1696 int SSLClientSocketNSS::Core::HandleNSSError(PRErrorCode nss_error, |
| 1686 bool handshake_error) { | 1697 bool handshake_error) { |
| 1687 DCHECK(OnNSSTaskRunner()); | 1698 DCHECK(OnNSSTaskRunner()); |
| 1688 | 1699 |
| 1689 int net_error = handshake_error ? MapNSSClientHandshakeError(nss_error) : | 1700 int net_error = handshake_error ? MapNSSClientHandshakeError(nss_error) |
| 1690 MapNSSClientError(nss_error); | 1701 : MapNSSClientError(nss_error); |
| 1691 | 1702 |
| 1692 #if defined(OS_WIN) | 1703 #if defined(OS_WIN) |
| 1693 // On Windows, a handle to the HCRYPTPROV is cached in the X509Certificate | 1704 // On Windows, a handle to the HCRYPTPROV is cached in the X509Certificate |
| 1694 // os_cert_handle() as an optimization. However, if the certificate | 1705 // os_cert_handle() as an optimization. However, if the certificate |
| 1695 // private key is stored on a smart card, and the smart card is removed, | 1706 // private key is stored on a smart card, and the smart card is removed, |
| 1696 // the cached HCRYPTPROV will not be able to obtain the HCRYPTKEY again, | 1707 // the cached HCRYPTPROV will not be able to obtain the HCRYPTKEY again, |
| 1697 // preventing client certificate authentication. Because the | 1708 // preventing client certificate authentication. Because the |
| 1698 // X509Certificate may outlive the individual SSLClientSocketNSS, due to | 1709 // X509Certificate may outlive the individual SSLClientSocketNSS, due to |
| 1699 // caching in X509Certificate, this failure ends up preventing client | 1710 // caching in X509Certificate, this failure ends up preventing client |
| 1700 // certificate authentication with the same certificate for all future | 1711 // certificate authentication with the same certificate for all future |
| 1701 // attempts, even after the smart card has been re-inserted. By setting | 1712 // attempts, even after the smart card has been re-inserted. By setting |
| 1702 // the CERT_KEY_PROV_HANDLE_PROP_ID to NULL, the cached HCRYPTPROV will | 1713 // the CERT_KEY_PROV_HANDLE_PROP_ID to NULL, the cached HCRYPTPROV will |
| 1703 // typically be freed. This allows a new HCRYPTPROV to be obtained from | 1714 // typically be freed. This allows a new HCRYPTPROV to be obtained from |
| 1704 // the certificate on the next attempt, which should succeed if the smart | 1715 // the certificate on the next attempt, which should succeed if the smart |
| 1705 // card has been re-inserted, or will typically prompt the user to | 1716 // card has been re-inserted, or will typically prompt the user to |
| 1706 // re-insert the smart card if not. | 1717 // re-insert the smart card if not. |
| 1707 if ((net_error == ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY || | 1718 if ((net_error == ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY || |
| 1708 net_error == ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED) && | 1719 net_error == ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED) && |
| 1709 ssl_config_.send_client_cert && ssl_config_.client_cert) { | 1720 ssl_config_.send_client_cert && ssl_config_.client_cert) { |
| 1710 CertSetCertificateContextProperty( | 1721 CertSetCertificateContextProperty(ssl_config_.client_cert->os_cert_handle(), |
| 1711 ssl_config_.client_cert->os_cert_handle(), | 1722 CERT_KEY_PROV_HANDLE_PROP_ID, |
| 1712 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL); | 1723 0, |
| 1724 NULL); |
| 1713 } | 1725 } |
| 1714 #endif | 1726 #endif |
| 1715 | 1727 |
| 1716 return net_error; | 1728 return net_error; |
| 1717 } | 1729 } |
| 1718 | 1730 |
| 1719 int SSLClientSocketNSS::Core::DoHandshakeLoop(int last_io_result) { | 1731 int SSLClientSocketNSS::Core::DoHandshakeLoop(int last_io_result) { |
| 1720 DCHECK(OnNSSTaskRunner()); | 1732 DCHECK(OnNSSTaskRunner()); |
| 1721 | 1733 |
| 1722 int rv = last_io_result; | 1734 int rv = last_io_result; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1756 DCHECK(OnNSSTaskRunner()); | 1768 DCHECK(OnNSSTaskRunner()); |
| 1757 DCHECK(false_started_ || handshake_callback_called_); | 1769 DCHECK(false_started_ || handshake_callback_called_); |
| 1758 DCHECK_EQ(STATE_NONE, next_handshake_state_); | 1770 DCHECK_EQ(STATE_NONE, next_handshake_state_); |
| 1759 | 1771 |
| 1760 if (result < 0) | 1772 if (result < 0) |
| 1761 return result; | 1773 return result; |
| 1762 | 1774 |
| 1763 if (!nss_bufs_) { | 1775 if (!nss_bufs_) { |
| 1764 LOG(DFATAL) << "!nss_bufs_"; | 1776 LOG(DFATAL) << "!nss_bufs_"; |
| 1765 int rv = ERR_UNEXPECTED; | 1777 int rv = ERR_UNEXPECTED; |
| 1766 PostOrRunCallback( | 1778 PostOrRunCallback(FROM_HERE, |
| 1767 FROM_HERE, | 1779 base::Bind(&AddLogEventWithCallback, |
| 1768 base::Bind(&AddLogEventWithCallback, weak_net_log_, | 1780 weak_net_log_, |
| 1769 NetLog::TYPE_SSL_READ_ERROR, | 1781 NetLog::TYPE_SSL_READ_ERROR, |
| 1770 CreateNetLogSSLErrorCallback(rv, 0))); | 1782 CreateNetLogSSLErrorCallback(rv, 0))); |
| 1771 return rv; | 1783 return rv; |
| 1772 } | 1784 } |
| 1773 | 1785 |
| 1774 bool network_moved; | 1786 bool network_moved; |
| 1775 int rv; | 1787 int rv; |
| 1776 do { | 1788 do { |
| 1777 rv = DoPayloadRead(); | 1789 rv = DoPayloadRead(); |
| 1778 network_moved = DoTransportIO(); | 1790 network_moved = DoTransportIO(); |
| 1779 } while (rv == ERR_IO_PENDING && network_moved); | 1791 } while (rv == ERR_IO_PENDING && network_moved); |
| 1780 | 1792 |
| 1781 return rv; | 1793 return rv; |
| 1782 } | 1794 } |
| 1783 | 1795 |
| 1784 int SSLClientSocketNSS::Core::DoWriteLoop(int result) { | 1796 int SSLClientSocketNSS::Core::DoWriteLoop(int result) { |
| 1785 DCHECK(OnNSSTaskRunner()); | 1797 DCHECK(OnNSSTaskRunner()); |
| 1786 DCHECK(false_started_ || handshake_callback_called_); | 1798 DCHECK(false_started_ || handshake_callback_called_); |
| 1787 DCHECK_EQ(STATE_NONE, next_handshake_state_); | 1799 DCHECK_EQ(STATE_NONE, next_handshake_state_); |
| 1788 | 1800 |
| 1789 if (result < 0) | 1801 if (result < 0) |
| 1790 return result; | 1802 return result; |
| 1791 | 1803 |
| 1792 if (!nss_bufs_) { | 1804 if (!nss_bufs_) { |
| 1793 LOG(DFATAL) << "!nss_bufs_"; | 1805 LOG(DFATAL) << "!nss_bufs_"; |
| 1794 int rv = ERR_UNEXPECTED; | 1806 int rv = ERR_UNEXPECTED; |
| 1795 PostOrRunCallback( | 1807 PostOrRunCallback(FROM_HERE, |
| 1796 FROM_HERE, | 1808 base::Bind(&AddLogEventWithCallback, |
| 1797 base::Bind(&AddLogEventWithCallback, weak_net_log_, | 1809 weak_net_log_, |
| 1798 NetLog::TYPE_SSL_READ_ERROR, | 1810 NetLog::TYPE_SSL_READ_ERROR, |
| 1799 CreateNetLogSSLErrorCallback(rv, 0))); | 1811 CreateNetLogSSLErrorCallback(rv, 0))); |
| 1800 return rv; | 1812 return rv; |
| 1801 } | 1813 } |
| 1802 | 1814 |
| 1803 bool network_moved; | 1815 bool network_moved; |
| 1804 int rv; | 1816 int rv; |
| 1805 do { | 1817 do { |
| 1806 rv = DoPayloadWrite(); | 1818 rv = DoPayloadWrite(); |
| 1807 network_moved = DoTransportIO(); | 1819 network_moved = DoTransportIO(); |
| 1808 } while (rv == ERR_IO_PENDING && network_moved); | 1820 } while (rv == ERR_IO_PENDING && network_moved); |
| 1809 | 1821 |
| 1810 LeaveFunction(rv); | 1822 LeaveFunction(rv); |
| 1811 return rv; | 1823 return rv; |
| 1812 } | 1824 } |
| 1813 | 1825 |
| 1814 int SSLClientSocketNSS::Core::DoHandshake() { | 1826 int SSLClientSocketNSS::Core::DoHandshake() { |
| 1815 DCHECK(OnNSSTaskRunner()); | 1827 DCHECK(OnNSSTaskRunner()); |
| 1816 | 1828 |
| 1817 int net_error = net::OK; | 1829 int net_error = net::OK; |
| 1818 SECStatus rv = SSL_ForceHandshake(nss_fd_); | 1830 SECStatus rv = SSL_ForceHandshake(nss_fd_); |
| 1819 | 1831 |
| 1820 // Note: this function may be called multiple times during the handshake, so | 1832 // Note: this function may be called multiple times during the handshake, so |
| 1821 // even though channel id and client auth are separate else cases, they can | 1833 // even though channel id and client auth are separate else cases, they can |
| 1822 // both be used during a single SSL handshake. | 1834 // both be used during a single SSL handshake. |
| 1823 if (channel_id_needed_) { | 1835 if (channel_id_needed_) { |
| 1824 GotoState(STATE_GET_DOMAIN_BOUND_CERT_COMPLETE); | 1836 GotoState(STATE_GET_DOMAIN_BOUND_CERT_COMPLETE); |
| 1825 net_error = ERR_IO_PENDING; | 1837 net_error = ERR_IO_PENDING; |
| 1826 } else if (client_auth_cert_needed_) { | 1838 } else if (client_auth_cert_needed_) { |
| 1827 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; | 1839 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; |
| 1828 PostOrRunCallback( | 1840 PostOrRunCallback(FROM_HERE, |
| 1829 FROM_HERE, | 1841 base::Bind(&AddLogEventWithCallback, |
| 1830 base::Bind(&AddLogEventWithCallback, weak_net_log_, | 1842 weak_net_log_, |
| 1831 NetLog::TYPE_SSL_HANDSHAKE_ERROR, | 1843 NetLog::TYPE_SSL_HANDSHAKE_ERROR, |
| 1832 CreateNetLogSSLErrorCallback(net_error, 0))); | 1844 CreateNetLogSSLErrorCallback(net_error, 0))); |
| 1833 | 1845 |
| 1834 // If the handshake already succeeded (because the server requests but | 1846 // If the handshake already succeeded (because the server requests but |
| 1835 // doesn't require a client cert), we need to invalidate the SSL session | 1847 // doesn't require a client cert), we need to invalidate the SSL session |
| 1836 // so that we won't try to resume the non-client-authenticated session in | 1848 // so that we won't try to resume the non-client-authenticated session in |
| 1837 // the next handshake. This will cause the server to ask for a client | 1849 // the next handshake. This will cause the server to ask for a client |
| 1838 // cert again. | 1850 // cert again. |
| 1839 if (rv == SECSuccess && SSL_InvalidateSession(nss_fd_) != SECSuccess) | 1851 if (rv == SECSuccess && SSL_InvalidateSession(nss_fd_) != SECSuccess) |
| 1840 LOG(WARNING) << "Couldn't invalidate SSL session: " << PR_GetError(); | 1852 LOG(WARNING) << "Couldn't invalidate SSL session: " << PR_GetError(); |
| 1841 } else if (rv == SECSuccess) { | 1853 } else if (rv == SECSuccess) { |
| 1842 if (!handshake_callback_called_) { | 1854 if (!handshake_callback_called_) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1863 ssl_config_.version_max >= SSL_PROTOCOL_VERSION_TLS1_1) { | 1875 ssl_config_.version_max >= SSL_PROTOCOL_VERSION_TLS1_1) { |
| 1864 net_error = ERR_SSL_PROTOCOL_ERROR; | 1876 net_error = ERR_SSL_PROTOCOL_ERROR; |
| 1865 } | 1877 } |
| 1866 | 1878 |
| 1867 // If not done, stay in this state | 1879 // If not done, stay in this state |
| 1868 if (net_error == ERR_IO_PENDING) { | 1880 if (net_error == ERR_IO_PENDING) { |
| 1869 GotoState(STATE_HANDSHAKE); | 1881 GotoState(STATE_HANDSHAKE); |
| 1870 } else { | 1882 } else { |
| 1871 PostOrRunCallback( | 1883 PostOrRunCallback( |
| 1872 FROM_HERE, | 1884 FROM_HERE, |
| 1873 base::Bind(&AddLogEventWithCallback, weak_net_log_, | 1885 base::Bind(&AddLogEventWithCallback, |
| 1886 weak_net_log_, |
| 1874 NetLog::TYPE_SSL_HANDSHAKE_ERROR, | 1887 NetLog::TYPE_SSL_HANDSHAKE_ERROR, |
| 1875 CreateNetLogSSLErrorCallback(net_error, prerr))); | 1888 CreateNetLogSSLErrorCallback(net_error, prerr))); |
| 1876 } | 1889 } |
| 1877 } | 1890 } |
| 1878 | 1891 |
| 1879 return net_error; | 1892 return net_error; |
| 1880 } | 1893 } |
| 1881 | 1894 |
| 1882 int SSLClientSocketNSS::Core::DoGetDBCertComplete(int result) { | 1895 int SSLClientSocketNSS::Core::DoGetDBCertComplete(int result) { |
| 1883 SECStatus rv; | 1896 SECStatus rv; |
| 1884 PostOrRunCallback( | 1897 PostOrRunCallback(FROM_HERE, |
| 1885 FROM_HERE, | 1898 base::Bind(&BoundNetLog::EndEventWithNetErrorCode, |
| 1886 base::Bind(&BoundNetLog::EndEventWithNetErrorCode, weak_net_log_, | 1899 weak_net_log_, |
| 1887 NetLog::TYPE_SSL_GET_DOMAIN_BOUND_CERT, result)); | 1900 NetLog::TYPE_SSL_GET_DOMAIN_BOUND_CERT, |
| 1901 result)); |
| 1888 | 1902 |
| 1889 channel_id_needed_ = false; | 1903 channel_id_needed_ = false; |
| 1890 | 1904 |
| 1891 if (result != OK) | 1905 if (result != OK) |
| 1892 return result; | 1906 return result; |
| 1893 | 1907 |
| 1894 SECKEYPublicKey* public_key; | 1908 SECKEYPublicKey* public_key; |
| 1895 SECKEYPrivateKey* private_key; | 1909 SECKEYPrivateKey* private_key; |
| 1896 int error = ImportChannelIDKeys(&public_key, &private_key); | 1910 int error = ImportChannelIDKeys(&public_key, &private_key); |
| 1897 if (error != OK) | 1911 if (error != OK) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1915 // If a previous greedy read resulted in an error that was not consumed (eg: | 1929 // If a previous greedy read resulted in an error that was not consumed (eg: |
| 1916 // due to the caller having read some data successfully), then return that | 1930 // due to the caller having read some data successfully), then return that |
| 1917 // pending error now. | 1931 // pending error now. |
| 1918 if (pending_read_result_ != kNoPendingReadResult) { | 1932 if (pending_read_result_ != kNoPendingReadResult) { |
| 1919 rv = pending_read_result_; | 1933 rv = pending_read_result_; |
| 1920 PRErrorCode prerr = pending_read_nss_error_; | 1934 PRErrorCode prerr = pending_read_nss_error_; |
| 1921 pending_read_result_ = kNoPendingReadResult; | 1935 pending_read_result_ = kNoPendingReadResult; |
| 1922 pending_read_nss_error_ = 0; | 1936 pending_read_nss_error_ = 0; |
| 1923 | 1937 |
| 1924 if (rv == 0) { | 1938 if (rv == 0) { |
| 1925 PostOrRunCallback( | 1939 PostOrRunCallback(FROM_HERE, |
| 1926 FROM_HERE, | 1940 base::Bind(&LogByteTransferEvent, |
| 1927 base::Bind(&LogByteTransferEvent, weak_net_log_, | 1941 weak_net_log_, |
| 1928 NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED, rv, | 1942 NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED, |
| 1929 scoped_refptr<IOBuffer>(user_read_buf_))); | 1943 rv, |
| 1944 scoped_refptr<IOBuffer>(user_read_buf_))); |
| 1930 } else { | 1945 } else { |
| 1931 PostOrRunCallback( | 1946 PostOrRunCallback(FROM_HERE, |
| 1932 FROM_HERE, | 1947 base::Bind(&AddLogEventWithCallback, |
| 1933 base::Bind(&AddLogEventWithCallback, weak_net_log_, | 1948 weak_net_log_, |
| 1934 NetLog::TYPE_SSL_READ_ERROR, | 1949 NetLog::TYPE_SSL_READ_ERROR, |
| 1935 CreateNetLogSSLErrorCallback(rv, prerr))); | 1950 CreateNetLogSSLErrorCallback(rv, prerr))); |
| 1936 } | 1951 } |
| 1937 return rv; | 1952 return rv; |
| 1938 } | 1953 } |
| 1939 | 1954 |
| 1940 // Perform a greedy read, attempting to read as much as the caller has | 1955 // Perform a greedy read, attempting to read as much as the caller has |
| 1941 // requested. In the current NSS implementation, PR_Read will return | 1956 // requested. In the current NSS implementation, PR_Read will return |
| 1942 // exactly one SSL application data record's worth of data per invocation. | 1957 // exactly one SSL application data record's worth of data per invocation. |
| 1943 // The record size is dictated by the server, and may be noticeably smaller | 1958 // The record size is dictated by the server, and may be noticeably smaller |
| 1944 // than the caller's buffer. This may be as little as a single byte, if the | 1959 // than the caller's buffer. This may be as little as a single byte, if the |
| 1945 // server is performing 1/n-1 record splitting. | 1960 // server is performing 1/n-1 record splitting. |
| 1946 // | 1961 // |
| 1947 // However, this greedy read may result in renegotiations/re-handshakes | 1962 // However, this greedy read may result in renegotiations/re-handshakes |
| 1948 // happening or may lead to some data being read, followed by an EOF (such as | 1963 // happening or may lead to some data being read, followed by an EOF (such as |
| 1949 // a TLS close-notify). If at least some data was read, then that result | 1964 // a TLS close-notify). If at least some data was read, then that result |
| 1950 // should be deferred until the next call to DoPayloadRead(). Otherwise, if no | 1965 // should be deferred until the next call to DoPayloadRead(). Otherwise, if no |
| 1951 // data was read, it's safe to return the error or EOF immediately. | 1966 // data was read, it's safe to return the error or EOF immediately. |
| 1952 int total_bytes_read = 0; | 1967 int total_bytes_read = 0; |
| 1953 do { | 1968 do { |
| 1954 rv = PR_Read(nss_fd_, user_read_buf_->data() + total_bytes_read, | 1969 rv = PR_Read(nss_fd_, |
| 1970 user_read_buf_->data() + total_bytes_read, |
| 1955 user_read_buf_len_ - total_bytes_read); | 1971 user_read_buf_len_ - total_bytes_read); |
| 1956 if (rv > 0) | 1972 if (rv > 0) |
| 1957 total_bytes_read += rv; | 1973 total_bytes_read += rv; |
| 1958 } while (total_bytes_read < user_read_buf_len_ && rv > 0); | 1974 } while (total_bytes_read < user_read_buf_len_ && rv > 0); |
| 1959 int amount_in_read_buffer = memio_GetReadableBufferSize(nss_bufs_); | 1975 int amount_in_read_buffer = memio_GetReadableBufferSize(nss_bufs_); |
| 1960 PostOrRunCallback(FROM_HERE, base::Bind(&Core::OnNSSBufferUpdated, this, | 1976 PostOrRunCallback( |
| 1961 amount_in_read_buffer)); | 1977 FROM_HERE, |
| 1978 base::Bind(&Core::OnNSSBufferUpdated, this, amount_in_read_buffer)); |
| 1962 | 1979 |
| 1963 if (total_bytes_read == user_read_buf_len_) { | 1980 if (total_bytes_read == user_read_buf_len_) { |
| 1964 // The caller's entire request was satisfied without error. No further | 1981 // The caller's entire request was satisfied without error. No further |
| 1965 // processing needed. | 1982 // processing needed. |
| 1966 rv = total_bytes_read; | 1983 rv = total_bytes_read; |
| 1967 } else { | 1984 } else { |
| 1968 // Otherwise, an error occurred (rv <= 0). The error needs to be handled | 1985 // Otherwise, an error occurred (rv <= 0). The error needs to be handled |
| 1969 // immediately, while the NSPR/NSS errors are still available in | 1986 // immediately, while the NSPR/NSS errors are still available in |
| 1970 // thread-local storage. However, the handled/remapped error code should | 1987 // thread-local storage. However, the handled/remapped error code should |
| 1971 // only be returned if no application data was already read; if it was, the | 1988 // only be returned if no application data was already read; if it was, the |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2000 // if a complete record may now be read. | 2017 // if a complete record may now be read. |
| 2001 pending_read_nss_error_ = 0; | 2018 pending_read_nss_error_ = 0; |
| 2002 pending_read_result_ = kNoPendingReadResult; | 2019 pending_read_result_ = kNoPendingReadResult; |
| 2003 } | 2020 } |
| 2004 } | 2021 } |
| 2005 } | 2022 } |
| 2006 | 2023 |
| 2007 DCHECK_NE(ERR_IO_PENDING, pending_read_result_); | 2024 DCHECK_NE(ERR_IO_PENDING, pending_read_result_); |
| 2008 | 2025 |
| 2009 if (rv >= 0) { | 2026 if (rv >= 0) { |
| 2010 PostOrRunCallback( | 2027 PostOrRunCallback(FROM_HERE, |
| 2011 FROM_HERE, | 2028 base::Bind(&LogByteTransferEvent, |
| 2012 base::Bind(&LogByteTransferEvent, weak_net_log_, | 2029 weak_net_log_, |
| 2013 NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED, rv, | 2030 NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED, |
| 2014 scoped_refptr<IOBuffer>(user_read_buf_))); | 2031 rv, |
| 2032 scoped_refptr<IOBuffer>(user_read_buf_))); |
| 2015 } else if (rv != ERR_IO_PENDING) { | 2033 } else if (rv != ERR_IO_PENDING) { |
| 2016 PostOrRunCallback( | 2034 PostOrRunCallback( |
| 2017 FROM_HERE, | 2035 FROM_HERE, |
| 2018 base::Bind(&AddLogEventWithCallback, weak_net_log_, | 2036 base::Bind(&AddLogEventWithCallback, |
| 2037 weak_net_log_, |
| 2019 NetLog::TYPE_SSL_READ_ERROR, | 2038 NetLog::TYPE_SSL_READ_ERROR, |
| 2020 CreateNetLogSSLErrorCallback(rv, pending_read_nss_error_))); | 2039 CreateNetLogSSLErrorCallback(rv, pending_read_nss_error_))); |
| 2021 pending_read_nss_error_ = 0; | 2040 pending_read_nss_error_ = 0; |
| 2022 } | 2041 } |
| 2023 return rv; | 2042 return rv; |
| 2024 } | 2043 } |
| 2025 | 2044 |
| 2026 int SSLClientSocketNSS::Core::DoPayloadWrite() { | 2045 int SSLClientSocketNSS::Core::DoPayloadWrite() { |
| 2027 DCHECK(OnNSSTaskRunner()); | 2046 DCHECK(OnNSSTaskRunner()); |
| 2028 | 2047 |
| 2029 DCHECK(user_write_buf_.get()); | 2048 DCHECK(user_write_buf_.get()); |
| 2030 | 2049 |
| 2031 int old_amount_in_read_buffer = memio_GetReadableBufferSize(nss_bufs_); | 2050 int old_amount_in_read_buffer = memio_GetReadableBufferSize(nss_bufs_); |
| 2032 int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_); | 2051 int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_); |
| 2033 int new_amount_in_read_buffer = memio_GetReadableBufferSize(nss_bufs_); | 2052 int new_amount_in_read_buffer = memio_GetReadableBufferSize(nss_bufs_); |
| 2034 // PR_Write could potentially consume the unhandled data in the memio read | 2053 // PR_Write could potentially consume the unhandled data in the memio read |
| 2035 // buffer if a renegotiation is in progress. If the buffer is consumed, | 2054 // buffer if a renegotiation is in progress. If the buffer is consumed, |
| 2036 // notify the latest buffer size to NetworkRunner. | 2055 // notify the latest buffer size to NetworkRunner. |
| 2037 if (old_amount_in_read_buffer != new_amount_in_read_buffer) { | 2056 if (old_amount_in_read_buffer != new_amount_in_read_buffer) { |
| 2038 PostOrRunCallback( | 2057 PostOrRunCallback( |
| 2039 FROM_HERE, | 2058 FROM_HERE, |
| 2040 base::Bind(&Core::OnNSSBufferUpdated, this, new_amount_in_read_buffer)); | 2059 base::Bind(&Core::OnNSSBufferUpdated, this, new_amount_in_read_buffer)); |
| 2041 } | 2060 } |
| 2042 if (rv >= 0) { | 2061 if (rv >= 0) { |
| 2043 PostOrRunCallback( | 2062 PostOrRunCallback(FROM_HERE, |
| 2044 FROM_HERE, | 2063 base::Bind(&LogByteTransferEvent, |
| 2045 base::Bind(&LogByteTransferEvent, weak_net_log_, | 2064 weak_net_log_, |
| 2046 NetLog::TYPE_SSL_SOCKET_BYTES_SENT, rv, | 2065 NetLog::TYPE_SSL_SOCKET_BYTES_SENT, |
| 2047 scoped_refptr<IOBuffer>(user_write_buf_))); | 2066 rv, |
| 2067 scoped_refptr<IOBuffer>(user_write_buf_))); |
| 2048 return rv; | 2068 return rv; |
| 2049 } | 2069 } |
| 2050 PRErrorCode prerr = PR_GetError(); | 2070 PRErrorCode prerr = PR_GetError(); |
| 2051 if (prerr == PR_WOULD_BLOCK_ERROR) | 2071 if (prerr == PR_WOULD_BLOCK_ERROR) |
| 2052 return ERR_IO_PENDING; | 2072 return ERR_IO_PENDING; |
| 2053 | 2073 |
| 2054 rv = HandleNSSError(prerr, false); | 2074 rv = HandleNSSError(prerr, false); |
| 2055 PostOrRunCallback( | 2075 PostOrRunCallback(FROM_HERE, |
| 2056 FROM_HERE, | 2076 base::Bind(&AddLogEventWithCallback, |
| 2057 base::Bind(&AddLogEventWithCallback, weak_net_log_, | 2077 weak_net_log_, |
| 2058 NetLog::TYPE_SSL_WRITE_ERROR, | 2078 NetLog::TYPE_SSL_WRITE_ERROR, |
| 2059 CreateNetLogSSLErrorCallback(rv, prerr))); | 2079 CreateNetLogSSLErrorCallback(rv, prerr))); |
| 2060 return rv; | 2080 return rv; |
| 2061 } | 2081 } |
| 2062 | 2082 |
| 2063 // Do as much network I/O as possible between the buffer and the | 2083 // Do as much network I/O as possible between the buffer and the |
| 2064 // transport socket. Return true if some I/O performed, false | 2084 // transport socket. Return true if some I/O performed, false |
| 2065 // otherwise (error or ERR_IO_PENDING). | 2085 // otherwise (error or ERR_IO_PENDING). |
| 2066 bool SSLClientSocketNSS::Core::DoTransportIO() { | 2086 bool SSLClientSocketNSS::Core::DoTransportIO() { |
| 2067 DCHECK(OnNSSTaskRunner()); | 2087 DCHECK(OnNSSTaskRunner()); |
| 2068 | 2088 |
| 2069 bool network_moved = false; | 2089 bool network_moved = false; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2105 if (!nb) { | 2125 if (!nb) { |
| 2106 // buffer too full to read into, so no I/O possible at moment | 2126 // buffer too full to read into, so no I/O possible at moment |
| 2107 rv = ERR_IO_PENDING; | 2127 rv = ERR_IO_PENDING; |
| 2108 } else { | 2128 } else { |
| 2109 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(nb)); | 2129 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(nb)); |
| 2110 if (OnNetworkTaskRunner()) { | 2130 if (OnNetworkTaskRunner()) { |
| 2111 rv = DoBufferRecv(read_buffer.get(), nb); | 2131 rv = DoBufferRecv(read_buffer.get(), nb); |
| 2112 } else { | 2132 } else { |
| 2113 bool posted = network_task_runner_->PostTask( | 2133 bool posted = network_task_runner_->PostTask( |
| 2114 FROM_HERE, | 2134 FROM_HERE, |
| 2115 base::Bind(IgnoreResult(&Core::DoBufferRecv), this, read_buffer, | 2135 base::Bind(IgnoreResult(&Core::DoBufferRecv), this, read_buffer, nb)); |
| 2116 nb)); | |
| 2117 rv = posted ? ERR_IO_PENDING : ERR_ABORTED; | 2136 rv = posted ? ERR_IO_PENDING : ERR_ABORTED; |
| 2118 } | 2137 } |
| 2119 | 2138 |
| 2120 if (rv == ERR_IO_PENDING) { | 2139 if (rv == ERR_IO_PENDING) { |
| 2121 transport_recv_busy_ = true; | 2140 transport_recv_busy_ = true; |
| 2122 } else { | 2141 } else { |
| 2123 if (rv > 0) { | 2142 if (rv > 0) { |
| 2124 memcpy(buf, read_buffer->data(), rv); | 2143 memcpy(buf, read_buffer->data(), rv); |
| 2125 } else if (rv == 0) { | 2144 } else if (rv == 0) { |
| 2126 transport_recv_eof_ = true; | 2145 transport_recv_eof_ = true; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2150 if (len) { | 2169 if (len) { |
| 2151 scoped_refptr<IOBuffer> send_buffer(new IOBuffer(len)); | 2170 scoped_refptr<IOBuffer> send_buffer(new IOBuffer(len)); |
| 2152 memcpy(send_buffer->data(), buf1, len1); | 2171 memcpy(send_buffer->data(), buf1, len1); |
| 2153 memcpy(send_buffer->data() + len1, buf2, len2); | 2172 memcpy(send_buffer->data() + len1, buf2, len2); |
| 2154 | 2173 |
| 2155 if (OnNetworkTaskRunner()) { | 2174 if (OnNetworkTaskRunner()) { |
| 2156 rv = DoBufferSend(send_buffer.get(), len); | 2175 rv = DoBufferSend(send_buffer.get(), len); |
| 2157 } else { | 2176 } else { |
| 2158 bool posted = network_task_runner_->PostTask( | 2177 bool posted = network_task_runner_->PostTask( |
| 2159 FROM_HERE, | 2178 FROM_HERE, |
| 2160 base::Bind(IgnoreResult(&Core::DoBufferSend), this, send_buffer, | 2179 base::Bind( |
| 2161 len)); | 2180 IgnoreResult(&Core::DoBufferSend), this, send_buffer, len)); |
| 2162 rv = posted ? ERR_IO_PENDING : ERR_ABORTED; | 2181 rv = posted ? ERR_IO_PENDING : ERR_ABORTED; |
| 2163 } | 2182 } |
| 2164 | 2183 |
| 2165 if (rv == ERR_IO_PENDING) { | 2184 if (rv == ERR_IO_PENDING) { |
| 2166 transport_send_busy_ = true; | 2185 transport_send_busy_ = true; |
| 2167 } else { | 2186 } else { |
| 2168 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv)); | 2187 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv)); |
| 2169 } | 2188 } |
| 2170 } | 2189 } |
| 2171 | 2190 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2232 // handshake. This requires network IO, which in turn calls | 2251 // handshake. This requires network IO, which in turn calls |
| 2233 // BufferRecvComplete() with a non-zero byte count. This byte count eventually | 2252 // BufferRecvComplete() with a non-zero byte count. This byte count eventually |
| 2234 // winds its way through the state machine and ends up being passed to the | 2253 // winds its way through the state machine and ends up being passed to the |
| 2235 // callback. For Read() and Write(), that's what we want. But for Connect(), | 2254 // callback. For Read() and Write(), that's what we want. But for Connect(), |
| 2236 // the caller expects OK (i.e. 0) for success. | 2255 // the caller expects OK (i.e. 0) for success. |
| 2237 void SSLClientSocketNSS::Core::DoConnectCallback(int rv) { | 2256 void SSLClientSocketNSS::Core::DoConnectCallback(int rv) { |
| 2238 DCHECK(OnNSSTaskRunner()); | 2257 DCHECK(OnNSSTaskRunner()); |
| 2239 DCHECK_NE(rv, ERR_IO_PENDING); | 2258 DCHECK_NE(rv, ERR_IO_PENDING); |
| 2240 DCHECK(!user_connect_callback_.is_null()); | 2259 DCHECK(!user_connect_callback_.is_null()); |
| 2241 | 2260 |
| 2242 base::Closure c = base::Bind( | 2261 base::Closure c = base::Bind(base::ResetAndReturn(&user_connect_callback_), |
| 2243 base::ResetAndReturn(&user_connect_callback_), | 2262 rv > OK ? OK : rv); |
| 2244 rv > OK ? OK : rv); | |
| 2245 PostOrRunCallback(FROM_HERE, c); | 2263 PostOrRunCallback(FROM_HERE, c); |
| 2246 } | 2264 } |
| 2247 | 2265 |
| 2248 void SSLClientSocketNSS::Core::DoReadCallback(int rv) { | 2266 void SSLClientSocketNSS::Core::DoReadCallback(int rv) { |
| 2249 DCHECK(OnNSSTaskRunner()); | 2267 DCHECK(OnNSSTaskRunner()); |
| 2250 DCHECK_NE(ERR_IO_PENDING, rv); | 2268 DCHECK_NE(ERR_IO_PENDING, rv); |
| 2251 DCHECK(!user_read_callback_.is_null()); | 2269 DCHECK(!user_read_callback_.is_null()); |
| 2252 | 2270 |
| 2253 user_read_buf_ = NULL; | 2271 user_read_buf_ = NULL; |
| 2254 user_read_buf_len_ = 0; | 2272 user_read_buf_len_ = 0; |
| 2255 int amount_in_read_buffer = memio_GetReadableBufferSize(nss_bufs_); | 2273 int amount_in_read_buffer = memio_GetReadableBufferSize(nss_bufs_); |
| 2256 // This is used to curry the |amount_int_read_buffer| and |user_cb| back to | 2274 // This is used to curry the |amount_int_read_buffer| and |user_cb| back to |
| 2257 // the network task runner. | 2275 // the network task runner. |
| 2258 PostOrRunCallback( | 2276 PostOrRunCallback( |
| 2259 FROM_HERE, | 2277 FROM_HERE, |
| 2260 base::Bind(&Core::OnNSSBufferUpdated, this, amount_in_read_buffer)); | 2278 base::Bind(&Core::OnNSSBufferUpdated, this, amount_in_read_buffer)); |
| 2261 PostOrRunCallback( | 2279 PostOrRunCallback(FROM_HERE, base::Bind(&Core::DidNSSRead, this, rv)); |
| 2262 FROM_HERE, | 2280 PostOrRunCallback(FROM_HERE, |
| 2263 base::Bind(&Core::DidNSSRead, this, rv)); | 2281 base::Bind(base::ResetAndReturn(&user_read_callback_), rv)); |
| 2264 PostOrRunCallback( | |
| 2265 FROM_HERE, | |
| 2266 base::Bind(base::ResetAndReturn(&user_read_callback_), rv)); | |
| 2267 } | 2282 } |
| 2268 | 2283 |
| 2269 void SSLClientSocketNSS::Core::DoWriteCallback(int rv) { | 2284 void SSLClientSocketNSS::Core::DoWriteCallback(int rv) { |
| 2270 DCHECK(OnNSSTaskRunner()); | 2285 DCHECK(OnNSSTaskRunner()); |
| 2271 DCHECK_NE(ERR_IO_PENDING, rv); | 2286 DCHECK_NE(ERR_IO_PENDING, rv); |
| 2272 DCHECK(!user_write_callback_.is_null()); | 2287 DCHECK(!user_write_callback_.is_null()); |
| 2273 | 2288 |
| 2274 // Since Run may result in Write being called, clear |user_write_callback_| | 2289 // Since Run may result in Write being called, clear |user_write_callback_| |
| 2275 // up front. | 2290 // up front. |
| 2276 user_write_buf_ = NULL; | 2291 user_write_buf_ = NULL; |
| 2277 user_write_buf_len_ = 0; | 2292 user_write_buf_len_ = 0; |
| 2278 // Update buffer status because DoWriteLoop called DoTransportIO which may | 2293 // Update buffer status because DoWriteLoop called DoTransportIO which may |
| 2279 // perform read operations. | 2294 // perform read operations. |
| 2280 int amount_in_read_buffer = memio_GetReadableBufferSize(nss_bufs_); | 2295 int amount_in_read_buffer = memio_GetReadableBufferSize(nss_bufs_); |
| 2281 // This is used to curry the |amount_int_read_buffer| and |user_cb| back to | 2296 // This is used to curry the |amount_int_read_buffer| and |user_cb| back to |
| 2282 // the network task runner. | 2297 // the network task runner. |
| 2283 PostOrRunCallback( | 2298 PostOrRunCallback( |
| 2284 FROM_HERE, | 2299 FROM_HERE, |
| 2285 base::Bind(&Core::OnNSSBufferUpdated, this, amount_in_read_buffer)); | 2300 base::Bind(&Core::OnNSSBufferUpdated, this, amount_in_read_buffer)); |
| 2301 PostOrRunCallback(FROM_HERE, base::Bind(&Core::DidNSSWrite, this, rv)); |
| 2286 PostOrRunCallback( | 2302 PostOrRunCallback( |
| 2287 FROM_HERE, | 2303 FROM_HERE, base::Bind(base::ResetAndReturn(&user_write_callback_), rv)); |
| 2288 base::Bind(&Core::DidNSSWrite, this, rv)); | |
| 2289 PostOrRunCallback( | |
| 2290 FROM_HERE, | |
| 2291 base::Bind(base::ResetAndReturn(&user_write_callback_), rv)); | |
| 2292 } | 2304 } |
| 2293 | 2305 |
| 2294 SECStatus SSLClientSocketNSS::Core::ClientChannelIDHandler( | 2306 SECStatus SSLClientSocketNSS::Core::ClientChannelIDHandler( |
| 2295 void* arg, | 2307 void* arg, |
| 2296 PRFileDesc* socket, | 2308 PRFileDesc* socket, |
| 2297 SECKEYPublicKey **out_public_key, | 2309 SECKEYPublicKey** out_public_key, |
| 2298 SECKEYPrivateKey **out_private_key) { | 2310 SECKEYPrivateKey** out_private_key) { |
| 2299 Core* core = reinterpret_cast<Core*>(arg); | 2311 Core* core = reinterpret_cast<Core*>(arg); |
| 2300 DCHECK(core->OnNSSTaskRunner()); | 2312 DCHECK(core->OnNSSTaskRunner()); |
| 2301 | 2313 |
| 2302 core->PostOrRunCallback( | 2314 core->PostOrRunCallback(FROM_HERE, |
| 2303 FROM_HERE, | 2315 base::Bind(&AddLogEvent, |
| 2304 base::Bind(&AddLogEvent, core->weak_net_log_, | 2316 core->weak_net_log_, |
| 2305 NetLog::TYPE_SSL_CHANNEL_ID_REQUESTED)); | 2317 NetLog::TYPE_SSL_CHANNEL_ID_REQUESTED)); |
| 2306 | 2318 |
| 2307 // We have negotiated the TLS channel ID extension. | 2319 // We have negotiated the TLS channel ID extension. |
| 2308 core->channel_id_xtn_negotiated_ = true; | 2320 core->channel_id_xtn_negotiated_ = true; |
| 2309 std::string host = core->host_and_port_.host(); | 2321 std::string host = core->host_and_port_.host(); |
| 2310 int error = ERR_UNEXPECTED; | 2322 int error = ERR_UNEXPECTED; |
| 2311 if (core->OnNetworkTaskRunner()) { | 2323 if (core->OnNetworkTaskRunner()) { |
| 2312 error = core->DoGetDomainBoundCert(host); | 2324 error = core->DoGetDomainBoundCert(host); |
| 2313 } else { | 2325 } else { |
| 2314 bool posted = core->network_task_runner_->PostTask( | 2326 bool posted = core->network_task_runner_->PostTask( |
| 2315 FROM_HERE, | 2327 FROM_HERE, |
| 2316 base::Bind( | 2328 base::Bind(IgnoreResult(&Core::DoGetDomainBoundCert), core, host)); |
| 2317 IgnoreResult(&Core::DoGetDomainBoundCert), | |
| 2318 core, host)); | |
| 2319 error = posted ? ERR_IO_PENDING : ERR_ABORTED; | 2329 error = posted ? ERR_IO_PENDING : ERR_ABORTED; |
| 2320 } | 2330 } |
| 2321 | 2331 |
| 2322 if (error == ERR_IO_PENDING) { | 2332 if (error == ERR_IO_PENDING) { |
| 2323 // Asynchronous case. | 2333 // Asynchronous case. |
| 2324 core->channel_id_needed_ = true; | 2334 core->channel_id_needed_ = true; |
| 2325 return SECWouldBlock; | 2335 return SECWouldBlock; |
| 2326 } | 2336 } |
| 2327 | 2337 |
| 2328 core->PostOrRunCallback( | 2338 core->PostOrRunCallback(FROM_HERE, |
| 2329 FROM_HERE, | 2339 base::Bind(&BoundNetLog::EndEventWithNetErrorCode, |
| 2330 base::Bind(&BoundNetLog::EndEventWithNetErrorCode, core->weak_net_log_, | 2340 core->weak_net_log_, |
| 2331 NetLog::TYPE_SSL_GET_DOMAIN_BOUND_CERT, error)); | 2341 NetLog::TYPE_SSL_GET_DOMAIN_BOUND_CERT, |
| 2342 error)); |
| 2332 SECStatus rv = SECSuccess; | 2343 SECStatus rv = SECSuccess; |
| 2333 if (error == OK) { | 2344 if (error == OK) { |
| 2334 // Synchronous success. | 2345 // Synchronous success. |
| 2335 int result = core->ImportChannelIDKeys(out_public_key, out_private_key); | 2346 int result = core->ImportChannelIDKeys(out_public_key, out_private_key); |
| 2336 if (result == OK) | 2347 if (result == OK) |
| 2337 core->SetChannelIDProvided(); | 2348 core->SetChannelIDProvided(); |
| 2338 else | 2349 else |
| 2339 rv = SECFailure; | 2350 rv = SECFailure; |
| 2340 } else { | 2351 } else { |
| 2341 rv = SECFailure; | 2352 rv = SECFailure; |
| 2342 } | 2353 } |
| 2343 | 2354 |
| 2344 return rv; | 2355 return rv; |
| 2345 } | 2356 } |
| 2346 | 2357 |
| 2347 int SSLClientSocketNSS::Core::ImportChannelIDKeys(SECKEYPublicKey** public_key, | 2358 int SSLClientSocketNSS::Core::ImportChannelIDKeys(SECKEYPublicKey** public_key, |
| 2348 SECKEYPrivateKey** key) { | 2359 SECKEYPrivateKey** key) { |
| 2349 // Set the certificate. | 2360 // Set the certificate. |
| 2350 SECItem cert_item; | 2361 SECItem cert_item; |
| 2351 cert_item.data = (unsigned char*) domain_bound_cert_.data(); | 2362 cert_item.data = (unsigned char*)domain_bound_cert_.data(); |
| 2352 cert_item.len = domain_bound_cert_.size(); | 2363 cert_item.len = domain_bound_cert_.size(); |
| 2353 ScopedCERTCertificate cert(CERT_NewTempCertificate(CERT_GetDefaultCertDB(), | 2364 ScopedCERTCertificate cert(CERT_NewTempCertificate( |
| 2354 &cert_item, | 2365 CERT_GetDefaultCertDB(), &cert_item, NULL, PR_FALSE, PR_TRUE)); |
| 2355 NULL, | |
| 2356 PR_FALSE, | |
| 2357 PR_TRUE)); | |
| 2358 if (cert == NULL) | 2366 if (cert == NULL) |
| 2359 return MapNSSError(PORT_GetError()); | 2367 return MapNSSError(PORT_GetError()); |
| 2360 | 2368 |
| 2361 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot()); | 2369 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot()); |
| 2362 // Set the private key. | 2370 // Set the private key. |
| 2363 if (!crypto::ECPrivateKey::ImportFromEncryptedPrivateKeyInfo( | 2371 if (!crypto::ECPrivateKey::ImportFromEncryptedPrivateKeyInfo( |
| 2364 slot.get(), | 2372 slot.get(), |
| 2365 ServerBoundCertService::kEPKIPassword, | 2373 ServerBoundCertService::kEPKIPassword, |
| 2366 reinterpret_cast<const unsigned char*>( | 2374 reinterpret_cast<const unsigned char*>( |
| 2367 domain_bound_private_key_.data()), | 2375 domain_bound_private_key_.data()), |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2378 return OK; | 2386 return OK; |
| 2379 } | 2387 } |
| 2380 | 2388 |
| 2381 void SSLClientSocketNSS::Core::UpdateServerCert() { | 2389 void SSLClientSocketNSS::Core::UpdateServerCert() { |
| 2382 nss_handshake_state_.server_cert_chain.Reset(nss_fd_); | 2390 nss_handshake_state_.server_cert_chain.Reset(nss_fd_); |
| 2383 nss_handshake_state_.server_cert = X509Certificate::CreateFromDERCertChain( | 2391 nss_handshake_state_.server_cert = X509Certificate::CreateFromDERCertChain( |
| 2384 nss_handshake_state_.server_cert_chain.AsStringPieceVector()); | 2392 nss_handshake_state_.server_cert_chain.AsStringPieceVector()); |
| 2385 if (nss_handshake_state_.server_cert.get()) { | 2393 if (nss_handshake_state_.server_cert.get()) { |
| 2386 // Since this will be called asynchronously on another thread, it needs to | 2394 // Since this will be called asynchronously on another thread, it needs to |
| 2387 // own a reference to the certificate. | 2395 // own a reference to the certificate. |
| 2388 NetLog::ParametersCallback net_log_callback = | 2396 NetLog::ParametersCallback net_log_callback = base::Bind( |
| 2389 base::Bind(&NetLogX509CertificateCallback, | 2397 &NetLogX509CertificateCallback, nss_handshake_state_.server_cert); |
| 2390 nss_handshake_state_.server_cert); | 2398 PostOrRunCallback(FROM_HERE, |
| 2391 PostOrRunCallback( | 2399 base::Bind(&AddLogEventWithCallback, |
| 2392 FROM_HERE, | 2400 weak_net_log_, |
| 2393 base::Bind(&AddLogEventWithCallback, weak_net_log_, | 2401 NetLog::TYPE_SSL_CERTIFICATES_RECEIVED, |
| 2394 NetLog::TYPE_SSL_CERTIFICATES_RECEIVED, | 2402 net_log_callback)); |
| 2395 net_log_callback)); | |
| 2396 } | 2403 } |
| 2397 } | 2404 } |
| 2398 | 2405 |
| 2399 void SSLClientSocketNSS::Core::UpdateSignedCertTimestamps() { | 2406 void SSLClientSocketNSS::Core::UpdateSignedCertTimestamps() { |
| 2400 const SECItem* signed_cert_timestamps = | 2407 const SECItem* signed_cert_timestamps = SSL_PeerSignedCertTimestamps(nss_fd_); |
| 2401 SSL_PeerSignedCertTimestamps(nss_fd_); | |
| 2402 | 2408 |
| 2403 if (!signed_cert_timestamps || !signed_cert_timestamps->len) | 2409 if (!signed_cert_timestamps || !signed_cert_timestamps->len) |
| 2404 return; | 2410 return; |
| 2405 | 2411 |
| 2406 nss_handshake_state_.sct_list_from_tls_extension = std::string( | 2412 nss_handshake_state_.sct_list_from_tls_extension = |
| 2407 reinterpret_cast<char*>(signed_cert_timestamps->data), | 2413 std::string(reinterpret_cast<char*>(signed_cert_timestamps->data), |
| 2408 signed_cert_timestamps->len); | 2414 signed_cert_timestamps->len); |
| 2409 } | 2415 } |
| 2410 | 2416 |
| 2411 void SSLClientSocketNSS::Core::UpdateStapledOCSPResponse() { | 2417 void SSLClientSocketNSS::Core::UpdateStapledOCSPResponse() { |
| 2412 PRBool ocsp_requested = PR_FALSE; | 2418 PRBool ocsp_requested = PR_FALSE; |
| 2413 SSL_OptionGet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, &ocsp_requested); | 2419 SSL_OptionGet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, &ocsp_requested); |
| 2414 const SECItemArray* ocsp_responses = | 2420 const SECItemArray* ocsp_responses = SSL_PeerStapledOCSPResponses(nss_fd_); |
| 2415 SSL_PeerStapledOCSPResponses(nss_fd_); | |
| 2416 bool ocsp_responses_present = ocsp_responses && ocsp_responses->len; | 2421 bool ocsp_responses_present = ocsp_responses && ocsp_responses->len; |
| 2417 if (ocsp_requested) | 2422 if (ocsp_requested) |
| 2418 UMA_HISTOGRAM_BOOLEAN("Net.OCSPResponseStapled", ocsp_responses_present); | 2423 UMA_HISTOGRAM_BOOLEAN("Net.OCSPResponseStapled", ocsp_responses_present); |
| 2419 if (!ocsp_responses_present) | 2424 if (!ocsp_responses_present) |
| 2420 return; | 2425 return; |
| 2421 | 2426 |
| 2422 nss_handshake_state_.stapled_ocsp_response = std::string( | 2427 nss_handshake_state_.stapled_ocsp_response = |
| 2423 reinterpret_cast<char*>(ocsp_responses->items[0].data), | 2428 std::string(reinterpret_cast<char*>(ocsp_responses->items[0].data), |
| 2424 ocsp_responses->items[0].len); | 2429 ocsp_responses->items[0].len); |
| 2425 | 2430 |
| 2426 // TODO(agl): figure out how to plumb an OCSP response into the Mac | 2431 // TODO(agl): figure out how to plumb an OCSP response into the Mac |
| 2427 // system library and update IsOCSPStaplingSupported for Mac. | 2432 // system library and update IsOCSPStaplingSupported for Mac. |
| 2428 if (IsOCSPStaplingSupported()) { | 2433 if (IsOCSPStaplingSupported()) { |
| 2429 #if defined(OS_WIN) | 2434 #if defined(OS_WIN) |
| 2430 if (nss_handshake_state_.server_cert) { | 2435 if (nss_handshake_state_.server_cert) { |
| 2431 CRYPT_DATA_BLOB ocsp_response_blob; | 2436 CRYPT_DATA_BLOB ocsp_response_blob; |
| 2432 ocsp_response_blob.cbData = ocsp_responses->items[0].len; | 2437 ocsp_response_blob.cbData = ocsp_responses->items[0].len; |
| 2433 ocsp_response_blob.pbData = ocsp_responses->items[0].data; | 2438 ocsp_response_blob.pbData = ocsp_responses->items[0].data; |
| 2434 BOOL ok = CertSetCertificateContextProperty( | 2439 BOOL ok = CertSetCertificateContextProperty( |
| 2435 nss_handshake_state_.server_cert->os_cert_handle(), | 2440 nss_handshake_state_.server_cert->os_cert_handle(), |
| 2436 CERT_OCSP_RESPONSE_PROP_ID, | 2441 CERT_OCSP_RESPONSE_PROP_ID, |
| 2437 CERT_SET_PROPERTY_IGNORE_PERSIST_ERROR_FLAG, | 2442 CERT_SET_PROPERTY_IGNORE_PERSIST_ERROR_FLAG, |
| 2438 &ocsp_response_blob); | 2443 &ocsp_response_blob); |
| 2439 if (!ok) { | 2444 if (!ok) { |
| 2440 VLOG(1) << "Failed to set OCSP response property: " | 2445 VLOG(1) << "Failed to set OCSP response property: " << GetLastError(); |
| 2441 << GetLastError(); | |
| 2442 } | 2446 } |
| 2443 } | 2447 } |
| 2444 #elif defined(USE_NSS) | 2448 #elif defined(USE_NSS) |
| 2445 CacheOCSPResponseFromSideChannelFunction cache_ocsp_response = | 2449 CacheOCSPResponseFromSideChannelFunction cache_ocsp_response = |
| 2446 GetCacheOCSPResponseFromSideChannelFunction(); | 2450 GetCacheOCSPResponseFromSideChannelFunction(); |
| 2447 | 2451 |
| 2448 cache_ocsp_response( | 2452 cache_ocsp_response(CERT_GetDefaultCertDB(), |
| 2449 CERT_GetDefaultCertDB(), | 2453 nss_handshake_state_.server_cert_chain[0], |
| 2450 nss_handshake_state_.server_cert_chain[0], PR_Now(), | 2454 PR_Now(), |
| 2451 &ocsp_responses->items[0], NULL); | 2455 &ocsp_responses->items[0], |
| 2452 #endif | 2456 NULL); |
| 2457 #endif |
| 2453 } // IsOCSPStaplingSupported() | 2458 } // IsOCSPStaplingSupported() |
| 2454 } | 2459 } |
| 2455 | 2460 |
| 2456 void SSLClientSocketNSS::Core::UpdateConnectionStatus() { | 2461 void SSLClientSocketNSS::Core::UpdateConnectionStatus() { |
| 2457 SSLChannelInfo channel_info; | 2462 SSLChannelInfo channel_info; |
| 2458 SECStatus ok = SSL_GetChannelInfo(nss_fd_, | 2463 SECStatus ok = |
| 2459 &channel_info, sizeof(channel_info)); | 2464 SSL_GetChannelInfo(nss_fd_, &channel_info, sizeof(channel_info)); |
| 2460 if (ok == SECSuccess && | 2465 if (ok == SECSuccess && channel_info.length == sizeof(channel_info) && |
| 2461 channel_info.length == sizeof(channel_info) && | |
| 2462 channel_info.cipherSuite) { | 2466 channel_info.cipherSuite) { |
| 2463 nss_handshake_state_.ssl_connection_status |= | 2467 nss_handshake_state_.ssl_connection_status |= |
| 2464 (static_cast<int>(channel_info.cipherSuite) & | 2468 (static_cast<int>(channel_info.cipherSuite) & |
| 2465 SSL_CONNECTION_CIPHERSUITE_MASK) << | 2469 SSL_CONNECTION_CIPHERSUITE_MASK) |
| 2466 SSL_CONNECTION_CIPHERSUITE_SHIFT; | 2470 << SSL_CONNECTION_CIPHERSUITE_SHIFT; |
| 2467 | 2471 |
| 2468 nss_handshake_state_.ssl_connection_status |= | 2472 nss_handshake_state_.ssl_connection_status |= |
| 2469 (static_cast<int>(channel_info.compressionMethod) & | 2473 (static_cast<int>(channel_info.compressionMethod) & |
| 2470 SSL_CONNECTION_COMPRESSION_MASK) << | 2474 SSL_CONNECTION_COMPRESSION_MASK) |
| 2471 SSL_CONNECTION_COMPRESSION_SHIFT; | 2475 << SSL_CONNECTION_COMPRESSION_SHIFT; |
| 2472 | 2476 |
| 2473 // NSS 3.14.x doesn't have a version macro for TLS 1.2 (because NSS didn't | 2477 // NSS 3.14.x doesn't have a version macro for TLS 1.2 (because NSS didn't |
| 2474 // support it yet), so use 0x0303 directly. | 2478 // support it yet), so use 0x0303 directly. |
| 2475 int version = SSL_CONNECTION_VERSION_UNKNOWN; | 2479 int version = SSL_CONNECTION_VERSION_UNKNOWN; |
| 2476 if (channel_info.protocolVersion < SSL_LIBRARY_VERSION_3_0) { | 2480 if (channel_info.protocolVersion < SSL_LIBRARY_VERSION_3_0) { |
| 2477 // All versions less than SSL_LIBRARY_VERSION_3_0 are treated as SSL | 2481 // All versions less than SSL_LIBRARY_VERSION_3_0 are treated as SSL |
| 2478 // version 2. | 2482 // version 2. |
| 2479 version = SSL_CONNECTION_VERSION_SSL2; | 2483 version = SSL_CONNECTION_VERSION_SSL2; |
| 2480 } else if (channel_info.protocolVersion == SSL_LIBRARY_VERSION_3_0) { | 2484 } else if (channel_info.protocolVersion == SSL_LIBRARY_VERSION_3_0) { |
| 2481 version = SSL_CONNECTION_VERSION_SSL3; | 2485 version = SSL_CONNECTION_VERSION_SSL3; |
| 2482 } else if (channel_info.protocolVersion == SSL_LIBRARY_VERSION_3_1_TLS) { | 2486 } else if (channel_info.protocolVersion == SSL_LIBRARY_VERSION_3_1_TLS) { |
| 2483 version = SSL_CONNECTION_VERSION_TLS1; | 2487 version = SSL_CONNECTION_VERSION_TLS1; |
| 2484 } else if (channel_info.protocolVersion == SSL_LIBRARY_VERSION_TLS_1_1) { | 2488 } else if (channel_info.protocolVersion == SSL_LIBRARY_VERSION_TLS_1_1) { |
| 2485 version = SSL_CONNECTION_VERSION_TLS1_1; | 2489 version = SSL_CONNECTION_VERSION_TLS1_1; |
| 2486 } else if (channel_info.protocolVersion == 0x0303) { | 2490 } else if (channel_info.protocolVersion == 0x0303) { |
| 2487 version = SSL_CONNECTION_VERSION_TLS1_2; | 2491 version = SSL_CONNECTION_VERSION_TLS1_2; |
| 2488 } | 2492 } |
| 2489 nss_handshake_state_.ssl_connection_status |= | 2493 nss_handshake_state_.ssl_connection_status |= |
| 2490 (version & SSL_CONNECTION_VERSION_MASK) << | 2494 (version & SSL_CONNECTION_VERSION_MASK) << SSL_CONNECTION_VERSION_SHIFT; |
| 2491 SSL_CONNECTION_VERSION_SHIFT; | |
| 2492 } | 2495 } |
| 2493 | 2496 |
| 2494 PRBool peer_supports_renego_ext; | 2497 PRBool peer_supports_renego_ext; |
| 2495 ok = SSL_HandshakeNegotiatedExtension(nss_fd_, ssl_renegotiation_info_xtn, | 2498 ok = SSL_HandshakeNegotiatedExtension( |
| 2496 &peer_supports_renego_ext); | 2499 nss_fd_, ssl_renegotiation_info_xtn, &peer_supports_renego_ext); |
| 2497 if (ok == SECSuccess) { | 2500 if (ok == SECSuccess) { |
| 2498 if (!peer_supports_renego_ext) { | 2501 if (!peer_supports_renego_ext) { |
| 2499 nss_handshake_state_.ssl_connection_status |= | 2502 nss_handshake_state_.ssl_connection_status |= |
| 2500 SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION; | 2503 SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION; |
| 2501 // Log an informational message if the server does not support secure | 2504 // Log an informational message if the server does not support secure |
| 2502 // renegotiation (RFC 5746). | 2505 // renegotiation (RFC 5746). |
| 2503 VLOG(1) << "The server " << host_and_port_.ToString() | 2506 VLOG(1) << "The server " << host_and_port_.ToString() |
| 2504 << " does not support the TLS renegotiation_info extension."; | 2507 << " does not support the TLS renegotiation_info extension."; |
| 2505 } | 2508 } |
| 2506 UMA_HISTOGRAM_ENUMERATION("Net.RenegotiationExtensionSupported", | 2509 UMA_HISTOGRAM_ENUMERATION( |
| 2507 peer_supports_renego_ext, 2); | 2510 "Net.RenegotiationExtensionSupported", peer_supports_renego_ext, 2); |
| 2508 | 2511 |
| 2509 // We would like to eliminate fallback to SSLv3 for non-buggy servers | 2512 // We would like to eliminate fallback to SSLv3 for non-buggy servers |
| 2510 // because of security concerns. For example, Google offers forward | 2513 // because of security concerns. For example, Google offers forward |
| 2511 // secrecy with ECDHE but that requires TLS 1.0. An attacker can block | 2514 // secrecy with ECDHE but that requires TLS 1.0. An attacker can block |
| 2512 // TLSv1 connections and force us to downgrade to SSLv3 and remove forward | 2515 // TLSv1 connections and force us to downgrade to SSLv3 and remove forward |
| 2513 // secrecy. | 2516 // secrecy. |
| 2514 // | 2517 // |
| 2515 // Yngve from Opera has suggested using the renegotiation extension as an | 2518 // Yngve from Opera has suggested using the renegotiation extension as an |
| 2516 // indicator that SSLv3 fallback was mistaken: | 2519 // indicator that SSLv3 fallback was mistaken: |
| 2517 // tools.ietf.org/html/draft-pettersen-tls-version-rollback-removal-00 . | 2520 // tools.ietf.org/html/draft-pettersen-tls-version-rollback-removal-00 . |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2560 } | 2563 } |
| 2561 | 2564 |
| 2562 void SSLClientSocketNSS::Core::RecordChannelIDSupportOnNSSTaskRunner() { | 2565 void SSLClientSocketNSS::Core::RecordChannelIDSupportOnNSSTaskRunner() { |
| 2563 DCHECK(OnNSSTaskRunner()); | 2566 DCHECK(OnNSSTaskRunner()); |
| 2564 if (nss_handshake_state_.resumed_handshake) | 2567 if (nss_handshake_state_.resumed_handshake) |
| 2565 return; | 2568 return; |
| 2566 | 2569 |
| 2567 // Copy the NSS task runner-only state to the network task runner and | 2570 // Copy the NSS task runner-only state to the network task runner and |
| 2568 // log histograms from there, since the histograms also need access to the | 2571 // log histograms from there, since the histograms also need access to the |
| 2569 // network task runner state. | 2572 // network task runner state. |
| 2570 PostOrRunCallback( | 2573 PostOrRunCallback(FROM_HERE, |
| 2571 FROM_HERE, | 2574 base::Bind(&Core::RecordChannelIDSupportOnNetworkTaskRunner, |
| 2572 base::Bind(&Core::RecordChannelIDSupportOnNetworkTaskRunner, | 2575 this, |
| 2573 this, | 2576 channel_id_xtn_negotiated_, |
| 2574 channel_id_xtn_negotiated_, | 2577 ssl_config_.channel_id_enabled, |
| 2575 ssl_config_.channel_id_enabled, | 2578 crypto::ECPrivateKey::IsSupported())); |
| 2576 crypto::ECPrivateKey::IsSupported())); | |
| 2577 } | 2579 } |
| 2578 | 2580 |
| 2579 void SSLClientSocketNSS::Core::RecordChannelIDSupportOnNetworkTaskRunner( | 2581 void SSLClientSocketNSS::Core::RecordChannelIDSupportOnNetworkTaskRunner( |
| 2580 bool negotiated_channel_id, | 2582 bool negotiated_channel_id, |
| 2581 bool channel_id_enabled, | 2583 bool channel_id_enabled, |
| 2582 bool supports_ecc) const { | 2584 bool supports_ecc) const { |
| 2583 DCHECK(OnNetworkTaskRunner()); | 2585 DCHECK(OnNetworkTaskRunner()); |
| 2584 | 2586 |
| 2585 RecordChannelIDSupport(server_bound_cert_service_, | 2587 RecordChannelIDSupport(server_bound_cert_service_, |
| 2586 negotiated_channel_id, | 2588 negotiated_channel_id, |
| 2587 channel_id_enabled, | 2589 channel_id_enabled, |
| 2588 supports_ecc); | 2590 supports_ecc); |
| 2589 } | 2591 } |
| 2590 | 2592 |
| 2591 int SSLClientSocketNSS::Core::DoBufferRecv(IOBuffer* read_buffer, int len) { | 2593 int SSLClientSocketNSS::Core::DoBufferRecv(IOBuffer* read_buffer, int len) { |
| 2592 DCHECK(OnNetworkTaskRunner()); | 2594 DCHECK(OnNetworkTaskRunner()); |
| 2593 DCHECK_GT(len, 0); | 2595 DCHECK_GT(len, 0); |
| 2594 | 2596 |
| 2595 if (detached_) | 2597 if (detached_) |
| 2596 return ERR_ABORTED; | 2598 return ERR_ABORTED; |
| 2597 | 2599 |
| 2598 int rv = transport_->socket()->Read( | 2600 int rv = transport_->socket()->Read( |
| 2599 read_buffer, len, | 2601 read_buffer, |
| 2600 base::Bind(&Core::BufferRecvComplete, base::Unretained(this), | 2602 len, |
| 2603 base::Bind(&Core::BufferRecvComplete, |
| 2604 base::Unretained(this), |
| 2601 scoped_refptr<IOBuffer>(read_buffer))); | 2605 scoped_refptr<IOBuffer>(read_buffer))); |
| 2602 | 2606 |
| 2603 if (!OnNSSTaskRunner() && rv != ERR_IO_PENDING) { | 2607 if (!OnNSSTaskRunner() && rv != ERR_IO_PENDING) { |
| 2604 nss_task_runner_->PostTask( | 2608 nss_task_runner_->PostTask(FROM_HERE, |
| 2605 FROM_HERE, base::Bind(&Core::BufferRecvComplete, this, | 2609 base::Bind(&Core::BufferRecvComplete, |
| 2606 scoped_refptr<IOBuffer>(read_buffer), rv)); | 2610 this, |
| 2611 scoped_refptr<IOBuffer>(read_buffer), |
| 2612 rv)); |
| 2607 return rv; | 2613 return rv; |
| 2608 } | 2614 } |
| 2609 | 2615 |
| 2610 return rv; | 2616 return rv; |
| 2611 } | 2617 } |
| 2612 | 2618 |
| 2613 int SSLClientSocketNSS::Core::DoBufferSend(IOBuffer* send_buffer, int len) { | 2619 int SSLClientSocketNSS::Core::DoBufferSend(IOBuffer* send_buffer, int len) { |
| 2614 DCHECK(OnNetworkTaskRunner()); | 2620 DCHECK(OnNetworkTaskRunner()); |
| 2615 DCHECK_GT(len, 0); | 2621 DCHECK_GT(len, 0); |
| 2616 | 2622 |
| 2617 if (detached_) | 2623 if (detached_) |
| 2618 return ERR_ABORTED; | 2624 return ERR_ABORTED; |
| 2619 | 2625 |
| 2620 int rv = transport_->socket()->Write( | 2626 int rv = transport_->socket()->Write( |
| 2621 send_buffer, len, | 2627 send_buffer, |
| 2622 base::Bind(&Core::BufferSendComplete, | 2628 len, |
| 2623 base::Unretained(this))); | 2629 base::Bind(&Core::BufferSendComplete, base::Unretained(this))); |
| 2624 | 2630 |
| 2625 if (!OnNSSTaskRunner() && rv != ERR_IO_PENDING) { | 2631 if (!OnNSSTaskRunner() && rv != ERR_IO_PENDING) { |
| 2626 nss_task_runner_->PostTask( | 2632 nss_task_runner_->PostTask(FROM_HERE, |
| 2627 FROM_HERE, | 2633 base::Bind(&Core::BufferSendComplete, this, rv)); |
| 2628 base::Bind(&Core::BufferSendComplete, this, rv)); | |
| 2629 return rv; | 2634 return rv; |
| 2630 } | 2635 } |
| 2631 | 2636 |
| 2632 return rv; | 2637 return rv; |
| 2633 } | 2638 } |
| 2634 | 2639 |
| 2635 int SSLClientSocketNSS::Core::DoGetDomainBoundCert(const std::string& host) { | 2640 int SSLClientSocketNSS::Core::DoGetDomainBoundCert(const std::string& host) { |
| 2636 DCHECK(OnNetworkTaskRunner()); | 2641 DCHECK(OnNetworkTaskRunner()); |
| 2637 | 2642 |
| 2638 if (detached_) | 2643 if (detached_) |
| 2639 return ERR_FAILED; | 2644 return ERR_FAILED; |
| 2640 | 2645 |
| 2641 weak_net_log_->BeginEvent(NetLog::TYPE_SSL_GET_DOMAIN_BOUND_CERT); | 2646 weak_net_log_->BeginEvent(NetLog::TYPE_SSL_GET_DOMAIN_BOUND_CERT); |
| 2642 | 2647 |
| 2643 int rv = server_bound_cert_service_->GetOrCreateDomainBoundCert( | 2648 int rv = server_bound_cert_service_->GetOrCreateDomainBoundCert( |
| 2644 host, | 2649 host, |
| 2645 &domain_bound_private_key_, | 2650 &domain_bound_private_key_, |
| 2646 &domain_bound_cert_, | 2651 &domain_bound_cert_, |
| 2647 base::Bind(&Core::OnGetDomainBoundCertComplete, base::Unretained(this)), | 2652 base::Bind(&Core::OnGetDomainBoundCertComplete, base::Unretained(this)), |
| 2648 &domain_bound_cert_request_handle_); | 2653 &domain_bound_cert_request_handle_); |
| 2649 | 2654 |
| 2650 if (rv != ERR_IO_PENDING && !OnNSSTaskRunner()) { | 2655 if (rv != ERR_IO_PENDING && !OnNSSTaskRunner()) { |
| 2651 nss_task_runner_->PostTask( | 2656 nss_task_runner_->PostTask( |
| 2652 FROM_HERE, | 2657 FROM_HERE, base::Bind(&Core::OnHandshakeIOComplete, this, rv)); |
| 2653 base::Bind(&Core::OnHandshakeIOComplete, this, rv)); | |
| 2654 return ERR_IO_PENDING; | 2658 return ERR_IO_PENDING; |
| 2655 } | 2659 } |
| 2656 | 2660 |
| 2657 return rv; | 2661 return rv; |
| 2658 } | 2662 } |
| 2659 | 2663 |
| 2660 void SSLClientSocketNSS::Core::OnHandshakeStateUpdated( | 2664 void SSLClientSocketNSS::Core::OnHandshakeStateUpdated( |
| 2661 const HandshakeState& state) { | 2665 const HandshakeState& state) { |
| 2662 DCHECK(OnNetworkTaskRunner()); | 2666 DCHECK(OnNetworkTaskRunner()); |
| 2663 network_handshake_state_ = state; | 2667 network_handshake_state_ = state; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2724 DoConnectCallback(rv); | 2728 DoConnectCallback(rv); |
| 2725 } | 2729 } |
| 2726 | 2730 |
| 2727 void SSLClientSocketNSS::Core::OnGetDomainBoundCertComplete(int result) { | 2731 void SSLClientSocketNSS::Core::OnGetDomainBoundCertComplete(int result) { |
| 2728 DVLOG(1) << __FUNCTION__ << " " << result; | 2732 DVLOG(1) << __FUNCTION__ << " " << result; |
| 2729 DCHECK(OnNetworkTaskRunner()); | 2733 DCHECK(OnNetworkTaskRunner()); |
| 2730 | 2734 |
| 2731 OnHandshakeIOComplete(result); | 2735 OnHandshakeIOComplete(result); |
| 2732 } | 2736 } |
| 2733 | 2737 |
| 2734 void SSLClientSocketNSS::Core::BufferRecvComplete( | 2738 void SSLClientSocketNSS::Core::BufferRecvComplete(IOBuffer* read_buffer, |
| 2735 IOBuffer* read_buffer, | 2739 int result) { |
| 2736 int result) { | |
| 2737 DCHECK(read_buffer); | 2740 DCHECK(read_buffer); |
| 2738 | 2741 |
| 2739 if (!OnNSSTaskRunner()) { | 2742 if (!OnNSSTaskRunner()) { |
| 2740 if (detached_) | 2743 if (detached_) |
| 2741 return; | 2744 return; |
| 2742 | 2745 |
| 2743 nss_task_runner_->PostTask( | 2746 nss_task_runner_->PostTask(FROM_HERE, |
| 2744 FROM_HERE, base::Bind(&Core::BufferRecvComplete, this, | 2747 base::Bind(&Core::BufferRecvComplete, |
| 2745 scoped_refptr<IOBuffer>(read_buffer), result)); | 2748 this, |
| 2749 scoped_refptr<IOBuffer>(read_buffer), |
| 2750 result)); |
| 2746 return; | 2751 return; |
| 2747 } | 2752 } |
| 2748 | 2753 |
| 2749 DCHECK(OnNSSTaskRunner()); | 2754 DCHECK(OnNSSTaskRunner()); |
| 2750 | 2755 |
| 2751 if (result > 0) { | 2756 if (result > 0) { |
| 2752 char* buf; | 2757 char* buf; |
| 2753 int nb = memio_GetReadParams(nss_bufs_, &buf); | 2758 int nb = memio_GetReadParams(nss_bufs_, &buf); |
| 2754 CHECK_GE(nb, result); | 2759 CHECK_GE(nb, result); |
| 2755 memcpy(buf, read_buffer->data(), result); | 2760 memcpy(buf, read_buffer->data(), result); |
| 2756 } else if (result == 0) { | 2761 } else if (result == 0) { |
| 2757 transport_recv_eof_ = true; | 2762 transport_recv_eof_ = true; |
| 2758 } | 2763 } |
| 2759 | 2764 |
| 2760 memio_PutReadResult(nss_bufs_, MapErrorToNSS(result)); | 2765 memio_PutReadResult(nss_bufs_, MapErrorToNSS(result)); |
| 2761 transport_recv_busy_ = false; | 2766 transport_recv_busy_ = false; |
| 2762 OnRecvComplete(result); | 2767 OnRecvComplete(result); |
| 2763 } | 2768 } |
| 2764 | 2769 |
| 2765 void SSLClientSocketNSS::Core::PostOrRunCallback( | 2770 void SSLClientSocketNSS::Core::PostOrRunCallback( |
| 2766 const tracked_objects::Location& location, | 2771 const tracked_objects::Location& location, |
| 2767 const base::Closure& task) { | 2772 const base::Closure& task) { |
| 2768 if (!OnNetworkTaskRunner()) { | 2773 if (!OnNetworkTaskRunner()) { |
| 2769 network_task_runner_->PostTask( | 2774 network_task_runner_->PostTask( |
| 2770 FROM_HERE, | 2775 FROM_HERE, base::Bind(&Core::PostOrRunCallback, this, location, task)); |
| 2771 base::Bind(&Core::PostOrRunCallback, this, location, task)); | |
| 2772 return; | 2776 return; |
| 2773 } | 2777 } |
| 2774 | 2778 |
| 2775 if (detached_ || task.is_null()) | 2779 if (detached_ || task.is_null()) |
| 2776 return; | 2780 return; |
| 2777 task.Run(); | 2781 task.Run(); |
| 2778 } | 2782 } |
| 2779 | 2783 |
| 2780 void SSLClientSocketNSS::Core::AddCertProvidedEvent(int cert_count) { | 2784 void SSLClientSocketNSS::Core::AddCertProvidedEvent(int cert_count) { |
| 2781 PostOrRunCallback( | 2785 PostOrRunCallback( |
| 2782 FROM_HERE, | 2786 FROM_HERE, |
| 2783 base::Bind(&AddLogEventWithCallback, weak_net_log_, | 2787 base::Bind(&AddLogEventWithCallback, |
| 2788 weak_net_log_, |
| 2784 NetLog::TYPE_SSL_CLIENT_CERT_PROVIDED, | 2789 NetLog::TYPE_SSL_CLIENT_CERT_PROVIDED, |
| 2785 NetLog::IntegerCallback("cert_count", cert_count))); | 2790 NetLog::IntegerCallback("cert_count", cert_count))); |
| 2786 } | 2791 } |
| 2787 | 2792 |
| 2788 void SSLClientSocketNSS::Core::SetChannelIDProvided() { | 2793 void SSLClientSocketNSS::Core::SetChannelIDProvided() { |
| 2789 PostOrRunCallback( | 2794 PostOrRunCallback( |
| 2790 FROM_HERE, base::Bind(&AddLogEvent, weak_net_log_, | 2795 FROM_HERE, |
| 2791 NetLog::TYPE_SSL_CHANNEL_ID_PROVIDED)); | 2796 base::Bind( |
| 2797 &AddLogEvent, weak_net_log_, NetLog::TYPE_SSL_CHANNEL_ID_PROVIDED)); |
| 2792 nss_handshake_state_.channel_id_sent = true; | 2798 nss_handshake_state_.channel_id_sent = true; |
| 2793 // Update the network task runner's view of the handshake state now that | 2799 // Update the network task runner's view of the handshake state now that |
| 2794 // channel id has been sent. | 2800 // channel id has been sent. |
| 2795 PostOrRunCallback( | 2801 PostOrRunCallback( |
| 2796 FROM_HERE, base::Bind(&Core::OnHandshakeStateUpdated, this, | 2802 FROM_HERE, |
| 2797 nss_handshake_state_)); | 2803 base::Bind(&Core::OnHandshakeStateUpdated, this, nss_handshake_state_)); |
| 2798 } | 2804 } |
| 2799 | 2805 |
| 2800 SSLClientSocketNSS::SSLClientSocketNSS( | 2806 SSLClientSocketNSS::SSLClientSocketNSS( |
| 2801 base::SequencedTaskRunner* nss_task_runner, | 2807 base::SequencedTaskRunner* nss_task_runner, |
| 2802 scoped_ptr<ClientSocketHandle> transport_socket, | 2808 scoped_ptr<ClientSocketHandle> transport_socket, |
| 2803 const HostPortPair& host_and_port, | 2809 const HostPortPair& host_and_port, |
| 2804 const SSLConfig& ssl_config, | 2810 const SSLConfig& ssl_config, |
| 2805 const SSLClientSocketContext& context) | 2811 const SSLClientSocketContext& context) |
| 2806 : nss_task_runner_(nss_task_runner), | 2812 : nss_task_runner_(nss_task_runner), |
| 2807 transport_(transport_socket.Pass()), | 2813 transport_(transport_socket.Pass()), |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2844 if (core_->state().server_cert_chain.empty() || | 2850 if (core_->state().server_cert_chain.empty() || |
| 2845 !core_->state().server_cert_chain[0]) { | 2851 !core_->state().server_cert_chain[0]) { |
| 2846 return false; | 2852 return false; |
| 2847 } | 2853 } |
| 2848 | 2854 |
| 2849 ssl_info->cert_status = server_cert_verify_result_.cert_status; | 2855 ssl_info->cert_status = server_cert_verify_result_.cert_status; |
| 2850 ssl_info->cert = server_cert_verify_result_.verified_cert; | 2856 ssl_info->cert = server_cert_verify_result_.verified_cert; |
| 2851 | 2857 |
| 2852 AddSCTInfoToSSLInfo(ssl_info); | 2858 AddSCTInfoToSSLInfo(ssl_info); |
| 2853 | 2859 |
| 2854 ssl_info->connection_status = | 2860 ssl_info->connection_status = core_->state().ssl_connection_status; |
| 2855 core_->state().ssl_connection_status; | |
| 2856 ssl_info->public_key_hashes = server_cert_verify_result_.public_key_hashes; | 2861 ssl_info->public_key_hashes = server_cert_verify_result_.public_key_hashes; |
| 2857 ssl_info->is_issued_by_known_root = | 2862 ssl_info->is_issued_by_known_root = |
| 2858 server_cert_verify_result_.is_issued_by_known_root; | 2863 server_cert_verify_result_.is_issued_by_known_root; |
| 2859 ssl_info->client_cert_sent = | 2864 ssl_info->client_cert_sent = |
| 2860 ssl_config_.send_client_cert && ssl_config_.client_cert.get(); | 2865 ssl_config_.send_client_cert && ssl_config_.client_cert.get(); |
| 2861 ssl_info->channel_id_sent = WasChannelIDSent(); | 2866 ssl_info->channel_id_sent = WasChannelIDSent(); |
| 2862 ssl_info->pinning_failure_log = pinning_failure_log_; | 2867 ssl_info->pinning_failure_log = pinning_failure_log_; |
| 2863 | 2868 |
| 2864 PRUint16 cipher_suite = SSLConnectionStatusToCipherSuite( | 2869 PRUint16 cipher_suite = |
| 2865 core_->state().ssl_connection_status); | 2870 SSLConnectionStatusToCipherSuite(core_->state().ssl_connection_status); |
| 2866 SSLCipherSuiteInfo cipher_info; | 2871 SSLCipherSuiteInfo cipher_info; |
| 2867 SECStatus ok = SSL_GetCipherSuiteInfo(cipher_suite, | 2872 SECStatus ok = |
| 2868 &cipher_info, sizeof(cipher_info)); | 2873 SSL_GetCipherSuiteInfo(cipher_suite, &cipher_info, sizeof(cipher_info)); |
| 2869 if (ok == SECSuccess) { | 2874 if (ok == SECSuccess) { |
| 2870 ssl_info->security_bits = cipher_info.effectiveKeyBits; | 2875 ssl_info->security_bits = cipher_info.effectiveKeyBits; |
| 2871 } else { | 2876 } else { |
| 2872 ssl_info->security_bits = -1; | 2877 ssl_info->security_bits = -1; |
| 2873 LOG(DFATAL) << "SSL_GetCipherSuiteInfo returned " << PR_GetError() | 2878 LOG(DFATAL) << "SSL_GetCipherSuiteInfo returned " << PR_GetError() |
| 2874 << " for cipherSuite " << cipher_suite; | 2879 << " for cipherSuite " << cipher_suite; |
| 2875 } | 2880 } |
| 2876 | 2881 |
| 2877 ssl_info->handshake_type = core_->state().resumed_handshake ? | 2882 ssl_info->handshake_type = core_->state().resumed_handshake |
| 2878 SSLInfo::HANDSHAKE_RESUME : SSLInfo::HANDSHAKE_FULL; | 2883 ? SSLInfo::HANDSHAKE_RESUME |
| 2884 : SSLInfo::HANDSHAKE_FULL; |
| 2879 | 2885 |
| 2880 LeaveFunction(""); | 2886 LeaveFunction(""); |
| 2881 return true; | 2887 return true; |
| 2882 } | 2888 } |
| 2883 | 2889 |
| 2884 void SSLClientSocketNSS::GetSSLCertRequestInfo( | 2890 void SSLClientSocketNSS::GetSSLCertRequestInfo( |
| 2885 SSLCertRequestInfo* cert_request_info) { | 2891 SSLCertRequestInfo* cert_request_info) { |
| 2886 EnterFunction(""); | 2892 EnterFunction(""); |
| 2887 cert_request_info->host_and_port = host_and_port_; | 2893 cert_request_info->host_and_port = host_and_port_; |
| 2888 cert_request_info->cert_authorities = core_->state().cert_authorities; | 2894 cert_request_info->cert_authorities = core_->state().cert_authorities; |
| 2889 LeaveFunction(""); | 2895 LeaveFunction(""); |
| 2890 } | 2896 } |
| 2891 | 2897 |
| 2892 int SSLClientSocketNSS::ExportKeyingMaterial(const base::StringPiece& label, | 2898 int SSLClientSocketNSS::ExportKeyingMaterial(const base::StringPiece& label, |
| 2893 bool has_context, | 2899 bool has_context, |
| 2894 const base::StringPiece& context, | 2900 const base::StringPiece& context, |
| 2895 unsigned char* out, | 2901 unsigned char* out, |
| 2896 unsigned int outlen) { | 2902 unsigned int outlen) { |
| 2897 if (!IsConnected()) | 2903 if (!IsConnected()) |
| 2898 return ERR_SOCKET_NOT_CONNECTED; | 2904 return ERR_SOCKET_NOT_CONNECTED; |
| 2899 | 2905 |
| 2900 // SSL_ExportKeyingMaterial may block the current thread if |core_| is in | 2906 // SSL_ExportKeyingMaterial may block the current thread if |core_| is in |
| 2901 // the midst of a handshake. | 2907 // the midst of a handshake. |
| 2902 SECStatus result = SSL_ExportKeyingMaterial( | 2908 SECStatus result = SSL_ExportKeyingMaterial( |
| 2903 nss_fd_, label.data(), label.size(), has_context, | 2909 nss_fd_, |
| 2910 label.data(), |
| 2911 label.size(), |
| 2912 has_context, |
| 2904 reinterpret_cast<const unsigned char*>(context.data()), | 2913 reinterpret_cast<const unsigned char*>(context.data()), |
| 2905 context.length(), out, outlen); | 2914 context.length(), |
| 2915 out, |
| 2916 outlen); |
| 2906 if (result != SECSuccess) { | 2917 if (result != SECSuccess) { |
| 2907 LogFailedNSSFunction(net_log_, "SSL_ExportKeyingMaterial", ""); | 2918 LogFailedNSSFunction(net_log_, "SSL_ExportKeyingMaterial", ""); |
| 2908 return MapNSSError(PORT_GetError()); | 2919 return MapNSSError(PORT_GetError()); |
| 2909 } | 2920 } |
| 2910 return OK; | 2921 return OK; |
| 2911 } | 2922 } |
| 2912 | 2923 |
| 2913 int SSLClientSocketNSS::GetTLSUniqueChannelBinding(std::string* out) { | 2924 int SSLClientSocketNSS::GetTLSUniqueChannelBinding(std::string* out) { |
| 2914 if (!IsConnected()) | 2925 if (!IsConnected()) |
| 2915 return ERR_SOCKET_NOT_CONNECTED; | 2926 return ERR_SOCKET_NOT_CONNECTED; |
| 2916 unsigned char buf[64]; | 2927 unsigned char buf[64]; |
| 2917 unsigned int len; | 2928 unsigned int len; |
| 2918 SECStatus result = SSL_GetChannelBinding(nss_fd_, | 2929 SECStatus result = SSL_GetChannelBinding( |
| 2919 SSL_CHANNEL_BINDING_TLS_UNIQUE, | 2930 nss_fd_, SSL_CHANNEL_BINDING_TLS_UNIQUE, buf, &len, arraysize(buf)); |
| 2920 buf, &len, arraysize(buf)); | |
| 2921 if (result != SECSuccess) { | 2931 if (result != SECSuccess) { |
| 2922 LogFailedNSSFunction(net_log_, "SSL_GetChannelBinding", ""); | 2932 LogFailedNSSFunction(net_log_, "SSL_GetChannelBinding", ""); |
| 2923 return MapNSSError(PORT_GetError()); | 2933 return MapNSSError(PORT_GetError()); |
| 2924 } | 2934 } |
| 2925 out->assign(reinterpret_cast<char*>(buf), len); | 2935 out->assign(reinterpret_cast<char*>(buf), len); |
| 2926 return OK; | 2936 return OK; |
| 2927 } | 2937 } |
| 2928 | 2938 |
| 2929 SSLClientSocket::NextProtoStatus | 2939 SSLClientSocket::NextProtoStatus SSLClientSocketNSS::GetNextProto( |
| 2930 SSLClientSocketNSS::GetNextProto(std::string* proto, | 2940 std::string* proto, |
| 2931 std::string* server_protos) { | 2941 std::string* server_protos) { |
| 2932 *proto = core_->state().next_proto; | 2942 *proto = core_->state().next_proto; |
| 2933 *server_protos = core_->state().server_protos; | 2943 *server_protos = core_->state().server_protos; |
| 2934 return core_->state().next_proto_status; | 2944 return core_->state().next_proto_status; |
| 2935 } | 2945 } |
| 2936 | 2946 |
| 2937 int SSLClientSocketNSS::Connect(const CompletionCallback& callback) { | 2947 int SSLClientSocketNSS::Connect(const CompletionCallback& callback) { |
| 2938 EnterFunction(""); | 2948 EnterFunction(""); |
| 2939 DCHECK(transport_.get()); | 2949 DCHECK(transport_.get()); |
| 2940 // It is an error to create an SSLClientSocket whose context has no | 2950 // It is an error to create an SSLClientSocket whose context has no |
| 2941 // TransportSecurityState. | 2951 // TransportSecurityState. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2985 CHECK(CalledOnValidThread()); | 2995 CHECK(CalledOnValidThread()); |
| 2986 | 2996 |
| 2987 // Shut down anything that may call us back. | 2997 // Shut down anything that may call us back. |
| 2988 core_->Detach(); | 2998 core_->Detach(); |
| 2989 verifier_.reset(); | 2999 verifier_.reset(); |
| 2990 transport_->socket()->Disconnect(); | 3000 transport_->socket()->Disconnect(); |
| 2991 | 3001 |
| 2992 // Reset object state. | 3002 // Reset object state. |
| 2993 user_connect_callback_.Reset(); | 3003 user_connect_callback_.Reset(); |
| 2994 server_cert_verify_result_.Reset(); | 3004 server_cert_verify_result_.Reset(); |
| 2995 completed_handshake_ = false; | 3005 completed_handshake_ = false; |
| 2996 start_cert_verification_time_ = base::TimeTicks(); | 3006 start_cert_verification_time_ = base::TimeTicks(); |
| 2997 InitCore(); | 3007 InitCore(); |
| 2998 | 3008 |
| 2999 LeaveFunction(""); | 3009 LeaveFunction(""); |
| 3000 } | 3010 } |
| 3001 | 3011 |
| 3002 bool SSLClientSocketNSS::IsConnected() const { | 3012 bool SSLClientSocketNSS::IsConnected() const { |
| 3003 EnterFunction(""); | 3013 EnterFunction(""); |
| 3004 bool ret = completed_handshake_ && | 3014 bool ret = completed_handshake_ && |
| 3005 (core_->HasPendingAsyncOperation() || | 3015 (core_->HasPendingAsyncOperation() || |
| 3006 (core_->IsConnected() && core_->HasUnhandledReceivedData()) || | 3016 (core_->IsConnected() && core_->HasUnhandledReceivedData()) || |
| 3007 transport_->socket()->IsConnected()); | 3017 transport_->socket()->IsConnected()); |
| 3008 LeaveFunction(""); | 3018 LeaveFunction(""); |
| 3009 return ret; | 3019 return ret; |
| 3010 } | 3020 } |
| 3011 | 3021 |
| 3012 bool SSLClientSocketNSS::IsConnectedAndIdle() const { | 3022 bool SSLClientSocketNSS::IsConnectedAndIdle() const { |
| 3013 EnterFunction(""); | 3023 EnterFunction(""); |
| 3014 bool ret = completed_handshake_ && | 3024 bool ret = completed_handshake_ && !core_->HasPendingAsyncOperation() && |
| 3015 !core_->HasPendingAsyncOperation() && | |
| 3016 !(core_->IsConnected() && core_->HasUnhandledReceivedData()) && | 3025 !(core_->IsConnected() && core_->HasUnhandledReceivedData()) && |
| 3017 transport_->socket()->IsConnectedAndIdle(); | 3026 transport_->socket()->IsConnectedAndIdle(); |
| 3018 LeaveFunction(""); | 3027 LeaveFunction(""); |
| 3019 return ret; | 3028 return ret; |
| 3020 } | 3029 } |
| 3021 | 3030 |
| 3022 int SSLClientSocketNSS::GetPeerAddress(IPEndPoint* address) const { | 3031 int SSLClientSocketNSS::GetPeerAddress(IPEndPoint* address) const { |
| 3023 return transport_->socket()->GetPeerAddress(address); | 3032 return transport_->socket()->GetPeerAddress(address); |
| 3024 } | 3033 } |
| 3025 | 3034 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 3054 } | 3063 } |
| 3055 | 3064 |
| 3056 bool SSLClientSocketNSS::UsingTCPFastOpen() const { | 3065 bool SSLClientSocketNSS::UsingTCPFastOpen() const { |
| 3057 if (transport_.get() && transport_->socket()) { | 3066 if (transport_.get() && transport_->socket()) { |
| 3058 return transport_->socket()->UsingTCPFastOpen(); | 3067 return transport_->socket()->UsingTCPFastOpen(); |
| 3059 } | 3068 } |
| 3060 NOTREACHED(); | 3069 NOTREACHED(); |
| 3061 return false; | 3070 return false; |
| 3062 } | 3071 } |
| 3063 | 3072 |
| 3064 int SSLClientSocketNSS::Read(IOBuffer* buf, int buf_len, | 3073 int SSLClientSocketNSS::Read(IOBuffer* buf, |
| 3074 int buf_len, |
| 3065 const CompletionCallback& callback) { | 3075 const CompletionCallback& callback) { |
| 3066 DCHECK(core_.get()); | 3076 DCHECK(core_.get()); |
| 3067 DCHECK(!callback.is_null()); | 3077 DCHECK(!callback.is_null()); |
| 3068 | 3078 |
| 3069 EnterFunction(buf_len); | 3079 EnterFunction(buf_len); |
| 3070 int rv = core_->Read(buf, buf_len, callback); | 3080 int rv = core_->Read(buf, buf_len, callback); |
| 3071 LeaveFunction(rv); | 3081 LeaveFunction(rv); |
| 3072 | 3082 |
| 3073 return rv; | 3083 return rv; |
| 3074 } | 3084 } |
| 3075 | 3085 |
| 3076 int SSLClientSocketNSS::Write(IOBuffer* buf, int buf_len, | 3086 int SSLClientSocketNSS::Write(IOBuffer* buf, |
| 3087 int buf_len, |
| 3077 const CompletionCallback& callback) { | 3088 const CompletionCallback& callback) { |
| 3078 DCHECK(core_.get()); | 3089 DCHECK(core_.get()); |
| 3079 DCHECK(!callback.is_null()); | 3090 DCHECK(!callback.is_null()); |
| 3080 | 3091 |
| 3081 EnterFunction(buf_len); | 3092 EnterFunction(buf_len); |
| 3082 int rv = core_->Write(buf, buf_len, callback); | 3093 int rv = core_->Write(buf, buf_len, callback); |
| 3083 LeaveFunction(rv); | 3094 LeaveFunction(rv); |
| 3084 | 3095 |
| 3085 return rv; | 3096 return rv; |
| 3086 } | 3097 } |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3176 if (ssl_config_.version_fallback) { | 3187 if (ssl_config_.version_fallback) { |
| 3177 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_FALLBACK_SCSV, PR_TRUE); | 3188 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_FALLBACK_SCSV, PR_TRUE); |
| 3178 if (rv != SECSuccess) { | 3189 if (rv != SECSuccess) { |
| 3179 LogFailedNSSFunction( | 3190 LogFailedNSSFunction( |
| 3180 net_log_, "SSL_OptionSet", "SSL_ENABLE_FALLBACK_SCSV"); | 3191 net_log_, "SSL_OptionSet", "SSL_ENABLE_FALLBACK_SCSV"); |
| 3181 } | 3192 } |
| 3182 } | 3193 } |
| 3183 | 3194 |
| 3184 for (std::vector<uint16>::const_iterator it = | 3195 for (std::vector<uint16>::const_iterator it = |
| 3185 ssl_config_.disabled_cipher_suites.begin(); | 3196 ssl_config_.disabled_cipher_suites.begin(); |
| 3186 it != ssl_config_.disabled_cipher_suites.end(); ++it) { | 3197 it != ssl_config_.disabled_cipher_suites.end(); |
| 3198 ++it) { |
| 3187 // This will fail if the specified cipher is not implemented by NSS, but | 3199 // This will fail if the specified cipher is not implemented by NSS, but |
| 3188 // the failure is harmless. | 3200 // the failure is harmless. |
| 3189 SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE); | 3201 SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE); |
| 3190 } | 3202 } |
| 3191 | 3203 |
| 3192 // Support RFC 5077 | 3204 // Support RFC 5077 |
| 3193 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_TRUE); | 3205 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_TRUE); |
| 3194 if (rv != SECSuccess) { | 3206 if (rv != SECSuccess) { |
| 3195 LogFailedNSSFunction( | 3207 LogFailedNSSFunction( |
| 3196 net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS"); | 3208 net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS"); |
| 3197 } | 3209 } |
| 3198 | 3210 |
| 3199 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_FALSE_START, | 3211 rv = SSL_OptionSet( |
| 3200 ssl_config_.false_start_enabled); | 3212 nss_fd_, SSL_ENABLE_FALSE_START, ssl_config_.false_start_enabled); |
| 3201 if (rv != SECSuccess) | 3213 if (rv != SECSuccess) |
| 3202 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_FALSE_START"); | 3214 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_FALSE_START"); |
| 3203 | 3215 |
| 3204 // We allow servers to request renegotiation. Since we're a client, | 3216 // We allow servers to request renegotiation. Since we're a client, |
| 3205 // prohibiting this is rather a waste of time. Only servers are in a | 3217 // prohibiting this is rather a waste of time. Only servers are in a |
| 3206 // position to prevent renegotiation attacks. | 3218 // position to prevent renegotiation attacks. |
| 3207 // http://extendedsubset.com/?p=8 | 3219 // http://extendedsubset.com/?p=8 |
| 3208 | 3220 |
| 3209 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION, | 3221 rv = SSL_OptionSet( |
| 3210 SSL_RENEGOTIATE_TRANSITIONAL); | 3222 nss_fd_, SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_TRANSITIONAL); |
| 3211 if (rv != SECSuccess) { | 3223 if (rv != SECSuccess) { |
| 3212 LogFailedNSSFunction( | 3224 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_RENEGOTIATION"); |
| 3213 net_log_, "SSL_OptionSet", "SSL_ENABLE_RENEGOTIATION"); | |
| 3214 } | 3225 } |
| 3215 | 3226 |
| 3216 rv = SSL_OptionSet(nss_fd_, SSL_CBC_RANDOM_IV, PR_TRUE); | 3227 rv = SSL_OptionSet(nss_fd_, SSL_CBC_RANDOM_IV, PR_TRUE); |
| 3217 if (rv != SECSuccess) | 3228 if (rv != SECSuccess) |
| 3218 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_CBC_RANDOM_IV"); | 3229 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_CBC_RANDOM_IV"); |
| 3219 | 3230 |
| 3220 // Added in NSS 3.15 | 3231 // Added in NSS 3.15 |
| 3221 #ifdef SSL_ENABLE_OCSP_STAPLING | 3232 #ifdef SSL_ENABLE_OCSP_STAPLING |
| 3222 // Request OCSP stapling even on platforms that don't support it, in | 3233 // Request OCSP stapling even on platforms that don't support it, in |
| 3223 // order to extract Certificate Transparency information. | 3234 // order to extract Certificate Transparency information. |
| 3224 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, | 3235 rv = SSL_OptionSet(nss_fd_, |
| 3236 SSL_ENABLE_OCSP_STAPLING, |
| 3225 (IsOCSPStaplingSupported() || | 3237 (IsOCSPStaplingSupported() || |
| 3226 ssl_config_.signed_cert_timestamps_enabled)); | 3238 ssl_config_.signed_cert_timestamps_enabled)); |
| 3227 if (rv != SECSuccess) { | 3239 if (rv != SECSuccess) { |
| 3228 LogFailedNSSFunction(net_log_, "SSL_OptionSet", | 3240 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_OCSP_STAPLING"); |
| 3229 "SSL_ENABLE_OCSP_STAPLING"); | |
| 3230 } | 3241 } |
| 3231 #endif | 3242 #endif |
| 3232 | 3243 |
| 3233 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, | 3244 rv = SSL_OptionSet(nss_fd_, |
| 3245 SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, |
| 3234 ssl_config_.signed_cert_timestamps_enabled); | 3246 ssl_config_.signed_cert_timestamps_enabled); |
| 3235 if (rv != SECSuccess) { | 3247 if (rv != SECSuccess) { |
| 3236 LogFailedNSSFunction(net_log_, "SSL_OptionSet", | 3248 LogFailedNSSFunction( |
| 3237 "SSL_ENABLE_SIGNED_CERT_TIMESTAMPS"); | 3249 net_log_, "SSL_OptionSet", "SSL_ENABLE_SIGNED_CERT_TIMESTAMPS"); |
| 3238 } | 3250 } |
| 3239 | 3251 |
| 3240 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); | 3252 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); |
| 3241 if (rv != SECSuccess) { | 3253 if (rv != SECSuccess) { |
| 3242 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); | 3254 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); |
| 3243 return ERR_UNEXPECTED; | 3255 return ERR_UNEXPECTED; |
| 3244 } | 3256 } |
| 3245 | 3257 |
| 3246 if (!core_->Init(nss_fd_, nss_bufs)) | 3258 if (!core_->Init(nss_fd_, nss_bufs)) |
| 3247 return ERR_UNEXPECTED; | 3259 return ERR_UNEXPECTED; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3262 if (err != OK) | 3274 if (err != OK) |
| 3263 return err; | 3275 return err; |
| 3264 | 3276 |
| 3265 SockaddrStorage storage; | 3277 SockaddrStorage storage; |
| 3266 if (!peer_address.ToSockAddr(storage.addr, &storage.addr_len)) | 3278 if (!peer_address.ToSockAddr(storage.addr, &storage.addr_len)) |
| 3267 return ERR_ADDRESS_INVALID; | 3279 return ERR_ADDRESS_INVALID; |
| 3268 | 3280 |
| 3269 PRNetAddr peername; | 3281 PRNetAddr peername; |
| 3270 memset(&peername, 0, sizeof(peername)); | 3282 memset(&peername, 0, sizeof(peername)); |
| 3271 DCHECK_LE(static_cast<size_t>(storage.addr_len), sizeof(peername)); | 3283 DCHECK_LE(static_cast<size_t>(storage.addr_len), sizeof(peername)); |
| 3272 size_t len = std::min(static_cast<size_t>(storage.addr_len), | 3284 size_t len = |
| 3273 sizeof(peername)); | 3285 std::min(static_cast<size_t>(storage.addr_len), sizeof(peername)); |
| 3274 memcpy(&peername, storage.addr, len); | 3286 memcpy(&peername, storage.addr, len); |
| 3275 | 3287 |
| 3276 // Adjust the address family field for BSD, whose sockaddr | 3288 // Adjust the address family field for BSD, whose sockaddr |
| 3277 // structure has a one-byte length and one-byte address family | 3289 // structure has a one-byte length and one-byte address family |
| 3278 // field at the beginning. PRNetAddr has a two-byte address | 3290 // field at the beginning. PRNetAddr has a two-byte address |
| 3279 // family field at the beginning. | 3291 // family field at the beginning. |
| 3280 peername.raw.family = storage.addr->sa_family; | 3292 peername.raw.family = storage.addr->sa_family; |
| 3281 | 3293 |
| 3282 memio_SetPeerName(nss_fd_, &peername); | 3294 memio_SetPeerName(nss_fd_, &peername); |
| 3283 | 3295 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3349 LOG(DFATAL) << "unexpected state " << state; | 3361 LOG(DFATAL) << "unexpected state " << state; |
| 3350 break; | 3362 break; |
| 3351 } | 3363 } |
| 3352 } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE); | 3364 } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE); |
| 3353 LeaveFunction(""); | 3365 LeaveFunction(""); |
| 3354 return rv; | 3366 return rv; |
| 3355 } | 3367 } |
| 3356 | 3368 |
| 3357 int SSLClientSocketNSS::DoHandshake() { | 3369 int SSLClientSocketNSS::DoHandshake() { |
| 3358 EnterFunction(""); | 3370 EnterFunction(""); |
| 3359 int rv = core_->Connect( | 3371 int rv = core_->Connect(base::Bind(&SSLClientSocketNSS::OnHandshakeIOComplete, |
| 3360 base::Bind(&SSLClientSocketNSS::OnHandshakeIOComplete, | 3372 base::Unretained(this))); |
| 3361 base::Unretained(this))); | |
| 3362 GotoState(STATE_HANDSHAKE_COMPLETE); | 3373 GotoState(STATE_HANDSHAKE_COMPLETE); |
| 3363 | 3374 |
| 3364 LeaveFunction(rv); | 3375 LeaveFunction(rv); |
| 3365 return rv; | 3376 return rv; |
| 3366 } | 3377 } |
| 3367 | 3378 |
| 3368 int SSLClientSocketNSS::DoHandshakeComplete(int result) { | 3379 int SSLClientSocketNSS::DoHandshakeComplete(int result) { |
| 3369 EnterFunction(result); | 3380 EnterFunction(result); |
| 3370 | 3381 |
| 3371 if (result == OK) { | 3382 if (result == OK) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3438 | 3449 |
| 3439 // Derived from AuthCertificateCallback() in | 3450 // Derived from AuthCertificateCallback() in |
| 3440 // mozilla/source/security/manager/ssl/src/nsNSSCallbacks.cpp. | 3451 // mozilla/source/security/manager/ssl/src/nsNSSCallbacks.cpp. |
| 3441 int SSLClientSocketNSS::DoVerifyCertComplete(int result) { | 3452 int SSLClientSocketNSS::DoVerifyCertComplete(int result) { |
| 3442 verifier_.reset(); | 3453 verifier_.reset(); |
| 3443 | 3454 |
| 3444 if (!start_cert_verification_time_.is_null()) { | 3455 if (!start_cert_verification_time_.is_null()) { |
| 3445 base::TimeDelta verify_time = | 3456 base::TimeDelta verify_time = |
| 3446 base::TimeTicks::Now() - start_cert_verification_time_; | 3457 base::TimeTicks::Now() - start_cert_verification_time_; |
| 3447 if (result == OK) | 3458 if (result == OK) |
| 3448 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTime", verify_time); | 3459 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTime", verify_time); |
| 3449 else | 3460 else |
| 3450 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTimeError", verify_time); | 3461 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTimeError", verify_time); |
| 3451 } | 3462 } |
| 3452 | 3463 |
| 3453 // We used to remember the intermediate CA certs in the NSS database | 3464 // We used to remember the intermediate CA certs in the NSS database |
| 3454 // persistently. However, NSS opens a connection to the SQLite database | 3465 // persistently. However, NSS opens a connection to the SQLite database |
| 3455 // during NSS initialization and doesn't close the connection until NSS | 3466 // during NSS initialization and doesn't close the connection until NSS |
| 3456 // shuts down. If the file system where the database resides is gone, | 3467 // shuts down. If the file system where the database resides is gone, |
| 3457 // the database connection goes bad. What's worse, the connection won't | 3468 // the database connection goes bad. What's worse, the connection won't |
| 3458 // recover when the file system comes back. Until this NSS or SQLite bug | 3469 // recover when the file system comes back. Until this NSS or SQLite bug |
| 3459 // is fixed, we need to avoid using the NSS database for non-essential | 3470 // is fixed, we need to avoid using the NSS database for non-essential |
| 3460 // purposes. See https://bugzilla.mozilla.org/show_bug.cgi?id=508081 and | 3471 // purposes. See https://bugzilla.mozilla.org/show_bug.cgi?id=508081 and |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3485 // user-installed trust anchor); and | 3496 // user-installed trust anchor); and |
| 3486 // * the build is recent (very old builds should fail open so that users | 3497 // * the build is recent (very old builds should fail open so that users |
| 3487 // have some chance to recover). | 3498 // have some chance to recover). |
| 3488 // | 3499 // |
| 3489 const CertStatus cert_status = server_cert_verify_result_.cert_status; | 3500 const CertStatus cert_status = server_cert_verify_result_.cert_status; |
| 3490 if (transport_security_state_ && | 3501 if (transport_security_state_ && |
| 3491 (result == OK || | 3502 (result == OK || |
| 3492 (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) && | 3503 (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) && |
| 3493 server_cert_verify_result_.is_issued_by_known_root && | 3504 server_cert_verify_result_.is_issued_by_known_root && |
| 3494 TransportSecurityState::IsBuildTimely()) { | 3505 TransportSecurityState::IsBuildTimely()) { |
| 3495 bool sni_available = | 3506 bool sni_available = ssl_config_.version_max >= SSL_PROTOCOL_VERSION_TLS1 || |
| 3496 ssl_config_.version_max >= SSL_PROTOCOL_VERSION_TLS1 || | 3507 ssl_config_.version_fallback; |
| 3497 ssl_config_.version_fallback; | |
| 3498 const std::string& host = host_and_port_.host(); | 3508 const std::string& host = host_and_port_.host(); |
| 3499 | 3509 |
| 3500 TransportSecurityState::DomainState domain_state; | 3510 TransportSecurityState::DomainState domain_state; |
| 3501 if (transport_security_state_->GetDomainState(host, sni_available, | 3511 if (transport_security_state_->GetDomainState( |
| 3502 &domain_state) && | 3512 host, sni_available, &domain_state) && |
| 3503 domain_state.HasPublicKeyPins()) { | 3513 domain_state.HasPublicKeyPins()) { |
| 3504 if (!domain_state.CheckPublicKeyPins( | 3514 if (!domain_state.CheckPublicKeyPins( |
| 3505 server_cert_verify_result_.public_key_hashes, | 3515 server_cert_verify_result_.public_key_hashes, |
| 3506 &pinning_failure_log_)) { | 3516 &pinning_failure_log_)) { |
| 3507 LOG(ERROR) << pinning_failure_log_; | 3517 LOG(ERROR) << pinning_failure_log_; |
| 3508 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; | 3518 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; |
| 3509 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", false); | 3519 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", false); |
| 3510 TransportSecurityState::ReportUMAOnPinFailure(host); | 3520 TransportSecurityState::ReportUMAOnPinFailure(host); |
| 3511 } else { | 3521 } else { |
| 3512 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", true); | 3522 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", true); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3549 | 3559 |
| 3550 VLOG(1) << "CT Verification complete: result " << result | 3560 VLOG(1) << "CT Verification complete: result " << result |
| 3551 << " Invalid scts: " << ct_verify_result_.invalid_scts.size() | 3561 << " Invalid scts: " << ct_verify_result_.invalid_scts.size() |
| 3552 << " Verified scts: " << ct_verify_result_.verified_scts.size() | 3562 << " Verified scts: " << ct_verify_result_.verified_scts.size() |
| 3553 << " scts from unknown logs: " | 3563 << " scts from unknown logs: " |
| 3554 << ct_verify_result_.unknown_logs_scts.size(); | 3564 << ct_verify_result_.unknown_logs_scts.size(); |
| 3555 } | 3565 } |
| 3556 | 3566 |
| 3557 void SSLClientSocketNSS::LogConnectionTypeMetrics() const { | 3567 void SSLClientSocketNSS::LogConnectionTypeMetrics() const { |
| 3558 UpdateConnectionTypeHistograms(CONNECTION_SSL); | 3568 UpdateConnectionTypeHistograms(CONNECTION_SSL); |
| 3559 int ssl_version = SSLConnectionStatusToVersion( | 3569 int ssl_version = |
| 3560 core_->state().ssl_connection_status); | 3570 SSLConnectionStatusToVersion(core_->state().ssl_connection_status); |
| 3561 switch (ssl_version) { | 3571 switch (ssl_version) { |
| 3562 case SSL_CONNECTION_VERSION_SSL2: | 3572 case SSL_CONNECTION_VERSION_SSL2: |
| 3563 UpdateConnectionTypeHistograms(CONNECTION_SSL_SSL2); | 3573 UpdateConnectionTypeHistograms(CONNECTION_SSL_SSL2); |
| 3564 break; | 3574 break; |
| 3565 case SSL_CONNECTION_VERSION_SSL3: | 3575 case SSL_CONNECTION_VERSION_SSL3: |
| 3566 UpdateConnectionTypeHistograms(CONNECTION_SSL_SSL3); | 3576 UpdateConnectionTypeHistograms(CONNECTION_SSL_SSL3); |
| 3567 break; | 3577 break; |
| 3568 case SSL_CONNECTION_VERSION_TLS1: | 3578 case SSL_CONNECTION_VERSION_TLS1: |
| 3569 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1); | 3579 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1); |
| 3570 break; | 3580 break; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3585 } | 3595 } |
| 3586 | 3596 |
| 3587 bool SSLClientSocketNSS::CalledOnValidThread() const { | 3597 bool SSLClientSocketNSS::CalledOnValidThread() const { |
| 3588 EnsureThreadIdAssigned(); | 3598 EnsureThreadIdAssigned(); |
| 3589 base::AutoLock auto_lock(lock_); | 3599 base::AutoLock auto_lock(lock_); |
| 3590 return valid_thread_id_ == base::PlatformThread::CurrentId(); | 3600 return valid_thread_id_ == base::PlatformThread::CurrentId(); |
| 3591 } | 3601 } |
| 3592 | 3602 |
| 3593 void SSLClientSocketNSS::AddSCTInfoToSSLInfo(SSLInfo* ssl_info) const { | 3603 void SSLClientSocketNSS::AddSCTInfoToSSLInfo(SSLInfo* ssl_info) const { |
| 3594 for (ct::SCTList::const_iterator iter = | 3604 for (ct::SCTList::const_iterator iter = |
| 3595 ct_verify_result_.verified_scts.begin(); | 3605 ct_verify_result_.verified_scts.begin(); |
| 3596 iter != ct_verify_result_.verified_scts.end(); ++iter) { | 3606 iter != ct_verify_result_.verified_scts.end(); |
| 3607 ++iter) { |
| 3597 ssl_info->signed_certificate_timestamps.push_back( | 3608 ssl_info->signed_certificate_timestamps.push_back( |
| 3598 SignedCertificateTimestampAndStatus(*iter, ct::SCT_STATUS_OK)); | 3609 SignedCertificateTimestampAndStatus(*iter, ct::SCT_STATUS_OK)); |
| 3599 } | 3610 } |
| 3600 for (ct::SCTList::const_iterator iter = | 3611 for (ct::SCTList::const_iterator iter = |
| 3601 ct_verify_result_.invalid_scts.begin(); | 3612 ct_verify_result_.invalid_scts.begin(); |
| 3602 iter != ct_verify_result_.invalid_scts.end(); ++iter) { | 3613 iter != ct_verify_result_.invalid_scts.end(); |
| 3614 ++iter) { |
| 3603 ssl_info->signed_certificate_timestamps.push_back( | 3615 ssl_info->signed_certificate_timestamps.push_back( |
| 3604 SignedCertificateTimestampAndStatus(*iter, ct::SCT_STATUS_INVALID)); | 3616 SignedCertificateTimestampAndStatus(*iter, ct::SCT_STATUS_INVALID)); |
| 3605 } | 3617 } |
| 3606 for (ct::SCTList::const_iterator iter = | 3618 for (ct::SCTList::const_iterator iter = |
| 3607 ct_verify_result_.unknown_logs_scts.begin(); | 3619 ct_verify_result_.unknown_logs_scts.begin(); |
| 3608 iter != ct_verify_result_.unknown_logs_scts.end(); ++iter) { | 3620 iter != ct_verify_result_.unknown_logs_scts.end(); |
| 3621 ++iter) { |
| 3609 ssl_info->signed_certificate_timestamps.push_back( | 3622 ssl_info->signed_certificate_timestamps.push_back( |
| 3610 SignedCertificateTimestampAndStatus(*iter, | 3623 SignedCertificateTimestampAndStatus(*iter, ct::SCT_STATUS_LOG_UNKNOWN)); |
| 3611 ct::SCT_STATUS_LOG_UNKNOWN)); | |
| 3612 } | 3624 } |
| 3613 } | 3625 } |
| 3614 | 3626 |
| 3615 scoped_refptr<X509Certificate> | 3627 scoped_refptr<X509Certificate> |
| 3616 SSLClientSocketNSS::GetUnverifiedServerCertificateChain() const { | 3628 SSLClientSocketNSS::GetUnverifiedServerCertificateChain() const { |
| 3617 return core_->state().server_cert.get(); | 3629 return core_->state().server_cert.get(); |
| 3618 } | 3630 } |
| 3619 | 3631 |
| 3620 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const { | 3632 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const { |
| 3621 return server_bound_cert_service_; | 3633 return server_bound_cert_service_; |
| 3622 } | 3634 } |
| 3623 | 3635 |
| 3624 } // namespace net | 3636 } // namespace net |
| OLD | NEW |