blob: 9923025f1cec592a1601689f1f77608da8246977 [file] [log] [blame]
[email protected]35a43f92011-02-09 04:39:481// Copyright (c) 2011 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]35a43f92011-02-09 04:39:4863#include <algorithm>
[email protected]7a8de3072010-10-01 16:25:5464#include <limits>
[email protected]35a43f92011-02-09 04:39:4865#include <map>
[email protected]7a8de3072010-10-01 16:25:5466
[email protected]bacff652009-03-31 17:50:3367#include "base/compiler_specific.h"
[email protected]b43c97c2008-10-22 19:50:5868#include "base/logging.h"
[email protected]3b63f8f42011-03-28 01:54:1569#include "base/memory/singleton.h"
[email protected]b92ead12011-01-19 15:29:0970#include "base/metrics/histogram.h"
[email protected]1b1a264a2010-01-14 22:36:3571#include "base/nss_util.h"
[email protected]899c3e92010-08-28 15:53:5072#include "base/string_number_conversions.h"
[email protected]b43c97c2008-10-22 19:50:5873#include "base/string_util.h"
[email protected]d8eb84242010-09-25 02:25:0674#include "base/stringprintf.h"
[email protected]34b99632011-01-01 01:01:0675#include "base/threading/thread_restrictions.h"
[email protected]7cbc6df12010-10-04 16:25:3976#include "base/values.h"
[email protected]ac9eec62010-02-20 18:50:3877#include "net/base/address_list.h"
[email protected]43025b7a2010-09-16 19:24:4578#include "net/base/cert_status_flags.h"
[email protected]92d9cad2009-06-25 23:40:2479#include "net/base/cert_verifier.h"
[email protected]757f2e2b2010-10-27 23:28:3580#include "net/base/connection_type_histograms.h"
[email protected]d8eb84242010-09-25 02:25:0681#include "net/base/dns_util.h"
[email protected]899c3e92010-08-28 15:53:5082#include "net/base/dnsrr_resolver.h"
[email protected]b24713592010-08-11 19:50:0283#include "net/base/dnssec_chain_verifier.h"
[email protected]597cf6e2009-05-29 09:43:2684#include "net/base/io_buffer.h"
[email protected]b43c97c2008-10-22 19:50:5885#include "net/base/net_errors.h"
[email protected]899c3e92010-08-28 15:53:5086#include "net/base/net_log.h"
[email protected]d84b3722009-10-15 21:23:3787#include "net/base/ssl_cert_request_info.h"
[email protected]fc7de492010-07-12 14:49:0488#include "net/base/ssl_connection_status_flags.h"
[email protected]b43c97c2008-10-22 19:50:5889#include "net/base/ssl_info.h"
[email protected]ac9eec62010-02-20 18:50:3890#include "net/base/sys_addrinfo.h"
[email protected]2a0c0a52009-07-31 07:51:3291#include "net/ocsp/nss_ocsp.h"
[email protected]e60e47a2010-07-14 03:37:1892#include "net/socket/client_socket_handle.h"
[email protected]345c613b2010-11-22 19:33:1893#include "net/socket/dns_cert_provenance_checker.h"
[email protected]f61c3972010-12-23 09:54:1594#include "net/socket/nss_ssl_util.h"
[email protected]47f7d742010-11-11 04:12:5395#include "net/socket/ssl_error_params.h"
[email protected]d0672be2010-10-20 16:30:1996#include "net/socket/ssl_host_info.h"
[email protected]b43c97c2008-10-22 19:50:5897
[email protected]11f40342010-11-22 13:35:4998#if defined(OS_WIN)
99#include <windows.h>
100#include <wincrypt.h>
101#elif defined(OS_MACOSX)
102#include <Security/SecBase.h>
103#include <Security/SecCertificate.h>
104#include <Security/SecIdentity.h>
[email protected]35a43f92011-02-09 04:39:48105#elif defined(USE_NSS)
106#include <dlfcn.h>
[email protected]11f40342010-11-22 13:35:49107#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]35a43f92011-02-09 04:39:48117#if defined(OS_WIN)
118// CERT_OCSP_RESPONSE_PROP_ID is only implemented on Vista+, but it can be
119// set on Windows XP without error. There is some overhead from the server
120// sending the OCSP response if it supports the extension, for the subset of
121// XP clients who will request it but be unable to use it, but this is an
122// acceptable trade-off for simplicity of implementation.
123static bool IsOCSPStaplingSupported() {
124 return true;
125}
126#elif defined(USE_NSS)
[email protected]b92ead12011-01-19 15:29:09127typedef SECStatus
128(*CacheOCSPResponseFromSideChannelFunction)(
129 CERTCertDBHandle *handle, CERTCertificate *cert, PRTime time,
130 SECItem *encodedResponse, void *pwArg);
131
[email protected]71d6ccaa2011-01-06 17:43:21132// On Linux, we dynamically link against the system version of libnss3.so. In
133// order to continue working on systems without up-to-date versions of NSS we
[email protected]b92ead12011-01-19 15:29:09134// lookup CERT_CacheOCSPResponseFromSideChannel with dlsym.
[email protected]71d6ccaa2011-01-06 17:43:21135
[email protected]b92ead12011-01-19 15:29:09136// RuntimeLibNSSFunctionPointers is a singleton which caches the results of any
137// runtime symbol resolution that we need.
138class RuntimeLibNSSFunctionPointers {
139 public:
140 CacheOCSPResponseFromSideChannelFunction
141 GetCacheOCSPResponseFromSideChannelFunction() {
142 return cache_ocsp_response_from_side_channel_;
143 }
144
145 static RuntimeLibNSSFunctionPointers* GetInstance() {
146 return Singleton<RuntimeLibNSSFunctionPointers>::get();
147 }
148
149 private:
150 friend struct DefaultSingletonTraits<RuntimeLibNSSFunctionPointers>;
151
152 RuntimeLibNSSFunctionPointers() {
153 cache_ocsp_response_from_side_channel_ =
154 (CacheOCSPResponseFromSideChannelFunction)
155 dlsym(RTLD_DEFAULT, "CERT_CacheOCSPResponseFromSideChannel");
156 }
157
158 CacheOCSPResponseFromSideChannelFunction
159 cache_ocsp_response_from_side_channel_;
160};
161
162static CacheOCSPResponseFromSideChannelFunction
163GetCacheOCSPResponseFromSideChannelFunction() {
164 return RuntimeLibNSSFunctionPointers::GetInstance()
165 ->GetCacheOCSPResponseFromSideChannelFunction();
[email protected]71d6ccaa2011-01-06 17:43:21166}
[email protected]35a43f92011-02-09 04:39:48167
168static bool IsOCSPStaplingSupported() {
169 return GetCacheOCSPResponseFromSideChannelFunction() != NULL;
170}
[email protected]71d6ccaa2011-01-06 17:43:21171#else
[email protected]35a43f92011-02-09 04:39:48172// TODO(agl): Figure out if we can plumb the OCSP response into Mac's system
173// certificate validation functions.
174static bool IsOCSPStaplingSupported() {
175 return false;
[email protected]71d6ccaa2011-01-06 17:43:21176}
177#endif
178
[email protected]b43c97c2008-10-22 19:50:58179namespace net {
180
[email protected]e17b4c12008-11-05 22:04:08181// State machines are easier to debug if you log state transitions.
182// Enable these if you want to see what's going on.
183#if 1
184#define EnterFunction(x)
185#define LeaveFunction(x)
[email protected]a3ff5e92009-10-13 04:48:06186#define GotoState(s) next_handshake_state_ = s
[email protected]ea224582008-12-07 20:25:46187#define LogData(s, len)
[email protected]e17b4c12008-11-05 22:04:08188#else
[email protected]b30a3f52010-10-16 01:05:46189#define EnterFunction(x)\
190 VLOG(1) << (void *)this << " " << __FUNCTION__ << " enter " << x\
191 << "; next_handshake_state " << next_handshake_state_
192#define LeaveFunction(x)\
193 VLOG(1) << (void *)this << " " << __FUNCTION__ << " leave " << x\
194 << "; next_handshake_state " << next_handshake_state_
195#define GotoState(s)\
196 do {\
197 VLOG(1) << (void *)this << " " << __FUNCTION__ << " jump to state " << s;\
198 next_handshake_state_ = s;\
199 } while (0)
200#define LogData(s, len)\
201 VLOG(1) << (void *)this << " " << __FUNCTION__\
202 << " data [" << std::string(s, len) << "]"
[email protected]e17b4c12008-11-05 22:04:08203#endif
204
[email protected]ea224582008-12-07 20:25:46205namespace {
206
[email protected]37a0b112010-05-08 02:23:46207#if defined(OS_WIN)
208
[email protected]01640f62010-08-10 19:42:12209// This callback is intended to be used with CertFindChainInStore. In addition
210// to filtering by extended/enhanced key usage, we do not show expired
211// certificates and require digital signature usage in the key usage
212// extension.
213//
214// This matches our behavior on Mac OS X and that of NSS. It also matches the
215// default behavior of IE8. See http://support.microsoft.com/kb/890326 and
216// 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
217BOOL WINAPI ClientCertFindCallback(PCCERT_CONTEXT cert_context,
218 void* find_arg) {
[email protected]b30a3f52010-10-16 01:05:46219 VLOG(1) << "Calling ClientCertFindCallback from _nss";
[email protected]01640f62010-08-10 19:42:12220 // Verify the certificate's KU is good.
221 BYTE key_usage;
222 if (CertGetIntendedKeyUsage(X509_ASN_ENCODING, cert_context->pCertInfo,
223 &key_usage, 1)) {
224 if (!(key_usage & CERT_DIGITAL_SIGNATURE_KEY_USAGE))
225 return FALSE;
226 } else {
227 DWORD err = GetLastError();
228 // If |err| is non-zero, it's an actual error. Otherwise the extension
229 // just isn't present, and we treat it as if everything was allowed.
230 if (err) {
231 DLOG(ERROR) << "CertGetIntendedKeyUsage failed: " << err;
232 return FALSE;
233 }
234 }
235
236 // Verify the current time is within the certificate's validity period.
237 if (CertVerifyTimeValidity(NULL, cert_context->pCertInfo) != 0)
238 return FALSE;
239
[email protected]187f48b2011-03-03 04:59:23240 // Verify private key metadata is associated with this certificate.
241 DWORD size = 0;
242 if (!CertGetCertificateContextProperty(
243 cert_context, CERT_KEY_PROV_INFO_PROP_ID, NULL, &size)) {
244 return FALSE;
245 }
246
[email protected]01640f62010-08-10 19:42:12247 return TRUE;
248}
249
[email protected]37a0b112010-05-08 02:23:46250#endif
251
[email protected]17570702010-10-28 15:16:09252// PeerCertificateChain is a helper object which extracts the certificate
253// chain, as given by the server, from an NSS socket and performs the needed
254// resource management. The first element of the chain is the leaf certificate
255// and the other elements are in the order given by the server.
256class PeerCertificateChain {
257 public:
[email protected]b92a96e2010-11-02 21:03:05258 explicit PeerCertificateChain(PRFileDesc* nss_fd)
[email protected]17570702010-10-28 15:16:09259 : num_certs_(0),
260 certs_(NULL) {
261 SECStatus rv = SSL_PeerCertificateChain(nss_fd, NULL, &num_certs_);
262 DCHECK_EQ(rv, SECSuccess);
263
264 certs_ = new CERTCertificate*[num_certs_];
265 const unsigned expected_num_certs = num_certs_;
266 rv = SSL_PeerCertificateChain(nss_fd, certs_, &num_certs_);
267 DCHECK_EQ(rv, SECSuccess);
268 DCHECK_EQ(num_certs_, expected_num_certs);
269 }
270
271 ~PeerCertificateChain() {
272 for (unsigned i = 0; i < num_certs_; i++)
273 CERT_DestroyCertificate(certs_[i]);
274 delete[] certs_;
275 }
276
277 unsigned size() const { return num_certs_; }
278
279 CERTCertificate* operator[](unsigned i) {
280 DCHECK_LT(i, num_certs_);
281 return certs_[i];
282 }
283
[email protected]d8fbf582010-11-04 21:51:12284 std::vector<base::StringPiece> AsStringPieceVector() const {
285 std::vector<base::StringPiece> v(size());
286 for (unsigned i = 0; i < size(); i++) {
287 v[i] = base::StringPiece(
288 reinterpret_cast<const char*>(certs_[i]->derCert.data),
289 certs_[i]->derCert.len);
290 }
291
292 return v;
293 }
294
[email protected]17570702010-10-28 15:16:09295 private:
296 unsigned num_certs_;
297 CERTCertificate** certs_;
298};
299
[email protected]d100e44f2011-01-26 22:47:11300void DestroyCertificates(CERTCertificate** certs, unsigned len) {
301 for (unsigned i = 0; i < len; i++)
302 CERT_DestroyCertificate(certs[i]);
303}
304
305// DNSValidationResult enumerates the possible outcomes from processing a
306// set of DNS records.
307enum DNSValidationResult {
308 DNSVR_SUCCESS, // the cert is immediately acceptable.
309 DNSVR_FAILURE, // the cert is unconditionally rejected.
310 DNSVR_CONTINUE, // perform CA validation as usual.
311};
312
313// VerifyTXTRecords processes the RRDATA for a number of DNS TXT records and
314// checks them against the given certificate.
315// dnssec: if true then the TXT records are DNSSEC validated. In this case,
316// DNSVR_SUCCESS may be returned.
317// server_cert_nss: the certificate to validate
318// rrdatas: the TXT records for the current domain.
319DNSValidationResult VerifyTXTRecords(
320 bool dnssec,
321 CERTCertificate* server_cert_nss,
322 const std::vector<base::StringPiece>& rrdatas) {
323 bool found_well_formed_record = false;
324 bool matched_record = false;
325
326 for (std::vector<base::StringPiece>::const_iterator
327 i = rrdatas.begin(); i != rrdatas.end(); ++i) {
328 std::map<std::string, std::string> m(
329 DNSSECChainVerifier::ParseTLSTXTRecord(*i));
330 if (m.empty())
331 continue;
332
333 std::map<std::string, std::string>::const_iterator j;
334 j = m.find("v");
335 if (j == m.end() || j->second != "tls1")
336 continue;
337
338 j = m.find("ha");
339
340 HASH_HashType hash_algorithm;
341 unsigned hash_length;
342 if (j == m.end() || j->second == "sha1") {
343 hash_algorithm = HASH_AlgSHA1;
344 hash_length = SHA1_LENGTH;
345 } else if (j->second == "sha256") {
346 hash_algorithm = HASH_AlgSHA256;
347 hash_length = SHA256_LENGTH;
348 } else {
349 continue;
350 }
351
352 j = m.find("h");
353 if (j == m.end())
354 continue;
355
356 std::vector<uint8> given_hash;
357 if (!base::HexStringToBytes(j->second, &given_hash))
358 continue;
359
360 if (given_hash.size() != hash_length)
361 continue;
362
363 uint8 calculated_hash[SHA256_LENGTH]; // SHA256 is the largest.
364 SECStatus rv;
365
366 j = m.find("hr");
367 if (j == m.end() || j->second == "pubkey") {
368 rv = HASH_HashBuf(hash_algorithm, calculated_hash,
369 server_cert_nss->derPublicKey.data,
370 server_cert_nss->derPublicKey.len);
371 } else if (j->second == "cert") {
372 rv = HASH_HashBuf(hash_algorithm, calculated_hash,
373 server_cert_nss->derCert.data,
374 server_cert_nss->derCert.len);
375 } else {
376 continue;
377 }
378
379 if (rv != SECSuccess)
380 NOTREACHED();
381
382 found_well_formed_record = true;
383
384 if (memcmp(calculated_hash, &given_hash[0], hash_length) == 0) {
385 matched_record = true;
386 if (dnssec)
387 return DNSVR_SUCCESS;
388 }
389 }
390
391 if (found_well_formed_record && !matched_record)
392 return DNSVR_FAILURE;
393
394 return DNSVR_CONTINUE;
395}
396
397// CheckDNSSECChain tries to validate a DNSSEC chain embedded in
398// |server_cert_nss_|. It returns true iff a chain is found that proves the
399// value of a TXT record that contains a valid public key fingerprint.
400DNSValidationResult CheckDNSSECChain(
401 const std::string& hostname,
402 CERTCertificate* server_cert_nss) {
403 if (!server_cert_nss)
404 return DNSVR_CONTINUE;
405
406 // CERT_FindCertExtensionByOID isn't exported so we have to install an OID,
407 // get a tag for it and find the extension by using that tag.
408 static SECOidTag dnssec_chain_tag;
409 static bool dnssec_chain_tag_valid;
410 if (!dnssec_chain_tag_valid) {
411 // It's harmless if multiple threads enter this block concurrently.
412 static const uint8 kDNSSECChainOID[] =
413 // 1.3.6.1.4.1.11129.2.1.4
414 // (iso.org.dod.internet.private.enterprises.google.googleSecurity.
415 // certificateExtensions.dnssecEmbeddedChain)
416 {0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x01, 0x04};
417 SECOidData oid_data;
418 memset(&oid_data, 0, sizeof(oid_data));
419 oid_data.oid.data = const_cast<uint8*>(kDNSSECChainOID);
420 oid_data.oid.len = sizeof(kDNSSECChainOID);
421 oid_data.desc = "DNSSEC chain";
422 oid_data.supportedExtension = SUPPORTED_CERT_EXTENSION;
423 dnssec_chain_tag = SECOID_AddEntry(&oid_data);
424 DCHECK_NE(SEC_OID_UNKNOWN, dnssec_chain_tag);
425 dnssec_chain_tag_valid = true;
426 }
427
428 SECItem dnssec_embedded_chain;
429 SECStatus rv = CERT_FindCertExtension(server_cert_nss,
430 dnssec_chain_tag, &dnssec_embedded_chain);
431 if (rv != SECSuccess)
432 return DNSVR_CONTINUE;
433
434 base::StringPiece chain(
435 reinterpret_cast<char*>(dnssec_embedded_chain.data),
436 dnssec_embedded_chain.len);
437 std::string dns_hostname;
438 if (!DNSDomainFromDot(hostname, &dns_hostname))
439 return DNSVR_CONTINUE;
440 DNSSECChainVerifier verifier(dns_hostname, chain);
441 DNSSECChainVerifier::Error err = verifier.Verify();
442 if (err != DNSSECChainVerifier::OK) {
443 LOG(ERROR) << "DNSSEC chain verification failed: " << err;
444 return DNSVR_CONTINUE;
445 }
446
447 if (verifier.rrtype() != kDNS_TXT)
448 return DNSVR_CONTINUE;
449
450 DNSValidationResult r = VerifyTXTRecords(
451 true /* DNSSEC verified */, server_cert_nss, verifier.rrdatas());
452 SECITEM_FreeItem(&dnssec_embedded_chain, PR_FALSE);
453 return r;
454}
455
[email protected]ea224582008-12-07 20:25:46456} // namespace
457
[email protected]e60e47a2010-07-14 03:37:18458SSLClientSocketNSS::SSLClientSocketNSS(ClientSocketHandle* transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27459 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21460 const SSLConfig& ssl_config,
[email protected]d8fbf582010-11-04 21:51:12461 SSLHostInfo* ssl_host_info,
[email protected]822581d2010-12-16 17:27:15462 CertVerifier* cert_verifier,
[email protected]345c613b2010-11-22 19:33:18463 DnsCertProvenanceChecker* dns_ctx)
[email protected]f505a9b2010-01-28 19:44:02464 : ALLOW_THIS_IN_INITIALIZER_LIST(buffer_send_callback_(
465 this, &SSLClientSocketNSS::BufferSendComplete)),
466 ALLOW_THIS_IN_INITIALIZER_LIST(buffer_recv_callback_(
467 this, &SSLClientSocketNSS::BufferRecvComplete)),
[email protected]b43c97c2008-10-22 19:50:58468 transport_send_busy_(false),
469 transport_recv_busy_(false),
[email protected]9ae2ee02010-09-08 16:41:14470 corked_(false),
[email protected]f505a9b2010-01-28 19:44:02471 ALLOW_THIS_IN_INITIALIZER_LIST(handshake_io_callback_(
472 this, &SSLClientSocketNSS::OnHandshakeIOComplete)),
[email protected]b43c97c2008-10-22 19:50:58473 transport_(transport_socket),
[email protected]4f4de7e62010-11-12 19:55:27474 host_and_port_(host_and_port),
[email protected]b43c97c2008-10-22 19:50:58475 ssl_config_(ssl_config),
[email protected]a6eb576292009-06-30 16:19:00476 user_connect_callback_(NULL),
[email protected]a3ff5e92009-10-13 04:48:06477 user_read_callback_(NULL),
478 user_write_callback_(NULL),
479 user_read_buf_len_(0),
480 user_write_buf_len_(0),
[email protected]f505a9b2010-01-28 19:44:02481 server_cert_nss_(NULL),
[email protected]3b1d3db2010-10-28 16:39:40482 server_cert_verify_result_(NULL),
[email protected]757f2e2b2010-10-27 23:28:35483 ssl_connection_status_(0),
[email protected]d84b3722009-10-15 21:23:37484 client_auth_cert_needed_(false),
[email protected]822581d2010-12-16 17:27:15485 cert_verifier_(cert_verifier),
[email protected]39afe642010-04-29 14:55:18486 handshake_callback_called_(false),
[email protected]b43c97c2008-10-22 19:50:58487 completed_handshake_(false),
[email protected]7a8de3072010-10-01 16:25:54488 pseudo_connected_(false),
[email protected]563cbcc62010-10-11 23:07:52489 eset_mitm_detected_(false),
[email protected]3b1d3db2010-10-28 16:39:40490 predicted_cert_chain_correct_(false),
[email protected]7f7e92392010-10-26 18:29:29491 peername_initialized_(false),
[email protected]899c3e92010-08-28 15:53:50492 dnssec_provider_(NULL),
[email protected]a3ff5e92009-10-13 04:48:06493 next_handshake_state_(STATE_NONE),
[email protected]b43c97c2008-10-22 19:50:58494 nss_fd_(NULL),
[email protected]a2006ece2010-04-23 16:44:02495 nss_bufs_(NULL),
[email protected]7a8de3072010-10-01 16:25:54496 net_log_(transport_socket->socket()->NetLog()),
497 predicted_npn_status_(kNextProtoUnsupported),
[email protected]7ab5bbd12010-10-19 13:33:21498 predicted_npn_proto_used_(false),
[email protected]d8fbf582010-11-04 21:51:12499 ssl_host_info_(ssl_host_info),
[email protected]93c57682011-02-12 02:05:08500 dns_cert_checker_(dns_ctx),
501 valid_thread_id_(base::kInvalidThreadId) {
[email protected]e17b4c12008-11-05 22:04:08502 EnterFunction("");
[email protected]b43c97c2008-10-22 19:50:58503}
504
505SSLClientSocketNSS::~SSLClientSocketNSS() {
[email protected]e17b4c12008-11-05 22:04:08506 EnterFunction("");
[email protected]b43c97c2008-10-22 19:50:58507 Disconnect();
[email protected]e17b4c12008-11-05 22:04:08508 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:58509}
510
[email protected]d100e44f2011-01-26 22:47:11511// static
512void SSLClientSocketNSS::ClearSessionCache() {
513 SSL_ClearSessionCache();
514}
515
516void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) {
[email protected]e17b4c12008-11-05 22:04:08517 EnterFunction("");
[email protected]d100e44f2011-01-26 22:47:11518 ssl_info->Reset();
[email protected]b43c97c2008-10-22 19:50:58519
[email protected]d100e44f2011-01-26 22:47:11520 if (!server_cert_) {
521 LOG(DFATAL) << "!server_cert_";
[email protected]7a8de3072010-10-01 16:25:54522 return;
523 }
524
[email protected]d100e44f2011-01-26 22:47:11525 ssl_info->cert_status = server_cert_verify_result_->cert_status;
526 DCHECK(server_cert_ != NULL);
527 ssl_info->cert = server_cert_;
528 ssl_info->connection_status = ssl_connection_status_;
[email protected]7a8de3072010-10-01 16:25:54529
[email protected]d100e44f2011-01-26 22:47:11530 PRUint16 cipher_suite =
531 SSLConnectionStatusToCipherSuite(ssl_connection_status_);
532 SSLCipherSuiteInfo cipher_info;
533 SECStatus ok = SSL_GetCipherSuiteInfo(cipher_suite,
534 &cipher_info, sizeof(cipher_info));
535 if (ok == SECSuccess) {
536 ssl_info->security_bits = cipher_info.effectiveKeyBits;
[email protected]98f397e2010-10-26 13:56:57537 } else {
[email protected]d100e44f2011-01-26 22:47:11538 ssl_info->security_bits = -1;
539 LOG(DFATAL) << "SSL_GetCipherSuiteInfo returned " << PR_GetError()
540 << " for cipherSuite " << cipher_suite;
[email protected]98f397e2010-10-26 13:56:57541 }
[email protected]d100e44f2011-01-26 22:47:11542 LeaveFunction("");
[email protected]7a8de3072010-10-01 16:25:54543}
544
[email protected]d100e44f2011-01-26 22:47:11545void SSLClientSocketNSS::GetSSLCertRequestInfo(
546 SSLCertRequestInfo* cert_request_info) {
547 EnterFunction("");
548 // TODO(rch): switch SSLCertRequestInfo.host_and_port to a HostPortPair
549 cert_request_info->host_and_port = host_and_port_.ToString();
550 cert_request_info->client_certs = client_certs_;
551 LeaveFunction(cert_request_info->client_certs.size());
[email protected]7a8de3072010-10-01 16:25:54552}
553
[email protected]d100e44f2011-01-26 22:47:11554SSLClientSocket::NextProtoStatus
555SSLClientSocketNSS::GetNextProto(std::string* proto) {
556#if defined(SSL_NEXT_PROTO_NEGOTIATED)
557 if (!handshake_callback_called_) {
558 DCHECK(pseudo_connected_);
559 predicted_npn_proto_used_ = true;
560 *proto = predicted_npn_proto_;
561 return predicted_npn_status_;
[email protected]d0672be2010-10-20 16:30:19562 }
563
[email protected]d100e44f2011-01-26 22:47:11564 unsigned char buf[255];
565 int state;
566 unsigned len;
567 SECStatus rv = SSL_GetNextProto(nss_fd_, &state, buf, &len, sizeof(buf));
568 if (rv != SECSuccess) {
569 NOTREACHED() << "Error return from SSL_GetNextProto: " << rv;
570 proto->clear();
571 return kNextProtoUnsupported;
[email protected]7a8de3072010-10-01 16:25:54572 }
[email protected]d100e44f2011-01-26 22:47:11573 // We don't check for truncation because sizeof(buf) is large enough to hold
574 // the maximum protocol size.
575 switch (state) {
576 case SSL_NEXT_PROTO_NO_SUPPORT:
577 proto->clear();
578 return kNextProtoUnsupported;
579 case SSL_NEXT_PROTO_NEGOTIATED:
580 *proto = std::string(reinterpret_cast<char*>(buf), len);
581 return kNextProtoNegotiated;
582 case SSL_NEXT_PROTO_NO_OVERLAP:
583 *proto = std::string(reinterpret_cast<char*>(buf), len);
584 return kNextProtoNoOverlap;
585 default:
586 NOTREACHED() << "Unknown status from SSL_GetNextProto: " << state;
587 proto->clear();
588 return kNextProtoUnsupported;
[email protected]d0672be2010-10-20 16:30:19589 }
[email protected]d100e44f2011-01-26 22:47:11590#else
591 // No NPN support in the libssl that we are building with.
592 proto->clear();
593 return kNextProtoUnsupported;
594#endif
[email protected]7a8de3072010-10-01 16:25:54595}
596
[email protected]d100e44f2011-01-26 22:47:11597void SSLClientSocketNSS::UseDNSSEC(DNSSECProvider* provider) {
598 dnssec_provider_ = provider;
[email protected]fa788512010-10-08 14:48:06599}
600
[email protected]a2006ece2010-04-23 16:44:02601int SSLClientSocketNSS::Connect(CompletionCallback* callback) {
[email protected]e17b4c12008-11-05 22:04:08602 EnterFunction("");
[email protected]b43c97c2008-10-22 19:50:58603 DCHECK(transport_.get());
[email protected]a3ff5e92009-10-13 04:48:06604 DCHECK(next_handshake_state_ == STATE_NONE);
605 DCHECK(!user_read_callback_);
606 DCHECK(!user_write_callback_);
[email protected]a6eb576292009-06-30 16:19:00607 DCHECK(!user_connect_callback_);
[email protected]a3ff5e92009-10-13 04:48:06608 DCHECK(!user_read_buf_);
609 DCHECK(!user_write_buf_);
[email protected]7a8de3072010-10-01 16:25:54610 DCHECK(!pseudo_connected_);
[email protected]b43c97c2008-10-22 19:50:58611
[email protected]93c57682011-02-12 02:05:08612 EnsureThreadIdAssigned();
613
[email protected]ec11be62010-04-28 19:28:09614 net_log_.BeginEvent(NetLog::TYPE_SSL_CONNECT, NULL);
[email protected]5a05c47a2009-11-02 23:25:19615
[email protected]dbc13b52010-04-16 00:59:56616 int rv = Init();
617 if (rv != OK) {
[email protected]d7fd1782011-02-08 19:16:43618 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
[email protected]dbc13b52010-04-16 00:59:56619 return rv;
[email protected]0ef0bcf2009-04-03 20:39:43620 }
621
[email protected]dbc13b52010-04-16 00:59:56622 rv = InitializeSSLOptions();
[email protected]5a05c47a2009-11-02 23:25:19623 if (rv != OK) {
[email protected]d7fd1782011-02-08 19:16:43624 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
[email protected]5a05c47a2009-11-02 23:25:19625 return rv;
626 }
627
[email protected]7f7e92392010-10-26 18:29:29628 // Attempt to initialize the peer name. In the case of TCP FastOpen,
629 // we don't have the peer yet.
630 if (!UsingTCPFastOpen()) {
631 rv = InitializeSSLPeerName();
632 if (rv != OK) {
[email protected]d7fd1782011-02-08 19:16:43633 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
[email protected]7f7e92392010-10-26 18:29:29634 return rv;
635 }
636 }
637
[email protected]7ab5bbd12010-10-19 13:33:21638 if (ssl_config_.snap_start_enabled && ssl_host_info_.get()) {
[email protected]7a8de3072010-10-01 16:25:54639 GotoState(STATE_SNAP_START_LOAD_INFO);
640 } else {
641 GotoState(STATE_HANDSHAKE);
642 }
643
[email protected]5a05c47a2009-11-02 23:25:19644 rv = DoHandshakeLoop(OK);
645 if (rv == ERR_IO_PENDING) {
[email protected]7a8de3072010-10-01 16:25:54646 if (pseudo_connected_) {
647 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL);
648 rv = OK;
649 } else {
650 user_connect_callback_ = callback;
651 }
[email protected]5a05c47a2009-11-02 23:25:19652 } else {
[email protected]d7fd1782011-02-08 19:16:43653 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
[email protected]5a05c47a2009-11-02 23:25:19654 }
655
656 LeaveFunction("");
657 return rv > OK ? OK : rv;
658}
659
[email protected]d100e44f2011-01-26 22:47:11660void SSLClientSocketNSS::Disconnect() {
661 EnterFunction("");
662
[email protected]0bc83b3e2011-03-08 22:32:53663 CHECK(CalledOnValidThread());
664
[email protected]93c57682011-02-12 02:05:08665 // Shut down anything that may call us back (through buffer_send_callback_,
666 // buffer_recv_callback, or handshake_io_callback_).
667 verifier_.reset();
668 transport_->socket()->Disconnect();
669
[email protected]d100e44f2011-01-26 22:47:11670 // TODO(wtc): Send SSL close_notify alert.
671 if (nss_fd_ != NULL) {
672 PR_Close(nss_fd_);
673 nss_fd_ = NULL;
674 }
675
[email protected]d100e44f2011-01-26 22:47:11676 // Reset object state
677 transport_send_busy_ = false;
678 transport_recv_busy_ = false;
679 user_connect_callback_ = NULL;
680 user_read_callback_ = NULL;
681 user_write_callback_ = NULL;
682 user_read_buf_ = NULL;
683 user_read_buf_len_ = 0;
684 user_write_buf_ = NULL;
685 user_write_buf_len_ = 0;
686 server_cert_ = NULL;
687 if (server_cert_nss_) {
688 CERT_DestroyCertificate(server_cert_nss_);
689 server_cert_nss_ = NULL;
690 }
691 local_server_cert_verify_result_.Reset();
692 server_cert_verify_result_ = NULL;
693 ssl_connection_status_ = 0;
694 completed_handshake_ = false;
695 pseudo_connected_ = false;
696 eset_mitm_detected_ = false;
697 start_cert_verification_time_ = base::TimeTicks();
698 predicted_cert_chain_correct_ = false;
699 peername_initialized_ = false;
700 nss_bufs_ = NULL;
701 client_certs_.clear();
702 client_auth_cert_needed_ = false;
703
704 LeaveFunction("");
705}
706
707bool SSLClientSocketNSS::IsConnected() const {
708 // Ideally, we should also check if we have received the close_notify alert
709 // message from the server, and return false in that case. We're not doing
710 // that, so this function may return a false positive. Since the upper
711 // layer (HttpNetworkTransaction) needs to handle a persistent connection
712 // closed by the server when we send a request anyway, a false positive in
713 // exchange for simpler code is a good trade-off.
714 EnterFunction("");
715 bool ret = (pseudo_connected_ || completed_handshake_) &&
716 transport_->socket()->IsConnected();
717 LeaveFunction("");
718 return ret;
719}
720
721bool SSLClientSocketNSS::IsConnectedAndIdle() const {
722 // Unlike IsConnected, this method doesn't return a false positive.
723 //
724 // Strictly speaking, we should check if we have received the close_notify
725 // alert message from the server, and return false in that case. Although
726 // the close_notify alert message means EOF in the SSL layer, it is just
727 // bytes to the transport layer below, so
728 // transport_->socket()->IsConnectedAndIdle() returns the desired false
729 // when we receive close_notify.
730 EnterFunction("");
731 bool ret = (pseudo_connected_ || completed_handshake_) &&
732 transport_->socket()->IsConnectedAndIdle();
733 LeaveFunction("");
734 return ret;
735}
736
737int SSLClientSocketNSS::GetPeerAddress(AddressList* address) const {
738 return transport_->socket()->GetPeerAddress(address);
739}
740
741const BoundNetLog& SSLClientSocketNSS::NetLog() const {
742 return net_log_;
743}
744
745void SSLClientSocketNSS::SetSubresourceSpeculation() {
746 if (transport_.get() && transport_->socket()) {
747 transport_->socket()->SetSubresourceSpeculation();
748 } else {
749 NOTREACHED();
750 }
751}
752
753void SSLClientSocketNSS::SetOmniboxSpeculation() {
754 if (transport_.get() && transport_->socket()) {
755 transport_->socket()->SetOmniboxSpeculation();
756 } else {
757 NOTREACHED();
758 }
759}
760
761bool SSLClientSocketNSS::WasEverUsed() const {
762 if (transport_.get() && transport_->socket()) {
763 return transport_->socket()->WasEverUsed();
764 }
765 NOTREACHED();
766 return false;
767}
768
769bool SSLClientSocketNSS::UsingTCPFastOpen() const {
770 if (transport_.get() && transport_->socket()) {
771 return transport_->socket()->UsingTCPFastOpen();
772 }
773 NOTREACHED();
774 return false;
775}
776
777int SSLClientSocketNSS::Read(IOBuffer* buf, int buf_len,
778 CompletionCallback* callback) {
779 EnterFunction(buf_len);
780 DCHECK(!user_read_callback_);
781 DCHECK(!user_connect_callback_);
782 DCHECK(!user_read_buf_);
783 DCHECK(nss_bufs_);
784
785 user_read_buf_ = buf;
786 user_read_buf_len_ = buf_len;
787
788 if (!completed_handshake_) {
789 // In this case we have lied about being connected in order to merge the
790 // first Write into a Snap Start handshake. We'll leave the read hanging
791 // until the handshake has completed.
792 DCHECK(pseudo_connected_);
793
794 user_read_callback_ = callback;
795 LeaveFunction(ERR_IO_PENDING);
796 return ERR_IO_PENDING;
797 }
798
799 int rv = DoReadLoop(OK);
800
801 if (rv == ERR_IO_PENDING) {
802 user_read_callback_ = callback;
803 } else {
804 user_read_buf_ = NULL;
805 user_read_buf_len_ = 0;
806 }
807 LeaveFunction(rv);
808 return rv;
809}
810
811int SSLClientSocketNSS::Write(IOBuffer* buf, int buf_len,
812 CompletionCallback* callback) {
813 EnterFunction(buf_len);
814 if (!pseudo_connected_) {
815 DCHECK(completed_handshake_);
816 DCHECK(next_handshake_state_ == STATE_NONE);
817 DCHECK(!user_connect_callback_);
818 }
819 DCHECK(!user_write_callback_);
820 DCHECK(!user_write_buf_);
821 DCHECK(nss_bufs_);
822
823 user_write_buf_ = buf;
824 user_write_buf_len_ = buf_len;
825
826 if (next_handshake_state_ == STATE_SNAP_START_WAIT_FOR_WRITE) {
827 // We lied about being connected and we have been waiting for this write in
828 // order to merge it into the Snap Start handshake. We'll leave the write
829 // pending until the handshake completes.
830 DCHECK(pseudo_connected_);
831 int rv = DoHandshakeLoop(OK);
832 if (rv == ERR_IO_PENDING) {
833 user_write_callback_ = callback;
834 } else {
835 user_write_buf_ = NULL;
836 user_write_buf_len_ = 0;
837 }
838 if (rv != OK)
839 return rv;
840 }
841
842 if (corked_) {
843 corked_ = false;
844 uncork_timer_.Reset();
845 }
846 int rv = DoWriteLoop(OK);
847
848 if (rv == ERR_IO_PENDING) {
849 user_write_callback_ = callback;
850 } else {
851 user_write_buf_ = NULL;
852 user_write_buf_len_ = 0;
853 }
854 LeaveFunction(rv);
855 return rv;
856}
857
858bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) {
859 return transport_->socket()->SetReceiveBufferSize(size);
860}
861
862bool SSLClientSocketNSS::SetSendBufferSize(int32 size) {
863 return transport_->socket()->SetSendBufferSize(size);
864}
865
866int SSLClientSocketNSS::Init() {
867 EnterFunction("");
868 // Initialize the NSS SSL library in a threadsafe way. This also
869 // initializes the NSS base library.
870 EnsureNSSSSLInit();
871 if (!NSS_IsInitialized())
872 return ERR_UNEXPECTED;
873#if !defined(OS_MACOSX) && !defined(OS_WIN)
874 // We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop
875 // by MessageLoopForIO::current().
876 // X509Certificate::Verify() runs on a worker thread of CertVerifier.
877 EnsureOCSPInit();
878#endif
879
880 LeaveFunction("");
881 return OK;
882}
883
[email protected]5a05c47a2009-11-02 23:25:19884int SSLClientSocketNSS::InitializeSSLOptions() {
[email protected]0ef0bcf2009-04-03 20:39:43885 // Transport connected, now hook it up to nss
886 // TODO(port): specify rx and tx buffer sizes separately
887 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize);
888 if (nss_fd_ == NULL) {
[email protected]38a18722009-12-04 00:09:04889 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR error code.
[email protected]0ef0bcf2009-04-03 20:39:43890 }
891
[email protected]0ef0bcf2009-04-03 20:39:43892 // Grab pointer to buffers
893 nss_bufs_ = memio_GetSecret(nss_fd_);
894
895 /* Create SSL state machine */
896 /* Push SSL onto our fake I/O socket */
897 nss_fd_ = SSL_ImportFD(NULL, nss_fd_);
898 if (nss_fd_ == NULL) {
[email protected]7cbc6df12010-10-04 16:25:39899 LogFailedNSSFunction(net_log_, "SSL_ImportFD", "");
[email protected]4e91b5c2010-09-22 01:04:38900 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR/NSS error code.
[email protected]0ef0bcf2009-04-03 20:39:43901 }
902 // TODO(port): set more ssl options! Check errors!
903
904 int rv;
905
906 rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE);
[email protected]7cbc6df12010-10-04 16:25:39907 if (rv != SECSuccess) {
908 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_SECURITY");
[email protected]4e91b5c2010-09-22 01:04:38909 return ERR_UNEXPECTED;
[email protected]7cbc6df12010-10-04 16:25:39910 }
[email protected]0ef0bcf2009-04-03 20:39:43911
[email protected]cc50fdf72010-11-30 17:48:54912 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL2, PR_FALSE);
[email protected]7cbc6df12010-10-04 16:25:39913 if (rv != SECSuccess) {
914 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL2");
[email protected]4e91b5c2010-09-22 01:04:38915 return ERR_UNEXPECTED;
[email protected]7cbc6df12010-10-04 16:25:39916 }
[email protected]0ef0bcf2009-04-03 20:39:43917
[email protected]cc50fdf72010-11-30 17:48:54918 // Don't do V2 compatible hellos because they don't support TLS extensions.
919 rv = SSL_OptionSet(nss_fd_, SSL_V2_COMPATIBLE_HELLO, PR_FALSE);
[email protected]7cbc6df12010-10-04 16:25:39920 if (rv != SECSuccess) {
921 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_V2_COMPATIBLE_HELLO");
922 return ERR_UNEXPECTED;
923 }
[email protected]0ef0bcf2009-04-03 20:39:43924
925 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL3, ssl_config_.ssl3_enabled);
[email protected]7cbc6df12010-10-04 16:25:39926 if (rv != SECSuccess) {
927 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL3");
928 return ERR_UNEXPECTED;
929 }
[email protected]0ef0bcf2009-04-03 20:39:43930
931 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_TLS, ssl_config_.tls1_enabled);
[email protected]7cbc6df12010-10-04 16:25:39932 if (rv != SECSuccess) {
933 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_TLS");
934 return ERR_UNEXPECTED;
935 }
[email protected]0ef0bcf2009-04-03 20:39:43936
[email protected]47f7d742010-11-11 04:12:53937 for (std::vector<uint16>::const_iterator it =
938 ssl_config_.disabled_cipher_suites.begin();
939 it != ssl_config_.disabled_cipher_suites.end(); ++it) {
940 // This will fail if the specified cipher is not implemented by NSS, but
941 // the failure is harmless.
942 SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE);
943 }
944
[email protected]0ef0bcf2009-04-03 20:39:43945#ifdef SSL_ENABLE_SESSION_TICKETS
946 // Support RFC 5077
947 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_TRUE);
[email protected]7cbc6df12010-10-04 16:25:39948 if (rv != SECSuccess) {
949 LogFailedNSSFunction(
950 net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS");
951 }
[email protected]0ef0bcf2009-04-03 20:39:43952#else
953 #error "You need to install NSS-3.12 or later to build chromium"
954#endif
955
[email protected]7e52ed72009-11-17 00:40:12956#ifdef SSL_ENABLE_DEFLATE
[email protected]074c1582010-01-08 21:38:28957 // Some web servers have been found to break if TLS is used *or* if DEFLATE
958 // is advertised. Thus, if TLS is disabled (probably because we are doing
959 // SSLv3 fallback), we disable DEFLATE also.
960 // See http://crbug.com/31628
961 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_DEFLATE, ssl_config_.tls1_enabled);
[email protected]7e52ed72009-11-17 00:40:12962 if (rv != SECSuccess)
[email protected]7cbc6df12010-10-04 16:25:39963 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_DEFLATE");
[email protected]7e52ed72009-11-17 00:40:12964#endif
965
[email protected]c2def1c2010-03-02 21:40:34966#ifdef SSL_ENABLE_FALSE_START
[email protected]a0deaecf2010-08-18 23:39:52967 rv = SSL_OptionSet(
968 nss_fd_, SSL_ENABLE_FALSE_START,
969 ssl_config_.false_start_enabled &&
[email protected]4f4de7e62010-11-12 19:55:27970 !SSLConfigService::IsKnownFalseStartIncompatibleServer(
971 host_and_port_.host()));
[email protected]c2def1c2010-03-02 21:40:34972 if (rv != SECSuccess)
[email protected]7cbc6df12010-10-04 16:25:39973 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_FALSE_START");
[email protected]c2def1c2010-03-02 21:40:34974#endif
975
[email protected]7a8de3072010-10-01 16:25:54976#ifdef SSL_ENABLE_SNAP_START
977 // TODO(agl): check that SSL_ENABLE_SNAP_START actually does something in the
978 // current NSS code.
[email protected]4d52f192010-10-11 17:00:30979 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SNAP_START,
[email protected]09125792010-11-03 23:23:22980 ssl_config_.snap_start_enabled);
[email protected]7a8de3072010-10-01 16:25:54981 if (rv != SECSuccess)
[email protected]b30a3f52010-10-16 01:05:46982 VLOG(1) << "SSL_ENABLE_SNAP_START failed. Old system nss?";
[email protected]7a8de3072010-10-01 16:25:54983#endif
984
[email protected]33b3eb92010-01-06 01:35:04985#ifdef SSL_ENABLE_RENEGOTIATION
[email protected]304b0e352010-09-13 18:10:08986 // Deliberately disable this check for now: http://crbug.com/55410
987 if (false &&
[email protected]4f4de7e62010-11-12 19:55:27988 SSLConfigService::IsKnownStrictTLSServer(host_and_port_.host()) &&
[email protected]944a0a12010-08-19 20:02:28989 !ssl_config_.mitm_proxies_allowed) {
[email protected]d102f542010-06-30 14:51:05990 rv = SSL_OptionSet(nss_fd_, SSL_REQUIRE_SAFE_NEGOTIATION, PR_TRUE);
[email protected]7cbc6df12010-10-04 16:25:39991 if (rv != SECSuccess) {
992 LogFailedNSSFunction(
993 net_log_, "SSL_OptionSet", "SSL_REQUIRE_SAFE_NEGOTIATION");
994 }
[email protected]d102f542010-06-30 14:51:05995 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION,
996 SSL_RENEGOTIATE_REQUIRES_XTN);
997 } else {
998 // We allow servers to request renegotiation. Since we're a client,
999 // prohibiting this is rather a waste of time. Only servers are in a
1000 // position to prevent renegotiation attacks.
1001 // http://extendedsubset.com/?p=8
1002
1003 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION,
[email protected]e7bad86e2010-08-17 00:56:401004 SSL_RENEGOTIATE_TRANSITIONAL);
[email protected]d102f542010-06-30 14:51:051005 }
[email protected]7cbc6df12010-10-04 16:25:391006 if (rv != SECSuccess) {
1007 LogFailedNSSFunction(
1008 net_log_, "SSL_OptionSet", "SSL_ENABLE_RENEGOTIATION");
1009 }
[email protected]d102f542010-06-30 14:51:051010#endif // SSL_ENABLE_RENEGOTIATION
[email protected]33b3eb92010-01-06 01:35:041011
[email protected]644bdca2009-11-30 20:40:531012#ifdef SSL_NEXT_PROTO_NEGOTIATED
1013 if (!ssl_config_.next_protos.empty()) {
1014 rv = SSL_SetNextProtoNego(
1015 nss_fd_,
1016 reinterpret_cast<const unsigned char *>(ssl_config_.next_protos.data()),
1017 ssl_config_.next_protos.size());
1018 if (rv != SECSuccess)
[email protected]7cbc6df12010-10-04 16:25:391019 LogFailedNSSFunction(net_log_, "SSL_SetNextProtoNego", "");
[email protected]644bdca2009-11-30 20:40:531020 }
1021#endif
1022
[email protected]71d6ccaa2011-01-06 17:43:211023#ifdef SSL_ENABLE_OCSP_STAPLING
[email protected]35a43f92011-02-09 04:39:481024 if (IsOCSPStaplingSupported() && !ssl_config_.snap_start_enabled) {
[email protected]71d6ccaa2011-01-06 17:43:211025 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE);
1026 if (rv != SECSuccess)
1027 LogFailedNSSFunction(net_log_, "SSL_OptionSet (OCSP stapling)", "");
1028 }
1029#endif
1030
[email protected]0ef0bcf2009-04-03 20:39:431031 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
[email protected]7cbc6df12010-10-04 16:25:391032 if (rv != SECSuccess) {
1033 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT");
1034 return ERR_UNEXPECTED;
1035 }
[email protected]0ef0bcf2009-04-03 20:39:431036
1037 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this);
[email protected]7cbc6df12010-10-04 16:25:391038 if (rv != SECSuccess) {
1039 LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", "");
1040 return ERR_UNEXPECTED;
1041 }
[email protected]0ef0bcf2009-04-03 20:39:431042
[email protected]4a842342010-11-04 16:21:331043#if defined(NSS_PLATFORM_CLIENT_AUTH)
1044 rv = SSL_GetPlatformClientAuthDataHook(nss_fd_, PlatformClientAuthHandler,
1045 this);
1046#else
[email protected]d84b3722009-10-15 21:23:371047 rv = SSL_GetClientAuthDataHook(nss_fd_, ClientAuthHandler, this);
[email protected]4a842342010-11-04 16:21:331048#endif
[email protected]7cbc6df12010-10-04 16:25:391049 if (rv != SECSuccess) {
1050 LogFailedNSSFunction(net_log_, "SSL_GetClientAuthDataHook", "");
1051 return ERR_UNEXPECTED;
1052 }
[email protected]d84b3722009-10-15 21:23:371053
[email protected]2345cc52009-06-04 09:18:471054 rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this);
[email protected]7cbc6df12010-10-04 16:25:391055 if (rv != SECSuccess) {
1056 LogFailedNSSFunction(net_log_, "SSL_HandshakeCallback", "");
[email protected]2345cc52009-06-04 09:18:471057 return ERR_UNEXPECTED;
[email protected]7cbc6df12010-10-04 16:25:391058 }
[email protected]0ef0bcf2009-04-03 20:39:431059
1060 // Tell SSL the hostname we're trying to connect to.
[email protected]4f4de7e62010-11-12 19:55:271061 SSL_SetURL(nss_fd_, host_and_port_.host().c_str());
[email protected]0ef0bcf2009-04-03 20:39:431062
[email protected]7f7e92392010-10-26 18:29:291063 // Tell SSL we're a client; needed if not letting NSPR do socket I/O
1064 SSL_ResetHandshake(nss_fd_, 0);
1065
1066 return OK;
1067}
1068
1069int SSLClientSocketNSS::InitializeSSLPeerName() {
1070 // Tell NSS who we're connected to
1071 AddressList peer_address;
1072 int err = transport_->socket()->GetPeerAddress(&peer_address);
1073 if (err != OK)
1074 return err;
1075
1076 const struct addrinfo* ai = peer_address.head();
1077
1078 PRNetAddr peername;
1079 memset(&peername, 0, sizeof(peername));
1080 DCHECK_LE(ai->ai_addrlen, sizeof(peername));
1081 size_t len = std::min(static_cast<size_t>(ai->ai_addrlen),
1082 sizeof(peername));
1083 memcpy(&peername, ai->ai_addr, len);
1084
1085 // Adjust the address family field for BSD, whose sockaddr
1086 // structure has a one-byte length and one-byte address family
1087 // field at the beginning. PRNetAddr has a two-byte address
1088 // family field at the beginning.
1089 peername.raw.family = ai->ai_addr->sa_family;
1090
1091 memio_SetPeerName(nss_fd_, &peername);
1092
[email protected]52c27fb2009-11-30 22:40:231093 // Set the peer ID for session reuse. This is necessary when we create an
1094 // SSL tunnel through a proxy -- GetPeerName returns the proxy's address
1095 // rather than the destination server's address in that case.
[email protected]4f4de7e62010-11-12 19:55:271096 std::string peer_id = host_and_port_.ToString();
[email protected]7f7e92392010-10-26 18:29:291097 SECStatus rv = SSL_SetSockPeerID(nss_fd_, const_cast<char*>(peer_id.c_str()));
[email protected]52c27fb2009-11-30 22:40:231098 if (rv != SECSuccess)
[email protected]7cbc6df12010-10-04 16:25:391099 LogFailedNSSFunction(net_log_, "SSL_SetSockPeerID", peer_id.c_str());
[email protected]52c27fb2009-11-30 22:40:231100
[email protected]7f7e92392010-10-26 18:29:291101 peername_initialized_ = true;
[email protected]5a05c47a2009-11-02 23:25:191102 return OK;
[email protected]b43c97c2008-10-22 19:50:581103}
1104
[email protected]2d6e77832010-11-10 22:13:461105
[email protected]757f2e2b2010-10-27 23:28:351106// Sets server_cert_ and server_cert_nss_ if not yet set.
1107// Returns server_cert_.
[email protected]bacff652009-03-31 17:50:331108X509Certificate *SSLClientSocketNSS::UpdateServerCert() {
[email protected]757f2e2b2010-10-27 23:28:351109 // We set the server_cert_ from HandshakeCallback().
[email protected]bacff652009-03-31 17:50:331110 if (server_cert_ == NULL) {
[email protected]f505a9b2010-01-28 19:44:021111 server_cert_nss_ = SSL_PeerCertificate(nss_fd_);
1112 if (server_cert_nss_) {
[email protected]4feca4b2010-10-28 16:50:321113 PeerCertificateChain certs(nss_fd_);
[email protected]d8fbf582010-11-04 21:51:121114 server_cert_ = X509Certificate::CreateFromDERCertChain(
1115 certs.AsStringPieceVector());
[email protected]bacff652009-03-31 17:50:331116 }
1117 }
1118 return server_cert_;
1119}
1120
[email protected]757f2e2b2010-10-27 23:28:351121// Sets ssl_connection_status_.
1122void SSLClientSocketNSS::UpdateConnectionStatus() {
1123 SSLChannelInfo channel_info;
1124 SECStatus ok = SSL_GetChannelInfo(nss_fd_,
1125 &channel_info, sizeof(channel_info));
1126 if (ok == SECSuccess &&
1127 channel_info.length == sizeof(channel_info) &&
1128 channel_info.cipherSuite) {
1129 ssl_connection_status_ |=
1130 (static_cast<int>(channel_info.cipherSuite) &
1131 SSL_CONNECTION_CIPHERSUITE_MASK) <<
1132 SSL_CONNECTION_CIPHERSUITE_SHIFT;
1133
1134 ssl_connection_status_ |=
1135 (static_cast<int>(channel_info.compressionMethod) &
1136 SSL_CONNECTION_COMPRESSION_MASK) <<
1137 SSL_CONNECTION_COMPRESSION_SHIFT;
1138
[email protected]b92a96e2010-11-02 21:03:051139 // NSS 3.12.x doesn't have version macros for TLS 1.1 and 1.2 (because NSS
1140 // doesn't support them yet), so we use 0x0302 and 0x0303 directly.
[email protected]757f2e2b2010-10-27 23:28:351141 int version = SSL_CONNECTION_VERSION_UNKNOWN;
1142 if (channel_info.protocolVersion < SSL_LIBRARY_VERSION_3_0) {
1143 // All versions less than SSL_LIBRARY_VERSION_3_0 are treated as SSL
1144 // version 2.
1145 version = SSL_CONNECTION_VERSION_SSL2;
1146 } else if (channel_info.protocolVersion == SSL_LIBRARY_VERSION_3_0) {
1147 version = SSL_CONNECTION_VERSION_SSL3;
1148 } else if (channel_info.protocolVersion == SSL_LIBRARY_VERSION_3_1_TLS) {
1149 version = SSL_CONNECTION_VERSION_TLS1;
[email protected]b92a96e2010-11-02 21:03:051150 } else if (channel_info.protocolVersion == 0x0302) {
1151 version = SSL_CONNECTION_VERSION_TLS1_1;
1152 } else if (channel_info.protocolVersion == 0x0303) {
1153 version = SSL_CONNECTION_VERSION_TLS1_2;
[email protected]757f2e2b2010-10-27 23:28:351154 }
1155 ssl_connection_status_ |=
1156 (version & SSL_CONNECTION_VERSION_MASK) <<
1157 SSL_CONNECTION_VERSION_SHIFT;
1158 }
1159
[email protected]1e7cd2c72010-02-27 01:31:191160 // SSL_HandshakeNegotiatedExtension was added in NSS 3.12.6.
1161 // Since SSL_MAX_EXTENSIONS was added at the same time, we can test
1162 // SSL_MAX_EXTENSIONS for the presence of SSL_HandshakeNegotiatedExtension.
1163#if defined(SSL_MAX_EXTENSIONS)
[email protected]757f2e2b2010-10-27 23:28:351164 PRBool peer_supports_renego_ext;
1165 ok = SSL_HandshakeNegotiatedExtension(nss_fd_, ssl_renegotiation_info_xtn,
1166 &peer_supports_renego_ext);
1167 if (ok == SECSuccess) {
1168 if (!peer_supports_renego_ext) {
1169 ssl_connection_status_ |= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION;
1170 // Log an informational message if the server does not support secure
1171 // renegotiation (RFC 5746).
[email protected]4f4de7e62010-11-12 19:55:271172 VLOG(1) << "The server " << host_and_port_.ToString()
[email protected]757f2e2b2010-10-27 23:28:351173 << " does not support the TLS renegotiation_info extension.";
1174 }
1175 UMA_HISTOGRAM_ENUMERATION("Net.RenegotiationExtensionSupported",
1176 peer_supports_renego_ext, 2);
[email protected]1e7cd2c72010-02-27 01:31:191177 }
1178#endif
[email protected]757f2e2b2010-10-27 23:28:351179
1180 if (ssl_config_.ssl3_fallback)
1181 ssl_connection_status_ |= SSL_CONNECTION_SSL3_FALLBACK;
[email protected]1e7cd2c72010-02-27 01:31:191182}
1183
[email protected]a3ff5e92009-10-13 04:48:061184void SSLClientSocketNSS::DoReadCallback(int rv) {
[email protected]e17b4c12008-11-05 22:04:081185 EnterFunction(rv);
[email protected]b43c97c2008-10-22 19:50:581186 DCHECK(rv != ERR_IO_PENDING);
[email protected]a3ff5e92009-10-13 04:48:061187 DCHECK(user_read_callback_);
[email protected]b43c97c2008-10-22 19:50:581188
[email protected]a3ff5e92009-10-13 04:48:061189 // Since Run may result in Read being called, clear |user_read_callback_|
1190 // up front.
1191 CompletionCallback* c = user_read_callback_;
1192 user_read_callback_ = NULL;
1193 user_read_buf_ = NULL;
1194 user_read_buf_len_ = 0;
1195 c->Run(rv);
1196 LeaveFunction("");
1197}
1198
1199void SSLClientSocketNSS::DoWriteCallback(int rv) {
1200 EnterFunction(rv);
1201 DCHECK(rv != ERR_IO_PENDING);
1202 DCHECK(user_write_callback_);
1203
1204 // Since Run may result in Write being called, clear |user_write_callback_|
1205 // up front.
1206 CompletionCallback* c = user_write_callback_;
1207 user_write_callback_ = NULL;
1208 user_write_buf_ = NULL;
1209 user_write_buf_len_ = 0;
[email protected]b43c97c2008-10-22 19:50:581210 c->Run(rv);
[email protected]e17b4c12008-11-05 22:04:081211 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:581212}
1213
[email protected]a6eb576292009-06-30 16:19:001214// As part of Connect(), the SSLClientSocketNSS object performs an SSL
1215// handshake. This requires network IO, which in turn calls
1216// BufferRecvComplete() with a non-zero byte count. This byte count eventually
1217// winds its way through the state machine and ends up being passed to the
1218// callback. For Read() and Write(), that's what we want. But for Connect(),
1219// the caller expects OK (i.e. 0) for success.
1220//
1221void SSLClientSocketNSS::DoConnectCallback(int rv) {
1222 EnterFunction(rv);
1223 DCHECK_NE(rv, ERR_IO_PENDING);
[email protected]a6eb576292009-06-30 16:19:001224
[email protected]a6eb576292009-06-30 16:19:001225 CompletionCallback* c = user_connect_callback_;
1226 user_connect_callback_ = NULL;
1227 c->Run(rv > OK ? OK : rv);
1228 LeaveFunction("");
1229}
1230
[email protected]a3ff5e92009-10-13 04:48:061231void SSLClientSocketNSS::OnHandshakeIOComplete(int result) {
[email protected]e17b4c12008-11-05 22:04:081232 EnterFunction(result);
[email protected]a3ff5e92009-10-13 04:48:061233 int rv = DoHandshakeLoop(result);
[email protected]5a05c47a2009-11-02 23:25:191234 if (rv != ERR_IO_PENDING) {
[email protected]d7fd1782011-02-08 19:16:431235 net_log_.EndEventWithNetErrorCode(net::NetLog::TYPE_SSL_CONNECT, rv);
[email protected]7a8de3072010-10-01 16:25:541236 // If we pseudo connected for Snap Start, then we won't have a connect
1237 // callback.
1238 if (user_connect_callback_)
1239 DoConnectCallback(rv);
[email protected]5a05c47a2009-11-02 23:25:191240 }
[email protected]a3ff5e92009-10-13 04:48:061241 LeaveFunction("");
1242}
1243
1244void SSLClientSocketNSS::OnSendComplete(int result) {
1245 EnterFunction(result);
[email protected]45965de2010-02-25 23:23:311246 if (next_handshake_state_ == STATE_HANDSHAKE) {
[email protected]a3ff5e92009-10-13 04:48:061247 // In handshake phase.
1248 OnHandshakeIOComplete(result);
1249 LeaveFunction("");
1250 return;
[email protected]a6eb576292009-06-30 16:19:001251 }
[email protected]a3ff5e92009-10-13 04:48:061252
1253 // OnSendComplete may need to call DoPayloadRead while the renegotiation
1254 // handshake is in progress.
1255 int rv_read = ERR_IO_PENDING;
1256 int rv_write = ERR_IO_PENDING;
1257 bool network_moved;
1258 do {
1259 if (user_read_buf_)
1260 rv_read = DoPayloadRead();
1261 if (user_write_buf_)
1262 rv_write = DoPayloadWrite();
1263 network_moved = DoTransportIO();
1264 } while (rv_read == ERR_IO_PENDING &&
1265 rv_write == ERR_IO_PENDING &&
1266 network_moved);
1267
1268 if (user_read_buf_ && rv_read != ERR_IO_PENDING)
1269 DoReadCallback(rv_read);
1270 if (user_write_buf_ && rv_write != ERR_IO_PENDING)
1271 DoWriteCallback(rv_write);
1272
1273 LeaveFunction("");
1274}
1275
1276void SSLClientSocketNSS::OnRecvComplete(int result) {
1277 EnterFunction(result);
[email protected]45965de2010-02-25 23:23:311278 if (next_handshake_state_ == STATE_HANDSHAKE) {
[email protected]a3ff5e92009-10-13 04:48:061279 // In handshake phase.
1280 OnHandshakeIOComplete(result);
1281 LeaveFunction("");
1282 return;
1283 }
1284
1285 // Network layer received some data, check if client requested to read
[email protected]7a8de3072010-10-01 16:25:541286 // decrypted data or if we're waiting for the first write for Snap Start.
1287 if (!user_read_buf_ || !completed_handshake_) {
[email protected]a3ff5e92009-10-13 04:48:061288 LeaveFunction("");
1289 return;
1290 }
1291
1292 int rv = DoReadLoop(result);
1293 if (rv != ERR_IO_PENDING)
1294 DoReadCallback(rv);
[email protected]e17b4c12008-11-05 22:04:081295 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:581296}
1297
[email protected]a3ff5e92009-10-13 04:48:061298int SSLClientSocketNSS::DoHandshakeLoop(int last_io_result) {
[email protected]e17b4c12008-11-05 22:04:081299 EnterFunction(last_io_result);
[email protected]b43c97c2008-10-22 19:50:581300 bool network_moved;
1301 int rv = last_io_result;
1302 do {
[email protected]e17b4c12008-11-05 22:04:081303 // Default to STATE_NONE for next state.
[email protected]ea224582008-12-07 20:25:461304 // (This is a quirk carried over from the windows
[email protected]e17b4c12008-11-05 22:04:081305 // implementation. It makes reading the logs a bit harder.)
[email protected]ea224582008-12-07 20:25:461306 // State handlers can and often do call GotoState just
[email protected]e17b4c12008-11-05 22:04:081307 // to stay in the current state.
[email protected]a3ff5e92009-10-13 04:48:061308 State state = next_handshake_state_;
[email protected]e17b4c12008-11-05 22:04:081309 GotoState(STATE_NONE);
[email protected]b43c97c2008-10-22 19:50:581310 switch (state) {
[email protected]e17b4c12008-11-05 22:04:081311 case STATE_NONE:
1312 // we're just pumping data between the buffer and the network
1313 break;
[email protected]7a8de3072010-10-01 16:25:541314 case STATE_SNAP_START_LOAD_INFO:
1315 rv = DoSnapStartLoadInfo();
1316 break;
1317 case STATE_SNAP_START_WAIT_FOR_WRITE:
1318 rv = DoSnapStartWaitForWrite();
1319 break;
[email protected]a3ff5e92009-10-13 04:48:061320 case STATE_HANDSHAKE:
1321 rv = DoHandshake();
[email protected]b43c97c2008-10-22 19:50:581322 break;
[email protected]899c3e92010-08-28 15:53:501323 case STATE_VERIFY_DNSSEC:
1324 rv = DoVerifyDNSSEC(rv);
1325 break;
1326 case STATE_VERIFY_DNSSEC_COMPLETE:
1327 rv = DoVerifyDNSSECComplete(rv);
1328 break;
[email protected]2345cc52009-06-04 09:18:471329 case STATE_VERIFY_CERT:
1330 DCHECK(rv == OK);
1331 rv = DoVerifyCert(rv);
1332 break;
1333 case STATE_VERIFY_CERT_COMPLETE:
1334 rv = DoVerifyCertComplete(rv);
1335 break;
[email protected]b43c97c2008-10-22 19:50:581336 default:
1337 rv = ERR_UNEXPECTED;
[email protected]4e91b5c2010-09-22 01:04:381338 LOG(DFATAL) << "unexpected state " << state;
[email protected]b43c97c2008-10-22 19:50:581339 break;
1340 }
1341
1342 // Do the actual network I/O
[email protected]a3ff5e92009-10-13 04:48:061343 network_moved = DoTransportIO();
[email protected]72d1e592009-03-10 17:39:461344 } while ((rv != ERR_IO_PENDING || network_moved) &&
[email protected]7a8de3072010-10-01 16:25:541345 next_handshake_state_ != STATE_NONE);
[email protected]a3ff5e92009-10-13 04:48:061346 LeaveFunction("");
1347 return rv;
1348}
1349
1350int SSLClientSocketNSS::DoReadLoop(int result) {
1351 EnterFunction("");
1352 DCHECK(completed_handshake_);
1353 DCHECK(next_handshake_state_ == STATE_NONE);
1354
1355 if (result < 0)
1356 return result;
1357
[email protected]4e91b5c2010-09-22 01:04:381358 if (!nss_bufs_) {
1359 LOG(DFATAL) << "!nss_bufs_";
[email protected]7cbc6df12010-10-04 16:25:391360 int rv = ERR_UNEXPECTED;
[email protected]00cd9c42010-11-02 20:15:571361 net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR,
1362 make_scoped_refptr(new SSLErrorParams(rv, 0)));
[email protected]7cbc6df12010-10-04 16:25:391363 return rv;
[email protected]4e91b5c2010-09-22 01:04:381364 }
[email protected]a3ff5e92009-10-13 04:48:061365
1366 bool network_moved;
1367 int rv;
1368 do {
1369 rv = DoPayloadRead();
1370 network_moved = DoTransportIO();
1371 } while (rv == ERR_IO_PENDING && network_moved);
1372
1373 LeaveFunction("");
1374 return rv;
1375}
1376
1377int SSLClientSocketNSS::DoWriteLoop(int result) {
1378 EnterFunction("");
1379 DCHECK(completed_handshake_);
1380 DCHECK(next_handshake_state_ == STATE_NONE);
1381
1382 if (result < 0)
1383 return result;
1384
[email protected]4e91b5c2010-09-22 01:04:381385 if (!nss_bufs_) {
1386 LOG(DFATAL) << "!nss_bufs_";
[email protected]7cbc6df12010-10-04 16:25:391387 int rv = ERR_UNEXPECTED;
[email protected]00cd9c42010-11-02 20:15:571388 net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR,
1389 make_scoped_refptr(new SSLErrorParams(rv, 0)));
[email protected]7cbc6df12010-10-04 16:25:391390 return rv;
[email protected]4e91b5c2010-09-22 01:04:381391 }
[email protected]a3ff5e92009-10-13 04:48:061392
1393 bool network_moved;
1394 int rv;
1395 do {
1396 rv = DoPayloadWrite();
1397 network_moved = DoTransportIO();
1398 } while (rv == ERR_IO_PENDING && network_moved);
1399
[email protected]e17b4c12008-11-05 22:04:081400 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:581401 return rv;
1402}
1403
[email protected]d100e44f2011-01-26 22:47:111404int SSLClientSocketNSS::DoSnapStartLoadInfo() {
1405 EnterFunction("");
1406 int rv = ssl_host_info_->WaitForDataReady(&handshake_io_callback_);
1407 GotoState(STATE_HANDSHAKE);
1408
1409 if (rv == OK) {
1410 if (ssl_host_info_->WaitForCertVerification(NULL) == OK) {
1411 if (LoadSnapStartInfo()) {
1412 pseudo_connected_ = true;
1413 GotoState(STATE_SNAP_START_WAIT_FOR_WRITE);
1414 if (user_connect_callback_)
1415 DoConnectCallback(OK);
1416 }
1417 } else if (!ssl_host_info_->state().server_hello.empty()) {
1418 // A non-empty ServerHello suggests that we would have tried a Snap Start
1419 // connection.
1420 base::TimeTicks now = base::TimeTicks::Now();
1421 const base::TimeDelta duration =
1422 now - ssl_host_info_->verification_start_time();
1423 UMA_HISTOGRAM_TIMES("Net.SSLSnapStartNeededVerificationInMs", duration);
1424 VLOG(1) << "Cannot snap start because verification isn't ready. "
1425 << "Wanted verification after "
1426 << duration.InMilliseconds() << "ms";
1427 }
1428 } else {
1429 DCHECK_EQ(ERR_IO_PENDING, rv);
1430 GotoState(STATE_SNAP_START_LOAD_INFO);
1431 }
1432
1433 LeaveFunction("");
1434 return rv;
1435}
1436
1437int SSLClientSocketNSS::DoSnapStartWaitForWrite() {
1438 EnterFunction("");
1439 // In this state, we're waiting for the first Write call so that we can merge
1440 // it into the Snap Start handshake.
1441 if (!user_write_buf_) {
1442 // We'll lie and say that we're connected in order that someone will call
1443 // Write.
1444 GotoState(STATE_SNAP_START_WAIT_FOR_WRITE);
1445 DCHECK(!user_connect_callback_);
1446 LeaveFunction("");
1447 return ERR_IO_PENDING;
1448 }
1449
1450 // This is the largest Snap Start application data payload that we'll try to
1451 // use. A TCP client can only send three frames of data without an ACK and,
1452 // at 2048 bytes, this leaves some space for the rest of the ClientHello
1453 // (including possible session ticket).
1454 static const int kMaxSnapStartPayloadSize = 2048;
1455
1456 if (user_write_buf_len_ > kMaxSnapStartPayloadSize) {
1457 user_write_buf_len_ = kMaxSnapStartPayloadSize;
1458 // When we complete the handshake and call user_write_callback_ we'll say
1459 // that we only wrote |kMaxSnapStartPayloadSize| bytes. That way the rest
1460 // of the payload will be presented to |Write| again and transmitted as
1461 // normal application data.
1462 }
1463
1464 SECStatus rv = SSL_SetSnapStartApplicationData(
1465 nss_fd_, reinterpret_cast<const unsigned char*>(user_write_buf_->data()),
1466 user_write_buf_len_);
1467 DCHECK_EQ(SECSuccess, rv);
1468
1469 GotoState(STATE_HANDSHAKE);
1470 LeaveFunction("");
1471 return OK;
1472}
1473
1474int SSLClientSocketNSS::DoHandshake() {
1475 EnterFunction("");
1476 int net_error = net::OK;
1477 SECStatus rv = SSL_ForceHandshake(nss_fd_);
1478
1479 if (client_auth_cert_needed_) {
1480 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
1481 net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR,
1482 make_scoped_refptr(new SSLErrorParams(net_error, 0)));
1483 // If the handshake already succeeded (because the server requests but
1484 // doesn't require a client cert), we need to invalidate the SSL session
1485 // so that we won't try to resume the non-client-authenticated session in
1486 // the next handshake. This will cause the server to ask for a client
1487 // cert again.
1488 if (rv == SECSuccess && SSL_InvalidateSession(nss_fd_) != SECSuccess) {
1489 LOG(WARNING) << "Couldn't invalidate SSL session: " << PR_GetError();
1490 }
1491 } else if (rv == SECSuccess) {
1492 if (handshake_callback_called_) {
1493 if (eset_mitm_detected_) {
1494 net_error = ERR_ESET_ANTI_VIRUS_SSL_INTERCEPTION;
1495 } else {
1496 // We need to see if the predicted certificate chain (in
1497 // |ssl_host_info_->state().certs) matches the actual certificate chain
1498 // before we call SaveSnapStartInfo, as that will update
1499 // |ssl_host_info_|.
1500 if (ssl_host_info_.get() && !ssl_host_info_->state().certs.empty()) {
1501 PeerCertificateChain certs(nss_fd_);
1502 const SSLHostInfo::State& state = ssl_host_info_->state();
1503 predicted_cert_chain_correct_ = certs.size() == state.certs.size();
1504 if (predicted_cert_chain_correct_) {
1505 for (unsigned i = 0; i < certs.size(); i++) {
1506 if (certs[i]->derCert.len != state.certs[i].size() ||
1507 memcmp(certs[i]->derCert.data, state.certs[i].data(),
1508 certs[i]->derCert.len) != 0) {
1509 predicted_cert_chain_correct_ = false;
1510 break;
1511 }
1512 }
1513 }
1514 }
1515
1516#if defined(SSL_ENABLE_OCSP_STAPLING)
[email protected]35a43f92011-02-09 04:39:481517 // TODO(agl): figure out how to plumb an OCSP response into the Mac
1518 // system library and update IsOCSPStaplingSupported for Mac.
1519 if (!predicted_cert_chain_correct_ && IsOCSPStaplingSupported()) {
[email protected]d100e44f2011-01-26 22:47:111520 unsigned int len = 0;
1521 SSL_GetStapledOCSPResponse(nss_fd_, NULL, &len);
1522 if (len) {
1523 const unsigned int orig_len = len;
1524 scoped_array<uint8> ocsp_response(new uint8[orig_len]);
1525 SSL_GetStapledOCSPResponse(nss_fd_, ocsp_response.get(), &len);
1526 DCHECK_EQ(orig_len, len);
1527
[email protected]35a43f92011-02-09 04:39:481528#if defined(OS_WIN)
1529 CRYPT_DATA_BLOB ocsp_response_blob;
1530 ocsp_response_blob.cbData = len;
1531 ocsp_response_blob.pbData = ocsp_response.get();
1532 BOOL ok = CertSetCertificateContextProperty(
1533 server_cert_->os_cert_handle(),
1534 CERT_OCSP_RESPONSE_PROP_ID,
1535 CERT_SET_PROPERTY_IGNORE_PERSIST_ERROR_FLAG,
1536 &ocsp_response_blob);
1537 if (!ok) {
1538 VLOG(1) << "Failed to set OCSP response property: "
1539 << GetLastError();
1540 }
1541#elif defined(USE_NSS)
1542 CacheOCSPResponseFromSideChannelFunction cache_ocsp_response =
1543 GetCacheOCSPResponseFromSideChannelFunction();
[email protected]d100e44f2011-01-26 22:47:111544 SECItem ocsp_response_item;
1545 ocsp_response_item.type = siBuffer;
1546 ocsp_response_item.data = ocsp_response.get();
1547 ocsp_response_item.len = len;
1548
1549 cache_ocsp_response(
1550 CERT_GetDefaultCertDB(), server_cert_nss_, PR_Now(),
1551 &ocsp_response_item, NULL);
[email protected]35a43f92011-02-09 04:39:481552#endif
[email protected]d100e44f2011-01-26 22:47:111553 }
1554 }
1555#endif
1556
1557 SaveSnapStartInfo();
1558 // SSL handshake is completed. It's possible that we mispredicted the
1559 // NPN agreed protocol. In this case, we've just sent a request in the
1560 // wrong protocol! The higher levels of this network stack aren't
1561 // prepared for switching the protocol like that so we make up an error
1562 // and rely on the fact that the request will be retried.
1563 if (IsNPNProtocolMispredicted()) {
1564 LOG(WARNING) << "Mispredicted NPN protocol for "
1565 << host_and_port_.ToString();
1566 net_error = ERR_SSL_SNAP_START_NPN_MISPREDICTION;
1567 } else {
1568 // Let's verify the certificate.
1569 GotoState(STATE_VERIFY_DNSSEC);
1570 }
1571 }
1572 // Done!
1573 } else {
1574 // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=562434 -
1575 // SSL_ForceHandshake returned SECSuccess prematurely.
1576 rv = SECFailure;
1577 net_error = ERR_SSL_PROTOCOL_ERROR;
1578 net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR,
1579 make_scoped_refptr(new SSLErrorParams(net_error, 0)));
1580 }
1581 } else {
1582 PRErrorCode prerr = PR_GetError();
[email protected]83530b72011-02-05 04:53:131583 net_error = HandleNSSError(prerr, true);
[email protected]d100e44f2011-01-26 22:47:111584
1585 // If not done, stay in this state
1586 if (net_error == ERR_IO_PENDING) {
1587 GotoState(STATE_HANDSHAKE);
1588 } else {
1589 LOG(ERROR) << "handshake failed; NSS error code " << prerr
1590 << ", net_error " << net_error;
1591 net_log_.AddEvent(
1592 NetLog::TYPE_SSL_HANDSHAKE_ERROR,
1593 make_scoped_refptr(new SSLErrorParams(net_error, prerr)));
1594 }
1595 }
1596
1597 LeaveFunction("");
1598 return net_error;
1599}
1600
1601int SSLClientSocketNSS::DoVerifyDNSSEC(int result) {
1602 if (ssl_config_.dns_cert_provenance_checking_enabled &&
1603 dns_cert_checker_) {
1604 PeerCertificateChain certs(nss_fd_);
1605 dns_cert_checker_->DoAsyncVerification(
1606 host_and_port_.host(), certs.AsStringPieceVector());
1607 }
1608
1609 if (ssl_config_.dnssec_enabled) {
1610 DNSValidationResult r = CheckDNSSECChain(host_and_port_.host(),
1611 server_cert_nss_);
1612 if (r == DNSVR_SUCCESS) {
1613 local_server_cert_verify_result_.cert_status |= CERT_STATUS_IS_DNSSEC;
1614 server_cert_verify_result_ = &local_server_cert_verify_result_;
1615 GotoState(STATE_VERIFY_CERT_COMPLETE);
1616 return OK;
1617 }
1618 }
1619
1620 if (dnssec_provider_ == NULL) {
1621 GotoState(STATE_VERIFY_CERT);
1622 return OK;
1623 }
1624
1625 GotoState(STATE_VERIFY_DNSSEC_COMPLETE);
1626 RRResponse* response;
1627 dnssec_wait_start_time_ = base::Time::Now();
1628 return dnssec_provider_->GetDNSSECRecords(&response, &handshake_io_callback_);
1629}
1630
1631int SSLClientSocketNSS::DoVerifyDNSSECComplete(int result) {
1632 RRResponse* response;
1633 int err = dnssec_provider_->GetDNSSECRecords(&response, NULL);
1634 DCHECK_EQ(err, OK);
1635
1636 const base::TimeDelta elapsed = base::Time::Now() - dnssec_wait_start_time_;
1637 HISTOGRAM_TIMES("Net.DNSSECWaitTime", elapsed);
1638
1639 GotoState(STATE_VERIFY_CERT);
1640 if (!response || response->rrdatas.empty())
1641 return OK;
1642
1643 std::vector<base::StringPiece> records;
1644 records.resize(response->rrdatas.size());
1645 for (unsigned i = 0; i < response->rrdatas.size(); i++)
1646 records[i] = base::StringPiece(response->rrdatas[i]);
1647 DNSValidationResult r =
1648 VerifyTXTRecords(response->dnssec, server_cert_nss_, records);
1649
1650 if (!ssl_config_.dnssec_enabled) {
1651 // If DNSSEC is not enabled we don't take any action based on the result,
1652 // except to record the latency, above.
1653 return OK;
1654 }
1655
1656 switch (r) {
1657 case DNSVR_FAILURE:
1658 GotoState(STATE_VERIFY_CERT_COMPLETE);
1659 local_server_cert_verify_result_.cert_status |= CERT_STATUS_NOT_IN_DNS;
1660 server_cert_verify_result_ = &local_server_cert_verify_result_;
1661 return ERR_CERT_NOT_IN_DNS;
1662 case DNSVR_CONTINUE:
1663 GotoState(STATE_VERIFY_CERT);
1664 break;
1665 case DNSVR_SUCCESS:
1666 local_server_cert_verify_result_.cert_status |= CERT_STATUS_IS_DNSSEC;
1667 server_cert_verify_result_ = &local_server_cert_verify_result_;
1668 GotoState(STATE_VERIFY_CERT_COMPLETE);
1669 break;
1670 default:
1671 NOTREACHED();
1672 GotoState(STATE_VERIFY_CERT);
1673 }
1674
1675 return OK;
1676}
1677
1678int SSLClientSocketNSS::DoVerifyCert(int result) {
1679 DCHECK(server_cert_);
1680
1681 GotoState(STATE_VERIFY_CERT_COMPLETE);
1682 start_cert_verification_time_ = base::TimeTicks::Now();
1683
1684 if (ssl_host_info_.get() && !ssl_host_info_->state().certs.empty() &&
1685 predicted_cert_chain_correct_) {
1686 // If the SSLHostInfo had a prediction for the certificate chain of this
1687 // server then it will have optimistically started a verification of that
1688 // chain. So, if the prediction was correct, we should wait for that
1689 // verification to finish rather than start our own.
1690 net_log_.AddEvent(NetLog::TYPE_SSL_VERIFICATION_MERGED, NULL);
1691 UMA_HISTOGRAM_ENUMERATION("Net.SSLVerificationMerged", 1 /* true */, 2);
1692 base::TimeTicks end_time = ssl_host_info_->verification_end_time();
1693 if (end_time.is_null())
1694 end_time = base::TimeTicks::Now();
1695 UMA_HISTOGRAM_TIMES("Net.SSLVerificationMergedMsSaved",
1696 end_time - ssl_host_info_->verification_start_time());
1697 server_cert_verify_result_ = &ssl_host_info_->cert_verify_result();
1698 return ssl_host_info_->WaitForCertVerification(&handshake_io_callback_);
1699 } else {
1700 UMA_HISTOGRAM_ENUMERATION("Net.SSLVerificationMerged", 0 /* false */, 2);
1701 }
1702
1703 int flags = 0;
1704 if (ssl_config_.rev_checking_enabled)
1705 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED;
1706 if (ssl_config_.verify_ev_cert)
1707 flags |= X509Certificate::VERIFY_EV_CERT;
1708 verifier_.reset(new SingleRequestCertVerifier(cert_verifier_));
1709 server_cert_verify_result_ = &local_server_cert_verify_result_;
1710 return verifier_->Verify(server_cert_, host_and_port_.host(), flags,
1711 &local_server_cert_verify_result_,
1712 &handshake_io_callback_);
1713}
1714
1715// Derived from AuthCertificateCallback() in
1716// mozilla/source/security/manager/ssl/src/nsNSSCallbacks.cpp.
1717int SSLClientSocketNSS::DoVerifyCertComplete(int result) {
1718 verifier_.reset();
1719
1720 if (!start_cert_verification_time_.is_null()) {
1721 base::TimeDelta verify_time =
1722 base::TimeTicks::Now() - start_cert_verification_time_;
1723 if (result == OK)
1724 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTime", verify_time);
1725 else
1726 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTimeError", verify_time);
1727 }
1728
[email protected]d100e44f2011-01-26 22:47:111729 // We used to remember the intermediate CA certs in the NSS database
1730 // persistently. However, NSS opens a connection to the SQLite database
1731 // during NSS initialization and doesn't close the connection until NSS
1732 // shuts down. If the file system where the database resides is gone,
1733 // the database connection goes bad. What's worse, the connection won't
1734 // recover when the file system comes back. Until this NSS or SQLite bug
1735 // is fixed, we need to avoid using the NSS database for non-essential
1736 // purposes. See https://bugzilla.mozilla.org/show_bug.cgi?id=508081 and
1737 // http://crbug.com/15630 for more info.
1738
1739 // If we have been explicitly told to accept this certificate, override the
1740 // result of verifier_.Verify.
1741 // Eventually, we should cache the cert verification results so that we don't
1742 // need to call verifier_.Verify repeatedly. But for now we need to do this.
1743 // Alternatively, we could use the cert's status that we stored along with
1744 // the cert in the allowed_bad_certs vector.
1745 if (IsCertificateError(result) &&
1746 ssl_config_.IsAllowedBadCert(server_cert_)) {
1747 VLOG(1) << "accepting bad SSL certificate, as user told us to";
1748 result = OK;
1749 }
1750
1751 if (result == OK)
1752 LogConnectionTypeMetrics();
1753
1754 completed_handshake_ = true;
1755
1756 // If we merged a Write call into the handshake we need to make the
1757 // callback now.
1758 if (user_write_callback_) {
1759 corked_ = false;
1760 if (result != OK) {
1761 DoWriteCallback(result);
1762 } else {
1763 SSLSnapStartResult snap_start_type;
1764 SECStatus rv = SSL_GetSnapStartResult(nss_fd_, &snap_start_type);
1765 DCHECK_EQ(rv, SECSuccess);
1766 DCHECK_NE(snap_start_type, SSL_SNAP_START_NONE);
1767 if (snap_start_type == SSL_SNAP_START_RECOVERY ||
1768 snap_start_type == SSL_SNAP_START_RESUME_RECOVERY) {
1769 // If we mispredicted the server's handshake then Snap Start will have
1770 // triggered a recovery mode. The misprediction could have been caused
1771 // by the server having a different certificate so the application data
1772 // wasn't resent. Now that we have verified the certificate, we need to
1773 // resend the application data.
1774 int bytes_written = DoPayloadWrite();
1775 if (bytes_written != ERR_IO_PENDING)
1776 DoWriteCallback(bytes_written);
1777 } else {
1778 DoWriteCallback(user_write_buf_len_);
1779 }
1780 }
1781 }
1782
1783 if (user_read_callback_) {
1784 int rv = DoReadLoop(OK);
1785 if (rv != ERR_IO_PENDING)
1786 DoReadCallback(rv);
1787 }
1788
1789 // Exit DoHandshakeLoop and return the result to the caller to Connect.
1790 DCHECK(next_handshake_state_ == STATE_NONE);
1791 return result;
1792}
1793
1794int SSLClientSocketNSS::DoPayloadRead() {
1795 EnterFunction(user_read_buf_len_);
1796 DCHECK(user_read_buf_);
1797 DCHECK_GT(user_read_buf_len_, 0);
1798 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_);
1799 if (client_auth_cert_needed_) {
1800 // We don't need to invalidate the non-client-authenticated SSL session
1801 // because the server will renegotiate anyway.
1802 LeaveFunction("");
1803 rv = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
1804 net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR,
1805 make_scoped_refptr(new SSLErrorParams(rv, 0)));
1806 return rv;
1807 }
1808 if (rv >= 0) {
1809 LogData(user_read_buf_->data(), rv);
1810 LeaveFunction("");
1811 return rv;
1812 }
1813 PRErrorCode prerr = PR_GetError();
1814 if (prerr == PR_WOULD_BLOCK_ERROR) {
1815 LeaveFunction("");
1816 return ERR_IO_PENDING;
1817 }
1818 LeaveFunction("");
[email protected]83530b72011-02-05 04:53:131819 rv = HandleNSSError(prerr, false);
[email protected]d100e44f2011-01-26 22:47:111820 net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR,
1821 make_scoped_refptr(new SSLErrorParams(rv, prerr)));
1822 return rv;
1823}
1824
1825int SSLClientSocketNSS::DoPayloadWrite() {
1826 EnterFunction(user_write_buf_len_);
1827 DCHECK(user_write_buf_);
1828 int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_);
1829 if (rv >= 0) {
1830 LogData(user_write_buf_->data(), rv);
1831 LeaveFunction("");
1832 return rv;
1833 }
1834 PRErrorCode prerr = PR_GetError();
1835 if (prerr == PR_WOULD_BLOCK_ERROR) {
1836 LeaveFunction("");
1837 return ERR_IO_PENDING;
1838 }
1839 LeaveFunction("");
[email protected]83530b72011-02-05 04:53:131840 rv = HandleNSSError(prerr, false);
[email protected]d100e44f2011-01-26 22:47:111841 net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR,
1842 make_scoped_refptr(new SSLErrorParams(rv, prerr)));
1843 return rv;
1844}
1845
1846void SSLClientSocketNSS::LogConnectionTypeMetrics() const {
1847 UpdateConnectionTypeHistograms(CONNECTION_SSL);
1848 if (server_cert_verify_result_->has_md5)
1849 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5);
1850 if (server_cert_verify_result_->has_md2)
1851 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2);
1852 if (server_cert_verify_result_->has_md4)
1853 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD4);
1854 if (server_cert_verify_result_->has_md5_ca)
1855 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5_CA);
1856 if (server_cert_verify_result_->has_md2_ca)
1857 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2_CA);
1858 int ssl_version = SSLConnectionStatusToVersion(ssl_connection_status_);
1859 switch (ssl_version) {
1860 case SSL_CONNECTION_VERSION_SSL2:
1861 UpdateConnectionTypeHistograms(CONNECTION_SSL_SSL2);
1862 break;
1863 case SSL_CONNECTION_VERSION_SSL3:
1864 UpdateConnectionTypeHistograms(CONNECTION_SSL_SSL3);
1865 break;
1866 case SSL_CONNECTION_VERSION_TLS1:
1867 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1);
1868 break;
1869 case SSL_CONNECTION_VERSION_TLS1_1:
1870 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_1);
1871 break;
1872 case SSL_CONNECTION_VERSION_TLS1_2:
1873 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_2);
1874 break;
1875 };
1876}
1877
1878// SaveSnapStartInfo extracts the information needed to perform a Snap Start
1879// with this server in the future (if any) and tells |ssl_host_info_| to
1880// preserve it.
1881void SSLClientSocketNSS::SaveSnapStartInfo() {
1882 if (!ssl_host_info_.get())
1883 return;
1884
1885 // If the SSLHostInfo hasn't managed to load from disk yet then we can't save
1886 // anything.
1887 if (ssl_host_info_->WaitForDataReady(NULL) != OK)
1888 return;
1889
1890 SECStatus rv;
1891 SSLSnapStartResult snap_start_type;
1892 rv = SSL_GetSnapStartResult(nss_fd_, &snap_start_type);
1893 if (rv != SECSuccess) {
1894 NOTREACHED();
1895 return;
1896 }
1897 net_log_.AddEvent(NetLog::TYPE_SSL_SNAP_START,
1898 new NetLogIntegerParameter("type", snap_start_type));
1899 if (snap_start_type == SSL_SNAP_START_FULL ||
1900 snap_start_type == SSL_SNAP_START_RESUME) {
1901 // If we did a successful Snap Start then our information was correct and
1902 // there's no point saving it again.
1903 return;
1904 }
1905
1906 const unsigned char* hello_data;
1907 unsigned hello_data_len;
1908 rv = SSL_GetPredictedServerHelloData(nss_fd_, &hello_data, &hello_data_len);
1909 if (rv != SECSuccess) {
1910 NOTREACHED();
1911 return;
1912 }
1913 if (hello_data_len > std::numeric_limits<uint16>::max())
1914 return;
1915 SSLHostInfo::State* state = ssl_host_info_->mutable_state();
1916
1917 if (hello_data_len > 0) {
1918 state->server_hello =
1919 std::string(reinterpret_cast<const char *>(hello_data), hello_data_len);
1920 state->npn_valid = true;
1921 state->npn_status = GetNextProto(&state->npn_protocol);
1922 } else {
1923 state->server_hello.clear();
1924 state->npn_valid = false;
1925 }
1926
1927 state->certs.clear();
1928 PeerCertificateChain certs(nss_fd_);
1929 for (unsigned i = 0; i < certs.size(); i++) {
1930 if (certs[i]->derCert.len > std::numeric_limits<uint16>::max())
1931 return;
1932
1933 state->certs.push_back(std::string(
1934 reinterpret_cast<char*>(certs[i]->derCert.data),
1935 certs[i]->derCert.len));
1936 }
1937
1938 ssl_host_info_->Persist();
1939}
1940
1941// LoadSnapStartInfo parses |info|, which contains data previously serialised
1942// by |SaveSnapStartInfo|, and sets the predicted certificates and ServerHello
1943// data on the NSS socket. Returns true on success. If this function returns
1944// false, the caller should try a normal TLS handshake.
1945bool SSLClientSocketNSS::LoadSnapStartInfo() {
1946 const SSLHostInfo::State& state(ssl_host_info_->state());
1947
1948 if (state.server_hello.empty() ||
1949 state.certs.empty() ||
1950 !state.npn_valid) {
1951 return false;
1952 }
1953
1954 SECStatus rv;
1955 rv = SSL_SetPredictedServerHelloData(
1956 nss_fd_,
1957 reinterpret_cast<const uint8*>(state.server_hello.data()),
1958 state.server_hello.size());
1959 DCHECK_EQ(SECSuccess, rv);
1960
1961 const std::vector<std::string>& certs_in = state.certs;
1962 scoped_array<CERTCertificate*> certs(new CERTCertificate*[certs_in.size()]);
1963 for (size_t i = 0; i < certs_in.size(); i++) {
1964 SECItem derCert;
1965 derCert.data =
1966 const_cast<uint8*>(reinterpret_cast<const uint8*>(certs_in[i].data()));
1967 derCert.len = certs_in[i].size();
1968 certs[i] = CERT_NewTempCertificate(
1969 CERT_GetDefaultCertDB(), &derCert, NULL /* no nickname given */,
1970 PR_FALSE /* not permanent */, PR_TRUE /* copy DER data */);
1971 if (!certs[i]) {
1972 DestroyCertificates(&certs[0], i);
1973 NOTREACHED();
1974 return false;
1975 }
1976 }
1977
1978 rv = SSL_SetPredictedPeerCertificates(nss_fd_, certs.get(), certs_in.size());
1979 DestroyCertificates(&certs[0], certs_in.size());
1980 DCHECK_EQ(SECSuccess, rv);
1981
1982 if (state.npn_valid) {
1983 predicted_npn_status_ = state.npn_status;
1984 predicted_npn_proto_ = state.npn_protocol;
1985 }
1986
1987 return true;
1988}
1989
1990bool SSLClientSocketNSS::IsNPNProtocolMispredicted() {
1991 DCHECK(handshake_callback_called_);
1992 if (!predicted_npn_proto_used_)
1993 return false;
1994 std::string npn_proto;
1995 GetNextProto(&npn_proto);
1996 return predicted_npn_proto_ != npn_proto;
1997}
1998
1999void SSLClientSocketNSS::UncorkAfterTimeout() {
2000 corked_ = false;
2001 int nsent;
2002 do {
2003 nsent = BufferSend();
2004 } while (nsent > 0);
2005}
2006
2007// Do network I/O between the given buffer and the given socket.
2008// Return true if some I/O performed, false otherwise (error or ERR_IO_PENDING)
2009bool SSLClientSocketNSS::DoTransportIO() {
2010 EnterFunction("");
2011 bool network_moved = false;
2012 if (nss_bufs_ != NULL) {
2013 int nsent = BufferSend();
2014 int nreceived = BufferRecv();
2015 network_moved = (nsent > 0 || nreceived >= 0);
2016 }
2017 LeaveFunction(network_moved);
2018 return network_moved;
2019}
2020
2021// Return 0 for EOF,
2022// > 0 for bytes transferred immediately,
2023// < 0 for error (or the non-error ERR_IO_PENDING).
2024int SSLClientSocketNSS::BufferSend(void) {
2025 if (transport_send_busy_)
2026 return ERR_IO_PENDING;
2027
2028 EnterFunction("");
2029 const char* buf1;
2030 const char* buf2;
2031 unsigned int len1, len2;
2032 memio_GetWriteParams(nss_bufs_, &buf1, &len1, &buf2, &len2);
2033 const unsigned int len = len1 + len2;
2034
2035 if (corked_ && len < kRecvBufferSize / 2)
2036 return 0;
2037
2038 int rv = 0;
2039 if (len) {
2040 scoped_refptr<IOBuffer> send_buffer(new IOBuffer(len));
2041 memcpy(send_buffer->data(), buf1, len1);
2042 memcpy(send_buffer->data() + len1, buf2, len2);
2043 rv = transport_->socket()->Write(send_buffer, len,
2044 &buffer_send_callback_);
2045 if (rv == ERR_IO_PENDING) {
2046 transport_send_busy_ = true;
2047 } else {
2048 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv));
2049 }
2050 }
2051
2052 LeaveFunction(rv);
2053 return rv;
2054}
2055
2056void SSLClientSocketNSS::BufferSendComplete(int result) {
2057 EnterFunction(result);
2058
2059 // In the case of TCP FastOpen, connect is now finished.
2060 if (!peername_initialized_ && UsingTCPFastOpen())
2061 InitializeSSLPeerName();
2062
2063 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(result));
2064 transport_send_busy_ = false;
2065 OnSendComplete(result);
2066 LeaveFunction("");
2067}
2068
2069int SSLClientSocketNSS::BufferRecv(void) {
2070 if (transport_recv_busy_) return ERR_IO_PENDING;
2071
2072 char *buf;
2073 int nb = memio_GetReadParams(nss_bufs_, &buf);
2074 EnterFunction(nb);
2075 int rv;
2076 if (!nb) {
2077 // buffer too full to read into, so no I/O possible at moment
2078 rv = ERR_IO_PENDING;
2079 } else {
2080 recv_buffer_ = new IOBuffer(nb);
2081 rv = transport_->socket()->Read(recv_buffer_, nb, &buffer_recv_callback_);
2082 if (rv == ERR_IO_PENDING) {
2083 transport_recv_busy_ = true;
2084 } else {
2085 if (rv > 0)
2086 memcpy(buf, recv_buffer_->data(), rv);
2087 memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv));
2088 recv_buffer_ = NULL;
2089 }
2090 }
2091 LeaveFunction(rv);
2092 return rv;
2093}
2094
2095void SSLClientSocketNSS::BufferRecvComplete(int result) {
2096 EnterFunction(result);
2097 if (result > 0) {
2098 char *buf;
2099 memio_GetReadParams(nss_bufs_, &buf);
2100 memcpy(buf, recv_buffer_->data(), result);
2101 }
2102 recv_buffer_ = NULL;
2103 memio_PutReadResult(nss_bufs_, MapErrorToNSS(result));
2104 transport_recv_busy_ = false;
2105 OnRecvComplete(result);
2106 LeaveFunction("");
2107}
2108
[email protected]83530b72011-02-05 04:53:132109int SSLClientSocketNSS::HandleNSSError(PRErrorCode nss_error,
2110 bool handshake_error) {
2111 int net_error = handshake_error ? MapNSSHandshakeError(nss_error) :
2112 MapNSSError(nss_error);
2113
2114#if defined(OS_WIN)
2115 // On Windows, a handle to the HCRYPTPROV is cached in the X509Certificate
2116 // os_cert_handle() as an optimization. However, if the certificate
2117 // private key is stored on a smart card, and the smart card is removed,
2118 // the cached HCRYPTPROV will not be able to obtain the HCRYPTKEY again,
2119 // preventing client certificate authentication. Because the
2120 // X509Certificate may outlive the individual SSLClientSocketNSS, due to
2121 // caching in X509Certificate, this failure ends up preventing client
2122 // certificate authentication with the same certificate for all future
2123 // attempts, even after the smart card has been re-inserted. By setting
2124 // the CERT_KEY_PROV_HANDLE_PROP_ID to NULL, the cached HCRYPTPROV will
2125 // typically be freed. This allows a new HCRYPTPROV to be obtained from
2126 // the certificate on the next attempt, which should succeed if the smart
2127 // card has been re-inserted, or will typically prompt the user to
2128 // re-insert the smart card if not.
2129 if ((net_error == ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY ||
2130 net_error == ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED) &&
2131 ssl_config_.send_client_cert && ssl_config_.client_cert) {
2132 CertSetCertificateContextProperty(
2133 ssl_config_.client_cert->os_cert_handle(),
2134 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL);
2135 }
2136#endif
2137
2138 return net_error;
2139}
2140
[email protected]bacff652009-03-31 17:50:332141// static
2142// NSS calls this if an incoming certificate needs to be verified.
[email protected]2345cc52009-06-04 09:18:472143// Do nothing but return SECSuccess.
2144// This is called only in full handshake mode.
2145// Peer certificate is retrieved in HandshakeCallback() later, which is called
2146// in full handshake mode or in resumption handshake mode.
[email protected]bacff652009-03-31 17:50:332147SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg,
2148 PRFileDesc* socket,
2149 PRBool checksig,
2150 PRBool is_server) {
[email protected]9ae2ee02010-09-08 16:41:142151#ifdef SSL_ENABLE_FALSE_START
2152 // In the event that we are False Starting this connection, we wish to send
2153 // out the Finished message and first application data record in the same
2154 // packet. This prevents non-determinism when talking to False Start
2155 // intolerant servers which, otherwise, might see the two messages in
2156 // different reads or not, depending on network conditions.
2157 PRBool false_start = 0;
2158 SECStatus rv = SSL_OptionGet(socket, SSL_ENABLE_FALSE_START, &false_start);
[email protected]79ba2d82010-11-05 14:07:462159 DCHECK_EQ(SECSuccess, rv);
2160
[email protected]9ae2ee02010-09-08 16:41:142161 if (false_start) {
2162 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
[email protected]563cbcc62010-10-11 23:07:522163
2164 // ESET anti-virus is capable of intercepting HTTPS connections on Windows.
2165 // However, it is False Start intolerant and causes the connections to hang
2166 // forever. We detect ESET by the issuer of the leaf certificate and set a
2167 // flag to return a specific error, giving the user instructions for
2168 // reconfiguring ESET.
2169 CERTCertificate* cert = SSL_PeerCertificate(that->nss_fd_);
2170 if (cert) {
2171 char* common_name = CERT_GetCommonName(&cert->issuer);
2172 if (common_name) {
2173 if (strcmp(common_name, "ESET_RootSslCert") == 0)
2174 that->eset_mitm_detected_ = true;
[email protected]081b0942010-12-13 19:34:142175 if (strcmp(common_name,
2176 "ContentWatch Root Certificate Authority") == 0) {
[email protected]79ba2d82010-11-05 14:07:462177 // This is NetNanny. NetNanny are updating their product so we
2178 // silently disable False Start for now.
2179 rv = SSL_OptionSet(socket, SSL_ENABLE_FALSE_START, PR_FALSE);
2180 DCHECK_EQ(SECSuccess, rv);
2181 false_start = 0;
2182 }
[email protected]563cbcc62010-10-11 23:07:522183 PORT_Free(common_name);
2184 }
2185 CERT_DestroyCertificate(cert);
2186 }
[email protected]79ba2d82010-11-05 14:07:462187
2188 if (false_start && !that->handshake_callback_called_) {
2189 that->corked_ = true;
2190 that->uncork_timer_.Start(
2191 base::TimeDelta::FromMilliseconds(kCorkTimeoutMs),
2192 that, &SSLClientSocketNSS::UncorkAfterTimeout);
2193 }
[email protected]9ae2ee02010-09-08 16:41:142194 }
2195#endif
2196
[email protected]2345cc52009-06-04 09:18:472197 // Tell NSS to not verify the certificate.
2198 return SECSuccess;
2199}
2200
[email protected]4a842342010-11-04 16:21:332201#if defined(NSS_PLATFORM_CLIENT_AUTH)
[email protected]2345cc52009-06-04 09:18:472202// static
[email protected]d84b3722009-10-15 21:23:372203// NSS calls this if a client certificate is needed.
[email protected]4a842342010-11-04 16:21:332204SECStatus SSLClientSocketNSS::PlatformClientAuthHandler(
[email protected]d84b3722009-10-15 21:23:372205 void* arg,
2206 PRFileDesc* socket,
2207 CERTDistNames* ca_names,
[email protected]4a842342010-11-04 16:21:332208 CERTCertList** result_certs,
2209 void** result_private_key) {
[email protected]d84b3722009-10-15 21:23:372210 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
2211
2212 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert;
[email protected]1d583612010-03-12 17:47:142213#if defined(OS_WIN)
2214 if (that->ssl_config_.send_client_cert) {
[email protected]4a842342010-11-04 16:21:332215 if (that->ssl_config_.client_cert) {
2216 PCCERT_CONTEXT cert_context =
2217 that->ssl_config_.client_cert->os_cert_handle();
[email protected]39815a02011-02-05 04:47:152218 PCERT_KEY_CONTEXT key_context = reinterpret_cast<PCERT_KEY_CONTEXT>(
2219 PORT_ZAlloc(sizeof(CERT_KEY_CONTEXT)));
2220 if (!key_context)
2221 return SECFailure;
2222 key_context->cbSize = sizeof(*key_context);
[email protected]b493c0b92010-11-11 05:12:422223
[email protected]4a842342010-11-04 16:21:332224 BOOL must_free = FALSE;
2225 BOOL acquired_key = CryptAcquireCertificatePrivateKey(
[email protected]fbe693bf2011-02-06 02:28:162226 cert_context, CRYPT_ACQUIRE_CACHE_FLAG, NULL,
2227 &key_context->hCryptProv, &key_context->dwKeySpec, &must_free);
[email protected]39815a02011-02-05 04:47:152228 if (acquired_key && key_context->hCryptProv) {
2229 DCHECK_NE(key_context->dwKeySpec, CERT_NCRYPT_KEY_SPEC);
[email protected]4a842342010-11-04 16:21:332230
2231 // The certificate cache may have been updated/used, in which case,
2232 // duplicate the existing handle, since NSS will free it when no
2233 // longer in use.
2234 if (!must_free)
[email protected]39815a02011-02-05 04:47:152235 CryptContextAddRef(key_context->hCryptProv, NULL, 0);
[email protected]4a842342010-11-04 16:21:332236
2237 SECItem der_cert;
2238 der_cert.type = siDERCertBuffer;
2239 der_cert.data = cert_context->pbCertEncoded;
2240 der_cert.len = cert_context->cbCertEncoded;
2241
2242 // TODO(rsleevi): Error checking for NSS allocation errors.
2243 *result_certs = CERT_NewCertList();
2244 CERTCertDBHandle* db_handle = CERT_GetDefaultCertDB();
2245 CERTCertificate* user_cert = CERT_NewTempCertificate(
2246 db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE);
2247 CERT_AddCertToListTail(*result_certs, user_cert);
2248
2249 // Add the intermediates.
2250 X509Certificate::OSCertHandles intermediates =
2251 that->ssl_config_.client_cert->GetIntermediateCertificates();
2252 for (X509Certificate::OSCertHandles::const_iterator it =
2253 intermediates.begin(); it != intermediates.end(); ++it) {
2254 der_cert.data = (*it)->pbCertEncoded;
2255 der_cert.len = (*it)->cbCertEncoded;
2256
2257 CERTCertificate* intermediate = CERT_NewTempCertificate(
2258 db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE);
2259 CERT_AddCertToListTail(*result_certs, intermediate);
2260 }
[email protected]39815a02011-02-05 04:47:152261 *result_private_key = key_context;
[email protected]4a842342010-11-04 16:21:332262 return SECSuccess;
2263 }
[email protected]39815a02011-02-05 04:47:152264 PORT_Free(key_context);
[email protected]4a842342010-11-04 16:21:332265 LOG(WARNING) << "Client cert found without private key";
2266 }
[email protected]1d583612010-03-12 17:47:142267 // Send no client certificate.
2268 return SECFailure;
2269 }
2270
2271 that->client_certs_.clear();
2272
2273 std::vector<CERT_NAME_BLOB> issuer_list(ca_names->nnames);
2274 for (int i = 0; i < ca_names->nnames; ++i) {
2275 issuer_list[i].cbData = ca_names->names[i].len;
2276 issuer_list[i].pbData = ca_names->names[i].data;
2277 }
2278
2279 // Client certificates of the user are in the "MY" system certificate store.
2280 HCERTSTORE my_cert_store = CertOpenSystemStore(NULL, L"MY");
2281 if (!my_cert_store) {
2282 LOG(ERROR) << "Could not open the \"MY\" system certificate store: "
2283 << GetLastError();
2284 return SECFailure;
2285 }
2286
2287 // Enumerate the client certificates.
2288 CERT_CHAIN_FIND_BY_ISSUER_PARA find_by_issuer_para;
2289 memset(&find_by_issuer_para, 0, sizeof(find_by_issuer_para));
2290 find_by_issuer_para.cbSize = sizeof(find_by_issuer_para);
2291 find_by_issuer_para.pszUsageIdentifier = szOID_PKIX_KP_CLIENT_AUTH;
2292 find_by_issuer_para.cIssuer = ca_names->nnames;
2293 find_by_issuer_para.rgIssuer = ca_names->nnames ? &issuer_list[0] : NULL;
[email protected]01640f62010-08-10 19:42:122294 find_by_issuer_para.pfnFindCallback = ClientCertFindCallback;
[email protected]1d583612010-03-12 17:47:142295
2296 PCCERT_CHAIN_CONTEXT chain_context = NULL;
2297
2298 for (;;) {
2299 // Find a certificate chain.
2300 chain_context = CertFindChainInStore(my_cert_store,
2301 X509_ASN_ENCODING,
2302 0,
2303 CERT_CHAIN_FIND_BY_ISSUER,
2304 &find_by_issuer_para,
2305 chain_context);
2306 if (!chain_context) {
2307 DWORD err = GetLastError();
2308 if (err != CRYPT_E_NOT_FOUND)
2309 DLOG(ERROR) << "CertFindChainInStore failed: " << err;
2310 break;
2311 }
2312
2313 // Get the leaf certificate.
2314 PCCERT_CONTEXT cert_context =
2315 chain_context->rgpChain[0]->rgpElement[0]->pCertContext;
2316 // Copy it to our own certificate store, so that we can close the "MY"
2317 // certificate store before returning from this function.
2318 PCCERT_CONTEXT cert_context2;
[email protected]670dca92010-10-26 13:27:092319 BOOL ok = CertAddCertificateContextToStore(X509Certificate::cert_store(),
2320 cert_context,
[email protected]1d583612010-03-12 17:47:142321 CERT_STORE_ADD_USE_EXISTING,
2322 &cert_context2);
2323 if (!ok) {
2324 NOTREACHED();
2325 continue;
2326 }
[email protected]4a842342010-11-04 16:21:332327
2328 // Copy the rest of the chain to our own store as well. Copying the chain
2329 // stops gracefully if an error is encountered, with the partial chain
2330 // being used as the intermediates, rather than failing to consider the
2331 // client certificate.
2332 net::X509Certificate::OSCertHandles intermediates;
2333 for (DWORD i = 1; i < chain_context->rgpChain[0]->cElement; i++) {
2334 PCCERT_CONTEXT intermediate_copy;
2335 ok = CertAddCertificateContextToStore(X509Certificate::cert_store(),
2336 chain_context->rgpChain[0]->rgpElement[i]->pCertContext,
2337 CERT_STORE_ADD_USE_EXISTING, &intermediate_copy);
2338 if (!ok) {
2339 NOTREACHED();
2340 break;
2341 }
2342 intermediates.push_back(intermediate_copy);
2343 }
2344
[email protected]1d583612010-03-12 17:47:142345 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
2346 cert_context2, X509Certificate::SOURCE_LONE_CERT_IMPORT,
[email protected]4a842342010-11-04 16:21:332347 intermediates);
[email protected]1d583612010-03-12 17:47:142348 that->client_certs_.push_back(cert);
[email protected]4a842342010-11-04 16:21:332349
2350 X509Certificate::FreeOSCertHandle(cert_context2);
2351 for (net::X509Certificate::OSCertHandles::iterator it =
2352 intermediates.begin(); it != intermediates.end(); ++it) {
2353 net::X509Certificate::FreeOSCertHandle(*it);
2354 }
[email protected]1d583612010-03-12 17:47:142355 }
2356
2357 BOOL ok = CertCloseStore(my_cert_store, CERT_CLOSE_STORE_CHECK_FLAG);
2358 DCHECK(ok);
2359
2360 // Tell NSS to suspend the client authentication. We will then abort the
2361 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
2362 return SECWouldBlock;
[email protected]3dd6f5e2010-06-01 20:28:032363#elif defined(OS_MACOSX)
[email protected]fd4f139f2010-06-11 17:02:202364 if (that->ssl_config_.send_client_cert) {
[email protected]4a842342010-11-04 16:21:332365 if (that->ssl_config_.client_cert) {
2366 OSStatus os_error = noErr;
2367 SecIdentityRef identity = NULL;
2368 SecKeyRef private_key = NULL;
2369 CFArrayRef chain =
2370 that->ssl_config_.client_cert->CreateClientCertificateChain();
2371 if (chain) {
2372 identity = reinterpret_cast<SecIdentityRef>(
2373 const_cast<void*>(CFArrayGetValueAtIndex(chain, 0)));
2374 }
2375 if (identity)
2376 os_error = SecIdentityCopyPrivateKey(identity, &private_key);
2377
2378 if (chain && identity && os_error == noErr) {
2379 // TODO(rsleevi): Error checking for NSS allocation errors.
2380 *result_certs = CERT_NewCertList();
[email protected]39815a02011-02-05 04:47:152381 *result_private_key = private_key;
[email protected]4a842342010-11-04 16:21:332382
2383 for (CFIndex i = 0; i < CFArrayGetCount(chain); ++i) {
2384 CSSM_DATA cert_data;
2385 SecCertificateRef cert_ref;
2386 if (i == 0) {
2387 cert_ref = that->ssl_config_.client_cert->os_cert_handle();
2388 } else {
2389 cert_ref = reinterpret_cast<SecCertificateRef>(
2390 const_cast<void*>(CFArrayGetValueAtIndex(chain, i)));
2391 }
2392 os_error = SecCertificateGetData(cert_ref, &cert_data);
2393 if (os_error != noErr)
2394 break;
2395
2396 SECItem der_cert;
2397 der_cert.type = siDERCertBuffer;
2398 der_cert.data = cert_data.Data;
2399 der_cert.len = cert_data.Length;
2400 CERTCertificate* nss_cert = CERT_NewTempCertificate(
2401 CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE);
2402 CERT_AddCertToListTail(*result_certs, nss_cert);
2403 }
2404 }
2405 if (os_error == noErr) {
2406 CFRelease(chain);
2407 return SECSuccess;
2408 }
2409 LOG(WARNING) << "Client cert found, but could not be used: "
2410 << os_error;
2411 if (*result_certs) {
2412 CERT_DestroyCertList(*result_certs);
2413 *result_certs = NULL;
2414 }
2415 if (*result_private_key)
2416 *result_private_key = NULL;
2417 if (private_key)
2418 CFRelease(private_key);
2419 if (chain)
2420 CFRelease(chain);
2421 }
[email protected]fd4f139f2010-06-11 17:02:202422 // Send no client certificate.
2423 return SECFailure;
2424 }
2425
2426 that->client_certs_.clear();
2427
2428 // First, get the cert issuer names allowed by the server.
2429 std::vector<CertPrincipal> valid_issuers;
2430 int n = ca_names->nnames;
2431 for (int i = 0; i < n; i++) {
2432 // Parse each name into a CertPrincipal object.
2433 CertPrincipal p;
2434 if (p.ParseDistinguishedName(ca_names->names[i].data,
2435 ca_names->names[i].len)) {
2436 valid_issuers.push_back(p);
2437 }
2438 }
2439
2440 // Now get the available client certs whose issuers are allowed by the server.
[email protected]4f4de7e62010-11-12 19:55:272441 X509Certificate::GetSSLClientCertificates(that->host_and_port_.host(),
[email protected]fd4f139f2010-06-11 17:02:202442 valid_issuers,
2443 &that->client_certs_);
2444
2445 // Tell NSS to suspend the client authentication. We will then abort the
2446 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
2447 return SECWouldBlock;
[email protected]1d583612010-03-12 17:47:142448#else
[email protected]4a842342010-11-04 16:21:332449 return SECFailure;
2450#endif
2451}
2452
2453#else // NSS_PLATFORM_CLIENT_AUTH
2454
2455// static
2456// NSS calls this if a client certificate is needed.
2457// Based on Mozilla's NSS_GetClientAuthData.
2458SECStatus SSLClientSocketNSS::ClientAuthHandler(
2459 void* arg,
2460 PRFileDesc* socket,
2461 CERTDistNames* ca_names,
2462 CERTCertificate** result_certificate,
2463 SECKEYPrivateKey** result_private_key) {
2464 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
2465
2466 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert;
[email protected]b8fee152009-10-24 03:39:312467 void* wincx = SSL_RevealPinArg(socket);
2468
[email protected]d84b3722009-10-15 21:23:372469 // Second pass: a client certificate should have been selected.
2470 if (that->ssl_config_.send_client_cert) {
2471 if (that->ssl_config_.client_cert) {
[email protected]701e8692010-08-17 20:00:432472 CERTCertificate* cert = CERT_DupCertificate(
[email protected]d84b3722009-10-15 21:23:372473 that->ssl_config_.client_cert->os_cert_handle());
[email protected]701e8692010-08-17 20:00:432474 SECKEYPrivateKey* privkey = PK11_FindKeyByAnyCert(cert, wincx);
[email protected]d84b3722009-10-15 21:23:372475 if (privkey) {
2476 // TODO(jsorianopastor): We should wait for server certificate
2477 // verification before sending our credentials. See
2478 // http://crbug.com/13934.
2479 *result_certificate = cert;
2480 *result_private_key = privkey;
2481 return SECSuccess;
2482 }
2483 LOG(WARNING) << "Client cert found without private key";
2484 }
2485 // Send no client certificate.
2486 return SECFailure;
2487 }
2488
[email protected]701e8692010-08-17 20:00:432489 // Iterate over all client certificates.
2490 CERTCertList* client_certs = CERT_FindUserCertsByUsage(
2491 CERT_GetDefaultCertDB(), certUsageSSLClient,
2492 PR_FALSE, PR_FALSE, wincx);
2493 if (client_certs) {
2494 for (CERTCertListNode* node = CERT_LIST_HEAD(client_certs);
2495 !CERT_LIST_END(node, client_certs);
2496 node = CERT_LIST_NEXT(node)) {
2497 // Only offer unexpired certificates.
2498 if (CERT_CheckCertValidTimes(node->cert, PR_Now(), PR_TRUE) !=
2499 secCertTimeValid)
[email protected]b8fee152009-10-24 03:39:312500 continue;
[email protected]701e8692010-08-17 20:00:432501 // Filter by issuer.
2502 //
2503 // TODO(davidben): This does a binary comparison of the DER-encoded
2504 // issuers. We should match according to RFC 5280 sec. 7.1. We should find
2505 // an appropriate NSS function or add one if needbe.
2506 if (ca_names->nnames &&
2507 NSS_CmpCertChainWCANames(node->cert, ca_names) != SECSuccess)
2508 continue;
2509 X509Certificate* x509_cert = X509Certificate::CreateFromHandle(
2510 node->cert, X509Certificate::SOURCE_LONE_CERT_IMPORT,
2511 net::X509Certificate::OSCertHandles());
2512 that->client_certs_.push_back(x509_cert);
[email protected]b8fee152009-10-24 03:39:312513 }
[email protected]701e8692010-08-17 20:00:432514 CERT_DestroyCertList(client_certs);
[email protected]b8fee152009-10-24 03:39:312515 }
[email protected]d84b3722009-10-15 21:23:372516
[email protected]f6ee0a012010-03-05 22:00:242517 // Tell NSS to suspend the client authentication. We will then abort the
2518 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
2519 return SECWouldBlock;
[email protected]d84b3722009-10-15 21:23:372520}
[email protected]4a842342010-11-04 16:21:332521#endif // NSS_PLATFORM_CLIENT_AUTH
[email protected]d84b3722009-10-15 21:23:372522
2523// static
[email protected]2345cc52009-06-04 09:18:472524// NSS calls this when handshake is completed.
2525// After the SSL handshake is finished, use CertVerifier to verify
2526// the saved server certificate.
2527void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket,
2528 void* arg) {
[email protected]bacff652009-03-31 17:50:332529 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
2530
[email protected]7a8de3072010-10-01 16:25:542531 that->handshake_callback_called_ = true;
[email protected]39afe642010-04-29 14:55:182532
[email protected]2345cc52009-06-04 09:18:472533 that->UpdateServerCert();
[email protected]757f2e2b2010-10-27 23:28:352534 that->UpdateConnectionStatus();
[email protected]2345cc52009-06-04 09:18:472535}
[email protected]bacff652009-03-31 17:50:332536
[email protected]93c57682011-02-12 02:05:082537void SSLClientSocketNSS::EnsureThreadIdAssigned() const {
2538 base::AutoLock auto_lock(lock_);
2539 if (valid_thread_id_ != base::kInvalidThreadId)
2540 return;
2541 valid_thread_id_ = base::PlatformThread::CurrentId();
2542}
2543
2544bool SSLClientSocketNSS::CalledOnValidThread() const {
2545 EnsureThreadIdAssigned();
2546 base::AutoLock auto_lock(lock_);
2547 return valid_thread_id_ == base::PlatformThread::CurrentId();
2548}
2549
[email protected]b43c97c2008-10-22 19:50:582550} // namespace net