• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived
6 // from AuthCertificateCallback() in
7 // 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 <mcgreer@netscape.com>
31  *   Javier Delgadillo <javi@netscape.com>
32  *   Kai Engert <kengert@redhat.com>
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 
48 #include "net/socket/ssl_client_socket_nss.h"
49 
50 #include <certdb.h>
51 #include <hasht.h>
52 #include <keyhi.h>
53 #include <nspr.h>
54 #include <nss.h>
55 #include <ocsp.h>
56 #include <pk11pub.h>
57 #include <secerr.h>
58 #include <sechash.h>
59 #include <ssl.h>
60 #include <sslerr.h>
61 #include <sslproto.h>
62 
63 #include <algorithm>
64 #include <limits>
65 #include <map>
66 
67 #include "base/compiler_specific.h"
68 #include "base/logging.h"
69 #include "base/memory/singleton.h"
70 #include "base/metrics/histogram.h"
71 #include "base/string_number_conversions.h"
72 #include "base/string_util.h"
73 #include "base/stringprintf.h"
74 #include "base/threading/thread_restrictions.h"
75 #include "base/values.h"
76 #include "net/base/address_list.h"
77 #include "net/base/cert_status_flags.h"
78 #include "net/base/cert_verifier.h"
79 #include "net/base/connection_type_histograms.h"
80 #include "net/base/dns_util.h"
81 #include "net/base/dnsrr_resolver.h"
82 #include "net/base/dnssec_chain_verifier.h"
83 #include "net/base/io_buffer.h"
84 #include "net/base/net_errors.h"
85 #include "net/base/net_log.h"
86 #include "net/base/ssl_cert_request_info.h"
87 #include "net/base/ssl_connection_status_flags.h"
88 #include "net/base/ssl_info.h"
89 #include "net/base/sys_addrinfo.h"
90 #include "net/ocsp/nss_ocsp.h"
91 #include "net/socket/client_socket_handle.h"
92 #include "net/socket/dns_cert_provenance_checker.h"
93 #include "net/socket/nss_ssl_util.h"
94 #include "net/socket/ssl_error_params.h"
95 #include "net/socket/ssl_host_info.h"
96 
97 #if defined(OS_WIN)
98 #include <windows.h>
99 #include <wincrypt.h>
100 #elif defined(OS_MACOSX)
101 #include <Security/SecBase.h>
102 #include <Security/SecCertificate.h>
103 #include <Security/SecIdentity.h>
104 #elif defined(USE_NSS)
105 #include <dlfcn.h>
106 #endif
107 
108 static const int kRecvBufferSize = 4096;
109 
110 // kCorkTimeoutMs is the number of milliseconds for which we'll wait for a
111 // Write to an SSL socket which we're False Starting. Since corking stops the
112 // Finished message from being sent, the server sees an incomplete handshake
113 // and some will time out such sockets quite aggressively.
114 static const int kCorkTimeoutMs = 200;
115 
116 #if defined(OS_WIN)
117 // CERT_OCSP_RESPONSE_PROP_ID is only implemented on Vista+, but it can be
118 // set on Windows XP without error. There is some overhead from the server
119 // sending the OCSP response if it supports the extension, for the subset of
120 // XP clients who will request it but be unable to use it, but this is an
121 // acceptable trade-off for simplicity of implementation.
IsOCSPStaplingSupported()122 static bool IsOCSPStaplingSupported() {
123   return true;
124 }
125 #elif defined(USE_NSS)
126 typedef SECStatus
127 (*CacheOCSPResponseFromSideChannelFunction)(
128     CERTCertDBHandle *handle, CERTCertificate *cert, PRTime time,
129     SECItem *encodedResponse, void *pwArg);
130 
131 // On Linux, we dynamically link against the system version of libnss3.so. In
132 // order to continue working on systems without up-to-date versions of NSS we
133 // lookup CERT_CacheOCSPResponseFromSideChannel with dlsym.
134 
135 // RuntimeLibNSSFunctionPointers is a singleton which caches the results of any
136 // runtime symbol resolution that we need.
137 class RuntimeLibNSSFunctionPointers {
138  public:
139   CacheOCSPResponseFromSideChannelFunction
GetCacheOCSPResponseFromSideChannelFunction()140   GetCacheOCSPResponseFromSideChannelFunction() {
141     return cache_ocsp_response_from_side_channel_;
142   }
143 
GetInstance()144   static RuntimeLibNSSFunctionPointers* GetInstance() {
145     return Singleton<RuntimeLibNSSFunctionPointers>::get();
146   }
147 
148  private:
149   friend struct DefaultSingletonTraits<RuntimeLibNSSFunctionPointers>;
150 
RuntimeLibNSSFunctionPointers()151   RuntimeLibNSSFunctionPointers() {
152     cache_ocsp_response_from_side_channel_ =
153         (CacheOCSPResponseFromSideChannelFunction)
154         dlsym(RTLD_DEFAULT, "CERT_CacheOCSPResponseFromSideChannel");
155   }
156 
157   CacheOCSPResponseFromSideChannelFunction
158       cache_ocsp_response_from_side_channel_;
159 };
160 
161 static CacheOCSPResponseFromSideChannelFunction
GetCacheOCSPResponseFromSideChannelFunction()162 GetCacheOCSPResponseFromSideChannelFunction() {
163   return RuntimeLibNSSFunctionPointers::GetInstance()
164     ->GetCacheOCSPResponseFromSideChannelFunction();
165 }
166 
IsOCSPStaplingSupported()167 static bool IsOCSPStaplingSupported() {
168   return GetCacheOCSPResponseFromSideChannelFunction() != NULL;
169 }
170 #else
171 // TODO(agl): Figure out if we can plumb the OCSP response into Mac's system
172 // certificate validation functions.
IsOCSPStaplingSupported()173 static bool IsOCSPStaplingSupported() {
174   return false;
175 }
176 #endif
177 
178 namespace net {
179 
180 // State machines are easier to debug if you log state transitions.
181 // Enable these if you want to see what's going on.
182 #if 1
183 #define EnterFunction(x)
184 #define LeaveFunction(x)
185 #define GotoState(s) next_handshake_state_ = s
186 #define LogData(s, len)
187 #else
188 #define EnterFunction(x)\
189     VLOG(1) << (void *)this << " " << __FUNCTION__ << " enter " << x\
190             << "; next_handshake_state " << next_handshake_state_
191 #define LeaveFunction(x)\
192     VLOG(1) << (void *)this << " " << __FUNCTION__ << " leave " << x\
193             << "; next_handshake_state " << next_handshake_state_
194 #define GotoState(s)\
195     do {\
196       VLOG(1) << (void *)this << " " << __FUNCTION__ << " jump to state " << s;\
197       next_handshake_state_ = s;\
198     } while (0)
199 #define LogData(s, len)\
200     VLOG(1) << (void *)this << " " << __FUNCTION__\
201             << " data [" << std::string(s, len) << "]"
202 #endif
203 
204 namespace {
205 
206 #if defined(OS_WIN)
207 
208 // This callback is intended to be used with CertFindChainInStore. In addition
209 // to filtering by extended/enhanced key usage, we do not show expired
210 // certificates and require digital signature usage in the key usage
211 // extension.
212 //
213 // This matches our behavior on Mac OS X and that of NSS. It also matches the
214 // default behavior of IE8. See http://support.microsoft.com/kb/890326 and
215 // 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
ClientCertFindCallback(PCCERT_CONTEXT cert_context,void * find_arg)216 BOOL WINAPI ClientCertFindCallback(PCCERT_CONTEXT cert_context,
217                                    void* find_arg) {
218   VLOG(1) << "Calling ClientCertFindCallback from _nss";
219   // Verify the certificate's KU is good.
220   BYTE key_usage;
221   if (CertGetIntendedKeyUsage(X509_ASN_ENCODING, cert_context->pCertInfo,
222                               &key_usage, 1)) {
223     if (!(key_usage & CERT_DIGITAL_SIGNATURE_KEY_USAGE))
224       return FALSE;
225   } else {
226     DWORD err = GetLastError();
227     // If |err| is non-zero, it's an actual error. Otherwise the extension
228     // just isn't present, and we treat it as if everything was allowed.
229     if (err) {
230       DLOG(ERROR) << "CertGetIntendedKeyUsage failed: " << err;
231       return FALSE;
232     }
233   }
234 
235   // Verify the current time is within the certificate's validity period.
236   if (CertVerifyTimeValidity(NULL, cert_context->pCertInfo) != 0)
237     return FALSE;
238 
239   // Verify private key metadata is associated with this certificate.
240   DWORD size = 0;
241   if (!CertGetCertificateContextProperty(
242           cert_context, CERT_KEY_PROV_INFO_PROP_ID, NULL, &size)) {
243     return FALSE;
244   }
245 
246   return TRUE;
247 }
248 
249 #endif
250 
251 // PeerCertificateChain is a helper object which extracts the certificate
252 // chain, as given by the server, from an NSS socket and performs the needed
253 // resource management. The first element of the chain is the leaf certificate
254 // and the other elements are in the order given by the server.
255 class PeerCertificateChain {
256  public:
PeerCertificateChain(PRFileDesc * nss_fd)257   explicit PeerCertificateChain(PRFileDesc* nss_fd)
258       : num_certs_(0),
259         certs_(NULL) {
260     SECStatus rv = SSL_PeerCertificateChain(nss_fd, NULL, &num_certs_);
261     DCHECK_EQ(rv, SECSuccess);
262 
263     certs_ = new CERTCertificate*[num_certs_];
264     const unsigned expected_num_certs = num_certs_;
265     rv = SSL_PeerCertificateChain(nss_fd, certs_, &num_certs_);
266     DCHECK_EQ(rv, SECSuccess);
267     DCHECK_EQ(num_certs_, expected_num_certs);
268   }
269 
~PeerCertificateChain()270   ~PeerCertificateChain() {
271     for (unsigned i = 0; i < num_certs_; i++)
272       CERT_DestroyCertificate(certs_[i]);
273     delete[] certs_;
274   }
275 
size() const276   unsigned size() const { return num_certs_; }
277 
operator [](unsigned i)278   CERTCertificate* operator[](unsigned i) {
279     DCHECK_LT(i, num_certs_);
280     return certs_[i];
281   }
282 
AsStringPieceVector() const283   std::vector<base::StringPiece> AsStringPieceVector() const {
284     std::vector<base::StringPiece> v(size());
285     for (unsigned i = 0; i < size(); i++) {
286       v[i] = base::StringPiece(
287           reinterpret_cast<const char*>(certs_[i]->derCert.data),
288           certs_[i]->derCert.len);
289     }
290 
291     return v;
292   }
293 
294  private:
295   unsigned num_certs_;
296   CERTCertificate** certs_;
297 };
298 
DestroyCertificates(CERTCertificate ** certs,unsigned len)299 void DestroyCertificates(CERTCertificate** certs, unsigned len) {
300   for (unsigned i = 0; i < len; i++)
301     CERT_DestroyCertificate(certs[i]);
302 }
303 
304 // DNSValidationResult enumerates the possible outcomes from processing a
305 // set of DNS records.
306 enum DNSValidationResult {
307   DNSVR_SUCCESS,   // the cert is immediately acceptable.
308   DNSVR_FAILURE,   // the cert is unconditionally rejected.
309   DNSVR_CONTINUE,  // perform CA validation as usual.
310 };
311 
312 // VerifyTXTRecords processes the RRDATA for a number of DNS TXT records and
313 // checks them against the given certificate.
314 //   dnssec: if true then the TXT records are DNSSEC validated. In this case,
315 //       DNSVR_SUCCESS may be returned.
316 //    server_cert_nss: the certificate to validate
317 //    rrdatas: the TXT records for the current domain.
VerifyTXTRecords(bool dnssec,CERTCertificate * server_cert_nss,const std::vector<base::StringPiece> & rrdatas)318 DNSValidationResult VerifyTXTRecords(
319     bool dnssec,
320     CERTCertificate* server_cert_nss,
321     const std::vector<base::StringPiece>& rrdatas) {
322   bool found_well_formed_record = false;
323   bool matched_record = false;
324 
325   for (std::vector<base::StringPiece>::const_iterator
326        i = rrdatas.begin(); i != rrdatas.end(); ++i) {
327     std::map<std::string, std::string> m(
328         DNSSECChainVerifier::ParseTLSTXTRecord(*i));
329     if (m.empty())
330       continue;
331 
332     std::map<std::string, std::string>::const_iterator j;
333     j = m.find("v");
334     if (j == m.end() || j->second != "tls1")
335       continue;
336 
337     j = m.find("ha");
338 
339     HASH_HashType hash_algorithm;
340     unsigned hash_length;
341     if (j == m.end() || j->second == "sha1") {
342       hash_algorithm = HASH_AlgSHA1;
343       hash_length = SHA1_LENGTH;
344     } else if (j->second == "sha256") {
345       hash_algorithm = HASH_AlgSHA256;
346       hash_length = SHA256_LENGTH;
347     } else {
348       continue;
349     }
350 
351     j = m.find("h");
352     if (j == m.end())
353       continue;
354 
355     std::vector<uint8> given_hash;
356     if (!base::HexStringToBytes(j->second, &given_hash))
357       continue;
358 
359     if (given_hash.size() != hash_length)
360       continue;
361 
362     uint8 calculated_hash[SHA256_LENGTH];  // SHA256 is the largest.
363     SECStatus rv;
364 
365     j = m.find("hr");
366     if (j == m.end() || j->second == "pubkey") {
367       rv = HASH_HashBuf(hash_algorithm, calculated_hash,
368                         server_cert_nss->derPublicKey.data,
369                         server_cert_nss->derPublicKey.len);
370     } else if (j->second == "cert") {
371       rv = HASH_HashBuf(hash_algorithm, calculated_hash,
372                         server_cert_nss->derCert.data,
373                         server_cert_nss->derCert.len);
374     } else {
375       continue;
376     }
377 
378     if (rv != SECSuccess)
379       NOTREACHED();
380 
381     found_well_formed_record = true;
382 
383     if (memcmp(calculated_hash, &given_hash[0], hash_length) == 0) {
384       matched_record = true;
385       if (dnssec)
386         return DNSVR_SUCCESS;
387     }
388   }
389 
390   if (found_well_formed_record && !matched_record)
391     return DNSVR_FAILURE;
392 
393   return DNSVR_CONTINUE;
394 }
395 
396 // CheckDNSSECChain tries to validate a DNSSEC chain embedded in
397 // |server_cert_nss_|. It returns true iff a chain is found that proves the
398 // value of a TXT record that contains a valid public key fingerprint.
CheckDNSSECChain(const std::string & hostname,CERTCertificate * server_cert_nss)399 DNSValidationResult CheckDNSSECChain(
400     const std::string& hostname,
401     CERTCertificate* server_cert_nss) {
402   if (!server_cert_nss)
403     return DNSVR_CONTINUE;
404 
405   // CERT_FindCertExtensionByOID isn't exported so we have to install an OID,
406   // get a tag for it and find the extension by using that tag.
407   static SECOidTag dnssec_chain_tag;
408   static bool dnssec_chain_tag_valid;
409   if (!dnssec_chain_tag_valid) {
410     // It's harmless if multiple threads enter this block concurrently.
411     static const uint8 kDNSSECChainOID[] =
412         // 1.3.6.1.4.1.11129.2.1.4
413         // (iso.org.dod.internet.private.enterprises.google.googleSecurity.
414         //  certificateExtensions.dnssecEmbeddedChain)
415         {0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x01, 0x04};
416     SECOidData oid_data;
417     memset(&oid_data, 0, sizeof(oid_data));
418     oid_data.oid.data = const_cast<uint8*>(kDNSSECChainOID);
419     oid_data.oid.len = sizeof(kDNSSECChainOID);
420     oid_data.desc = "DNSSEC chain";
421     oid_data.supportedExtension = SUPPORTED_CERT_EXTENSION;
422     dnssec_chain_tag = SECOID_AddEntry(&oid_data);
423     DCHECK_NE(SEC_OID_UNKNOWN, dnssec_chain_tag);
424     dnssec_chain_tag_valid = true;
425   }
426 
427   SECItem dnssec_embedded_chain;
428   SECStatus rv = CERT_FindCertExtension(server_cert_nss,
429       dnssec_chain_tag, &dnssec_embedded_chain);
430   if (rv != SECSuccess)
431     return DNSVR_CONTINUE;
432 
433   base::StringPiece chain(
434       reinterpret_cast<char*>(dnssec_embedded_chain.data),
435       dnssec_embedded_chain.len);
436   std::string dns_hostname;
437   if (!DNSDomainFromDot(hostname, &dns_hostname))
438     return DNSVR_CONTINUE;
439   DNSSECChainVerifier verifier(dns_hostname, chain);
440   DNSSECChainVerifier::Error err = verifier.Verify();
441   if (err != DNSSECChainVerifier::OK) {
442     LOG(ERROR) << "DNSSEC chain verification failed: " << err;
443     return DNSVR_CONTINUE;
444   }
445 
446   if (verifier.rrtype() != kDNS_TXT)
447     return DNSVR_CONTINUE;
448 
449   DNSValidationResult r = VerifyTXTRecords(
450       true /* DNSSEC verified */, server_cert_nss, verifier.rrdatas());
451   SECITEM_FreeItem(&dnssec_embedded_chain, PR_FALSE);
452   return r;
453 }
454 
455 }  // namespace
456 
SSLClientSocketNSS(ClientSocketHandle * transport_socket,const HostPortPair & host_and_port,const SSLConfig & ssl_config,SSLHostInfo * ssl_host_info,CertVerifier * cert_verifier,DnsCertProvenanceChecker * dns_ctx)457 SSLClientSocketNSS::SSLClientSocketNSS(ClientSocketHandle* transport_socket,
458                                        const HostPortPair& host_and_port,
459                                        const SSLConfig& ssl_config,
460                                        SSLHostInfo* ssl_host_info,
461                                        CertVerifier* cert_verifier,
462                                        DnsCertProvenanceChecker* dns_ctx)
463     : ALLOW_THIS_IN_INITIALIZER_LIST(buffer_send_callback_(
464           this, &SSLClientSocketNSS::BufferSendComplete)),
465       ALLOW_THIS_IN_INITIALIZER_LIST(buffer_recv_callback_(
466           this, &SSLClientSocketNSS::BufferRecvComplete)),
467       transport_send_busy_(false),
468       transport_recv_busy_(false),
469       corked_(false),
470       ALLOW_THIS_IN_INITIALIZER_LIST(handshake_io_callback_(
471           this, &SSLClientSocketNSS::OnHandshakeIOComplete)),
472       transport_(transport_socket),
473       host_and_port_(host_and_port),
474       ssl_config_(ssl_config),
475       user_connect_callback_(NULL),
476       user_read_callback_(NULL),
477       user_write_callback_(NULL),
478       user_read_buf_len_(0),
479       user_write_buf_len_(0),
480       server_cert_nss_(NULL),
481       server_cert_verify_result_(NULL),
482       ssl_connection_status_(0),
483       client_auth_cert_needed_(false),
484       cert_verifier_(cert_verifier),
485       handshake_callback_called_(false),
486       completed_handshake_(false),
487       eset_mitm_detected_(false),
488       predicted_cert_chain_correct_(false),
489       peername_initialized_(false),
490       dnssec_provider_(NULL),
491       next_handshake_state_(STATE_NONE),
492       nss_fd_(NULL),
493       nss_bufs_(NULL),
494       net_log_(transport_socket->socket()->NetLog()),
495       ssl_host_info_(ssl_host_info),
496       dns_cert_checker_(dns_ctx),
497       valid_thread_id_(base::kInvalidThreadId) {
498   EnterFunction("");
499 }
500 
~SSLClientSocketNSS()501 SSLClientSocketNSS::~SSLClientSocketNSS() {
502   EnterFunction("");
503   Disconnect();
504   LeaveFunction("");
505 }
506 
507 // static
ClearSessionCache()508 void SSLClientSocketNSS::ClearSessionCache() {
509   SSL_ClearSessionCache();
510 }
511 
GetSSLInfo(SSLInfo * ssl_info)512 void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) {
513   EnterFunction("");
514   ssl_info->Reset();
515 
516   if (!server_cert_)
517     return;
518 
519   ssl_info->cert_status = server_cert_verify_result_->cert_status;
520   DCHECK(server_cert_ != NULL);
521   ssl_info->cert = server_cert_;
522   ssl_info->connection_status = ssl_connection_status_;
523   ssl_info->public_key_hashes = server_cert_verify_result_->public_key_hashes;
524   ssl_info->is_issued_by_known_root =
525       server_cert_verify_result_->is_issued_by_known_root;
526 
527   PRUint16 cipher_suite =
528       SSLConnectionStatusToCipherSuite(ssl_connection_status_);
529   SSLCipherSuiteInfo cipher_info;
530   SECStatus ok = SSL_GetCipherSuiteInfo(cipher_suite,
531                                         &cipher_info, sizeof(cipher_info));
532   if (ok == SECSuccess) {
533     ssl_info->security_bits = cipher_info.effectiveKeyBits;
534   } else {
535     ssl_info->security_bits = -1;
536     LOG(DFATAL) << "SSL_GetCipherSuiteInfo returned " << PR_GetError()
537                 << " for cipherSuite " << cipher_suite;
538   }
539   LeaveFunction("");
540 }
541 
GetSSLCertRequestInfo(SSLCertRequestInfo * cert_request_info)542 void SSLClientSocketNSS::GetSSLCertRequestInfo(
543     SSLCertRequestInfo* cert_request_info) {
544   EnterFunction("");
545   // TODO(rch): switch SSLCertRequestInfo.host_and_port to a HostPortPair
546   cert_request_info->host_and_port = host_and_port_.ToString();
547   cert_request_info->client_certs = client_certs_;
548   LeaveFunction(cert_request_info->client_certs.size());
549 }
550 
551 SSLClientSocket::NextProtoStatus
GetNextProto(std::string * proto)552 SSLClientSocketNSS::GetNextProto(std::string* proto) {
553 #if defined(SSL_NEXT_PROTO_NEGOTIATED)
554   unsigned char buf[255];
555   int state;
556   unsigned len;
557   SECStatus rv = SSL_GetNextProto(nss_fd_, &state, buf, &len, sizeof(buf));
558   if (rv != SECSuccess) {
559     NOTREACHED() << "Error return from SSL_GetNextProto: " << rv;
560     proto->clear();
561     return kNextProtoUnsupported;
562   }
563   // We don't check for truncation because sizeof(buf) is large enough to hold
564   // the maximum protocol size.
565   switch (state) {
566     case SSL_NEXT_PROTO_NO_SUPPORT:
567       proto->clear();
568       return kNextProtoUnsupported;
569     case SSL_NEXT_PROTO_NEGOTIATED:
570       *proto = std::string(reinterpret_cast<char*>(buf), len);
571       return kNextProtoNegotiated;
572     case SSL_NEXT_PROTO_NO_OVERLAP:
573       *proto = std::string(reinterpret_cast<char*>(buf), len);
574       return kNextProtoNoOverlap;
575     default:
576       NOTREACHED() << "Unknown status from SSL_GetNextProto: " << state;
577       proto->clear();
578       return kNextProtoUnsupported;
579   }
580 #else
581   // No NPN support in the libssl that we are building with.
582   proto->clear();
583   return kNextProtoUnsupported;
584 #endif
585 }
586 
UseDNSSEC(DNSSECProvider * provider)587 void SSLClientSocketNSS::UseDNSSEC(DNSSECProvider* provider) {
588   dnssec_provider_ = provider;
589 }
590 
591 #ifdef ANDROID
592 // TODO(kristianm): handle the case when wait_for_connect is true
593 // (sync requests)
594 #endif
Connect(CompletionCallback * callback,bool wait_for_connect)595 int SSLClientSocketNSS::Connect(CompletionCallback* callback
596 #ifdef ANDROID
597                                 , bool wait_for_connect
598 #endif
599                                ) {
600   EnterFunction("");
601   DCHECK(transport_.get());
602   DCHECK(next_handshake_state_ == STATE_NONE);
603   DCHECK(!user_read_callback_);
604   DCHECK(!user_write_callback_);
605   DCHECK(!user_connect_callback_);
606   DCHECK(!user_read_buf_);
607   DCHECK(!user_write_buf_);
608 
609   EnsureThreadIdAssigned();
610 
611   net_log_.BeginEvent(NetLog::TYPE_SSL_CONNECT, NULL);
612 
613   int rv = Init();
614   if (rv != OK) {
615     net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
616     return rv;
617   }
618 
619   rv = InitializeSSLOptions();
620   if (rv != OK) {
621     net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
622     return rv;
623   }
624 
625   // Attempt to initialize the peer name.  In the case of TCP FastOpen,
626   // we don't have the peer yet.
627   if (!UsingTCPFastOpen()) {
628     rv = InitializeSSLPeerName();
629     if (rv != OK) {
630       net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
631       return rv;
632     }
633   }
634 
635   GotoState(STATE_HANDSHAKE);
636 
637   rv = DoHandshakeLoop(OK);
638   if (rv == ERR_IO_PENDING) {
639     user_connect_callback_ = callback;
640   } else {
641     net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
642   }
643 
644   LeaveFunction("");
645   return rv > OK ? OK : rv;
646 }
647 
Disconnect()648 void SSLClientSocketNSS::Disconnect() {
649   EnterFunction("");
650 
651   CHECK(CalledOnValidThread());
652 
653   // Shut down anything that may call us back (through buffer_send_callback_,
654   // buffer_recv_callback, or handshake_io_callback_).
655   verifier_.reset();
656   transport_->socket()->Disconnect();
657 
658   // TODO(wtc): Send SSL close_notify alert.
659   if (nss_fd_ != NULL) {
660     PR_Close(nss_fd_);
661     nss_fd_ = NULL;
662   }
663 
664   // Reset object state
665   transport_send_busy_   = false;
666   transport_recv_busy_   = false;
667   user_connect_callback_ = NULL;
668   user_read_callback_    = NULL;
669   user_write_callback_   = NULL;
670   user_read_buf_         = NULL;
671   user_read_buf_len_     = 0;
672   user_write_buf_        = NULL;
673   user_write_buf_len_    = 0;
674   server_cert_           = NULL;
675   if (server_cert_nss_) {
676     CERT_DestroyCertificate(server_cert_nss_);
677     server_cert_nss_     = NULL;
678   }
679   local_server_cert_verify_result_.Reset();
680   server_cert_verify_result_ = NULL;
681   ssl_connection_status_ = 0;
682   completed_handshake_   = false;
683   eset_mitm_detected_    = false;
684   start_cert_verification_time_ = base::TimeTicks();
685   predicted_cert_chain_correct_ = false;
686   peername_initialized_  = false;
687   nss_bufs_              = NULL;
688   client_certs_.clear();
689   client_auth_cert_needed_ = false;
690 
691   LeaveFunction("");
692 }
693 
IsConnected() const694 bool SSLClientSocketNSS::IsConnected() const {
695   // Ideally, we should also check if we have received the close_notify alert
696   // message from the server, and return false in that case.  We're not doing
697   // that, so this function may return a false positive.  Since the upper
698   // layer (HttpNetworkTransaction) needs to handle a persistent connection
699   // closed by the server when we send a request anyway, a false positive in
700   // exchange for simpler code is a good trade-off.
701   EnterFunction("");
702   bool ret = completed_handshake_ && transport_->socket()->IsConnected();
703   LeaveFunction("");
704   return ret;
705 }
706 
IsConnectedAndIdle() const707 bool SSLClientSocketNSS::IsConnectedAndIdle() const {
708   // Unlike IsConnected, this method doesn't return a false positive.
709   //
710   // Strictly speaking, we should check if we have received the close_notify
711   // alert message from the server, and return false in that case.  Although
712   // the close_notify alert message means EOF in the SSL layer, it is just
713   // bytes to the transport layer below, so
714   // transport_->socket()->IsConnectedAndIdle() returns the desired false
715   // when we receive close_notify.
716   EnterFunction("");
717   bool ret = completed_handshake_ && transport_->socket()->IsConnectedAndIdle();
718   LeaveFunction("");
719   return ret;
720 }
721 
GetPeerAddress(AddressList * address) const722 int SSLClientSocketNSS::GetPeerAddress(AddressList* address) const {
723   return transport_->socket()->GetPeerAddress(address);
724 }
725 
GetLocalAddress(IPEndPoint * address) const726 int SSLClientSocketNSS::GetLocalAddress(IPEndPoint* address) const {
727   return transport_->socket()->GetLocalAddress(address);
728 }
729 
NetLog() const730 const BoundNetLog& SSLClientSocketNSS::NetLog() const {
731   return net_log_;
732 }
733 
SetSubresourceSpeculation()734 void SSLClientSocketNSS::SetSubresourceSpeculation() {
735   if (transport_.get() && transport_->socket()) {
736     transport_->socket()->SetSubresourceSpeculation();
737   } else {
738     NOTREACHED();
739   }
740 }
741 
SetOmniboxSpeculation()742 void SSLClientSocketNSS::SetOmniboxSpeculation() {
743   if (transport_.get() && transport_->socket()) {
744     transport_->socket()->SetOmniboxSpeculation();
745   } else {
746     NOTREACHED();
747   }
748 }
749 
WasEverUsed() const750 bool SSLClientSocketNSS::WasEverUsed() const {
751   if (transport_.get() && transport_->socket()) {
752     return transport_->socket()->WasEverUsed();
753   }
754   NOTREACHED();
755   return false;
756 }
757 
UsingTCPFastOpen() const758 bool SSLClientSocketNSS::UsingTCPFastOpen() const {
759   if (transport_.get() && transport_->socket()) {
760     return transport_->socket()->UsingTCPFastOpen();
761   }
762   NOTREACHED();
763   return false;
764 }
765 
Read(IOBuffer * buf,int buf_len,CompletionCallback * callback)766 int SSLClientSocketNSS::Read(IOBuffer* buf, int buf_len,
767                              CompletionCallback* callback) {
768   EnterFunction(buf_len);
769   DCHECK(completed_handshake_);
770   DCHECK(next_handshake_state_ == STATE_NONE);
771   DCHECK(!user_read_callback_);
772   DCHECK(!user_connect_callback_);
773   DCHECK(!user_read_buf_);
774   DCHECK(nss_bufs_);
775 
776   user_read_buf_ = buf;
777   user_read_buf_len_ = buf_len;
778 
779   int rv = DoReadLoop(OK);
780 
781   if (rv == ERR_IO_PENDING) {
782     user_read_callback_ = callback;
783   } else {
784     user_read_buf_ = NULL;
785     user_read_buf_len_ = 0;
786   }
787   LeaveFunction(rv);
788   return rv;
789 }
790 
Write(IOBuffer * buf,int buf_len,CompletionCallback * callback)791 int SSLClientSocketNSS::Write(IOBuffer* buf, int buf_len,
792                               CompletionCallback* callback) {
793   EnterFunction(buf_len);
794   DCHECK(completed_handshake_);
795   DCHECK(next_handshake_state_ == STATE_NONE);
796   DCHECK(!user_write_callback_);
797   DCHECK(!user_connect_callback_);
798   DCHECK(!user_write_buf_);
799   DCHECK(nss_bufs_);
800 
801   user_write_buf_ = buf;
802   user_write_buf_len_ = buf_len;
803 
804   if (corked_) {
805     corked_ = false;
806     uncork_timer_.Reset();
807   }
808   int rv = DoWriteLoop(OK);
809 
810   if (rv == ERR_IO_PENDING) {
811     user_write_callback_ = callback;
812   } else {
813     user_write_buf_ = NULL;
814     user_write_buf_len_ = 0;
815   }
816   LeaveFunction(rv);
817   return rv;
818 }
819 
SetReceiveBufferSize(int32 size)820 bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) {
821   return transport_->socket()->SetReceiveBufferSize(size);
822 }
823 
SetSendBufferSize(int32 size)824 bool SSLClientSocketNSS::SetSendBufferSize(int32 size) {
825   return transport_->socket()->SetSendBufferSize(size);
826 }
827 
Init()828 int SSLClientSocketNSS::Init() {
829   EnterFunction("");
830   // Initialize the NSS SSL library in a threadsafe way.  This also
831   // initializes the NSS base library.
832   EnsureNSSSSLInit();
833   if (!NSS_IsInitialized())
834     return ERR_UNEXPECTED;
835 #if !defined(OS_MACOSX) && !defined(OS_WIN)
836   // We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop
837   // by MessageLoopForIO::current().
838   // X509Certificate::Verify() runs on a worker thread of CertVerifier.
839   EnsureOCSPInit();
840 #endif
841 
842   LeaveFunction("");
843   return OK;
844 }
845 
InitializeSSLOptions()846 int SSLClientSocketNSS::InitializeSSLOptions() {
847   // Transport connected, now hook it up to nss
848   // TODO(port): specify rx and tx buffer sizes separately
849   nss_fd_ = memio_CreateIOLayer(kRecvBufferSize);
850   if (nss_fd_ == NULL) {
851     return ERR_OUT_OF_MEMORY;  // TODO(port): map NSPR error code.
852   }
853 
854   // Grab pointer to buffers
855   nss_bufs_ = memio_GetSecret(nss_fd_);
856 
857   /* Create SSL state machine */
858   /* Push SSL onto our fake I/O socket */
859   nss_fd_ = SSL_ImportFD(NULL, nss_fd_);
860   if (nss_fd_ == NULL) {
861     LogFailedNSSFunction(net_log_, "SSL_ImportFD", "");
862     return ERR_OUT_OF_MEMORY;  // TODO(port): map NSPR/NSS error code.
863   }
864   // TODO(port): set more ssl options!  Check errors!
865 
866   int rv;
867 
868   rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE);
869   if (rv != SECSuccess) {
870     LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_SECURITY");
871     return ERR_UNEXPECTED;
872   }
873 
874   rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL2, PR_FALSE);
875   if (rv != SECSuccess) {
876     LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL2");
877     return ERR_UNEXPECTED;
878   }
879 
880   // Don't do V2 compatible hellos because they don't support TLS extensions.
881   rv = SSL_OptionSet(nss_fd_, SSL_V2_COMPATIBLE_HELLO, PR_FALSE);
882   if (rv != SECSuccess) {
883     LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_V2_COMPATIBLE_HELLO");
884     return ERR_UNEXPECTED;
885   }
886 
887   rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL3, ssl_config_.ssl3_enabled);
888   if (rv != SECSuccess) {
889     LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL3");
890     return ERR_UNEXPECTED;
891   }
892 
893   rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_TLS, ssl_config_.tls1_enabled);
894   if (rv != SECSuccess) {
895     LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_TLS");
896     return ERR_UNEXPECTED;
897   }
898 
899   for (std::vector<uint16>::const_iterator it =
900            ssl_config_.disabled_cipher_suites.begin();
901        it != ssl_config_.disabled_cipher_suites.end(); ++it) {
902     // This will fail if the specified cipher is not implemented by NSS, but
903     // the failure is harmless.
904     SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE);
905   }
906 
907 #ifdef SSL_ENABLE_SESSION_TICKETS
908   // Support RFC 5077
909   rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_TRUE);
910   if (rv != SECSuccess) {
911     LogFailedNSSFunction(
912         net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS");
913   }
914 #else
915   #error "You need to install NSS-3.12 or later to build chromium"
916 #endif
917 
918 #ifdef SSL_ENABLE_DEFLATE
919   // Some web servers have been found to break if TLS is used *or* if DEFLATE
920   // is advertised. Thus, if TLS is disabled (probably because we are doing
921   // SSLv3 fallback), we disable DEFLATE also.
922   // See http://crbug.com/31628
923   rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_DEFLATE, ssl_config_.tls1_enabled);
924   if (rv != SECSuccess)
925     LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_DEFLATE");
926 #endif
927 
928 #ifdef SSL_ENABLE_FALSE_START
929   rv = SSL_OptionSet(
930       nss_fd_, SSL_ENABLE_FALSE_START,
931       ssl_config_.false_start_enabled &&
932       !SSLConfigService::IsKnownFalseStartIncompatibleServer(
933           host_and_port_.host()));
934   if (rv != SECSuccess)
935     LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_FALSE_START");
936 #endif
937 
938 #ifdef SSL_ENABLE_RENEGOTIATION
939   // We allow servers to request renegotiation. Since we're a client,
940   // prohibiting this is rather a waste of time. Only servers are in a
941   // position to prevent renegotiation attacks.
942   // http://extendedsubset.com/?p=8
943 
944   rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION,
945                      SSL_RENEGOTIATE_TRANSITIONAL);
946   if (rv != SECSuccess) {
947     LogFailedNSSFunction(
948         net_log_, "SSL_OptionSet", "SSL_ENABLE_RENEGOTIATION");
949   }
950 #endif  // SSL_ENABLE_RENEGOTIATION
951 
952 #ifdef SSL_NEXT_PROTO_NEGOTIATED
953   if (!ssl_config_.next_protos.empty()) {
954     rv = SSL_SetNextProtoNego(
955        nss_fd_,
956        reinterpret_cast<const unsigned char *>(ssl_config_.next_protos.data()),
957        ssl_config_.next_protos.size());
958     if (rv != SECSuccess)
959       LogFailedNSSFunction(net_log_, "SSL_SetNextProtoNego", "");
960   }
961 #endif
962 
963 #ifdef SSL_ENABLE_OCSP_STAPLING
964   if (IsOCSPStaplingSupported()) {
965     rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE);
966     if (rv != SECSuccess)
967       LogFailedNSSFunction(net_log_, "SSL_OptionSet (OCSP stapling)", "");
968   }
969 #endif
970 
971   rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
972   if (rv != SECSuccess) {
973     LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT");
974     return ERR_UNEXPECTED;
975   }
976 
977   rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this);
978   if (rv != SECSuccess) {
979     LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", "");
980     return ERR_UNEXPECTED;
981   }
982 
983 #if defined(NSS_PLATFORM_CLIENT_AUTH)
984   rv = SSL_GetPlatformClientAuthDataHook(nss_fd_, PlatformClientAuthHandler,
985                                          this);
986 #else
987   rv = SSL_GetClientAuthDataHook(nss_fd_, ClientAuthHandler, this);
988 #endif
989   if (rv != SECSuccess) {
990     LogFailedNSSFunction(net_log_, "SSL_GetClientAuthDataHook", "");
991     return ERR_UNEXPECTED;
992   }
993 
994   rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this);
995   if (rv != SECSuccess) {
996     LogFailedNSSFunction(net_log_, "SSL_HandshakeCallback", "");
997     return ERR_UNEXPECTED;
998   }
999 
1000   // Tell SSL the hostname we're trying to connect to.
1001   SSL_SetURL(nss_fd_, host_and_port_.host().c_str());
1002 
1003   // Tell SSL we're a client; needed if not letting NSPR do socket I/O
1004   SSL_ResetHandshake(nss_fd_, 0);
1005 
1006   return OK;
1007 }
1008 
InitializeSSLPeerName()1009 int SSLClientSocketNSS::InitializeSSLPeerName() {
1010   // Tell NSS who we're connected to
1011   AddressList peer_address;
1012   int err = transport_->socket()->GetPeerAddress(&peer_address);
1013   if (err != OK)
1014     return err;
1015 
1016   const struct addrinfo* ai = peer_address.head();
1017 
1018   PRNetAddr peername;
1019   memset(&peername, 0, sizeof(peername));
1020   DCHECK_LE(ai->ai_addrlen, sizeof(peername));
1021   size_t len = std::min(static_cast<size_t>(ai->ai_addrlen),
1022                         sizeof(peername));
1023   memcpy(&peername, ai->ai_addr, len);
1024 
1025   // Adjust the address family field for BSD, whose sockaddr
1026   // structure has a one-byte length and one-byte address family
1027   // field at the beginning.  PRNetAddr has a two-byte address
1028   // family field at the beginning.
1029   peername.raw.family = ai->ai_addr->sa_family;
1030 
1031   memio_SetPeerName(nss_fd_, &peername);
1032 
1033   // Set the peer ID for session reuse.  This is necessary when we create an
1034   // SSL tunnel through a proxy -- GetPeerName returns the proxy's address
1035   // rather than the destination server's address in that case.
1036   std::string peer_id = host_and_port_.ToString();
1037   SECStatus rv = SSL_SetSockPeerID(nss_fd_, const_cast<char*>(peer_id.c_str()));
1038   if (rv != SECSuccess)
1039     LogFailedNSSFunction(net_log_, "SSL_SetSockPeerID", peer_id.c_str());
1040 
1041   peername_initialized_ = true;
1042   return OK;
1043 }
1044 
1045 
1046 // Sets server_cert_ and server_cert_nss_ if not yet set.
1047 // Returns server_cert_.
UpdateServerCert()1048 X509Certificate *SSLClientSocketNSS::UpdateServerCert() {
1049   // We set the server_cert_ from HandshakeCallback().
1050   if (server_cert_ == NULL) {
1051     server_cert_nss_ = SSL_PeerCertificate(nss_fd_);
1052     if (server_cert_nss_) {
1053       PeerCertificateChain certs(nss_fd_);
1054       server_cert_ = X509Certificate::CreateFromDERCertChain(
1055           certs.AsStringPieceVector());
1056     }
1057   }
1058   return server_cert_;
1059 }
1060 
1061 // Sets ssl_connection_status_.
UpdateConnectionStatus()1062 void SSLClientSocketNSS::UpdateConnectionStatus() {
1063   SSLChannelInfo channel_info;
1064   SECStatus ok = SSL_GetChannelInfo(nss_fd_,
1065                                     &channel_info, sizeof(channel_info));
1066   if (ok == SECSuccess &&
1067       channel_info.length == sizeof(channel_info) &&
1068       channel_info.cipherSuite) {
1069     ssl_connection_status_ |=
1070         (static_cast<int>(channel_info.cipherSuite) &
1071          SSL_CONNECTION_CIPHERSUITE_MASK) <<
1072         SSL_CONNECTION_CIPHERSUITE_SHIFT;
1073 
1074     ssl_connection_status_ |=
1075         (static_cast<int>(channel_info.compressionMethod) &
1076          SSL_CONNECTION_COMPRESSION_MASK) <<
1077         SSL_CONNECTION_COMPRESSION_SHIFT;
1078 
1079     // NSS 3.12.x doesn't have version macros for TLS 1.1 and 1.2 (because NSS
1080     // doesn't support them yet), so we use 0x0302 and 0x0303 directly.
1081     int version = SSL_CONNECTION_VERSION_UNKNOWN;
1082     if (channel_info.protocolVersion < SSL_LIBRARY_VERSION_3_0) {
1083       // All versions less than SSL_LIBRARY_VERSION_3_0 are treated as SSL
1084       // version 2.
1085       version = SSL_CONNECTION_VERSION_SSL2;
1086     } else if (channel_info.protocolVersion == SSL_LIBRARY_VERSION_3_0) {
1087       version = SSL_CONNECTION_VERSION_SSL3;
1088     } else if (channel_info.protocolVersion == SSL_LIBRARY_VERSION_3_1_TLS) {
1089       version = SSL_CONNECTION_VERSION_TLS1;
1090     } else if (channel_info.protocolVersion == 0x0302) {
1091       version = SSL_CONNECTION_VERSION_TLS1_1;
1092     } else if (channel_info.protocolVersion == 0x0303) {
1093       version = SSL_CONNECTION_VERSION_TLS1_2;
1094     }
1095     ssl_connection_status_ |=
1096         (version & SSL_CONNECTION_VERSION_MASK) <<
1097         SSL_CONNECTION_VERSION_SHIFT;
1098   }
1099 
1100   // SSL_HandshakeNegotiatedExtension was added in NSS 3.12.6.
1101   // Since SSL_MAX_EXTENSIONS was added at the same time, we can test
1102   // SSL_MAX_EXTENSIONS for the presence of SSL_HandshakeNegotiatedExtension.
1103 #if defined(SSL_MAX_EXTENSIONS)
1104   PRBool peer_supports_renego_ext;
1105   ok = SSL_HandshakeNegotiatedExtension(nss_fd_, ssl_renegotiation_info_xtn,
1106                                         &peer_supports_renego_ext);
1107   if (ok == SECSuccess) {
1108     if (!peer_supports_renego_ext) {
1109       ssl_connection_status_ |= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION;
1110       // Log an informational message if the server does not support secure
1111       // renegotiation (RFC 5746).
1112       VLOG(1) << "The server " << host_and_port_.ToString()
1113               << " does not support the TLS renegotiation_info extension.";
1114     }
1115     UMA_HISTOGRAM_ENUMERATION("Net.RenegotiationExtensionSupported",
1116                               peer_supports_renego_ext, 2);
1117   }
1118 #endif
1119 
1120   if (ssl_config_.ssl3_fallback)
1121     ssl_connection_status_ |= SSL_CONNECTION_SSL3_FALLBACK;
1122 }
1123 
DoReadCallback(int rv)1124 void SSLClientSocketNSS::DoReadCallback(int rv) {
1125   EnterFunction(rv);
1126   DCHECK(rv != ERR_IO_PENDING);
1127   DCHECK(user_read_callback_);
1128 
1129   // Since Run may result in Read being called, clear |user_read_callback_|
1130   // up front.
1131   CompletionCallback* c = user_read_callback_;
1132   user_read_callback_ = NULL;
1133   user_read_buf_ = NULL;
1134   user_read_buf_len_ = 0;
1135   c->Run(rv);
1136   LeaveFunction("");
1137 }
1138 
DoWriteCallback(int rv)1139 void SSLClientSocketNSS::DoWriteCallback(int rv) {
1140   EnterFunction(rv);
1141   DCHECK(rv != ERR_IO_PENDING);
1142   DCHECK(user_write_callback_);
1143 
1144   // Since Run may result in Write being called, clear |user_write_callback_|
1145   // up front.
1146   CompletionCallback* c = user_write_callback_;
1147   user_write_callback_ = NULL;
1148   user_write_buf_ = NULL;
1149   user_write_buf_len_ = 0;
1150   c->Run(rv);
1151   LeaveFunction("");
1152 }
1153 
1154 // As part of Connect(), the SSLClientSocketNSS object performs an SSL
1155 // handshake. This requires network IO, which in turn calls
1156 // BufferRecvComplete() with a non-zero byte count. This byte count eventually
1157 // winds its way through the state machine and ends up being passed to the
1158 // callback. For Read() and Write(), that's what we want. But for Connect(),
1159 // the caller expects OK (i.e. 0) for success.
1160 //
DoConnectCallback(int rv)1161 void SSLClientSocketNSS::DoConnectCallback(int rv) {
1162   EnterFunction(rv);
1163   DCHECK_NE(rv, ERR_IO_PENDING);
1164   DCHECK(user_connect_callback_);
1165 
1166   CompletionCallback* c = user_connect_callback_;
1167   user_connect_callback_ = NULL;
1168   c->Run(rv > OK ? OK : rv);
1169   LeaveFunction("");
1170 }
1171 
OnHandshakeIOComplete(int result)1172 void SSLClientSocketNSS::OnHandshakeIOComplete(int result) {
1173   EnterFunction(result);
1174   int rv = DoHandshakeLoop(result);
1175   if (rv != ERR_IO_PENDING) {
1176     net_log_.EndEventWithNetErrorCode(net::NetLog::TYPE_SSL_CONNECT, rv);
1177     DoConnectCallback(rv);
1178   }
1179   LeaveFunction("");
1180 }
1181 
OnSendComplete(int result)1182 void SSLClientSocketNSS::OnSendComplete(int result) {
1183   EnterFunction(result);
1184   if (next_handshake_state_ == STATE_HANDSHAKE) {
1185     // In handshake phase.
1186     OnHandshakeIOComplete(result);
1187     LeaveFunction("");
1188     return;
1189   }
1190 
1191   // OnSendComplete may need to call DoPayloadRead while the renegotiation
1192   // handshake is in progress.
1193   int rv_read = ERR_IO_PENDING;
1194   int rv_write = ERR_IO_PENDING;
1195   bool network_moved;
1196   do {
1197       if (user_read_buf_)
1198           rv_read = DoPayloadRead();
1199       if (user_write_buf_)
1200           rv_write = DoPayloadWrite();
1201       network_moved = DoTransportIO();
1202   } while (rv_read == ERR_IO_PENDING &&
1203            rv_write == ERR_IO_PENDING &&
1204            network_moved);
1205 
1206   if (user_read_buf_ && rv_read != ERR_IO_PENDING)
1207       DoReadCallback(rv_read);
1208   if (user_write_buf_ && rv_write != ERR_IO_PENDING)
1209       DoWriteCallback(rv_write);
1210 
1211   LeaveFunction("");
1212 }
1213 
OnRecvComplete(int result)1214 void SSLClientSocketNSS::OnRecvComplete(int result) {
1215   EnterFunction(result);
1216   if (next_handshake_state_ == STATE_HANDSHAKE) {
1217     // In handshake phase.
1218     OnHandshakeIOComplete(result);
1219     LeaveFunction("");
1220     return;
1221   }
1222 
1223   // Network layer received some data, check if client requested to read
1224   // decrypted data.
1225   if (!user_read_buf_) {
1226     LeaveFunction("");
1227     return;
1228   }
1229 
1230   int rv = DoReadLoop(result);
1231   if (rv != ERR_IO_PENDING)
1232     DoReadCallback(rv);
1233   LeaveFunction("");
1234 }
1235 
DoHandshakeLoop(int last_io_result)1236 int SSLClientSocketNSS::DoHandshakeLoop(int last_io_result) {
1237   EnterFunction(last_io_result);
1238   bool network_moved;
1239   int rv = last_io_result;
1240   do {
1241     // Default to STATE_NONE for next state.
1242     // (This is a quirk carried over from the windows
1243     // implementation.  It makes reading the logs a bit harder.)
1244     // State handlers can and often do call GotoState just
1245     // to stay in the current state.
1246     State state = next_handshake_state_;
1247     GotoState(STATE_NONE);
1248     switch (state) {
1249       case STATE_NONE:
1250         // we're just pumping data between the buffer and the network
1251         break;
1252       case STATE_HANDSHAKE:
1253         rv = DoHandshake();
1254         break;
1255       case STATE_VERIFY_DNSSEC:
1256         rv = DoVerifyDNSSEC(rv);
1257         break;
1258       case STATE_VERIFY_DNSSEC_COMPLETE:
1259         rv = DoVerifyDNSSECComplete(rv);
1260         break;
1261       case STATE_VERIFY_CERT:
1262         DCHECK(rv == OK);
1263         rv = DoVerifyCert(rv);
1264         break;
1265       case STATE_VERIFY_CERT_COMPLETE:
1266         rv = DoVerifyCertComplete(rv);
1267         break;
1268       default:
1269         rv = ERR_UNEXPECTED;
1270         LOG(DFATAL) << "unexpected state " << state;
1271         break;
1272     }
1273 
1274     // Do the actual network I/O
1275     network_moved = DoTransportIO();
1276   } while ((rv != ERR_IO_PENDING || network_moved) &&
1277            next_handshake_state_ != STATE_NONE);
1278   LeaveFunction("");
1279   return rv;
1280 }
1281 
DoReadLoop(int result)1282 int SSLClientSocketNSS::DoReadLoop(int result) {
1283   EnterFunction("");
1284   DCHECK(completed_handshake_);
1285   DCHECK(next_handshake_state_ == STATE_NONE);
1286 
1287   if (result < 0)
1288     return result;
1289 
1290   if (!nss_bufs_) {
1291     LOG(DFATAL) << "!nss_bufs_";
1292     int rv = ERR_UNEXPECTED;
1293     net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR,
1294                       make_scoped_refptr(new SSLErrorParams(rv, 0)));
1295     return rv;
1296   }
1297 
1298   bool network_moved;
1299   int rv;
1300   do {
1301     rv = DoPayloadRead();
1302     network_moved = DoTransportIO();
1303   } while (rv == ERR_IO_PENDING && network_moved);
1304 
1305   LeaveFunction("");
1306   return rv;
1307 }
1308 
DoWriteLoop(int result)1309 int SSLClientSocketNSS::DoWriteLoop(int result) {
1310   EnterFunction("");
1311   DCHECK(completed_handshake_);
1312   DCHECK(next_handshake_state_ == STATE_NONE);
1313 
1314   if (result < 0)
1315     return result;
1316 
1317   if (!nss_bufs_) {
1318     LOG(DFATAL) << "!nss_bufs_";
1319     int rv = ERR_UNEXPECTED;
1320     net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR,
1321                       make_scoped_refptr(new SSLErrorParams(rv, 0)));
1322     return rv;
1323   }
1324 
1325   bool network_moved;
1326   int rv;
1327   do {
1328     rv = DoPayloadWrite();
1329     network_moved = DoTransportIO();
1330   } while (rv == ERR_IO_PENDING && network_moved);
1331 
1332   LeaveFunction("");
1333   return rv;
1334 }
1335 
DoHandshake()1336 int SSLClientSocketNSS::DoHandshake() {
1337   EnterFunction("");
1338   int net_error = net::OK;
1339   SECStatus rv = SSL_ForceHandshake(nss_fd_);
1340 
1341   if (client_auth_cert_needed_) {
1342     net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
1343     net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR,
1344                       make_scoped_refptr(new SSLErrorParams(net_error, 0)));
1345     // If the handshake already succeeded (because the server requests but
1346     // doesn't require a client cert), we need to invalidate the SSL session
1347     // so that we won't try to resume the non-client-authenticated session in
1348     // the next handshake.  This will cause the server to ask for a client
1349     // cert again.
1350     if (rv == SECSuccess && SSL_InvalidateSession(nss_fd_) != SECSuccess) {
1351       LOG(WARNING) << "Couldn't invalidate SSL session: " << PR_GetError();
1352     }
1353   } else if (rv == SECSuccess) {
1354     if (handshake_callback_called_) {
1355       if (eset_mitm_detected_) {
1356         net_error = ERR_ESET_ANTI_VIRUS_SSL_INTERCEPTION;
1357       } else {
1358         // We need to see if the predicted certificate chain (in
1359         // |ssl_host_info_->state().certs) matches the actual certificate chain
1360         // before we try to save it before we update |ssl_host_info_|.
1361         if (ssl_host_info_.get() && !ssl_host_info_->state().certs.empty()) {
1362           PeerCertificateChain certs(nss_fd_);
1363           const SSLHostInfo::State& state = ssl_host_info_->state();
1364           predicted_cert_chain_correct_ = certs.size() == state.certs.size();
1365           if (predicted_cert_chain_correct_) {
1366             for (unsigned i = 0; i < certs.size(); i++) {
1367               if (certs[i]->derCert.len != state.certs[i].size() ||
1368                   memcmp(certs[i]->derCert.data, state.certs[i].data(),
1369                          certs[i]->derCert.len) != 0) {
1370                 predicted_cert_chain_correct_ = false;
1371                 break;
1372               }
1373             }
1374           }
1375         }
1376 
1377 #if defined(SSL_ENABLE_OCSP_STAPLING)
1378         // TODO(agl): figure out how to plumb an OCSP response into the Mac
1379         // system library and update IsOCSPStaplingSupported for Mac.
1380         if (!predicted_cert_chain_correct_ && IsOCSPStaplingSupported()) {
1381           unsigned int len = 0;
1382           SSL_GetStapledOCSPResponse(nss_fd_, NULL, &len);
1383           if (len) {
1384             const unsigned int orig_len = len;
1385             scoped_array<uint8> ocsp_response(new uint8[orig_len]);
1386             SSL_GetStapledOCSPResponse(nss_fd_, ocsp_response.get(), &len);
1387             DCHECK_EQ(orig_len, len);
1388 
1389 #if defined(OS_WIN)
1390             CRYPT_DATA_BLOB ocsp_response_blob;
1391             ocsp_response_blob.cbData = len;
1392             ocsp_response_blob.pbData = ocsp_response.get();
1393             BOOL ok = CertSetCertificateContextProperty(
1394                 server_cert_->os_cert_handle(),
1395                 CERT_OCSP_RESPONSE_PROP_ID,
1396                 CERT_SET_PROPERTY_IGNORE_PERSIST_ERROR_FLAG,
1397                 &ocsp_response_blob);
1398             if (!ok) {
1399               VLOG(1) << "Failed to set OCSP response property: "
1400                       << GetLastError();
1401             }
1402 #elif defined(USE_NSS)
1403             CacheOCSPResponseFromSideChannelFunction cache_ocsp_response =
1404                 GetCacheOCSPResponseFromSideChannelFunction();
1405             SECItem ocsp_response_item;
1406             ocsp_response_item.type = siBuffer;
1407             ocsp_response_item.data = ocsp_response.get();
1408             ocsp_response_item.len = len;
1409 
1410             cache_ocsp_response(
1411                 CERT_GetDefaultCertDB(), server_cert_nss_, PR_Now(),
1412                 &ocsp_response_item, NULL);
1413 #endif
1414           }
1415         }
1416 #endif
1417 
1418         SaveSSLHostInfo();
1419         // SSL handshake is completed. Let's verify the certificate.
1420         GotoState(STATE_VERIFY_DNSSEC);
1421       }
1422       // Done!
1423     } else {
1424       // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=562434 -
1425       // SSL_ForceHandshake returned SECSuccess prematurely.
1426       rv = SECFailure;
1427       net_error = ERR_SSL_PROTOCOL_ERROR;
1428       net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR,
1429                         make_scoped_refptr(new SSLErrorParams(net_error, 0)));
1430     }
1431   } else {
1432     PRErrorCode prerr = PR_GetError();
1433     net_error = HandleNSSError(prerr, true);
1434 
1435     // If not done, stay in this state
1436     if (net_error == ERR_IO_PENDING) {
1437       GotoState(STATE_HANDSHAKE);
1438     } else {
1439       LOG(ERROR) << "handshake failed; NSS error code " << prerr
1440                  << ", net_error " << net_error;
1441       net_log_.AddEvent(
1442           NetLog::TYPE_SSL_HANDSHAKE_ERROR,
1443           make_scoped_refptr(new SSLErrorParams(net_error, prerr)));
1444     }
1445   }
1446 
1447   LeaveFunction("");
1448   return net_error;
1449 }
1450 
DoVerifyDNSSEC(int result)1451 int SSLClientSocketNSS::DoVerifyDNSSEC(int result) {
1452   if (ssl_config_.dns_cert_provenance_checking_enabled &&
1453       dns_cert_checker_) {
1454     PeerCertificateChain certs(nss_fd_);
1455     dns_cert_checker_->DoAsyncVerification(
1456         host_and_port_.host(), certs.AsStringPieceVector());
1457   }
1458 
1459   if (ssl_config_.dnssec_enabled) {
1460     DNSValidationResult r = CheckDNSSECChain(host_and_port_.host(),
1461                                              server_cert_nss_);
1462     if (r == DNSVR_SUCCESS) {
1463       local_server_cert_verify_result_.cert_status |= CERT_STATUS_IS_DNSSEC;
1464       server_cert_verify_result_ = &local_server_cert_verify_result_;
1465       GotoState(STATE_VERIFY_CERT_COMPLETE);
1466       return OK;
1467     }
1468   }
1469 
1470   if (dnssec_provider_ == NULL) {
1471     GotoState(STATE_VERIFY_CERT);
1472     return OK;
1473   }
1474 
1475   GotoState(STATE_VERIFY_DNSSEC_COMPLETE);
1476   RRResponse* response;
1477   dnssec_wait_start_time_ = base::Time::Now();
1478   return dnssec_provider_->GetDNSSECRecords(&response, &handshake_io_callback_);
1479 }
1480 
DoVerifyDNSSECComplete(int result)1481 int SSLClientSocketNSS::DoVerifyDNSSECComplete(int result) {
1482   RRResponse* response;
1483   int err = dnssec_provider_->GetDNSSECRecords(&response, NULL);
1484   DCHECK_EQ(err, OK);
1485 
1486   const base::TimeDelta elapsed = base::Time::Now() - dnssec_wait_start_time_;
1487   HISTOGRAM_TIMES("Net.DNSSECWaitTime", elapsed);
1488 
1489   GotoState(STATE_VERIFY_CERT);
1490   if (!response || response->rrdatas.empty())
1491     return OK;
1492 
1493   std::vector<base::StringPiece> records;
1494   records.resize(response->rrdatas.size());
1495   for (unsigned i = 0; i < response->rrdatas.size(); i++)
1496     records[i] = base::StringPiece(response->rrdatas[i]);
1497   DNSValidationResult r =
1498       VerifyTXTRecords(response->dnssec, server_cert_nss_, records);
1499 
1500   if (!ssl_config_.dnssec_enabled) {
1501     // If DNSSEC is not enabled we don't take any action based on the result,
1502     // except to record the latency, above.
1503     return OK;
1504   }
1505 
1506   switch (r) {
1507     case DNSVR_FAILURE:
1508       GotoState(STATE_VERIFY_CERT_COMPLETE);
1509       local_server_cert_verify_result_.cert_status |= CERT_STATUS_NOT_IN_DNS;
1510       server_cert_verify_result_ = &local_server_cert_verify_result_;
1511       return ERR_CERT_NOT_IN_DNS;
1512     case DNSVR_CONTINUE:
1513       GotoState(STATE_VERIFY_CERT);
1514       break;
1515     case DNSVR_SUCCESS:
1516       local_server_cert_verify_result_.cert_status |= CERT_STATUS_IS_DNSSEC;
1517       server_cert_verify_result_ = &local_server_cert_verify_result_;
1518       GotoState(STATE_VERIFY_CERT_COMPLETE);
1519       break;
1520     default:
1521       NOTREACHED();
1522       GotoState(STATE_VERIFY_CERT);
1523   }
1524 
1525   return OK;
1526 }
1527 
DoVerifyCert(int result)1528 int SSLClientSocketNSS::DoVerifyCert(int result) {
1529   DCHECK(server_cert_);
1530 
1531   GotoState(STATE_VERIFY_CERT_COMPLETE);
1532   start_cert_verification_time_ = base::TimeTicks::Now();
1533 
1534   if (ssl_host_info_.get() && !ssl_host_info_->state().certs.empty() &&
1535       predicted_cert_chain_correct_) {
1536     // If the SSLHostInfo had a prediction for the certificate chain of this
1537     // server then it will have optimistically started a verification of that
1538     // chain. So, if the prediction was correct, we should wait for that
1539     // verification to finish rather than start our own.
1540     net_log_.AddEvent(NetLog::TYPE_SSL_VERIFICATION_MERGED, NULL);
1541     UMA_HISTOGRAM_ENUMERATION("Net.SSLVerificationMerged", 1 /* true */, 2);
1542     base::TimeTicks end_time = ssl_host_info_->verification_end_time();
1543     if (end_time.is_null())
1544       end_time = base::TimeTicks::Now();
1545     UMA_HISTOGRAM_TIMES("Net.SSLVerificationMergedMsSaved",
1546                         end_time - ssl_host_info_->verification_start_time());
1547     server_cert_verify_result_ = &ssl_host_info_->cert_verify_result();
1548     return ssl_host_info_->WaitForCertVerification(&handshake_io_callback_);
1549   } else {
1550     UMA_HISTOGRAM_ENUMERATION("Net.SSLVerificationMerged", 0 /* false */, 2);
1551   }
1552 
1553   int flags = 0;
1554   if (ssl_config_.rev_checking_enabled)
1555     flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED;
1556   if (ssl_config_.verify_ev_cert)
1557     flags |= X509Certificate::VERIFY_EV_CERT;
1558   verifier_.reset(new SingleRequestCertVerifier(cert_verifier_));
1559   server_cert_verify_result_ = &local_server_cert_verify_result_;
1560   return verifier_->Verify(server_cert_, host_and_port_.host(), flags,
1561                            &local_server_cert_verify_result_,
1562                            &handshake_io_callback_);
1563 }
1564 
1565 // Derived from AuthCertificateCallback() in
1566 // mozilla/source/security/manager/ssl/src/nsNSSCallbacks.cpp.
DoVerifyCertComplete(int result)1567 int SSLClientSocketNSS::DoVerifyCertComplete(int result) {
1568   verifier_.reset();
1569 
1570   if (!start_cert_verification_time_.is_null()) {
1571     base::TimeDelta verify_time =
1572         base::TimeTicks::Now() - start_cert_verification_time_;
1573     if (result == OK)
1574         UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTime", verify_time);
1575     else
1576         UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTimeError", verify_time);
1577   }
1578 
1579   // We used to remember the intermediate CA certs in the NSS database
1580   // persistently.  However, NSS opens a connection to the SQLite database
1581   // during NSS initialization and doesn't close the connection until NSS
1582   // shuts down.  If the file system where the database resides is gone,
1583   // the database connection goes bad.  What's worse, the connection won't
1584   // recover when the file system comes back.  Until this NSS or SQLite bug
1585   // is fixed, we need to  avoid using the NSS database for non-essential
1586   // purposes.  See https://bugzilla.mozilla.org/show_bug.cgi?id=508081 and
1587   // http://crbug.com/15630 for more info.
1588 
1589   // If we have been explicitly told to accept this certificate, override the
1590   // result of verifier_.Verify.
1591   // Eventually, we should cache the cert verification results so that we don't
1592   // need to call verifier_.Verify repeatedly.  But for now we need to do this.
1593   // Alternatively, we could use the cert's status that we stored along with
1594   // the cert in the allowed_bad_certs vector.
1595   if (IsCertificateError(result) &&
1596       ssl_config_.IsAllowedBadCert(server_cert_)) {
1597     VLOG(1) << "accepting bad SSL certificate, as user told us to";
1598     result = OK;
1599   }
1600 
1601   if (result == OK)
1602     LogConnectionTypeMetrics();
1603 
1604   completed_handshake_ = true;
1605 
1606   if (user_read_callback_) {
1607     int rv = DoReadLoop(OK);
1608     if (rv != ERR_IO_PENDING)
1609       DoReadCallback(rv);
1610   }
1611 
1612   // Exit DoHandshakeLoop and return the result to the caller to Connect.
1613   DCHECK(next_handshake_state_ == STATE_NONE);
1614   return result;
1615 }
1616 
DoPayloadRead()1617 int SSLClientSocketNSS::DoPayloadRead() {
1618   EnterFunction(user_read_buf_len_);
1619   DCHECK(user_read_buf_);
1620   DCHECK_GT(user_read_buf_len_, 0);
1621   int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_);
1622   if (client_auth_cert_needed_) {
1623     // We don't need to invalidate the non-client-authenticated SSL session
1624     // because the server will renegotiate anyway.
1625     LeaveFunction("");
1626     rv = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
1627     net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR,
1628                       make_scoped_refptr(new SSLErrorParams(rv, 0)));
1629     return rv;
1630   }
1631   if (rv >= 0) {
1632     LogData(user_read_buf_->data(), rv);
1633     LeaveFunction("");
1634     return rv;
1635   }
1636   PRErrorCode prerr = PR_GetError();
1637   if (prerr == PR_WOULD_BLOCK_ERROR) {
1638     LeaveFunction("");
1639     return ERR_IO_PENDING;
1640   }
1641   LeaveFunction("");
1642   rv = HandleNSSError(prerr, false);
1643   net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR,
1644                     make_scoped_refptr(new SSLErrorParams(rv, prerr)));
1645   return rv;
1646 }
1647 
DoPayloadWrite()1648 int SSLClientSocketNSS::DoPayloadWrite() {
1649   EnterFunction(user_write_buf_len_);
1650   DCHECK(user_write_buf_);
1651   int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_);
1652   if (rv >= 0) {
1653     LogData(user_write_buf_->data(), rv);
1654     LeaveFunction("");
1655     return rv;
1656   }
1657   PRErrorCode prerr = PR_GetError();
1658   if (prerr == PR_WOULD_BLOCK_ERROR) {
1659     LeaveFunction("");
1660     return ERR_IO_PENDING;
1661   }
1662   LeaveFunction("");
1663   rv = HandleNSSError(prerr, false);
1664   net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR,
1665                     make_scoped_refptr(new SSLErrorParams(rv, prerr)));
1666   return rv;
1667 }
1668 
LogConnectionTypeMetrics() const1669 void SSLClientSocketNSS::LogConnectionTypeMetrics() const {
1670   UpdateConnectionTypeHistograms(CONNECTION_SSL);
1671   if (server_cert_verify_result_->has_md5)
1672     UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5);
1673   if (server_cert_verify_result_->has_md2)
1674     UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2);
1675   if (server_cert_verify_result_->has_md4)
1676     UpdateConnectionTypeHistograms(CONNECTION_SSL_MD4);
1677   if (server_cert_verify_result_->has_md5_ca)
1678     UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5_CA);
1679   if (server_cert_verify_result_->has_md2_ca)
1680     UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2_CA);
1681   int ssl_version = SSLConnectionStatusToVersion(ssl_connection_status_);
1682   switch (ssl_version) {
1683     case SSL_CONNECTION_VERSION_SSL2:
1684       UpdateConnectionTypeHistograms(CONNECTION_SSL_SSL2);
1685       break;
1686     case SSL_CONNECTION_VERSION_SSL3:
1687       UpdateConnectionTypeHistograms(CONNECTION_SSL_SSL3);
1688       break;
1689     case SSL_CONNECTION_VERSION_TLS1:
1690       UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1);
1691       break;
1692     case SSL_CONNECTION_VERSION_TLS1_1:
1693       UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_1);
1694       break;
1695     case SSL_CONNECTION_VERSION_TLS1_2:
1696       UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_2);
1697       break;
1698   };
1699 }
1700 
1701 // SaveSSLHostInfo saves the certificate chain of the connection so that we can
1702 // start verification faster in the future.
SaveSSLHostInfo()1703 void SSLClientSocketNSS::SaveSSLHostInfo() {
1704   if (!ssl_host_info_.get())
1705     return;
1706 
1707   // If the SSLHostInfo hasn't managed to load from disk yet then we can't save
1708   // anything.
1709   if (ssl_host_info_->WaitForDataReady(NULL) != OK)
1710     return;
1711 
1712   SSLHostInfo::State* state = ssl_host_info_->mutable_state();
1713 
1714   state->certs.clear();
1715   PeerCertificateChain certs(nss_fd_);
1716   for (unsigned i = 0; i < certs.size(); i++) {
1717     if (certs[i]->derCert.len > std::numeric_limits<uint16>::max())
1718       return;
1719 
1720     state->certs.push_back(std::string(
1721           reinterpret_cast<char*>(certs[i]->derCert.data),
1722           certs[i]->derCert.len));
1723   }
1724 
1725   ssl_host_info_->Persist();
1726 }
1727 
UncorkAfterTimeout()1728 void SSLClientSocketNSS::UncorkAfterTimeout() {
1729   corked_ = false;
1730   int nsent;
1731   do {
1732     nsent = BufferSend();
1733   } while (nsent > 0);
1734 }
1735 
1736 // Do network I/O between the given buffer and the given socket.
1737 // Return true if some I/O performed, false otherwise (error or ERR_IO_PENDING)
DoTransportIO()1738 bool SSLClientSocketNSS::DoTransportIO() {
1739   EnterFunction("");
1740   bool network_moved = false;
1741   if (nss_bufs_ != NULL) {
1742     int nsent = BufferSend();
1743     int nreceived = BufferRecv();
1744     network_moved = (nsent > 0 || nreceived >= 0);
1745   }
1746   LeaveFunction(network_moved);
1747   return network_moved;
1748 }
1749 
1750 // Return 0 for EOF,
1751 // > 0 for bytes transferred immediately,
1752 // < 0 for error (or the non-error ERR_IO_PENDING).
BufferSend(void)1753 int SSLClientSocketNSS::BufferSend(void) {
1754   if (transport_send_busy_)
1755     return ERR_IO_PENDING;
1756 
1757   EnterFunction("");
1758   const char* buf1;
1759   const char* buf2;
1760   unsigned int len1, len2;
1761   memio_GetWriteParams(nss_bufs_, &buf1, &len1, &buf2, &len2);
1762   const unsigned int len = len1 + len2;
1763 
1764   if (corked_ && len < kRecvBufferSize / 2)
1765     return 0;
1766 
1767   int rv = 0;
1768   if (len) {
1769     scoped_refptr<IOBuffer> send_buffer(new IOBuffer(len));
1770     memcpy(send_buffer->data(), buf1, len1);
1771     memcpy(send_buffer->data() + len1, buf2, len2);
1772     rv = transport_->socket()->Write(send_buffer, len,
1773                                      &buffer_send_callback_);
1774     if (rv == ERR_IO_PENDING) {
1775       transport_send_busy_ = true;
1776     } else {
1777       memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv));
1778     }
1779   }
1780 
1781   LeaveFunction(rv);
1782   return rv;
1783 }
1784 
BufferSendComplete(int result)1785 void SSLClientSocketNSS::BufferSendComplete(int result) {
1786   EnterFunction(result);
1787 
1788   // In the case of TCP FastOpen, connect is now finished.
1789   if (!peername_initialized_ && UsingTCPFastOpen())
1790     InitializeSSLPeerName();
1791 
1792   memio_PutWriteResult(nss_bufs_, MapErrorToNSS(result));
1793   transport_send_busy_ = false;
1794   OnSendComplete(result);
1795   LeaveFunction("");
1796 }
1797 
BufferRecv(void)1798 int SSLClientSocketNSS::BufferRecv(void) {
1799   if (transport_recv_busy_) return ERR_IO_PENDING;
1800 
1801   char *buf;
1802   int nb = memio_GetReadParams(nss_bufs_, &buf);
1803   EnterFunction(nb);
1804   int rv;
1805   if (!nb) {
1806     // buffer too full to read into, so no I/O possible at moment
1807     rv = ERR_IO_PENDING;
1808   } else {
1809     recv_buffer_ = new IOBuffer(nb);
1810     rv = transport_->socket()->Read(recv_buffer_, nb, &buffer_recv_callback_);
1811     if (rv == ERR_IO_PENDING) {
1812       transport_recv_busy_ = true;
1813     } else {
1814       if (rv > 0)
1815         memcpy(buf, recv_buffer_->data(), rv);
1816       memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv));
1817       recv_buffer_ = NULL;
1818     }
1819   }
1820   LeaveFunction(rv);
1821   return rv;
1822 }
1823 
BufferRecvComplete(int result)1824 void SSLClientSocketNSS::BufferRecvComplete(int result) {
1825   EnterFunction(result);
1826   if (result > 0) {
1827     char *buf;
1828     memio_GetReadParams(nss_bufs_, &buf);
1829     memcpy(buf, recv_buffer_->data(), result);
1830   }
1831   recv_buffer_ = NULL;
1832   memio_PutReadResult(nss_bufs_, MapErrorToNSS(result));
1833   transport_recv_busy_ = false;
1834   OnRecvComplete(result);
1835   LeaveFunction("");
1836 }
1837 
HandleNSSError(PRErrorCode nss_error,bool handshake_error)1838 int SSLClientSocketNSS::HandleNSSError(PRErrorCode nss_error,
1839                                        bool handshake_error) {
1840   int net_error = handshake_error ? MapNSSHandshakeError(nss_error) :
1841                                     MapNSSError(nss_error);
1842 
1843 #if defined(OS_WIN)
1844   // On Windows, a handle to the HCRYPTPROV is cached in the X509Certificate
1845   // os_cert_handle() as an optimization. However, if the certificate
1846   // private key is stored on a smart card, and the smart card is removed,
1847   // the cached HCRYPTPROV will not be able to obtain the HCRYPTKEY again,
1848   // preventing client certificate authentication. Because the
1849   // X509Certificate may outlive the individual SSLClientSocketNSS, due to
1850   // caching in X509Certificate, this failure ends up preventing client
1851   // certificate authentication with the same certificate for all future
1852   // attempts, even after the smart card has been re-inserted. By setting
1853   // the CERT_KEY_PROV_HANDLE_PROP_ID to NULL, the cached HCRYPTPROV will
1854   // typically be freed. This allows a new HCRYPTPROV to be obtained from
1855   // the certificate on the next attempt, which should succeed if the smart
1856   // card has been re-inserted, or will typically prompt the user to
1857   // re-insert the smart card if not.
1858   if ((net_error == ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY ||
1859        net_error == ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED) &&
1860       ssl_config_.send_client_cert && ssl_config_.client_cert) {
1861     CertSetCertificateContextProperty(
1862         ssl_config_.client_cert->os_cert_handle(),
1863         CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL);
1864   }
1865 #endif
1866 
1867   return net_error;
1868 }
1869 
1870 // static
1871 // NSS calls this if an incoming certificate needs to be verified.
1872 // Do nothing but return SECSuccess.
1873 // This is called only in full handshake mode.
1874 // Peer certificate is retrieved in HandshakeCallback() later, which is called
1875 // in full handshake mode or in resumption handshake mode.
OwnAuthCertHandler(void * arg,PRFileDesc * socket,PRBool checksig,PRBool is_server)1876 SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg,
1877                                                  PRFileDesc* socket,
1878                                                  PRBool checksig,
1879                                                  PRBool is_server) {
1880 #ifdef SSL_ENABLE_FALSE_START
1881   // In the event that we are False Starting this connection, we wish to send
1882   // out the Finished message and first application data record in the same
1883   // packet. This prevents non-determinism when talking to False Start
1884   // intolerant servers which, otherwise, might see the two messages in
1885   // different reads or not, depending on network conditions.
1886   PRBool false_start = 0;
1887   SECStatus rv = SSL_OptionGet(socket, SSL_ENABLE_FALSE_START, &false_start);
1888   DCHECK_EQ(SECSuccess, rv);
1889 
1890   if (false_start) {
1891     SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
1892 
1893     // ESET anti-virus is capable of intercepting HTTPS connections on Windows.
1894     // However, it is False Start intolerant and causes the connections to hang
1895     // forever. We detect ESET by the issuer of the leaf certificate and set a
1896     // flag to return a specific error, giving the user instructions for
1897     // reconfiguring ESET.
1898     CERTCertificate* cert = SSL_PeerCertificate(that->nss_fd_);
1899     if (cert) {
1900       char* common_name = CERT_GetCommonName(&cert->issuer);
1901       if (common_name) {
1902         if (strcmp(common_name, "ESET_RootSslCert") == 0)
1903           that->eset_mitm_detected_ = true;
1904         if (strcmp(common_name,
1905                    "ContentWatch Root Certificate Authority") == 0) {
1906           // This is NetNanny. NetNanny are updating their product so we
1907           // silently disable False Start for now.
1908           rv = SSL_OptionSet(socket, SSL_ENABLE_FALSE_START, PR_FALSE);
1909           DCHECK_EQ(SECSuccess, rv);
1910           false_start = 0;
1911         }
1912         PORT_Free(common_name);
1913       }
1914       CERT_DestroyCertificate(cert);
1915     }
1916 
1917     if (false_start && !that->handshake_callback_called_) {
1918       that->corked_ = true;
1919       that->uncork_timer_.Start(
1920           base::TimeDelta::FromMilliseconds(kCorkTimeoutMs),
1921           that, &SSLClientSocketNSS::UncorkAfterTimeout);
1922     }
1923   }
1924 #endif
1925 
1926   // Tell NSS to not verify the certificate.
1927   return SECSuccess;
1928 }
1929 
1930 #if defined(NSS_PLATFORM_CLIENT_AUTH)
1931 // static
1932 // NSS calls this if a client certificate is needed.
PlatformClientAuthHandler(void * arg,PRFileDesc * socket,CERTDistNames * ca_names,CERTCertList ** result_certs,void ** result_private_key)1933 SECStatus SSLClientSocketNSS::PlatformClientAuthHandler(
1934     void* arg,
1935     PRFileDesc* socket,
1936     CERTDistNames* ca_names,
1937     CERTCertList** result_certs,
1938     void** result_private_key) {
1939   SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
1940 
1941   that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert;
1942 #if defined(OS_WIN)
1943   if (that->ssl_config_.send_client_cert) {
1944     if (that->ssl_config_.client_cert) {
1945       PCCERT_CONTEXT cert_context =
1946           that->ssl_config_.client_cert->os_cert_handle();
1947       PCERT_KEY_CONTEXT key_context = reinterpret_cast<PCERT_KEY_CONTEXT>(
1948           PORT_ZAlloc(sizeof(CERT_KEY_CONTEXT)));
1949       if (!key_context)
1950         return SECFailure;
1951       key_context->cbSize = sizeof(*key_context);
1952 
1953       BOOL must_free = FALSE;
1954       BOOL acquired_key = CryptAcquireCertificatePrivateKey(
1955           cert_context, CRYPT_ACQUIRE_CACHE_FLAG, NULL,
1956           &key_context->hCryptProv, &key_context->dwKeySpec, &must_free);
1957       if (acquired_key && key_context->hCryptProv) {
1958         DCHECK_NE(key_context->dwKeySpec, CERT_NCRYPT_KEY_SPEC);
1959 
1960         // The certificate cache may have been updated/used, in which case,
1961         // duplicate the existing handle, since NSS will free it when no
1962         // longer in use.
1963         if (!must_free)
1964           CryptContextAddRef(key_context->hCryptProv, NULL, 0);
1965 
1966         SECItem der_cert;
1967         der_cert.type = siDERCertBuffer;
1968         der_cert.data = cert_context->pbCertEncoded;
1969         der_cert.len  = cert_context->cbCertEncoded;
1970 
1971         // TODO(rsleevi): Error checking for NSS allocation errors.
1972         *result_certs = CERT_NewCertList();
1973         CERTCertDBHandle* db_handle = CERT_GetDefaultCertDB();
1974         CERTCertificate* user_cert = CERT_NewTempCertificate(
1975             db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE);
1976         CERT_AddCertToListTail(*result_certs, user_cert);
1977 
1978         // Add the intermediates.
1979         X509Certificate::OSCertHandles intermediates =
1980             that->ssl_config_.client_cert->GetIntermediateCertificates();
1981         for (X509Certificate::OSCertHandles::const_iterator it =
1982             intermediates.begin(); it != intermediates.end(); ++it) {
1983           der_cert.data = (*it)->pbCertEncoded;
1984           der_cert.len = (*it)->cbCertEncoded;
1985 
1986           CERTCertificate* intermediate = CERT_NewTempCertificate(
1987               db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE);
1988           CERT_AddCertToListTail(*result_certs, intermediate);
1989         }
1990         *result_private_key = key_context;
1991         return SECSuccess;
1992       }
1993       PORT_Free(key_context);
1994       LOG(WARNING) << "Client cert found without private key";
1995     }
1996     // Send no client certificate.
1997     return SECFailure;
1998   }
1999 
2000   that->client_certs_.clear();
2001 
2002   std::vector<CERT_NAME_BLOB> issuer_list(ca_names->nnames);
2003   for (int i = 0; i < ca_names->nnames; ++i) {
2004     issuer_list[i].cbData = ca_names->names[i].len;
2005     issuer_list[i].pbData = ca_names->names[i].data;
2006   }
2007 
2008   // Client certificates of the user are in the "MY" system certificate store.
2009   HCERTSTORE my_cert_store = CertOpenSystemStore(NULL, L"MY");
2010   if (!my_cert_store) {
2011     LOG(ERROR) << "Could not open the \"MY\" system certificate store: "
2012                << GetLastError();
2013     return SECFailure;
2014   }
2015 
2016   // Enumerate the client certificates.
2017   CERT_CHAIN_FIND_BY_ISSUER_PARA find_by_issuer_para;
2018   memset(&find_by_issuer_para, 0, sizeof(find_by_issuer_para));
2019   find_by_issuer_para.cbSize = sizeof(find_by_issuer_para);
2020   find_by_issuer_para.pszUsageIdentifier = szOID_PKIX_KP_CLIENT_AUTH;
2021   find_by_issuer_para.cIssuer = ca_names->nnames;
2022   find_by_issuer_para.rgIssuer = ca_names->nnames ? &issuer_list[0] : NULL;
2023   find_by_issuer_para.pfnFindCallback = ClientCertFindCallback;
2024 
2025   PCCERT_CHAIN_CONTEXT chain_context = NULL;
2026 
2027   for (;;) {
2028     // Find a certificate chain.
2029     chain_context = CertFindChainInStore(my_cert_store,
2030                                          X509_ASN_ENCODING,
2031                                          0,
2032                                          CERT_CHAIN_FIND_BY_ISSUER,
2033                                          &find_by_issuer_para,
2034                                          chain_context);
2035     if (!chain_context) {
2036       DWORD err = GetLastError();
2037       if (err != CRYPT_E_NOT_FOUND)
2038         DLOG(ERROR) << "CertFindChainInStore failed: " << err;
2039       break;
2040     }
2041 
2042     // Get the leaf certificate.
2043     PCCERT_CONTEXT cert_context =
2044         chain_context->rgpChain[0]->rgpElement[0]->pCertContext;
2045     // Copy it to our own certificate store, so that we can close the "MY"
2046     // certificate store before returning from this function.
2047     PCCERT_CONTEXT cert_context2;
2048     BOOL ok = CertAddCertificateContextToStore(X509Certificate::cert_store(),
2049                                                cert_context,
2050                                                CERT_STORE_ADD_USE_EXISTING,
2051                                                &cert_context2);
2052     if (!ok) {
2053       NOTREACHED();
2054       continue;
2055     }
2056 
2057     // Copy the rest of the chain to our own store as well. Copying the chain
2058     // stops gracefully if an error is encountered, with the partial chain
2059     // being used as the intermediates, rather than failing to consider the
2060     // client certificate.
2061     net::X509Certificate::OSCertHandles intermediates;
2062     for (DWORD i = 1; i < chain_context->rgpChain[0]->cElement; i++) {
2063       PCCERT_CONTEXT intermediate_copy;
2064       ok = CertAddCertificateContextToStore(X509Certificate::cert_store(),
2065           chain_context->rgpChain[0]->rgpElement[i]->pCertContext,
2066           CERT_STORE_ADD_USE_EXISTING, &intermediate_copy);
2067       if (!ok) {
2068         NOTREACHED();
2069         break;
2070       }
2071       intermediates.push_back(intermediate_copy);
2072     }
2073 
2074     scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
2075         cert_context2, X509Certificate::SOURCE_LONE_CERT_IMPORT,
2076         intermediates);
2077     that->client_certs_.push_back(cert);
2078 
2079     X509Certificate::FreeOSCertHandle(cert_context2);
2080     for (net::X509Certificate::OSCertHandles::iterator it =
2081         intermediates.begin(); it != intermediates.end(); ++it) {
2082       net::X509Certificate::FreeOSCertHandle(*it);
2083     }
2084   }
2085 
2086   BOOL ok = CertCloseStore(my_cert_store, CERT_CLOSE_STORE_CHECK_FLAG);
2087   DCHECK(ok);
2088 
2089   // Tell NSS to suspend the client authentication.  We will then abort the
2090   // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
2091   return SECWouldBlock;
2092 #elif defined(OS_MACOSX)
2093   if (that->ssl_config_.send_client_cert) {
2094     if (that->ssl_config_.client_cert) {
2095       OSStatus os_error = noErr;
2096       SecIdentityRef identity = NULL;
2097       SecKeyRef private_key = NULL;
2098       CFArrayRef chain =
2099           that->ssl_config_.client_cert->CreateClientCertificateChain();
2100       if (chain) {
2101         identity = reinterpret_cast<SecIdentityRef>(
2102             const_cast<void*>(CFArrayGetValueAtIndex(chain, 0)));
2103       }
2104       if (identity)
2105         os_error = SecIdentityCopyPrivateKey(identity, &private_key);
2106 
2107       if (chain && identity && os_error == noErr) {
2108         // TODO(rsleevi): Error checking for NSS allocation errors.
2109         *result_certs = CERT_NewCertList();
2110         *result_private_key = private_key;
2111 
2112         for (CFIndex i = 0; i < CFArrayGetCount(chain); ++i) {
2113           CSSM_DATA cert_data;
2114           SecCertificateRef cert_ref;
2115           if (i == 0) {
2116             cert_ref = that->ssl_config_.client_cert->os_cert_handle();
2117           } else {
2118             cert_ref = reinterpret_cast<SecCertificateRef>(
2119                 const_cast<void*>(CFArrayGetValueAtIndex(chain, i)));
2120           }
2121           os_error = SecCertificateGetData(cert_ref, &cert_data);
2122           if (os_error != noErr)
2123             break;
2124 
2125           SECItem der_cert;
2126           der_cert.type = siDERCertBuffer;
2127           der_cert.data = cert_data.Data;
2128           der_cert.len = cert_data.Length;
2129           CERTCertificate* nss_cert = CERT_NewTempCertificate(
2130               CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE);
2131           CERT_AddCertToListTail(*result_certs, nss_cert);
2132         }
2133       }
2134       if (os_error == noErr) {
2135         CFRelease(chain);
2136         return SECSuccess;
2137       }
2138       LOG(WARNING) << "Client cert found, but could not be used: "
2139                    << os_error;
2140       if (*result_certs) {
2141         CERT_DestroyCertList(*result_certs);
2142         *result_certs = NULL;
2143       }
2144       if (*result_private_key)
2145         *result_private_key = NULL;
2146       if (private_key)
2147         CFRelease(private_key);
2148       if (chain)
2149         CFRelease(chain);
2150     }
2151     // Send no client certificate.
2152     return SECFailure;
2153   }
2154 
2155   that->client_certs_.clear();
2156 
2157   // First, get the cert issuer names allowed by the server.
2158   std::vector<CertPrincipal> valid_issuers;
2159   int n = ca_names->nnames;
2160   for (int i = 0; i < n; i++) {
2161     // Parse each name into a CertPrincipal object.
2162     CertPrincipal p;
2163     if (p.ParseDistinguishedName(ca_names->names[i].data,
2164                                  ca_names->names[i].len)) {
2165       valid_issuers.push_back(p);
2166     }
2167   }
2168 
2169   // Now get the available client certs whose issuers are allowed by the server.
2170   X509Certificate::GetSSLClientCertificates(that->host_and_port_.host(),
2171                                             valid_issuers,
2172                                             &that->client_certs_);
2173 
2174   // Tell NSS to suspend the client authentication.  We will then abort the
2175   // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
2176   return SECWouldBlock;
2177 #else
2178   return SECFailure;
2179 #endif
2180 }
2181 
2182 #else  // NSS_PLATFORM_CLIENT_AUTH
2183 
2184 // static
2185 // NSS calls this if a client certificate is needed.
2186 // Based on Mozilla's NSS_GetClientAuthData.
ClientAuthHandler(void * arg,PRFileDesc * socket,CERTDistNames * ca_names,CERTCertificate ** result_certificate,SECKEYPrivateKey ** result_private_key)2187 SECStatus SSLClientSocketNSS::ClientAuthHandler(
2188     void* arg,
2189     PRFileDesc* socket,
2190     CERTDistNames* ca_names,
2191     CERTCertificate** result_certificate,
2192     SECKEYPrivateKey** result_private_key) {
2193   SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
2194 
2195   that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert;
2196   void* wincx  = SSL_RevealPinArg(socket);
2197 
2198   // Second pass: a client certificate should have been selected.
2199   if (that->ssl_config_.send_client_cert) {
2200     if (that->ssl_config_.client_cert) {
2201       CERTCertificate* cert = CERT_DupCertificate(
2202           that->ssl_config_.client_cert->os_cert_handle());
2203       SECKEYPrivateKey* privkey = PK11_FindKeyByAnyCert(cert, wincx);
2204       if (privkey) {
2205         // TODO(jsorianopastor): We should wait for server certificate
2206         // verification before sending our credentials.  See
2207         // http://crbug.com/13934.
2208         *result_certificate = cert;
2209         *result_private_key = privkey;
2210         return SECSuccess;
2211       }
2212       LOG(WARNING) << "Client cert found without private key";
2213     }
2214     // Send no client certificate.
2215     return SECFailure;
2216   }
2217 
2218   // Iterate over all client certificates.
2219   CERTCertList* client_certs = CERT_FindUserCertsByUsage(
2220       CERT_GetDefaultCertDB(), certUsageSSLClient,
2221       PR_FALSE, PR_FALSE, wincx);
2222   if (client_certs) {
2223     for (CERTCertListNode* node = CERT_LIST_HEAD(client_certs);
2224          !CERT_LIST_END(node, client_certs);
2225          node = CERT_LIST_NEXT(node)) {
2226       // Only offer unexpired certificates.
2227       if (CERT_CheckCertValidTimes(node->cert, PR_Now(), PR_TRUE) !=
2228           secCertTimeValid)
2229         continue;
2230       // Filter by issuer.
2231       //
2232       // TODO(davidben): This does a binary comparison of the DER-encoded
2233       // issuers. We should match according to RFC 5280 sec. 7.1. We should find
2234       // an appropriate NSS function or add one if needbe.
2235       if (ca_names->nnames &&
2236           NSS_CmpCertChainWCANames(node->cert, ca_names) != SECSuccess)
2237         continue;
2238       X509Certificate* x509_cert = X509Certificate::CreateFromHandle(
2239           node->cert, X509Certificate::SOURCE_LONE_CERT_IMPORT,
2240           net::X509Certificate::OSCertHandles());
2241       that->client_certs_.push_back(x509_cert);
2242     }
2243     CERT_DestroyCertList(client_certs);
2244   }
2245 
2246   // Tell NSS to suspend the client authentication.  We will then abort the
2247   // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
2248   return SECWouldBlock;
2249 }
2250 #endif  // NSS_PLATFORM_CLIENT_AUTH
2251 
2252 // static
2253 // NSS calls this when handshake is completed.
2254 // After the SSL handshake is finished, use CertVerifier to verify
2255 // the saved server certificate.
HandshakeCallback(PRFileDesc * socket,void * arg)2256 void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket,
2257                                            void* arg) {
2258   SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
2259 
2260   that->handshake_callback_called_ = true;
2261 
2262   that->UpdateServerCert();
2263   that->UpdateConnectionStatus();
2264 }
2265 
EnsureThreadIdAssigned() const2266 void SSLClientSocketNSS::EnsureThreadIdAssigned() const {
2267   base::AutoLock auto_lock(lock_);
2268   if (valid_thread_id_ != base::kInvalidThreadId)
2269     return;
2270   valid_thread_id_ = base::PlatformThread::CurrentId();
2271 }
2272 
CalledOnValidThread() const2273 bool SSLClientSocketNSS::CalledOnValidThread() const {
2274   EnsureThreadIdAssigned();
2275   base::AutoLock auto_lock(lock_);
2276   return valid_thread_id_ == base::PlatformThread::CurrentId();
2277 }
2278 
2279 }  // namespace net
2280