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 3b29d415746d4c94c8bdb75f8186429d9f85487e..a5f1bbc4c563e5b5f3dc69242f49a42bceaa33dd 100644 |
--- a/net/socket/ssl_client_socket_impl.cc |
+++ b/net/socket/ssl_client_socket_impl.cc |
@@ -255,6 +255,43 @@ bssl::UniquePtr<CRYPTO_BUFFER> OSCertHandleToBuffer( |
} |
#endif |
+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. The client |
+ // certificate does not contain information needed to impersonate the user |
+ // (that's the private key which isn't sent over the wire), but it may contain |
+ // information on the user's identity. |
+ 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 { |
@@ -315,6 +352,8 @@ class SSLClientSocketImpl::SSLContext { |
// Deduplicate all certificates minted from the SSL_CTX in memory. |
SSL_CTX_set0_buffer_pool(ssl_ctx_.get(), x509_util::GetBufferPool()); |
+ SSL_CTX_set_msg_callback(ssl_ctx_.get(), MessageCallback); |
+ |
if (!SSL_CTX_add_client_custom_ext(ssl_ctx_.get(), kTbExtNum, |
&TokenBindingAddCallback, |
&TokenBindingFreeCallback, nullptr, |
@@ -405,6 +444,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_; |
@@ -1812,6 +1862,27 @@ 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, buf, len)); |
+ 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, buf, len)); |
+ break; |
+ default: |
+ return; |
+ } |
+} |
+ |
int SSLClientSocketImpl::TokenBindingAdd(const uint8_t** out, |
size_t* out_len, |
int* out_alert_value) { |