• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/socket/ssl_client_socket.h"
6 
7 #include <string>
8 
9 #include "base/logging.h"
10 #include "base/observer_list.h"
11 #include "net/socket/ssl_client_socket_impl.h"
12 #include "net/socket/stream_socket.h"
13 #include "net/ssl/ssl_client_session_cache.h"
14 #include "net/ssl/ssl_key_logger.h"
15 
16 namespace net {
17 
18 SSLClientSocket::SSLClientSocket() = default;
19 
20 // static
SetSSLKeyLogger(std::unique_ptr<SSLKeyLogger> logger)21 void SSLClientSocket::SetSSLKeyLogger(std::unique_ptr<SSLKeyLogger> logger) {
22   SSLClientSocketImpl::SetSSLKeyLogger(std::move(logger));
23 }
24 
25 // static
SerializeNextProtos(const NextProtoVector & next_protos)26 std::vector<uint8_t> SSLClientSocket::SerializeNextProtos(
27     const NextProtoVector& next_protos) {
28   std::vector<uint8_t> wire_protos;
29   for (const NextProto next_proto : next_protos) {
30     const std::string proto = NextProtoToString(next_proto);
31     if (proto.size() > 255) {
32       LOG(WARNING) << "Ignoring overlong ALPN protocol: " << proto;
33       continue;
34     }
35     if (proto.size() == 0) {
36       LOG(WARNING) << "Ignoring empty ALPN protocol";
37       continue;
38     }
39     wire_protos.push_back(proto.size());
40     for (const char ch : proto) {
41       wire_protos.push_back(static_cast<uint8_t>(ch));
42     }
43   }
44 
45   return wire_protos;
46 }
47 
SSLClientContext(SSLConfigService * ssl_config_service,CertVerifier * cert_verifier,TransportSecurityState * transport_security_state,CTPolicyEnforcer * ct_policy_enforcer,SSLClientSessionCache * ssl_client_session_cache,SCTAuditingDelegate * sct_auditing_delegate)48 SSLClientContext::SSLClientContext(
49     SSLConfigService* ssl_config_service,
50     CertVerifier* cert_verifier,
51     TransportSecurityState* transport_security_state,
52     CTPolicyEnforcer* ct_policy_enforcer,
53     SSLClientSessionCache* ssl_client_session_cache,
54     SCTAuditingDelegate* sct_auditing_delegate)
55     : ssl_config_service_(ssl_config_service),
56       cert_verifier_(cert_verifier),
57       transport_security_state_(transport_security_state),
58       ct_policy_enforcer_(ct_policy_enforcer),
59       ssl_client_session_cache_(ssl_client_session_cache),
60       sct_auditing_delegate_(sct_auditing_delegate) {
61   CHECK(cert_verifier_);
62   CHECK(transport_security_state_);
63   CHECK(ct_policy_enforcer_);
64 
65   if (ssl_config_service_) {
66     config_ = ssl_config_service_->GetSSLContextConfig();
67     ssl_config_service_->AddObserver(this);
68   }
69   cert_verifier_->AddObserver(this);
70   CertDatabase::GetInstance()->AddObserver(this);
71 }
72 
~SSLClientContext()73 SSLClientContext::~SSLClientContext() {
74   if (ssl_config_service_) {
75     ssl_config_service_->RemoveObserver(this);
76   }
77   cert_verifier_->RemoveObserver(this);
78   CertDatabase::GetInstance()->RemoveObserver(this);
79 }
80 
CreateSSLClientSocket(std::unique_ptr<StreamSocket> stream_socket,const HostPortPair & host_and_port,const SSLConfig & ssl_config)81 std::unique_ptr<SSLClientSocket> SSLClientContext::CreateSSLClientSocket(
82     std::unique_ptr<StreamSocket> stream_socket,
83     const HostPortPair& host_and_port,
84     const SSLConfig& ssl_config) {
85   return std::make_unique<SSLClientSocketImpl>(this, std::move(stream_socket),
86                                                host_and_port, ssl_config);
87 }
88 
GetClientCertificate(const HostPortPair & server,scoped_refptr<X509Certificate> * client_cert,scoped_refptr<SSLPrivateKey> * private_key)89 bool SSLClientContext::GetClientCertificate(
90     const HostPortPair& server,
91     scoped_refptr<X509Certificate>* client_cert,
92     scoped_refptr<SSLPrivateKey>* private_key) {
93   return ssl_client_auth_cache_.Lookup(server, client_cert, private_key);
94 }
95 
SetClientCertificate(const HostPortPair & server,scoped_refptr<X509Certificate> client_cert,scoped_refptr<SSLPrivateKey> private_key)96 void SSLClientContext::SetClientCertificate(
97     const HostPortPair& server,
98     scoped_refptr<X509Certificate> client_cert,
99     scoped_refptr<SSLPrivateKey> private_key) {
100   ssl_client_auth_cache_.Add(server, std::move(client_cert),
101                              std::move(private_key));
102 
103   if (ssl_client_session_cache_) {
104     // Session resumption bypasses client certificate negotiation, so flush all
105     // associated sessions when preferences change.
106     ssl_client_session_cache_->FlushForServer(server);
107   }
108   NotifySSLConfigForServerChanged(server);
109 }
110 
ClearClientCertificate(const HostPortPair & server)111 bool SSLClientContext::ClearClientCertificate(const HostPortPair& server) {
112   if (!ssl_client_auth_cache_.Remove(server)) {
113     return false;
114   }
115 
116   if (ssl_client_session_cache_) {
117     // Session resumption bypasses client certificate negotiation, so flush all
118     // associated sessions when preferences change.
119     ssl_client_session_cache_->FlushForServer(server);
120   }
121   NotifySSLConfigForServerChanged(server);
122   return true;
123 }
124 
AddObserver(Observer * observer)125 void SSLClientContext::AddObserver(Observer* observer) {
126   observers_.AddObserver(observer);
127 }
128 
RemoveObserver(Observer * observer)129 void SSLClientContext::RemoveObserver(Observer* observer) {
130   observers_.RemoveObserver(observer);
131 }
132 
OnSSLContextConfigChanged()133 void SSLClientContext::OnSSLContextConfigChanged() {
134   // TODO(davidben): Should we flush |ssl_client_session_cache_| here? We flush
135   // the socket pools, but not the session cache. While BoringSSL-based servers
136   // never change version or cipher negotiation based on client-offered
137   // sessions, other servers do.
138   config_ = ssl_config_service_->GetSSLContextConfig();
139   NotifySSLConfigChanged(SSLConfigChangeType::kSSLConfigChanged);
140 }
141 
OnCertVerifierChanged()142 void SSLClientContext::OnCertVerifierChanged() {
143   NotifySSLConfigChanged(SSLConfigChangeType::kCertVerifierChanged);
144 }
145 
OnCertDBChanged()146 void SSLClientContext::OnCertDBChanged() {
147   // Both the trust store and client certificate store may have changed.
148   ssl_client_auth_cache_.Clear();
149   if (ssl_client_session_cache_) {
150     ssl_client_session_cache_->Flush();
151   }
152   NotifySSLConfigChanged(SSLConfigChangeType::kCertDatabaseChanged);
153 }
154 
NotifySSLConfigChanged(SSLConfigChangeType change_type)155 void SSLClientContext::NotifySSLConfigChanged(SSLConfigChangeType change_type) {
156   for (Observer& observer : observers_) {
157     observer.OnSSLConfigChanged(change_type);
158   }
159 }
160 
NotifySSLConfigForServerChanged(const HostPortPair & server)161 void SSLClientContext::NotifySSLConfigForServerChanged(
162     const HostPortPair& server) {
163   for (Observer& observer : observers_) {
164     observer.OnSSLConfigForServerChanged(server);
165   }
166 }
167 
168 }  // namespace net
169