1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/socket/ssl_client_socket_win.h" 6 7 #include <schnlsp.h> 8 #include <map> 9 10 #include "base/compiler_specific.h" 11 #include "base/lazy_instance.h" 12 #include "base/stl_util-inl.h" 13 #include "base/string_util.h" 14 #include "base/synchronization/lock.h" 15 #include "base/utf_string_conversions.h" 16 #include "net/base/cert_verifier.h" 17 #include "net/base/connection_type_histograms.h" 18 #include "net/base/host_port_pair.h" 19 #include "net/base/io_buffer.h" 20 #include "net/base/net_log.h" 21 #include "net/base/net_errors.h" 22 #include "net/base/ssl_cert_request_info.h" 23 #include "net/base/ssl_connection_status_flags.h" 24 #include "net/base/ssl_info.h" 25 #include "net/socket/client_socket_handle.h" 26 27 #pragma comment(lib, "secur32.lib") 28 29 namespace net { 30 31 //----------------------------------------------------------------------------- 32 33 // TODO(wtc): See http://msdn.microsoft.com/en-us/library/aa377188(VS.85).aspx 34 // for the other error codes we may need to map. 35 static int MapSecurityError(SECURITY_STATUS err) { 36 // There are numerous security error codes, but these are the ones we thus 37 // far find interesting. 38 switch (err) { 39 case SEC_E_WRONG_PRINCIPAL: // Schannel - server certificate error. 40 case CERT_E_CN_NO_MATCH: // CryptoAPI 41 return ERR_CERT_COMMON_NAME_INVALID; 42 case SEC_E_UNTRUSTED_ROOT: // Schannel - server certificate error or 43 // unknown_ca alert. 44 case CERT_E_UNTRUSTEDROOT: // CryptoAPI 45 return ERR_CERT_AUTHORITY_INVALID; 46 case SEC_E_CERT_EXPIRED: // Schannel - server certificate error or 47 // certificate_expired alert. 48 case CERT_E_EXPIRED: // CryptoAPI 49 return ERR_CERT_DATE_INVALID; 50 case CRYPT_E_NO_REVOCATION_CHECK: 51 return ERR_CERT_NO_REVOCATION_MECHANISM; 52 case CRYPT_E_REVOCATION_OFFLINE: 53 return ERR_CERT_UNABLE_TO_CHECK_REVOCATION; 54 case CRYPT_E_REVOKED: // CryptoAPI and Schannel server certificate error, 55 // or certificate_revoked alert. 56 return ERR_CERT_REVOKED; 57 58 // We received one of the following alert messages from the server: 59 // bad_certificate 60 // unsupported_certificate 61 // certificate_unknown 62 case SEC_E_CERT_UNKNOWN: 63 case CERT_E_ROLE: 64 return ERR_CERT_INVALID; 65 66 // We received one of the following alert messages from the server: 67 // decode_error 68 // export_restriction 69 // handshake_failure 70 // illegal_parameter 71 // record_overflow 72 // unexpected_message 73 // and all other TLS alerts not explicitly specified elsewhere. 74 case SEC_E_ILLEGAL_MESSAGE: 75 // We received one of the following alert messages from the server: 76 // decrypt_error 77 // decryption_failed 78 case SEC_E_DECRYPT_FAILURE: 79 // We received one of the following alert messages from the server: 80 // bad_record_mac 81 // decompression_failure 82 case SEC_E_MESSAGE_ALTERED: 83 // TODO(rsleevi): Add SEC_E_INTERNAL_ERROR, which corresponds to an 84 // internal_error alert message being received. However, it is also used 85 // by Schannel for authentication errors that happen locally, so it has 86 // been omitted to prevent masking them as protocol errors. 87 return ERR_SSL_PROTOCOL_ERROR; 88 89 case SEC_E_LOGON_DENIED: // Received a access_denied alert. 90 return ERR_BAD_SSL_CLIENT_AUTH_CERT; 91 92 case SEC_E_UNSUPPORTED_FUNCTION: // Received a protocol_version alert. 93 case SEC_E_ALGORITHM_MISMATCH: // Received an insufficient_security alert. 94 return ERR_SSL_VERSION_OR_CIPHER_MISMATCH; 95 96 case SEC_E_NO_CREDENTIALS: 97 return ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY; 98 case SEC_E_INVALID_HANDLE: 99 case SEC_E_INVALID_TOKEN: 100 LOG(ERROR) << "Unexpected error " << err; 101 return ERR_UNEXPECTED; 102 case SEC_E_OK: 103 return OK; 104 default: 105 LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED"; 106 return ERR_FAILED; 107 } 108 } 109 110 //----------------------------------------------------------------------------- 111 112 // A bitmask consisting of these bit flags encodes which versions of the SSL 113 // protocol (SSL 3.0 and TLS 1.0) are enabled. 114 enum { 115 SSL3 = 1 << 0, 116 TLS1 = 1 << 1, 117 SSL_VERSION_MASKS = 1 << 2 // The number of SSL version bitmasks. 118 }; 119 120 // CredHandleClass simply gives a default constructor and a destructor to 121 // SSPI's CredHandle type (a C struct). 122 class CredHandleClass : public CredHandle { 123 public: 124 CredHandleClass() { 125 SecInvalidateHandle(this); 126 } 127 128 ~CredHandleClass() { 129 if (SecIsValidHandle(this)) { 130 SECURITY_STATUS status = FreeCredentialsHandle(this); 131 DCHECK(status == SEC_E_OK); 132 } 133 } 134 }; 135 136 // A table of CredHandles. 137 class CredHandleTable { 138 public: 139 CredHandleTable() {} 140 141 ~CredHandleTable() { 142 STLDeleteContainerPairSecondPointers(client_cert_creds_.begin(), 143 client_cert_creds_.end()); 144 } 145 146 int GetHandle(PCCERT_CONTEXT client_cert, 147 int ssl_version_mask, 148 CredHandle** handle_ptr) { 149 DCHECK(0 < ssl_version_mask && 150 ssl_version_mask < arraysize(anonymous_creds_)); 151 CredHandleClass* handle; 152 base::AutoLock lock(lock_); 153 if (client_cert) { 154 CredHandleMapKey key = std::make_pair(client_cert, ssl_version_mask); 155 CredHandleMap::const_iterator it = client_cert_creds_.find(key); 156 if (it == client_cert_creds_.end()) { 157 handle = new CredHandleClass; 158 client_cert_creds_[key] = handle; 159 } else { 160 handle = it->second; 161 } 162 } else { 163 handle = &anonymous_creds_[ssl_version_mask]; 164 } 165 if (!SecIsValidHandle(handle)) { 166 int result = InitializeHandle(handle, client_cert, ssl_version_mask); 167 if (result != OK) 168 return result; 169 } 170 *handle_ptr = handle; 171 return OK; 172 } 173 174 private: 175 // CredHandleMapKey is a std::pair consisting of these two components: 176 // PCCERT_CONTEXT client_cert 177 // int ssl_version_mask 178 typedef std::pair<PCCERT_CONTEXT, int> CredHandleMapKey; 179 180 typedef std::map<CredHandleMapKey, CredHandleClass*> CredHandleMap; 181 182 // Returns OK on success or a network error code on failure. 183 static int InitializeHandle(CredHandle* handle, 184 PCCERT_CONTEXT client_cert, 185 int ssl_version_mask); 186 187 base::Lock lock_; 188 189 // Anonymous (no client certificate) CredHandles for all possible 190 // combinations of SSL versions. Defined as an array for fast lookup. 191 CredHandleClass anonymous_creds_[SSL_VERSION_MASKS]; 192 193 // CredHandles that use a client certificate. 194 CredHandleMap client_cert_creds_; 195 }; 196 197 static base::LazyInstance<CredHandleTable> g_cred_handle_table( 198 base::LINKER_INITIALIZED); 199 200 // static 201 int CredHandleTable::InitializeHandle(CredHandle* handle, 202 PCCERT_CONTEXT client_cert, 203 int ssl_version_mask) { 204 SCHANNEL_CRED schannel_cred = {0}; 205 schannel_cred.dwVersion = SCHANNEL_CRED_VERSION; 206 if (client_cert) { 207 schannel_cred.cCreds = 1; 208 schannel_cred.paCred = &client_cert; 209 // Schannel will make its own copy of client_cert. 210 } 211 212 // The global system registry settings take precedence over the value of 213 // schannel_cred.grbitEnabledProtocols. 214 schannel_cred.grbitEnabledProtocols = 0; 215 if (ssl_version_mask & SSL3) 216 schannel_cred.grbitEnabledProtocols |= SP_PROT_SSL3; 217 if (ssl_version_mask & TLS1) 218 schannel_cred.grbitEnabledProtocols |= SP_PROT_TLS1; 219 220 // The default session lifetime is 36000000 milliseconds (ten hours). Set 221 // schannel_cred.dwSessionLifespan to change the number of milliseconds that 222 // Schannel keeps the session in its session cache. 223 224 // We can set the key exchange algorithms (RSA or DH) in 225 // schannel_cred.{cSupportedAlgs,palgSupportedAlgs}. 226 227 // Although SCH_CRED_AUTO_CRED_VALIDATION is convenient, we have to use 228 // SCH_CRED_MANUAL_CRED_VALIDATION for three reasons. 229 // 1. SCH_CRED_AUTO_CRED_VALIDATION doesn't allow us to get the certificate 230 // context if the certificate validation fails. 231 // 2. SCH_CRED_AUTO_CRED_VALIDATION returns only one error even if the 232 // certificate has multiple errors. 233 // 3. SCH_CRED_AUTO_CRED_VALIDATION doesn't allow us to ignore untrusted CA 234 // and expired certificate errors. There are only flags to ignore the 235 // name mismatch and unable-to-check-revocation errors. 236 // 237 // We specify SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT to cause the TLS 238 // certificate status request extension (commonly known as OCSP stapling) 239 // to be sent on Vista or later. This flag matches the 240 // CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT flag that we pass to the 241 // CertGetCertificateChain calls. Note: we specify this flag even when 242 // revocation checking is disabled to avoid doubling the number of 243 // credentials handles we need to acquire. 244 // 245 // TODO(wtc): Look into undocumented or poorly documented flags: 246 // SCH_CRED_RESTRICTED_ROOTS 247 // SCH_CRED_REVOCATION_CHECK_CACHE_ONLY 248 // SCH_CRED_CACHE_ONLY_URL_RETRIEVAL 249 // SCH_CRED_MEMORY_STORE_CERT 250 schannel_cred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS | 251 SCH_CRED_MANUAL_CRED_VALIDATION | 252 SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT; 253 TimeStamp expiry; 254 SECURITY_STATUS status; 255 256 status = AcquireCredentialsHandle( 257 NULL, // Not used 258 UNISP_NAME, // Microsoft Unified Security Protocol Provider 259 SECPKG_CRED_OUTBOUND, 260 NULL, // Not used 261 &schannel_cred, 262 NULL, // Not used 263 NULL, // Not used 264 handle, 265 &expiry); // Optional 266 if (status != SEC_E_OK) 267 LOG(ERROR) << "AcquireCredentialsHandle failed: " << status; 268 return MapSecurityError(status); 269 } 270 271 // For the SSL sockets to share SSL sessions by session resumption handshakes, 272 // they need to use the same CredHandle. The GetCredHandle function creates 273 // and stores a shared CredHandle in *handle_ptr. On success, GetCredHandle 274 // returns OK. On failure, GetCredHandle returns a network error code and 275 // leaves *handle_ptr unchanged. 276 // 277 // The versions of the SSL protocol enabled are a property of the CredHandle. 278 // So we need a separate CredHandle for each combination of SSL versions. 279 // Most of the time Chromium will use only one or two combinations of SSL 280 // versions (for example, SSL3 | TLS1 for normal use, plus SSL3 when visiting 281 // TLS-intolerant servers). These CredHandles are initialized only when 282 // needed. 283 284 static int GetCredHandle(PCCERT_CONTEXT client_cert, 285 int ssl_version_mask, 286 CredHandle** handle_ptr) { 287 if (ssl_version_mask <= 0 || ssl_version_mask >= SSL_VERSION_MASKS) { 288 NOTREACHED(); 289 return ERR_UNEXPECTED; 290 } 291 return g_cred_handle_table.Get().GetHandle(client_cert, 292 ssl_version_mask, 293 handle_ptr); 294 } 295 296 //----------------------------------------------------------------------------- 297 298 // This callback is intended to be used with CertFindChainInStore. In addition 299 // to filtering by extended/enhanced key usage, we do not show expired 300 // certificates and require digital signature usage in the key usage 301 // extension. 302 // 303 // This matches our behavior on Mac OS X and that of NSS. It also matches the 304 // default behavior of IE8. See http://support.microsoft.com/kb/890326 and 305 // http://blogs.msdn.com/b/askie/archive/2009/06/09/my-expired-client-certificates-no-longer-display-when-connecting-to-my-web-server-using-ie8.aspx 306 static BOOL WINAPI ClientCertFindCallback(PCCERT_CONTEXT cert_context, 307 void* find_arg) { 308 // Verify the certificate's KU is good. 309 BYTE key_usage; 310 if (CertGetIntendedKeyUsage(X509_ASN_ENCODING, cert_context->pCertInfo, 311 &key_usage, 1)) { 312 if (!(key_usage & CERT_DIGITAL_SIGNATURE_KEY_USAGE)) 313 return FALSE; 314 } else { 315 DWORD err = GetLastError(); 316 // If |err| is non-zero, it's an actual error. Otherwise the extension 317 // just isn't present, and we treat it as if everything was allowed. 318 if (err) { 319 DLOG(ERROR) << "CertGetIntendedKeyUsage failed: " << err; 320 return FALSE; 321 } 322 } 323 324 // Verify the current time is within the certificate's validity period. 325 if (CertVerifyTimeValidity(NULL, cert_context->pCertInfo) != 0) 326 return FALSE; 327 328 // Verify private key metadata is associated with this certificate. 329 DWORD size = 0; 330 if (!CertGetCertificateContextProperty( 331 cert_context, CERT_KEY_PROV_INFO_PROP_ID, NULL, &size)) { 332 return FALSE; 333 } 334 335 return TRUE; 336 } 337 338 //----------------------------------------------------------------------------- 339 340 // A memory certificate store for client certificates. This allows us to 341 // close the "MY" system certificate store when we finish searching for 342 // client certificates. 343 class ClientCertStore { 344 public: 345 ClientCertStore() { 346 store_ = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL); 347 } 348 349 ~ClientCertStore() { 350 if (store_) { 351 BOOL ok = CertCloseStore(store_, CERT_CLOSE_STORE_CHECK_FLAG); 352 DCHECK(ok); 353 } 354 } 355 356 PCCERT_CONTEXT CopyCertContext(PCCERT_CONTEXT client_cert) { 357 PCCERT_CONTEXT copy; 358 BOOL ok = CertAddCertificateContextToStore(store_, client_cert, 359 CERT_STORE_ADD_USE_EXISTING, 360 ©); 361 DCHECK(ok); 362 return ok ? copy : NULL; 363 } 364 365 private: 366 HCERTSTORE store_; 367 }; 368 369 static base::LazyInstance<ClientCertStore> g_client_cert_store( 370 base::LINKER_INITIALIZED); 371 372 //----------------------------------------------------------------------------- 373 374 // Size of recv_buffer_ 375 // 376 // Ciphertext is decrypted one SSL record at a time, so recv_buffer_ needs to 377 // have room for a full SSL record, with the header and trailer. Here is the 378 // breakdown of the size: 379 // 5: SSL record header 380 // 16K: SSL record maximum size 381 // 64: >= SSL record trailer (16 or 20 have been observed) 382 static const int kRecvBufferSize = (5 + 16*1024 + 64); 383 384 SSLClientSocketWin::SSLClientSocketWin(ClientSocketHandle* transport_socket, 385 const HostPortPair& host_and_port, 386 const SSLConfig& ssl_config, 387 CertVerifier* cert_verifier) 388 : ALLOW_THIS_IN_INITIALIZER_LIST( 389 handshake_io_callback_(this, 390 &SSLClientSocketWin::OnHandshakeIOComplete)), 391 ALLOW_THIS_IN_INITIALIZER_LIST( 392 read_callback_(this, &SSLClientSocketWin::OnReadComplete)), 393 ALLOW_THIS_IN_INITIALIZER_LIST( 394 write_callback_(this, &SSLClientSocketWin::OnWriteComplete)), 395 transport_(transport_socket), 396 host_and_port_(host_and_port), 397 ssl_config_(ssl_config), 398 user_connect_callback_(NULL), 399 user_read_callback_(NULL), 400 user_read_buf_len_(0), 401 user_write_callback_(NULL), 402 user_write_buf_len_(0), 403 next_state_(STATE_NONE), 404 cert_verifier_(cert_verifier), 405 creds_(NULL), 406 isc_status_(SEC_E_OK), 407 payload_send_buffer_len_(0), 408 bytes_sent_(0), 409 decrypted_ptr_(NULL), 410 bytes_decrypted_(0), 411 received_ptr_(NULL), 412 bytes_received_(0), 413 writing_first_token_(false), 414 ignore_ok_result_(false), 415 renegotiating_(false), 416 need_more_data_(false), 417 net_log_(transport_socket->socket()->NetLog()) { 418 memset(&stream_sizes_, 0, sizeof(stream_sizes_)); 419 memset(in_buffers_, 0, sizeof(in_buffers_)); 420 memset(&send_buffer_, 0, sizeof(send_buffer_)); 421 memset(&ctxt_, 0, sizeof(ctxt_)); 422 } 423 424 SSLClientSocketWin::~SSLClientSocketWin() { 425 Disconnect(); 426 } 427 428 void SSLClientSocketWin::GetSSLInfo(SSLInfo* ssl_info) { 429 ssl_info->Reset(); 430 431 if (!server_cert_) 432 return; 433 434 ssl_info->cert = server_cert_; 435 ssl_info->cert_status = server_cert_verify_result_.cert_status; 436 ssl_info->public_key_hashes = server_cert_verify_result_.public_key_hashes; 437 ssl_info->is_issued_by_known_root = 438 server_cert_verify_result_.is_issued_by_known_root; 439 SecPkgContext_ConnectionInfo connection_info; 440 SECURITY_STATUS status = QueryContextAttributes( 441 &ctxt_, SECPKG_ATTR_CONNECTION_INFO, &connection_info); 442 if (status == SEC_E_OK) { 443 // TODO(wtc): compute the overall security strength, taking into account 444 // dwExchStrength and dwHashStrength. dwExchStrength needs to be 445 // normalized. 446 ssl_info->security_bits = connection_info.dwCipherStrength; 447 } 448 // SecPkgContext_CipherInfo comes from CNG and is available on Vista or 449 // later only. On XP, the next QueryContextAttributes call fails with 450 // SEC_E_UNSUPPORTED_FUNCTION (0x80090302), so ssl_info->connection_status 451 // won't contain the cipher suite. If this is a problem, we can build the 452 // cipher suite from the aiCipher, aiHash, and aiExch fields of 453 // SecPkgContext_ConnectionInfo based on Appendix C of RFC 5246. 454 SecPkgContext_CipherInfo cipher_info = { SECPKGCONTEXT_CIPHERINFO_V1 }; 455 status = QueryContextAttributes( 456 &ctxt_, SECPKG_ATTR_CIPHER_INFO, &cipher_info); 457 if (status == SEC_E_OK) { 458 // TODO(wtc): find out what the cipher_info.dwBaseCipherSuite field is. 459 ssl_info->connection_status |= 460 (cipher_info.dwCipherSuite & SSL_CONNECTION_CIPHERSUITE_MASK) << 461 SSL_CONNECTION_CIPHERSUITE_SHIFT; 462 // SChannel doesn't support TLS compression, so cipher_info doesn't have 463 // any field related to the compression method. 464 } 465 466 if (ssl_config_.ssl3_fallback) 467 ssl_info->connection_status |= SSL_CONNECTION_SSL3_FALLBACK; 468 } 469 470 void SSLClientSocketWin::GetSSLCertRequestInfo( 471 SSLCertRequestInfo* cert_request_info) { 472 cert_request_info->host_and_port = host_and_port_.ToString(); 473 cert_request_info->client_certs.clear(); 474 475 // Get the certificate_authorities field of the CertificateRequest message. 476 // Schannel doesn't return the certificate_types field of the 477 // CertificateRequest message to us, so we can't filter the client 478 // certificates properly. :-( 479 SecPkgContext_IssuerListInfoEx issuer_list; 480 SECURITY_STATUS status = QueryContextAttributes( 481 &ctxt_, SECPKG_ATTR_ISSUER_LIST_EX, &issuer_list); 482 if (status != SEC_E_OK) { 483 DLOG(ERROR) << "QueryContextAttributes (issuer list) failed: " << status; 484 return; 485 } 486 487 // Client certificates of the user are in the "MY" system certificate store. 488 HCERTSTORE my_cert_store = CertOpenSystemStore(NULL, L"MY"); 489 if (!my_cert_store) { 490 LOG(ERROR) << "Could not open the \"MY\" system certificate store: " 491 << GetLastError(); 492 FreeContextBuffer(issuer_list.aIssuers); 493 return; 494 } 495 496 // Enumerate the client certificates. 497 CERT_CHAIN_FIND_BY_ISSUER_PARA find_by_issuer_para; 498 memset(&find_by_issuer_para, 0, sizeof(find_by_issuer_para)); 499 find_by_issuer_para.cbSize = sizeof(find_by_issuer_para); 500 find_by_issuer_para.pszUsageIdentifier = szOID_PKIX_KP_CLIENT_AUTH; 501 find_by_issuer_para.cIssuer = issuer_list.cIssuers; 502 find_by_issuer_para.rgIssuer = issuer_list.aIssuers; 503 find_by_issuer_para.pfnFindCallback = ClientCertFindCallback; 504 505 PCCERT_CHAIN_CONTEXT chain_context = NULL; 506 507 for (;;) { 508 // Find a certificate chain. 509 chain_context = CertFindChainInStore(my_cert_store, 510 X509_ASN_ENCODING, 511 0, 512 CERT_CHAIN_FIND_BY_ISSUER, 513 &find_by_issuer_para, 514 chain_context); 515 if (!chain_context) { 516 DWORD err = GetLastError(); 517 if (err != CRYPT_E_NOT_FOUND) 518 DLOG(ERROR) << "CertFindChainInStore failed: " << err; 519 break; 520 } 521 522 // Get the leaf certificate. 523 PCCERT_CONTEXT cert_context = 524 chain_context->rgpChain[0]->rgpElement[0]->pCertContext; 525 // Copy it to our own certificate store, so that we can close the "MY" 526 // certificate store before returning from this function. 527 PCCERT_CONTEXT cert_context2 = 528 g_client_cert_store.Get().CopyCertContext(cert_context); 529 if (!cert_context2) { 530 NOTREACHED(); 531 continue; 532 } 533 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( 534 cert_context2, X509Certificate::SOURCE_LONE_CERT_IMPORT, 535 X509Certificate::OSCertHandles()); 536 cert_request_info->client_certs.push_back(cert); 537 CertFreeCertificateContext(cert_context2); 538 } 539 540 FreeContextBuffer(issuer_list.aIssuers); 541 542 BOOL ok = CertCloseStore(my_cert_store, CERT_CLOSE_STORE_CHECK_FLAG); 543 DCHECK(ok); 544 } 545 546 SSLClientSocket::NextProtoStatus 547 SSLClientSocketWin::GetNextProto(std::string* proto) { 548 proto->clear(); 549 return kNextProtoUnsupported; 550 } 551 552 #ifdef ANDROID 553 // TODO(kristianm): handle the case when wait_for_connect is true 554 // (sync requests) 555 #endif 556 int SSLClientSocketWin::Connect(CompletionCallback* callback 557 #ifdef ANDROID 558 , bool wait_for_connect 559 #endif 560 ) { 561 DCHECK(transport_.get()); 562 DCHECK(next_state_ == STATE_NONE); 563 DCHECK(!user_connect_callback_); 564 565 net_log_.BeginEvent(NetLog::TYPE_SSL_CONNECT, NULL); 566 567 int rv = InitializeSSLContext(); 568 if (rv != OK) { 569 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL); 570 return rv; 571 } 572 573 writing_first_token_ = true; 574 next_state_ = STATE_HANDSHAKE_WRITE; 575 rv = DoLoop(OK); 576 if (rv == ERR_IO_PENDING) { 577 user_connect_callback_ = callback; 578 } else { 579 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL); 580 } 581 return rv; 582 } 583 584 int SSLClientSocketWin::InitializeSSLContext() { 585 int ssl_version_mask = 0; 586 if (ssl_config_.ssl3_enabled) 587 ssl_version_mask |= SSL3; 588 if (ssl_config_.tls1_enabled) 589 ssl_version_mask |= TLS1; 590 // If we pass 0 to GetCredHandle, we will let Schannel select the protocols, 591 // rather than enabling no protocols. So we have to fail here. 592 if (ssl_version_mask == 0) 593 return ERR_NO_SSL_VERSIONS_ENABLED; 594 PCCERT_CONTEXT cert_context = NULL; 595 if (ssl_config_.client_cert) 596 cert_context = ssl_config_.client_cert->os_cert_handle(); 597 int result = GetCredHandle(cert_context, ssl_version_mask, &creds_); 598 if (result != OK) 599 return result; 600 601 memset(&ctxt_, 0, sizeof(ctxt_)); 602 603 SecBufferDesc buffer_desc; 604 DWORD out_flags; 605 DWORD flags = ISC_REQ_SEQUENCE_DETECT | 606 ISC_REQ_REPLAY_DETECT | 607 ISC_REQ_CONFIDENTIALITY | 608 ISC_RET_EXTENDED_ERROR | 609 ISC_REQ_ALLOCATE_MEMORY | 610 ISC_REQ_STREAM; 611 612 send_buffer_.pvBuffer = NULL; 613 send_buffer_.BufferType = SECBUFFER_TOKEN; 614 send_buffer_.cbBuffer = 0; 615 616 buffer_desc.cBuffers = 1; 617 buffer_desc.pBuffers = &send_buffer_; 618 buffer_desc.ulVersion = SECBUFFER_VERSION; 619 620 TimeStamp expiry; 621 SECURITY_STATUS status; 622 623 status = InitializeSecurityContext( 624 creds_, 625 NULL, // NULL on the first call 626 const_cast<wchar_t*>(ASCIIToWide(host_and_port_.host()).c_str()), 627 flags, 628 0, // Reserved 629 0, // Not used with Schannel. 630 NULL, // NULL on the first call 631 0, // Reserved 632 &ctxt_, // Receives the new context handle 633 &buffer_desc, 634 &out_flags, 635 &expiry); 636 if (status != SEC_I_CONTINUE_NEEDED) { 637 LOG(ERROR) << "InitializeSecurityContext failed: " << status; 638 if (status == SEC_E_INVALID_HANDLE) { 639 // The only handle we passed to this InitializeSecurityContext call is 640 // creds_, so print its contents to figure out why it's invalid. 641 if (creds_) { 642 LOG(ERROR) << "creds_->dwLower = " << creds_->dwLower 643 << "; creds_->dwUpper = " << creds_->dwUpper; 644 } else { 645 LOG(ERROR) << "creds_ is NULL"; 646 } 647 } 648 return MapSecurityError(status); 649 } 650 651 return OK; 652 } 653 654 655 void SSLClientSocketWin::Disconnect() { 656 // TODO(wtc): Send SSL close_notify alert. 657 next_state_ = STATE_NONE; 658 659 // Shut down anything that may call us back. 660 verifier_.reset(); 661 transport_->socket()->Disconnect(); 662 663 if (send_buffer_.pvBuffer) 664 FreeSendBuffer(); 665 if (SecIsValidHandle(&ctxt_)) { 666 DeleteSecurityContext(&ctxt_); 667 SecInvalidateHandle(&ctxt_); 668 } 669 if (server_cert_) 670 server_cert_ = NULL; 671 672 // TODO(wtc): reset more members? 673 bytes_decrypted_ = 0; 674 bytes_received_ = 0; 675 writing_first_token_ = false; 676 renegotiating_ = false; 677 need_more_data_ = false; 678 } 679 680 bool SSLClientSocketWin::IsConnected() const { 681 // Ideally, we should also check if we have received the close_notify alert 682 // message from the server, and return false in that case. We're not doing 683 // that, so this function may return a false positive. Since the upper 684 // layer (HttpNetworkTransaction) needs to handle a persistent connection 685 // closed by the server when we send a request anyway, a false positive in 686 // exchange for simpler code is a good trade-off. 687 return completed_handshake() && transport_->socket()->IsConnected(); 688 } 689 690 bool SSLClientSocketWin::IsConnectedAndIdle() const { 691 // Unlike IsConnected, this method doesn't return a false positive. 692 // 693 // Strictly speaking, we should check if we have received the close_notify 694 // alert message from the server, and return false in that case. Although 695 // the close_notify alert message means EOF in the SSL layer, it is just 696 // bytes to the transport layer below, so 697 // transport_->socket()->IsConnectedAndIdle() returns the desired false 698 // when we receive close_notify. 699 return completed_handshake() && transport_->socket()->IsConnectedAndIdle(); 700 } 701 702 int SSLClientSocketWin::GetPeerAddress(AddressList* address) const { 703 return transport_->socket()->GetPeerAddress(address); 704 } 705 706 int SSLClientSocketWin::GetLocalAddress(IPEndPoint* address) const { 707 return transport_->socket()->GetLocalAddress(address); 708 } 709 710 void SSLClientSocketWin::SetSubresourceSpeculation() { 711 if (transport_.get() && transport_->socket()) { 712 transport_->socket()->SetSubresourceSpeculation(); 713 } else { 714 NOTREACHED(); 715 } 716 } 717 718 void SSLClientSocketWin::SetOmniboxSpeculation() { 719 if (transport_.get() && transport_->socket()) { 720 transport_->socket()->SetOmniboxSpeculation(); 721 } else { 722 NOTREACHED(); 723 } 724 } 725 726 bool SSLClientSocketWin::WasEverUsed() const { 727 if (transport_.get() && transport_->socket()) { 728 return transport_->socket()->WasEverUsed(); 729 } 730 NOTREACHED(); 731 return false; 732 } 733 734 bool SSLClientSocketWin::UsingTCPFastOpen() const { 735 if (transport_.get() && transport_->socket()) { 736 return transport_->socket()->UsingTCPFastOpen(); 737 } 738 NOTREACHED(); 739 return false; 740 } 741 742 int SSLClientSocketWin::Read(IOBuffer* buf, int buf_len, 743 CompletionCallback* callback) { 744 DCHECK(completed_handshake()); 745 DCHECK(!user_read_callback_); 746 747 // If we have surplus decrypted plaintext, satisfy the Read with it without 748 // reading more ciphertext from the transport socket. 749 if (bytes_decrypted_ != 0) { 750 int len = std::min(buf_len, bytes_decrypted_); 751 memcpy(buf->data(), decrypted_ptr_, len); 752 decrypted_ptr_ += len; 753 bytes_decrypted_ -= len; 754 if (bytes_decrypted_ == 0) { 755 decrypted_ptr_ = NULL; 756 if (bytes_received_ != 0) { 757 memmove(recv_buffer_.get(), received_ptr_, bytes_received_); 758 received_ptr_ = recv_buffer_.get(); 759 } 760 } 761 return len; 762 } 763 764 DCHECK(!user_read_buf_); 765 // http://crbug.com/16371: We're seeing |buf->data()| return NULL. See if the 766 // user is passing in an IOBuffer with a NULL |data_|. 767 CHECK(buf); 768 CHECK(buf->data()); 769 user_read_buf_ = buf; 770 user_read_buf_len_ = buf_len; 771 772 int rv = DoPayloadRead(); 773 if (rv == ERR_IO_PENDING) { 774 user_read_callback_ = callback; 775 } else { 776 user_read_buf_ = NULL; 777 user_read_buf_len_ = 0; 778 } 779 return rv; 780 } 781 782 int SSLClientSocketWin::Write(IOBuffer* buf, int buf_len, 783 CompletionCallback* callback) { 784 DCHECK(completed_handshake()); 785 DCHECK(!user_write_callback_); 786 787 DCHECK(!user_write_buf_); 788 user_write_buf_ = buf; 789 user_write_buf_len_ = buf_len; 790 791 int rv = DoPayloadEncrypt(); 792 if (rv != OK) 793 return rv; 794 795 rv = DoPayloadWrite(); 796 if (rv == ERR_IO_PENDING) { 797 user_write_callback_ = callback; 798 } else { 799 user_write_buf_ = NULL; 800 user_write_buf_len_ = 0; 801 } 802 return rv; 803 } 804 805 bool SSLClientSocketWin::SetReceiveBufferSize(int32 size) { 806 return transport_->socket()->SetReceiveBufferSize(size); 807 } 808 809 bool SSLClientSocketWin::SetSendBufferSize(int32 size) { 810 return transport_->socket()->SetSendBufferSize(size); 811 } 812 813 void SSLClientSocketWin::OnHandshakeIOComplete(int result) { 814 int rv = DoLoop(result); 815 816 // The SSL handshake has some round trips. We need to notify the caller of 817 // success or any error, other than waiting for IO. 818 if (rv != ERR_IO_PENDING) { 819 // If there is no connect callback available to call, we are renegotiating 820 // (which occurs because we are in the middle of a Read when the 821 // renegotiation process starts). So we complete the Read here. 822 if (!user_connect_callback_) { 823 CompletionCallback* c = user_read_callback_; 824 user_read_callback_ = NULL; 825 user_read_buf_ = NULL; 826 user_read_buf_len_ = 0; 827 c->Run(rv); 828 return; 829 } 830 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL); 831 CompletionCallback* c = user_connect_callback_; 832 user_connect_callback_ = NULL; 833 c->Run(rv); 834 } 835 } 836 837 void SSLClientSocketWin::OnReadComplete(int result) { 838 DCHECK(completed_handshake()); 839 840 result = DoPayloadReadComplete(result); 841 if (result > 0) 842 result = DoPayloadDecrypt(); 843 if (result != ERR_IO_PENDING) { 844 DCHECK(user_read_callback_); 845 CompletionCallback* c = user_read_callback_; 846 user_read_callback_ = NULL; 847 user_read_buf_ = NULL; 848 user_read_buf_len_ = 0; 849 c->Run(result); 850 } 851 } 852 853 void SSLClientSocketWin::OnWriteComplete(int result) { 854 DCHECK(completed_handshake()); 855 856 int rv = DoPayloadWriteComplete(result); 857 if (rv != ERR_IO_PENDING) { 858 DCHECK(user_write_callback_); 859 CompletionCallback* c = user_write_callback_; 860 user_write_callback_ = NULL; 861 user_write_buf_ = NULL; 862 user_write_buf_len_ = 0; 863 c->Run(rv); 864 } 865 } 866 867 868 int SSLClientSocketWin::DoLoop(int last_io_result) { 869 DCHECK(next_state_ != STATE_NONE); 870 int rv = last_io_result; 871 do { 872 State state = next_state_; 873 next_state_ = STATE_NONE; 874 switch (state) { 875 case STATE_HANDSHAKE_READ: 876 rv = DoHandshakeRead(); 877 break; 878 case STATE_HANDSHAKE_READ_COMPLETE: 879 rv = DoHandshakeReadComplete(rv); 880 break; 881 case STATE_HANDSHAKE_WRITE: 882 rv = DoHandshakeWrite(); 883 break; 884 case STATE_HANDSHAKE_WRITE_COMPLETE: 885 rv = DoHandshakeWriteComplete(rv); 886 break; 887 case STATE_VERIFY_CERT: 888 rv = DoVerifyCert(); 889 break; 890 case STATE_VERIFY_CERT_COMPLETE: 891 rv = DoVerifyCertComplete(rv); 892 break; 893 case STATE_COMPLETED_RENEGOTIATION: 894 rv = DoCompletedRenegotiation(rv); 895 break; 896 case STATE_COMPLETED_HANDSHAKE: 897 next_state_ = STATE_COMPLETED_HANDSHAKE; 898 // This is the end of our state machine, so return. 899 return rv; 900 default: 901 rv = ERR_UNEXPECTED; 902 LOG(DFATAL) << "unexpected state " << state; 903 break; 904 } 905 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); 906 return rv; 907 } 908 909 int SSLClientSocketWin::DoHandshakeRead() { 910 next_state_ = STATE_HANDSHAKE_READ_COMPLETE; 911 912 if (!recv_buffer_.get()) 913 recv_buffer_.reset(new char[kRecvBufferSize]); 914 915 int buf_len = kRecvBufferSize - bytes_received_; 916 917 if (buf_len <= 0) { 918 LOG(DFATAL) << "Receive buffer is too small!"; 919 return ERR_UNEXPECTED; 920 } 921 922 DCHECK(!transport_read_buf_); 923 transport_read_buf_ = new IOBuffer(buf_len); 924 925 return transport_->socket()->Read(transport_read_buf_, buf_len, 926 &handshake_io_callback_); 927 } 928 929 int SSLClientSocketWin::DoHandshakeReadComplete(int result) { 930 if (result < 0) { 931 transport_read_buf_ = NULL; 932 return result; 933 } 934 935 if (transport_read_buf_) { 936 // A transition to STATE_HANDSHAKE_READ_COMPLETE is set in multiple places, 937 // not only in DoHandshakeRead(), so we may not have a transport_read_buf_. 938 DCHECK_LE(result, kRecvBufferSize - bytes_received_); 939 char* buf = recv_buffer_.get() + bytes_received_; 940 memcpy(buf, transport_read_buf_->data(), result); 941 transport_read_buf_ = NULL; 942 } 943 944 if (result == 0 && !ignore_ok_result_) 945 return ERR_SSL_PROTOCOL_ERROR; // Incomplete response :( 946 947 ignore_ok_result_ = false; 948 949 bytes_received_ += result; 950 951 // Process the contents of recv_buffer_. 952 TimeStamp expiry; 953 DWORD out_flags; 954 955 DWORD flags = ISC_REQ_SEQUENCE_DETECT | 956 ISC_REQ_REPLAY_DETECT | 957 ISC_REQ_CONFIDENTIALITY | 958 ISC_RET_EXTENDED_ERROR | 959 ISC_REQ_ALLOCATE_MEMORY | 960 ISC_REQ_STREAM; 961 962 if (ssl_config_.send_client_cert) 963 flags |= ISC_REQ_USE_SUPPLIED_CREDS; 964 965 SecBufferDesc in_buffer_desc, out_buffer_desc; 966 967 in_buffer_desc.cBuffers = 2; 968 in_buffer_desc.pBuffers = in_buffers_; 969 in_buffer_desc.ulVersion = SECBUFFER_VERSION; 970 971 in_buffers_[0].pvBuffer = recv_buffer_.get(); 972 in_buffers_[0].cbBuffer = bytes_received_; 973 in_buffers_[0].BufferType = SECBUFFER_TOKEN; 974 975 in_buffers_[1].pvBuffer = NULL; 976 in_buffers_[1].cbBuffer = 0; 977 in_buffers_[1].BufferType = SECBUFFER_EMPTY; 978 979 out_buffer_desc.cBuffers = 1; 980 out_buffer_desc.pBuffers = &send_buffer_; 981 out_buffer_desc.ulVersion = SECBUFFER_VERSION; 982 983 send_buffer_.pvBuffer = NULL; 984 send_buffer_.BufferType = SECBUFFER_TOKEN; 985 send_buffer_.cbBuffer = 0; 986 987 isc_status_ = InitializeSecurityContext( 988 creds_, 989 &ctxt_, 990 NULL, 991 flags, 992 0, 993 0, 994 &in_buffer_desc, 995 0, 996 NULL, 997 &out_buffer_desc, 998 &out_flags, 999 &expiry); 1000 1001 if (isc_status_ == SEC_E_INVALID_TOKEN) { 1002 // Peer sent us an SSL record type that's invalid during SSL handshake. 1003 // TODO(wtc): move this to MapSecurityError after sufficient testing. 1004 LOG(ERROR) << "InitializeSecurityContext failed: " << isc_status_; 1005 return ERR_SSL_PROTOCOL_ERROR; 1006 } 1007 1008 if (send_buffer_.cbBuffer != 0 && 1009 (isc_status_ == SEC_E_OK || 1010 isc_status_ == SEC_I_CONTINUE_NEEDED || 1011 (FAILED(isc_status_) && (out_flags & ISC_RET_EXTENDED_ERROR)))) { 1012 next_state_ = STATE_HANDSHAKE_WRITE; 1013 return OK; 1014 } 1015 return DidCallInitializeSecurityContext(); 1016 } 1017 1018 int SSLClientSocketWin::DidCallInitializeSecurityContext() { 1019 if (isc_status_ == SEC_E_INCOMPLETE_MESSAGE) { 1020 next_state_ = STATE_HANDSHAKE_READ; 1021 return OK; 1022 } 1023 1024 if (isc_status_ == SEC_E_OK) { 1025 if (in_buffers_[1].BufferType == SECBUFFER_EXTRA) { 1026 // Save this data for later. 1027 memmove(recv_buffer_.get(), 1028 recv_buffer_.get() + (bytes_received_ - in_buffers_[1].cbBuffer), 1029 in_buffers_[1].cbBuffer); 1030 bytes_received_ = in_buffers_[1].cbBuffer; 1031 } else { 1032 bytes_received_ = 0; 1033 } 1034 return DidCompleteHandshake(); 1035 } 1036 1037 if (FAILED(isc_status_)) { 1038 LOG(ERROR) << "InitializeSecurityContext failed: " << isc_status_; 1039 if (isc_status_ == SEC_E_INTERNAL_ERROR) { 1040 // "The Local Security Authority cannot be contacted". This happens 1041 // when the user denies access to the private key for SSL client auth. 1042 return ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED; 1043 } 1044 int result = MapSecurityError(isc_status_); 1045 // We told Schannel to not verify the server certificate 1046 // (SCH_CRED_MANUAL_CRED_VALIDATION), so any certificate error returned by 1047 // InitializeSecurityContext must be referring to the bad or missing 1048 // client certificate. 1049 if (IsCertificateError(result)) { 1050 // TODO(wtc): Add fine-grained error codes for client certificate errors 1051 // reported by the server using the following SSL/TLS alert messages: 1052 // access_denied 1053 // bad_certificate 1054 // unsupported_certificate 1055 // certificate_expired 1056 // certificate_revoked 1057 // certificate_unknown 1058 // unknown_ca 1059 return ERR_BAD_SSL_CLIENT_AUTH_CERT; 1060 } 1061 return result; 1062 } 1063 1064 if (isc_status_ == SEC_I_INCOMPLETE_CREDENTIALS) 1065 return ERR_SSL_CLIENT_AUTH_CERT_NEEDED; 1066 1067 if (isc_status_ == SEC_I_NO_RENEGOTIATION) { 1068 // Received a no_renegotiation alert message. Although this is just a 1069 // warning, SChannel doesn't seem to allow us to continue after this 1070 // point, so we have to return an error. See http://crbug.com/36835. 1071 return ERR_SSL_NO_RENEGOTIATION; 1072 } 1073 1074 DCHECK(isc_status_ == SEC_I_CONTINUE_NEEDED); 1075 if (in_buffers_[1].BufferType == SECBUFFER_EXTRA) { 1076 memmove(recv_buffer_.get(), 1077 recv_buffer_.get() + (bytes_received_ - in_buffers_[1].cbBuffer), 1078 in_buffers_[1].cbBuffer); 1079 bytes_received_ = in_buffers_[1].cbBuffer; 1080 next_state_ = STATE_HANDSHAKE_READ_COMPLETE; 1081 ignore_ok_result_ = true; // OK doesn't mean EOF. 1082 return OK; 1083 } 1084 1085 bytes_received_ = 0; 1086 next_state_ = STATE_HANDSHAKE_READ; 1087 return OK; 1088 } 1089 1090 int SSLClientSocketWin::DoHandshakeWrite() { 1091 next_state_ = STATE_HANDSHAKE_WRITE_COMPLETE; 1092 1093 // We should have something to send. 1094 DCHECK(send_buffer_.pvBuffer); 1095 DCHECK(send_buffer_.cbBuffer > 0); 1096 DCHECK(!transport_write_buf_); 1097 1098 const char* buf = static_cast<char*>(send_buffer_.pvBuffer) + bytes_sent_; 1099 int buf_len = send_buffer_.cbBuffer - bytes_sent_; 1100 transport_write_buf_ = new IOBuffer(buf_len); 1101 memcpy(transport_write_buf_->data(), buf, buf_len); 1102 1103 return transport_->socket()->Write(transport_write_buf_, buf_len, 1104 &handshake_io_callback_); 1105 } 1106 1107 int SSLClientSocketWin::DoHandshakeWriteComplete(int result) { 1108 DCHECK(transport_write_buf_); 1109 transport_write_buf_ = NULL; 1110 if (result < 0) 1111 return result; 1112 1113 DCHECK(result != 0); 1114 1115 bytes_sent_ += result; 1116 DCHECK(bytes_sent_ <= static_cast<int>(send_buffer_.cbBuffer)); 1117 1118 if (bytes_sent_ >= static_cast<int>(send_buffer_.cbBuffer)) { 1119 bool overflow = (bytes_sent_ > static_cast<int>(send_buffer_.cbBuffer)); 1120 FreeSendBuffer(); 1121 bytes_sent_ = 0; 1122 if (overflow) { // Bug! 1123 LOG(DFATAL) << "overflow"; 1124 return ERR_UNEXPECTED; 1125 } 1126 if (writing_first_token_) { 1127 writing_first_token_ = false; 1128 DCHECK(bytes_received_ == 0); 1129 next_state_ = STATE_HANDSHAKE_READ; 1130 return OK; 1131 } 1132 return DidCallInitializeSecurityContext(); 1133 } 1134 1135 // Send the remaining bytes. 1136 next_state_ = STATE_HANDSHAKE_WRITE; 1137 return OK; 1138 } 1139 1140 // Set server_cert_status_ and return OK or a network error. 1141 int SSLClientSocketWin::DoVerifyCert() { 1142 next_state_ = STATE_VERIFY_CERT_COMPLETE; 1143 1144 DCHECK(server_cert_); 1145 1146 int flags = 0; 1147 if (ssl_config_.rev_checking_enabled) 1148 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED; 1149 if (ssl_config_.verify_ev_cert) 1150 flags |= X509Certificate::VERIFY_EV_CERT; 1151 verifier_.reset(new SingleRequestCertVerifier(cert_verifier_)); 1152 return verifier_->Verify(server_cert_, host_and_port_.host(), flags, 1153 &server_cert_verify_result_, 1154 &handshake_io_callback_); 1155 } 1156 1157 int SSLClientSocketWin::DoVerifyCertComplete(int result) { 1158 DCHECK(verifier_.get()); 1159 verifier_.reset(); 1160 1161 // If we have been explicitly told to accept this certificate, override the 1162 // result of verifier_.Verify. 1163 // Eventually, we should cache the cert verification results so that we don't 1164 // need to call verifier_.Verify repeatedly. But for now we need to do this. 1165 // Alternatively, we could use the cert's status that we stored along with 1166 // the cert in the allowed_bad_certs vector. 1167 if (IsCertificateError(result) && 1168 ssl_config_.IsAllowedBadCert(server_cert_)) 1169 result = OK; 1170 1171 if (result == OK) 1172 LogConnectionTypeMetrics(); 1173 if (renegotiating_) { 1174 DidCompleteRenegotiation(); 1175 return result; 1176 } 1177 1178 // The initial handshake has completed. 1179 next_state_ = STATE_COMPLETED_HANDSHAKE; 1180 return result; 1181 } 1182 1183 int SSLClientSocketWin::DoPayloadRead() { 1184 DCHECK(recv_buffer_.get()); 1185 1186 int buf_len = kRecvBufferSize - bytes_received_; 1187 1188 if (buf_len <= 0) { 1189 NOTREACHED() << "Receive buffer is too small!"; 1190 return ERR_FAILED; 1191 } 1192 1193 int rv; 1194 // If bytes_received_, we have some data from a previous read still ready 1195 // for decoding. Otherwise, we need to issue a real read. 1196 if (!bytes_received_ || need_more_data_) { 1197 DCHECK(!transport_read_buf_); 1198 transport_read_buf_ = new IOBuffer(buf_len); 1199 1200 rv = transport_->socket()->Read(transport_read_buf_, buf_len, 1201 &read_callback_); 1202 if (rv != ERR_IO_PENDING) 1203 rv = DoPayloadReadComplete(rv); 1204 if (rv <= 0) 1205 return rv; 1206 } 1207 1208 // Decode what we've read. If there is not enough data to decode yet, 1209 // this may return ERR_IO_PENDING still. 1210 return DoPayloadDecrypt(); 1211 } 1212 1213 // result is the number of bytes that have been read; it should not be 1214 // less than zero; a value of zero means that no additional bytes have 1215 // been read. 1216 int SSLClientSocketWin::DoPayloadReadComplete(int result) { 1217 DCHECK(completed_handshake()); 1218 1219 // If IO Pending, there is nothing to do here. 1220 if (result == ERR_IO_PENDING) 1221 return result; 1222 1223 // We completed a Read, so reset the need_more_data_ flag. 1224 need_more_data_ = false; 1225 1226 // Check for error 1227 if (result <= 0) { 1228 transport_read_buf_ = NULL; 1229 if (result == 0 && bytes_received_ != 0) { 1230 // TODO(wtc): Unless we have received the close_notify alert, we need 1231 // to return an error code indicating that the SSL connection ended 1232 // uncleanly, a potential truncation attack. See 1233 // http://crbug.com/18586. 1234 return ERR_SSL_PROTOCOL_ERROR; 1235 } 1236 return result; 1237 } 1238 1239 // Transfer the data from transport_read_buf_ to recv_buffer_. 1240 if (transport_read_buf_) { 1241 DCHECK_LE(result, kRecvBufferSize - bytes_received_); 1242 char* buf = recv_buffer_.get() + bytes_received_; 1243 memcpy(buf, transport_read_buf_->data(), result); 1244 transport_read_buf_ = NULL; 1245 } 1246 1247 bytes_received_ += result; 1248 1249 return result; 1250 } 1251 1252 int SSLClientSocketWin::DoPayloadDecrypt() { 1253 // Process the contents of recv_buffer_. 1254 int len = 0; // the number of bytes we've copied to the user buffer. 1255 while (bytes_received_) { 1256 SecBuffer buffers[4]; 1257 buffers[0].pvBuffer = recv_buffer_.get(); 1258 buffers[0].cbBuffer = bytes_received_; 1259 buffers[0].BufferType = SECBUFFER_DATA; 1260 1261 buffers[1].BufferType = SECBUFFER_EMPTY; 1262 buffers[2].BufferType = SECBUFFER_EMPTY; 1263 buffers[3].BufferType = SECBUFFER_EMPTY; 1264 1265 SecBufferDesc buffer_desc; 1266 buffer_desc.cBuffers = 4; 1267 buffer_desc.pBuffers = buffers; 1268 buffer_desc.ulVersion = SECBUFFER_VERSION; 1269 1270 SECURITY_STATUS status; 1271 status = DecryptMessage(&ctxt_, &buffer_desc, 0, NULL); 1272 1273 if (status == SEC_E_INCOMPLETE_MESSAGE) { 1274 need_more_data_ = true; 1275 return DoPayloadRead(); 1276 } 1277 1278 if (status == SEC_I_CONTEXT_EXPIRED) { 1279 // Received the close_notify alert. 1280 bytes_received_ = 0; 1281 return OK; 1282 } 1283 1284 if (status != SEC_E_OK && status != SEC_I_RENEGOTIATE) { 1285 DCHECK(status != SEC_E_MESSAGE_ALTERED); 1286 LOG(ERROR) << "DecryptMessage failed: " << status; 1287 return MapSecurityError(status); 1288 } 1289 1290 // The received ciphertext was decrypted in place in recv_buffer_. Remember 1291 // the location and length of the decrypted plaintext and any unused 1292 // ciphertext. 1293 decrypted_ptr_ = NULL; 1294 bytes_decrypted_ = 0; 1295 received_ptr_ = NULL; 1296 bytes_received_ = 0; 1297 for (int i = 1; i < 4; i++) { 1298 switch (buffers[i].BufferType) { 1299 case SECBUFFER_DATA: 1300 DCHECK(!decrypted_ptr_ && bytes_decrypted_ == 0); 1301 decrypted_ptr_ = static_cast<char*>(buffers[i].pvBuffer); 1302 bytes_decrypted_ = buffers[i].cbBuffer; 1303 break; 1304 case SECBUFFER_EXTRA: 1305 DCHECK(!received_ptr_ && bytes_received_ == 0); 1306 received_ptr_ = static_cast<char*>(buffers[i].pvBuffer); 1307 bytes_received_ = buffers[i].cbBuffer; 1308 break; 1309 default: 1310 break; 1311 } 1312 } 1313 1314 DCHECK(len == 0); 1315 if (bytes_decrypted_ != 0) { 1316 len = std::min(user_read_buf_len_, bytes_decrypted_); 1317 memcpy(user_read_buf_->data(), decrypted_ptr_, len); 1318 decrypted_ptr_ += len; 1319 bytes_decrypted_ -= len; 1320 } 1321 if (bytes_decrypted_ == 0) { 1322 decrypted_ptr_ = NULL; 1323 if (bytes_received_ != 0) { 1324 memmove(recv_buffer_.get(), received_ptr_, bytes_received_); 1325 received_ptr_ = recv_buffer_.get(); 1326 } 1327 } 1328 1329 if (status == SEC_I_RENEGOTIATE) { 1330 if (bytes_received_ != 0) { 1331 // The server requested renegotiation, but there are some data yet to 1332 // be decrypted. The Platform SDK WebClient.c sample doesn't handle 1333 // this, so we don't know how to handle this. Assume this cannot 1334 // happen. 1335 LOG(ERROR) << "DecryptMessage returned SEC_I_RENEGOTIATE with a buffer " 1336 << "of type SECBUFFER_EXTRA."; 1337 return ERR_SSL_RENEGOTIATION_REQUESTED; 1338 } 1339 if (len != 0) { 1340 // The server requested renegotiation, but there are some decrypted 1341 // data. We can't start renegotiation until we have returned all 1342 // decrypted data to the caller. 1343 // 1344 // This hasn't happened during testing. Assume this cannot happen even 1345 // though we know how to handle this. 1346 LOG(ERROR) << "DecryptMessage returned SEC_I_RENEGOTIATE with a buffer " 1347 << "of type SECBUFFER_DATA."; 1348 return ERR_SSL_RENEGOTIATION_REQUESTED; 1349 } 1350 // Jump to the handshake sequence. Will come back when the rehandshake is 1351 // done. 1352 renegotiating_ = true; 1353 ignore_ok_result_ = true; // OK doesn't mean EOF. 1354 // If renegotiation handshake occurred, we need to go back into the 1355 // handshake state machine. 1356 next_state_ = STATE_HANDSHAKE_READ_COMPLETE; 1357 return DoLoop(OK); 1358 } 1359 1360 // We've already copied data into the user buffer, so quit now. 1361 // TODO(mbelshe): We really should keep decoding as long as we can. This 1362 // break out is causing us to return pretty small chunks of data up to the 1363 // application, even though more is already buffered and ready to be 1364 // decoded. 1365 if (len) 1366 break; 1367 } 1368 1369 // If we decrypted 0 bytes, don't report 0 bytes read, which would be 1370 // mistaken for EOF. Continue decrypting or read more. 1371 if (len == 0) 1372 return DoPayloadRead(); 1373 return len; 1374 } 1375 1376 int SSLClientSocketWin::DoPayloadEncrypt() { 1377 DCHECK(completed_handshake()); 1378 DCHECK(user_write_buf_); 1379 DCHECK(user_write_buf_len_ > 0); 1380 1381 ULONG message_len = std::min( 1382 stream_sizes_.cbMaximumMessage, static_cast<ULONG>(user_write_buf_len_)); 1383 ULONG alloc_len = 1384 message_len + stream_sizes_.cbHeader + stream_sizes_.cbTrailer; 1385 user_write_buf_len_ = message_len; 1386 1387 payload_send_buffer_.reset(new char[alloc_len]); 1388 memcpy(&payload_send_buffer_[stream_sizes_.cbHeader], 1389 user_write_buf_->data(), message_len); 1390 1391 SecBuffer buffers[4]; 1392 buffers[0].pvBuffer = payload_send_buffer_.get(); 1393 buffers[0].cbBuffer = stream_sizes_.cbHeader; 1394 buffers[0].BufferType = SECBUFFER_STREAM_HEADER; 1395 1396 buffers[1].pvBuffer = &payload_send_buffer_[stream_sizes_.cbHeader]; 1397 buffers[1].cbBuffer = message_len; 1398 buffers[1].BufferType = SECBUFFER_DATA; 1399 1400 buffers[2].pvBuffer = &payload_send_buffer_[stream_sizes_.cbHeader + 1401 message_len]; 1402 buffers[2].cbBuffer = stream_sizes_.cbTrailer; 1403 buffers[2].BufferType = SECBUFFER_STREAM_TRAILER; 1404 1405 buffers[3].BufferType = SECBUFFER_EMPTY; 1406 1407 SecBufferDesc buffer_desc; 1408 buffer_desc.cBuffers = 4; 1409 buffer_desc.pBuffers = buffers; 1410 buffer_desc.ulVersion = SECBUFFER_VERSION; 1411 1412 SECURITY_STATUS status = EncryptMessage(&ctxt_, 0, &buffer_desc, 0); 1413 1414 if (FAILED(status)) { 1415 LOG(ERROR) << "EncryptMessage failed: " << status; 1416 return MapSecurityError(status); 1417 } 1418 1419 payload_send_buffer_len_ = buffers[0].cbBuffer + 1420 buffers[1].cbBuffer + 1421 buffers[2].cbBuffer; 1422 DCHECK(bytes_sent_ == 0); 1423 return OK; 1424 } 1425 1426 int SSLClientSocketWin::DoPayloadWrite() { 1427 DCHECK(completed_handshake()); 1428 1429 // We should have something to send. 1430 DCHECK(payload_send_buffer_.get()); 1431 DCHECK(payload_send_buffer_len_ > 0); 1432 DCHECK(!transport_write_buf_); 1433 1434 const char* buf = payload_send_buffer_.get() + bytes_sent_; 1435 int buf_len = payload_send_buffer_len_ - bytes_sent_; 1436 transport_write_buf_ = new IOBuffer(buf_len); 1437 memcpy(transport_write_buf_->data(), buf, buf_len); 1438 1439 int rv = transport_->socket()->Write(transport_write_buf_, buf_len, 1440 &write_callback_); 1441 if (rv != ERR_IO_PENDING) 1442 rv = DoPayloadWriteComplete(rv); 1443 return rv; 1444 } 1445 1446 int SSLClientSocketWin::DoPayloadWriteComplete(int result) { 1447 DCHECK(transport_write_buf_); 1448 transport_write_buf_ = NULL; 1449 if (result < 0) 1450 return result; 1451 1452 DCHECK(result != 0); 1453 1454 bytes_sent_ += result; 1455 DCHECK(bytes_sent_ <= payload_send_buffer_len_); 1456 1457 if (bytes_sent_ >= payload_send_buffer_len_) { 1458 bool overflow = (bytes_sent_ > payload_send_buffer_len_); 1459 payload_send_buffer_.reset(); 1460 payload_send_buffer_len_ = 0; 1461 bytes_sent_ = 0; 1462 if (overflow) { // Bug! 1463 LOG(DFATAL) << "overflow"; 1464 return ERR_UNEXPECTED; 1465 } 1466 // Done 1467 return user_write_buf_len_; 1468 } 1469 1470 // Send the remaining bytes. 1471 return DoPayloadWrite(); 1472 } 1473 1474 int SSLClientSocketWin::DoCompletedRenegotiation(int result) { 1475 // The user had a read in progress, which was usurped by the renegotiation. 1476 // Restart the read sequence. 1477 next_state_ = STATE_COMPLETED_HANDSHAKE; 1478 if (result != OK) 1479 return result; 1480 return DoPayloadRead(); 1481 } 1482 1483 int SSLClientSocketWin::DidCompleteHandshake() { 1484 SECURITY_STATUS status = QueryContextAttributes( 1485 &ctxt_, SECPKG_ATTR_STREAM_SIZES, &stream_sizes_); 1486 if (status != SEC_E_OK) { 1487 LOG(ERROR) << "QueryContextAttributes (stream sizes) failed: " << status; 1488 return MapSecurityError(status); 1489 } 1490 DCHECK(!server_cert_ || renegotiating_); 1491 PCCERT_CONTEXT server_cert_handle = NULL; 1492 status = QueryContextAttributes( 1493 &ctxt_, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &server_cert_handle); 1494 if (status != SEC_E_OK) { 1495 LOG(ERROR) << "QueryContextAttributes (remote cert) failed: " << status; 1496 return MapSecurityError(status); 1497 } 1498 if (renegotiating_ && 1499 X509Certificate::IsSameOSCert(server_cert_->os_cert_handle(), 1500 server_cert_handle)) { 1501 // We already verified the server certificate. Either it is good or the 1502 // user has accepted the certificate error. 1503 DidCompleteRenegotiation(); 1504 } else { 1505 server_cert_ = X509Certificate::CreateFromHandle( 1506 server_cert_handle, X509Certificate::SOURCE_FROM_NETWORK, 1507 X509Certificate::OSCertHandles()); 1508 1509 next_state_ = STATE_VERIFY_CERT; 1510 } 1511 CertFreeCertificateContext(server_cert_handle); 1512 return OK; 1513 } 1514 1515 // Called when a renegotiation is completed. |result| is the verification 1516 // result of the server certificate received during renegotiation. 1517 void SSLClientSocketWin::DidCompleteRenegotiation() { 1518 DCHECK(!user_connect_callback_); 1519 DCHECK(user_read_callback_); 1520 renegotiating_ = false; 1521 next_state_ = STATE_COMPLETED_RENEGOTIATION; 1522 } 1523 1524 void SSLClientSocketWin::LogConnectionTypeMetrics() const { 1525 UpdateConnectionTypeHistograms(CONNECTION_SSL); 1526 if (server_cert_verify_result_.has_md5) 1527 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5); 1528 if (server_cert_verify_result_.has_md2) 1529 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2); 1530 if (server_cert_verify_result_.has_md4) 1531 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD4); 1532 if (server_cert_verify_result_.has_md5_ca) 1533 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5_CA); 1534 if (server_cert_verify_result_.has_md2_ca) 1535 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2_CA); 1536 } 1537 1538 void SSLClientSocketWin::FreeSendBuffer() { 1539 SECURITY_STATUS status = FreeContextBuffer(send_buffer_.pvBuffer); 1540 DCHECK(status == SEC_E_OK); 1541 memset(&send_buffer_, 0, sizeof(send_buffer_)); 1542 } 1543 1544 } // namespace net 1545