| OLD | NEW |
| 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 #include "net/http/http_response_info.h" | 5 #include "net/http/http_response_info.h" |
| 6 | 6 |
| 7 #include <openssl/ssl.h> |
| 8 |
| 7 #include "base/logging.h" | 9 #include "base/logging.h" |
| 8 #include "base/pickle.h" | 10 #include "base/pickle.h" |
| 9 #include "base/time/time.h" | 11 #include "base/time/time.h" |
| 10 #include "net/base/auth.h" | 12 #include "net/base/auth.h" |
| 11 #include "net/base/io_buffer.h" | 13 #include "net/base/io_buffer.h" |
| 12 #include "net/base/net_errors.h" | 14 #include "net/base/net_errors.h" |
| 13 #include "net/cert/sct_status_flags.h" | 15 #include "net/cert/sct_status_flags.h" |
| 14 #include "net/cert/signed_certificate_timestamp.h" | 16 #include "net/cert/signed_certificate_timestamp.h" |
| 15 #include "net/cert/x509_certificate.h" | 17 #include "net/cert/x509_certificate.h" |
| 16 #include "net/http/http_response_headers.h" | 18 #include "net/http/http_response_headers.h" |
| 17 #include "net/ssl/ssl_cert_request_info.h" | 19 #include "net/ssl/ssl_cert_request_info.h" |
| 20 #include "net/ssl/ssl_connection_status_flags.h" |
| 18 | 21 |
| 19 using base::Time; | 22 using base::Time; |
| 20 | 23 |
| 21 namespace net { | 24 namespace net { |
| 22 | 25 |
| 23 namespace { | 26 namespace { |
| 24 | 27 |
| 25 X509Certificate::PickleType GetPickleTypeForVersion(int version) { | 28 X509Certificate::PickleType GetPickleTypeForVersion(int version) { |
| 26 switch (version) { | 29 switch (version) { |
| 27 case 1: | 30 case 1: |
| 28 return X509Certificate::PICKLETYPE_SINGLE_CERTIFICATE; | 31 return X509Certificate::PICKLETYPE_SINGLE_CERTIFICATE; |
| 29 case 2: | 32 case 2: |
| 30 return X509Certificate::PICKLETYPE_CERTIFICATE_CHAIN_V2; | 33 return X509Certificate::PICKLETYPE_CERTIFICATE_CHAIN_V2; |
| 31 case 3: | 34 case 3: |
| 32 default: | 35 default: |
| 33 return X509Certificate::PICKLETYPE_CERTIFICATE_CHAIN_V3; | 36 return X509Certificate::PICKLETYPE_CERTIFICATE_CHAIN_V3; |
| 34 } | 37 } |
| 35 } | 38 } |
| 36 | 39 |
| 40 bool KeyExchangeGroupIsValid(int ssl_connection_status) { |
| 41 // TLS 1.3 and later always treat the field correctly. |
| 42 if (SSLConnectionStatusToVersion(ssl_connection_status) >= |
| 43 SSL_CONNECTION_VERSION_TLS1_3) { |
| 44 return true; |
| 45 } |
| 46 |
| 47 // Prior to TLS 1.3, only ECDHE ciphers have groups. |
| 48 const SSL_CIPHER* cipher = SSL_get_cipher_by_value( |
| 49 SSLConnectionStatusToCipherSuite(ssl_connection_status)); |
| 50 return cipher && SSL_CIPHER_is_ECDHE(cipher); |
| 51 } |
| 52 |
| 37 } // namespace | 53 } // namespace |
| 38 | 54 |
| 39 // These values can be bit-wise combined to form the flags field of the | 55 // These values can be bit-wise combined to form the flags field of the |
| 40 // serialized HttpResponseInfo. | 56 // serialized HttpResponseInfo. |
| 41 enum { | 57 enum { |
| 42 // The version of the response info used when persisting response info. | 58 // The version of the response info used when persisting response info. |
| 43 RESPONSE_INFO_VERSION = 3, | 59 RESPONSE_INFO_VERSION = 3, |
| 44 | 60 |
| 45 // The minimum version supported for deserializing response info. | 61 // The minimum version supported for deserializing response info. |
| 46 RESPONSE_INFO_MINIMUM_VERSION = 1, | 62 RESPONSE_INFO_MINIMUM_VERSION = 1, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 RESPONSE_INFO_HAS_CONNECTION_INFO = 1 << 18, | 103 RESPONSE_INFO_HAS_CONNECTION_INFO = 1 << 18, |
| 88 | 104 |
| 89 // This bit is set if the request has http authentication. | 105 // This bit is set if the request has http authentication. |
| 90 RESPONSE_INFO_USE_HTTP_AUTHENTICATION = 1 << 19, | 106 RESPONSE_INFO_USE_HTTP_AUTHENTICATION = 1 << 19, |
| 91 | 107 |
| 92 // This bit is set if ssl_info has SCTs. | 108 // This bit is set if ssl_info has SCTs. |
| 93 RESPONSE_INFO_HAS_SIGNED_CERTIFICATE_TIMESTAMPS = 1 << 20, | 109 RESPONSE_INFO_HAS_SIGNED_CERTIFICATE_TIMESTAMPS = 1 << 20, |
| 94 | 110 |
| 95 RESPONSE_INFO_UNUSED_SINCE_PREFETCH = 1 << 21, | 111 RESPONSE_INFO_UNUSED_SINCE_PREFETCH = 1 << 21, |
| 96 | 112 |
| 97 // This bit is set if the response has a key-exchange-info field at the end. | 113 // This bit is set if the response has a key exchange group. |
| 98 RESPONSE_INFO_HAS_KEY_EXCHANGE_INFO = 1 << 22, | 114 RESPONSE_INFO_HAS_KEY_EXCHANGE_GROUP = 1 << 22, |
| 99 | 115 |
| 100 // This bit is set if ssl_info recorded that PKP was bypassed due to a local | 116 // This bit is set if ssl_info recorded that PKP was bypassed due to a local |
| 101 // trust anchor. | 117 // trust anchor. |
| 102 RESPONSE_INFO_PKP_BYPASSED = 1 << 23, | 118 RESPONSE_INFO_PKP_BYPASSED = 1 << 23, |
| 103 | 119 |
| 104 // TODO(darin): Add other bits to indicate alternate request methods. | 120 // TODO(darin): Add other bits to indicate alternate request methods. |
| 105 // For now, we don't support storing those. | 121 // For now, we don't support storing those. |
| 106 }; | 122 }; |
| 107 | 123 |
| 108 HttpResponseInfo::HttpResponseInfo() | 124 HttpResponseInfo::HttpResponseInfo() |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 int value; | 295 int value; |
| 280 if (!iter.ReadInt(&value)) | 296 if (!iter.ReadInt(&value)) |
| 281 return false; | 297 return false; |
| 282 | 298 |
| 283 if (value > static_cast<int>(CONNECTION_INFO_UNKNOWN) && | 299 if (value > static_cast<int>(CONNECTION_INFO_UNKNOWN) && |
| 284 value < static_cast<int>(NUM_OF_CONNECTION_INFOS)) { | 300 value < static_cast<int>(NUM_OF_CONNECTION_INFOS)) { |
| 285 connection_info = static_cast<ConnectionInfo>(value); | 301 connection_info = static_cast<ConnectionInfo>(value); |
| 286 } | 302 } |
| 287 } | 303 } |
| 288 | 304 |
| 289 // Read key_exchange_info | 305 // Read key_exchange_group |
| 290 if (flags & RESPONSE_INFO_HAS_KEY_EXCHANGE_INFO) { | 306 if (flags & RESPONSE_INFO_HAS_KEY_EXCHANGE_GROUP) { |
| 291 int key_exchange_info; | 307 int key_exchange_group; |
| 292 if (!iter.ReadInt(&key_exchange_info)) | 308 if (!iter.ReadInt(&key_exchange_group)) |
| 293 return false; | 309 return false; |
| 294 ssl_info.key_exchange_info = key_exchange_info; | 310 |
| 311 // Historically, the key_exchange_group field was key_exchange_info which |
| 312 // conflated a number of different values based on the cipher suite, so some |
| 313 // values must be discarded. See https://crbug.com/639421. |
| 314 if (KeyExchangeGroupIsValid(ssl_info.connection_status)) |
| 315 ssl_info.key_exchange_group = key_exchange_group; |
| 295 } | 316 } |
| 296 | 317 |
| 297 was_fetched_via_spdy = (flags & RESPONSE_INFO_WAS_SPDY) != 0; | 318 was_fetched_via_spdy = (flags & RESPONSE_INFO_WAS_SPDY) != 0; |
| 298 | 319 |
| 299 was_npn_negotiated = (flags & RESPONSE_INFO_WAS_NPN) != 0; | 320 was_npn_negotiated = (flags & RESPONSE_INFO_WAS_NPN) != 0; |
| 300 | 321 |
| 301 was_fetched_via_proxy = (flags & RESPONSE_INFO_WAS_PROXY) != 0; | 322 was_fetched_via_proxy = (flags & RESPONSE_INFO_WAS_PROXY) != 0; |
| 302 | 323 |
| 303 *response_truncated = (flags & RESPONSE_INFO_TRUNCATED) != 0; | 324 *response_truncated = (flags & RESPONSE_INFO_TRUNCATED) != 0; |
| 304 | 325 |
| 305 did_use_http_auth = (flags & RESPONSE_INFO_USE_HTTP_AUTHENTICATION) != 0; | 326 did_use_http_auth = (flags & RESPONSE_INFO_USE_HTTP_AUTHENTICATION) != 0; |
| 306 | 327 |
| 307 unused_since_prefetch = (flags & RESPONSE_INFO_UNUSED_SINCE_PREFETCH) != 0; | 328 unused_since_prefetch = (flags & RESPONSE_INFO_UNUSED_SINCE_PREFETCH) != 0; |
| 308 | 329 |
| 309 ssl_info.pkp_bypassed = (flags & RESPONSE_INFO_PKP_BYPASSED) != 0; | 330 ssl_info.pkp_bypassed = (flags & RESPONSE_INFO_PKP_BYPASSED) != 0; |
| 310 | 331 |
| 311 return true; | 332 return true; |
| 312 } | 333 } |
| 313 | 334 |
| 314 void HttpResponseInfo::Persist(base::Pickle* pickle, | 335 void HttpResponseInfo::Persist(base::Pickle* pickle, |
| 315 bool skip_transient_headers, | 336 bool skip_transient_headers, |
| 316 bool response_truncated) const { | 337 bool response_truncated) const { |
| 317 int flags = RESPONSE_INFO_VERSION; | 338 int flags = RESPONSE_INFO_VERSION; |
| 318 if (ssl_info.is_valid()) { | 339 if (ssl_info.is_valid()) { |
| 319 flags |= RESPONSE_INFO_HAS_CERT; | 340 flags |= RESPONSE_INFO_HAS_CERT; |
| 320 flags |= RESPONSE_INFO_HAS_CERT_STATUS; | 341 flags |= RESPONSE_INFO_HAS_CERT_STATUS; |
| 321 if (ssl_info.security_bits != -1) | 342 if (ssl_info.security_bits != -1) |
| 322 flags |= RESPONSE_INFO_HAS_SECURITY_BITS; | 343 flags |= RESPONSE_INFO_HAS_SECURITY_BITS; |
| 323 if (ssl_info.key_exchange_info != 0) | 344 if (ssl_info.key_exchange_group != 0) |
| 324 flags |= RESPONSE_INFO_HAS_KEY_EXCHANGE_INFO; | 345 flags |= RESPONSE_INFO_HAS_KEY_EXCHANGE_GROUP; |
| 325 if (ssl_info.connection_status != 0) | 346 if (ssl_info.connection_status != 0) |
| 326 flags |= RESPONSE_INFO_HAS_SSL_CONNECTION_STATUS; | 347 flags |= RESPONSE_INFO_HAS_SSL_CONNECTION_STATUS; |
| 327 } | 348 } |
| 328 if (vary_data.is_valid()) | 349 if (vary_data.is_valid()) |
| 329 flags |= RESPONSE_INFO_HAS_VARY_DATA; | 350 flags |= RESPONSE_INFO_HAS_VARY_DATA; |
| 330 if (response_truncated) | 351 if (response_truncated) |
| 331 flags |= RESPONSE_INFO_TRUNCATED; | 352 flags |= RESPONSE_INFO_TRUNCATED; |
| 332 if (was_fetched_via_spdy) | 353 if (was_fetched_via_spdy) |
| 333 flags |= RESPONSE_INFO_WAS_SPDY; | 354 flags |= RESPONSE_INFO_WAS_SPDY; |
| 334 if (was_npn_negotiated) { | 355 if (was_npn_negotiated) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 | 410 |
| 390 pickle->WriteString(socket_address.host()); | 411 pickle->WriteString(socket_address.host()); |
| 391 pickle->WriteUInt16(socket_address.port()); | 412 pickle->WriteUInt16(socket_address.port()); |
| 392 | 413 |
| 393 if (was_npn_negotiated) | 414 if (was_npn_negotiated) |
| 394 pickle->WriteString(npn_negotiated_protocol); | 415 pickle->WriteString(npn_negotiated_protocol); |
| 395 | 416 |
| 396 if (connection_info != CONNECTION_INFO_UNKNOWN) | 417 if (connection_info != CONNECTION_INFO_UNKNOWN) |
| 397 pickle->WriteInt(static_cast<int>(connection_info)); | 418 pickle->WriteInt(static_cast<int>(connection_info)); |
| 398 | 419 |
| 399 if (ssl_info.is_valid() && ssl_info.key_exchange_info != 0) | 420 if (ssl_info.is_valid() && ssl_info.key_exchange_group != 0) |
| 400 pickle->WriteInt(ssl_info.key_exchange_info); | 421 pickle->WriteInt(ssl_info.key_exchange_group); |
| 401 } | 422 } |
| 402 | 423 |
| 403 HttpResponseInfo::ConnectionInfo HttpResponseInfo::ConnectionInfoFromNextProto( | 424 HttpResponseInfo::ConnectionInfo HttpResponseInfo::ConnectionInfoFromNextProto( |
| 404 NextProto next_proto) { | 425 NextProto next_proto) { |
| 405 switch (next_proto) { | 426 switch (next_proto) { |
| 406 case kProtoHTTP2: | 427 case kProtoHTTP2: |
| 407 return CONNECTION_INFO_HTTP2; | 428 return CONNECTION_INFO_HTTP2; |
| 408 case kProtoQUIC1SPDY3: | 429 case kProtoQUIC1SPDY3: |
| 409 return CONNECTION_INFO_QUIC1_SPDY3; | 430 return CONNECTION_INFO_QUIC1_SPDY3; |
| 410 | 431 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 case CONNECTION_INFO_HTTP1_0: | 466 case CONNECTION_INFO_HTTP1_0: |
| 446 return "http/1.0"; | 467 return "http/1.0"; |
| 447 case NUM_OF_CONNECTION_INFOS: | 468 case NUM_OF_CONNECTION_INFOS: |
| 448 break; | 469 break; |
| 449 } | 470 } |
| 450 NOTREACHED(); | 471 NOTREACHED(); |
| 451 return ""; | 472 return ""; |
| 452 } | 473 } |
| 453 | 474 |
| 454 } // namespace net | 475 } // namespace net |
| OLD | NEW |