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

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 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 ssl_socket_data_index_ = SSL_get_ex_new_index(0, 0, 0, 0, 0); 168 ssl_socket_data_index_ = SSL_get_ex_new_index(0, 0, 0, 0, 0);
169 DCHECK_NE(ssl_socket_data_index_, -1); 169 DCHECK_NE(ssl_socket_data_index_, -1);
170 ssl_ctx_.reset(SSL_CTX_new(SSLv23_client_method())); 170 ssl_ctx_.reset(SSL_CTX_new(SSLv23_client_method()));
171 SSL_CTX_set_cert_verify_callback(ssl_ctx_.get(), NoOpVerifyCallback, NULL); 171 SSL_CTX_set_cert_verify_callback(ssl_ctx_.get(), NoOpVerifyCallback, NULL);
172 SSL_CTX_set_session_cache_mode(ssl_ctx_.get(), SSL_SESS_CACHE_CLIENT); 172 SSL_CTX_set_session_cache_mode(ssl_ctx_.get(), SSL_SESS_CACHE_CLIENT);
173 SSL_CTX_sess_set_new_cb(ssl_ctx_.get(), NewSessionCallbackStatic); 173 SSL_CTX_sess_set_new_cb(ssl_ctx_.get(), NewSessionCallbackStatic);
174 SSL_CTX_sess_set_remove_cb(ssl_ctx_.get(), RemoveSessionCallbackStatic); 174 SSL_CTX_sess_set_remove_cb(ssl_ctx_.get(), RemoveSessionCallbackStatic);
175 SSL_CTX_set_timeout(ssl_ctx_.get(), kSessionCacheTimeoutSeconds); 175 SSL_CTX_set_timeout(ssl_ctx_.get(), kSessionCacheTimeoutSeconds);
176 SSL_CTX_sess_set_cache_size(ssl_ctx_.get(), kSessionCacheMaxEntires); 176 SSL_CTX_sess_set_cache_size(ssl_ctx_.get(), kSessionCacheMaxEntires);
177 SSL_CTX_set_client_cert_cb(ssl_ctx_.get(), ClientCertCallback); 177 SSL_CTX_set_client_cert_cb(ssl_ctx_.get(), ClientCertCallback);
178 #if defined(OPENSSL_NPN_NEGOTIATED)
179 // TODO(kristianm): Only select this if ssl_config_.next_proto is not empty.
180 // It would be better if the callback were not a global setting,
181 // but that is an OpenSSL issue.
182 SSL_CTX_set_next_proto_select_cb(ssl_ctx_.get(), SelectNextProtoCallback,
183 NULL);
184 #endif
178 } 185 }
179 186
180 static int NewSessionCallbackStatic(SSL* ssl, SSL_SESSION* session) { 187 static int NewSessionCallbackStatic(SSL* ssl, SSL_SESSION* session) {
181 return Get()->NewSessionCallback(ssl, session); 188 return Get()->NewSessionCallback(ssl, session);
182 } 189 }
183 190
184 int NewSessionCallback(SSL* ssl, SSL_SESSION* session) { 191 int NewSessionCallback(SSL* ssl, SSL_SESSION* session) {
185 SSLClientSocketOpenSSL* socket = GetClientSocketFromSSL(ssl); 192 SSLClientSocketOpenSSL* socket = GetClientSocketFromSSL(ssl);
186 session_cache_.OnSessionAdded(socket->host_and_port(), session); 193 session_cache_.OnSessionAdded(socket->host_and_port(), session);
187 return 1; // 1 => We took ownership of |session|. 194 return 1; // 1 => We took ownership of |session|.
188 } 195 }
189 196
190 static void RemoveSessionCallbackStatic(SSL_CTX* ctx, SSL_SESSION* session) { 197 static void RemoveSessionCallbackStatic(SSL_CTX* ctx, SSL_SESSION* session) {
191 return Get()->RemoveSessionCallback(ctx, session); 198 return Get()->RemoveSessionCallback(ctx, session);
192 } 199 }
193 200
194 void RemoveSessionCallback(SSL_CTX* ctx, SSL_SESSION* session) { 201 void RemoveSessionCallback(SSL_CTX* ctx, SSL_SESSION* session) {
195 DCHECK(ctx == ssl_ctx()); 202 DCHECK(ctx == ssl_ctx());
196 session_cache_.OnSessionRemoved(session); 203 session_cache_.OnSessionRemoved(session);
197 } 204 }
198 205
199 static int ClientCertCallback(SSL* ssl, X509** x509, EVP_PKEY** pkey) { 206 static int ClientCertCallback(SSL* ssl, X509** x509, EVP_PKEY** pkey) {
200 SSLClientSocketOpenSSL* socket = Get()->GetClientSocketFromSSL(ssl); 207 SSLClientSocketOpenSSL* socket = Get()->GetClientSocketFromSSL(ssl);
201 CHECK(socket); 208 CHECK(socket);
202 return socket->ClientCertRequestCallback(ssl, x509, pkey); 209 return socket->ClientCertRequestCallback(ssl, x509, pkey);
203 } 210 }
204 211
212 static int SelectNextProtoCallback(SSL* ssl,
213 unsigned char** out, unsigned char* outlen,
214 const unsigned char* in,
215 unsigned int inlen, void* arg) {
216 SSLClientSocketOpenSSL* socket = Get()->GetClientSocketFromSSL(ssl);
217 return socket->SelectNextProtoCallback(out, outlen, in, inlen);
218 }
219
205 // This is the index used with SSL_get_ex_data to retrieve the owner 220 // This is the index used with SSL_get_ex_data to retrieve the owner
206 // SSLClientSocketOpenSSL object from an SSL instance. 221 // SSLClientSocketOpenSSL object from an SSL instance.
207 int ssl_socket_data_index_; 222 int ssl_socket_data_index_;
208 223
209 base::ScopedOpenSSL<SSL_CTX, SSL_CTX_free> ssl_ctx_; 224 base::ScopedOpenSSL<SSL_CTX, SSL_CTX_free> ssl_ctx_;
210 SSLSessionCache session_cache_; 225 SSLSessionCache session_cache_;
211 }; 226 };
212 227
213 // Utility to construct the appropriate set & clear masks for use the OpenSSL 228 // Utility to construct the appropriate set & clear masks for use the OpenSSL
214 // options and mode configuration functions. (SSL_set_options etc) 229 // options and mode configuration functions. (SSL_set_options etc)
(...skipping 26 matching lines...) Expand all
241 completed_handshake_(false), 256 completed_handshake_(false),
242 client_auth_cert_needed_(false), 257 client_auth_cert_needed_(false),
243 ALLOW_THIS_IN_INITIALIZER_LIST(handshake_io_callback_( 258 ALLOW_THIS_IN_INITIALIZER_LIST(handshake_io_callback_(
244 this, &SSLClientSocketOpenSSL::OnHandshakeIOComplete)), 259 this, &SSLClientSocketOpenSSL::OnHandshakeIOComplete)),
245 ssl_(NULL), 260 ssl_(NULL),
246 transport_bio_(NULL), 261 transport_bio_(NULL),
247 transport_(transport_socket), 262 transport_(transport_socket),
248 host_and_port_(host_and_port), 263 host_and_port_(host_and_port),
249 ssl_config_(ssl_config), 264 ssl_config_(ssl_config),
250 trying_cached_session_(false), 265 trying_cached_session_(false),
266 npn_status_(kNextProtoUnsupported),
251 net_log_(transport_socket->socket()->NetLog()) { 267 net_log_(transport_socket->socket()->NetLog()) {
252 } 268 }
253 269
254 SSLClientSocketOpenSSL::~SSLClientSocketOpenSSL() { 270 SSLClientSocketOpenSSL::~SSLClientSocketOpenSSL() {
255 Disconnect(); 271 Disconnect();
256 } 272 }
257 273
258 bool SSLClientSocketOpenSSL::Init() { 274 bool SSLClientSocketOpenSSL::Init() {
259 DCHECK(!ssl_); 275 DCHECK(!ssl_);
260 DCHECK(!transport_bio_); 276 DCHECK(!transport_bio_);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 } 379 }
364 380
365 void SSLClientSocketOpenSSL::GetSSLCertRequestInfo( 381 void SSLClientSocketOpenSSL::GetSSLCertRequestInfo(
366 SSLCertRequestInfo* cert_request_info) { 382 SSLCertRequestInfo* cert_request_info) {
367 cert_request_info->host_and_port = host_and_port_.ToString(); 383 cert_request_info->host_and_port = host_and_port_.ToString();
368 cert_request_info->client_certs = client_certs_; 384 cert_request_info->client_certs = client_certs_;
369 } 385 }
370 386
371 SSLClientSocket::NextProtoStatus SSLClientSocketOpenSSL::GetNextProto( 387 SSLClientSocket::NextProtoStatus SSLClientSocketOpenSSL::GetNextProto(
372 std::string* proto) { 388 std::string* proto) {
373 proto->clear(); 389 *proto = npn_proto_;
374 return kNextProtoUnsupported; 390 return npn_status_;
375 } 391 }
376 392
377 void SSLClientSocketOpenSSL::DoReadCallback(int rv) { 393 void SSLClientSocketOpenSSL::DoReadCallback(int rv) {
378 // Since Run may result in Read being called, clear |user_read_callback_| 394 // Since Run may result in Read being called, clear |user_read_callback_|
379 // up front. 395 // up front.
380 CompletionCallback* c = user_read_callback_; 396 CompletionCallback* c = user_read_callback_;
381 user_read_callback_ = NULL; 397 user_read_callback_ = NULL;
382 user_read_buf_ = NULL; 398 user_read_buf_ = NULL;
383 user_read_buf_len_ = 0; 399 user_read_buf_len_ = 0;
384 c->Run(rv); 400 c->Run(rv);
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 // TODO(joth): We need a way to lookup the private key this 576 // TODO(joth): We need a way to lookup the private key this
561 // certificate. See http://crbug.com/64951 and example code in 577 // certificate. See http://crbug.com/64951 and example code in
562 // http://codereview.chromium.org/5195001/diff/6001/net/socket/ssl_client_so cket_openssl.cc 578 // http://codereview.chromium.org/5195001/diff/6001/net/socket/ssl_client_so cket_openssl.cc
563 NOTIMPLEMENTED(); 579 NOTIMPLEMENTED();
564 } 580 }
565 581
566 // Send no client certificate. 582 // Send no client certificate.
567 return 0; 583 return 0;
568 } 584 }
569 585
586 int SSLClientSocketOpenSSL::SelectNextProtoCallback(unsigned char** out,
587 unsigned char* outlen,
588 const unsigned char* in,
589 unsigned int inlen) {
590 #if defined(OPENSSL_NPN_NEGOTIATED)
591 if (ssl_config_.next_protos.empty()) {
592 *outlen = 0;
agl 2010/12/03 15:17:37 *out = "http/1.1"; *outlen = 8;
Kristian_ 2010/12/03 15:30:57 I added this in later patch, should I change to th
593 return SSL_TLSEXT_ERR_OK;
594 }
595
596 int status = SSL_select_next_proto(
597 out, outlen, in, inlen,
598 reinterpret_cast<const unsigned char*>(ssl_config_.next_protos.data()),
599 ssl_config_.next_protos.size());
600
601 npn_proto_.assign(reinterpret_cast<const char*>(*out), *outlen);
602 switch (status) {
603 //case OPENSSL_NPN_UNSUPPORTED:
agl 2010/12/03 15:17:37 Why commented out?
Kristian_ 2010/12/03 15:30:57 Thanks, it was to test compile on ubuntu where the
604 npn_status_ = SSLClientSocket::kNextProtoUnsupported;
605 break;
606 //case OPENSSL_NPN_NEGOTIATED:
607 npn_status_ = SSLClientSocket::kNextProtoNegotiated;
608 break;
609 //case OPENSSL_NPN_NO_OVERLAP:
610 npn_status_ = SSLClientSocket::kNextProtoNoOverlap;
611 break;
612 default:
613 NOTREACHED() << status;
614 break;
615 }
616 #endif
617 return SSL_TLSEXT_ERR_OK;
618 }
619
570 int SSLClientSocketOpenSSL::DoVerifyCert(int result) { 620 int SSLClientSocketOpenSSL::DoVerifyCert(int result) {
571 DCHECK(server_cert_); 621 DCHECK(server_cert_);
572 GotoState(STATE_VERIFY_CERT_COMPLETE); 622 GotoState(STATE_VERIFY_CERT_COMPLETE);
573 int flags = 0; 623 int flags = 0;
574 624
575 if (ssl_config_.rev_checking_enabled) 625 if (ssl_config_.rev_checking_enabled)
576 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED; 626 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED;
577 if (ssl_config_.verify_ev_cert) 627 if (ssl_config_.verify_ev_cert)
578 flags |= X509Certificate::VERIFY_EV_CERT; 628 flags |= X509Certificate::VERIFY_EV_CERT;
579 verifier_.reset(new CertVerifier); 629 verifier_.reset(new CertVerifier);
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_); 994 int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_);
945 995
946 if (rv >= 0) 996 if (rv >= 0)
947 return rv; 997 return rv;
948 998
949 int err = SSL_get_error(ssl_, rv); 999 int err = SSL_get_error(ssl_, rv);
950 return MapOpenSSLError(err); 1000 return MapOpenSSLError(err);
951 } 1001 }
952 1002
953 } // namespace net 1003 } // 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