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

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

Issue 1360633002: Implement Token Binding negotiation TLS extension (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@test-server-flags
Patch Set: respond to comments Created 5 years, 1 month 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <errno.h> 10 #include <errno.h>
11 #include <openssl/bio.h> 11 #include <openssl/bio.h>
12 #include <openssl/bytestring.h>
12 #include <openssl/err.h> 13 #include <openssl/err.h>
14 #include <openssl/evp.h>
13 #include <openssl/mem.h> 15 #include <openssl/mem.h>
14 #include <openssl/ssl.h> 16 #include <openssl/ssl.h>
15 #include <string.h> 17 #include <string.h>
16 18
17 #include "base/bind.h" 19 #include "base/bind.h"
18 #include "base/callback_helpers.h" 20 #include "base/callback_helpers.h"
19 #include "base/lazy_instance.h" 21 #include "base/lazy_instance.h"
20 #include "base/memory/singleton.h" 22 #include "base/memory/singleton.h"
21 #include "base/metrics/histogram_macros.h" 23 #include "base/metrics/histogram_macros.h"
22 #include "base/profiler/scoped_tracker.h" 24 #include "base/profiler/scoped_tracker.h"
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 // overlap with any value of the net::Error range, including net::OK). 77 // overlap with any value of the net::Error range, including net::OK).
76 const int kNoPendingResult = 1; 78 const int kNoPendingResult = 1;
77 79
78 // If a client doesn't have a list of protocols that it supports, but 80 // If a client doesn't have a list of protocols that it supports, but
79 // the server supports NPN, choosing "http/1.1" is the best answer. 81 // the server supports NPN, choosing "http/1.1" is the best answer.
80 const char kDefaultSupportedNPNProtocol[] = "http/1.1"; 82 const char kDefaultSupportedNPNProtocol[] = "http/1.1";
81 83
82 // Default size of the internal BoringSSL buffers. 84 // Default size of the internal BoringSSL buffers.
83 const int KDefaultOpenSSLBufferSize = 17 * 1024; 85 const int KDefaultOpenSSLBufferSize = 17 * 1024;
84 86
87 // TLS extension number use for Token Binding.
88 const unsigned int kTbExtNum = 30033;
89
90 // Token Binding ProtocolVersions supported.
91 const uint8_t kTbProtocolVersionMajor = 0;
92 const uint8_t kTbProtocolVersionMinor = 3;
93 const uint8_t kTbMinProtocolVersionMajor = 0;
94 const uint8_t kTbMinProtocolVersionMinor = 2;
95
85 void FreeX509Stack(STACK_OF(X509)* ptr) { 96 void FreeX509Stack(STACK_OF(X509)* ptr) {
86 sk_X509_pop_free(ptr, X509_free); 97 sk_X509_pop_free(ptr, X509_free);
87 } 98 }
88 99
89 using ScopedX509Stack = crypto::ScopedOpenSSL<STACK_OF(X509), FreeX509Stack>; 100 using ScopedX509Stack = crypto::ScopedOpenSSL<STACK_OF(X509), FreeX509Stack>;
90 101
91 // Used for encoding the |connection_status| field of an SSLInfo object. 102 // Used for encoding the |connection_status| field of an SSLInfo object.
92 int EncodeSSLConnectionStatus(uint16 cipher_suite, 103 int EncodeSSLConnectionStatus(uint16 cipher_suite,
93 int compression, 104 int compression,
94 int version) { 105 int version) {
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 // Note that SSL_OP_DISABLE_NPN is used to disable NPN if 247 // Note that SSL_OP_DISABLE_NPN is used to disable NPN if
237 // ssl_config_.next_proto is empty. 248 // ssl_config_.next_proto is empty.
238 SSL_CTX_set_next_proto_select_cb(ssl_ctx_.get(), SelectNextProtoCallback, 249 SSL_CTX_set_next_proto_select_cb(ssl_ctx_.get(), SelectNextProtoCallback,
239 NULL); 250 NULL);
240 251
241 // Disable the internal session cache. Session caching is handled 252 // Disable the internal session cache. Session caching is handled
242 // externally (i.e. by SSLClientSessionCacheOpenSSL). 253 // externally (i.e. by SSLClientSessionCacheOpenSSL).
243 SSL_CTX_set_session_cache_mode( 254 SSL_CTX_set_session_cache_mode(
244 ssl_ctx_.get(), SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL); 255 ssl_ctx_.get(), SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL);
245 SSL_CTX_sess_set_new_cb(ssl_ctx_.get(), NewSessionCallback); 256 SSL_CTX_sess_set_new_cb(ssl_ctx_.get(), NewSessionCallback);
257
258 if (SSL_CTX_add_client_custom_ext(
davidben 2015/11/04 17:40:13 Nit: This can just be if (!SSL_CTX_....) { Boring
nharper 2015/11/04 19:43:19 Done.
259 ssl_ctx_.get(), kTbExtNum,
260 &SSLClientSocketOpenSSL::TokenBindingAddCallback,
261 &SSLClientSocketOpenSSL::TokenBindingFreeCallback, nullptr,
262 &SSLClientSocketOpenSSL::TokenBindingParseCallback, nullptr) != 1) {
263 NOTREACHED();
264 }
246 } 265 }
247 266
248 static int ClientCertRequestCallback(SSL* ssl, void* arg) { 267 static int ClientCertRequestCallback(SSL* ssl, void* arg) {
249 SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl); 268 SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl);
250 DCHECK(socket); 269 DCHECK(socket);
251 return socket->ClientCertRequestCallback(ssl); 270 return socket->ClientCertRequestCallback(ssl);
252 } 271 }
253 272
254 static int CertVerifyCallback(X509_STORE_CTX *store_ctx, void *arg) { 273 static int CertVerifyCallback(X509_STORE_CTX *store_ctx, void *arg) {
255 SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data( 274 SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 pending_read_error_(kNoPendingResult), 443 pending_read_error_(kNoPendingResult),
425 pending_read_ssl_error_(SSL_ERROR_NONE), 444 pending_read_ssl_error_(SSL_ERROR_NONE),
426 transport_read_error_(OK), 445 transport_read_error_(OK),
427 transport_write_error_(OK), 446 transport_write_error_(OK),
428 server_cert_chain_(new PeerCertificateChain(NULL)), 447 server_cert_chain_(new PeerCertificateChain(NULL)),
429 completed_connect_(false), 448 completed_connect_(false),
430 was_ever_used_(false), 449 was_ever_used_(false),
431 cert_verifier_(context.cert_verifier), 450 cert_verifier_(context.cert_verifier),
432 cert_transparency_verifier_(context.cert_transparency_verifier), 451 cert_transparency_verifier_(context.cert_transparency_verifier),
433 channel_id_service_(context.channel_id_service), 452 channel_id_service_(context.channel_id_service),
453 tb_was_negotiated_(false),
454 tb_negotiated_param_(TB_PARAM_ECDSAP256),
434 ssl_(NULL), 455 ssl_(NULL),
435 transport_bio_(NULL), 456 transport_bio_(NULL),
436 transport_(transport_socket.Pass()), 457 transport_(transport_socket.Pass()),
437 host_and_port_(host_and_port), 458 host_and_port_(host_and_port),
438 ssl_config_(ssl_config), 459 ssl_config_(ssl_config),
439 ssl_session_cache_shard_(context.ssl_session_cache_shard), 460 ssl_session_cache_shard_(context.ssl_session_cache_shard),
440 next_handshake_state_(STATE_NONE), 461 next_handshake_state_(STATE_NONE),
441 disconnected_(false), 462 disconnected_(false),
442 npn_status_(kNextProtoUnsupported), 463 npn_status_(kNextProtoUnsupported),
443 channel_id_sent_(false), 464 channel_id_sent_(false),
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 621
601 cert_authorities_.clear(); 622 cert_authorities_.clear();
602 cert_key_types_.clear(); 623 cert_key_types_.clear();
603 624
604 start_cert_verification_time_ = base::TimeTicks(); 625 start_cert_verification_time_ = base::TimeTicks();
605 626
606 npn_status_ = kNextProtoUnsupported; 627 npn_status_ = kNextProtoUnsupported;
607 npn_proto_.clear(); 628 npn_proto_.clear();
608 629
609 channel_id_sent_ = false; 630 channel_id_sent_ = false;
631 tb_was_negotiated_ = false;
610 session_pending_ = false; 632 session_pending_ = false;
611 certificate_verified_ = false; 633 certificate_verified_ = false;
612 channel_id_request_.Cancel(); 634 channel_id_request_.Cancel();
613 ssl_failure_state_ = SSL_FAILURE_NONE; 635 ssl_failure_state_ = SSL_FAILURE_NONE;
614 636
615 private_key_.reset(); 637 private_key_.reset();
616 signature_result_ = kNoPendingResult; 638 signature_result_ = kNoPendingResult;
617 signature_.clear(); 639 signature_.clear();
618 } 640 }
619 641
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 ssl_info->cert = server_cert_verify_result_.verified_cert; 719 ssl_info->cert = server_cert_verify_result_.verified_cert;
698 ssl_info->unverified_cert = server_cert_; 720 ssl_info->unverified_cert = server_cert_;
699 ssl_info->cert_status = server_cert_verify_result_.cert_status; 721 ssl_info->cert_status = server_cert_verify_result_.cert_status;
700 ssl_info->is_issued_by_known_root = 722 ssl_info->is_issued_by_known_root =
701 server_cert_verify_result_.is_issued_by_known_root; 723 server_cert_verify_result_.is_issued_by_known_root;
702 ssl_info->public_key_hashes = 724 ssl_info->public_key_hashes =
703 server_cert_verify_result_.public_key_hashes; 725 server_cert_verify_result_.public_key_hashes;
704 ssl_info->client_cert_sent = 726 ssl_info->client_cert_sent =
705 ssl_config_.send_client_cert && ssl_config_.client_cert.get(); 727 ssl_config_.send_client_cert && ssl_config_.client_cert.get();
706 ssl_info->channel_id_sent = channel_id_sent_; 728 ssl_info->channel_id_sent = channel_id_sent_;
729 ssl_info->token_binding_negotiated = tb_was_negotiated_;
730 ssl_info->token_binding_key_param = tb_negotiated_param_;
707 ssl_info->pinning_failure_log = pinning_failure_log_; 731 ssl_info->pinning_failure_log = pinning_failure_log_;
708 732
709 AddSCTInfoToSSLInfo(ssl_info); 733 AddSCTInfoToSSLInfo(ssl_info);
710 734
711 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl_); 735 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl_);
712 CHECK(cipher); 736 CHECK(cipher);
713 ssl_info->security_bits = SSL_CIPHER_get_bits(cipher, NULL); 737 ssl_info->security_bits = SSL_CIPHER_get_bits(cipher, NULL);
714 ssl_info->key_exchange_info = 738 ssl_info->key_exchange_info =
715 SSL_SESSION_get_key_exchange_info(SSL_get_session(ssl_)); 739 SSL_SESSION_get_key_exchange_info(SSL_get_session(ssl_));
716 740
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 1120
1097 int SSLClientSocketOpenSSL::DoHandshakeComplete(int result) { 1121 int SSLClientSocketOpenSSL::DoHandshakeComplete(int result) {
1098 if (result < 0) 1122 if (result < 0)
1099 return result; 1123 return result;
1100 1124
1101 if (ssl_config_.version_fallback && 1125 if (ssl_config_.version_fallback &&
1102 ssl_config_.version_max < ssl_config_.version_fallback_min) { 1126 ssl_config_.version_max < ssl_config_.version_fallback_min) {
1103 return ERR_SSL_FALLBACK_BEYOND_MINIMUM_VERSION; 1127 return ERR_SSL_FALLBACK_BEYOND_MINIMUM_VERSION;
1104 } 1128 }
1105 1129
1130 // Check that if token binding was negotiated, then extended master secret
1131 // must also be negotiated.
1132 if (tb_was_negotiated_ && !SSL_get_extms_support(ssl_))
1133 return ERR_SSL_PROTOCOL_ERROR;
1134
1106 // SSL handshake is completed. If NPN wasn't negotiated, see if ALPN was. 1135 // SSL handshake is completed. If NPN wasn't negotiated, see if ALPN was.
1107 if (npn_status_ == kNextProtoUnsupported) { 1136 if (npn_status_ == kNextProtoUnsupported) {
1108 const uint8_t* alpn_proto = NULL; 1137 const uint8_t* alpn_proto = NULL;
1109 unsigned alpn_len = 0; 1138 unsigned alpn_len = 0;
1110 SSL_get0_alpn_selected(ssl_, &alpn_proto, &alpn_len); 1139 SSL_get0_alpn_selected(ssl_, &alpn_proto, &alpn_len);
1111 if (alpn_len > 0) { 1140 if (alpn_len > 0) {
1112 npn_proto_.assign(reinterpret_cast<const char*>(alpn_proto), alpn_len); 1141 npn_proto_.assign(reinterpret_cast<const char*>(alpn_proto), alpn_len);
1113 npn_status_ = kNextProtoNegotiated; 1142 npn_status_ = kNextProtoNegotiated;
1114 set_negotiation_extension(kExtensionALPN); 1143 set_negotiation_extension(kExtensionALPN);
1115 } 1144 }
(...skipping 942 matching lines...) Expand 10 before | Expand all | Expand 10 after
2058 result.append("deprecated"); 2087 result.append("deprecated");
2059 2088
2060 result.append("/"); 2089 result.append("/");
2061 if (ssl_config_.channel_id_enabled) 2090 if (ssl_config_.channel_id_enabled)
2062 result.append("channelid"); 2091 result.append("channelid");
2063 2092
2064 return result; 2093 return result;
2065 } 2094 }
2066 2095
2067 bool SSLClientSocketOpenSSL::IsRenegotiationAllowed() const { 2096 bool SSLClientSocketOpenSSL::IsRenegotiationAllowed() const {
2097 if (tb_was_negotiated_)
2098 return false;
2099
2068 if (npn_status_ == kNextProtoUnsupported) 2100 if (npn_status_ == kNextProtoUnsupported)
2069 return ssl_config_.renego_allowed_default; 2101 return ssl_config_.renego_allowed_default;
2070 2102
2071 NextProto next_proto = NextProtoFromString(npn_proto_); 2103 NextProto next_proto = NextProtoFromString(npn_proto_);
2072 for (NextProto allowed : ssl_config_.renego_allowed_for_protos) { 2104 for (NextProto allowed : ssl_config_.renego_allowed_for_protos) {
2073 if (next_proto == allowed) 2105 if (next_proto == allowed)
2074 return true; 2106 return true;
2075 } 2107 }
2076 return false; 2108 return false;
2077 } 2109 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
2158 if (next_handshake_state_ == STATE_HANDSHAKE) { 2190 if (next_handshake_state_ == STATE_HANDSHAKE) {
2159 OnHandshakeIOComplete(signature_result_); 2191 OnHandshakeIOComplete(signature_result_);
2160 return; 2192 return;
2161 } 2193 }
2162 2194
2163 // During a renegotiation, either Read or Write calls may be blocked on an 2195 // During a renegotiation, either Read or Write calls may be blocked on an
2164 // asynchronous private key operation. 2196 // asynchronous private key operation.
2165 PumpReadWriteEvents(); 2197 PumpReadWriteEvents();
2166 } 2198 }
2167 2199
2200 namespace {
2201 class ScopedCBB {
2202 public:
2203 ScopedCBB() { CBB_zero(&cbb_); }
2204 ~ScopedCBB() { CBB_cleanup(&cbb_); }
2205
2206 CBB* get() { return &cbb_; }
2207
2208 private:
2209 CBB cbb_;
2210 DISALLOW_COPY_AND_ASSIGN(ScopedCBB);
2211 };
2212 }
davidben 2015/11/04 17:40:13 Nit: I'd put this up in line 207 with all the othe
nharper 2015/11/04 19:43:19 Done.
2213
2214 int SSLClientSocketOpenSSL::TokenBindingAdd(const uint8_t** out,
2215 size_t* out_len,
2216 int* out_alert_value) {
2217 if (ssl_config_.token_binding_params.empty()) {
2218 return 0;
2219 }
2220 ScopedCBB output;
2221 CBB parameters_list;
2222 int retval = -1;
2223 if (!CBB_init(output.get(), 7) ||
2224 !CBB_add_u8(output.get(), kTbProtocolVersionMajor) ||
2225 !CBB_add_u8(output.get(), kTbProtocolVersionMinor) ||
2226 !CBB_add_u8_length_prefixed(output.get(), &parameters_list)) {
2227 return 0;
davidben 2015/11/04 17:40:13 *out_alert_value = SSL_AD_INTERNAL_ERROR; return -
nharper 2015/11/04 19:43:19 Done.
2228 }
2229 for (size_t i = 0; i < ssl_config_.token_binding_params.size(); ++i) {
2230 if (!CBB_add_u8(&parameters_list, ssl_config_.token_binding_params[i]))
2231 return 0;
davidben 2015/11/04 17:40:13 *out_alert_value = SSL_AD_INTERNAL_ERROR; return -
nharper 2015/11/04 19:43:19 Done.
2232 }
2233 // |*out| will be freed by TokenBindingFreeCallback.
2234 if (!CBB_finish(output.get(), const_cast<uint8_t**>(out), out_len))
2235 return 0;
davidben 2015/11/04 17:40:13 *out_alert_value = SSL_AD_INTERNAL_ERROR; return -
nharper 2015/11/04 19:43:18 Done.
2236
2237 retval = 1;
davidben 2015/11/04 17:40:13 return 1;
nharper 2015/11/04 19:43:19 Done. (This was from when I was using goto.)
2238
2239 if (retval == -1)
2240 *out_alert_value = SSL_AD_INTERNAL_ERROR;
2241 return retval;
2242 }
2243
2244 int SSLClientSocketOpenSSL::TokenBindingParse(const uint8_t* contents,
2245 size_t contents_len,
2246 int* out_alert_value) {
2247 if (completed_connect_) {
2248 // Token Binding may only be negotiated on the initial handshake.
2249 *out_alert_value = SSL_AD_ILLEGAL_PARAMETER;
2250 return 0;
2251 }
2252
2253 CBS extension;
2254 CBS_init(&extension, contents, contents_len);
2255
2256 CBS parameters_list;
2257 uint8_t version_major, version_minor, param;
2258 if (!CBS_get_u8(&extension, &version_major) ||
2259 !CBS_get_u8(&extension, &version_minor) ||
2260 !CBS_get_u8_length_prefixed(&extension, &parameters_list) ||
2261 !CBS_get_u8(&parameters_list, &param) || CBS_len(&parameters_list) > 0 ||
2262 CBS_len(&extension) > 0) {
2263 *out_alert_value = SSL_AD_DECODE_ERROR;
2264 return 0;
2265 }
2266 // The server-negotiated version must be less than or equal to our version.
2267 if (version_major > kTbProtocolVersionMajor ||
2268 (version_minor > kTbProtocolVersionMinor &&
2269 version_major == kTbProtocolVersionMajor)) {
2270 *out_alert_value = SSL_AD_ILLEGAL_PARAMETER;
2271 return 0;
2272 }
2273 // If the version the server negotiated is older than we support, don't fail
2274 // parsing the extension, but also don't set |negotiated_|.
2275 if (version_major < kTbMinProtocolVersionMajor ||
2276 (version_minor < kTbMinProtocolVersionMinor &&
2277 version_major == kTbMinProtocolVersionMajor)) {
2278 return 1;
2279 }
2280
2281 for (size_t i = 0; i < ssl_config_.token_binding_params.size(); ++i) {
2282 if (param == ssl_config_.token_binding_params[i]) {
2283 tb_negotiated_param_ = ssl_config_.token_binding_params[i];
2284 tb_was_negotiated_ = true;
2285 return 1;
2286 }
2287 }
2288
2289 *out_alert_value = SSL_AD_ILLEGAL_PARAMETER;
2290 return 0;
2291 }
2292
2293 // static
2294 int SSLClientSocketOpenSSL::TokenBindingAddCallback(
2295 SSL* ssl,
2296 unsigned int extension_value,
2297 const uint8_t** out,
2298 size_t* out_len,
2299 int* out_alert_value,
2300 void* add_arg) {
2301 DCHECK_EQ(extension_value, kTbExtNum);
2302 SSLClientSocketOpenSSL* socket =
2303 SSLClientSocketOpenSSL::SSLContext::GetInstance()->GetClientSocketFromSSL(
2304 ssl);
2305 return socket->TokenBindingAdd(out, out_len, out_alert_value);
2306 }
2307
2308 // static
2309 void SSLClientSocketOpenSSL::TokenBindingFreeCallback(SSL* ssl,
2310 unsigned extension_value,
2311 const uint8_t* out,
2312 void* add_arg) {
2313 DCHECK_EQ(extension_value, kTbExtNum);
2314 OPENSSL_free(const_cast<unsigned char*>(out));
2315 }
2316
2317 // static
2318 int SSLClientSocketOpenSSL::TokenBindingParseCallback(
2319 SSL* ssl,
2320 unsigned int extension_value,
2321 const uint8_t* contents,
2322 size_t contents_len,
2323 int* out_alert_value,
2324 void* parse_arg) {
2325 DCHECK_EQ(extension_value, kTbExtNum);
2326 SSLClientSocketOpenSSL* socket =
2327 SSLClientSocketOpenSSL::SSLContext::GetInstance()->GetClientSocketFromSSL(
2328 ssl);
2329 return socket->TokenBindingParse(contents, contents_len, out_alert_value);
2330 }
2331
2168 } // namespace net 2332 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698