OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 #ifndef NET_SOCKET_SSL_CLIENT_SOCKET_NSS_H_ | 5 #ifndef NET_SOCKET_SSL_CLIENT_SOCKET_NSS_H_ |
6 #define NET_SOCKET_SSL_CLIENT_SOCKET_NSS_H_ | 6 #define NET_SOCKET_SSL_CLIENT_SOCKET_NSS_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <certt.h> | 9 #include <certt.h> |
10 #include <keyt.h> | 10 #include <keyt.h> |
(...skipping 12 matching lines...) Expand all Loading... | |
23 #include "net/base/completion_callback.h" | 23 #include "net/base/completion_callback.h" |
24 #include "net/base/host_port_pair.h" | 24 #include "net/base/host_port_pair.h" |
25 #include "net/base/net_export.h" | 25 #include "net/base/net_export.h" |
26 #include "net/base/net_log.h" | 26 #include "net/base/net_log.h" |
27 #include "net/base/nss_memio.h" | 27 #include "net/base/nss_memio.h" |
28 #include "net/base/server_bound_cert_service.h" | 28 #include "net/base/server_bound_cert_service.h" |
29 #include "net/base/ssl_config_service.h" | 29 #include "net/base/ssl_config_service.h" |
30 #include "net/base/x509_certificate.h" | 30 #include "net/base/x509_certificate.h" |
31 #include "net/socket/ssl_client_socket.h" | 31 #include "net/socket/ssl_client_socket.h" |
32 | 32 |
33 namespace base { | |
34 class SingleThreadTaskRunner; | |
35 } | |
36 | |
33 namespace net { | 37 namespace net { |
34 | 38 |
35 class BoundNetLog; | 39 class BoundNetLog; |
36 class CertVerifier; | 40 class CertVerifier; |
37 class ClientSocketHandle; | 41 class ClientSocketHandle; |
38 class ServerBoundCertService; | 42 class ServerBoundCertService; |
39 class SingleRequestCertVerifier; | 43 class SingleRequestCertVerifier; |
40 class SSLHostInfo; | 44 class SSLHostInfo; |
41 class TransportSecurityState; | 45 class TransportSecurityState; |
42 class X509Certificate; | 46 class X509Certificate; |
43 | 47 |
44 // An SSL client socket implemented with Mozilla NSS. | 48 // An SSL client socket implemented with Mozilla NSS. |
45 class SSLClientSocketNSS : public SSLClientSocket { | 49 class SSLClientSocketNSS : public SSLClientSocket { |
46 public: | 50 public: |
47 // Takes ownership of the |transport_socket|, which must already be connected. | 51 // Takes ownership of the |transport_socket|, which must already be connected. |
48 // The hostname specified in |host_and_port| will be compared with the name(s) | 52 // The hostname specified in |host_and_port| will be compared with the name(s) |
49 // in the server's certificate during the SSL handshake. If SSL client | 53 // in the server's certificate during the SSL handshake. If SSL client |
50 // authentication is requested, the host_and_port field of SSLCertRequestInfo | 54 // authentication is requested, the host_and_port field of SSLCertRequestInfo |
51 // will be populated with |host_and_port|. |ssl_config| specifies | 55 // will be populated with |host_and_port|. |ssl_config| specifies |
52 // the SSL settings. | 56 // the SSL settings. |
53 SSLClientSocketNSS(ClientSocketHandle* transport_socket, | 57 // |
58 // Because calls to NSS may block, such as due to needing to access slow | |
59 // hardware or needing to synchronously unlock protected tokens, calls to | |
60 // NSS may optionally be run on a dedicated thread. If synchronous/blocking | |
61 // behaviour is desired, for performance or compatibility, the current task | |
willchan no longer on Chromium
2012/06/04 16:50:38
behavior
| |
62 // runner should be supplied instead. | |
63 SSLClientSocketNSS(base::SingleThreadTaskRunner* nss_task_runner, | |
64 ClientSocketHandle* transport_socket, | |
54 const HostPortPair& host_and_port, | 65 const HostPortPair& host_and_port, |
55 const SSLConfig& ssl_config, | 66 const SSLConfig& ssl_config, |
56 SSLHostInfo* ssl_host_info, | 67 SSLHostInfo* ssl_host_info, |
57 const SSLClientSocketContext& context); | 68 const SSLClientSocketContext& context); |
58 virtual ~SSLClientSocketNSS(); | 69 virtual ~SSLClientSocketNSS(); |
59 | 70 |
60 // SSLClientSocket implementation. | 71 // SSLClientSocket implementation. |
61 virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE; | 72 virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE; |
62 virtual void GetSSLCertRequestInfo( | 73 virtual void GetSSLCertRequestInfo( |
63 SSLCertRequestInfo* cert_request_info) OVERRIDE; | 74 SSLCertRequestInfo* cert_request_info) OVERRIDE; |
(...skipping 25 matching lines...) Expand all Loading... | |
89 int buf_len, | 100 int buf_len, |
90 const CompletionCallback& callback) OVERRIDE; | 101 const CompletionCallback& callback) OVERRIDE; |
91 virtual int Write(IOBuffer* buf, | 102 virtual int Write(IOBuffer* buf, |
92 int buf_len, | 103 int buf_len, |
93 const CompletionCallback& callback) OVERRIDE; | 104 const CompletionCallback& callback) OVERRIDE; |
94 virtual bool SetReceiveBufferSize(int32 size) OVERRIDE; | 105 virtual bool SetReceiveBufferSize(int32 size) OVERRIDE; |
95 virtual bool SetSendBufferSize(int32 size) OVERRIDE; | 106 virtual bool SetSendBufferSize(int32 size) OVERRIDE; |
96 virtual ServerBoundCertService* GetServerBoundCertService() const OVERRIDE; | 107 virtual ServerBoundCertService* GetServerBoundCertService() const OVERRIDE; |
97 | 108 |
98 private: | 109 private: |
110 // Helper class to handle marshalling any NSS interaction to and from the | |
111 // NSS and network task runners. Not every call needs to happen on the Core | |
112 class Core; | |
113 | |
99 enum State { | 114 enum State { |
100 STATE_NONE, | 115 STATE_NONE, |
101 STATE_LOAD_SSL_HOST_INFO, | 116 STATE_LOAD_SSL_HOST_INFO, |
102 STATE_HANDSHAKE, | 117 STATE_HANDSHAKE, |
103 STATE_GET_DOMAIN_BOUND_CERT_COMPLETE, | 118 STATE_HANDSHAKE_COMPLETE, |
104 STATE_VERIFY_DNSSEC, | 119 STATE_VERIFY_DNSSEC, |
105 STATE_VERIFY_CERT, | 120 STATE_VERIFY_CERT, |
106 STATE_VERIFY_CERT_COMPLETE, | 121 STATE_VERIFY_CERT_COMPLETE, |
107 }; | 122 }; |
108 | 123 |
109 int Init(); | 124 int Init(); |
125 void InitCore(); | |
110 | 126 |
111 // Initializes NSS SSL options. Returns a net error code. | 127 // Initializes NSS SSL options. Returns a net error code. |
112 int InitializeSSLOptions(); | 128 int InitializeSSLOptions(); |
113 | 129 |
114 // Initializes the socket peer name in SSL. Returns a net error code. | 130 // Initializes the socket peer name in SSL. Returns a net error code. |
115 int InitializeSSLPeerName(); | 131 int InitializeSSLPeerName(); |
116 | 132 |
117 void UpdateServerCert(); | |
118 void UpdateConnectionStatus(); | |
119 void DoReadCallback(int result); | |
120 void DoWriteCallback(int result); | |
121 void DoConnectCallback(int result); | 133 void DoConnectCallback(int result); |
122 void OnHandshakeIOComplete(int result); | 134 void OnHandshakeIOComplete(int result); |
123 void OnSendComplete(int result); | 135 |
124 void OnRecvComplete(int result); | 136 void LoadSSLHostInfo(); |
137 int DoLoadSSLHostInfo(); | |
125 | 138 |
126 int DoHandshakeLoop(int last_io_result); | 139 int DoHandshakeLoop(int last_io_result); |
127 int DoReadLoop(int result); | |
128 int DoWriteLoop(int result); | |
129 | |
130 bool LoadSSLHostInfo(); | |
131 int DoLoadSSLHostInfo(); | |
132 | |
133 int DoHandshake(); | 140 int DoHandshake(); |
134 | 141 int DoHandshakeComplete(int result); |
135 // ImportDBCertAndKey is a helper function for turning a DER-encoded cert and | |
136 // key into a CERTCertificate and SECKEYPrivateKey. Returns OK upon success | |
137 // and an error code otherwise. | |
138 // Requires |domain_bound_private_key_| and |domain_bound_cert_| to have been | |
139 // set by a call to ServerBoundCertService->GetDomainBoundCert. The caller | |
140 // takes ownership of the |*cert| and |*key|. | |
141 int ImportDBCertAndKey(CERTCertificate** cert, SECKEYPrivateKey** key); | |
142 int DoGetDBCertComplete(int result); | |
143 int DoVerifyDNSSEC(int result); | 142 int DoVerifyDNSSEC(int result); |
144 int DoVerifyCert(int result); | 143 int DoVerifyCert(int result); |
145 int DoVerifyCertComplete(int result); | 144 int DoVerifyCertComplete(int result); |
146 int DoPayloadRead(); | |
147 int DoPayloadWrite(); | |
148 void LogConnectionTypeMetrics() const; | |
149 void SaveSSLHostInfo(); | 145 void SaveSSLHostInfo(); |
150 | 146 |
151 bool DoTransportIO(); | 147 void LogConnectionTypeMetrics() const; |
152 int BufferSend(); | |
153 void BufferSendComplete(int result); | |
154 int BufferRecv(); | |
155 void BufferRecvComplete(int result); | |
156 | |
157 // Handles an NSS error generated while handshaking or performing IO. | |
158 // Returns a network error code mapped from the original NSS error. | |
159 int HandleNSSError(PRErrorCode error, bool handshake_error); | |
160 | |
161 // NSS calls this when checking certificates. We pass 'this' as the first | |
162 // argument. | |
163 static SECStatus OwnAuthCertHandler(void* arg, PRFileDesc* socket, | |
164 PRBool checksig, PRBool is_server); | |
165 // Returns true if connection negotiated the domain bound cert extension. | |
166 static bool DomainBoundCertNegotiated(PRFileDesc* socket); | |
167 // Domain bound cert client auth handler. | |
168 // Returns the value the ClientAuthHandler function should return. | |
169 SECStatus DomainBoundClientAuthHandler( | |
170 const SECItem* cert_types, | |
171 CERTCertificate** result_certificate, | |
172 SECKEYPrivateKey** result_private_key); | |
173 #if defined(NSS_PLATFORM_CLIENT_AUTH) | |
174 // On platforms where we use the native certificate store, NSS calls this | |
175 // instead when client authentication is requested. At most one of | |
176 // (result_certs, result_private_key) or | |
177 // (result_nss_certificate, result_nss_private_key) should be set. | |
178 static SECStatus PlatformClientAuthHandler( | |
179 void* arg, | |
180 PRFileDesc* socket, | |
181 CERTDistNames* ca_names, | |
182 CERTCertList** result_certs, | |
183 void** result_private_key, | |
184 CERTCertificate** result_nss_certificate, | |
185 SECKEYPrivateKey** result_nss_private_key); | |
186 #else | |
187 // NSS calls this when client authentication is requested. | |
188 static SECStatus ClientAuthHandler(void* arg, | |
189 PRFileDesc* socket, | |
190 CERTDistNames* ca_names, | |
191 CERTCertificate** result_certificate, | |
192 SECKEYPrivateKey** result_private_key); | |
193 #endif | |
194 // Record histograms for DBC support. The histogram will only be updated if | |
195 // this socket did a full handshake. | |
196 void RecordDomainBoundCertSupport() const; | |
197 | |
198 // NSS calls this when handshake is completed. We pass 'this' as the second | |
199 // argument. | |
200 static void HandshakeCallback(PRFileDesc* socket, void* arg); | |
201 | |
202 static SECStatus NextProtoCallback(void* arg, | |
203 PRFileDesc* fd, | |
204 const unsigned char* protos, | |
205 unsigned int protos_len, | |
206 unsigned char* proto_out, | |
207 unsigned int* proto_out_len, | |
208 unsigned int proto_max_len); | |
209 | 148 |
210 // The following methods are for debugging bug 65948. Will remove this code | 149 // The following methods are for debugging bug 65948. Will remove this code |
211 // after fixing bug 65948. | 150 // after fixing bug 65948. |
212 void EnsureThreadIdAssigned() const; | 151 void EnsureThreadIdAssigned() const; |
213 bool CalledOnValidThread() const; | 152 bool CalledOnValidThread() const; |
214 | 153 |
215 bool transport_send_busy_; | 154 // The task runner used to perform NSS operations. |
216 bool transport_recv_busy_; | 155 scoped_refptr<base::SingleThreadTaskRunner> nss_task_runner_; |
willchan no longer on Chromium
2012/06/04 16:50:38
const?
Ryan Sleevi
2012/06/04 21:51:51
Is this a new thing, trying to document const poin
willchan no longer on Chromium
2012/06/04 21:55:43
There's no One True Way. My stylistic preference i
| |
217 bool transport_recv_eof_; | |
218 scoped_refptr<IOBuffer> recv_buffer_; | |
219 | |
220 scoped_ptr<ClientSocketHandle> transport_; | 156 scoped_ptr<ClientSocketHandle> transport_; |
221 HostPortPair host_and_port_; | 157 HostPortPair host_and_port_; |
222 SSLConfig ssl_config_; | 158 SSLConfig ssl_config_; |
223 | 159 |
160 scoped_refptr<Core> core_; | |
willchan no longer on Chromium
2012/06/04 16:50:38
const?
Ryan Sleevi
2012/06/04 21:51:51
This is not const - we do reset on Disconnect()
| |
161 | |
224 CompletionCallback user_connect_callback_; | 162 CompletionCallback user_connect_callback_; |
225 CompletionCallback user_read_callback_; | |
226 CompletionCallback user_write_callback_; | |
227 | 163 |
228 // Used by Read function. | |
229 scoped_refptr<IOBuffer> user_read_buf_; | |
230 int user_read_buf_len_; | |
231 | |
232 // Used by Write function. | |
233 scoped_refptr<IOBuffer> user_write_buf_; | |
234 int user_write_buf_len_; | |
235 | |
236 // Set when handshake finishes. The server certificate is first received | |
237 // from NSS as an NSS certificate handle (server_cert_nss_), and then | |
238 // converted into an X509Certificate object (server_cert_). | |
239 scoped_refptr<X509Certificate> server_cert_; | |
240 CERTCertificate* server_cert_nss_; | |
241 // |server_cert_verify_result_| points at the verification result, which may, | 164 // |server_cert_verify_result_| points at the verification result, which may, |
242 // or may not be, |&local_server_cert_verify_result_|, depending on whether | 165 // or may not be, |&local_server_cert_verify_result_|, depending on whether |
243 // we used an SSLHostInfo's verification. | 166 // we used an SSLHostInfo's verification. |
244 const CertVerifyResult* server_cert_verify_result_; | 167 const CertVerifyResult* server_cert_verify_result_; |
245 CertVerifyResult local_server_cert_verify_result_; | 168 CertVerifyResult local_server_cert_verify_result_; |
246 std::vector<SHA1Fingerprint> side_pinned_public_keys_; | 169 std::vector<SHA1Fingerprint> side_pinned_public_keys_; |
247 int ssl_connection_status_; | |
248 | |
249 // Stores client authentication information between ClientAuthHandler and | |
250 // GetSSLCertRequestInfo calls. | |
251 std::vector<scoped_refptr<X509Certificate> > client_certs_; | |
252 bool client_auth_cert_needed_; | |
253 | 170 |
254 CertVerifier* const cert_verifier_; | 171 CertVerifier* const cert_verifier_; |
255 scoped_ptr<SingleRequestCertVerifier> verifier_; | 172 scoped_ptr<SingleRequestCertVerifier> verifier_; |
256 | 173 |
257 // For domain bound certificates in client auth. | 174 // For domain bound certificates in client auth. |
258 bool domain_bound_cert_xtn_negotiated_; | |
259 ServerBoundCertService* server_bound_cert_service_; | 175 ServerBoundCertService* server_bound_cert_service_; |
260 SSLClientCertType domain_bound_cert_type_; | |
261 std::string domain_bound_private_key_; | |
262 std::string domain_bound_cert_; | |
263 ServerBoundCertService::RequestHandle domain_bound_cert_request_handle_; | |
264 | |
265 // True if NSS has called HandshakeCallback. | |
266 bool handshake_callback_called_; | |
267 | |
268 // True if the SSL handshake has been completed. | |
269 bool completed_handshake_; | |
270 | 176 |
271 // ssl_session_cache_shard_ is an opaque string that partitions the SSL | 177 // ssl_session_cache_shard_ is an opaque string that partitions the SSL |
272 // session cache. i.e. sessions created with one value will not attempt to | 178 // session cache. i.e. sessions created with one value will not attempt to |
273 // resume on the socket with a different value. | 179 // resume on the socket with a different value. |
274 const std::string ssl_session_cache_shard_; | 180 const std::string ssl_session_cache_shard_; |
275 | 181 |
276 // True iff |ssl_host_info_| contained a predicted certificate chain and | 182 // True if the SSL handshake has been completed. |
277 // that we found the prediction to be correct. | 183 bool completed_handshake_; |
278 bool predicted_cert_chain_correct_; | |
279 | 184 |
280 State next_handshake_state_; | 185 State next_handshake_state_; |
281 | 186 |
282 // The NSS SSL state machine | 187 // The NSS SSL state machine. This is owned by |core_|. |
188 // TODO(rsleevi): http://crbug.com/130616 - Remove this member once | |
189 // ExportKeyingMaterial is updated to be asynchronous. | |
283 PRFileDesc* nss_fd_; | 190 PRFileDesc* nss_fd_; |
284 | 191 |
285 // Buffers for the network end of the SSL state machine | |
286 memio_Private* nss_bufs_; | |
287 | |
288 BoundNetLog net_log_; | 192 BoundNetLog net_log_; |
289 | 193 |
290 base::TimeTicks start_cert_verification_time_; | 194 base::TimeTicks start_cert_verification_time_; |
291 | 195 |
292 scoped_ptr<SSLHostInfo> ssl_host_info_; | 196 scoped_ptr<SSLHostInfo> ssl_host_info_; |
293 | 197 |
294 TransportSecurityState* transport_security_state_; | 198 TransportSecurityState* transport_security_state_; |
295 | 199 |
296 // next_proto_ is the protocol that we selected by NPN. | |
297 std::string next_proto_; | |
298 NextProtoStatus next_proto_status_; | |
299 // Server's NPN advertised protocols. | |
300 std::string server_protos_; | |
301 | |
302 // The following two variables are added for debugging bug 65948. Will | 200 // The following two variables are added for debugging bug 65948. Will |
303 // remove this code after fixing bug 65948. | 201 // remove this code after fixing bug 65948. |
304 // Added the following code Debugging in release mode. | 202 // Added the following code Debugging in release mode. |
305 mutable base::Lock lock_; | 203 mutable base::Lock lock_; |
306 // This is mutable so that CalledOnValidThread can set it. | 204 // This is mutable so that CalledOnValidThread can set it. |
307 // It's guarded by |lock_|. | 205 // It's guarded by |lock_|. |
308 mutable base::PlatformThreadId valid_thread_id_; | 206 mutable base::PlatformThreadId valid_thread_id_; |
309 }; | 207 }; |
310 | 208 |
311 } // namespace net | 209 } // namespace net |
312 | 210 |
313 #endif // NET_SOCKET_SSL_CLIENT_SOCKET_NSS_H_ | 211 #endif // NET_SOCKET_SSL_CLIENT_SOCKET_NSS_H_ |
OLD | NEW |