Chromium Code Reviews| Index: net/socket/ssl_client_socket_impl.cc |
| diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc |
| index 77f305914444c20fedfbec5ff2c108c0114e18f5..648d45956106f0ef05d38696a6f4a66de3170be2 100644 |
| --- a/net/socket/ssl_client_socket_impl.cc |
| +++ b/net/socket/ssl_client_socket_impl.cc |
| @@ -236,6 +236,40 @@ bool AreLegacyECDSACiphersEnabled() { |
| const base::Feature kShortRecordHeaderFeature{ |
| "SSLShortRecordHeader", base::FEATURE_DISABLED_BY_DEFAULT}; |
| +std::unique_ptr<base::Value> NetLogSSLAlertCallback( |
| + const void* bytes, |
| + size_t len, |
| + NetLogCaptureMode capture_mode) { |
| + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
| + dict->SetString("hex_encoded_bytes", base::HexEncode(bytes, len)); |
| + return std::move(dict); |
| +} |
| + |
| +std::unique_ptr<base::Value> NetLogSSLMessageCallback( |
| + bool is_write, |
| + const void* bytes, |
| + size_t len, |
| + NetLogCaptureMode capture_mode) { |
| + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
| + if (len == 0) { |
| + NOTREACHED(); |
| + return std::move(dict); |
| + } |
| + |
| + // The handshake message type is the first byte. Include it so elided messages |
| + // still report their type. |
| + uint8_t type = reinterpret_cast<const uint8_t*>(bytes)[0]; |
| + dict->SetInteger("type", type); |
| + |
| + // Elide client certificate messages unless logging socket bytes. |
| + if (!is_write || type != SSL3_MT_CERTIFICATE || |
| + capture_mode.include_socket_bytes()) { |
| + dict->SetString("hex_encoded_bytes", base::HexEncode(bytes, len)); |
| + } |
| + |
| + return std::move(dict); |
| +} |
| + |
| } // namespace |
| class SSLClientSocketImpl::SSLContext { |
| @@ -299,6 +333,8 @@ class SSLClientSocketImpl::SSLContext { |
| SSL_CTX_set_short_header_enabled(ssl_ctx_.get(), 1); |
| } |
| + SSL_CTX_set_msg_callback(ssl_ctx_.get(), MessageCallback); |
| + |
| if (!SSL_CTX_add_client_custom_ext(ssl_ctx_.get(), kTbExtNum, |
| &TokenBindingAddCallback, |
| &TokenBindingFreeCallback, nullptr, |
| @@ -398,6 +434,17 @@ class SSLClientSocketImpl::SSLContext { |
| } |
| #endif |
| + static void MessageCallback(int is_write, |
| + int version, |
| + int content_type, |
| + const void* buf, |
| + size_t len, |
| + SSL* ssl, |
| + void* arg) { |
| + SSLClientSocketImpl* socket = GetInstance()->GetClientSocketFromSSL(ssl); |
| + return socket->MessageCallback(is_write, content_type, buf, len); |
| + } |
| + |
| // This is the index used with SSL_get_ex_data to retrieve the owner |
| // SSLClientSocketImpl object from an SSL instance. |
| int ssl_socket_data_index_; |
| @@ -1901,6 +1948,29 @@ void SSLClientSocketImpl::OnPrivateKeyComplete( |
| RetryAllOperations(); |
| } |
| +void SSLClientSocketImpl::MessageCallback(int is_write, |
| + int content_type, |
| + const void* buf, |
| + size_t len) { |
| + switch (content_type) { |
| + case SSL3_RT_ALERT: |
| + net_log_.AddEvent( |
| + is_write ? NetLogEventType::SSL_ALERT_SENT |
| + : NetLogEventType::SSL_ALERT_RECEIVED, |
| + base::Bind(&NetLogSSLAlertCallback, base::Unretained(buf), len)); |
|
eroman
2017/02/17 22:16:51
Is Unretained() needed here, or is it just for doc
davidben
2017/04/18 20:51:17
Oh, I didn't realize they weren't needed. Removed.
|
| + break; |
| + case SSL3_RT_HANDSHAKE: |
| + net_log_.AddEvent(is_write |
| + ? NetLogEventType::SSL_HANDSHAKE_MESSAGE_SENT |
| + : NetLogEventType::SSL_HANDSHAKE_MESSAGE_RECEIVED, |
| + base::Bind(&NetLogSSLMessageCallback, !!is_write, |
| + base::Unretained(buf), len)); |
| + break; |
| + default: |
| + return; |
| + } |
| +} |
| + |
| int SSLClientSocketImpl::TokenBindingAdd(const uint8_t** out, |
| size_t* out_len, |
| int* out_alert_value) { |