blob: 603583c7fbc3f20fa69252b216a7d0fa48697e60 [file] [log] [blame]
[email protected]a2006ece2010-04-23 16:44:021// Copyright (c) 2010 The Chromium Authors. All rights reserved.
[email protected]b43c97c2008-10-22 19:50:582// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]e83ba1c42009-11-30 18:18:325// This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived
6// from AuthCertificateCallback() in
[email protected]bf0136d2009-05-29 05:55:047// mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp.
8
9/* ***** BEGIN LICENSE BLOCK *****
10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
11 *
12 * The contents of this file are subject to the Mozilla Public License Version
13 * 1.1 (the "License"); you may not use this file except in compliance with
14 * the License. You may obtain a copy of the License at
15 * http://www.mozilla.org/MPL/
16 *
17 * Software distributed under the License is distributed on an "AS IS" basis,
18 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
19 * for the specific language governing rights and limitations under the
20 * License.
21 *
22 * The Original Code is the Netscape security libraries.
23 *
24 * The Initial Developer of the Original Code is
25 * Netscape Communications Corporation.
26 * Portions created by the Initial Developer are Copyright (C) 2000
27 * the Initial Developer. All Rights Reserved.
28 *
29 * Contributor(s):
30 * Ian McGreer <[email protected]>
31 * Javier Delgadillo <[email protected]>
32 * Kai Engert <[email protected]>
33 *
34 * Alternatively, the contents of this file may be used under the terms of
35 * either the GNU General Public License Version 2 or later (the "GPL"), or
36 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
37 * in which case the provisions of the GPL or the LGPL are applicable instead
38 * of those above. If you wish to allow use of your version of this file only
39 * under the terms of either the GPL or the LGPL, and not to allow others to
40 * use your version of this file under the terms of the MPL, indicate your
41 * decision by deleting the provisions above and replace them with the notice
42 * and other provisions required by the GPL or the LGPL. If you do not delete
43 * the provisions above, a recipient may use your version of this file under
44 * the terms of any one of the MPL, the GPL or the LGPL.
45 *
46 * ***** END LICENSE BLOCK ***** */
47
[email protected]f7984fc62009-06-22 23:26:4448#include "net/socket/ssl_client_socket_nss.h"
[email protected]b43c97c2008-10-22 19:50:5849
[email protected]bf0136d2009-05-29 05:55:0450#include <certdb.h>
[email protected]b24713592010-08-11 19:50:0251#include <hasht.h>
[email protected]d84b3722009-10-15 21:23:3752#include <keyhi.h>
[email protected]b43c97c2008-10-22 19:50:5853#include <nspr.h>
54#include <nss.h>
[email protected]71d6ccaa2011-01-06 17:43:2155#include <ocsp.h>
[email protected]d8eb84242010-09-25 02:25:0656#include <pk11pub.h>
[email protected]ea224582008-12-07 20:25:4657#include <secerr.h>
[email protected]b24713592010-08-11 19:50:0258#include <sechash.h>
[email protected]b43c97c2008-10-22 19:50:5859#include <ssl.h>
[email protected]ea224582008-12-07 20:25:4660#include <sslerr.h>
[email protected]757f2e2b2010-10-27 23:28:3561#include <sslproto.h>
[email protected]b43c97c2008-10-22 19:50:5862
[email protected]b92ead12011-01-19 15:29:0963#if defined(OS_LINUX) || defined(USE_SYSTEM_SSL)
64#include <dlfcn.h>
65#endif
66
[email protected]7a8de3072010-10-01 16:25:5467#include <limits>
68
[email protected]bacff652009-03-31 17:50:3369#include "base/compiler_specific.h"
[email protected]b43c97c2008-10-22 19:50:5870#include "base/logging.h"
[email protected]b92ead12011-01-19 15:29:0971#include "base/metrics/histogram.h"
[email protected]1b1a264a2010-01-14 22:36:3572#include "base/nss_util.h"
[email protected]b92ead12011-01-19 15:29:0973#include "base/singleton.h"
[email protected]899c3e92010-08-28 15:53:5074#include "base/string_number_conversions.h"
[email protected]b43c97c2008-10-22 19:50:5875#include "base/string_util.h"
[email protected]d8eb84242010-09-25 02:25:0676#include "base/stringprintf.h"
[email protected]34b99632011-01-01 01:01:0677#include "base/threading/thread_restrictions.h"
[email protected]7cbc6df12010-10-04 16:25:3978#include "base/values.h"
[email protected]ac9eec62010-02-20 18:50:3879#include "net/base/address_list.h"
[email protected]43025b7a2010-09-16 19:24:4580#include "net/base/cert_status_flags.h"
[email protected]92d9cad2009-06-25 23:40:2481#include "net/base/cert_verifier.h"
[email protected]757f2e2b2010-10-27 23:28:3582#include "net/base/connection_type_histograms.h"
[email protected]d8eb84242010-09-25 02:25:0683#include "net/base/dns_util.h"
[email protected]899c3e92010-08-28 15:53:5084#include "net/base/dnsrr_resolver.h"
[email protected]b24713592010-08-11 19:50:0285#include "net/base/dnssec_chain_verifier.h"
[email protected]597cf6e2009-05-29 09:43:2686#include "net/base/io_buffer.h"
[email protected]b43c97c2008-10-22 19:50:5887#include "net/base/net_errors.h"
[email protected]899c3e92010-08-28 15:53:5088#include "net/base/net_log.h"
[email protected]d84b3722009-10-15 21:23:3789#include "net/base/ssl_cert_request_info.h"
[email protected]fc7de492010-07-12 14:49:0490#include "net/base/ssl_connection_status_flags.h"
[email protected]b43c97c2008-10-22 19:50:5891#include "net/base/ssl_info.h"
[email protected]ac9eec62010-02-20 18:50:3892#include "net/base/sys_addrinfo.h"
[email protected]2a0c0a52009-07-31 07:51:3293#include "net/ocsp/nss_ocsp.h"
[email protected]e60e47a2010-07-14 03:37:1894#include "net/socket/client_socket_handle.h"
[email protected]345c613b2010-11-22 19:33:1895#include "net/socket/dns_cert_provenance_checker.h"
[email protected]f61c3972010-12-23 09:54:1596#include "net/socket/nss_ssl_util.h"
[email protected]47f7d742010-11-11 04:12:5397#include "net/socket/ssl_error_params.h"
[email protected]d0672be2010-10-20 16:30:1998#include "net/socket/ssl_host_info.h"
[email protected]b43c97c2008-10-22 19:50:5899
[email protected]11f40342010-11-22 13:35:49100#if defined(OS_WIN)
101#include <windows.h>
102#include <wincrypt.h>
103#elif defined(OS_MACOSX)
104#include <Security/SecBase.h>
105#include <Security/SecCertificate.h>
106#include <Security/SecIdentity.h>
107#endif
108
[email protected]b43c97c2008-10-22 19:50:58109static const int kRecvBufferSize = 4096;
110
[email protected]fa788512010-10-08 14:48:06111// kCorkTimeoutMs is the number of milliseconds for which we'll wait for a
112// Write to an SSL socket which we're False Starting. Since corking stops the
113// Finished message from being sent, the server sees an incomplete handshake
114// and some will time out such sockets quite aggressively.
115static const int kCorkTimeoutMs = 200;
116
[email protected]b92ead12011-01-19 15:29:09117typedef SECStatus
118(*CacheOCSPResponseFromSideChannelFunction)(
119 CERTCertDBHandle *handle, CERTCertificate *cert, PRTime time,
120 SECItem *encodedResponse, void *pwArg);
121
[email protected]71d6ccaa2011-01-06 17:43:21122#if defined(OS_LINUX)
123// On Linux, we dynamically link against the system version of libnss3.so. In
124// order to continue working on systems without up-to-date versions of NSS we
[email protected]b92ead12011-01-19 15:29:09125// lookup CERT_CacheOCSPResponseFromSideChannel with dlsym.
[email protected]71d6ccaa2011-01-06 17:43:21126
[email protected]b92ead12011-01-19 15:29:09127// RuntimeLibNSSFunctionPointers is a singleton which caches the results of any
128// runtime symbol resolution that we need.
129class RuntimeLibNSSFunctionPointers {
130 public:
131 CacheOCSPResponseFromSideChannelFunction
132 GetCacheOCSPResponseFromSideChannelFunction() {
133 return cache_ocsp_response_from_side_channel_;
134 }
135
136 static RuntimeLibNSSFunctionPointers* GetInstance() {
137 return Singleton<RuntimeLibNSSFunctionPointers>::get();
138 }
139
140 private:
141 friend struct DefaultSingletonTraits<RuntimeLibNSSFunctionPointers>;
142
143 RuntimeLibNSSFunctionPointers() {
144 cache_ocsp_response_from_side_channel_ =
145 (CacheOCSPResponseFromSideChannelFunction)
146 dlsym(RTLD_DEFAULT, "CERT_CacheOCSPResponseFromSideChannel");
147 }
148
149 CacheOCSPResponseFromSideChannelFunction
150 cache_ocsp_response_from_side_channel_;
151};
152
153static CacheOCSPResponseFromSideChannelFunction
154GetCacheOCSPResponseFromSideChannelFunction() {
155 return RuntimeLibNSSFunctionPointers::GetInstance()
156 ->GetCacheOCSPResponseFromSideChannelFunction();
[email protected]71d6ccaa2011-01-06 17:43:21157}
158#else
159// On other platforms we use the system's certificate validation functions.
160// Thus we need, in the future, to plumb the OCSP response into those system
161// functions. Until then, we act as if we didn't support OCSP stapling.
[email protected]b92ead12011-01-19 15:29:09162static CacheOCSPResponseFromSideChannelFunction
163GetCacheOCSPResponseFromSideChannelFunction() {
164 return NULL;
[email protected]71d6ccaa2011-01-06 17:43:21165}
166#endif
167
[email protected]b43c97c2008-10-22 19:50:58168namespace net {
169
[email protected]e17b4c12008-11-05 22:04:08170// State machines are easier to debug if you log state transitions.
171// Enable these if you want to see what's going on.
172#if 1
173#define EnterFunction(x)
174#define LeaveFunction(x)
[email protected]a3ff5e92009-10-13 04:48:06175#define GotoState(s) next_handshake_state_ = s
[email protected]ea224582008-12-07 20:25:46176#define LogData(s, len)
[email protected]e17b4c12008-11-05 22:04:08177#else
[email protected]b30a3f52010-10-16 01:05:46178#define EnterFunction(x)\
179 VLOG(1) << (void *)this << " " << __FUNCTION__ << " enter " << x\
180 << "; next_handshake_state " << next_handshake_state_
181#define LeaveFunction(x)\
182 VLOG(1) << (void *)this << " " << __FUNCTION__ << " leave " << x\
183 << "; next_handshake_state " << next_handshake_state_
184#define GotoState(s)\
185 do {\
186 VLOG(1) << (void *)this << " " << __FUNCTION__ << " jump to state " << s;\
187 next_handshake_state_ = s;\
188 } while (0)
189#define LogData(s, len)\
190 VLOG(1) << (void *)this << " " << __FUNCTION__\
191 << " data [" << std::string(s, len) << "]"
[email protected]e17b4c12008-11-05 22:04:08192#endif
193
[email protected]ea224582008-12-07 20:25:46194namespace {
195
[email protected]37a0b112010-05-08 02:23:46196#if defined(OS_WIN)
197
[email protected]01640f62010-08-10 19:42:12198// This callback is intended to be used with CertFindChainInStore. In addition
199// to filtering by extended/enhanced key usage, we do not show expired
200// certificates and require digital signature usage in the key usage
201// extension.
202//
203// This matches our behavior on Mac OS X and that of NSS. It also matches the
204// default behavior of IE8. See http://support.microsoft.com/kb/890326 and
205// http://blogs.msdn.com/b/askie/archive/2009/06/09/my-expired-client-certificates-no-longer-display-when-connecting-to-my-web-server-using-ie8.aspx
206BOOL WINAPI ClientCertFindCallback(PCCERT_CONTEXT cert_context,
207 void* find_arg) {
[email protected]b30a3f52010-10-16 01:05:46208 VLOG(1) << "Calling ClientCertFindCallback from _nss";
[email protected]01640f62010-08-10 19:42:12209 // Verify the certificate's KU is good.
210 BYTE key_usage;
211 if (CertGetIntendedKeyUsage(X509_ASN_ENCODING, cert_context->pCertInfo,
212 &key_usage, 1)) {
213 if (!(key_usage & CERT_DIGITAL_SIGNATURE_KEY_USAGE))
214 return FALSE;
215 } else {
216 DWORD err = GetLastError();
217 // If |err| is non-zero, it's an actual error. Otherwise the extension
218 // just isn't present, and we treat it as if everything was allowed.
219 if (err) {
220 DLOG(ERROR) << "CertGetIntendedKeyUsage failed: " << err;
221 return FALSE;
222 }
223 }
224
225 // Verify the current time is within the certificate's validity period.
226 if (CertVerifyTimeValidity(NULL, cert_context->pCertInfo) != 0)
227 return FALSE;
228
229 return TRUE;
230}
231
[email protected]37a0b112010-05-08 02:23:46232#endif
233
[email protected]17570702010-10-28 15:16:09234// PeerCertificateChain is a helper object which extracts the certificate
235// chain, as given by the server, from an NSS socket and performs the needed
236// resource management. The first element of the chain is the leaf certificate
237// and the other elements are in the order given by the server.
238class PeerCertificateChain {
239 public:
[email protected]b92a96e2010-11-02 21:03:05240 explicit PeerCertificateChain(PRFileDesc* nss_fd)
[email protected]17570702010-10-28 15:16:09241 : num_certs_(0),
242 certs_(NULL) {
243 SECStatus rv = SSL_PeerCertificateChain(nss_fd, NULL, &num_certs_);
244 DCHECK_EQ(rv, SECSuccess);
245
246 certs_ = new CERTCertificate*[num_certs_];
247 const unsigned expected_num_certs = num_certs_;
248 rv = SSL_PeerCertificateChain(nss_fd, certs_, &num_certs_);
249 DCHECK_EQ(rv, SECSuccess);
250 DCHECK_EQ(num_certs_, expected_num_certs);
251 }
252
253 ~PeerCertificateChain() {
254 for (unsigned i = 0; i < num_certs_; i++)
255 CERT_DestroyCertificate(certs_[i]);
256 delete[] certs_;
257 }
258
259 unsigned size() const { return num_certs_; }
260
261 CERTCertificate* operator[](unsigned i) {
262 DCHECK_LT(i, num_certs_);
263 return certs_[i];
264 }
265
[email protected]d8fbf582010-11-04 21:51:12266 std::vector<base::StringPiece> AsStringPieceVector() const {
267 std::vector<base::StringPiece> v(size());
268 for (unsigned i = 0; i < size(); i++) {
269 v[i] = base::StringPiece(
270 reinterpret_cast<const char*>(certs_[i]->derCert.data),
271 certs_[i]->derCert.len);
272 }
273
274 return v;
275 }
276
[email protected]17570702010-10-28 15:16:09277 private:
278 unsigned num_certs_;
279 CERTCertificate** certs_;
280};
281
[email protected]d100e44f2011-01-26 22:47:11282void DestroyCertificates(CERTCertificate** certs, unsigned len) {
283 for (unsigned i = 0; i < len; i++)
284 CERT_DestroyCertificate(certs[i]);
285}
286
287// DNSValidationResult enumerates the possible outcomes from processing a
288// set of DNS records.
289enum DNSValidationResult {
290 DNSVR_SUCCESS, // the cert is immediately acceptable.
291 DNSVR_FAILURE, // the cert is unconditionally rejected.
292 DNSVR_CONTINUE, // perform CA validation as usual.
293};
294
295// VerifyTXTRecords processes the RRDATA for a number of DNS TXT records and
296// checks them against the given certificate.
297// dnssec: if true then the TXT records are DNSSEC validated. In this case,
298// DNSVR_SUCCESS may be returned.
299// server_cert_nss: the certificate to validate
300// rrdatas: the TXT records for the current domain.
301DNSValidationResult VerifyTXTRecords(
302 bool dnssec,
303 CERTCertificate* server_cert_nss,
304 const std::vector<base::StringPiece>& rrdatas) {
305 bool found_well_formed_record = false;
306 bool matched_record = false;
307
308 for (std::vector<base::StringPiece>::const_iterator
309 i = rrdatas.begin(); i != rrdatas.end(); ++i) {
310 std::map<std::string, std::string> m(
311 DNSSECChainVerifier::ParseTLSTXTRecord(*i));
312 if (m.empty())
313 continue;
314
315 std::map<std::string, std::string>::const_iterator j;
316 j = m.find("v");
317 if (j == m.end() || j->second != "tls1")
318 continue;
319
320 j = m.find("ha");
321
322 HASH_HashType hash_algorithm;
323 unsigned hash_length;
324 if (j == m.end() || j->second == "sha1") {
325 hash_algorithm = HASH_AlgSHA1;
326 hash_length = SHA1_LENGTH;
327 } else if (j->second == "sha256") {
328 hash_algorithm = HASH_AlgSHA256;
329 hash_length = SHA256_LENGTH;
330 } else {
331 continue;
332 }
333
334 j = m.find("h");
335 if (j == m.end())
336 continue;
337
338 std::vector<uint8> given_hash;
339 if (!base::HexStringToBytes(j->second, &given_hash))
340 continue;
341
342 if (given_hash.size() != hash_length)
343 continue;
344
345 uint8 calculated_hash[SHA256_LENGTH]; // SHA256 is the largest.
346 SECStatus rv;
347
348 j = m.find("hr");
349 if (j == m.end() || j->second == "pubkey") {
350 rv = HASH_HashBuf(hash_algorithm, calculated_hash,
351 server_cert_nss->derPublicKey.data,
352 server_cert_nss->derPublicKey.len);
353 } else if (j->second == "cert") {
354 rv = HASH_HashBuf(hash_algorithm, calculated_hash,
355 server_cert_nss->derCert.data,
356 server_cert_nss->derCert.len);
357 } else {
358 continue;
359 }
360
361 if (rv != SECSuccess)
362 NOTREACHED();
363
364 found_well_formed_record = true;
365
366 if (memcmp(calculated_hash, &given_hash[0], hash_length) == 0) {
367 matched_record = true;
368 if (dnssec)
369 return DNSVR_SUCCESS;
370 }
371 }
372
373 if (found_well_formed_record && !matched_record)
374 return DNSVR_FAILURE;
375
376 return DNSVR_CONTINUE;
377}
378
379// CheckDNSSECChain tries to validate a DNSSEC chain embedded in
380// |server_cert_nss_|. It returns true iff a chain is found that proves the
381// value of a TXT record that contains a valid public key fingerprint.
382DNSValidationResult CheckDNSSECChain(
383 const std::string& hostname,
384 CERTCertificate* server_cert_nss) {
385 if (!server_cert_nss)
386 return DNSVR_CONTINUE;
387
388 // CERT_FindCertExtensionByOID isn't exported so we have to install an OID,
389 // get a tag for it and find the extension by using that tag.
390 static SECOidTag dnssec_chain_tag;
391 static bool dnssec_chain_tag_valid;
392 if (!dnssec_chain_tag_valid) {
393 // It's harmless if multiple threads enter this block concurrently.
394 static const uint8 kDNSSECChainOID[] =
395 // 1.3.6.1.4.1.11129.2.1.4
396 // (iso.org.dod.internet.private.enterprises.google.googleSecurity.
397 // certificateExtensions.dnssecEmbeddedChain)
398 {0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x01, 0x04};
399 SECOidData oid_data;
400 memset(&oid_data, 0, sizeof(oid_data));
401 oid_data.oid.data = const_cast<uint8*>(kDNSSECChainOID);
402 oid_data.oid.len = sizeof(kDNSSECChainOID);
403 oid_data.desc = "DNSSEC chain";
404 oid_data.supportedExtension = SUPPORTED_CERT_EXTENSION;
405 dnssec_chain_tag = SECOID_AddEntry(&oid_data);
406 DCHECK_NE(SEC_OID_UNKNOWN, dnssec_chain_tag);
407 dnssec_chain_tag_valid = true;
408 }
409
410 SECItem dnssec_embedded_chain;
411 SECStatus rv = CERT_FindCertExtension(server_cert_nss,
412 dnssec_chain_tag, &dnssec_embedded_chain);
413 if (rv != SECSuccess)
414 return DNSVR_CONTINUE;
415
416 base::StringPiece chain(
417 reinterpret_cast<char*>(dnssec_embedded_chain.data),
418 dnssec_embedded_chain.len);
419 std::string dns_hostname;
420 if (!DNSDomainFromDot(hostname, &dns_hostname))
421 return DNSVR_CONTINUE;
422 DNSSECChainVerifier verifier(dns_hostname, chain);
423 DNSSECChainVerifier::Error err = verifier.Verify();
424 if (err != DNSSECChainVerifier::OK) {
425 LOG(ERROR) << "DNSSEC chain verification failed: " << err;
426 return DNSVR_CONTINUE;
427 }
428
429 if (verifier.rrtype() != kDNS_TXT)
430 return DNSVR_CONTINUE;
431
432 DNSValidationResult r = VerifyTXTRecords(
433 true /* DNSSEC verified */, server_cert_nss, verifier.rrdatas());
434 SECITEM_FreeItem(&dnssec_embedded_chain, PR_FALSE);
435 return r;
436}
437
[email protected]ea224582008-12-07 20:25:46438} // namespace
439
[email protected]e60e47a2010-07-14 03:37:18440SSLClientSocketNSS::SSLClientSocketNSS(ClientSocketHandle* transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27441 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21442 const SSLConfig& ssl_config,
[email protected]d8fbf582010-11-04 21:51:12443 SSLHostInfo* ssl_host_info,
[email protected]822581d2010-12-16 17:27:15444 CertVerifier* cert_verifier,
[email protected]345c613b2010-11-22 19:33:18445 DnsCertProvenanceChecker* dns_ctx)
[email protected]f505a9b2010-01-28 19:44:02446 : ALLOW_THIS_IN_INITIALIZER_LIST(buffer_send_callback_(
447 this, &SSLClientSocketNSS::BufferSendComplete)),
448 ALLOW_THIS_IN_INITIALIZER_LIST(buffer_recv_callback_(
449 this, &SSLClientSocketNSS::BufferRecvComplete)),
[email protected]b43c97c2008-10-22 19:50:58450 transport_send_busy_(false),
451 transport_recv_busy_(false),
[email protected]9ae2ee02010-09-08 16:41:14452 corked_(false),
[email protected]f505a9b2010-01-28 19:44:02453 ALLOW_THIS_IN_INITIALIZER_LIST(handshake_io_callback_(
454 this, &SSLClientSocketNSS::OnHandshakeIOComplete)),
[email protected]b43c97c2008-10-22 19:50:58455 transport_(transport_socket),
[email protected]4f4de7e62010-11-12 19:55:27456 host_and_port_(host_and_port),
[email protected]b43c97c2008-10-22 19:50:58457 ssl_config_(ssl_config),
[email protected]a6eb576292009-06-30 16:19:00458 user_connect_callback_(NULL),
[email protected]a3ff5e92009-10-13 04:48:06459 user_read_callback_(NULL),
460 user_write_callback_(NULL),
461 user_read_buf_len_(0),
462 user_write_buf_len_(0),
[email protected]f505a9b2010-01-28 19:44:02463 server_cert_nss_(NULL),
[email protected]3b1d3db2010-10-28 16:39:40464 server_cert_verify_result_(NULL),
[email protected]757f2e2b2010-10-27 23:28:35465 ssl_connection_status_(0),
[email protected]d84b3722009-10-15 21:23:37466 client_auth_cert_needed_(false),
[email protected]822581d2010-12-16 17:27:15467 cert_verifier_(cert_verifier),
[email protected]39afe642010-04-29 14:55:18468 handshake_callback_called_(false),
[email protected]b43c97c2008-10-22 19:50:58469 completed_handshake_(false),
[email protected]7a8de3072010-10-01 16:25:54470 pseudo_connected_(false),
[email protected]563cbcc62010-10-11 23:07:52471 eset_mitm_detected_(false),
[email protected]3b1d3db2010-10-28 16:39:40472 predicted_cert_chain_correct_(false),
[email protected]7f7e92392010-10-26 18:29:29473 peername_initialized_(false),
[email protected]899c3e92010-08-28 15:53:50474 dnssec_provider_(NULL),
[email protected]a3ff5e92009-10-13 04:48:06475 next_handshake_state_(STATE_NONE),
[email protected]b43c97c2008-10-22 19:50:58476 nss_fd_(NULL),
[email protected]a2006ece2010-04-23 16:44:02477 nss_bufs_(NULL),
[email protected]7a8de3072010-10-01 16:25:54478 net_log_(transport_socket->socket()->NetLog()),
479 predicted_npn_status_(kNextProtoUnsupported),
[email protected]7ab5bbd12010-10-19 13:33:21480 predicted_npn_proto_used_(false),
[email protected]d8fbf582010-11-04 21:51:12481 ssl_host_info_(ssl_host_info),
[email protected]345c613b2010-11-22 19:33:18482 dns_cert_checker_(dns_ctx) {
[email protected]e17b4c12008-11-05 22:04:08483 EnterFunction("");
[email protected]b43c97c2008-10-22 19:50:58484}
485
486SSLClientSocketNSS::~SSLClientSocketNSS() {
[email protected]e17b4c12008-11-05 22:04:08487 EnterFunction("");
[email protected]b43c97c2008-10-22 19:50:58488 Disconnect();
[email protected]e17b4c12008-11-05 22:04:08489 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:58490}
491
[email protected]d100e44f2011-01-26 22:47:11492// static
493void SSLClientSocketNSS::ClearSessionCache() {
494 SSL_ClearSessionCache();
495}
496
497void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) {
[email protected]e17b4c12008-11-05 22:04:08498 EnterFunction("");
[email protected]d100e44f2011-01-26 22:47:11499 ssl_info->Reset();
[email protected]b43c97c2008-10-22 19:50:58500
[email protected]d100e44f2011-01-26 22:47:11501 if (!server_cert_) {
502 LOG(DFATAL) << "!server_cert_";
[email protected]7a8de3072010-10-01 16:25:54503 return;
504 }
505
[email protected]d100e44f2011-01-26 22:47:11506 ssl_info->cert_status = server_cert_verify_result_->cert_status;
507 DCHECK(server_cert_ != NULL);
508 ssl_info->cert = server_cert_;
509 ssl_info->connection_status = ssl_connection_status_;
[email protected]7a8de3072010-10-01 16:25:54510
[email protected]d100e44f2011-01-26 22:47:11511 PRUint16 cipher_suite =
512 SSLConnectionStatusToCipherSuite(ssl_connection_status_);
513 SSLCipherSuiteInfo cipher_info;
514 SECStatus ok = SSL_GetCipherSuiteInfo(cipher_suite,
515 &cipher_info, sizeof(cipher_info));
516 if (ok == SECSuccess) {
517 ssl_info->security_bits = cipher_info.effectiveKeyBits;
[email protected]98f397e2010-10-26 13:56:57518 } else {
[email protected]d100e44f2011-01-26 22:47:11519 ssl_info->security_bits = -1;
520 LOG(DFATAL) << "SSL_GetCipherSuiteInfo returned " << PR_GetError()
521 << " for cipherSuite " << cipher_suite;
[email protected]98f397e2010-10-26 13:56:57522 }
[email protected]d100e44f2011-01-26 22:47:11523 LeaveFunction("");
[email protected]7a8de3072010-10-01 16:25:54524}
525
[email protected]d100e44f2011-01-26 22:47:11526void SSLClientSocketNSS::GetSSLCertRequestInfo(
527 SSLCertRequestInfo* cert_request_info) {
528 EnterFunction("");
529 // TODO(rch): switch SSLCertRequestInfo.host_and_port to a HostPortPair
530 cert_request_info->host_and_port = host_and_port_.ToString();
531 cert_request_info->client_certs = client_certs_;
532 LeaveFunction(cert_request_info->client_certs.size());
[email protected]7a8de3072010-10-01 16:25:54533}
534
[email protected]d100e44f2011-01-26 22:47:11535SSLClientSocket::NextProtoStatus
536SSLClientSocketNSS::GetNextProto(std::string* proto) {
537#if defined(SSL_NEXT_PROTO_NEGOTIATED)
538 if (!handshake_callback_called_) {
539 DCHECK(pseudo_connected_);
540 predicted_npn_proto_used_ = true;
541 *proto = predicted_npn_proto_;
542 return predicted_npn_status_;
[email protected]d0672be2010-10-20 16:30:19543 }
544
[email protected]d100e44f2011-01-26 22:47:11545 unsigned char buf[255];
546 int state;
547 unsigned len;
548 SECStatus rv = SSL_GetNextProto(nss_fd_, &state, buf, &len, sizeof(buf));
549 if (rv != SECSuccess) {
550 NOTREACHED() << "Error return from SSL_GetNextProto: " << rv;
551 proto->clear();
552 return kNextProtoUnsupported;
[email protected]7a8de3072010-10-01 16:25:54553 }
[email protected]d100e44f2011-01-26 22:47:11554 // We don't check for truncation because sizeof(buf) is large enough to hold
555 // the maximum protocol size.
556 switch (state) {
557 case SSL_NEXT_PROTO_NO_SUPPORT:
558 proto->clear();
559 return kNextProtoUnsupported;
560 case SSL_NEXT_PROTO_NEGOTIATED:
561 *proto = std::string(reinterpret_cast<char*>(buf), len);
562 return kNextProtoNegotiated;
563 case SSL_NEXT_PROTO_NO_OVERLAP:
564 *proto = std::string(reinterpret_cast<char*>(buf), len);
565 return kNextProtoNoOverlap;
566 default:
567 NOTREACHED() << "Unknown status from SSL_GetNextProto: " << state;
568 proto->clear();
569 return kNextProtoUnsupported;
[email protected]d0672be2010-10-20 16:30:19570 }
[email protected]d100e44f2011-01-26 22:47:11571#else
572 // No NPN support in the libssl that we are building with.
573 proto->clear();
574 return kNextProtoUnsupported;
575#endif
[email protected]7a8de3072010-10-01 16:25:54576}
577
[email protected]d100e44f2011-01-26 22:47:11578void SSLClientSocketNSS::UseDNSSEC(DNSSECProvider* provider) {
579 dnssec_provider_ = provider;
[email protected]fa788512010-10-08 14:48:06580}
581
[email protected]a2006ece2010-04-23 16:44:02582int SSLClientSocketNSS::Connect(CompletionCallback* callback) {
[email protected]e17b4c12008-11-05 22:04:08583 EnterFunction("");
[email protected]b43c97c2008-10-22 19:50:58584 DCHECK(transport_.get());
[email protected]a3ff5e92009-10-13 04:48:06585 DCHECK(next_handshake_state_ == STATE_NONE);
586 DCHECK(!user_read_callback_);
587 DCHECK(!user_write_callback_);
[email protected]a6eb576292009-06-30 16:19:00588 DCHECK(!user_connect_callback_);
[email protected]a3ff5e92009-10-13 04:48:06589 DCHECK(!user_read_buf_);
590 DCHECK(!user_write_buf_);
[email protected]7a8de3072010-10-01 16:25:54591 DCHECK(!pseudo_connected_);
[email protected]b43c97c2008-10-22 19:50:58592
[email protected]ec11be62010-04-28 19:28:09593 net_log_.BeginEvent(NetLog::TYPE_SSL_CONNECT, NULL);
[email protected]5a05c47a2009-11-02 23:25:19594
[email protected]dbc13b52010-04-16 00:59:56595 int rv = Init();
596 if (rv != OK) {
[email protected]ec11be62010-04-28 19:28:09597 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL);
[email protected]dbc13b52010-04-16 00:59:56598 return rv;
[email protected]0ef0bcf2009-04-03 20:39:43599 }
600
[email protected]dbc13b52010-04-16 00:59:56601 rv = InitializeSSLOptions();
[email protected]5a05c47a2009-11-02 23:25:19602 if (rv != OK) {
[email protected]ec11be62010-04-28 19:28:09603 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL);
[email protected]5a05c47a2009-11-02 23:25:19604 return rv;
605 }
606
[email protected]7f7e92392010-10-26 18:29:29607 // Attempt to initialize the peer name. In the case of TCP FastOpen,
608 // we don't have the peer yet.
609 if (!UsingTCPFastOpen()) {
610 rv = InitializeSSLPeerName();
611 if (rv != OK) {
612 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL);
613 return rv;
614 }
615 }
616
[email protected]7ab5bbd12010-10-19 13:33:21617 if (ssl_config_.snap_start_enabled && ssl_host_info_.get()) {
[email protected]7a8de3072010-10-01 16:25:54618 GotoState(STATE_SNAP_START_LOAD_INFO);
619 } else {
620 GotoState(STATE_HANDSHAKE);
621 }
622
[email protected]5a05c47a2009-11-02 23:25:19623 rv = DoHandshakeLoop(OK);
624 if (rv == ERR_IO_PENDING) {
[email protected]7a8de3072010-10-01 16:25:54625 if (pseudo_connected_) {
626 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL);
627 rv = OK;
628 } else {
629 user_connect_callback_ = callback;
630 }
[email protected]5a05c47a2009-11-02 23:25:19631 } else {
[email protected]ec11be62010-04-28 19:28:09632 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL);
[email protected]5a05c47a2009-11-02 23:25:19633 }
634
635 LeaveFunction("");
636 return rv > OK ? OK : rv;
637}
638
[email protected]d100e44f2011-01-26 22:47:11639void SSLClientSocketNSS::Disconnect() {
640 EnterFunction("");
641
642 // TODO(wtc): Send SSL close_notify alert.
643 if (nss_fd_ != NULL) {
644 PR_Close(nss_fd_);
645 nss_fd_ = NULL;
646 }
647
648 // Shut down anything that may call us back (through buffer_send_callback_,
649 // buffer_recv_callback, or handshake_io_callback_).
650 verifier_.reset();
651 transport_->socket()->Disconnect();
652
653 // Reset object state
654 transport_send_busy_ = false;
655 transport_recv_busy_ = false;
656 user_connect_callback_ = NULL;
657 user_read_callback_ = NULL;
658 user_write_callback_ = NULL;
659 user_read_buf_ = NULL;
660 user_read_buf_len_ = 0;
661 user_write_buf_ = NULL;
662 user_write_buf_len_ = 0;
663 server_cert_ = NULL;
664 if (server_cert_nss_) {
665 CERT_DestroyCertificate(server_cert_nss_);
666 server_cert_nss_ = NULL;
667 }
668 local_server_cert_verify_result_.Reset();
669 server_cert_verify_result_ = NULL;
670 ssl_connection_status_ = 0;
671 completed_handshake_ = false;
672 pseudo_connected_ = false;
673 eset_mitm_detected_ = false;
674 start_cert_verification_time_ = base::TimeTicks();
675 predicted_cert_chain_correct_ = false;
676 peername_initialized_ = false;
677 nss_bufs_ = NULL;
678 client_certs_.clear();
679 client_auth_cert_needed_ = false;
680
681 LeaveFunction("");
682}
683
684bool SSLClientSocketNSS::IsConnected() const {
685 // Ideally, we should also check if we have received the close_notify alert
686 // message from the server, and return false in that case. We're not doing
687 // that, so this function may return a false positive. Since the upper
688 // layer (HttpNetworkTransaction) needs to handle a persistent connection
689 // closed by the server when we send a request anyway, a false positive in
690 // exchange for simpler code is a good trade-off.
691 EnterFunction("");
692 bool ret = (pseudo_connected_ || completed_handshake_) &&
693 transport_->socket()->IsConnected();
694 LeaveFunction("");
695 return ret;
696}
697
698bool SSLClientSocketNSS::IsConnectedAndIdle() const {
699 // Unlike IsConnected, this method doesn't return a false positive.
700 //
701 // Strictly speaking, we should check if we have received the close_notify
702 // alert message from the server, and return false in that case. Although
703 // the close_notify alert message means EOF in the SSL layer, it is just
704 // bytes to the transport layer below, so
705 // transport_->socket()->IsConnectedAndIdle() returns the desired false
706 // when we receive close_notify.
707 EnterFunction("");
708 bool ret = (pseudo_connected_ || completed_handshake_) &&
709 transport_->socket()->IsConnectedAndIdle();
710 LeaveFunction("");
711 return ret;
712}
713
714int SSLClientSocketNSS::GetPeerAddress(AddressList* address) const {
715 return transport_->socket()->GetPeerAddress(address);
716}
717
718const BoundNetLog& SSLClientSocketNSS::NetLog() const {
719 return net_log_;
720}
721
722void SSLClientSocketNSS::SetSubresourceSpeculation() {
723 if (transport_.get() && transport_->socket()) {
724 transport_->socket()->SetSubresourceSpeculation();
725 } else {
726 NOTREACHED();
727 }
728}
729
730void SSLClientSocketNSS::SetOmniboxSpeculation() {
731 if (transport_.get() && transport_->socket()) {
732 transport_->socket()->SetOmniboxSpeculation();
733 } else {
734 NOTREACHED();
735 }
736}
737
738bool SSLClientSocketNSS::WasEverUsed() const {
739 if (transport_.get() && transport_->socket()) {
740 return transport_->socket()->WasEverUsed();
741 }
742 NOTREACHED();
743 return false;
744}
745
746bool SSLClientSocketNSS::UsingTCPFastOpen() const {
747 if (transport_.get() && transport_->socket()) {
748 return transport_->socket()->UsingTCPFastOpen();
749 }
750 NOTREACHED();
751 return false;
752}
753
754int SSLClientSocketNSS::Read(IOBuffer* buf, int buf_len,
755 CompletionCallback* callback) {
756 EnterFunction(buf_len);
757 DCHECK(!user_read_callback_);
758 DCHECK(!user_connect_callback_);
759 DCHECK(!user_read_buf_);
760 DCHECK(nss_bufs_);
761
762 user_read_buf_ = buf;
763 user_read_buf_len_ = buf_len;
764
765 if (!completed_handshake_) {
766 // In this case we have lied about being connected in order to merge the
767 // first Write into a Snap Start handshake. We'll leave the read hanging
768 // until the handshake has completed.
769 DCHECK(pseudo_connected_);
770
771 user_read_callback_ = callback;
772 LeaveFunction(ERR_IO_PENDING);
773 return ERR_IO_PENDING;
774 }
775
776 int rv = DoReadLoop(OK);
777
778 if (rv == ERR_IO_PENDING) {
779 user_read_callback_ = callback;
780 } else {
781 user_read_buf_ = NULL;
782 user_read_buf_len_ = 0;
783 }
784 LeaveFunction(rv);
785 return rv;
786}
787
788int SSLClientSocketNSS::Write(IOBuffer* buf, int buf_len,
789 CompletionCallback* callback) {
790 EnterFunction(buf_len);
791 if (!pseudo_connected_) {
792 DCHECK(completed_handshake_);
793 DCHECK(next_handshake_state_ == STATE_NONE);
794 DCHECK(!user_connect_callback_);
795 }
796 DCHECK(!user_write_callback_);
797 DCHECK(!user_write_buf_);
798 DCHECK(nss_bufs_);
799
800 user_write_buf_ = buf;
801 user_write_buf_len_ = buf_len;
802
803 if (next_handshake_state_ == STATE_SNAP_START_WAIT_FOR_WRITE) {
804 // We lied about being connected and we have been waiting for this write in
805 // order to merge it into the Snap Start handshake. We'll leave the write
806 // pending until the handshake completes.
807 DCHECK(pseudo_connected_);
808 int rv = DoHandshakeLoop(OK);
809 if (rv == ERR_IO_PENDING) {
810 user_write_callback_ = callback;
811 } else {
812 user_write_buf_ = NULL;
813 user_write_buf_len_ = 0;
814 }
815 if (rv != OK)
816 return rv;
817 }
818
819 if (corked_) {
820 corked_ = false;
821 uncork_timer_.Reset();
822 }
823 int rv = DoWriteLoop(OK);
824
825 if (rv == ERR_IO_PENDING) {
826 user_write_callback_ = callback;
827 } else {
828 user_write_buf_ = NULL;
829 user_write_buf_len_ = 0;
830 }
831 LeaveFunction(rv);
832 return rv;
833}
834
835bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) {
836 return transport_->socket()->SetReceiveBufferSize(size);
837}
838
839bool SSLClientSocketNSS::SetSendBufferSize(int32 size) {
840 return transport_->socket()->SetSendBufferSize(size);
841}
842
843int SSLClientSocketNSS::Init() {
844 EnterFunction("");
845 // Initialize the NSS SSL library in a threadsafe way. This also
846 // initializes the NSS base library.
847 EnsureNSSSSLInit();
848 if (!NSS_IsInitialized())
849 return ERR_UNEXPECTED;
850#if !defined(OS_MACOSX) && !defined(OS_WIN)
851 // We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop
852 // by MessageLoopForIO::current().
853 // X509Certificate::Verify() runs on a worker thread of CertVerifier.
854 EnsureOCSPInit();
855#endif
856
857 LeaveFunction("");
858 return OK;
859}
860
[email protected]5a05c47a2009-11-02 23:25:19861int SSLClientSocketNSS::InitializeSSLOptions() {
[email protected]0ef0bcf2009-04-03 20:39:43862 // Transport connected, now hook it up to nss
863 // TODO(port): specify rx and tx buffer sizes separately
864 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize);
865 if (nss_fd_ == NULL) {
[email protected]38a18722009-12-04 00:09:04866 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR error code.
[email protected]0ef0bcf2009-04-03 20:39:43867 }
868
[email protected]0ef0bcf2009-04-03 20:39:43869 // Grab pointer to buffers
870 nss_bufs_ = memio_GetSecret(nss_fd_);
871
872 /* Create SSL state machine */
873 /* Push SSL onto our fake I/O socket */
874 nss_fd_ = SSL_ImportFD(NULL, nss_fd_);
875 if (nss_fd_ == NULL) {
[email protected]7cbc6df12010-10-04 16:25:39876 LogFailedNSSFunction(net_log_, "SSL_ImportFD", "");
[email protected]4e91b5c2010-09-22 01:04:38877 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR/NSS error code.
[email protected]0ef0bcf2009-04-03 20:39:43878 }
879 // TODO(port): set more ssl options! Check errors!
880
881 int rv;
882
883 rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE);
[email protected]7cbc6df12010-10-04 16:25:39884 if (rv != SECSuccess) {
885 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_SECURITY");
[email protected]4e91b5c2010-09-22 01:04:38886 return ERR_UNEXPECTED;
[email protected]7cbc6df12010-10-04 16:25:39887 }
[email protected]0ef0bcf2009-04-03 20:39:43888
[email protected]cc50fdf72010-11-30 17:48:54889 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL2, PR_FALSE);
[email protected]7cbc6df12010-10-04 16:25:39890 if (rv != SECSuccess) {
891 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL2");
[email protected]4e91b5c2010-09-22 01:04:38892 return ERR_UNEXPECTED;
[email protected]7cbc6df12010-10-04 16:25:39893 }
[email protected]0ef0bcf2009-04-03 20:39:43894
[email protected]cc50fdf72010-11-30 17:48:54895 // Don't do V2 compatible hellos because they don't support TLS extensions.
896 rv = SSL_OptionSet(nss_fd_, SSL_V2_COMPATIBLE_HELLO, PR_FALSE);
[email protected]7cbc6df12010-10-04 16:25:39897 if (rv != SECSuccess) {
898 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_V2_COMPATIBLE_HELLO");
899 return ERR_UNEXPECTED;
900 }
[email protected]0ef0bcf2009-04-03 20:39:43901
902 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL3, ssl_config_.ssl3_enabled);
[email protected]7cbc6df12010-10-04 16:25:39903 if (rv != SECSuccess) {
904 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL3");
905 return ERR_UNEXPECTED;
906 }
[email protected]0ef0bcf2009-04-03 20:39:43907
908 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_TLS, ssl_config_.tls1_enabled);
[email protected]7cbc6df12010-10-04 16:25:39909 if (rv != SECSuccess) {
910 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_TLS");
911 return ERR_UNEXPECTED;
912 }
[email protected]0ef0bcf2009-04-03 20:39:43913
[email protected]47f7d742010-11-11 04:12:53914 for (std::vector<uint16>::const_iterator it =
915 ssl_config_.disabled_cipher_suites.begin();
916 it != ssl_config_.disabled_cipher_suites.end(); ++it) {
917 // This will fail if the specified cipher is not implemented by NSS, but
918 // the failure is harmless.
919 SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE);
920 }
921
[email protected]0ef0bcf2009-04-03 20:39:43922#ifdef SSL_ENABLE_SESSION_TICKETS
923 // Support RFC 5077
924 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_TRUE);
[email protected]7cbc6df12010-10-04 16:25:39925 if (rv != SECSuccess) {
926 LogFailedNSSFunction(
927 net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS");
928 }
[email protected]0ef0bcf2009-04-03 20:39:43929#else
930 #error "You need to install NSS-3.12 or later to build chromium"
931#endif
932
[email protected]7e52ed72009-11-17 00:40:12933#ifdef SSL_ENABLE_DEFLATE
[email protected]074c1582010-01-08 21:38:28934 // Some web servers have been found to break if TLS is used *or* if DEFLATE
935 // is advertised. Thus, if TLS is disabled (probably because we are doing
936 // SSLv3 fallback), we disable DEFLATE also.
937 // See http://crbug.com/31628
938 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_DEFLATE, ssl_config_.tls1_enabled);
[email protected]7e52ed72009-11-17 00:40:12939 if (rv != SECSuccess)
[email protected]7cbc6df12010-10-04 16:25:39940 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_DEFLATE");
[email protected]7e52ed72009-11-17 00:40:12941#endif
942
[email protected]c2def1c2010-03-02 21:40:34943#ifdef SSL_ENABLE_FALSE_START
[email protected]a0deaecf2010-08-18 23:39:52944 rv = SSL_OptionSet(
945 nss_fd_, SSL_ENABLE_FALSE_START,
946 ssl_config_.false_start_enabled &&
[email protected]4f4de7e62010-11-12 19:55:27947 !SSLConfigService::IsKnownFalseStartIncompatibleServer(
948 host_and_port_.host()));
[email protected]c2def1c2010-03-02 21:40:34949 if (rv != SECSuccess)
[email protected]7cbc6df12010-10-04 16:25:39950 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_FALSE_START");
[email protected]c2def1c2010-03-02 21:40:34951#endif
952
[email protected]7a8de3072010-10-01 16:25:54953#ifdef SSL_ENABLE_SNAP_START
954 // TODO(agl): check that SSL_ENABLE_SNAP_START actually does something in the
955 // current NSS code.
[email protected]4d52f192010-10-11 17:00:30956 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SNAP_START,
[email protected]09125792010-11-03 23:23:22957 ssl_config_.snap_start_enabled);
[email protected]7a8de3072010-10-01 16:25:54958 if (rv != SECSuccess)
[email protected]b30a3f52010-10-16 01:05:46959 VLOG(1) << "SSL_ENABLE_SNAP_START failed. Old system nss?";
[email protected]7a8de3072010-10-01 16:25:54960#endif
961
[email protected]33b3eb92010-01-06 01:35:04962#ifdef SSL_ENABLE_RENEGOTIATION
[email protected]304b0e352010-09-13 18:10:08963 // Deliberately disable this check for now: http://crbug.com/55410
964 if (false &&
[email protected]4f4de7e62010-11-12 19:55:27965 SSLConfigService::IsKnownStrictTLSServer(host_and_port_.host()) &&
[email protected]944a0a12010-08-19 20:02:28966 !ssl_config_.mitm_proxies_allowed) {
[email protected]d102f542010-06-30 14:51:05967 rv = SSL_OptionSet(nss_fd_, SSL_REQUIRE_SAFE_NEGOTIATION, PR_TRUE);
[email protected]7cbc6df12010-10-04 16:25:39968 if (rv != SECSuccess) {
969 LogFailedNSSFunction(
970 net_log_, "SSL_OptionSet", "SSL_REQUIRE_SAFE_NEGOTIATION");
971 }
[email protected]d102f542010-06-30 14:51:05972 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION,
973 SSL_RENEGOTIATE_REQUIRES_XTN);
974 } else {
975 // We allow servers to request renegotiation. Since we're a client,
976 // prohibiting this is rather a waste of time. Only servers are in a
977 // position to prevent renegotiation attacks.
978 // http://extendedsubset.com/?p=8
979
980 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION,
[email protected]e7bad86e2010-08-17 00:56:40981 SSL_RENEGOTIATE_TRANSITIONAL);
[email protected]d102f542010-06-30 14:51:05982 }
[email protected]7cbc6df12010-10-04 16:25:39983 if (rv != SECSuccess) {
984 LogFailedNSSFunction(
985 net_log_, "SSL_OptionSet", "SSL_ENABLE_RENEGOTIATION");
986 }
[email protected]d102f542010-06-30 14:51:05987#endif // SSL_ENABLE_RENEGOTIATION
[email protected]33b3eb92010-01-06 01:35:04988
[email protected]644bdca2009-11-30 20:40:53989#ifdef SSL_NEXT_PROTO_NEGOTIATED
990 if (!ssl_config_.next_protos.empty()) {
991 rv = SSL_SetNextProtoNego(
992 nss_fd_,
993 reinterpret_cast<const unsigned char *>(ssl_config_.next_protos.data()),
994 ssl_config_.next_protos.size());
995 if (rv != SECSuccess)
[email protected]7cbc6df12010-10-04 16:25:39996 LogFailedNSSFunction(net_log_, "SSL_SetNextProtoNego", "");
[email protected]644bdca2009-11-30 20:40:53997 }
998#endif
999
[email protected]71d6ccaa2011-01-06 17:43:211000#ifdef SSL_ENABLE_OCSP_STAPLING
[email protected]b92ead12011-01-19 15:29:091001 if (GetCacheOCSPResponseFromSideChannelFunction() &&
[email protected]71d6ccaa2011-01-06 17:43:211002 !ssl_config_.snap_start_enabled) {
1003 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE);
1004 if (rv != SECSuccess)
1005 LogFailedNSSFunction(net_log_, "SSL_OptionSet (OCSP stapling)", "");
1006 }
1007#endif
1008
[email protected]0ef0bcf2009-04-03 20:39:431009 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
[email protected]7cbc6df12010-10-04 16:25:391010 if (rv != SECSuccess) {
1011 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT");
1012 return ERR_UNEXPECTED;
1013 }
[email protected]0ef0bcf2009-04-03 20:39:431014
1015 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this);
[email protected]7cbc6df12010-10-04 16:25:391016 if (rv != SECSuccess) {
1017 LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", "");
1018 return ERR_UNEXPECTED;
1019 }
[email protected]0ef0bcf2009-04-03 20:39:431020
[email protected]4a842342010-11-04 16:21:331021#if defined(NSS_PLATFORM_CLIENT_AUTH)
1022 rv = SSL_GetPlatformClientAuthDataHook(nss_fd_, PlatformClientAuthHandler,
1023 this);
1024#else
[email protected]d84b3722009-10-15 21:23:371025 rv = SSL_GetClientAuthDataHook(nss_fd_, ClientAuthHandler, this);
[email protected]4a842342010-11-04 16:21:331026#endif
[email protected]7cbc6df12010-10-04 16:25:391027 if (rv != SECSuccess) {
1028 LogFailedNSSFunction(net_log_, "SSL_GetClientAuthDataHook", "");
1029 return ERR_UNEXPECTED;
1030 }
[email protected]d84b3722009-10-15 21:23:371031
[email protected]2345cc52009-06-04 09:18:471032 rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this);
[email protected]7cbc6df12010-10-04 16:25:391033 if (rv != SECSuccess) {
1034 LogFailedNSSFunction(net_log_, "SSL_HandshakeCallback", "");
[email protected]2345cc52009-06-04 09:18:471035 return ERR_UNEXPECTED;
[email protected]7cbc6df12010-10-04 16:25:391036 }
[email protected]0ef0bcf2009-04-03 20:39:431037
1038 // Tell SSL the hostname we're trying to connect to.
[email protected]4f4de7e62010-11-12 19:55:271039 SSL_SetURL(nss_fd_, host_and_port_.host().c_str());
[email protected]0ef0bcf2009-04-03 20:39:431040
[email protected]7f7e92392010-10-26 18:29:291041 // Tell SSL we're a client; needed if not letting NSPR do socket I/O
1042 SSL_ResetHandshake(nss_fd_, 0);
1043
1044 return OK;
1045}
1046
1047int SSLClientSocketNSS::InitializeSSLPeerName() {
1048 // Tell NSS who we're connected to
1049 AddressList peer_address;
1050 int err = transport_->socket()->GetPeerAddress(&peer_address);
1051 if (err != OK)
1052 return err;
1053
1054 const struct addrinfo* ai = peer_address.head();
1055
1056 PRNetAddr peername;
1057 memset(&peername, 0, sizeof(peername));
1058 DCHECK_LE(ai->ai_addrlen, sizeof(peername));
1059 size_t len = std::min(static_cast<size_t>(ai->ai_addrlen),
1060 sizeof(peername));
1061 memcpy(&peername, ai->ai_addr, len);
1062
1063 // Adjust the address family field for BSD, whose sockaddr
1064 // structure has a one-byte length and one-byte address family
1065 // field at the beginning. PRNetAddr has a two-byte address
1066 // family field at the beginning.
1067 peername.raw.family = ai->ai_addr->sa_family;
1068
1069 memio_SetPeerName(nss_fd_, &peername);
1070
[email protected]52c27fb2009-11-30 22:40:231071 // Set the peer ID for session reuse. This is necessary when we create an
1072 // SSL tunnel through a proxy -- GetPeerName returns the proxy's address
1073 // rather than the destination server's address in that case.
[email protected]4f4de7e62010-11-12 19:55:271074 std::string peer_id = host_and_port_.ToString();
[email protected]7f7e92392010-10-26 18:29:291075 SECStatus rv = SSL_SetSockPeerID(nss_fd_, const_cast<char*>(peer_id.c_str()));
[email protected]52c27fb2009-11-30 22:40:231076 if (rv != SECSuccess)
[email protected]7cbc6df12010-10-04 16:25:391077 LogFailedNSSFunction(net_log_, "SSL_SetSockPeerID", peer_id.c_str());
[email protected]52c27fb2009-11-30 22:40:231078
[email protected]7f7e92392010-10-26 18:29:291079 peername_initialized_ = true;
[email protected]5a05c47a2009-11-02 23:25:191080 return OK;
[email protected]b43c97c2008-10-22 19:50:581081}
1082
[email protected]2d6e77832010-11-10 22:13:461083
[email protected]757f2e2b2010-10-27 23:28:351084// Sets server_cert_ and server_cert_nss_ if not yet set.
1085// Returns server_cert_.
[email protected]bacff652009-03-31 17:50:331086X509Certificate *SSLClientSocketNSS::UpdateServerCert() {
[email protected]757f2e2b2010-10-27 23:28:351087 // We set the server_cert_ from HandshakeCallback().
[email protected]bacff652009-03-31 17:50:331088 if (server_cert_ == NULL) {
[email protected]f505a9b2010-01-28 19:44:021089 server_cert_nss_ = SSL_PeerCertificate(nss_fd_);
1090 if (server_cert_nss_) {
[email protected]4feca4b2010-10-28 16:50:321091 PeerCertificateChain certs(nss_fd_);
[email protected]d8fbf582010-11-04 21:51:121092 server_cert_ = X509Certificate::CreateFromDERCertChain(
1093 certs.AsStringPieceVector());
[email protected]bacff652009-03-31 17:50:331094 }
1095 }
1096 return server_cert_;
1097}
1098
[email protected]757f2e2b2010-10-27 23:28:351099// Sets ssl_connection_status_.
1100void SSLClientSocketNSS::UpdateConnectionStatus() {
1101 SSLChannelInfo channel_info;
1102 SECStatus ok = SSL_GetChannelInfo(nss_fd_,
1103 &channel_info, sizeof(channel_info));
1104 if (ok == SECSuccess &&
1105 channel_info.length == sizeof(channel_info) &&
1106 channel_info.cipherSuite) {
1107 ssl_connection_status_ |=
1108 (static_cast<int>(channel_info.cipherSuite) &
1109 SSL_CONNECTION_CIPHERSUITE_MASK) <<
1110 SSL_CONNECTION_CIPHERSUITE_SHIFT;
1111
1112 ssl_connection_status_ |=
1113 (static_cast<int>(channel_info.compressionMethod) &
1114 SSL_CONNECTION_COMPRESSION_MASK) <<
1115 SSL_CONNECTION_COMPRESSION_SHIFT;
1116
[email protected]b92a96e2010-11-02 21:03:051117 // NSS 3.12.x doesn't have version macros for TLS 1.1 and 1.2 (because NSS
1118 // doesn't support them yet), so we use 0x0302 and 0x0303 directly.
[email protected]757f2e2b2010-10-27 23:28:351119 int version = SSL_CONNECTION_VERSION_UNKNOWN;
1120 if (channel_info.protocolVersion < SSL_LIBRARY_VERSION_3_0) {
1121 // All versions less than SSL_LIBRARY_VERSION_3_0 are treated as SSL
1122 // version 2.
1123 version = SSL_CONNECTION_VERSION_SSL2;
1124 } else if (channel_info.protocolVersion == SSL_LIBRARY_VERSION_3_0) {
1125 version = SSL_CONNECTION_VERSION_SSL3;
1126 } else if (channel_info.protocolVersion == SSL_LIBRARY_VERSION_3_1_TLS) {
1127 version = SSL_CONNECTION_VERSION_TLS1;
[email protected]b92a96e2010-11-02 21:03:051128 } else if (channel_info.protocolVersion == 0x0302) {
1129 version = SSL_CONNECTION_VERSION_TLS1_1;
1130 } else if (channel_info.protocolVersion == 0x0303) {
1131 version = SSL_CONNECTION_VERSION_TLS1_2;
[email protected]757f2e2b2010-10-27 23:28:351132 }
1133 ssl_connection_status_ |=
1134 (version & SSL_CONNECTION_VERSION_MASK) <<
1135 SSL_CONNECTION_VERSION_SHIFT;
1136 }
1137
[email protected]1e7cd2c72010-02-27 01:31:191138 // SSL_HandshakeNegotiatedExtension was added in NSS 3.12.6.
1139 // Since SSL_MAX_EXTENSIONS was added at the same time, we can test
1140 // SSL_MAX_EXTENSIONS for the presence of SSL_HandshakeNegotiatedExtension.
1141#if defined(SSL_MAX_EXTENSIONS)
[email protected]757f2e2b2010-10-27 23:28:351142 PRBool peer_supports_renego_ext;
1143 ok = SSL_HandshakeNegotiatedExtension(nss_fd_, ssl_renegotiation_info_xtn,
1144 &peer_supports_renego_ext);
1145 if (ok == SECSuccess) {
1146 if (!peer_supports_renego_ext) {
1147 ssl_connection_status_ |= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION;
1148 // Log an informational message if the server does not support secure
1149 // renegotiation (RFC 5746).
[email protected]4f4de7e62010-11-12 19:55:271150 VLOG(1) << "The server " << host_and_port_.ToString()
[email protected]757f2e2b2010-10-27 23:28:351151 << " does not support the TLS renegotiation_info extension.";
1152 }
1153 UMA_HISTOGRAM_ENUMERATION("Net.RenegotiationExtensionSupported",
1154 peer_supports_renego_ext, 2);
[email protected]1e7cd2c72010-02-27 01:31:191155 }
1156#endif
[email protected]757f2e2b2010-10-27 23:28:351157
1158 if (ssl_config_.ssl3_fallback)
1159 ssl_connection_status_ |= SSL_CONNECTION_SSL3_FALLBACK;
[email protected]1e7cd2c72010-02-27 01:31:191160}
1161
[email protected]a3ff5e92009-10-13 04:48:061162void SSLClientSocketNSS::DoReadCallback(int rv) {
[email protected]e17b4c12008-11-05 22:04:081163 EnterFunction(rv);
[email protected]b43c97c2008-10-22 19:50:581164 DCHECK(rv != ERR_IO_PENDING);
[email protected]a3ff5e92009-10-13 04:48:061165 DCHECK(user_read_callback_);
[email protected]b43c97c2008-10-22 19:50:581166
[email protected]a3ff5e92009-10-13 04:48:061167 // Since Run may result in Read being called, clear |user_read_callback_|
1168 // up front.
1169 CompletionCallback* c = user_read_callback_;
1170 user_read_callback_ = NULL;
1171 user_read_buf_ = NULL;
1172 user_read_buf_len_ = 0;
1173 c->Run(rv);
1174 LeaveFunction("");
1175}
1176
1177void SSLClientSocketNSS::DoWriteCallback(int rv) {
1178 EnterFunction(rv);
1179 DCHECK(rv != ERR_IO_PENDING);
1180 DCHECK(user_write_callback_);
1181
1182 // Since Run may result in Write being called, clear |user_write_callback_|
1183 // up front.
1184 CompletionCallback* c = user_write_callback_;
1185 user_write_callback_ = NULL;
1186 user_write_buf_ = NULL;
1187 user_write_buf_len_ = 0;
[email protected]b43c97c2008-10-22 19:50:581188 c->Run(rv);
[email protected]e17b4c12008-11-05 22:04:081189 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:581190}
1191
[email protected]a6eb576292009-06-30 16:19:001192// As part of Connect(), the SSLClientSocketNSS object performs an SSL
1193// handshake. This requires network IO, which in turn calls
1194// BufferRecvComplete() with a non-zero byte count. This byte count eventually
1195// winds its way through the state machine and ends up being passed to the
1196// callback. For Read() and Write(), that's what we want. But for Connect(),
1197// the caller expects OK (i.e. 0) for success.
1198//
1199void SSLClientSocketNSS::DoConnectCallback(int rv) {
1200 EnterFunction(rv);
1201 DCHECK_NE(rv, ERR_IO_PENDING);
[email protected]a6eb576292009-06-30 16:19:001202
[email protected]a6eb576292009-06-30 16:19:001203 CompletionCallback* c = user_connect_callback_;
1204 user_connect_callback_ = NULL;
1205 c->Run(rv > OK ? OK : rv);
1206 LeaveFunction("");
1207}
1208
[email protected]a3ff5e92009-10-13 04:48:061209void SSLClientSocketNSS::OnHandshakeIOComplete(int result) {
[email protected]e17b4c12008-11-05 22:04:081210 EnterFunction(result);
[email protected]a3ff5e92009-10-13 04:48:061211 int rv = DoHandshakeLoop(result);
[email protected]5a05c47a2009-11-02 23:25:191212 if (rv != ERR_IO_PENDING) {
[email protected]ec11be62010-04-28 19:28:091213 net_log_.EndEvent(net::NetLog::TYPE_SSL_CONNECT, NULL);
[email protected]7a8de3072010-10-01 16:25:541214 // If we pseudo connected for Snap Start, then we won't have a connect
1215 // callback.
1216 if (user_connect_callback_)
1217 DoConnectCallback(rv);
[email protected]5a05c47a2009-11-02 23:25:191218 }
[email protected]a3ff5e92009-10-13 04:48:061219 LeaveFunction("");
1220}
1221
1222void SSLClientSocketNSS::OnSendComplete(int result) {
1223 EnterFunction(result);
[email protected]45965de2010-02-25 23:23:311224 if (next_handshake_state_ == STATE_HANDSHAKE) {
[email protected]a3ff5e92009-10-13 04:48:061225 // In handshake phase.
1226 OnHandshakeIOComplete(result);
1227 LeaveFunction("");
1228 return;
[email protected]a6eb576292009-06-30 16:19:001229 }
[email protected]a3ff5e92009-10-13 04:48:061230
1231 // OnSendComplete may need to call DoPayloadRead while the renegotiation
1232 // handshake is in progress.
1233 int rv_read = ERR_IO_PENDING;
1234 int rv_write = ERR_IO_PENDING;
1235 bool network_moved;
1236 do {
1237 if (user_read_buf_)
1238 rv_read = DoPayloadRead();
1239 if (user_write_buf_)
1240 rv_write = DoPayloadWrite();
1241 network_moved = DoTransportIO();
1242 } while (rv_read == ERR_IO_PENDING &&
1243 rv_write == ERR_IO_PENDING &&
1244 network_moved);
1245
1246 if (user_read_buf_ && rv_read != ERR_IO_PENDING)
1247 DoReadCallback(rv_read);
1248 if (user_write_buf_ && rv_write != ERR_IO_PENDING)
1249 DoWriteCallback(rv_write);
1250
1251 LeaveFunction("");
1252}
1253
1254void SSLClientSocketNSS::OnRecvComplete(int result) {
1255 EnterFunction(result);
[email protected]45965de2010-02-25 23:23:311256 if (next_handshake_state_ == STATE_HANDSHAKE) {
[email protected]a3ff5e92009-10-13 04:48:061257 // In handshake phase.
1258 OnHandshakeIOComplete(result);
1259 LeaveFunction("");
1260 return;
1261 }
1262
1263 // Network layer received some data, check if client requested to read
[email protected]7a8de3072010-10-01 16:25:541264 // decrypted data or if we're waiting for the first write for Snap Start.
1265 if (!user_read_buf_ || !completed_handshake_) {
[email protected]a3ff5e92009-10-13 04:48:061266 LeaveFunction("");
1267 return;
1268 }
1269
1270 int rv = DoReadLoop(result);
1271 if (rv != ERR_IO_PENDING)
1272 DoReadCallback(rv);
[email protected]e17b4c12008-11-05 22:04:081273 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:581274}
1275
[email protected]a3ff5e92009-10-13 04:48:061276int SSLClientSocketNSS::DoHandshakeLoop(int last_io_result) {
[email protected]e17b4c12008-11-05 22:04:081277 EnterFunction(last_io_result);
[email protected]b43c97c2008-10-22 19:50:581278 bool network_moved;
1279 int rv = last_io_result;
1280 do {
[email protected]e17b4c12008-11-05 22:04:081281 // Default to STATE_NONE for next state.
[email protected]ea224582008-12-07 20:25:461282 // (This is a quirk carried over from the windows
[email protected]e17b4c12008-11-05 22:04:081283 // implementation. It makes reading the logs a bit harder.)
[email protected]ea224582008-12-07 20:25:461284 // State handlers can and often do call GotoState just
[email protected]e17b4c12008-11-05 22:04:081285 // to stay in the current state.
[email protected]a3ff5e92009-10-13 04:48:061286 State state = next_handshake_state_;
[email protected]e17b4c12008-11-05 22:04:081287 GotoState(STATE_NONE);
[email protected]b43c97c2008-10-22 19:50:581288 switch (state) {
[email protected]e17b4c12008-11-05 22:04:081289 case STATE_NONE:
1290 // we're just pumping data between the buffer and the network
1291 break;
[email protected]7a8de3072010-10-01 16:25:541292 case STATE_SNAP_START_LOAD_INFO:
1293 rv = DoSnapStartLoadInfo();
1294 break;
1295 case STATE_SNAP_START_WAIT_FOR_WRITE:
1296 rv = DoSnapStartWaitForWrite();
1297 break;
[email protected]a3ff5e92009-10-13 04:48:061298 case STATE_HANDSHAKE:
1299 rv = DoHandshake();
[email protected]b43c97c2008-10-22 19:50:581300 break;
[email protected]899c3e92010-08-28 15:53:501301 case STATE_VERIFY_DNSSEC:
1302 rv = DoVerifyDNSSEC(rv);
1303 break;
1304 case STATE_VERIFY_DNSSEC_COMPLETE:
1305 rv = DoVerifyDNSSECComplete(rv);
1306 break;
[email protected]2345cc52009-06-04 09:18:471307 case STATE_VERIFY_CERT:
1308 DCHECK(rv == OK);
1309 rv = DoVerifyCert(rv);
1310 break;
1311 case STATE_VERIFY_CERT_COMPLETE:
1312 rv = DoVerifyCertComplete(rv);
1313 break;
[email protected]b43c97c2008-10-22 19:50:581314 default:
1315 rv = ERR_UNEXPECTED;
[email protected]4e91b5c2010-09-22 01:04:381316 LOG(DFATAL) << "unexpected state " << state;
[email protected]b43c97c2008-10-22 19:50:581317 break;
1318 }
1319
1320 // Do the actual network I/O
[email protected]a3ff5e92009-10-13 04:48:061321 network_moved = DoTransportIO();
[email protected]72d1e592009-03-10 17:39:461322 } while ((rv != ERR_IO_PENDING || network_moved) &&
[email protected]7a8de3072010-10-01 16:25:541323 next_handshake_state_ != STATE_NONE);
[email protected]a3ff5e92009-10-13 04:48:061324 LeaveFunction("");
1325 return rv;
1326}
1327
1328int SSLClientSocketNSS::DoReadLoop(int result) {
1329 EnterFunction("");
1330 DCHECK(completed_handshake_);
1331 DCHECK(next_handshake_state_ == STATE_NONE);
1332
1333 if (result < 0)
1334 return result;
1335
[email protected]4e91b5c2010-09-22 01:04:381336 if (!nss_bufs_) {
1337 LOG(DFATAL) << "!nss_bufs_";
[email protected]7cbc6df12010-10-04 16:25:391338 int rv = ERR_UNEXPECTED;
[email protected]00cd9c42010-11-02 20:15:571339 net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR,
1340 make_scoped_refptr(new SSLErrorParams(rv, 0)));
[email protected]7cbc6df12010-10-04 16:25:391341 return rv;
[email protected]4e91b5c2010-09-22 01:04:381342 }
[email protected]a3ff5e92009-10-13 04:48:061343
1344 bool network_moved;
1345 int rv;
1346 do {
1347 rv = DoPayloadRead();
1348 network_moved = DoTransportIO();
1349 } while (rv == ERR_IO_PENDING && network_moved);
1350
1351 LeaveFunction("");
1352 return rv;
1353}
1354
1355int SSLClientSocketNSS::DoWriteLoop(int result) {
1356 EnterFunction("");
1357 DCHECK(completed_handshake_);
1358 DCHECK(next_handshake_state_ == STATE_NONE);
1359
1360 if (result < 0)
1361 return result;
1362
[email protected]4e91b5c2010-09-22 01:04:381363 if (!nss_bufs_) {
1364 LOG(DFATAL) << "!nss_bufs_";
[email protected]7cbc6df12010-10-04 16:25:391365 int rv = ERR_UNEXPECTED;
[email protected]00cd9c42010-11-02 20:15:571366 net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR,
1367 make_scoped_refptr(new SSLErrorParams(rv, 0)));
[email protected]7cbc6df12010-10-04 16:25:391368 return rv;
[email protected]4e91b5c2010-09-22 01:04:381369 }
[email protected]a3ff5e92009-10-13 04:48:061370
1371 bool network_moved;
1372 int rv;
1373 do {
1374 rv = DoPayloadWrite();
1375 network_moved = DoTransportIO();
1376 } while (rv == ERR_IO_PENDING && network_moved);
1377
[email protected]e17b4c12008-11-05 22:04:081378 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:581379 return rv;
1380}
1381
[email protected]d100e44f2011-01-26 22:47:111382int SSLClientSocketNSS::DoSnapStartLoadInfo() {
1383 EnterFunction("");
1384 int rv = ssl_host_info_->WaitForDataReady(&handshake_io_callback_);
1385 GotoState(STATE_HANDSHAKE);
1386
1387 if (rv == OK) {
1388 if (ssl_host_info_->WaitForCertVerification(NULL) == OK) {
1389 if (LoadSnapStartInfo()) {
1390 pseudo_connected_ = true;
1391 GotoState(STATE_SNAP_START_WAIT_FOR_WRITE);
1392 if (user_connect_callback_)
1393 DoConnectCallback(OK);
1394 }
1395 } else if (!ssl_host_info_->state().server_hello.empty()) {
1396 // A non-empty ServerHello suggests that we would have tried a Snap Start
1397 // connection.
1398 base::TimeTicks now = base::TimeTicks::Now();
1399 const base::TimeDelta duration =
1400 now - ssl_host_info_->verification_start_time();
1401 UMA_HISTOGRAM_TIMES("Net.SSLSnapStartNeededVerificationInMs", duration);
1402 VLOG(1) << "Cannot snap start because verification isn't ready. "
1403 << "Wanted verification after "
1404 << duration.InMilliseconds() << "ms";
1405 }
1406 } else {
1407 DCHECK_EQ(ERR_IO_PENDING, rv);
1408 GotoState(STATE_SNAP_START_LOAD_INFO);
1409 }
1410
1411 LeaveFunction("");
1412 return rv;
1413}
1414
1415int SSLClientSocketNSS::DoSnapStartWaitForWrite() {
1416 EnterFunction("");
1417 // In this state, we're waiting for the first Write call so that we can merge
1418 // it into the Snap Start handshake.
1419 if (!user_write_buf_) {
1420 // We'll lie and say that we're connected in order that someone will call
1421 // Write.
1422 GotoState(STATE_SNAP_START_WAIT_FOR_WRITE);
1423 DCHECK(!user_connect_callback_);
1424 LeaveFunction("");
1425 return ERR_IO_PENDING;
1426 }
1427
1428 // This is the largest Snap Start application data payload that we'll try to
1429 // use. A TCP client can only send three frames of data without an ACK and,
1430 // at 2048 bytes, this leaves some space for the rest of the ClientHello
1431 // (including possible session ticket).
1432 static const int kMaxSnapStartPayloadSize = 2048;
1433
1434 if (user_write_buf_len_ > kMaxSnapStartPayloadSize) {
1435 user_write_buf_len_ = kMaxSnapStartPayloadSize;
1436 // When we complete the handshake and call user_write_callback_ we'll say
1437 // that we only wrote |kMaxSnapStartPayloadSize| bytes. That way the rest
1438 // of the payload will be presented to |Write| again and transmitted as
1439 // normal application data.
1440 }
1441
1442 SECStatus rv = SSL_SetSnapStartApplicationData(
1443 nss_fd_, reinterpret_cast<const unsigned char*>(user_write_buf_->data()),
1444 user_write_buf_len_);
1445 DCHECK_EQ(SECSuccess, rv);
1446
1447 GotoState(STATE_HANDSHAKE);
1448 LeaveFunction("");
1449 return OK;
1450}
1451
1452int SSLClientSocketNSS::DoHandshake() {
1453 EnterFunction("");
1454 int net_error = net::OK;
1455 SECStatus rv = SSL_ForceHandshake(nss_fd_);
1456
1457 if (client_auth_cert_needed_) {
1458 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
1459 net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR,
1460 make_scoped_refptr(new SSLErrorParams(net_error, 0)));
1461 // If the handshake already succeeded (because the server requests but
1462 // doesn't require a client cert), we need to invalidate the SSL session
1463 // so that we won't try to resume the non-client-authenticated session in
1464 // the next handshake. This will cause the server to ask for a client
1465 // cert again.
1466 if (rv == SECSuccess && SSL_InvalidateSession(nss_fd_) != SECSuccess) {
1467 LOG(WARNING) << "Couldn't invalidate SSL session: " << PR_GetError();
1468 }
1469 } else if (rv == SECSuccess) {
1470 if (handshake_callback_called_) {
1471 if (eset_mitm_detected_) {
1472 net_error = ERR_ESET_ANTI_VIRUS_SSL_INTERCEPTION;
1473 } else {
1474 // We need to see if the predicted certificate chain (in
1475 // |ssl_host_info_->state().certs) matches the actual certificate chain
1476 // before we call SaveSnapStartInfo, as that will update
1477 // |ssl_host_info_|.
1478 if (ssl_host_info_.get() && !ssl_host_info_->state().certs.empty()) {
1479 PeerCertificateChain certs(nss_fd_);
1480 const SSLHostInfo::State& state = ssl_host_info_->state();
1481 predicted_cert_chain_correct_ = certs.size() == state.certs.size();
1482 if (predicted_cert_chain_correct_) {
1483 for (unsigned i = 0; i < certs.size(); i++) {
1484 if (certs[i]->derCert.len != state.certs[i].size() ||
1485 memcmp(certs[i]->derCert.data, state.certs[i].data(),
1486 certs[i]->derCert.len) != 0) {
1487 predicted_cert_chain_correct_ = false;
1488 break;
1489 }
1490 }
1491 }
1492 }
1493
1494#if defined(SSL_ENABLE_OCSP_STAPLING)
1495 const CacheOCSPResponseFromSideChannelFunction cache_ocsp_response =
1496 GetCacheOCSPResponseFromSideChannelFunction();
1497 // TODO: we need to be able to plumb an OCSP response into the system
1498 // libraries. When we do, GetOCSPResponseFromSideChannelFunction
1499 // needs to be updated for those platforms.
1500 if (!predicted_cert_chain_correct_ && cache_ocsp_response) {
1501 unsigned int len = 0;
1502 SSL_GetStapledOCSPResponse(nss_fd_, NULL, &len);
1503 if (len) {
1504 const unsigned int orig_len = len;
1505 scoped_array<uint8> ocsp_response(new uint8[orig_len]);
1506 SSL_GetStapledOCSPResponse(nss_fd_, ocsp_response.get(), &len);
1507 DCHECK_EQ(orig_len, len);
1508
1509 SECItem ocsp_response_item;
1510 ocsp_response_item.type = siBuffer;
1511 ocsp_response_item.data = ocsp_response.get();
1512 ocsp_response_item.len = len;
1513
1514 cache_ocsp_response(
1515 CERT_GetDefaultCertDB(), server_cert_nss_, PR_Now(),
1516 &ocsp_response_item, NULL);
1517 }
1518 }
1519#endif
1520
1521 SaveSnapStartInfo();
1522 // SSL handshake is completed. It's possible that we mispredicted the
1523 // NPN agreed protocol. In this case, we've just sent a request in the
1524 // wrong protocol! The higher levels of this network stack aren't
1525 // prepared for switching the protocol like that so we make up an error
1526 // and rely on the fact that the request will be retried.
1527 if (IsNPNProtocolMispredicted()) {
1528 LOG(WARNING) << "Mispredicted NPN protocol for "
1529 << host_and_port_.ToString();
1530 net_error = ERR_SSL_SNAP_START_NPN_MISPREDICTION;
1531 } else {
1532 // Let's verify the certificate.
1533 GotoState(STATE_VERIFY_DNSSEC);
1534 }
1535 }
1536 // Done!
1537 } else {
1538 // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=562434 -
1539 // SSL_ForceHandshake returned SECSuccess prematurely.
1540 rv = SECFailure;
1541 net_error = ERR_SSL_PROTOCOL_ERROR;
1542 net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR,
1543 make_scoped_refptr(new SSLErrorParams(net_error, 0)));
1544 }
1545 } else {
1546 PRErrorCode prerr = PR_GetError();
1547 net_error = MapNSSHandshakeError(prerr);
1548
1549 // If not done, stay in this state
1550 if (net_error == ERR_IO_PENDING) {
1551 GotoState(STATE_HANDSHAKE);
1552 } else {
1553 LOG(ERROR) << "handshake failed; NSS error code " << prerr
1554 << ", net_error " << net_error;
1555 net_log_.AddEvent(
1556 NetLog::TYPE_SSL_HANDSHAKE_ERROR,
1557 make_scoped_refptr(new SSLErrorParams(net_error, prerr)));
1558 }
1559 }
1560
1561 LeaveFunction("");
1562 return net_error;
1563}
1564
1565int SSLClientSocketNSS::DoVerifyDNSSEC(int result) {
1566 if (ssl_config_.dns_cert_provenance_checking_enabled &&
1567 dns_cert_checker_) {
1568 PeerCertificateChain certs(nss_fd_);
1569 dns_cert_checker_->DoAsyncVerification(
1570 host_and_port_.host(), certs.AsStringPieceVector());
1571 }
1572
1573 if (ssl_config_.dnssec_enabled) {
1574 DNSValidationResult r = CheckDNSSECChain(host_and_port_.host(),
1575 server_cert_nss_);
1576 if (r == DNSVR_SUCCESS) {
1577 local_server_cert_verify_result_.cert_status |= CERT_STATUS_IS_DNSSEC;
1578 server_cert_verify_result_ = &local_server_cert_verify_result_;
1579 GotoState(STATE_VERIFY_CERT_COMPLETE);
1580 return OK;
1581 }
1582 }
1583
1584 if (dnssec_provider_ == NULL) {
1585 GotoState(STATE_VERIFY_CERT);
1586 return OK;
1587 }
1588
1589 GotoState(STATE_VERIFY_DNSSEC_COMPLETE);
1590 RRResponse* response;
1591 dnssec_wait_start_time_ = base::Time::Now();
1592 return dnssec_provider_->GetDNSSECRecords(&response, &handshake_io_callback_);
1593}
1594
1595int SSLClientSocketNSS::DoVerifyDNSSECComplete(int result) {
1596 RRResponse* response;
1597 int err = dnssec_provider_->GetDNSSECRecords(&response, NULL);
1598 DCHECK_EQ(err, OK);
1599
1600 const base::TimeDelta elapsed = base::Time::Now() - dnssec_wait_start_time_;
1601 HISTOGRAM_TIMES("Net.DNSSECWaitTime", elapsed);
1602
1603 GotoState(STATE_VERIFY_CERT);
1604 if (!response || response->rrdatas.empty())
1605 return OK;
1606
1607 std::vector<base::StringPiece> records;
1608 records.resize(response->rrdatas.size());
1609 for (unsigned i = 0; i < response->rrdatas.size(); i++)
1610 records[i] = base::StringPiece(response->rrdatas[i]);
1611 DNSValidationResult r =
1612 VerifyTXTRecords(response->dnssec, server_cert_nss_, records);
1613
1614 if (!ssl_config_.dnssec_enabled) {
1615 // If DNSSEC is not enabled we don't take any action based on the result,
1616 // except to record the latency, above.
1617 return OK;
1618 }
1619
1620 switch (r) {
1621 case DNSVR_FAILURE:
1622 GotoState(STATE_VERIFY_CERT_COMPLETE);
1623 local_server_cert_verify_result_.cert_status |= CERT_STATUS_NOT_IN_DNS;
1624 server_cert_verify_result_ = &local_server_cert_verify_result_;
1625 return ERR_CERT_NOT_IN_DNS;
1626 case DNSVR_CONTINUE:
1627 GotoState(STATE_VERIFY_CERT);
1628 break;
1629 case DNSVR_SUCCESS:
1630 local_server_cert_verify_result_.cert_status |= CERT_STATUS_IS_DNSSEC;
1631 server_cert_verify_result_ = &local_server_cert_verify_result_;
1632 GotoState(STATE_VERIFY_CERT_COMPLETE);
1633 break;
1634 default:
1635 NOTREACHED();
1636 GotoState(STATE_VERIFY_CERT);
1637 }
1638
1639 return OK;
1640}
1641
1642int SSLClientSocketNSS::DoVerifyCert(int result) {
1643 DCHECK(server_cert_);
1644
1645 GotoState(STATE_VERIFY_CERT_COMPLETE);
1646 start_cert_verification_time_ = base::TimeTicks::Now();
1647
1648 if (ssl_host_info_.get() && !ssl_host_info_->state().certs.empty() &&
1649 predicted_cert_chain_correct_) {
1650 // If the SSLHostInfo had a prediction for the certificate chain of this
1651 // server then it will have optimistically started a verification of that
1652 // chain. So, if the prediction was correct, we should wait for that
1653 // verification to finish rather than start our own.
1654 net_log_.AddEvent(NetLog::TYPE_SSL_VERIFICATION_MERGED, NULL);
1655 UMA_HISTOGRAM_ENUMERATION("Net.SSLVerificationMerged", 1 /* true */, 2);
1656 base::TimeTicks end_time = ssl_host_info_->verification_end_time();
1657 if (end_time.is_null())
1658 end_time = base::TimeTicks::Now();
1659 UMA_HISTOGRAM_TIMES("Net.SSLVerificationMergedMsSaved",
1660 end_time - ssl_host_info_->verification_start_time());
1661 server_cert_verify_result_ = &ssl_host_info_->cert_verify_result();
1662 return ssl_host_info_->WaitForCertVerification(&handshake_io_callback_);
1663 } else {
1664 UMA_HISTOGRAM_ENUMERATION("Net.SSLVerificationMerged", 0 /* false */, 2);
1665 }
1666
1667 int flags = 0;
1668 if (ssl_config_.rev_checking_enabled)
1669 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED;
1670 if (ssl_config_.verify_ev_cert)
1671 flags |= X509Certificate::VERIFY_EV_CERT;
1672 verifier_.reset(new SingleRequestCertVerifier(cert_verifier_));
1673 server_cert_verify_result_ = &local_server_cert_verify_result_;
1674 return verifier_->Verify(server_cert_, host_and_port_.host(), flags,
1675 &local_server_cert_verify_result_,
1676 &handshake_io_callback_);
1677}
1678
1679// Derived from AuthCertificateCallback() in
1680// mozilla/source/security/manager/ssl/src/nsNSSCallbacks.cpp.
1681int SSLClientSocketNSS::DoVerifyCertComplete(int result) {
1682 verifier_.reset();
1683
1684 if (!start_cert_verification_time_.is_null()) {
1685 base::TimeDelta verify_time =
1686 base::TimeTicks::Now() - start_cert_verification_time_;
1687 if (result == OK)
1688 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTime", verify_time);
1689 else
1690 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTimeError", verify_time);
1691 }
1692
[email protected]d100e44f2011-01-26 22:47:111693 // We used to remember the intermediate CA certs in the NSS database
1694 // persistently. However, NSS opens a connection to the SQLite database
1695 // during NSS initialization and doesn't close the connection until NSS
1696 // shuts down. If the file system where the database resides is gone,
1697 // the database connection goes bad. What's worse, the connection won't
1698 // recover when the file system comes back. Until this NSS or SQLite bug
1699 // is fixed, we need to avoid using the NSS database for non-essential
1700 // purposes. See https://bugzilla.mozilla.org/show_bug.cgi?id=508081 and
1701 // http://crbug.com/15630 for more info.
1702
1703 // If we have been explicitly told to accept this certificate, override the
1704 // result of verifier_.Verify.
1705 // Eventually, we should cache the cert verification results so that we don't
1706 // need to call verifier_.Verify repeatedly. But for now we need to do this.
1707 // Alternatively, we could use the cert's status that we stored along with
1708 // the cert in the allowed_bad_certs vector.
1709 if (IsCertificateError(result) &&
1710 ssl_config_.IsAllowedBadCert(server_cert_)) {
1711 VLOG(1) << "accepting bad SSL certificate, as user told us to";
1712 result = OK;
1713 }
1714
1715 if (result == OK)
1716 LogConnectionTypeMetrics();
1717
1718 completed_handshake_ = true;
1719
1720 // If we merged a Write call into the handshake we need to make the
1721 // callback now.
1722 if (user_write_callback_) {
1723 corked_ = false;
1724 if (result != OK) {
1725 DoWriteCallback(result);
1726 } else {
1727 SSLSnapStartResult snap_start_type;
1728 SECStatus rv = SSL_GetSnapStartResult(nss_fd_, &snap_start_type);
1729 DCHECK_EQ(rv, SECSuccess);
1730 DCHECK_NE(snap_start_type, SSL_SNAP_START_NONE);
1731 if (snap_start_type == SSL_SNAP_START_RECOVERY ||
1732 snap_start_type == SSL_SNAP_START_RESUME_RECOVERY) {
1733 // If we mispredicted the server's handshake then Snap Start will have
1734 // triggered a recovery mode. The misprediction could have been caused
1735 // by the server having a different certificate so the application data
1736 // wasn't resent. Now that we have verified the certificate, we need to
1737 // resend the application data.
1738 int bytes_written = DoPayloadWrite();
1739 if (bytes_written != ERR_IO_PENDING)
1740 DoWriteCallback(bytes_written);
1741 } else {
1742 DoWriteCallback(user_write_buf_len_);
1743 }
1744 }
1745 }
1746
1747 if (user_read_callback_) {
1748 int rv = DoReadLoop(OK);
1749 if (rv != ERR_IO_PENDING)
1750 DoReadCallback(rv);
1751 }
1752
1753 // Exit DoHandshakeLoop and return the result to the caller to Connect.
1754 DCHECK(next_handshake_state_ == STATE_NONE);
1755 return result;
1756}
1757
1758int SSLClientSocketNSS::DoPayloadRead() {
1759 EnterFunction(user_read_buf_len_);
1760 DCHECK(user_read_buf_);
1761 DCHECK_GT(user_read_buf_len_, 0);
1762 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_);
1763 if (client_auth_cert_needed_) {
1764 // We don't need to invalidate the non-client-authenticated SSL session
1765 // because the server will renegotiate anyway.
1766 LeaveFunction("");
1767 rv = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
1768 net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR,
1769 make_scoped_refptr(new SSLErrorParams(rv, 0)));
1770 return rv;
1771 }
1772 if (rv >= 0) {
1773 LogData(user_read_buf_->data(), rv);
1774 LeaveFunction("");
1775 return rv;
1776 }
1777 PRErrorCode prerr = PR_GetError();
1778 if (prerr == PR_WOULD_BLOCK_ERROR) {
1779 LeaveFunction("");
1780 return ERR_IO_PENDING;
1781 }
1782 LeaveFunction("");
1783 rv = MapNSSError(prerr);
1784 net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR,
1785 make_scoped_refptr(new SSLErrorParams(rv, prerr)));
1786 return rv;
1787}
1788
1789int SSLClientSocketNSS::DoPayloadWrite() {
1790 EnterFunction(user_write_buf_len_);
1791 DCHECK(user_write_buf_);
1792 int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_);
1793 if (rv >= 0) {
1794 LogData(user_write_buf_->data(), rv);
1795 LeaveFunction("");
1796 return rv;
1797 }
1798 PRErrorCode prerr = PR_GetError();
1799 if (prerr == PR_WOULD_BLOCK_ERROR) {
1800 LeaveFunction("");
1801 return ERR_IO_PENDING;
1802 }
1803 LeaveFunction("");
1804 rv = MapNSSError(prerr);
1805 net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR,
1806 make_scoped_refptr(new SSLErrorParams(rv, prerr)));
1807 return rv;
1808}
1809
1810void SSLClientSocketNSS::LogConnectionTypeMetrics() const {
1811 UpdateConnectionTypeHistograms(CONNECTION_SSL);
1812 if (server_cert_verify_result_->has_md5)
1813 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5);
1814 if (server_cert_verify_result_->has_md2)
1815 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2);
1816 if (server_cert_verify_result_->has_md4)
1817 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD4);
1818 if (server_cert_verify_result_->has_md5_ca)
1819 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5_CA);
1820 if (server_cert_verify_result_->has_md2_ca)
1821 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2_CA);
1822 int ssl_version = SSLConnectionStatusToVersion(ssl_connection_status_);
1823 switch (ssl_version) {
1824 case SSL_CONNECTION_VERSION_SSL2:
1825 UpdateConnectionTypeHistograms(CONNECTION_SSL_SSL2);
1826 break;
1827 case SSL_CONNECTION_VERSION_SSL3:
1828 UpdateConnectionTypeHistograms(CONNECTION_SSL_SSL3);
1829 break;
1830 case SSL_CONNECTION_VERSION_TLS1:
1831 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1);
1832 break;
1833 case SSL_CONNECTION_VERSION_TLS1_1:
1834 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_1);
1835 break;
1836 case SSL_CONNECTION_VERSION_TLS1_2:
1837 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_2);
1838 break;
1839 };
1840}
1841
1842// SaveSnapStartInfo extracts the information needed to perform a Snap Start
1843// with this server in the future (if any) and tells |ssl_host_info_| to
1844// preserve it.
1845void SSLClientSocketNSS::SaveSnapStartInfo() {
1846 if (!ssl_host_info_.get())
1847 return;
1848
1849 // If the SSLHostInfo hasn't managed to load from disk yet then we can't save
1850 // anything.
1851 if (ssl_host_info_->WaitForDataReady(NULL) != OK)
1852 return;
1853
1854 SECStatus rv;
1855 SSLSnapStartResult snap_start_type;
1856 rv = SSL_GetSnapStartResult(nss_fd_, &snap_start_type);
1857 if (rv != SECSuccess) {
1858 NOTREACHED();
1859 return;
1860 }
1861 net_log_.AddEvent(NetLog::TYPE_SSL_SNAP_START,
1862 new NetLogIntegerParameter("type", snap_start_type));
1863 if (snap_start_type == SSL_SNAP_START_FULL ||
1864 snap_start_type == SSL_SNAP_START_RESUME) {
1865 // If we did a successful Snap Start then our information was correct and
1866 // there's no point saving it again.
1867 return;
1868 }
1869
1870 const unsigned char* hello_data;
1871 unsigned hello_data_len;
1872 rv = SSL_GetPredictedServerHelloData(nss_fd_, &hello_data, &hello_data_len);
1873 if (rv != SECSuccess) {
1874 NOTREACHED();
1875 return;
1876 }
1877 if (hello_data_len > std::numeric_limits<uint16>::max())
1878 return;
1879 SSLHostInfo::State* state = ssl_host_info_->mutable_state();
1880
1881 if (hello_data_len > 0) {
1882 state->server_hello =
1883 std::string(reinterpret_cast<const char *>(hello_data), hello_data_len);
1884 state->npn_valid = true;
1885 state->npn_status = GetNextProto(&state->npn_protocol);
1886 } else {
1887 state->server_hello.clear();
1888 state->npn_valid = false;
1889 }
1890
1891 state->certs.clear();
1892 PeerCertificateChain certs(nss_fd_);
1893 for (unsigned i = 0; i < certs.size(); i++) {
1894 if (certs[i]->derCert.len > std::numeric_limits<uint16>::max())
1895 return;
1896
1897 state->certs.push_back(std::string(
1898 reinterpret_cast<char*>(certs[i]->derCert.data),
1899 certs[i]->derCert.len));
1900 }
1901
1902 ssl_host_info_->Persist();
1903}
1904
1905// LoadSnapStartInfo parses |info|, which contains data previously serialised
1906// by |SaveSnapStartInfo|, and sets the predicted certificates and ServerHello
1907// data on the NSS socket. Returns true on success. If this function returns
1908// false, the caller should try a normal TLS handshake.
1909bool SSLClientSocketNSS::LoadSnapStartInfo() {
1910 const SSLHostInfo::State& state(ssl_host_info_->state());
1911
1912 if (state.server_hello.empty() ||
1913 state.certs.empty() ||
1914 !state.npn_valid) {
1915 return false;
1916 }
1917
1918 SECStatus rv;
1919 rv = SSL_SetPredictedServerHelloData(
1920 nss_fd_,
1921 reinterpret_cast<const uint8*>(state.server_hello.data()),
1922 state.server_hello.size());
1923 DCHECK_EQ(SECSuccess, rv);
1924
1925 const std::vector<std::string>& certs_in = state.certs;
1926 scoped_array<CERTCertificate*> certs(new CERTCertificate*[certs_in.size()]);
1927 for (size_t i = 0; i < certs_in.size(); i++) {
1928 SECItem derCert;
1929 derCert.data =
1930 const_cast<uint8*>(reinterpret_cast<const uint8*>(certs_in[i].data()));
1931 derCert.len = certs_in[i].size();
1932 certs[i] = CERT_NewTempCertificate(
1933 CERT_GetDefaultCertDB(), &derCert, NULL /* no nickname given */,
1934 PR_FALSE /* not permanent */, PR_TRUE /* copy DER data */);
1935 if (!certs[i]) {
1936 DestroyCertificates(&certs[0], i);
1937 NOTREACHED();
1938 return false;
1939 }
1940 }
1941
1942 rv = SSL_SetPredictedPeerCertificates(nss_fd_, certs.get(), certs_in.size());
1943 DestroyCertificates(&certs[0], certs_in.size());
1944 DCHECK_EQ(SECSuccess, rv);
1945
1946 if (state.npn_valid) {
1947 predicted_npn_status_ = state.npn_status;
1948 predicted_npn_proto_ = state.npn_protocol;
1949 }
1950
1951 return true;
1952}
1953
1954bool SSLClientSocketNSS::IsNPNProtocolMispredicted() {
1955 DCHECK(handshake_callback_called_);
1956 if (!predicted_npn_proto_used_)
1957 return false;
1958 std::string npn_proto;
1959 GetNextProto(&npn_proto);
1960 return predicted_npn_proto_ != npn_proto;
1961}
1962
1963void SSLClientSocketNSS::UncorkAfterTimeout() {
1964 corked_ = false;
1965 int nsent;
1966 do {
1967 nsent = BufferSend();
1968 } while (nsent > 0);
1969}
1970
1971// Do network I/O between the given buffer and the given socket.
1972// Return true if some I/O performed, false otherwise (error or ERR_IO_PENDING)
1973bool SSLClientSocketNSS::DoTransportIO() {
1974 EnterFunction("");
1975 bool network_moved = false;
1976 if (nss_bufs_ != NULL) {
1977 int nsent = BufferSend();
1978 int nreceived = BufferRecv();
1979 network_moved = (nsent > 0 || nreceived >= 0);
1980 }
1981 LeaveFunction(network_moved);
1982 return network_moved;
1983}
1984
1985// Return 0 for EOF,
1986// > 0 for bytes transferred immediately,
1987// < 0 for error (or the non-error ERR_IO_PENDING).
1988int SSLClientSocketNSS::BufferSend(void) {
1989 if (transport_send_busy_)
1990 return ERR_IO_PENDING;
1991
1992 EnterFunction("");
1993 const char* buf1;
1994 const char* buf2;
1995 unsigned int len1, len2;
1996 memio_GetWriteParams(nss_bufs_, &buf1, &len1, &buf2, &len2);
1997 const unsigned int len = len1 + len2;
1998
1999 if (corked_ && len < kRecvBufferSize / 2)
2000 return 0;
2001
2002 int rv = 0;
2003 if (len) {
2004 scoped_refptr<IOBuffer> send_buffer(new IOBuffer(len));
2005 memcpy(send_buffer->data(), buf1, len1);
2006 memcpy(send_buffer->data() + len1, buf2, len2);
2007 rv = transport_->socket()->Write(send_buffer, len,
2008 &buffer_send_callback_);
2009 if (rv == ERR_IO_PENDING) {
2010 transport_send_busy_ = true;
2011 } else {
2012 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv));
2013 }
2014 }
2015
2016 LeaveFunction(rv);
2017 return rv;
2018}
2019
2020void SSLClientSocketNSS::BufferSendComplete(int result) {
2021 EnterFunction(result);
2022
2023 // In the case of TCP FastOpen, connect is now finished.
2024 if (!peername_initialized_ && UsingTCPFastOpen())
2025 InitializeSSLPeerName();
2026
2027 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(result));
2028 transport_send_busy_ = false;
2029 OnSendComplete(result);
2030 LeaveFunction("");
2031}
2032
2033int SSLClientSocketNSS::BufferRecv(void) {
2034 if (transport_recv_busy_) return ERR_IO_PENDING;
2035
2036 char *buf;
2037 int nb = memio_GetReadParams(nss_bufs_, &buf);
2038 EnterFunction(nb);
2039 int rv;
2040 if (!nb) {
2041 // buffer too full to read into, so no I/O possible at moment
2042 rv = ERR_IO_PENDING;
2043 } else {
2044 recv_buffer_ = new IOBuffer(nb);
2045 rv = transport_->socket()->Read(recv_buffer_, nb, &buffer_recv_callback_);
2046 if (rv == ERR_IO_PENDING) {
2047 transport_recv_busy_ = true;
2048 } else {
2049 if (rv > 0)
2050 memcpy(buf, recv_buffer_->data(), rv);
2051 memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv));
2052 recv_buffer_ = NULL;
2053 }
2054 }
2055 LeaveFunction(rv);
2056 return rv;
2057}
2058
2059void SSLClientSocketNSS::BufferRecvComplete(int result) {
2060 EnterFunction(result);
2061 if (result > 0) {
2062 char *buf;
2063 memio_GetReadParams(nss_bufs_, &buf);
2064 memcpy(buf, recv_buffer_->data(), result);
2065 }
2066 recv_buffer_ = NULL;
2067 memio_PutReadResult(nss_bufs_, MapErrorToNSS(result));
2068 transport_recv_busy_ = false;
2069 OnRecvComplete(result);
2070 LeaveFunction("");
2071}
2072
[email protected]bacff652009-03-31 17:50:332073// static
2074// NSS calls this if an incoming certificate needs to be verified.
[email protected]2345cc52009-06-04 09:18:472075// Do nothing but return SECSuccess.
2076// This is called only in full handshake mode.
2077// Peer certificate is retrieved in HandshakeCallback() later, which is called
2078// in full handshake mode or in resumption handshake mode.
[email protected]bacff652009-03-31 17:50:332079SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg,
2080 PRFileDesc* socket,
2081 PRBool checksig,
2082 PRBool is_server) {
[email protected]9ae2ee02010-09-08 16:41:142083#ifdef SSL_ENABLE_FALSE_START
2084 // In the event that we are False Starting this connection, we wish to send
2085 // out the Finished message and first application data record in the same
2086 // packet. This prevents non-determinism when talking to False Start
2087 // intolerant servers which, otherwise, might see the two messages in
2088 // different reads or not, depending on network conditions.
2089 PRBool false_start = 0;
2090 SECStatus rv = SSL_OptionGet(socket, SSL_ENABLE_FALSE_START, &false_start);
[email protected]79ba2d82010-11-05 14:07:462091 DCHECK_EQ(SECSuccess, rv);
2092
[email protected]9ae2ee02010-09-08 16:41:142093 if (false_start) {
2094 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
[email protected]563cbcc62010-10-11 23:07:522095
2096 // ESET anti-virus is capable of intercepting HTTPS connections on Windows.
2097 // However, it is False Start intolerant and causes the connections to hang
2098 // forever. We detect ESET by the issuer of the leaf certificate and set a
2099 // flag to return a specific error, giving the user instructions for
2100 // reconfiguring ESET.
2101 CERTCertificate* cert = SSL_PeerCertificate(that->nss_fd_);
2102 if (cert) {
2103 char* common_name = CERT_GetCommonName(&cert->issuer);
2104 if (common_name) {
2105 if (strcmp(common_name, "ESET_RootSslCert") == 0)
2106 that->eset_mitm_detected_ = true;
[email protected]081b0942010-12-13 19:34:142107 if (strcmp(common_name,
2108 "ContentWatch Root Certificate Authority") == 0) {
[email protected]79ba2d82010-11-05 14:07:462109 // This is NetNanny. NetNanny are updating their product so we
2110 // silently disable False Start for now.
2111 rv = SSL_OptionSet(socket, SSL_ENABLE_FALSE_START, PR_FALSE);
2112 DCHECK_EQ(SECSuccess, rv);
2113 false_start = 0;
2114 }
[email protected]563cbcc62010-10-11 23:07:522115 PORT_Free(common_name);
2116 }
2117 CERT_DestroyCertificate(cert);
2118 }
[email protected]79ba2d82010-11-05 14:07:462119
2120 if (false_start && !that->handshake_callback_called_) {
2121 that->corked_ = true;
2122 that->uncork_timer_.Start(
2123 base::TimeDelta::FromMilliseconds(kCorkTimeoutMs),
2124 that, &SSLClientSocketNSS::UncorkAfterTimeout);
2125 }
[email protected]9ae2ee02010-09-08 16:41:142126 }
2127#endif
2128
[email protected]2345cc52009-06-04 09:18:472129 // Tell NSS to not verify the certificate.
2130 return SECSuccess;
2131}
2132
[email protected]4a842342010-11-04 16:21:332133#if defined(NSS_PLATFORM_CLIENT_AUTH)
[email protected]2345cc52009-06-04 09:18:472134// static
[email protected]d84b3722009-10-15 21:23:372135// NSS calls this if a client certificate is needed.
[email protected]4a842342010-11-04 16:21:332136SECStatus SSLClientSocketNSS::PlatformClientAuthHandler(
[email protected]d84b3722009-10-15 21:23:372137 void* arg,
2138 PRFileDesc* socket,
2139 CERTDistNames* ca_names,
[email protected]4a842342010-11-04 16:21:332140 CERTCertList** result_certs,
2141 void** result_private_key) {
[email protected]d84b3722009-10-15 21:23:372142 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
2143
2144 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert;
[email protected]1d583612010-03-12 17:47:142145#if defined(OS_WIN)
2146 if (that->ssl_config_.send_client_cert) {
[email protected]4a842342010-11-04 16:21:332147 if (that->ssl_config_.client_cert) {
2148 PCCERT_CONTEXT cert_context =
2149 that->ssl_config_.client_cert->os_cert_handle();
[email protected]39815a02011-02-05 04:47:152150 PCERT_KEY_CONTEXT key_context = reinterpret_cast<PCERT_KEY_CONTEXT>(
2151 PORT_ZAlloc(sizeof(CERT_KEY_CONTEXT)));
2152 if (!key_context)
2153 return SECFailure;
2154 key_context->cbSize = sizeof(*key_context);
[email protected]b493c0b92010-11-11 05:12:422155
[email protected]4a842342010-11-04 16:21:332156 BOOL must_free = FALSE;
2157 BOOL acquired_key = CryptAcquireCertificatePrivateKey(
2158 cert_context,
2159 CRYPT_ACQUIRE_CACHE_FLAG | CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
[email protected]39815a02011-02-05 04:47:152160 NULL, &key_context->hCryptProv, &key_context->dwKeySpec,
2161 &must_free);
2162 if (acquired_key && key_context->hCryptProv) {
2163 DCHECK_NE(key_context->dwKeySpec, CERT_NCRYPT_KEY_SPEC);
[email protected]4a842342010-11-04 16:21:332164
2165 // The certificate cache may have been updated/used, in which case,
2166 // duplicate the existing handle, since NSS will free it when no
2167 // longer in use.
2168 if (!must_free)
[email protected]39815a02011-02-05 04:47:152169 CryptContextAddRef(key_context->hCryptProv, NULL, 0);
[email protected]4a842342010-11-04 16:21:332170
2171 SECItem der_cert;
2172 der_cert.type = siDERCertBuffer;
2173 der_cert.data = cert_context->pbCertEncoded;
2174 der_cert.len = cert_context->cbCertEncoded;
2175
2176 // TODO(rsleevi): Error checking for NSS allocation errors.
2177 *result_certs = CERT_NewCertList();
2178 CERTCertDBHandle* db_handle = CERT_GetDefaultCertDB();
2179 CERTCertificate* user_cert = CERT_NewTempCertificate(
2180 db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE);
2181 CERT_AddCertToListTail(*result_certs, user_cert);
2182
2183 // Add the intermediates.
2184 X509Certificate::OSCertHandles intermediates =
2185 that->ssl_config_.client_cert->GetIntermediateCertificates();
2186 for (X509Certificate::OSCertHandles::const_iterator it =
2187 intermediates.begin(); it != intermediates.end(); ++it) {
2188 der_cert.data = (*it)->pbCertEncoded;
2189 der_cert.len = (*it)->cbCertEncoded;
2190
2191 CERTCertificate* intermediate = CERT_NewTempCertificate(
2192 db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE);
2193 CERT_AddCertToListTail(*result_certs, intermediate);
2194 }
[email protected]39815a02011-02-05 04:47:152195 *result_private_key = key_context;
[email protected]4a842342010-11-04 16:21:332196 return SECSuccess;
2197 }
[email protected]39815a02011-02-05 04:47:152198 PORT_Free(key_context);
[email protected]4a842342010-11-04 16:21:332199 LOG(WARNING) << "Client cert found without private key";
2200 }
[email protected]1d583612010-03-12 17:47:142201 // Send no client certificate.
2202 return SECFailure;
2203 }
2204
2205 that->client_certs_.clear();
2206
2207 std::vector<CERT_NAME_BLOB> issuer_list(ca_names->nnames);
2208 for (int i = 0; i < ca_names->nnames; ++i) {
2209 issuer_list[i].cbData = ca_names->names[i].len;
2210 issuer_list[i].pbData = ca_names->names[i].data;
2211 }
2212
2213 // Client certificates of the user are in the "MY" system certificate store.
2214 HCERTSTORE my_cert_store = CertOpenSystemStore(NULL, L"MY");
2215 if (!my_cert_store) {
2216 LOG(ERROR) << "Could not open the \"MY\" system certificate store: "
2217 << GetLastError();
2218 return SECFailure;
2219 }
2220
2221 // Enumerate the client certificates.
2222 CERT_CHAIN_FIND_BY_ISSUER_PARA find_by_issuer_para;
2223 memset(&find_by_issuer_para, 0, sizeof(find_by_issuer_para));
2224 find_by_issuer_para.cbSize = sizeof(find_by_issuer_para);
2225 find_by_issuer_para.pszUsageIdentifier = szOID_PKIX_KP_CLIENT_AUTH;
2226 find_by_issuer_para.cIssuer = ca_names->nnames;
2227 find_by_issuer_para.rgIssuer = ca_names->nnames ? &issuer_list[0] : NULL;
[email protected]01640f62010-08-10 19:42:122228 find_by_issuer_para.pfnFindCallback = ClientCertFindCallback;
[email protected]1d583612010-03-12 17:47:142229
2230 PCCERT_CHAIN_CONTEXT chain_context = NULL;
2231
2232 for (;;) {
2233 // Find a certificate chain.
2234 chain_context = CertFindChainInStore(my_cert_store,
2235 X509_ASN_ENCODING,
2236 0,
2237 CERT_CHAIN_FIND_BY_ISSUER,
2238 &find_by_issuer_para,
2239 chain_context);
2240 if (!chain_context) {
2241 DWORD err = GetLastError();
2242 if (err != CRYPT_E_NOT_FOUND)
2243 DLOG(ERROR) << "CertFindChainInStore failed: " << err;
2244 break;
2245 }
2246
2247 // Get the leaf certificate.
2248 PCCERT_CONTEXT cert_context =
2249 chain_context->rgpChain[0]->rgpElement[0]->pCertContext;
2250 // Copy it to our own certificate store, so that we can close the "MY"
2251 // certificate store before returning from this function.
2252 PCCERT_CONTEXT cert_context2;
[email protected]670dca92010-10-26 13:27:092253 BOOL ok = CertAddCertificateContextToStore(X509Certificate::cert_store(),
2254 cert_context,
[email protected]1d583612010-03-12 17:47:142255 CERT_STORE_ADD_USE_EXISTING,
2256 &cert_context2);
2257 if (!ok) {
2258 NOTREACHED();
2259 continue;
2260 }
[email protected]4a842342010-11-04 16:21:332261
2262 // Copy the rest of the chain to our own store as well. Copying the chain
2263 // stops gracefully if an error is encountered, with the partial chain
2264 // being used as the intermediates, rather than failing to consider the
2265 // client certificate.
2266 net::X509Certificate::OSCertHandles intermediates;
2267 for (DWORD i = 1; i < chain_context->rgpChain[0]->cElement; i++) {
2268 PCCERT_CONTEXT intermediate_copy;
2269 ok = CertAddCertificateContextToStore(X509Certificate::cert_store(),
2270 chain_context->rgpChain[0]->rgpElement[i]->pCertContext,
2271 CERT_STORE_ADD_USE_EXISTING, &intermediate_copy);
2272 if (!ok) {
2273 NOTREACHED();
2274 break;
2275 }
2276 intermediates.push_back(intermediate_copy);
2277 }
2278
[email protected]1d583612010-03-12 17:47:142279 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
2280 cert_context2, X509Certificate::SOURCE_LONE_CERT_IMPORT,
[email protected]4a842342010-11-04 16:21:332281 intermediates);
[email protected]1d583612010-03-12 17:47:142282 that->client_certs_.push_back(cert);
[email protected]4a842342010-11-04 16:21:332283
2284 X509Certificate::FreeOSCertHandle(cert_context2);
2285 for (net::X509Certificate::OSCertHandles::iterator it =
2286 intermediates.begin(); it != intermediates.end(); ++it) {
2287 net::X509Certificate::FreeOSCertHandle(*it);
2288 }
[email protected]1d583612010-03-12 17:47:142289 }
2290
2291 BOOL ok = CertCloseStore(my_cert_store, CERT_CLOSE_STORE_CHECK_FLAG);
2292 DCHECK(ok);
2293
2294 // Tell NSS to suspend the client authentication. We will then abort the
2295 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
2296 return SECWouldBlock;
[email protected]3dd6f5e2010-06-01 20:28:032297#elif defined(OS_MACOSX)
[email protected]fd4f139f2010-06-11 17:02:202298 if (that->ssl_config_.send_client_cert) {
[email protected]4a842342010-11-04 16:21:332299 if (that->ssl_config_.client_cert) {
2300 OSStatus os_error = noErr;
2301 SecIdentityRef identity = NULL;
2302 SecKeyRef private_key = NULL;
2303 CFArrayRef chain =
2304 that->ssl_config_.client_cert->CreateClientCertificateChain();
2305 if (chain) {
2306 identity = reinterpret_cast<SecIdentityRef>(
2307 const_cast<void*>(CFArrayGetValueAtIndex(chain, 0)));
2308 }
2309 if (identity)
2310 os_error = SecIdentityCopyPrivateKey(identity, &private_key);
2311
2312 if (chain && identity && os_error == noErr) {
2313 // TODO(rsleevi): Error checking for NSS allocation errors.
2314 *result_certs = CERT_NewCertList();
[email protected]39815a02011-02-05 04:47:152315 *result_private_key = private_key;
[email protected]4a842342010-11-04 16:21:332316
2317 for (CFIndex i = 0; i < CFArrayGetCount(chain); ++i) {
2318 CSSM_DATA cert_data;
2319 SecCertificateRef cert_ref;
2320 if (i == 0) {
2321 cert_ref = that->ssl_config_.client_cert->os_cert_handle();
2322 } else {
2323 cert_ref = reinterpret_cast<SecCertificateRef>(
2324 const_cast<void*>(CFArrayGetValueAtIndex(chain, i)));
2325 }
2326 os_error = SecCertificateGetData(cert_ref, &cert_data);
2327 if (os_error != noErr)
2328 break;
2329
2330 SECItem der_cert;
2331 der_cert.type = siDERCertBuffer;
2332 der_cert.data = cert_data.Data;
2333 der_cert.len = cert_data.Length;
2334 CERTCertificate* nss_cert = CERT_NewTempCertificate(
2335 CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE);
2336 CERT_AddCertToListTail(*result_certs, nss_cert);
2337 }
2338 }
2339 if (os_error == noErr) {
2340 CFRelease(chain);
2341 return SECSuccess;
2342 }
2343 LOG(WARNING) << "Client cert found, but could not be used: "
2344 << os_error;
2345 if (*result_certs) {
2346 CERT_DestroyCertList(*result_certs);
2347 *result_certs = NULL;
2348 }
2349 if (*result_private_key)
2350 *result_private_key = NULL;
2351 if (private_key)
2352 CFRelease(private_key);
2353 if (chain)
2354 CFRelease(chain);
2355 }
[email protected]fd4f139f2010-06-11 17:02:202356 // Send no client certificate.
2357 return SECFailure;
2358 }
2359
2360 that->client_certs_.clear();
2361
2362 // First, get the cert issuer names allowed by the server.
2363 std::vector<CertPrincipal> valid_issuers;
2364 int n = ca_names->nnames;
2365 for (int i = 0; i < n; i++) {
2366 // Parse each name into a CertPrincipal object.
2367 CertPrincipal p;
2368 if (p.ParseDistinguishedName(ca_names->names[i].data,
2369 ca_names->names[i].len)) {
2370 valid_issuers.push_back(p);
2371 }
2372 }
2373
2374 // Now get the available client certs whose issuers are allowed by the server.
[email protected]4f4de7e62010-11-12 19:55:272375 X509Certificate::GetSSLClientCertificates(that->host_and_port_.host(),
[email protected]fd4f139f2010-06-11 17:02:202376 valid_issuers,
2377 &that->client_certs_);
2378
2379 // Tell NSS to suspend the client authentication. We will then abort the
2380 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
2381 return SECWouldBlock;
[email protected]1d583612010-03-12 17:47:142382#else
[email protected]4a842342010-11-04 16:21:332383 return SECFailure;
2384#endif
2385}
2386
2387#else // NSS_PLATFORM_CLIENT_AUTH
2388
2389// static
2390// NSS calls this if a client certificate is needed.
2391// Based on Mozilla's NSS_GetClientAuthData.
2392SECStatus SSLClientSocketNSS::ClientAuthHandler(
2393 void* arg,
2394 PRFileDesc* socket,
2395 CERTDistNames* ca_names,
2396 CERTCertificate** result_certificate,
2397 SECKEYPrivateKey** result_private_key) {
2398 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
2399
2400 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert;
[email protected]b8fee152009-10-24 03:39:312401 void* wincx = SSL_RevealPinArg(socket);
2402
[email protected]d84b3722009-10-15 21:23:372403 // Second pass: a client certificate should have been selected.
2404 if (that->ssl_config_.send_client_cert) {
2405 if (that->ssl_config_.client_cert) {
[email protected]701e8692010-08-17 20:00:432406 CERTCertificate* cert = CERT_DupCertificate(
[email protected]d84b3722009-10-15 21:23:372407 that->ssl_config_.client_cert->os_cert_handle());
[email protected]701e8692010-08-17 20:00:432408 SECKEYPrivateKey* privkey = PK11_FindKeyByAnyCert(cert, wincx);
[email protected]d84b3722009-10-15 21:23:372409 if (privkey) {
2410 // TODO(jsorianopastor): We should wait for server certificate
2411 // verification before sending our credentials. See
2412 // http://crbug.com/13934.
2413 *result_certificate = cert;
2414 *result_private_key = privkey;
2415 return SECSuccess;
2416 }
2417 LOG(WARNING) << "Client cert found without private key";
2418 }
2419 // Send no client certificate.
2420 return SECFailure;
2421 }
2422
[email protected]701e8692010-08-17 20:00:432423 // Iterate over all client certificates.
2424 CERTCertList* client_certs = CERT_FindUserCertsByUsage(
2425 CERT_GetDefaultCertDB(), certUsageSSLClient,
2426 PR_FALSE, PR_FALSE, wincx);
2427 if (client_certs) {
2428 for (CERTCertListNode* node = CERT_LIST_HEAD(client_certs);
2429 !CERT_LIST_END(node, client_certs);
2430 node = CERT_LIST_NEXT(node)) {
2431 // Only offer unexpired certificates.
2432 if (CERT_CheckCertValidTimes(node->cert, PR_Now(), PR_TRUE) !=
2433 secCertTimeValid)
[email protected]b8fee152009-10-24 03:39:312434 continue;
[email protected]701e8692010-08-17 20:00:432435 // Filter by issuer.
2436 //
2437 // TODO(davidben): This does a binary comparison of the DER-encoded
2438 // issuers. We should match according to RFC 5280 sec. 7.1. We should find
2439 // an appropriate NSS function or add one if needbe.
2440 if (ca_names->nnames &&
2441 NSS_CmpCertChainWCANames(node->cert, ca_names) != SECSuccess)
2442 continue;
2443 X509Certificate* x509_cert = X509Certificate::CreateFromHandle(
2444 node->cert, X509Certificate::SOURCE_LONE_CERT_IMPORT,
2445 net::X509Certificate::OSCertHandles());
2446 that->client_certs_.push_back(x509_cert);
[email protected]b8fee152009-10-24 03:39:312447 }
[email protected]701e8692010-08-17 20:00:432448 CERT_DestroyCertList(client_certs);
[email protected]b8fee152009-10-24 03:39:312449 }
[email protected]d84b3722009-10-15 21:23:372450
[email protected]f6ee0a012010-03-05 22:00:242451 // Tell NSS to suspend the client authentication. We will then abort the
2452 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
2453 return SECWouldBlock;
[email protected]d84b3722009-10-15 21:23:372454}
[email protected]4a842342010-11-04 16:21:332455#endif // NSS_PLATFORM_CLIENT_AUTH
[email protected]d84b3722009-10-15 21:23:372456
2457// static
[email protected]2345cc52009-06-04 09:18:472458// NSS calls this when handshake is completed.
2459// After the SSL handshake is finished, use CertVerifier to verify
2460// the saved server certificate.
2461void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket,
2462 void* arg) {
[email protected]bacff652009-03-31 17:50:332463 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
2464
[email protected]7a8de3072010-10-01 16:25:542465 that->handshake_callback_called_ = true;
[email protected]39afe642010-04-29 14:55:182466
[email protected]2345cc52009-06-04 09:18:472467 that->UpdateServerCert();
[email protected]757f2e2b2010-10-27 23:28:352468 that->UpdateConnectionStatus();
[email protected]2345cc52009-06-04 09:18:472469}
[email protected]bacff652009-03-31 17:50:332470
[email protected]b43c97c2008-10-22 19:50:582471} // namespace net