OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "extensions/browser/api/cast_channel/cast_socket.h" | 5 #include "extensions/browser/api/cast_channel/cast_socket.h" |
6 | 6 |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 #include <string.h> | 8 #include <string.h> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/callback_helpers.h" | 11 #include "base/callback_helpers.h" |
12 #include "base/format_macros.h" | 12 #include "base/format_macros.h" |
13 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
14 #include "base/numerics/safe_conversions.h" | 14 #include "base/numerics/safe_conversions.h" |
15 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" |
16 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
17 #include "base/sys_byteorder.h" | 17 #include "base/sys_byteorder.h" |
| 18 #include "base/time/time.h" |
18 #include "extensions/browser/api/cast_channel/cast_auth_util.h" | 19 #include "extensions/browser/api/cast_channel/cast_auth_util.h" |
19 #include "extensions/browser/api/cast_channel/cast_framer.h" | 20 #include "extensions/browser/api/cast_channel/cast_framer.h" |
20 #include "extensions/browser/api/cast_channel/cast_message_util.h" | 21 #include "extensions/browser/api/cast_channel/cast_message_util.h" |
21 #include "extensions/browser/api/cast_channel/cast_transport.h" | 22 #include "extensions/browser/api/cast_channel/cast_transport.h" |
22 #include "extensions/browser/api/cast_channel/logger.h" | 23 #include "extensions/browser/api/cast_channel/logger.h" |
23 #include "extensions/browser/api/cast_channel/logger_util.h" | 24 #include "extensions/browser/api/cast_channel/logger_util.h" |
24 #include "extensions/common/api/cast_channel/cast_channel.pb.h" | 25 #include "extensions/common/api/cast_channel/cast_channel.pb.h" |
25 #include "net/base/address_list.h" | 26 #include "net/base/address_list.h" |
26 #include "net/base/host_port_pair.h" | 27 #include "net/base/host_port_pair.h" |
27 #include "net/base/net_errors.h" | 28 #include "net/base/net_errors.h" |
(...skipping 14 matching lines...) Expand all Loading... |
42 #define VLOG_WITH_CONNECTION(level) VLOG(level) << "[" << \ | 43 #define VLOG_WITH_CONNECTION(level) VLOG(level) << "[" << \ |
43 ip_endpoint_.ToString() << ", auth=" << channel_auth_ << "] " | 44 ip_endpoint_.ToString() << ", auth=" << channel_auth_ << "] " |
44 | 45 |
45 namespace { | 46 namespace { |
46 | 47 |
47 // The default keepalive delay. On Linux, keepalives probes will be sent after | 48 // The default keepalive delay. On Linux, keepalives probes will be sent after |
48 // the socket is idle for this length of time, and the socket will be closed | 49 // the socket is idle for this length of time, and the socket will be closed |
49 // after 9 failed probes. So the total idle time before close is 10 * | 50 // after 9 failed probes. So the total idle time before close is 10 * |
50 // kTcpKeepAliveDelaySecs. | 51 // kTcpKeepAliveDelaySecs. |
51 const int kTcpKeepAliveDelaySecs = 10; | 52 const int kTcpKeepAliveDelaySecs = 10; |
| 53 |
| 54 const int kMaxSelfSignedCertLifetimeInDays = 2; |
| 55 |
| 56 std::string FormatTimeForLogging(base::Time time) { |
| 57 base::Time::Exploded exploded; |
| 58 time.UTCExplode(&exploded); |
| 59 return base::StringPrintf( |
| 60 "%04d-%02d-%02d %02d:%02d:%02d.%03d UTC", exploded.year, exploded.month, |
| 61 exploded.day_of_month, exploded.hour, exploded.minute, exploded.second, |
| 62 exploded.millisecond); |
| 63 } |
| 64 |
52 } // namespace | 65 } // namespace |
53 | 66 |
54 namespace extensions { | 67 namespace extensions { |
55 static base::LazyInstance<BrowserContextKeyedAPIFactory< | 68 static base::LazyInstance<BrowserContextKeyedAPIFactory< |
56 ApiResourceManager<core_api::cast_channel::CastSocket> > > g_factory = | 69 ApiResourceManager<core_api::cast_channel::CastSocket> > > g_factory = |
57 LAZY_INSTANCE_INITIALIZER; | 70 LAZY_INSTANCE_INITIALIZER; |
58 | 71 |
59 // static | 72 // static |
60 template <> | 73 template <> |
61 BrowserContextKeyedAPIFactory< | 74 BrowserContextKeyedAPIFactory< |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 bool CastSocketImpl::ExtractPeerCert(std::string* cert) { | 183 bool CastSocketImpl::ExtractPeerCert(std::string* cert) { |
171 DCHECK(cert); | 184 DCHECK(cert); |
172 DCHECK(peer_cert_.empty()); | 185 DCHECK(peer_cert_.empty()); |
173 net::SSLInfo ssl_info; | 186 net::SSLInfo ssl_info; |
174 if (!socket_->GetSSLInfo(&ssl_info) || !ssl_info.cert.get()) { | 187 if (!socket_->GetSSLInfo(&ssl_info) || !ssl_info.cert.get()) { |
175 return false; | 188 return false; |
176 } | 189 } |
177 | 190 |
178 logger_->LogSocketEvent(channel_id_, proto::SSL_INFO_OBTAINED); | 191 logger_->LogSocketEvent(channel_id_, proto::SSL_INFO_OBTAINED); |
179 | 192 |
| 193 // Ensure that the peer cert (which is self-signed) doesn't have an excessive |
| 194 // life-time (i.e. no more than 2 days). |
| 195 base::Time expiry = ssl_info.cert->valid_expiry(); |
| 196 base::Time lifetimeLimit = |
| 197 base::Time::Now() + |
| 198 base::TimeDelta::FromDays(kMaxSelfSignedCertLifetimeInDays); |
| 199 if (expiry.is_null() || expiry > lifetimeLimit) { |
| 200 std::string details = FormatTimeForLogging(expiry); |
| 201 details += " " + ip_endpoint().ToString(); |
| 202 LOG(ERROR) << "Peer cert has excessive lifetime. details=" << details; |
| 203 logger_->LogSocketEventWithDetails( |
| 204 channel_id_, proto::SSL_CERT_EXCESSIVE_LIFETIME, details); |
| 205 return false; |
| 206 } |
| 207 |
180 bool result = net::X509Certificate::GetDEREncoded( | 208 bool result = net::X509Certificate::GetDEREncoded( |
181 ssl_info.cert->os_cert_handle(), cert); | 209 ssl_info.cert->os_cert_handle(), cert); |
182 if (result) { | 210 if (result) { |
183 VLOG_WITH_CONNECTION(1) << "Successfully extracted peer certificate: " | 211 VLOG_WITH_CONNECTION(1) << "Successfully extracted peer certificate"; |
184 << *cert; | |
185 } | 212 } |
186 | 213 |
187 logger_->LogSocketEventWithRv( | 214 logger_->LogSocketEventWithRv( |
188 channel_id_, proto::DER_ENCODED_CERT_OBTAIN, result ? 1 : 0); | 215 channel_id_, proto::DER_ENCODED_CERT_OBTAIN, result ? 1 : 0); |
189 return result; | 216 return result; |
190 } | 217 } |
191 | 218 |
192 bool CastSocketImpl::VerifyChallengeReply() { | 219 bool CastSocketImpl::VerifyChallengeReply() { |
193 AuthResult result = AuthenticateChallengeReply(*challenge_reply_, peer_cert_); | 220 AuthResult result = AuthenticateChallengeReply(*challenge_reply_, peer_cert_); |
194 if (result.success()) { | 221 if (result.success()) { |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 void CastSocketImpl::SetErrorState(ChannelError error_state) { | 558 void CastSocketImpl::SetErrorState(ChannelError error_state) { |
532 VLOG_WITH_CONNECTION(1) << "SetErrorState " << error_state; | 559 VLOG_WITH_CONNECTION(1) << "SetErrorState " << error_state; |
533 DCHECK_EQ(CHANNEL_ERROR_NONE, error_state_); | 560 DCHECK_EQ(CHANNEL_ERROR_NONE, error_state_); |
534 error_state_ = error_state; | 561 error_state_ = error_state; |
535 logger_->LogSocketErrorState(channel_id_, ErrorStateToProto(error_state_)); | 562 logger_->LogSocketErrorState(channel_id_, ErrorStateToProto(error_state_)); |
536 } | 563 } |
537 } // namespace cast_channel | 564 } // namespace cast_channel |
538 } // namespace core_api | 565 } // namespace core_api |
539 } // namespace extensions | 566 } // namespace extensions |
540 #undef VLOG_WITH_CONNECTION | 567 #undef VLOG_WITH_CONNECTION |
OLD | NEW |