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