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