1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick// Use of this source code is governed by a BSD-style license that can be 3c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick// found in the LICENSE file. 4c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 5c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick// OpenSSL binding for SSLClientSocket. The class layout and general principle 6c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick// of operation is derived from SSLClientSocketNSS. 700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#include "net/socket/ssl_client_socket_openssl.h" 900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 10c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick#include <openssl/ssl.h> 11c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick#include <openssl/err.h> 120dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen#ifdef ANDROID 130dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen#include <string> 140dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen#endif 15c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/singleton.h" 17731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/metrics/histogram.h" 1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/synchronization/lock.h" 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/openssl_util.h" 204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "net/base/cert_verifier.h" 2100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#include "net/base/net_errors.h" 2221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/base/openssl_private_key_store.h" 2321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/base/ssl_cert_request_info.h" 24c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick#include "net/base/ssl_connection_status_flags.h" 25c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick#include "net/base/ssl_info.h" 2621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/socket/ssl_error_params.h" 2700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 2800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochnamespace net { 2900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 30c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merricknamespace { 31c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 32c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick// Enable this to see logging for state machine state transitions. 33c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick#if 0 34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#define GotoState(s) do { DVLOG(2) << (void *)this << " " << __FUNCTION__ << \ 3500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch " jump to state " << s; \ 3600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch next_handshake_state_ = s; } while (0) 37c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick#else 38c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick#define GotoState(s) next_handshake_state_ = s 3900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#endif 4000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 41c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrickconst size_t kMaxRecvBufferSize = 4096; 42201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst int kSessionCacheTimeoutSeconds = 60 * 60; 43201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst size_t kSessionCacheMaxEntires = 1024; 4400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 45731158395b8ae1105c69cc42dae6244385f6b4ffBrian Carlstrom#if OPENSSL_VERSION_NUMBER < 0x1000100fL 46731158395b8ae1105c69cc42dae6244385f6b4ffBrian Carlstrom// This method was first included in OpenSSL 1.0.1. 47731158395b8ae1105c69cc42dae6244385f6b4ffBrian Carlstromunsigned long SSL_CIPHER_get_id(const SSL_CIPHER* cipher) { return cipher->id; } 48731158395b8ae1105c69cc42dae6244385f6b4ffBrian Carlstrom#endif 49731158395b8ae1105c69cc42dae6244385f6b4ffBrian Carlstrom 5021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Used for encoding the |connection_status| field of an SSLInfo object. 5121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint EncodeSSLConnectionStatus(int cipher_suite, 5221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int compression, 5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int version) { 5421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ((cipher_suite & SSL_CONNECTION_CIPHERSUITE_MASK) << 5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SSL_CONNECTION_CIPHERSUITE_SHIFT) | 5621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ((compression & SSL_CONNECTION_COMPRESSION_MASK) << 5721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SSL_CONNECTION_COMPRESSION_SHIFT) | 5821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ((version & SSL_CONNECTION_VERSION_MASK) << 5921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SSL_CONNECTION_VERSION_SHIFT); 6021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 6121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 6221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Returns the net SSL version number (see ssl_connection_status_flags.h) for 6321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// this SSL connection. 6421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint GetNetSSLVersion(SSL* ssl) { 6521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen switch (SSL_version(ssl)) { 6621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL2_VERSION: 6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return SSL_CONNECTION_VERSION_SSL2; 6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL3_VERSION: 6921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return SSL_CONNECTION_VERSION_SSL3; 7021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case TLS1_VERSION: 7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return SSL_CONNECTION_VERSION_TLS1; 7221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case 0x0302: 7321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return SSL_CONNECTION_VERSION_TLS1_1; 7421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case 0x0303: 7521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return SSL_CONNECTION_VERSION_TLS1_2; 7621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen default: 7721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return SSL_CONNECTION_VERSION_UNKNOWN; 7821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 7921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 8021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 8121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint MapOpenSSLErrorSSL() { 8221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Walk down the error stack to find the SSLerr generated reason. 8321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen unsigned long error_code; 8421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen do { 8521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen error_code = ERR_get_error(); 8621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (error_code == 0) 8721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_SSL_PROTOCOL_ERROR; 8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } while (ERR_GET_LIB(error_code) != ERR_LIB_SSL); 8921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 9021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DVLOG(1) << "OpenSSL SSL error, reason: " << ERR_GET_REASON(error_code) 9121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen << ", name: " << ERR_error_string(error_code, NULL); 9221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen switch (ERR_GET_REASON(error_code)) { 9321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_READ_TIMEOUT_EXPIRED: 9421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_TIMED_OUT; 9521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_BAD_RESPONSE_ARGUMENT: 9621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_INVALID_ARGUMENT; 9721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_UNKNOWN_CERTIFICATE_TYPE: 9821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_UNKNOWN_CIPHER_TYPE: 9921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE: 10021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_UNKNOWN_PKEY_TYPE: 10121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_UNKNOWN_REMOTE_ERROR_TYPE: 10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_UNKNOWN_SSL_VERSION: 10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_NOT_IMPLEMENTED; 10421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_UNSUPPORTED_SSL_VERSION: 10521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_NO_CIPHER_MATCH: 10621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_NO_SHARED_CIPHER: 10721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY: 10821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION: 10921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_SSL_VERSION_OR_CIPHER_MISMATCH; 11021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE: 11121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE: 11221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED: 11321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED: 11421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN: 11521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_TLSV1_ALERT_ACCESS_DENIED: 11621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_TLSV1_ALERT_UNKNOWN_CA: 11721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_BAD_SSL_CLIENT_AUTH_CERT; 11821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_BAD_DECOMPRESSION: 11921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE: 12021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_SSL_DECOMPRESSION_FAILURE_ALERT; 12121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_SSLV3_ALERT_BAD_RECORD_MAC: 12221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_SSL_BAD_RECORD_MAC_ALERT; 12321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED: 12421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_SSL_UNSAFE_NEGOTIATION; 12521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_WRONG_NUMBER_OF_KEY_BITS: 12621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY; 12721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // SSL_R_UNKNOWN_PROTOCOL is reported if premature application data is 12821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // received (see http://crbug.com/42538), and also if all the protocol 12921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // versions supported by the server were disabled in this socket instance. 13021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Mapped to ERR_SSL_PROTOCOL_ERROR for compatibility with other SSL sockets 13121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // in the former scenario. 13221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_UNKNOWN_PROTOCOL: 13321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_SSL_HANDSHAKE_FAILURE: 13421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_DECRYPTION_FAILED: 13521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC: 13621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG: 13721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_DIGEST_CHECK_FAILED: 13821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_DUPLICATE_COMPRESSION_ID: 13921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER: 14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_ENCRYPTED_LENGTH_TOO_LONG: 14121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST: 14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_EXCESSIVE_MESSAGE_SIZE: 14321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_EXTRA_DATA_IN_MESSAGE: 14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_GOT_A_FIN_BEFORE_A_CCS: 14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_ILLEGAL_PADDING: 14621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_INVALID_CHALLENGE_LENGTH: 14721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_INVALID_COMMAND: 14821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_INVALID_PURPOSE: 14921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_INVALID_STATUS_RESPONSE: 15021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_INVALID_TICKET_KEYS_LENGTH: 15121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_KEY_ARG_TOO_LONG: 15221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_READ_WRONG_PACKET_TYPE: 15321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE: 15421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // TODO(joth): SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE may be returned from the 15521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // server after receiving ClientHello if there's no common supported cipher. 15621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Ideally we'd map that specific case to ERR_SSL_VERSION_OR_CIPHER_MISMATCH 15721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // to match the NSS implementation. See also http://goo.gl/oMtZW 15821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE: 15921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_SSLV3_ALERT_NO_CERTIFICATE: 16021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER: 16121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_TLSV1_ALERT_DECODE_ERROR: 16221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_TLSV1_ALERT_DECRYPTION_FAILED: 16321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_TLSV1_ALERT_DECRYPT_ERROR: 16421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION: 16521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_TLSV1_ALERT_INTERNAL_ERROR: 16621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_TLSV1_ALERT_NO_RENEGOTIATION: 16721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_TLSV1_ALERT_RECORD_OVERFLOW: 16821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_R_TLSV1_ALERT_USER_CANCELLED: 16921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_SSL_PROTOCOL_ERROR; 17021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen default: 17121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LOG(WARNING) << "Unmapped error reason: " << ERR_GET_REASON(error_code); 17221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_FAILED; 17321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 17421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 17521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 17621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Converts an OpenSSL error code into a net error code, walking the OpenSSL 17721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// error stack if needed. Note that |tracer| is not currently used in the 17821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// implementation, but is passed in anyway as this ensures the caller will clear 17921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// any residual codes left on the error stack. 180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint MapOpenSSLError(int err, const crypto::OpenSSLErrStackTracer& tracer) { 181c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick switch (err) { 182c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick case SSL_ERROR_WANT_READ: 183c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick case SSL_ERROR_WANT_WRITE: 184c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick return ERR_IO_PENDING; 185731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick case SSL_ERROR_SYSCALL: 186731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DVLOG(1) << "OpenSSL SYSCALL error, errno " << errno; 187731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ERR_SSL_PROTOCOL_ERROR; 18821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case SSL_ERROR_SSL: 18921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return MapOpenSSLErrorSSL(); 190c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick default: 191c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick // TODO(joth): Implement full mapping. 192c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick LOG(WARNING) << "Unknown OpenSSL error " << err; 193c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick return ERR_SSL_PROTOCOL_ERROR; 19400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch } 19500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 19600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 1974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// We do certificate verification after handshake, so we disable the default 1984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// by registering a no-op verify function. 1994a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochint NoOpVerifyCallback(X509_STORE_CTX*, void *) { 2004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch DVLOG(3) << "skipping cert verify"; 2014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return 1; 2024a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 2034a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 204201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// OpenSSL manages a cache of SSL_SESSION, this class provides the application 205201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// side policy for that cache about session re-use: we retain one session per 206201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// unique HostPortPair. 207201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochclass SSLSessionCache { 208201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch public: 209201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SSLSessionCache() {} 210201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 211201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch void OnSessionAdded(const HostPortPair& host_and_port, SSL_SESSION* session) { 212201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Declare the session cleaner-upper before the lock, so any call into 213201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // OpenSSL to free the session will happen after the lock is released. 214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen crypto::ScopedOpenSSL<SSL_SESSION, SSL_SESSION_free> session_to_free; 21572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 216201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 217201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK_EQ(0U, session_map_.count(session)); 218201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::pair<HostPortMap::iterator, bool> res = 219201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch host_port_map_.insert(std::make_pair(host_and_port, session)); 220201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (!res.second) { // Already exists: replace old entry. 221201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch session_to_free.reset(res.first->second); 222201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch session_map_.erase(session_to_free.get()); 223201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch res.first->second = session; 224201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 225201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DVLOG(2) << "Adding session " << session << " => " 226201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << host_and_port.ToString() << ", new entry = " << res.second; 227201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(host_port_map_[host_and_port] == session); 228201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch session_map_[session] = res.first; 229201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK_EQ(host_port_map_.size(), session_map_.size()); 230201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK_LE(host_port_map_.size(), kSessionCacheMaxEntires); 2314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 232201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 233201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch void OnSessionRemoved(SSL_SESSION* session) { 234201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Declare the session cleaner-upper before the lock, so any call into 235201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // OpenSSL to free the session will happen after the lock is released. 236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen crypto::ScopedOpenSSL<SSL_SESSION, SSL_SESSION_free> session_to_free; 23772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 238201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 239201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SessionMap::iterator it = session_map_.find(session); 240201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (it == session_map_.end()) 241201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return; 242201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DVLOG(2) << "Remove session " << session << " => " 243201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << it->second->first.ToString(); 244201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(it->second->second == session); 245201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch host_port_map_.erase(it->second); 246201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch session_map_.erase(it); 247201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch session_to_free.reset(session); 248201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK_EQ(host_port_map_.size(), session_map_.size()); 2494a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 250201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 251201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Looks up the host:port in the cache, and if a session is found it is added 252201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // to |ssl|, returning true on success. 253201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch bool SetSSLSession(SSL* ssl, const HostPortPair& host_and_port) { 25472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 255201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HostPortMap::iterator it = host_port_map_.find(host_and_port); 256201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (it == host_port_map_.end()) 257201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return false; 258201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DVLOG(2) << "Lookup session: " << it->second << " => " 259201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << host_and_port.ToString(); 260201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SSL_SESSION* session = it->second; 261201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(session); 262201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(session_map_[session] == it); 263201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Ideally we'd release |lock_| before calling into OpenSSL here, however 264201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // that opens a small risk |session| will go out of scope before it is used. 265201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Alternatively we would take a temporary local refcount on |session|, 266201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // except OpenSSL does not provide a public API for adding a ref (c.f. 267201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // SSL_SESSION_free which decrements the ref). 268201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return SSL_set_session(ssl, session) == 1; 269201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 270201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 271201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch private: 272201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // A pair of maps to allow bi-directional lookups between host:port and an 27321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // associated session. 274201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // TODO(joth): When client certificates are implemented we should key the 275201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // cache on the client certificate used in addition to the host-port pair. 276201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch typedef std::map<HostPortPair, SSL_SESSION*> HostPortMap; 277201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch typedef std::map<SSL_SESSION*, HostPortMap::iterator> SessionMap; 278201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch HostPortMap host_port_map_; 279201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SessionMap session_map_; 280201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 281201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Protects access to both the above maps. 28272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::Lock lock_; 283201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 284201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DISALLOW_COPY_AND_ASSIGN(SSLSessionCache); 2854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}; 2864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 287201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochclass SSLContext { 288201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch public: 28921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen static SSLContext* GetInstance() { return Singleton<SSLContext>::get(); } 290201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SSL_CTX* ssl_ctx() { return ssl_ctx_.get(); } 291201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SSLSessionCache* session_cache() { return &session_cache_; } 292201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 293201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SSLClientSocketOpenSSL* GetClientSocketFromSSL(SSL* ssl) { 294201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(ssl); 295201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SSLClientSocketOpenSSL* socket = static_cast<SSLClientSocketOpenSSL*>( 296201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SSL_get_ex_data(ssl, ssl_socket_data_index_)); 297201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(socket); 298201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return socket; 299201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 300201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 301201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch bool SetClientSocketForSSL(SSL* ssl, SSLClientSocketOpenSSL* socket) { 302201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return SSL_set_ex_data(ssl, ssl_socket_data_index_, socket) != 0; 303201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 304201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 305201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch private: 306201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch friend struct DefaultSingletonTraits<SSLContext>; 307201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 308201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SSLContext() { 309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen crypto::EnsureOpenSSLInit(); 310201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ssl_socket_data_index_ = SSL_get_ex_new_index(0, 0, 0, 0, 0); 311201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK_NE(ssl_socket_data_index_, -1); 312201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ssl_ctx_.reset(SSL_CTX_new(SSLv23_client_method())); 313201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SSL_CTX_set_cert_verify_callback(ssl_ctx_.get(), NoOpVerifyCallback, NULL); 314201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SSL_CTX_set_session_cache_mode(ssl_ctx_.get(), SSL_SESS_CACHE_CLIENT); 315201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SSL_CTX_sess_set_new_cb(ssl_ctx_.get(), NewSessionCallbackStatic); 316201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SSL_CTX_sess_set_remove_cb(ssl_ctx_.get(), RemoveSessionCallbackStatic); 317201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SSL_CTX_set_timeout(ssl_ctx_.get(), kSessionCacheTimeoutSeconds); 318201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SSL_CTX_sess_set_cache_size(ssl_ctx_.get(), kSessionCacheMaxEntires); 31921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SSL_CTX_set_client_cert_cb(ssl_ctx_.get(), ClientCertCallback); 3200dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen#if defined(OPENSSL_NPN_NEGOTIATED) 3210dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen // TODO(kristianm): Only select this if ssl_config_.next_proto is not empty. 3220dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen // It would be better if the callback were not a global setting, 3230dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen // but that is an OpenSSL issue. 3240dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen SSL_CTX_set_next_proto_select_cb(ssl_ctx_.get(), SelectNextProtoCallback, 3250dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen NULL); 3260dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen#endif 327201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 328201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 329201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static int NewSessionCallbackStatic(SSL* ssl, SSL_SESSION* session) { 33021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return GetInstance()->NewSessionCallback(ssl, session); 331201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 332201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 333201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int NewSessionCallback(SSL* ssl, SSL_SESSION* session) { 334201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SSLClientSocketOpenSSL* socket = GetClientSocketFromSSL(ssl); 335201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch session_cache_.OnSessionAdded(socket->host_and_port(), session); 336201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return 1; // 1 => We took ownership of |session|. 337201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 338201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 339201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static void RemoveSessionCallbackStatic(SSL_CTX* ctx, SSL_SESSION* session) { 34021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return GetInstance()->RemoveSessionCallback(ctx, session); 341201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 342201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 343201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch void RemoveSessionCallback(SSL_CTX* ctx, SSL_SESSION* session) { 344201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(ctx == ssl_ctx()); 345201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch session_cache_.OnSessionRemoved(session); 346201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 347201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 34821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen static int ClientCertCallback(SSL* ssl, X509** x509, EVP_PKEY** pkey) { 34921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl); 35021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CHECK(socket); 35121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return socket->ClientCertRequestCallback(ssl, x509, pkey); 35221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 35321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 3540dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen static int SelectNextProtoCallback(SSL* ssl, 3550dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen unsigned char** out, unsigned char* outlen, 3560dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen const unsigned char* in, 3570dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen unsigned int inlen, void* arg) { 35821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl); 35921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return socket->SelectNextProtoCallback(out, outlen, in, inlen); 36021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 3610dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen 362201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // This is the index used with SSL_get_ex_data to retrieve the owner 363201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // SSLClientSocketOpenSSL object from an SSL instance. 364201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int ssl_socket_data_index_; 365201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen crypto::ScopedOpenSSL<SSL_CTX, SSL_CTX_free> ssl_ctx_; 367201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch SSLSessionCache session_cache_; 368201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}; 3694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 3708db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom// Utility to construct the appropriate set & clear masks for use the OpenSSL 3718db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom// options and mode configuration functions. (SSL_set_options etc) 3728db08726a8eea9d32f637ced774aac6b16416071Brian Carlstromstruct SslSetClearMask { 3738db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom SslSetClearMask() : set_mask(0), clear_mask(0) {} 3748db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom void ConfigureFlag(long flag, bool state) { 3758db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom (state ? set_mask : clear_mask) |= flag; 3768db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom // Make sure we haven't got any intersection in the set & clear options. 3778db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom DCHECK_EQ(0, set_mask & clear_mask) << flag << ":" << state; 3788db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom } 3798db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom long set_mask; 3808db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom long clear_mask; 3818db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom}; 3828db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom 383c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick} // namespace 384c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 385c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain MerrickSSLClientSocketOpenSSL::SSLClientSocketOpenSSL( 386c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick ClientSocketHandle* transport_socket, 3874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const HostPortPair& host_and_port, 38821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const SSLConfig& ssl_config, 38921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CertVerifier* cert_verifier) 390c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick : ALLOW_THIS_IN_INITIALIZER_LIST(buffer_send_callback_( 391c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick this, &SSLClientSocketOpenSSL::BufferSendComplete)), 392c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick ALLOW_THIS_IN_INITIALIZER_LIST(buffer_recv_callback_( 393c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick this, &SSLClientSocketOpenSSL::BufferRecvComplete)), 394c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick transport_send_busy_(false), 39500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch transport_recv_busy_(false), 39600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_connect_callback_(NULL), 39700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_read_callback_(NULL), 39800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_write_callback_(NULL), 399201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch completed_handshake_(false), 40000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch client_auth_cert_needed_(false), 40121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen cert_verifier_(cert_verifier), 402731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ALLOW_THIS_IN_INITIALIZER_LIST(handshake_io_callback_( 403731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick this, &SSLClientSocketOpenSSL::OnHandshakeIOComplete)), 404c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick ssl_(NULL), 405c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick transport_bio_(NULL), 40600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch transport_(transport_socket), 4074a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch host_and_port_(host_and_port), 40800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch ssl_config_(ssl_config), 409201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch trying_cached_session_(false), 41021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen npn_status_(kNextProtoUnsupported), 41100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch net_log_(transport_socket->socket()->NetLog()) { 41200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 41300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 41400d26a728db2814620f390b418a7d6325ce5aca6Ben MurdochSSLClientSocketOpenSSL::~SSLClientSocketOpenSSL() { 41500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch Disconnect(); 41600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 41700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 418c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrickbool SSLClientSocketOpenSSL::Init() { 419731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(!ssl_); 420731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(!transport_bio_); 421731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 42221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SSLContext* context = SSLContext::GetInstance(); 423ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 424201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 425201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ssl_ = SSL_new(context->ssl_ctx()); 426201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (!ssl_ || !context->SetClientSocketForSSL(ssl_, this)) 427c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick return false; 428c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 429201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (!SSL_set_tlsext_host_name(ssl_, host_and_port_.host().c_str())) 430c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick return false; 431201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 432201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch trying_cached_session_ = 433201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch context->session_cache()->SetSSLSession(ssl_, host_and_port_); 434c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 435c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick BIO* ssl_bio = NULL; 436201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // 0 => use default buffer sizes. 437201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (!BIO_new_bio_pair(&ssl_bio, 0, &transport_bio_, 0)) 438c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick return false; 439c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick DCHECK(ssl_bio); 440c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick DCHECK(transport_bio_); 441c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 442c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick SSL_set_bio(ssl_, ssl_bio, ssl_bio); 443c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 444731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // OpenSSL defaults some options to on, others to off. To avoid ambiguity, 445731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // set everything we care about to an absolute value. 4468db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom SslSetClearMask options; 4478db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom options.ConfigureFlag(SSL_OP_NO_SSLv2, true); 4488db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom options.ConfigureFlag(SSL_OP_NO_SSLv3, !ssl_config_.ssl3_enabled); 4498db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom options.ConfigureFlag(SSL_OP_NO_TLSv1, !ssl_config_.tls1_enabled); 450fb292835997c64a14669de65d74ba5357aa4d7d7Selim Gurun#ifdef SSL_OP_NO_TLSv1_1 451fb292835997c64a14669de65d74ba5357aa4d7d7Selim Gurun options.ConfigureFlag(SSL_OP_NO_TLSv1_1, true); 452fb292835997c64a14669de65d74ba5357aa4d7d7Selim Gurun#endif 453fb292835997c64a14669de65d74ba5357aa4d7d7Selim Gurun#ifdef SSL_OP_NO_TLSv1_2 454fb292835997c64a14669de65d74ba5357aa4d7d7Selim Gurun options.ConfigureFlag(SSL_OP_NO_TLSv1_2, true); 455fb292835997c64a14669de65d74ba5357aa4d7d7Selim Gurun#endif 4568db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom 4578db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom#if defined(SSL_OP_NO_COMPRESSION) 4588db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom // If TLS was disabled also disable compression, to provide maximum site 4598db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom // compatibility in the case of protocol fallback. See http://crbug.com/31628 460de6c9f9aec5e2e7e66cb77140f7418fc29644ef0Selim Gurun#ifdef ANDROID 461de6c9f9aec5e2e7e66cb77140f7418fc29644ef0Selim Gurun options.ConfigureFlag(SSL_OP_NO_COMPRESSION, true); 462de6c9f9aec5e2e7e66cb77140f7418fc29644ef0Selim Gurun#else 4638db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom options.ConfigureFlag(SSL_OP_NO_COMPRESSION, !ssl_config_.tls1_enabled); 4648db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom#endif 465de6c9f9aec5e2e7e66cb77140f7418fc29644ef0Selim Gurun#endif 466731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 467731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // TODO(joth): Set this conditionally, see http://crbug.com/55410 4688db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom options.ConfigureFlag(SSL_OP_LEGACY_SERVER_CONNECT, true); 4698db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom 4708db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom SSL_set_options(ssl_, options.set_mask); 4718db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom SSL_clear_options(ssl_, options.clear_mask); 47221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 47321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Same as above, this time for the SSL mode. 47421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SslSetClearMask mode; 47521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 47621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#if defined(SSL_MODE_HANDSHAKE_CUTTHROUGH) 47721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen mode.ConfigureFlag(SSL_MODE_HANDSHAKE_CUTTHROUGH, 47821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ssl_config_.false_start_enabled && 47921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen !SSLConfigService::IsKnownFalseStartIncompatibleServer( 48021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen host_and_port_.host())); 48121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#endif 48221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 48321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#if defined(SSL_MODE_RELEASE_BUFFERS) 48421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen mode.ConfigureFlag(SSL_MODE_RELEASE_BUFFERS, true); 48521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#endif 48621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 4878db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom#if defined(SSL_MODE_SMALL_BUFFERS) 4888db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom mode.ConfigureFlag(SSL_MODE_SMALL_BUFFERS, true); 4898db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom#endif 490731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 4918db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom SSL_set_mode(ssl_, mode.set_mask); 4928db08726a8eea9d32f637ced774aac6b16416071Brian Carlstrom SSL_clear_mode(ssl_, mode.clear_mask); 49321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 49421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Removing ciphers by ID from OpenSSL is a bit involved as we must use the 49521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // textual name with SSL_set_cipher_list because there is no public API to 49621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // directly remove a cipher by ID. 49721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl_); 49821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(ciphers); 49921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // See SSLConfig::disabled_cipher_suites for description of the suites 50021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // disabled by default. 50121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string command("DEFAULT:!NULL:!aNULL:!IDEA:!FZA"); 50221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Walk through all the installed ciphers, seeing if any need to be 50321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // appended to the cipher removal |command|. 50421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen for (int i = 0; i < sk_SSL_CIPHER_num(ciphers); ++i) { 50521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i); 50621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const uint16 id = SSL_CIPHER_get_id(cipher); 50721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Remove any ciphers with a strength of less than 80 bits. Note the NSS 50821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // implementation uses "effective" bits here but OpenSSL does not provide 50921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // this detail. This only impacts Triple DES: reports 112 vs. 168 bits, 51021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // both of which are greater than 80 anyway. 51121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen bool disable = SSL_CIPHER_get_bits(cipher, NULL) < 80; 51221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!disable) { 51321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen disable = std::find(ssl_config_.disabled_cipher_suites.begin(), 51421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ssl_config_.disabled_cipher_suites.end(), id) != 51521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ssl_config_.disabled_cipher_suites.end(); 51621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 51721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (disable) { 51821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const char* name = SSL_CIPHER_get_name(cipher); 51921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DVLOG(3) << "Found cipher to remove: '" << name << "', ID: " << id 52021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen << " strength: " << SSL_CIPHER_get_bits(cipher, NULL); 52121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen command.append(":!"); 52221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen command.append(name); 52321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 52421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 52521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int rv = SSL_set_cipher_list(ssl_, command.c_str()); 52621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // If this fails (rv = 0) it means there are no ciphers enabled on this SSL. 52721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // This will almost certainly result in the socket failing to complete the 52821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // handshake at which point the appropriate error is bubbled up to the client. 52921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LOG_IF(WARNING, rv != 1) << "SSL_set_cipher_list('" << command << "') " 53021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen "returned " << rv; 531c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick return true; 532c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick} 53300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 53421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl, 53521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen X509** x509, 53621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EVP_PKEY** pkey) { 53721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DVLOG(3) << "OpenSSL ClientCertRequestCallback called"; 53821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(ssl == ssl_); 53921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(*x509 == NULL); 54021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(*pkey == NULL); 54121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 54221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!ssl_config_.send_client_cert) { 54321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen client_auth_cert_needed_ = true; 54421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return -1; // Suspends handshake. 54521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 54621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 54721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Second pass: a client certificate should have been selected. 54821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (ssl_config_.client_cert) { 54921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EVP_PKEY* privkey = OpenSSLPrivateKeyStore::GetInstance()->FetchPrivateKey( 55021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen X509_PUBKEY_get(X509_get_X509_PUBKEY( 55121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ssl_config_.client_cert->os_cert_handle()))); 55221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (privkey) { 55388cd212725de4726b13b171fde17a47e2073ff2fBrian Carlstrom CRYPTO_add(&privkey->references, 1, CRYPTO_LOCK_EVP_PKEY); 55421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // TODO(joth): (copied from NSS) We should wait for server certificate 55521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // verification before sending our credentials. See http://crbug.com/13934 55621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen *x509 = X509Certificate::DupOSCertHandle( 55721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ssl_config_.client_cert->os_cert_handle()); 55821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen *pkey = privkey; 55921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return 1; 56021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 56121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LOG(WARNING) << "Client cert found without private key"; 56221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 56321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 56421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Send no client certificate. 56521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return 0; 56621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 56721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 56800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch// SSLClientSocket methods 56900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 57000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochvoid SSLClientSocketOpenSSL::GetSSLInfo(SSLInfo* ssl_info) { 571c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick ssl_info->Reset(); 572731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!server_cert_) 573731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return; 574731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 575731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl_info->cert = server_cert_; 576731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl_info->cert_status = server_cert_verify_result_.cert_status; 577ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ssl_info->is_issued_by_known_root = 578ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen server_cert_verify_result_.is_issued_by_known_root; 579ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ssl_info->public_key_hashes = 580ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen server_cert_verify_result_.public_key_hashes; 581731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 582731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl_); 583731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CHECK(cipher); 584731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl_info->security_bits = SSL_CIPHER_get_bits(cipher, NULL); 585731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const COMP_METHOD* compression = SSL_get_current_compression(ssl_); 58621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 58721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ssl_info->connection_status = EncodeSSLConnectionStatus( 58821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SSL_CIPHER_get_id(cipher), 58921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen compression ? compression->type : 0, 59021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen GetNetSSLVersion(ssl_)); 591731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 592731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool peer_supports_renego_ext = !!SSL_get_secure_renegotiation_support(ssl_); 593731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!peer_supports_renego_ext) 594731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl_info->connection_status |= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION; 59521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen UMA_HISTOGRAM_ENUMERATION("Net.RenegotiationExtensionSupported", 59621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen implicit_cast<int>(peer_supports_renego_ext), 2); 597731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 598731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (ssl_config_.ssl3_fallback) 599731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl_info->connection_status |= SSL_CONNECTION_SSL3_FALLBACK; 60021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 60121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DVLOG(3) << "Encoded connection status: cipher suite = " 60221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen << SSLConnectionStatusToCipherSuite(ssl_info->connection_status) 60321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen << " compression = " 60421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen << SSLConnectionStatusToCompression(ssl_info->connection_status) 60521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen << " version = " 60621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen << SSLConnectionStatusToVersion(ssl_info->connection_status); 60700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 60800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 60900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochvoid SSLClientSocketOpenSSL::GetSSLCertRequestInfo( 61000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch SSLCertRequestInfo* cert_request_info) { 61121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen cert_request_info->host_and_port = host_and_port_.ToString(); 61221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen cert_request_info->client_certs = client_certs_; 61300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 61400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 615c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain MerrickSSLClientSocket::NextProtoStatus SSLClientSocketOpenSSL::GetNextProto( 616c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick std::string* proto) { 6170dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen *proto = npn_proto_; 6180dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen return npn_status_; 61900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 62000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 62100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochvoid SSLClientSocketOpenSSL::DoReadCallback(int rv) { 62200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // Since Run may result in Read being called, clear |user_read_callback_| 62300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // up front. 62400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch CompletionCallback* c = user_read_callback_; 62500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_read_callback_ = NULL; 62600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_read_buf_ = NULL; 62700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_read_buf_len_ = 0; 62800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch c->Run(rv); 62900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 63000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 63100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochvoid SSLClientSocketOpenSSL::DoWriteCallback(int rv) { 63200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // Since Run may result in Write being called, clear |user_write_callback_| 63300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // up front. 63400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch CompletionCallback* c = user_write_callback_; 63500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_write_callback_ = NULL; 63600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_write_buf_ = NULL; 63700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_write_buf_len_ = 0; 63800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch c->Run(rv); 63900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 64000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 64100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch// ClientSocket methods 64200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 6437b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#ifdef ANDROID 6447b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen// TODO(kristianm): handle the case when wait_for_connect is true 6457b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen// (sync requests) 6467b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#endif 6477b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsenint SSLClientSocketOpenSSL::Connect(CompletionCallback* callback 6487b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#ifdef ANDROID 6497b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen , bool wait_for_connect 650e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma , bool valid_uid 651e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma , uid_t calling_uid 6527b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#endif 6537b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen ) { 654c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick net_log_.BeginEvent(NetLog::TYPE_SSL_CONNECT, NULL); 655c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 656c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick // Set up new ssl object. 657c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick if (!Init()) { 65872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int result = ERR_UNEXPECTED; 65972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, result); 66072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return result; 66100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch } 66200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 663c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick // Set SSL to client mode. Handshake happens in the loop below. 664c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick SSL_set_connect_state(ssl_); 66500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 66600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch GotoState(STATE_HANDSHAKE); 66700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int rv = DoHandshakeLoop(net::OK); 66800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch if (rv == ERR_IO_PENDING) { 66900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_connect_callback_ = callback; 670c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick } else { 67172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv); 67200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch } 67300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 67400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch return rv > OK ? OK : rv; 67500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 67600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 67700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochvoid SSLClientSocketOpenSSL::Disconnect() { 678731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (ssl_) { 679731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SSL_free(ssl_); 680731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl_ = NULL; 681731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 682731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (transport_bio_) { 683731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BIO_free_all(transport_bio_); 684731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick transport_bio_ = NULL; 685731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 686731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 687731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Shut down anything that may call us back (through buffer_send_callback_, 688731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // buffer_recv_callback, or handshake_io_callback_). 689731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick verifier_.reset(); 690731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick transport_->socket()->Disconnect(); 691731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 692c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick // Null all callbacks, delete all buffers. 693c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick transport_send_busy_ = false; 694c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick send_buffer_ = NULL; 695c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick transport_recv_busy_ = false; 696c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick recv_buffer_ = NULL; 697c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 698c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick user_connect_callback_ = NULL; 699c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick user_read_callback_ = NULL; 700c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick user_write_callback_ = NULL; 701c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick user_read_buf_ = NULL; 702c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick user_read_buf_len_ = 0; 703c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick user_write_buf_ = NULL; 704c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick user_write_buf_len_ = 0; 705c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 706731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick server_cert_verify_result_.Reset(); 70700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch completed_handshake_ = false; 708201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 709201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch client_certs_.clear(); 710201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch client_auth_cert_needed_ = false; 71100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 71200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 71300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochint SSLClientSocketOpenSSL::DoHandshakeLoop(int last_io_result) { 71400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch bool network_moved; 71500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int rv = last_io_result; 71600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch do { 71700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // Default to STATE_NONE for next state. 71800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // (This is a quirk carried over from the windows 71900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // implementation. It makes reading the logs a bit harder.) 72000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // State handlers can and often do call GotoState just 72100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // to stay in the current state. 72200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch State state = next_handshake_state_; 72300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch GotoState(STATE_NONE); 72400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch switch (state) { 72500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch case STATE_NONE: 72600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // we're just pumping data between the buffer and the network 72700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch break; 72800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch case STATE_HANDSHAKE: 72900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch rv = DoHandshake(); 73000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch break; 73100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch case STATE_VERIFY_CERT: 732c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick DCHECK(rv == OK); 733c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick rv = DoVerifyCert(rv); 734c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick break; 73500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch case STATE_VERIFY_CERT_COMPLETE: 736c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick rv = DoVerifyCertComplete(rv); 737c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick break; 73800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch default: 739c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick rv = ERR_UNEXPECTED; 740c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick NOTREACHED() << "unexpected state" << state; 74100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch break; 74200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch } 74300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 74400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // To avoid getting an ERR_IO_PENDING here after handshake complete. 74500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch if (next_handshake_state_ == STATE_NONE) 74600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch break; 74700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 748c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick // Do the actual network I/O. 74900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch network_moved = DoTransportIO(); 75000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch } while ((rv != ERR_IO_PENDING || network_moved) && 75100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch next_handshake_state_ != STATE_NONE); 75200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch return rv; 75300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 75400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 75500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochint SSLClientSocketOpenSSL::DoHandshake() { 756ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 757c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick int net_error = net::OK; 758c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick int rv = SSL_do_handshake(ssl_); 75900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 76021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (client_auth_cert_needed_) { 76121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; 76221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // If the handshake already succeeded (because the server requests but 76321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // doesn't require a client cert), we need to invalidate the SSL session 76421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // so that we won't try to resume the non-client-authenticated session in 76521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // the next handshake. This will cause the server to ask for a client 76621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // cert again. 76721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv == 1) { 76821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Remove from session cache but don't clear this connection. 76921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SSL_SESSION* session = SSL_get_session(ssl_); 77021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (session) { 77121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int rv = SSL_CTX_remove_session(SSL_get_SSL_CTX(ssl_), session); 77221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LOG_IF(WARNING, !rv) << "Couldn't invalidate SSL session: " << session; 77321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 77421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 77521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } else if (rv == 1) { 776201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (trying_cached_session_ && logging::DEBUG_MODE) { 777201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DVLOG(2) << "Result of session reuse for " << host_and_port_.ToString() 778201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch << " is: " << (SSL_session_reused(ssl_) ? "Success" : "Fail"); 779201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 78000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // SSL handshake is completed. Let's verify the certificate. 781731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const bool got_cert = !!UpdateServerCert(); 782731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(got_cert); 783731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GotoState(STATE_VERIFY_CERT); 78400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch } else { 785c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick int ssl_error = SSL_get_error(ssl_, rv); 78621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net_error = MapOpenSSLError(ssl_error, err_tracer); 78700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 78800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // If not done, stay in this state 789731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (net_error == ERR_IO_PENDING) { 790731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GotoState(STATE_HANDSHAKE); 791731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 792731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LOG(ERROR) << "handshake failed; returned " << rv 793731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << ", SSL error code " << ssl_error 794731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << ", net_error " << net_error; 79521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net_log_.AddEvent( 79621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen NetLog::TYPE_SSL_HANDSHAKE_ERROR, 79721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen make_scoped_refptr(new SSLErrorParams(net_error, ssl_error))); 798731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 79900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch } 800c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick return net_error; 80100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 80200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 8030dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsenint SSLClientSocketOpenSSL::SelectNextProtoCallback(unsigned char** out, 8040dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen unsigned char* outlen, 8050dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen const unsigned char* in, 8060dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen unsigned int inlen) { 8070dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen#if defined(OPENSSL_NPN_NEGOTIATED) 8080dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen if (ssl_config_.next_protos.empty()) { 8090dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen *out = reinterpret_cast<uint8*>(const_cast<char*>("http/1.1")); 8100dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen *outlen = 8; 8110dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen npn_status_ = SSLClientSocket::kNextProtoUnsupported; 8120dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen return SSL_TLSEXT_ERR_OK; 8130dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen } 8140dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen 8150dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen int status = SSL_select_next_proto( 8160dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen out, outlen, in, inlen, 8170dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen reinterpret_cast<const unsigned char*>(ssl_config_.next_protos.data()), 8180dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen ssl_config_.next_protos.size()); 8190dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen 8200dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen npn_proto_.assign(reinterpret_cast<const char*>(*out), *outlen); 8210dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen switch (status) { 8220dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen case OPENSSL_NPN_UNSUPPORTED: 8230dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen npn_status_ = SSLClientSocket::kNextProtoUnsupported; 8240dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen break; 8250dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen case OPENSSL_NPN_NEGOTIATED: 8260dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen npn_status_ = SSLClientSocket::kNextProtoNegotiated; 8270dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen break; 8280dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen case OPENSSL_NPN_NO_OVERLAP: 8290dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen npn_status_ = SSLClientSocket::kNextProtoNoOverlap; 8300dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen break; 8310dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen default: 8320dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen NOTREACHED() << status; 8330dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen break; 8340dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen } 83521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DVLOG(2) << "next protocol: '" << npn_proto_ << "' status: " << npn_status_; 83621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#endif 83721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return SSL_TLSEXT_ERR_OK; 83821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 8390dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen 840731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickint SSLClientSocketOpenSSL::DoVerifyCert(int result) { 841731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(server_cert_); 842731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GotoState(STATE_VERIFY_CERT_COMPLETE); 843731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int flags = 0; 844731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 845731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (ssl_config_.rev_checking_enabled) 846731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED; 847731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (ssl_config_.verify_ev_cert) 848731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick flags |= X509Certificate::VERIFY_EV_CERT; 84921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen verifier_.reset(new SingleRequestCertVerifier(cert_verifier_)); 8504a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return verifier_->Verify(server_cert_, host_and_port_.host(), flags, 851731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &server_cert_verify_result_, 852731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &handshake_io_callback_); 853731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 854731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 855731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickint SSLClientSocketOpenSSL::DoVerifyCertComplete(int result) { 856731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick verifier_.reset(); 857731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 858731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (result == OK) { 859731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // TODO(joth): Work out if we need to remember the intermediate CA certs 860731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // when the server sends them to us, and do so here. 861731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 862731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DVLOG(1) << "DoVerifyCertComplete error " << ErrorToString(result) 863731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << " (" << result << ")"; 864731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 865731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 866731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // If we have been explicitly told to accept this certificate, override the 867731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // result of verifier_.Verify. 868731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Eventually, we should cache the cert verification results so that we don't 869731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // need to call verifier_.Verify repeatedly. But for now we need to do this. 870731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Alternatively, we could use the cert's status that we stored along with 871731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // the cert in the allowed_bad_certs vector. 872731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (IsCertificateError(result) && 873731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ssl_config_.IsAllowedBadCert(server_cert_)) { 874731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick VLOG(1) << "accepting bad SSL certificate, as user told us to"; 875731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick result = OK; 876731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 877731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 878731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick completed_handshake_ = true; 879731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Exit DoHandshakeLoop and return the result to the caller to Connect. 880731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK_EQ(STATE_NONE, next_handshake_state_); 881731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return result; 882731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 883731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 884731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickX509Certificate* SSLClientSocketOpenSSL::UpdateServerCert() { 885731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (server_cert_) 886731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return server_cert_; 887731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 888ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen crypto::ScopedOpenSSL<X509, X509_free> cert(SSL_get_peer_certificate(ssl_)); 889731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!cert.get()) { 890731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LOG(WARNING) << "SSL_get_peer_certificate returned NULL"; 891731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return NULL; 892731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 893731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 894731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Unlike SSL_get_peer_certificate, SSL_get_peer_cert_chain does not 895731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // increment the reference so sk_X509_free does not need to be called. 896731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl_); 897731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick X509Certificate::OSCertHandles intermediates; 898731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (chain) { 899731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (int i = 0; i < sk_X509_num(chain); ++i) 900731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick intermediates.push_back(sk_X509_value(chain, i)); 901731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 902731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick server_cert_ = X509Certificate::CreateFromHandle( 903731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick cert.get(), X509Certificate::SOURCE_FROM_NETWORK, intermediates); 904731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(server_cert_); 905731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 906731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return server_cert_; 907731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 908731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 90900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochbool SSLClientSocketOpenSSL::DoTransportIO() { 91000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch bool network_moved = false; 91100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int nsent = BufferSend(); 91200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int nreceived = BufferRecv(); 91300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch network_moved = (nsent > 0 || nreceived >= 0); 91400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch return network_moved; 91500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 91600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 91700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochint SSLClientSocketOpenSSL::BufferSend(void) { 918c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick if (transport_send_busy_) 919c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick return ERR_IO_PENDING; 920c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 921c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick if (!send_buffer_) { 922c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick // Get a fresh send buffer out of the send BIO. 923c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick size_t max_read = BIO_ctrl_pending(transport_bio_); 924c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick if (max_read > 0) { 925c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick send_buffer_ = new DrainableIOBuffer(new IOBuffer(max_read), max_read); 926c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick int read_bytes = BIO_read(transport_bio_, send_buffer_->data(), max_read); 927c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick DCHECK_GT(read_bytes, 0); 928c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick CHECK_EQ(static_cast<int>(max_read), read_bytes); 929c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick } 93000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch } 93100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 932c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick int rv = 0; 933c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick while (send_buffer_) { 934c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick rv = transport_->socket()->Write(send_buffer_, 935c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick send_buffer_->BytesRemaining(), 936c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick &buffer_send_callback_); 937c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick if (rv == ERR_IO_PENDING) { 938c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick transport_send_busy_ = true; 939c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick return rv; 940c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick } 941c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick TransportWriteComplete(rv); 94200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch } 943c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick return rv; 94400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 94500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 94600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochvoid SSLClientSocketOpenSSL::BufferSendComplete(int result) { 94700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch transport_send_busy_ = false; 948c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick TransportWriteComplete(result); 94900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch OnSendComplete(result); 95000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 95100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 952c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrickvoid SSLClientSocketOpenSSL::TransportWriteComplete(int result) { 953731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(ERR_IO_PENDING != result); 954c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick if (result < 0) { 955c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick // Got a socket write error; close the BIO to indicate this upward. 956731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DVLOG(1) << "TransportWriteComplete error " << result; 957c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick (void)BIO_shutdown_wr(transport_bio_); 958c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick send_buffer_ = NULL; 959c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick } else { 960c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick DCHECK(send_buffer_); 961c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick send_buffer_->DidConsume(result); 962c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick DCHECK_GE(send_buffer_->BytesRemaining(), 0); 963c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick if (send_buffer_->BytesRemaining() <= 0) 964c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick send_buffer_ = NULL; 965c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick } 966c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick} 967c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 96800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochint SSLClientSocketOpenSSL::BufferRecv(void) { 96900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch if (transport_recv_busy_) 97000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch return ERR_IO_PENDING; 97100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 972c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick size_t max_write = BIO_ctrl_get_write_guarantee(transport_bio_); 973c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick if (max_write > kMaxRecvBufferSize) 974c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick max_write = kMaxRecvBufferSize; 975c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 976c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick if (!max_write) 977c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick return ERR_IO_PENDING; 978c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 979c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick recv_buffer_ = new IOBuffer(max_write); 980c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick int rv = transport_->socket()->Read(recv_buffer_, max_write, 981c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick &buffer_recv_callback_); 982c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick if (rv == ERR_IO_PENDING) { 983c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick transport_recv_busy_ = true; 98400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch } else { 985c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick TransportReadComplete(rv); 98600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch } 98700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch return rv; 98800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 98900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 99000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochvoid SSLClientSocketOpenSSL::BufferRecvComplete(int result) { 991c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick TransportReadComplete(result); 992c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick OnRecvComplete(result); 993c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick} 994c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 995c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrickvoid SSLClientSocketOpenSSL::TransportReadComplete(int result) { 996731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(ERR_IO_PENDING != result); 997731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (result <= 0) { 998731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DVLOG(1) << "TransportReadComplete result " << result; 999731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Received 0 (end of file) or an error. Either way, bubble it up to the 1000731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // SSL layer via the BIO. TODO(joth): consider stashing the error code, to 1001731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // relay up to the SSL socket client (i.e. via DoReadCallback). 1002731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BIO_set_mem_eof_return(transport_bio_, 0); 1003731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick (void)BIO_shutdown_wr(transport_bio_); 1004731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 1005731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(recv_buffer_); 1006c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick int ret = BIO_write(transport_bio_, recv_buffer_->data(), result); 1007c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick // A write into a memory BIO should always succeed. 1008c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick CHECK_EQ(result, ret); 100900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch } 101000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch recv_buffer_ = NULL; 101100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch transport_recv_busy_ = false; 101200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 101300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 101400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochvoid SSLClientSocketOpenSSL::DoConnectCallback(int rv) { 101500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch CompletionCallback* c = user_connect_callback_; 101600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_connect_callback_ = NULL; 101700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch c->Run(rv > OK ? OK : rv); 101800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 101900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 102000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochvoid SSLClientSocketOpenSSL::OnHandshakeIOComplete(int result) { 102100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int rv = DoHandshakeLoop(result); 102200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch if (rv != ERR_IO_PENDING) { 102372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv); 102400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch DoConnectCallback(rv); 102500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch } 102600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 102700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 102800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochvoid SSLClientSocketOpenSSL::OnSendComplete(int result) { 102900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch if (next_handshake_state_ != STATE_NONE) { 103000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // In handshake phase. 103100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch OnHandshakeIOComplete(result); 103200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch return; 103300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch } 103400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 103500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // OnSendComplete may need to call DoPayloadRead while the renegotiation 103600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // handshake is in progress. 103700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int rv_read = ERR_IO_PENDING; 103800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int rv_write = ERR_IO_PENDING; 103900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch bool network_moved; 104000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch do { 104100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch if (user_read_buf_) 104200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch rv_read = DoPayloadRead(); 104300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch if (user_write_buf_) 104400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch rv_write = DoPayloadWrite(); 104500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch network_moved = DoTransportIO(); 104600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch } while (rv_read == ERR_IO_PENDING && 104700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch rv_write == ERR_IO_PENDING && 104800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch network_moved); 104900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 105000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch if (user_read_buf_ && rv_read != ERR_IO_PENDING) 105100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch DoReadCallback(rv_read); 105200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch if (user_write_buf_ && rv_write != ERR_IO_PENDING) 105300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch DoWriteCallback(rv_write); 105400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 105500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 105600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochvoid SSLClientSocketOpenSSL::OnRecvComplete(int result) { 105700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch if (next_handshake_state_ != STATE_NONE) { 105800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // In handshake phase. 105900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch OnHandshakeIOComplete(result); 106000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch return; 106100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch } 106200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 106300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // Network layer received some data, check if client requested to read 106400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // decrypted data. 1065c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick if (!user_read_buf_) 106600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch return; 106700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 106800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int rv = DoReadLoop(result); 106900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch if (rv != ERR_IO_PENDING) 107000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch DoReadCallback(rv); 107100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 107200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 107300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochbool SSLClientSocketOpenSSL::IsConnected() const { 107400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch bool ret = completed_handshake_ && transport_->socket()->IsConnected(); 107500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch return ret; 107600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 107700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 107800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochbool SSLClientSocketOpenSSL::IsConnectedAndIdle() const { 107900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch bool ret = completed_handshake_ && transport_->socket()->IsConnectedAndIdle(); 108000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch return ret; 108100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 108200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 108300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochint SSLClientSocketOpenSSL::GetPeerAddress(AddressList* addressList) const { 108400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch return transport_->socket()->GetPeerAddress(addressList); 108500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 108600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 1087ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint SSLClientSocketOpenSSL::GetLocalAddress(IPEndPoint* addressList) const { 1088ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return transport_->socket()->GetLocalAddress(addressList); 1089ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 1090ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 109100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochconst BoundNetLog& SSLClientSocketOpenSSL::NetLog() const { 1092c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick return net_log_; 1093c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick} 1094c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 1095c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrickvoid SSLClientSocketOpenSSL::SetSubresourceSpeculation() { 1096c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick if (transport_.get() && transport_->socket()) { 1097c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick transport_->socket()->SetSubresourceSpeculation(); 1098c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick } else { 1099c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick NOTREACHED(); 1100c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick } 1101c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick} 1102c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 1103c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrickvoid SSLClientSocketOpenSSL::SetOmniboxSpeculation() { 1104c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick if (transport_.get() && transport_->socket()) { 1105c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick transport_->socket()->SetOmniboxSpeculation(); 1106c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick } else { 1107c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick NOTREACHED(); 1108c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick } 1109c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick} 1110c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 1111c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrickbool SSLClientSocketOpenSSL::WasEverUsed() const { 1112c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick if (transport_.get() && transport_->socket()) 1113c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick return transport_->socket()->WasEverUsed(); 1114c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 1115c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick NOTREACHED(); 1116c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick return false; 111700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 111800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 1119513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool SSLClientSocketOpenSSL::UsingTCPFastOpen() const { 1120513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (transport_.get() && transport_->socket()) 1121513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return transport_->socket()->UsingTCPFastOpen(); 1122513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 1123513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NOTREACHED(); 1124513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 1125513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 1126513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 112700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch// Socket methods 112800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 1129c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrickint SSLClientSocketOpenSSL::Read(IOBuffer* buf, 1130c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick int buf_len, 1131c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick CompletionCallback* callback) { 113200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_read_buf_ = buf; 113300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_read_buf_len_ = buf_len; 113400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 113500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int rv = DoReadLoop(OK); 113600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 1137c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick if (rv == ERR_IO_PENDING) { 113800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_read_callback_ = callback; 1139c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick } else { 114000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_read_buf_ = NULL; 114100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_read_buf_len_ = 0; 114200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch } 114300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 114400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch return rv; 114500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 114600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 114700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochint SSLClientSocketOpenSSL::DoReadLoop(int result) { 114800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch if (result < 0) 114900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch return result; 115000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 115100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch bool network_moved; 115200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int rv; 115300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch do { 115400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch rv = DoPayloadRead(); 115500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch network_moved = DoTransportIO(); 115600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch } while (rv == ERR_IO_PENDING && network_moved); 115700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 115800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch return rv; 115900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 116000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 1161c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrickint SSLClientSocketOpenSSL::Write(IOBuffer* buf, 1162c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick int buf_len, 1163c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick CompletionCallback* callback) { 116400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_write_buf_ = buf; 116500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_write_buf_len_ = buf_len; 116600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 116700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int rv = DoWriteLoop(OK); 116800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 1169c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick if (rv == ERR_IO_PENDING) { 117000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_write_callback_ = callback; 1171c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick } else { 117200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_write_buf_ = NULL; 117300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch user_write_buf_len_ = 0; 117400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch } 117500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 117600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch return rv; 117700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 117800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 117900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochint SSLClientSocketOpenSSL::DoWriteLoop(int result) { 118000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch if (result < 0) 118100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch return result; 118200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 118300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch bool network_moved; 118400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int rv; 118500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch do { 118600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch rv = DoPayloadWrite(); 118700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch network_moved = DoTransportIO(); 118800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch } while (rv == ERR_IO_PENDING && network_moved); 118900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 119000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch return rv; 119100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 119200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 119300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochbool SSLClientSocketOpenSSL::SetReceiveBufferSize(int32 size) { 1194c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick return transport_->socket()->SetReceiveBufferSize(size); 119500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 119600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 119700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochbool SSLClientSocketOpenSSL::SetSendBufferSize(int32 size) { 1198c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick return transport_->socket()->SetSendBufferSize(size); 119900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 120000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 120100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochint SSLClientSocketOpenSSL::DoPayloadRead() { 1202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 1203c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick int rv = SSL_read(ssl_, user_read_buf_->data(), user_read_buf_len_); 1204c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick // We don't need to invalidate the non-client-authenticated SSL session 1205c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick // because the server will renegotiate anyway. 1206c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick if (client_auth_cert_needed_) 120700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch return ERR_SSL_CLIENT_AUTH_CERT_NEEDED; 120800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 1209c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick if (rv >= 0) 121000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch return rv; 121100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 1212c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick int err = SSL_get_error(ssl_, rv); 121321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return MapOpenSSLError(err, err_tracer); 121400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 121500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 121600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochint SSLClientSocketOpenSSL::DoPayloadWrite() { 1217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 1218c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_); 121900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 1220c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick if (rv >= 0) 122100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch return rv; 122200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 1223c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick int err = SSL_get_error(ssl_, rv); 122421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return MapOpenSSLError(err, err_tracer); 122500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} 122600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 122721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} // namespace net 1228