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

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

Issue 5528003: Add support for OpenSSL Next Protocol Negotiation (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 10 years 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
« no previous file with comments | « net/socket/ssl_client_socket_openssl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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>
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 ssl_socket_data_index_ = SSL_get_ex_new_index(0, 0, 0, 0, 0); 304 ssl_socket_data_index_ = SSL_get_ex_new_index(0, 0, 0, 0, 0);
305 DCHECK_NE(ssl_socket_data_index_, -1); 305 DCHECK_NE(ssl_socket_data_index_, -1);
306 ssl_ctx_.reset(SSL_CTX_new(SSLv23_client_method())); 306 ssl_ctx_.reset(SSL_CTX_new(SSLv23_client_method()));
307 SSL_CTX_set_cert_verify_callback(ssl_ctx_.get(), NoOpVerifyCallback, NULL); 307 SSL_CTX_set_cert_verify_callback(ssl_ctx_.get(), NoOpVerifyCallback, NULL);
308 SSL_CTX_set_session_cache_mode(ssl_ctx_.get(), SSL_SESS_CACHE_CLIENT); 308 SSL_CTX_set_session_cache_mode(ssl_ctx_.get(), SSL_SESS_CACHE_CLIENT);
309 SSL_CTX_sess_set_new_cb(ssl_ctx_.get(), NewSessionCallbackStatic); 309 SSL_CTX_sess_set_new_cb(ssl_ctx_.get(), NewSessionCallbackStatic);
310 SSL_CTX_sess_set_remove_cb(ssl_ctx_.get(), RemoveSessionCallbackStatic); 310 SSL_CTX_sess_set_remove_cb(ssl_ctx_.get(), RemoveSessionCallbackStatic);
311 SSL_CTX_set_timeout(ssl_ctx_.get(), kSessionCacheTimeoutSeconds); 311 SSL_CTX_set_timeout(ssl_ctx_.get(), kSessionCacheTimeoutSeconds);
312 SSL_CTX_sess_set_cache_size(ssl_ctx_.get(), kSessionCacheMaxEntires); 312 SSL_CTX_sess_set_cache_size(ssl_ctx_.get(), kSessionCacheMaxEntires);
313 SSL_CTX_set_client_cert_cb(ssl_ctx_.get(), ClientCertCallback); 313 SSL_CTX_set_client_cert_cb(ssl_ctx_.get(), ClientCertCallback);
314 #if defined(OPENSSL_NPN_NEGOTIATED)
315 // TODO(kristianm): Only select this if ssl_config_.next_proto is not empty.
316 // It would be better if the callback were not a global setting,
317 // but that is an OpenSSL issue.
318 SSL_CTX_set_next_proto_select_cb(ssl_ctx_.get(), SelectNextProtoCallback,
319 NULL);
320 #endif
314 } 321 }
315 322
316 static int NewSessionCallbackStatic(SSL* ssl, SSL_SESSION* session) { 323 static int NewSessionCallbackStatic(SSL* ssl, SSL_SESSION* session) {
317 return Get()->NewSessionCallback(ssl, session); 324 return Get()->NewSessionCallback(ssl, session);
318 } 325 }
319 326
320 int NewSessionCallback(SSL* ssl, SSL_SESSION* session) { 327 int NewSessionCallback(SSL* ssl, SSL_SESSION* session) {
321 SSLClientSocketOpenSSL* socket = GetClientSocketFromSSL(ssl); 328 SSLClientSocketOpenSSL* socket = GetClientSocketFromSSL(ssl);
322 session_cache_.OnSessionAdded(socket->host_and_port(), session); 329 session_cache_.OnSessionAdded(socket->host_and_port(), session);
323 return 1; // 1 => We took ownership of |session|. 330 return 1; // 1 => We took ownership of |session|.
324 } 331 }
325 332
326 static void RemoveSessionCallbackStatic(SSL_CTX* ctx, SSL_SESSION* session) { 333 static void RemoveSessionCallbackStatic(SSL_CTX* ctx, SSL_SESSION* session) {
327 return Get()->RemoveSessionCallback(ctx, session); 334 return Get()->RemoveSessionCallback(ctx, session);
328 } 335 }
329 336
330 void RemoveSessionCallback(SSL_CTX* ctx, SSL_SESSION* session) { 337 void RemoveSessionCallback(SSL_CTX* ctx, SSL_SESSION* session) {
331 DCHECK(ctx == ssl_ctx()); 338 DCHECK(ctx == ssl_ctx());
332 session_cache_.OnSessionRemoved(session); 339 session_cache_.OnSessionRemoved(session);
333 } 340 }
334 341
335 static int ClientCertCallback(SSL* ssl, X509** x509, EVP_PKEY** pkey) { 342 static int ClientCertCallback(SSL* ssl, X509** x509, EVP_PKEY** pkey) {
336 SSLClientSocketOpenSSL* socket = Get()->GetClientSocketFromSSL(ssl); 343 SSLClientSocketOpenSSL* socket = Get()->GetClientSocketFromSSL(ssl);
337 CHECK(socket); 344 CHECK(socket);
338 return socket->ClientCertRequestCallback(ssl, x509, pkey); 345 return socket->ClientCertRequestCallback(ssl, x509, pkey);
339 } 346 }
340 347
348 static int SelectNextProtoCallback(SSL* ssl,
349 unsigned char** out, unsigned char* outlen,
350 const unsigned char* in,
351 unsigned int inlen, void* arg) {
352 SSLClientSocketOpenSSL* socket = Get()->GetClientSocketFromSSL(ssl);
353 return socket->SelectNextProtoCallback(out, outlen, in, inlen);
354 }
355
341 // This is the index used with SSL_get_ex_data to retrieve the owner 356 // This is the index used with SSL_get_ex_data to retrieve the owner
342 // SSLClientSocketOpenSSL object from an SSL instance. 357 // SSLClientSocketOpenSSL object from an SSL instance.
343 int ssl_socket_data_index_; 358 int ssl_socket_data_index_;
344 359
345 base::ScopedOpenSSL<SSL_CTX, SSL_CTX_free> ssl_ctx_; 360 base::ScopedOpenSSL<SSL_CTX, SSL_CTX_free> ssl_ctx_;
346 SSLSessionCache session_cache_; 361 SSLSessionCache session_cache_;
347 }; 362 };
348 363
349 // Utility to construct the appropriate set & clear masks for use the OpenSSL 364 // Utility to construct the appropriate set & clear masks for use the OpenSSL
350 // options and mode configuration functions. (SSL_set_options etc) 365 // options and mode configuration functions. (SSL_set_options etc)
(...skipping 26 matching lines...) Expand all
377 completed_handshake_(false), 392 completed_handshake_(false),
378 client_auth_cert_needed_(false), 393 client_auth_cert_needed_(false),
379 ALLOW_THIS_IN_INITIALIZER_LIST(handshake_io_callback_( 394 ALLOW_THIS_IN_INITIALIZER_LIST(handshake_io_callback_(
380 this, &SSLClientSocketOpenSSL::OnHandshakeIOComplete)), 395 this, &SSLClientSocketOpenSSL::OnHandshakeIOComplete)),
381 ssl_(NULL), 396 ssl_(NULL),
382 transport_bio_(NULL), 397 transport_bio_(NULL),
383 transport_(transport_socket), 398 transport_(transport_socket),
384 host_and_port_(host_and_port), 399 host_and_port_(host_and_port),
385 ssl_config_(ssl_config), 400 ssl_config_(ssl_config),
386 trying_cached_session_(false), 401 trying_cached_session_(false),
402 npn_status_(kNextProtoUnsupported),
387 net_log_(transport_socket->socket()->NetLog()) { 403 net_log_(transport_socket->socket()->NetLog()) {
388 } 404 }
389 405
390 SSLClientSocketOpenSSL::~SSLClientSocketOpenSSL() { 406 SSLClientSocketOpenSSL::~SSLClientSocketOpenSSL() {
391 Disconnect(); 407 Disconnect();
392 } 408 }
393 409
394 bool SSLClientSocketOpenSSL::Init() { 410 bool SSLClientSocketOpenSSL::Init() {
395 DCHECK(!ssl_); 411 DCHECK(!ssl_);
396 DCHECK(!transport_bio_); 412 DCHECK(!transport_bio_);
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 } 576 }
561 577
562 void SSLClientSocketOpenSSL::GetSSLCertRequestInfo( 578 void SSLClientSocketOpenSSL::GetSSLCertRequestInfo(
563 SSLCertRequestInfo* cert_request_info) { 579 SSLCertRequestInfo* cert_request_info) {
564 cert_request_info->host_and_port = host_and_port_.ToString(); 580 cert_request_info->host_and_port = host_and_port_.ToString();
565 cert_request_info->client_certs = client_certs_; 581 cert_request_info->client_certs = client_certs_;
566 } 582 }
567 583
568 SSLClientSocket::NextProtoStatus SSLClientSocketOpenSSL::GetNextProto( 584 SSLClientSocket::NextProtoStatus SSLClientSocketOpenSSL::GetNextProto(
569 std::string* proto) { 585 std::string* proto) {
570 proto->clear(); 586 *proto = npn_proto_;
571 return kNextProtoUnsupported; 587 return npn_status_;
572 } 588 }
573 589
574 void SSLClientSocketOpenSSL::DoReadCallback(int rv) { 590 void SSLClientSocketOpenSSL::DoReadCallback(int rv) {
575 // Since Run may result in Read being called, clear |user_read_callback_| 591 // Since Run may result in Read being called, clear |user_read_callback_|
576 // up front. 592 // up front.
577 CompletionCallback* c = user_read_callback_; 593 CompletionCallback* c = user_read_callback_;
578 user_read_callback_ = NULL; 594 user_read_callback_ = NULL;
579 user_read_buf_ = NULL; 595 user_read_buf_ = NULL;
580 user_read_buf_len_ = 0; 596 user_read_buf_len_ = 0;
581 c->Run(rv); 597 c->Run(rv);
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 << ", SSL error code " << ssl_error 751 << ", SSL error code " << ssl_error
736 << ", net_error " << net_error; 752 << ", net_error " << net_error;
737 net_log_.AddEvent( 753 net_log_.AddEvent(
738 NetLog::TYPE_SSL_HANDSHAKE_ERROR, 754 NetLog::TYPE_SSL_HANDSHAKE_ERROR,
739 make_scoped_refptr(new SSLErrorParams(net_error, ssl_error))); 755 make_scoped_refptr(new SSLErrorParams(net_error, ssl_error)));
740 } 756 }
741 } 757 }
742 return net_error; 758 return net_error;
743 } 759 }
744 760
761 int SSLClientSocketOpenSSL::SelectNextProtoCallback(unsigned char** out,
762 unsigned char* outlen,
763 const unsigned char* in,
764 unsigned int inlen) {
765 #if defined(OPENSSL_NPN_NEGOTIATED)
766 if (ssl_config_.next_protos.empty()) {
767 *out = "http/1.1";
768 *outlen = 8;
769 npn_status_ = SSLClientSocket::kNextProtoUnsupported;
770 return SSL_TLSEXT_ERR_OK;
771 }
772
773 int status = SSL_select_next_proto(
774 out, outlen, in, inlen,
775 reinterpret_cast<const unsigned char*>(ssl_config_.next_protos.data()),
776 ssl_config_.next_protos.size());
777
778 npn_proto_.assign(reinterpret_cast<const char*>(*out), *outlen);
779 switch (status) {
780 case OPENSSL_NPN_UNSUPPORTED:
781 npn_status_ = SSLClientSocket::kNextProtoUnsupported;
782 break;
783 case OPENSSL_NPN_NEGOTIATED:
784 npn_status_ = SSLClientSocket::kNextProtoNegotiated;
785 break;
786 case OPENSSL_NPN_NO_OVERLAP:
787 npn_status_ = SSLClientSocket::kNextProtoNoOverlap;
788 break;
789 default:
790 NOTREACHED() << status;
791 break;
792 }
793 #endif
794 return SSL_TLSEXT_ERR_OK;
795 }
796
745 int SSLClientSocketOpenSSL::DoVerifyCert(int result) { 797 int SSLClientSocketOpenSSL::DoVerifyCert(int result) {
746 DCHECK(server_cert_); 798 DCHECK(server_cert_);
747 GotoState(STATE_VERIFY_CERT_COMPLETE); 799 GotoState(STATE_VERIFY_CERT_COMPLETE);
748 int flags = 0; 800 int flags = 0;
749 801
750 if (ssl_config_.rev_checking_enabled) 802 if (ssl_config_.rev_checking_enabled)
751 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED; 803 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED;
752 if (ssl_config_.verify_ev_cert) 804 if (ssl_config_.verify_ev_cert)
753 flags |= X509Certificate::VERIFY_EV_CERT; 805 flags |= X509Certificate::VERIFY_EV_CERT;
754 verifier_.reset(new CertVerifier); 806 verifier_.reset(new CertVerifier);
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
1119 int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_); 1171 int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_);
1120 1172
1121 if (rv >= 0) 1173 if (rv >= 0)
1122 return rv; 1174 return rv;
1123 1175
1124 int err = SSL_get_error(ssl_, rv); 1176 int err = SSL_get_error(ssl_, rv);
1125 return MapOpenSSLError(err, err_tracer); 1177 return MapOpenSSLError(err, err_tracer);
1126 } 1178 }
1127 1179
1128 } // namespace net 1180 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/ssl_client_socket_openssl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698