Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(366)

Side by Side Diff: net/socket/ssl_client_socket_openssl.cc

Issue 6805019: Move crypto files out of base, to a top level directory. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // OpenSSL binding for SSLClientSocket. The class layout and general principle 5 // OpenSSL binding for SSLClientSocket. The class layout and general principle
6 // of operation is derived from SSLClientSocketNSS. 6 // of operation is derived from SSLClientSocketNSS.
7 7
8 #include "net/socket/ssl_client_socket_openssl.h" 8 #include "net/socket/ssl_client_socket_openssl.h"
9 9
10 #include <openssl/ssl.h> 10 #include <openssl/ssl.h>
11 #include <openssl/err.h> 11 #include <openssl/err.h>
12 12
13 #include "base/memory/singleton.h" 13 #include "base/memory/singleton.h"
14 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
15 #include "base/openssl_util.h"
16 #include "base/synchronization/lock.h" 15 #include "base/synchronization/lock.h"
16 #include "crypto/openssl_util.h"
17 #include "net/base/cert_verifier.h" 17 #include "net/base/cert_verifier.h"
18 #include "net/base/net_errors.h" 18 #include "net/base/net_errors.h"
19 #include "net/base/openssl_private_key_store.h" 19 #include "net/base/openssl_private_key_store.h"
20 #include "net/base/ssl_cert_request_info.h" 20 #include "net/base/ssl_cert_request_info.h"
21 #include "net/base/ssl_connection_status_flags.h" 21 #include "net/base/ssl_connection_status_flags.h"
22 #include "net/base/ssl_info.h" 22 #include "net/base/ssl_info.h"
23 #include "net/socket/ssl_error_params.h" 23 #include "net/socket/ssl_error_params.h"
24 24
25 namespace net { 25 namespace net {
26 26
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 default: 165 default:
166 LOG(WARNING) << "Unmapped error reason: " << ERR_GET_REASON(error_code); 166 LOG(WARNING) << "Unmapped error reason: " << ERR_GET_REASON(error_code);
167 return ERR_FAILED; 167 return ERR_FAILED;
168 } 168 }
169 } 169 }
170 170
171 // Converts an OpenSSL error code into a net error code, walking the OpenSSL 171 // Converts an OpenSSL error code into a net error code, walking the OpenSSL
172 // error stack if needed. Note that |tracer| is not currently used in the 172 // error stack if needed. Note that |tracer| is not currently used in the
173 // implementation, but is passed in anyway as this ensures the caller will clear 173 // implementation, but is passed in anyway as this ensures the caller will clear
174 // any residual codes left on the error stack. 174 // any residual codes left on the error stack.
175 int MapOpenSSLError(int err, const base::OpenSSLErrStackTracer& tracer) { 175 int MapOpenSSLError(int err, const crypto::OpenSSLErrStackTracer& tracer) {
176 switch (err) { 176 switch (err) {
177 case SSL_ERROR_WANT_READ: 177 case SSL_ERROR_WANT_READ:
178 case SSL_ERROR_WANT_WRITE: 178 case SSL_ERROR_WANT_WRITE:
179 return ERR_IO_PENDING; 179 return ERR_IO_PENDING;
180 case SSL_ERROR_SYSCALL: 180 case SSL_ERROR_SYSCALL:
181 DVLOG(1) << "OpenSSL SYSCALL error, errno " << errno; 181 DVLOG(1) << "OpenSSL SYSCALL error, errno " << errno;
182 return ERR_SSL_PROTOCOL_ERROR; 182 return ERR_SSL_PROTOCOL_ERROR;
183 case SSL_ERROR_SSL: 183 case SSL_ERROR_SSL:
184 return MapOpenSSLErrorSSL(); 184 return MapOpenSSLErrorSSL();
185 default: 185 default:
(...skipping 13 matching lines...) Expand all
199 // OpenSSL manages a cache of SSL_SESSION, this class provides the application 199 // OpenSSL manages a cache of SSL_SESSION, this class provides the application
200 // side policy for that cache about session re-use: we retain one session per 200 // side policy for that cache about session re-use: we retain one session per
201 // unique HostPortPair. 201 // unique HostPortPair.
202 class SSLSessionCache { 202 class SSLSessionCache {
203 public: 203 public:
204 SSLSessionCache() {} 204 SSLSessionCache() {}
205 205
206 void OnSessionAdded(const HostPortPair& host_and_port, SSL_SESSION* session) { 206 void OnSessionAdded(const HostPortPair& host_and_port, SSL_SESSION* session) {
207 // Declare the session cleaner-upper before the lock, so any call into 207 // Declare the session cleaner-upper before the lock, so any call into
208 // OpenSSL to free the session will happen after the lock is released. 208 // OpenSSL to free the session will happen after the lock is released.
209 base::ScopedOpenSSL<SSL_SESSION, SSL_SESSION_free> session_to_free; 209 crypto::ScopedOpenSSL<SSL_SESSION, SSL_SESSION_free> session_to_free;
210 base::AutoLock lock(lock_); 210 base::AutoLock lock(lock_);
211 211
212 DCHECK_EQ(0U, session_map_.count(session)); 212 DCHECK_EQ(0U, session_map_.count(session));
213 std::pair<HostPortMap::iterator, bool> res = 213 std::pair<HostPortMap::iterator, bool> res =
214 host_port_map_.insert(std::make_pair(host_and_port, session)); 214 host_port_map_.insert(std::make_pair(host_and_port, session));
215 if (!res.second) { // Already exists: replace old entry. 215 if (!res.second) { // Already exists: replace old entry.
216 session_to_free.reset(res.first->second); 216 session_to_free.reset(res.first->second);
217 session_map_.erase(session_to_free.get()); 217 session_map_.erase(session_to_free.get());
218 res.first->second = session; 218 res.first->second = session;
219 } 219 }
220 DVLOG(2) << "Adding session " << session << " => " 220 DVLOG(2) << "Adding session " << session << " => "
221 << host_and_port.ToString() << ", new entry = " << res.second; 221 << host_and_port.ToString() << ", new entry = " << res.second;
222 DCHECK(host_port_map_[host_and_port] == session); 222 DCHECK(host_port_map_[host_and_port] == session);
223 session_map_[session] = res.first; 223 session_map_[session] = res.first;
224 DCHECK_EQ(host_port_map_.size(), session_map_.size()); 224 DCHECK_EQ(host_port_map_.size(), session_map_.size());
225 DCHECK_LE(host_port_map_.size(), kSessionCacheMaxEntires); 225 DCHECK_LE(host_port_map_.size(), kSessionCacheMaxEntires);
226 } 226 }
227 227
228 void OnSessionRemoved(SSL_SESSION* session) { 228 void OnSessionRemoved(SSL_SESSION* session) {
229 // Declare the session cleaner-upper before the lock, so any call into 229 // Declare the session cleaner-upper before the lock, so any call into
230 // OpenSSL to free the session will happen after the lock is released. 230 // OpenSSL to free the session will happen after the lock is released.
231 base::ScopedOpenSSL<SSL_SESSION, SSL_SESSION_free> session_to_free; 231 crypto::ScopedOpenSSL<SSL_SESSION, SSL_SESSION_free> session_to_free;
232 base::AutoLock lock(lock_); 232 base::AutoLock lock(lock_);
233 233
234 SessionMap::iterator it = session_map_.find(session); 234 SessionMap::iterator it = session_map_.find(session);
235 if (it == session_map_.end()) 235 if (it == session_map_.end())
236 return; 236 return;
237 DVLOG(2) << "Remove session " << session << " => " 237 DVLOG(2) << "Remove session " << session << " => "
238 << it->second->first.ToString(); 238 << it->second->first.ToString();
239 DCHECK(it->second->second == session); 239 DCHECK(it->second->second == session);
240 host_port_map_.erase(it->second); 240 host_port_map_.erase(it->second);
241 session_map_.erase(it); 241 session_map_.erase(it);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 } 294 }
295 295
296 bool SetClientSocketForSSL(SSL* ssl, SSLClientSocketOpenSSL* socket) { 296 bool SetClientSocketForSSL(SSL* ssl, SSLClientSocketOpenSSL* socket) {
297 return SSL_set_ex_data(ssl, ssl_socket_data_index_, socket) != 0; 297 return SSL_set_ex_data(ssl, ssl_socket_data_index_, socket) != 0;
298 } 298 }
299 299
300 private: 300 private:
301 friend struct DefaultSingletonTraits<SSLContext>; 301 friend struct DefaultSingletonTraits<SSLContext>;
302 302
303 SSLContext() { 303 SSLContext() {
304 base::EnsureOpenSSLInit(); 304 crypto::EnsureOpenSSLInit();
305 ssl_socket_data_index_ = SSL_get_ex_new_index(0, 0, 0, 0, 0); 305 ssl_socket_data_index_ = SSL_get_ex_new_index(0, 0, 0, 0, 0);
306 DCHECK_NE(ssl_socket_data_index_, -1); 306 DCHECK_NE(ssl_socket_data_index_, -1);
307 ssl_ctx_.reset(SSL_CTX_new(SSLv23_client_method())); 307 ssl_ctx_.reset(SSL_CTX_new(SSLv23_client_method()));
308 SSL_CTX_set_cert_verify_callback(ssl_ctx_.get(), NoOpVerifyCallback, NULL); 308 SSL_CTX_set_cert_verify_callback(ssl_ctx_.get(), NoOpVerifyCallback, NULL);
309 SSL_CTX_set_session_cache_mode(ssl_ctx_.get(), SSL_SESS_CACHE_CLIENT); 309 SSL_CTX_set_session_cache_mode(ssl_ctx_.get(), SSL_SESS_CACHE_CLIENT);
310 SSL_CTX_sess_set_new_cb(ssl_ctx_.get(), NewSessionCallbackStatic); 310 SSL_CTX_sess_set_new_cb(ssl_ctx_.get(), NewSessionCallbackStatic);
311 SSL_CTX_sess_set_remove_cb(ssl_ctx_.get(), RemoveSessionCallbackStatic); 311 SSL_CTX_sess_set_remove_cb(ssl_ctx_.get(), RemoveSessionCallbackStatic);
312 SSL_CTX_set_timeout(ssl_ctx_.get(), kSessionCacheTimeoutSeconds); 312 SSL_CTX_set_timeout(ssl_ctx_.get(), kSessionCacheTimeoutSeconds);
313 SSL_CTX_sess_set_cache_size(ssl_ctx_.get(), kSessionCacheMaxEntires); 313 SSL_CTX_sess_set_cache_size(ssl_ctx_.get(), kSessionCacheMaxEntires);
314 SSL_CTX_set_client_cert_cb(ssl_ctx_.get(), ClientCertCallback); 314 SSL_CTX_set_client_cert_cb(ssl_ctx_.get(), ClientCertCallback);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 const unsigned char* in, 351 const unsigned char* in,
352 unsigned int inlen, void* arg) { 352 unsigned int inlen, void* arg) {
353 SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl); 353 SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl);
354 return socket->SelectNextProtoCallback(out, outlen, in, inlen); 354 return socket->SelectNextProtoCallback(out, outlen, in, inlen);
355 } 355 }
356 356
357 // This is the index used with SSL_get_ex_data to retrieve the owner 357 // This is the index used with SSL_get_ex_data to retrieve the owner
358 // SSLClientSocketOpenSSL object from an SSL instance. 358 // SSLClientSocketOpenSSL object from an SSL instance.
359 int ssl_socket_data_index_; 359 int ssl_socket_data_index_;
360 360
361 base::ScopedOpenSSL<SSL_CTX, SSL_CTX_free> ssl_ctx_; 361 crypto::ScopedOpenSSL<SSL_CTX, SSL_CTX_free> ssl_ctx_;
362 SSLSessionCache session_cache_; 362 SSLSessionCache session_cache_;
363 }; 363 };
364 364
365 // Utility to construct the appropriate set & clear masks for use the OpenSSL 365 // Utility to construct the appropriate set & clear masks for use the OpenSSL
366 // options and mode configuration functions. (SSL_set_options etc) 366 // options and mode configuration functions. (SSL_set_options etc)
367 struct SslSetClearMask { 367 struct SslSetClearMask {
368 SslSetClearMask() : set_mask(0), clear_mask(0) {} 368 SslSetClearMask() : set_mask(0), clear_mask(0) {}
369 void ConfigureFlag(long flag, bool state) { 369 void ConfigureFlag(long flag, bool state) {
370 (state ? set_mask : clear_mask) |= flag; 370 (state ? set_mask : clear_mask) |= flag;
371 // Make sure we haven't got any intersection in the set & clear options. 371 // Make sure we haven't got any intersection in the set & clear options.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 408
409 SSLClientSocketOpenSSL::~SSLClientSocketOpenSSL() { 409 SSLClientSocketOpenSSL::~SSLClientSocketOpenSSL() {
410 Disconnect(); 410 Disconnect();
411 } 411 }
412 412
413 bool SSLClientSocketOpenSSL::Init() { 413 bool SSLClientSocketOpenSSL::Init() {
414 DCHECK(!ssl_); 414 DCHECK(!ssl_);
415 DCHECK(!transport_bio_); 415 DCHECK(!transport_bio_);
416 416
417 SSLContext* context = SSLContext::GetInstance(); 417 SSLContext* context = SSLContext::GetInstance();
418 base::OpenSSLErrStackTracer err_tracer(FROM_HERE); 418 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
419 419
420 ssl_ = SSL_new(context->ssl_ctx()); 420 ssl_ = SSL_new(context->ssl_ctx());
421 if (!ssl_ || !context->SetClientSocketForSSL(ssl_, this)) 421 if (!ssl_ || !context->SetClientSocketForSSL(ssl_, this))
422 return false; 422 return false;
423 423
424 if (!SSL_set_tlsext_host_name(ssl_, host_and_port_.host().c_str())) 424 if (!SSL_set_tlsext_host_name(ssl_, host_and_port_.host().c_str()))
425 return false; 425 return false;
426 426
427 trying_cached_session_ = 427 trying_cached_session_ =
428 context->session_cache()->SetSSLSession(ssl_, host_and_port_); 428 context->session_cache()->SetSSLSession(ssl_, host_and_port_);
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 break; 716 break;
717 717
718 // Do the actual network I/O. 718 // Do the actual network I/O.
719 network_moved = DoTransportIO(); 719 network_moved = DoTransportIO();
720 } while ((rv != ERR_IO_PENDING || network_moved) && 720 } while ((rv != ERR_IO_PENDING || network_moved) &&
721 next_handshake_state_ != STATE_NONE); 721 next_handshake_state_ != STATE_NONE);
722 return rv; 722 return rv;
723 } 723 }
724 724
725 int SSLClientSocketOpenSSL::DoHandshake() { 725 int SSLClientSocketOpenSSL::DoHandshake() {
726 base::OpenSSLErrStackTracer err_tracer(FROM_HERE); 726 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
727 int net_error = net::OK; 727 int net_error = net::OK;
728 int rv = SSL_do_handshake(ssl_); 728 int rv = SSL_do_handshake(ssl_);
729 729
730 if (client_auth_cert_needed_) { 730 if (client_auth_cert_needed_) {
731 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; 731 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
732 // If the handshake already succeeded (because the server requests but 732 // If the handshake already succeeded (because the server requests but
733 // doesn't require a client cert), we need to invalidate the SSL session 733 // doesn't require a client cert), we need to invalidate the SSL session
734 // so that we won't try to resume the non-client-authenticated session in 734 // so that we won't try to resume the non-client-authenticated session in
735 // the next handshake. This will cause the server to ask for a client 735 // the next handshake. This will cause the server to ask for a client
736 // cert again. 736 // cert again.
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 completed_handshake_ = true; 848 completed_handshake_ = true;
849 // Exit DoHandshakeLoop and return the result to the caller to Connect. 849 // Exit DoHandshakeLoop and return the result to the caller to Connect.
850 DCHECK_EQ(STATE_NONE, next_handshake_state_); 850 DCHECK_EQ(STATE_NONE, next_handshake_state_);
851 return result; 851 return result;
852 } 852 }
853 853
854 X509Certificate* SSLClientSocketOpenSSL::UpdateServerCert() { 854 X509Certificate* SSLClientSocketOpenSSL::UpdateServerCert() {
855 if (server_cert_) 855 if (server_cert_)
856 return server_cert_; 856 return server_cert_;
857 857
858 base::ScopedOpenSSL<X509, X509_free> cert(SSL_get_peer_certificate(ssl_)); 858 crypto::ScopedOpenSSL<X509, X509_free> cert(SSL_get_peer_certificate(ssl_));
859 if (!cert.get()) { 859 if (!cert.get()) {
860 LOG(WARNING) << "SSL_get_peer_certificate returned NULL"; 860 LOG(WARNING) << "SSL_get_peer_certificate returned NULL";
861 return NULL; 861 return NULL;
862 } 862 }
863 863
864 // Unlike SSL_get_peer_certificate, SSL_get_peer_cert_chain does not 864 // Unlike SSL_get_peer_certificate, SSL_get_peer_cert_chain does not
865 // increment the reference so sk_X509_free does not need to be called. 865 // increment the reference so sk_X509_free does not need to be called.
866 STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl_); 866 STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl_);
867 X509Certificate::OSCertHandles intermediates; 867 X509Certificate::OSCertHandles intermediates;
868 if (chain) { 868 if (chain) {
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 1158
1159 bool SSLClientSocketOpenSSL::SetReceiveBufferSize(int32 size) { 1159 bool SSLClientSocketOpenSSL::SetReceiveBufferSize(int32 size) {
1160 return transport_->socket()->SetReceiveBufferSize(size); 1160 return transport_->socket()->SetReceiveBufferSize(size);
1161 } 1161 }
1162 1162
1163 bool SSLClientSocketOpenSSL::SetSendBufferSize(int32 size) { 1163 bool SSLClientSocketOpenSSL::SetSendBufferSize(int32 size) {
1164 return transport_->socket()->SetSendBufferSize(size); 1164 return transport_->socket()->SetSendBufferSize(size);
1165 } 1165 }
1166 1166
1167 int SSLClientSocketOpenSSL::DoPayloadRead() { 1167 int SSLClientSocketOpenSSL::DoPayloadRead() {
1168 base::OpenSSLErrStackTracer err_tracer(FROM_HERE); 1168 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
1169 int rv = SSL_read(ssl_, user_read_buf_->data(), user_read_buf_len_); 1169 int rv = SSL_read(ssl_, user_read_buf_->data(), user_read_buf_len_);
1170 // We don't need to invalidate the non-client-authenticated SSL session 1170 // We don't need to invalidate the non-client-authenticated SSL session
1171 // because the server will renegotiate anyway. 1171 // because the server will renegotiate anyway.
1172 if (client_auth_cert_needed_) 1172 if (client_auth_cert_needed_)
1173 return ERR_SSL_CLIENT_AUTH_CERT_NEEDED; 1173 return ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
1174 1174
1175 if (rv >= 0) 1175 if (rv >= 0)
1176 return rv; 1176 return rv;
1177 1177
1178 int err = SSL_get_error(ssl_, rv); 1178 int err = SSL_get_error(ssl_, rv);
1179 return MapOpenSSLError(err, err_tracer); 1179 return MapOpenSSLError(err, err_tracer);
1180 } 1180 }
1181 1181
1182 int SSLClientSocketOpenSSL::DoPayloadWrite() { 1182 int SSLClientSocketOpenSSL::DoPayloadWrite() {
1183 base::OpenSSLErrStackTracer err_tracer(FROM_HERE); 1183 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
1184 int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_); 1184 int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_);
1185 1185
1186 if (rv >= 0) 1186 if (rv >= 0)
1187 return rv; 1187 return rv;
1188 1188
1189 int err = SSL_get_error(ssl_, rv); 1189 int err = SSL_get_error(ssl_, rv);
1190 return MapOpenSSLError(err, err_tracer); 1190 return MapOpenSSLError(err, err_tracer);
1191 } 1191 }
1192 1192
1193 } // namespace net 1193 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698