blob: ee80ca528919b40df32a40c227bdfd9384d15097 [file] [log] [blame]
[email protected]a2006ece2010-04-23 16:44:021// Copyright (c) 2010 The Chromium Authors. All rights reserved.
[email protected]b43c97c2008-10-22 19:50:582// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]e83ba1c42009-11-30 18:18:325// This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived
6// from AuthCertificateCallback() in
[email protected]bf0136d2009-05-29 05:55:047// mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp.
8
9/* ***** BEGIN LICENSE BLOCK *****
10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
11 *
12 * The contents of this file are subject to the Mozilla Public License Version
13 * 1.1 (the "License"); you may not use this file except in compliance with
14 * the License. You may obtain a copy of the License at
15 * http://www.mozilla.org/MPL/
16 *
17 * Software distributed under the License is distributed on an "AS IS" basis,
18 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
19 * for the specific language governing rights and limitations under the
20 * License.
21 *
22 * The Original Code is the Netscape security libraries.
23 *
24 * The Initial Developer of the Original Code is
25 * Netscape Communications Corporation.
26 * Portions created by the Initial Developer are Copyright (C) 2000
27 * the Initial Developer. All Rights Reserved.
28 *
29 * Contributor(s):
30 * Ian McGreer <[email protected]>
31 * Javier Delgadillo <[email protected]>
32 * Kai Engert <[email protected]>
33 *
34 * Alternatively, the contents of this file may be used under the terms of
35 * either the GNU General Public License Version 2 or later (the "GPL"), or
36 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
37 * in which case the provisions of the GPL or the LGPL are applicable instead
38 * of those above. If you wish to allow use of your version of this file only
39 * under the terms of either the GPL or the LGPL, and not to allow others to
40 * use your version of this file under the terms of the MPL, indicate your
41 * decision by deleting the provisions above and replace them with the notice
42 * and other provisions required by the GPL or the LGPL. If you do not delete
43 * the provisions above, a recipient may use your version of this file under
44 * the terms of any one of the MPL, the GPL or the LGPL.
45 *
46 * ***** END LICENSE BLOCK ***** */
47
[email protected]f7984fc62009-06-22 23:26:4448#include "net/socket/ssl_client_socket_nss.h"
[email protected]b43c97c2008-10-22 19:50:5849
[email protected]bf0136d2009-05-29 05:55:0450#include <certdb.h>
[email protected]b24713592010-08-11 19:50:0251#include <hasht.h>
[email protected]d84b3722009-10-15 21:23:3752#include <keyhi.h>
[email protected]b43c97c2008-10-22 19:50:5853#include <nspr.h>
54#include <nss.h>
[email protected]d8eb84242010-09-25 02:25:0655#include <pk11pub.h>
[email protected]ea224582008-12-07 20:25:4656#include <secerr.h>
[email protected]b24713592010-08-11 19:50:0257#include <sechash.h>
[email protected]b43c97c2008-10-22 19:50:5858#include <ssl.h>
[email protected]ea224582008-12-07 20:25:4659#include <sslerr.h>
[email protected]757f2e2b2010-10-27 23:28:3560#include <sslproto.h>
[email protected]b43c97c2008-10-22 19:50:5861
[email protected]7a8de3072010-10-01 16:25:5462#include <limits>
63
[email protected]bacff652009-03-31 17:50:3364#include "base/compiler_specific.h"
[email protected]835d7c82010-10-14 04:38:3865#include "base/metrics/histogram.h"
[email protected]b43c97c2008-10-22 19:50:5866#include "base/logging.h"
[email protected]1b1a264a2010-01-14 22:36:3567#include "base/nss_util.h"
[email protected]899c3e92010-08-28 15:53:5068#include "base/string_number_conversions.h"
[email protected]b43c97c2008-10-22 19:50:5869#include "base/string_util.h"
[email protected]d8eb84242010-09-25 02:25:0670#include "base/stringprintf.h"
[email protected]34b99632011-01-01 01:01:0671#include "base/threading/thread_restrictions.h"
[email protected]7cbc6df12010-10-04 16:25:3972#include "base/values.h"
[email protected]ac9eec62010-02-20 18:50:3873#include "net/base/address_list.h"
[email protected]43025b7a2010-09-16 19:24:4574#include "net/base/cert_status_flags.h"
[email protected]92d9cad2009-06-25 23:40:2475#include "net/base/cert_verifier.h"
[email protected]757f2e2b2010-10-27 23:28:3576#include "net/base/connection_type_histograms.h"
[email protected]d8eb84242010-09-25 02:25:0677#include "net/base/dns_util.h"
[email protected]899c3e92010-08-28 15:53:5078#include "net/base/dnsrr_resolver.h"
[email protected]b24713592010-08-11 19:50:0279#include "net/base/dnssec_chain_verifier.h"
[email protected]597cf6e2009-05-29 09:43:2680#include "net/base/io_buffer.h"
[email protected]b43c97c2008-10-22 19:50:5881#include "net/base/net_errors.h"
[email protected]899c3e92010-08-28 15:53:5082#include "net/base/net_log.h"
[email protected]d84b3722009-10-15 21:23:3783#include "net/base/ssl_cert_request_info.h"
[email protected]fc7de492010-07-12 14:49:0484#include "net/base/ssl_connection_status_flags.h"
[email protected]b43c97c2008-10-22 19:50:5885#include "net/base/ssl_info.h"
[email protected]ac9eec62010-02-20 18:50:3886#include "net/base/sys_addrinfo.h"
[email protected]2a0c0a52009-07-31 07:51:3287#include "net/ocsp/nss_ocsp.h"
[email protected]e60e47a2010-07-14 03:37:1888#include "net/socket/client_socket_handle.h"
[email protected]345c613b2010-11-22 19:33:1889#include "net/socket/dns_cert_provenance_checker.h"
[email protected]f61c3972010-12-23 09:54:1590#include "net/socket/nss_ssl_util.h"
[email protected]47f7d742010-11-11 04:12:5391#include "net/socket/ssl_error_params.h"
[email protected]d0672be2010-10-20 16:30:1992#include "net/socket/ssl_host_info.h"
[email protected]b43c97c2008-10-22 19:50:5893
[email protected]11f40342010-11-22 13:35:4994#if defined(USE_SYSTEM_SSL)
95#include <dlfcn.h>
96#endif
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#endif
105
[email protected]b43c97c2008-10-22 19:50:58106static const int kRecvBufferSize = 4096;
107
[email protected]fa788512010-10-08 14:48:06108// kCorkTimeoutMs is the number of milliseconds for which we'll wait for a
109// Write to an SSL socket which we're False Starting. Since corking stops the
110// Finished message from being sent, the server sees an incomplete handshake
111// and some will time out such sockets quite aggressively.
112static const int kCorkTimeoutMs = 200;
113
[email protected]b43c97c2008-10-22 19:50:58114namespace net {
115
[email protected]e17b4c12008-11-05 22:04:08116// State machines are easier to debug if you log state transitions.
117// Enable these if you want to see what's going on.
118#if 1
119#define EnterFunction(x)
120#define LeaveFunction(x)
[email protected]a3ff5e92009-10-13 04:48:06121#define GotoState(s) next_handshake_state_ = s
[email protected]ea224582008-12-07 20:25:46122#define LogData(s, len)
[email protected]e17b4c12008-11-05 22:04:08123#else
[email protected]b30a3f52010-10-16 01:05:46124#define EnterFunction(x)\
125 VLOG(1) << (void *)this << " " << __FUNCTION__ << " enter " << x\
126 << "; next_handshake_state " << next_handshake_state_
127#define LeaveFunction(x)\
128 VLOG(1) << (void *)this << " " << __FUNCTION__ << " leave " << x\
129 << "; next_handshake_state " << next_handshake_state_
130#define GotoState(s)\
131 do {\
132 VLOG(1) << (void *)this << " " << __FUNCTION__ << " jump to state " << s;\
133 next_handshake_state_ = s;\
134 } while (0)
135#define LogData(s, len)\
136 VLOG(1) << (void *)this << " " << __FUNCTION__\
137 << " data [" << std::string(s, len) << "]"
[email protected]e17b4c12008-11-05 22:04:08138#endif
139
[email protected]ea224582008-12-07 20:25:46140namespace {
141
[email protected]37a0b112010-05-08 02:23:46142#if defined(OS_WIN)
143
[email protected]01640f62010-08-10 19:42:12144// This callback is intended to be used with CertFindChainInStore. In addition
145// to filtering by extended/enhanced key usage, we do not show expired
146// certificates and require digital signature usage in the key usage
147// extension.
148//
149// This matches our behavior on Mac OS X and that of NSS. It also matches the
150// default behavior of IE8. See http://support.microsoft.com/kb/890326 and
151// 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
152BOOL WINAPI ClientCertFindCallback(PCCERT_CONTEXT cert_context,
153 void* find_arg) {
[email protected]b30a3f52010-10-16 01:05:46154 VLOG(1) << "Calling ClientCertFindCallback from _nss";
[email protected]01640f62010-08-10 19:42:12155 // Verify the certificate's KU is good.
156 BYTE key_usage;
157 if (CertGetIntendedKeyUsage(X509_ASN_ENCODING, cert_context->pCertInfo,
158 &key_usage, 1)) {
159 if (!(key_usage & CERT_DIGITAL_SIGNATURE_KEY_USAGE))
160 return FALSE;
161 } else {
162 DWORD err = GetLastError();
163 // If |err| is non-zero, it's an actual error. Otherwise the extension
164 // just isn't present, and we treat it as if everything was allowed.
165 if (err) {
166 DLOG(ERROR) << "CertGetIntendedKeyUsage failed: " << err;
167 return FALSE;
168 }
169 }
170
171 // Verify the current time is within the certificate's validity period.
172 if (CertVerifyTimeValidity(NULL, cert_context->pCertInfo) != 0)
173 return FALSE;
174
175 return TRUE;
176}
177
[email protected]37a0b112010-05-08 02:23:46178#endif
179
[email protected]17570702010-10-28 15:16:09180// PeerCertificateChain is a helper object which extracts the certificate
181// chain, as given by the server, from an NSS socket and performs the needed
182// resource management. The first element of the chain is the leaf certificate
183// and the other elements are in the order given by the server.
184class PeerCertificateChain {
185 public:
[email protected]b92a96e2010-11-02 21:03:05186 explicit PeerCertificateChain(PRFileDesc* nss_fd)
[email protected]17570702010-10-28 15:16:09187 : num_certs_(0),
188 certs_(NULL) {
189 SECStatus rv = SSL_PeerCertificateChain(nss_fd, NULL, &num_certs_);
190 DCHECK_EQ(rv, SECSuccess);
191
192 certs_ = new CERTCertificate*[num_certs_];
193 const unsigned expected_num_certs = num_certs_;
194 rv = SSL_PeerCertificateChain(nss_fd, certs_, &num_certs_);
195 DCHECK_EQ(rv, SECSuccess);
196 DCHECK_EQ(num_certs_, expected_num_certs);
197 }
198
199 ~PeerCertificateChain() {
200 for (unsigned i = 0; i < num_certs_; i++)
201 CERT_DestroyCertificate(certs_[i]);
202 delete[] certs_;
203 }
204
205 unsigned size() const { return num_certs_; }
206
207 CERTCertificate* operator[](unsigned i) {
208 DCHECK_LT(i, num_certs_);
209 return certs_[i];
210 }
211
[email protected]d8fbf582010-11-04 21:51:12212 std::vector<base::StringPiece> AsStringPieceVector() const {
213 std::vector<base::StringPiece> v(size());
214 for (unsigned i = 0; i < size(); i++) {
215 v[i] = base::StringPiece(
216 reinterpret_cast<const char*>(certs_[i]->derCert.data),
217 certs_[i]->derCert.len);
218 }
219
220 return v;
221 }
222
[email protected]17570702010-10-28 15:16:09223 private:
224 unsigned num_certs_;
225 CERTCertificate** certs_;
226};
227
[email protected]ea224582008-12-07 20:25:46228} // namespace
229
[email protected]e60e47a2010-07-14 03:37:18230SSLClientSocketNSS::SSLClientSocketNSS(ClientSocketHandle* transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27231 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21232 const SSLConfig& ssl_config,
[email protected]d8fbf582010-11-04 21:51:12233 SSLHostInfo* ssl_host_info,
[email protected]822581d2010-12-16 17:27:15234 CertVerifier* cert_verifier,
[email protected]345c613b2010-11-22 19:33:18235 DnsCertProvenanceChecker* dns_ctx)
[email protected]f505a9b2010-01-28 19:44:02236 : ALLOW_THIS_IN_INITIALIZER_LIST(buffer_send_callback_(
237 this, &SSLClientSocketNSS::BufferSendComplete)),
238 ALLOW_THIS_IN_INITIALIZER_LIST(buffer_recv_callback_(
239 this, &SSLClientSocketNSS::BufferRecvComplete)),
[email protected]b43c97c2008-10-22 19:50:58240 transport_send_busy_(false),
241 transport_recv_busy_(false),
[email protected]9ae2ee02010-09-08 16:41:14242 corked_(false),
[email protected]f505a9b2010-01-28 19:44:02243 ALLOW_THIS_IN_INITIALIZER_LIST(handshake_io_callback_(
244 this, &SSLClientSocketNSS::OnHandshakeIOComplete)),
[email protected]b43c97c2008-10-22 19:50:58245 transport_(transport_socket),
[email protected]4f4de7e62010-11-12 19:55:27246 host_and_port_(host_and_port),
[email protected]b43c97c2008-10-22 19:50:58247 ssl_config_(ssl_config),
[email protected]a6eb576292009-06-30 16:19:00248 user_connect_callback_(NULL),
[email protected]a3ff5e92009-10-13 04:48:06249 user_read_callback_(NULL),
250 user_write_callback_(NULL),
251 user_read_buf_len_(0),
252 user_write_buf_len_(0),
[email protected]f505a9b2010-01-28 19:44:02253 server_cert_nss_(NULL),
[email protected]3b1d3db2010-10-28 16:39:40254 server_cert_verify_result_(NULL),
[email protected]757f2e2b2010-10-27 23:28:35255 ssl_connection_status_(0),
[email protected]d84b3722009-10-15 21:23:37256 client_auth_cert_needed_(false),
[email protected]822581d2010-12-16 17:27:15257 cert_verifier_(cert_verifier),
[email protected]39afe642010-04-29 14:55:18258 handshake_callback_called_(false),
[email protected]b43c97c2008-10-22 19:50:58259 completed_handshake_(false),
[email protected]7a8de3072010-10-01 16:25:54260 pseudo_connected_(false),
[email protected]563cbcc62010-10-11 23:07:52261 eset_mitm_detected_(false),
[email protected]3b1d3db2010-10-28 16:39:40262 predicted_cert_chain_correct_(false),
[email protected]7f7e92392010-10-26 18:29:29263 peername_initialized_(false),
[email protected]899c3e92010-08-28 15:53:50264 dnssec_provider_(NULL),
[email protected]a3ff5e92009-10-13 04:48:06265 next_handshake_state_(STATE_NONE),
[email protected]b43c97c2008-10-22 19:50:58266 nss_fd_(NULL),
[email protected]a2006ece2010-04-23 16:44:02267 nss_bufs_(NULL),
[email protected]7a8de3072010-10-01 16:25:54268 net_log_(transport_socket->socket()->NetLog()),
269 predicted_npn_status_(kNextProtoUnsupported),
[email protected]7ab5bbd12010-10-19 13:33:21270 predicted_npn_proto_used_(false),
[email protected]d8fbf582010-11-04 21:51:12271 ssl_host_info_(ssl_host_info),
[email protected]345c613b2010-11-22 19:33:18272 dns_cert_checker_(dns_ctx) {
[email protected]e17b4c12008-11-05 22:04:08273 EnterFunction("");
[email protected]b43c97c2008-10-22 19:50:58274}
275
276SSLClientSocketNSS::~SSLClientSocketNSS() {
[email protected]e17b4c12008-11-05 22:04:08277 EnterFunction("");
[email protected]b43c97c2008-10-22 19:50:58278 Disconnect();
[email protected]e17b4c12008-11-05 22:04:08279 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:58280}
281
282int SSLClientSocketNSS::Init() {
[email protected]e17b4c12008-11-05 22:04:08283 EnterFunction("");
[email protected]829296f2010-01-27 02:58:03284 // Initialize the NSS SSL library in a threadsafe way. This also
285 // initializes the NSS base library.
286 EnsureNSSSSLInit();
[email protected]dbc13b52010-04-16 00:59:56287 if (!NSS_IsInitialized())
288 return ERR_UNEXPECTED;
[email protected]3dd6f5e2010-06-01 20:28:03289#if !defined(OS_MACOSX) && !defined(OS_WIN)
[email protected]2a0c0a52009-07-31 07:51:32290 // We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop
291 // by MessageLoopForIO::current().
292 // X509Certificate::Verify() runs on a worker thread of CertVerifier.
293 EnsureOCSPInit();
[email protected]f505a9b2010-01-28 19:44:02294#endif
[email protected]b43c97c2008-10-22 19:50:58295
[email protected]e17b4c12008-11-05 22:04:08296 LeaveFunction("");
297 return OK;
[email protected]b43c97c2008-10-22 19:50:58298}
299
[email protected]d0672be2010-10-20 16:30:19300// SaveSnapStartInfo extracts the information needed to perform a Snap Start
301// with this server in the future (if any) and tells |ssl_host_info_| to
302// preserve it.
[email protected]7a8de3072010-10-01 16:25:54303void SSLClientSocketNSS::SaveSnapStartInfo() {
[email protected]7ab5bbd12010-10-19 13:33:21304 if (!ssl_host_info_.get())
[email protected]7a8de3072010-10-01 16:25:54305 return;
306
[email protected]fd348122010-12-16 22:17:35307 // If the SSLHostInfo hasn't managed to load from disk yet then we can't save
308 // anything.
309 if (ssl_host_info_->WaitForDataReady(NULL) != OK)
310 return;
311
[email protected]7a8de3072010-10-01 16:25:54312 SECStatus rv;
313 SSLSnapStartResult snap_start_type;
314 rv = SSL_GetSnapStartResult(nss_fd_, &snap_start_type);
315 if (rv != SECSuccess) {
316 NOTREACHED();
317 return;
318 }
[email protected]09125792010-11-03 23:23:22319 net_log_.AddEvent(NetLog::TYPE_SSL_SNAP_START,
320 new NetLogIntegerParameter("type", snap_start_type));
[email protected]7a8de3072010-10-01 16:25:54321 if (snap_start_type == SSL_SNAP_START_FULL ||
322 snap_start_type == SSL_SNAP_START_RESUME) {
323 // If we did a successful Snap Start then our information was correct and
324 // there's no point saving it again.
325 return;
326 }
327
328 const unsigned char* hello_data;
329 unsigned hello_data_len;
330 rv = SSL_GetPredictedServerHelloData(nss_fd_, &hello_data, &hello_data_len);
331 if (rv != SECSuccess) {
332 NOTREACHED();
333 return;
334 }
[email protected]7a8de3072010-10-01 16:25:54335 if (hello_data_len > std::numeric_limits<uint16>::max())
336 return;
[email protected]d0672be2010-10-20 16:30:19337 SSLHostInfo::State* state = ssl_host_info_->mutable_state();
338 state->server_hello =
339 std::string(reinterpret_cast<const char *>(hello_data), hello_data_len);
[email protected]7a8de3072010-10-01 16:25:54340
[email protected]98f397e2010-10-26 13:56:57341 if (hello_data_len > 0) {
342 state->npn_valid = true;
343 state->npn_status = GetNextProto(&state->npn_protocol);
344 } else {
345 state->npn_valid = false;
346 }
[email protected]7a8de3072010-10-01 16:25:54347
[email protected]98f397e2010-10-26 13:56:57348 state->certs.clear();
[email protected]17570702010-10-28 15:16:09349 PeerCertificateChain certs(nss_fd_);
350 for (unsigned i = 0; i < certs.size(); i++) {
351 if (certs[i]->derCert.len > std::numeric_limits<uint16>::max())
[email protected]7a8de3072010-10-01 16:25:54352 return;
[email protected]98f397e2010-10-26 13:56:57353
[email protected]d0672be2010-10-20 16:30:19354 state->certs.push_back(std::string(
[email protected]17570702010-10-28 15:16:09355 reinterpret_cast<char*>(certs[i]->derCert.data),
356 certs[i]->derCert.len));
[email protected]7a8de3072010-10-01 16:25:54357 }
358
[email protected]d0672be2010-10-20 16:30:19359 ssl_host_info_->Persist();
[email protected]7a8de3072010-10-01 16:25:54360}
361
362static void DestroyCertificates(CERTCertificate** certs, unsigned len) {
363 for (unsigned i = 0; i < len; i++)
364 CERT_DestroyCertificate(certs[i]);
365}
366
367// LoadSnapStartInfo parses |info|, which contains data previously serialised
368// by |SaveSnapStartInfo|, and sets the predicted certificates and ServerHello
369// data on the NSS socket. Returns true on success. If this function returns
370// false, the caller should try a normal TLS handshake.
[email protected]d0672be2010-10-20 16:30:19371bool SSLClientSocketNSS::LoadSnapStartInfo() {
372 const SSLHostInfo::State& state(ssl_host_info_->state());
373
374 if (state.server_hello.empty() ||
375 state.certs.empty() ||
376 !state.npn_valid) {
377 return false;
378 }
379
[email protected]7a8de3072010-10-01 16:25:54380 SECStatus rv;
[email protected]d0672be2010-10-20 16:30:19381 rv = SSL_SetPredictedServerHelloData(
382 nss_fd_,
383 reinterpret_cast<const uint8*>(state.server_hello.data()),
384 state.server_hello.size());
[email protected]7a8de3072010-10-01 16:25:54385 DCHECK_EQ(SECSuccess, rv);
[email protected]7a8de3072010-10-01 16:25:54386
[email protected]d0672be2010-10-20 16:30:19387 const std::vector<std::string>& certs_in = state.certs;
388 scoped_array<CERTCertificate*> certs(new CERTCertificate*[certs_in.size()]);
389 for (size_t i = 0; i < certs_in.size(); i++) {
[email protected]7a8de3072010-10-01 16:25:54390 SECItem derCert;
[email protected]d0672be2010-10-20 16:30:19391 derCert.data =
392 const_cast<uint8*>(reinterpret_cast<const uint8*>(certs_in[i].data()));
393 derCert.len = certs_in[i].size();
[email protected]7a8de3072010-10-01 16:25:54394 certs[i] = CERT_NewTempCertificate(
395 CERT_GetDefaultCertDB(), &derCert, NULL /* no nickname given */,
396 PR_FALSE /* not permanent */, PR_TRUE /* copy DER data */);
397 if (!certs[i]) {
398 DestroyCertificates(&certs[0], i);
399 NOTREACHED();
400 return false;
401 }
402 }
403
[email protected]d0672be2010-10-20 16:30:19404 rv = SSL_SetPredictedPeerCertificates(nss_fd_, certs.get(), certs_in.size());
405 DestroyCertificates(&certs[0], certs_in.size());
[email protected]7a8de3072010-10-01 16:25:54406 DCHECK_EQ(SECSuccess, rv);
407
[email protected]d0672be2010-10-20 16:30:19408 if (state.npn_valid) {
409 predicted_npn_status_ = state.npn_status;
410 predicted_npn_proto_ = state.npn_protocol;
411 }
[email protected]7a8de3072010-10-01 16:25:54412
413 return true;
414}
415
416bool SSLClientSocketNSS::IsNPNProtocolMispredicted() {
417 DCHECK(handshake_callback_called_);
418 if (!predicted_npn_proto_used_)
419 return false;
420 std::string npn_proto;
421 GetNextProto(&npn_proto);
422 return predicted_npn_proto_ != npn_proto;
423}
424
[email protected]fa788512010-10-08 14:48:06425void SSLClientSocketNSS::UncorkAfterTimeout() {
426 corked_ = false;
427 int nsent;
428 do {
429 nsent = BufferSend();
430 } while (nsent > 0);
431}
432
[email protected]a2006ece2010-04-23 16:44:02433int SSLClientSocketNSS::Connect(CompletionCallback* callback) {
[email protected]e17b4c12008-11-05 22:04:08434 EnterFunction("");
[email protected]b43c97c2008-10-22 19:50:58435 DCHECK(transport_.get());
[email protected]a3ff5e92009-10-13 04:48:06436 DCHECK(next_handshake_state_ == STATE_NONE);
437 DCHECK(!user_read_callback_);
438 DCHECK(!user_write_callback_);
[email protected]a6eb576292009-06-30 16:19:00439 DCHECK(!user_connect_callback_);
[email protected]a3ff5e92009-10-13 04:48:06440 DCHECK(!user_read_buf_);
441 DCHECK(!user_write_buf_);
[email protected]7a8de3072010-10-01 16:25:54442 DCHECK(!pseudo_connected_);
[email protected]b43c97c2008-10-22 19:50:58443
[email protected]ec11be62010-04-28 19:28:09444 net_log_.BeginEvent(NetLog::TYPE_SSL_CONNECT, NULL);
[email protected]5a05c47a2009-11-02 23:25:19445
[email protected]dbc13b52010-04-16 00:59:56446 int rv = Init();
447 if (rv != OK) {
[email protected]ec11be62010-04-28 19:28:09448 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL);
[email protected]dbc13b52010-04-16 00:59:56449 return rv;
[email protected]0ef0bcf2009-04-03 20:39:43450 }
451
[email protected]dbc13b52010-04-16 00:59:56452 rv = InitializeSSLOptions();
[email protected]5a05c47a2009-11-02 23:25:19453 if (rv != OK) {
[email protected]ec11be62010-04-28 19:28:09454 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL);
[email protected]5a05c47a2009-11-02 23:25:19455 return rv;
456 }
457
[email protected]7f7e92392010-10-26 18:29:29458 // Attempt to initialize the peer name. In the case of TCP FastOpen,
459 // we don't have the peer yet.
460 if (!UsingTCPFastOpen()) {
461 rv = InitializeSSLPeerName();
462 if (rv != OK) {
463 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL);
464 return rv;
465 }
466 }
467
[email protected]7ab5bbd12010-10-19 13:33:21468 if (ssl_config_.snap_start_enabled && ssl_host_info_.get()) {
[email protected]7a8de3072010-10-01 16:25:54469 GotoState(STATE_SNAP_START_LOAD_INFO);
470 } else {
471 GotoState(STATE_HANDSHAKE);
472 }
473
[email protected]5a05c47a2009-11-02 23:25:19474 rv = DoHandshakeLoop(OK);
475 if (rv == ERR_IO_PENDING) {
[email protected]7a8de3072010-10-01 16:25:54476 if (pseudo_connected_) {
477 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL);
478 rv = OK;
479 } else {
480 user_connect_callback_ = callback;
481 }
[email protected]5a05c47a2009-11-02 23:25:19482 } else {
[email protected]ec11be62010-04-28 19:28:09483 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL);
[email protected]5a05c47a2009-11-02 23:25:19484 }
485
486 LeaveFunction("");
487 return rv > OK ? OK : rv;
488}
489
490int SSLClientSocketNSS::InitializeSSLOptions() {
[email protected]0ef0bcf2009-04-03 20:39:43491 // Transport connected, now hook it up to nss
492 // TODO(port): specify rx and tx buffer sizes separately
493 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize);
494 if (nss_fd_ == NULL) {
[email protected]38a18722009-12-04 00:09:04495 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR error code.
[email protected]0ef0bcf2009-04-03 20:39:43496 }
497
[email protected]0ef0bcf2009-04-03 20:39:43498 // Grab pointer to buffers
499 nss_bufs_ = memio_GetSecret(nss_fd_);
500
501 /* Create SSL state machine */
502 /* Push SSL onto our fake I/O socket */
503 nss_fd_ = SSL_ImportFD(NULL, nss_fd_);
504 if (nss_fd_ == NULL) {
[email protected]7cbc6df12010-10-04 16:25:39505 LogFailedNSSFunction(net_log_, "SSL_ImportFD", "");
[email protected]4e91b5c2010-09-22 01:04:38506 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR/NSS error code.
[email protected]0ef0bcf2009-04-03 20:39:43507 }
508 // TODO(port): set more ssl options! Check errors!
509
510 int rv;
511
512 rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE);
[email protected]7cbc6df12010-10-04 16:25:39513 if (rv != SECSuccess) {
514 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_SECURITY");
[email protected]4e91b5c2010-09-22 01:04:38515 return ERR_UNEXPECTED;
[email protected]7cbc6df12010-10-04 16:25:39516 }
[email protected]0ef0bcf2009-04-03 20:39:43517
[email protected]cc50fdf72010-11-30 17:48:54518 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL2, PR_FALSE);
[email protected]7cbc6df12010-10-04 16:25:39519 if (rv != SECSuccess) {
520 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL2");
[email protected]4e91b5c2010-09-22 01:04:38521 return ERR_UNEXPECTED;
[email protected]7cbc6df12010-10-04 16:25:39522 }
[email protected]0ef0bcf2009-04-03 20:39:43523
[email protected]cc50fdf72010-11-30 17:48:54524 // Don't do V2 compatible hellos because they don't support TLS extensions.
525 rv = SSL_OptionSet(nss_fd_, SSL_V2_COMPATIBLE_HELLO, PR_FALSE);
[email protected]7cbc6df12010-10-04 16:25:39526 if (rv != SECSuccess) {
527 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_V2_COMPATIBLE_HELLO");
528 return ERR_UNEXPECTED;
529 }
[email protected]0ef0bcf2009-04-03 20:39:43530
531 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL3, ssl_config_.ssl3_enabled);
[email protected]7cbc6df12010-10-04 16:25:39532 if (rv != SECSuccess) {
533 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL3");
534 return ERR_UNEXPECTED;
535 }
[email protected]0ef0bcf2009-04-03 20:39:43536
537 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_TLS, ssl_config_.tls1_enabled);
[email protected]7cbc6df12010-10-04 16:25:39538 if (rv != SECSuccess) {
539 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_TLS");
540 return ERR_UNEXPECTED;
541 }
[email protected]0ef0bcf2009-04-03 20:39:43542
[email protected]47f7d742010-11-11 04:12:53543 for (std::vector<uint16>::const_iterator it =
544 ssl_config_.disabled_cipher_suites.begin();
545 it != ssl_config_.disabled_cipher_suites.end(); ++it) {
546 // This will fail if the specified cipher is not implemented by NSS, but
547 // the failure is harmless.
548 SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE);
549 }
550
[email protected]0ef0bcf2009-04-03 20:39:43551#ifdef SSL_ENABLE_SESSION_TICKETS
552 // Support RFC 5077
553 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_TRUE);
[email protected]7cbc6df12010-10-04 16:25:39554 if (rv != SECSuccess) {
555 LogFailedNSSFunction(
556 net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS");
557 }
[email protected]0ef0bcf2009-04-03 20:39:43558#else
559 #error "You need to install NSS-3.12 or later to build chromium"
560#endif
561
[email protected]f61c3972010-12-23 09:54:15562 rv = SSL_OptionSet(nss_fd_, SSL_NO_CACHE,
563 ssl_config_.session_resume_disabled);
564 if (rv != SECSuccess) {
565 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_NO_CACHE");
566 return ERR_UNEXPECTED;
567 }
568
[email protected]7e52ed72009-11-17 00:40:12569#ifdef SSL_ENABLE_DEFLATE
[email protected]074c1582010-01-08 21:38:28570 // Some web servers have been found to break if TLS is used *or* if DEFLATE
571 // is advertised. Thus, if TLS is disabled (probably because we are doing
572 // SSLv3 fallback), we disable DEFLATE also.
573 // See http://crbug.com/31628
574 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_DEFLATE, ssl_config_.tls1_enabled);
[email protected]7e52ed72009-11-17 00:40:12575 if (rv != SECSuccess)
[email protected]7cbc6df12010-10-04 16:25:39576 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_DEFLATE");
[email protected]7e52ed72009-11-17 00:40:12577#endif
578
[email protected]c2def1c2010-03-02 21:40:34579#ifdef SSL_ENABLE_FALSE_START
[email protected]a0deaecf2010-08-18 23:39:52580 rv = SSL_OptionSet(
581 nss_fd_, SSL_ENABLE_FALSE_START,
582 ssl_config_.false_start_enabled &&
[email protected]4f4de7e62010-11-12 19:55:27583 !SSLConfigService::IsKnownFalseStartIncompatibleServer(
584 host_and_port_.host()));
[email protected]c2def1c2010-03-02 21:40:34585 if (rv != SECSuccess)
[email protected]7cbc6df12010-10-04 16:25:39586 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_FALSE_START");
[email protected]c2def1c2010-03-02 21:40:34587#endif
588
[email protected]7a8de3072010-10-01 16:25:54589#ifdef SSL_ENABLE_SNAP_START
590 // TODO(agl): check that SSL_ENABLE_SNAP_START actually does something in the
591 // current NSS code.
[email protected]4d52f192010-10-11 17:00:30592 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SNAP_START,
[email protected]09125792010-11-03 23:23:22593 ssl_config_.snap_start_enabled);
[email protected]7a8de3072010-10-01 16:25:54594 if (rv != SECSuccess)
[email protected]b30a3f52010-10-16 01:05:46595 VLOG(1) << "SSL_ENABLE_SNAP_START failed. Old system nss?";
[email protected]7a8de3072010-10-01 16:25:54596#endif
597
[email protected]33b3eb92010-01-06 01:35:04598#ifdef SSL_ENABLE_RENEGOTIATION
[email protected]304b0e352010-09-13 18:10:08599 // Deliberately disable this check for now: http://crbug.com/55410
600 if (false &&
[email protected]4f4de7e62010-11-12 19:55:27601 SSLConfigService::IsKnownStrictTLSServer(host_and_port_.host()) &&
[email protected]944a0a12010-08-19 20:02:28602 !ssl_config_.mitm_proxies_allowed) {
[email protected]d102f542010-06-30 14:51:05603 rv = SSL_OptionSet(nss_fd_, SSL_REQUIRE_SAFE_NEGOTIATION, PR_TRUE);
[email protected]7cbc6df12010-10-04 16:25:39604 if (rv != SECSuccess) {
605 LogFailedNSSFunction(
606 net_log_, "SSL_OptionSet", "SSL_REQUIRE_SAFE_NEGOTIATION");
607 }
[email protected]d102f542010-06-30 14:51:05608 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION,
609 SSL_RENEGOTIATE_REQUIRES_XTN);
610 } else {
611 // We allow servers to request renegotiation. Since we're a client,
612 // prohibiting this is rather a waste of time. Only servers are in a
613 // position to prevent renegotiation attacks.
614 // http://extendedsubset.com/?p=8
615
616 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION,
[email protected]e7bad86e2010-08-17 00:56:40617 SSL_RENEGOTIATE_TRANSITIONAL);
[email protected]d102f542010-06-30 14:51:05618 }
[email protected]7cbc6df12010-10-04 16:25:39619 if (rv != SECSuccess) {
620 LogFailedNSSFunction(
621 net_log_, "SSL_OptionSet", "SSL_ENABLE_RENEGOTIATION");
622 }
[email protected]d102f542010-06-30 14:51:05623#endif // SSL_ENABLE_RENEGOTIATION
[email protected]33b3eb92010-01-06 01:35:04624
[email protected]644bdca2009-11-30 20:40:53625#ifdef SSL_NEXT_PROTO_NEGOTIATED
626 if (!ssl_config_.next_protos.empty()) {
627 rv = SSL_SetNextProtoNego(
628 nss_fd_,
629 reinterpret_cast<const unsigned char *>(ssl_config_.next_protos.data()),
630 ssl_config_.next_protos.size());
631 if (rv != SECSuccess)
[email protected]7cbc6df12010-10-04 16:25:39632 LogFailedNSSFunction(net_log_, "SSL_SetNextProtoNego", "");
[email protected]644bdca2009-11-30 20:40:53633 }
634#endif
635
[email protected]0ef0bcf2009-04-03 20:39:43636 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
[email protected]7cbc6df12010-10-04 16:25:39637 if (rv != SECSuccess) {
638 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT");
639 return ERR_UNEXPECTED;
640 }
[email protected]0ef0bcf2009-04-03 20:39:43641
642 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this);
[email protected]7cbc6df12010-10-04 16:25:39643 if (rv != SECSuccess) {
644 LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", "");
645 return ERR_UNEXPECTED;
646 }
[email protected]0ef0bcf2009-04-03 20:39:43647
[email protected]4a842342010-11-04 16:21:33648#if defined(NSS_PLATFORM_CLIENT_AUTH)
649 rv = SSL_GetPlatformClientAuthDataHook(nss_fd_, PlatformClientAuthHandler,
650 this);
651#else
[email protected]d84b3722009-10-15 21:23:37652 rv = SSL_GetClientAuthDataHook(nss_fd_, ClientAuthHandler, this);
[email protected]4a842342010-11-04 16:21:33653#endif
[email protected]7cbc6df12010-10-04 16:25:39654 if (rv != SECSuccess) {
655 LogFailedNSSFunction(net_log_, "SSL_GetClientAuthDataHook", "");
656 return ERR_UNEXPECTED;
657 }
[email protected]d84b3722009-10-15 21:23:37658
[email protected]2345cc52009-06-04 09:18:47659 rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this);
[email protected]7cbc6df12010-10-04 16:25:39660 if (rv != SECSuccess) {
661 LogFailedNSSFunction(net_log_, "SSL_HandshakeCallback", "");
[email protected]2345cc52009-06-04 09:18:47662 return ERR_UNEXPECTED;
[email protected]7cbc6df12010-10-04 16:25:39663 }
[email protected]0ef0bcf2009-04-03 20:39:43664
665 // Tell SSL the hostname we're trying to connect to.
[email protected]4f4de7e62010-11-12 19:55:27666 SSL_SetURL(nss_fd_, host_and_port_.host().c_str());
[email protected]0ef0bcf2009-04-03 20:39:43667
[email protected]7f7e92392010-10-26 18:29:29668 // Tell SSL we're a client; needed if not letting NSPR do socket I/O
669 SSL_ResetHandshake(nss_fd_, 0);
670
671 return OK;
672}
673
674int SSLClientSocketNSS::InitializeSSLPeerName() {
675 // Tell NSS who we're connected to
676 AddressList peer_address;
677 int err = transport_->socket()->GetPeerAddress(&peer_address);
678 if (err != OK)
679 return err;
680
681 const struct addrinfo* ai = peer_address.head();
682
683 PRNetAddr peername;
684 memset(&peername, 0, sizeof(peername));
685 DCHECK_LE(ai->ai_addrlen, sizeof(peername));
686 size_t len = std::min(static_cast<size_t>(ai->ai_addrlen),
687 sizeof(peername));
688 memcpy(&peername, ai->ai_addr, len);
689
690 // Adjust the address family field for BSD, whose sockaddr
691 // structure has a one-byte length and one-byte address family
692 // field at the beginning. PRNetAddr has a two-byte address
693 // family field at the beginning.
694 peername.raw.family = ai->ai_addr->sa_family;
695
696 memio_SetPeerName(nss_fd_, &peername);
697
[email protected]52c27fb2009-11-30 22:40:23698 // Set the peer ID for session reuse. This is necessary when we create an
699 // SSL tunnel through a proxy -- GetPeerName returns the proxy's address
700 // rather than the destination server's address in that case.
[email protected]4f4de7e62010-11-12 19:55:27701 std::string peer_id = host_and_port_.ToString();
[email protected]7f7e92392010-10-26 18:29:29702 SECStatus rv = SSL_SetSockPeerID(nss_fd_, const_cast<char*>(peer_id.c_str()));
[email protected]52c27fb2009-11-30 22:40:23703 if (rv != SECSuccess)
[email protected]7cbc6df12010-10-04 16:25:39704 LogFailedNSSFunction(net_log_, "SSL_SetSockPeerID", peer_id.c_str());
[email protected]52c27fb2009-11-30 22:40:23705
[email protected]7f7e92392010-10-26 18:29:29706 peername_initialized_ = true;
[email protected]5a05c47a2009-11-02 23:25:19707 return OK;
[email protected]b43c97c2008-10-22 19:50:58708}
709
[email protected]b43c97c2008-10-22 19:50:58710void SSLClientSocketNSS::Disconnect() {
[email protected]e17b4c12008-11-05 22:04:08711 EnterFunction("");
[email protected]bacff652009-03-31 17:50:33712
[email protected]b43c97c2008-10-22 19:50:58713 // TODO(wtc): Send SSL close_notify alert.
714 if (nss_fd_ != NULL) {
[email protected]b43c97c2008-10-22 19:50:58715 PR_Close(nss_fd_);
716 nss_fd_ = NULL;
717 }
[email protected]bacff652009-03-31 17:50:33718
[email protected]92d9cad2009-06-25 23:40:24719 // Shut down anything that may call us back (through buffer_send_callback_,
[email protected]a3ff5e92009-10-13 04:48:06720 // buffer_recv_callback, or handshake_io_callback_).
[email protected]92d9cad2009-06-25 23:40:24721 verifier_.reset();
[email protected]e60e47a2010-07-14 03:37:18722 transport_->socket()->Disconnect();
[email protected]bf0136d2009-05-29 05:55:04723
724 // Reset object state
[email protected]a6eb576292009-06-30 16:19:00725 transport_send_busy_ = false;
726 transport_recv_busy_ = false;
727 user_connect_callback_ = NULL;
[email protected]a3ff5e92009-10-13 04:48:06728 user_read_callback_ = NULL;
729 user_write_callback_ = NULL;
730 user_read_buf_ = NULL;
731 user_read_buf_len_ = 0;
732 user_write_buf_ = NULL;
733 user_write_buf_len_ = 0;
[email protected]a6eb576292009-06-30 16:19:00734 server_cert_ = NULL;
[email protected]f505a9b2010-01-28 19:44:02735 if (server_cert_nss_) {
736 CERT_DestroyCertificate(server_cert_nss_);
737 server_cert_nss_ = NULL;
738 }
[email protected]3b1d3db2010-10-28 16:39:40739 local_server_cert_verify_result_.Reset();
740 server_cert_verify_result_ = NULL;
[email protected]757f2e2b2010-10-27 23:28:35741 ssl_connection_status_ = 0;
[email protected]a6eb576292009-06-30 16:19:00742 completed_handshake_ = false;
[email protected]7a8de3072010-10-01 16:25:54743 pseudo_connected_ = false;
[email protected]563cbcc62010-10-11 23:07:52744 eset_mitm_detected_ = false;
[email protected]081b0942010-12-13 19:34:14745 start_cert_verification_time_ = base::TimeTicks();
[email protected]3b1d3db2010-10-28 16:39:40746 predicted_cert_chain_correct_ = false;
[email protected]7f7e92392010-10-26 18:29:29747 peername_initialized_ = false;
[email protected]a6eb576292009-06-30 16:19:00748 nss_bufs_ = NULL;
[email protected]b8fee152009-10-24 03:39:31749 client_certs_.clear();
[email protected]d84b3722009-10-15 21:23:37750 client_auth_cert_needed_ = false;
[email protected]bf0136d2009-05-29 05:55:04751
[email protected]e17b4c12008-11-05 22:04:08752 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:58753}
754
755bool SSLClientSocketNSS::IsConnected() const {
[email protected]b2197852009-02-19 23:27:33756 // Ideally, we should also check if we have received the close_notify alert
757 // message from the server, and return false in that case. We're not doing
758 // that, so this function may return a false positive. Since the upper
759 // layer (HttpNetworkTransaction) needs to handle a persistent connection
760 // closed by the server when we send a request anyway, a false positive in
761 // exchange for simpler code is a good trade-off.
[email protected]e17b4c12008-11-05 22:04:08762 EnterFunction("");
[email protected]7a8de3072010-10-01 16:25:54763 bool ret = (pseudo_connected_ || completed_handshake_) &&
764 transport_->socket()->IsConnected();
[email protected]e17b4c12008-11-05 22:04:08765 LeaveFunction("");
766 return ret;
[email protected]b43c97c2008-10-22 19:50:58767}
768
[email protected]b2197852009-02-19 23:27:33769bool SSLClientSocketNSS::IsConnectedAndIdle() const {
770 // Unlike IsConnected, this method doesn't return a false positive.
771 //
772 // Strictly speaking, we should check if we have received the close_notify
773 // alert message from the server, and return false in that case. Although
774 // the close_notify alert message means EOF in the SSL layer, it is just
[email protected]e60e47a2010-07-14 03:37:18775 // bytes to the transport layer below, so
776 // transport_->socket()->IsConnectedAndIdle() returns the desired false
777 // when we receive close_notify.
[email protected]b2197852009-02-19 23:27:33778 EnterFunction("");
[email protected]7a8de3072010-10-01 16:25:54779 bool ret = (pseudo_connected_ || completed_handshake_) &&
780 transport_->socket()->IsConnectedAndIdle();
[email protected]b2197852009-02-19 23:27:33781 LeaveFunction("");
782 return ret;
783}
784
[email protected]ac9eec62010-02-20 18:50:38785int SSLClientSocketNSS::GetPeerAddress(AddressList* address) const {
[email protected]e60e47a2010-07-14 03:37:18786 return transport_->socket()->GetPeerAddress(address);
[email protected]9f864b32010-01-20 15:01:16787}
788
[email protected]e4be2dd2010-12-14 00:44:39789const BoundNetLog& SSLClientSocketNSS::NetLog() const {
790 return net_log_;
791}
792
[email protected]9b5614a2010-08-25 20:29:45793void SSLClientSocketNSS::SetSubresourceSpeculation() {
794 if (transport_.get() && transport_->socket()) {
795 transport_->socket()->SetSubresourceSpeculation();
796 } else {
797 NOTREACHED();
798 }
799}
800
801void SSLClientSocketNSS::SetOmniboxSpeculation() {
802 if (transport_.get() && transport_->socket()) {
803 transport_->socket()->SetOmniboxSpeculation();
804 } else {
805 NOTREACHED();
806 }
807}
808
[email protected]0f873e82010-09-02 16:09:01809bool SSLClientSocketNSS::WasEverUsed() const {
810 if (transport_.get() && transport_->socket()) {
811 return transport_->socket()->WasEverUsed();
812 }
813 NOTREACHED();
814 return false;
815}
816
[email protected]7f7e92392010-10-26 18:29:29817bool SSLClientSocketNSS::UsingTCPFastOpen() const {
818 if (transport_.get() && transport_->socket()) {
819 return transport_->socket()->UsingTCPFastOpen();
820 }
821 NOTREACHED();
822 return false;
823}
824
[email protected]ffeb0882009-04-30 21:51:25825int SSLClientSocketNSS::Read(IOBuffer* buf, int buf_len,
[email protected]ea224582008-12-07 20:25:46826 CompletionCallback* callback) {
[email protected]e17b4c12008-11-05 22:04:08827 EnterFunction(buf_len);
[email protected]a3ff5e92009-10-13 04:48:06828 DCHECK(!user_read_callback_);
[email protected]a6eb576292009-06-30 16:19:00829 DCHECK(!user_connect_callback_);
[email protected]a3ff5e92009-10-13 04:48:06830 DCHECK(!user_read_buf_);
831 DCHECK(nss_bufs_);
[email protected]b43c97c2008-10-22 19:50:58832
[email protected]a3ff5e92009-10-13 04:48:06833 user_read_buf_ = buf;
834 user_read_buf_len_ = buf_len;
[email protected]b43c97c2008-10-22 19:50:58835
[email protected]7a8de3072010-10-01 16:25:54836 if (!completed_handshake_) {
837 // In this case we have lied about being connected in order to merge the
838 // first Write into a Snap Start handshake. We'll leave the read hanging
839 // until the handshake has completed.
840 DCHECK(pseudo_connected_);
841
842 user_read_callback_ = callback;
843 LeaveFunction(ERR_IO_PENDING);
844 return ERR_IO_PENDING;
845 }
846
[email protected]a3ff5e92009-10-13 04:48:06847 int rv = DoReadLoop(OK);
848
[email protected]1d583612010-03-12 17:47:14849 if (rv == ERR_IO_PENDING) {
[email protected]a3ff5e92009-10-13 04:48:06850 user_read_callback_ = callback;
[email protected]1d583612010-03-12 17:47:14851 } else {
[email protected]a3ff5e92009-10-13 04:48:06852 user_read_buf_ = NULL;
853 user_read_buf_len_ = 0;
854 }
[email protected]ea224582008-12-07 20:25:46855 LeaveFunction(rv);
[email protected]b43c97c2008-10-22 19:50:58856 return rv;
857}
858
[email protected]ffeb0882009-04-30 21:51:25859int SSLClientSocketNSS::Write(IOBuffer* buf, int buf_len,
[email protected]a3ff5e92009-10-13 04:48:06860 CompletionCallback* callback) {
[email protected]e17b4c12008-11-05 22:04:08861 EnterFunction(buf_len);
[email protected]7a8de3072010-10-01 16:25:54862 if (!pseudo_connected_) {
863 DCHECK(completed_handshake_);
864 DCHECK(next_handshake_state_ == STATE_NONE);
865 DCHECK(!user_connect_callback_);
866 }
[email protected]a3ff5e92009-10-13 04:48:06867 DCHECK(!user_write_callback_);
[email protected]a3ff5e92009-10-13 04:48:06868 DCHECK(!user_write_buf_);
869 DCHECK(nss_bufs_);
[email protected]b43c97c2008-10-22 19:50:58870
[email protected]a3ff5e92009-10-13 04:48:06871 user_write_buf_ = buf;
872 user_write_buf_len_ = buf_len;
[email protected]b43c97c2008-10-22 19:50:58873
[email protected]7a8de3072010-10-01 16:25:54874 if (next_handshake_state_ == STATE_SNAP_START_WAIT_FOR_WRITE) {
875 // We lied about being connected and we have been waiting for this write in
876 // order to merge it into the Snap Start handshake. We'll leave the write
877 // pending until the handshake completes.
878 DCHECK(pseudo_connected_);
879 int rv = DoHandshakeLoop(OK);
880 if (rv == ERR_IO_PENDING) {
881 user_write_callback_ = callback;
882 } else {
883 user_write_buf_ = NULL;
884 user_write_buf_len_ = 0;
885 }
886 if (rv != OK)
887 return rv;
888 }
889
[email protected]fa788512010-10-08 14:48:06890 if (corked_) {
891 corked_ = false;
892 uncork_timer_.Reset();
893 }
[email protected]a3ff5e92009-10-13 04:48:06894 int rv = DoWriteLoop(OK);
895
[email protected]1d583612010-03-12 17:47:14896 if (rv == ERR_IO_PENDING) {
[email protected]a3ff5e92009-10-13 04:48:06897 user_write_callback_ = callback;
[email protected]1d583612010-03-12 17:47:14898 } else {
[email protected]a3ff5e92009-10-13 04:48:06899 user_write_buf_ = NULL;
900 user_write_buf_len_ = 0;
901 }
[email protected]ea224582008-12-07 20:25:46902 LeaveFunction(rv);
[email protected]b43c97c2008-10-22 19:50:58903 return rv;
904}
905
[email protected]d3f66572009-09-09 22:38:04906bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) {
[email protected]e60e47a2010-07-14 03:37:18907 return transport_->socket()->SetReceiveBufferSize(size);
[email protected]d3f66572009-09-09 22:38:04908}
909
910bool SSLClientSocketNSS::SetSendBufferSize(int32 size) {
[email protected]e60e47a2010-07-14 03:37:18911 return transport_->socket()->SetSendBufferSize(size);
[email protected]d3f66572009-09-09 22:38:04912}
913
[email protected]2d6e77832010-11-10 22:13:46914// static
915void SSLClientSocketNSS::ClearSessionCache() {
916 SSL_ClearSessionCache();
917}
918
[email protected]757f2e2b2010-10-27 23:28:35919// Sets server_cert_ and server_cert_nss_ if not yet set.
920// Returns server_cert_.
[email protected]bacff652009-03-31 17:50:33921X509Certificate *SSLClientSocketNSS::UpdateServerCert() {
[email protected]757f2e2b2010-10-27 23:28:35922 // We set the server_cert_ from HandshakeCallback().
[email protected]bacff652009-03-31 17:50:33923 if (server_cert_ == NULL) {
[email protected]f505a9b2010-01-28 19:44:02924 server_cert_nss_ = SSL_PeerCertificate(nss_fd_);
925 if (server_cert_nss_) {
[email protected]4feca4b2010-10-28 16:50:32926 PeerCertificateChain certs(nss_fd_);
[email protected]d8fbf582010-11-04 21:51:12927 server_cert_ = X509Certificate::CreateFromDERCertChain(
928 certs.AsStringPieceVector());
[email protected]bacff652009-03-31 17:50:33929 }
930 }
931 return server_cert_;
932}
933
[email protected]757f2e2b2010-10-27 23:28:35934// Sets ssl_connection_status_.
935void SSLClientSocketNSS::UpdateConnectionStatus() {
936 SSLChannelInfo channel_info;
937 SECStatus ok = SSL_GetChannelInfo(nss_fd_,
938 &channel_info, sizeof(channel_info));
939 if (ok == SECSuccess &&
940 channel_info.length == sizeof(channel_info) &&
941 channel_info.cipherSuite) {
942 ssl_connection_status_ |=
943 (static_cast<int>(channel_info.cipherSuite) &
944 SSL_CONNECTION_CIPHERSUITE_MASK) <<
945 SSL_CONNECTION_CIPHERSUITE_SHIFT;
946
947 ssl_connection_status_ |=
948 (static_cast<int>(channel_info.compressionMethod) &
949 SSL_CONNECTION_COMPRESSION_MASK) <<
950 SSL_CONNECTION_COMPRESSION_SHIFT;
951
[email protected]b92a96e2010-11-02 21:03:05952 // NSS 3.12.x doesn't have version macros for TLS 1.1 and 1.2 (because NSS
953 // doesn't support them yet), so we use 0x0302 and 0x0303 directly.
[email protected]757f2e2b2010-10-27 23:28:35954 int version = SSL_CONNECTION_VERSION_UNKNOWN;
955 if (channel_info.protocolVersion < SSL_LIBRARY_VERSION_3_0) {
956 // All versions less than SSL_LIBRARY_VERSION_3_0 are treated as SSL
957 // version 2.
958 version = SSL_CONNECTION_VERSION_SSL2;
959 } else if (channel_info.protocolVersion == SSL_LIBRARY_VERSION_3_0) {
960 version = SSL_CONNECTION_VERSION_SSL3;
961 } else if (channel_info.protocolVersion == SSL_LIBRARY_VERSION_3_1_TLS) {
962 version = SSL_CONNECTION_VERSION_TLS1;
[email protected]b92a96e2010-11-02 21:03:05963 } else if (channel_info.protocolVersion == 0x0302) {
964 version = SSL_CONNECTION_VERSION_TLS1_1;
965 } else if (channel_info.protocolVersion == 0x0303) {
966 version = SSL_CONNECTION_VERSION_TLS1_2;
[email protected]757f2e2b2010-10-27 23:28:35967 }
968 ssl_connection_status_ |=
969 (version & SSL_CONNECTION_VERSION_MASK) <<
970 SSL_CONNECTION_VERSION_SHIFT;
971 }
972
[email protected]1e7cd2c72010-02-27 01:31:19973 // SSL_HandshakeNegotiatedExtension was added in NSS 3.12.6.
974 // Since SSL_MAX_EXTENSIONS was added at the same time, we can test
975 // SSL_MAX_EXTENSIONS for the presence of SSL_HandshakeNegotiatedExtension.
976#if defined(SSL_MAX_EXTENSIONS)
[email protected]757f2e2b2010-10-27 23:28:35977 PRBool peer_supports_renego_ext;
978 ok = SSL_HandshakeNegotiatedExtension(nss_fd_, ssl_renegotiation_info_xtn,
979 &peer_supports_renego_ext);
980 if (ok == SECSuccess) {
981 if (!peer_supports_renego_ext) {
982 ssl_connection_status_ |= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION;
983 // Log an informational message if the server does not support secure
984 // renegotiation (RFC 5746).
[email protected]4f4de7e62010-11-12 19:55:27985 VLOG(1) << "The server " << host_and_port_.ToString()
[email protected]757f2e2b2010-10-27 23:28:35986 << " does not support the TLS renegotiation_info extension.";
987 }
988 UMA_HISTOGRAM_ENUMERATION("Net.RenegotiationExtensionSupported",
989 peer_supports_renego_ext, 2);
[email protected]1e7cd2c72010-02-27 01:31:19990 }
991#endif
[email protected]757f2e2b2010-10-27 23:28:35992
993 if (ssl_config_.ssl3_fallback)
994 ssl_connection_status_ |= SSL_CONNECTION_SSL3_FALLBACK;
[email protected]1e7cd2c72010-02-27 01:31:19995}
996
[email protected]b43c97c2008-10-22 19:50:58997void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) {
[email protected]e17b4c12008-11-05 22:04:08998 EnterFunction("");
[email protected]b43c97c2008-10-22 19:50:58999 ssl_info->Reset();
[email protected]7a8de3072010-10-01 16:25:541000
1001 if (!server_cert_) {
1002 LOG(DFATAL) << "!server_cert_";
[email protected]2345cc52009-06-04 09:18:471003 return;
[email protected]7a8de3072010-10-01 16:25:541004 }
[email protected]2345cc52009-06-04 09:18:471005
[email protected]3b1d3db2010-10-28 16:39:401006 ssl_info->cert_status = server_cert_verify_result_->cert_status;
[email protected]bacff652009-03-31 17:50:331007 DCHECK(server_cert_ != NULL);
1008 ssl_info->cert = server_cert_;
[email protected]757f2e2b2010-10-27 23:28:351009 ssl_info->connection_status = ssl_connection_status_;
[email protected]644bdca2009-11-30 20:40:531010
[email protected]757f2e2b2010-10-27 23:28:351011 PRUint16 cipher_suite =
1012 SSLConnectionStatusToCipherSuite(ssl_connection_status_);
1013 SSLCipherSuiteInfo cipher_info;
1014 SECStatus ok = SSL_GetCipherSuiteInfo(cipher_suite,
1015 &cipher_info, sizeof(cipher_info));
[email protected]fc7de492010-07-12 14:49:041016 if (ok == SECSuccess) {
[email protected]757f2e2b2010-10-27 23:28:351017 ssl_info->security_bits = cipher_info.effectiveKeyBits;
1018 } else {
1019 ssl_info->security_bits = -1;
1020 LOG(DFATAL) << "SSL_GetCipherSuiteInfo returned " << PR_GetError()
1021 << " for cipherSuite " << cipher_suite;
[email protected]fc7de492010-07-12 14:49:041022 }
[email protected]e17b4c12008-11-05 22:04:081023 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:581024}
1025
[email protected]0b45559b2009-06-12 21:45:111026void SSLClientSocketNSS::GetSSLCertRequestInfo(
1027 SSLCertRequestInfo* cert_request_info) {
[email protected]d84b3722009-10-15 21:23:371028 EnterFunction("");
[email protected]4f4de7e62010-11-12 19:55:271029 // TODO(rch): switch SSLCertRequestInfo.host_and_port to a HostPortPair
1030 cert_request_info->host_and_port = host_and_port_.ToString();
[email protected]b8fee152009-10-24 03:39:311031 cert_request_info->client_certs = client_certs_;
[email protected]d84b3722009-10-15 21:23:371032 LeaveFunction(cert_request_info->client_certs.size());
[email protected]0b45559b2009-06-12 21:45:111033}
1034
[email protected]b28f19d72009-12-10 21:52:271035SSLClientSocket::NextProtoStatus
[email protected]f49ea7d2009-12-11 20:03:501036SSLClientSocketNSS::GetNextProto(std::string* proto) {
1037#if defined(SSL_NEXT_PROTO_NEGOTIATED)
[email protected]7a8de3072010-10-01 16:25:541038 if (!handshake_callback_called_) {
1039 DCHECK(pseudo_connected_);
1040 predicted_npn_proto_used_ = true;
1041 *proto = predicted_npn_proto_;
1042 return predicted_npn_status_;
1043 }
1044
[email protected]f49ea7d2009-12-11 20:03:501045 unsigned char buf[255];
[email protected]b28f19d72009-12-10 21:52:271046 int state;
1047 unsigned len;
1048 SECStatus rv = SSL_GetNextProto(nss_fd_, &state, buf, &len, sizeof(buf));
1049 if (rv != SECSuccess) {
1050 NOTREACHED() << "Error return from SSL_GetNextProto: " << rv;
1051 proto->clear();
1052 return kNextProtoUnsupported;
1053 }
[email protected]f49ea7d2009-12-11 20:03:501054 // We don't check for truncation because sizeof(buf) is large enough to hold
1055 // the maximum protocol size.
[email protected]829296f2010-01-27 02:58:031056 switch (state) {
[email protected]f49ea7d2009-12-11 20:03:501057 case SSL_NEXT_PROTO_NO_SUPPORT:
1058 proto->clear();
1059 return kNextProtoUnsupported;
1060 case SSL_NEXT_PROTO_NEGOTIATED:
1061 *proto = std::string(reinterpret_cast<char*>(buf), len);
1062 return kNextProtoNegotiated;
1063 case SSL_NEXT_PROTO_NO_OVERLAP:
1064 *proto = std::string(reinterpret_cast<char*>(buf), len);
1065 return kNextProtoNoOverlap;
1066 default:
1067 NOTREACHED() << "Unknown status from SSL_GetNextProto: " << state;
1068 proto->clear();
1069 return kNextProtoUnsupported;
[email protected]b28f19d72009-12-10 21:52:271070 }
[email protected]f49ea7d2009-12-11 20:03:501071#else
1072 // No NPN support in the libssl that we are building with.
1073 proto->clear();
1074 return kNextProtoUnsupported;
[email protected]b28f19d72009-12-10 21:52:271075#endif
1076}
1077
[email protected]899c3e92010-08-28 15:53:501078void SSLClientSocketNSS::UseDNSSEC(DNSSECProvider* provider) {
1079 dnssec_provider_ = provider;
1080}
1081
[email protected]a3ff5e92009-10-13 04:48:061082void SSLClientSocketNSS::DoReadCallback(int rv) {
[email protected]e17b4c12008-11-05 22:04:081083 EnterFunction(rv);
[email protected]b43c97c2008-10-22 19:50:581084 DCHECK(rv != ERR_IO_PENDING);
[email protected]a3ff5e92009-10-13 04:48:061085 DCHECK(user_read_callback_);
[email protected]b43c97c2008-10-22 19:50:581086
[email protected]a3ff5e92009-10-13 04:48:061087 // Since Run may result in Read being called, clear |user_read_callback_|
1088 // up front.
1089 CompletionCallback* c = user_read_callback_;
1090 user_read_callback_ = NULL;
1091 user_read_buf_ = NULL;
1092 user_read_buf_len_ = 0;
1093 c->Run(rv);
1094 LeaveFunction("");
1095}
1096
1097void SSLClientSocketNSS::DoWriteCallback(int rv) {
1098 EnterFunction(rv);
1099 DCHECK(rv != ERR_IO_PENDING);
1100 DCHECK(user_write_callback_);
1101
1102 // Since Run may result in Write being called, clear |user_write_callback_|
1103 // up front.
1104 CompletionCallback* c = user_write_callback_;
1105 user_write_callback_ = NULL;
1106 user_write_buf_ = NULL;
1107 user_write_buf_len_ = 0;
[email protected]b43c97c2008-10-22 19:50:581108 c->Run(rv);
[email protected]e17b4c12008-11-05 22:04:081109 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:581110}
1111
[email protected]a6eb576292009-06-30 16:19:001112// As part of Connect(), the SSLClientSocketNSS object performs an SSL
1113// handshake. This requires network IO, which in turn calls
1114// BufferRecvComplete() with a non-zero byte count. This byte count eventually
1115// winds its way through the state machine and ends up being passed to the
1116// callback. For Read() and Write(), that's what we want. But for Connect(),
1117// the caller expects OK (i.e. 0) for success.
1118//
1119void SSLClientSocketNSS::DoConnectCallback(int rv) {
1120 EnterFunction(rv);
1121 DCHECK_NE(rv, ERR_IO_PENDING);
[email protected]a6eb576292009-06-30 16:19:001122
[email protected]a6eb576292009-06-30 16:19:001123 CompletionCallback* c = user_connect_callback_;
1124 user_connect_callback_ = NULL;
1125 c->Run(rv > OK ? OK : rv);
1126 LeaveFunction("");
1127}
1128
[email protected]a3ff5e92009-10-13 04:48:061129void SSLClientSocketNSS::OnHandshakeIOComplete(int result) {
[email protected]e17b4c12008-11-05 22:04:081130 EnterFunction(result);
[email protected]a3ff5e92009-10-13 04:48:061131 int rv = DoHandshakeLoop(result);
[email protected]5a05c47a2009-11-02 23:25:191132 if (rv != ERR_IO_PENDING) {
[email protected]ec11be62010-04-28 19:28:091133 net_log_.EndEvent(net::NetLog::TYPE_SSL_CONNECT, NULL);
[email protected]7a8de3072010-10-01 16:25:541134 // If we pseudo connected for Snap Start, then we won't have a connect
1135 // callback.
1136 if (user_connect_callback_)
1137 DoConnectCallback(rv);
[email protected]5a05c47a2009-11-02 23:25:191138 }
[email protected]a3ff5e92009-10-13 04:48:061139 LeaveFunction("");
1140}
1141
1142void SSLClientSocketNSS::OnSendComplete(int result) {
1143 EnterFunction(result);
[email protected]45965de2010-02-25 23:23:311144 if (next_handshake_state_ == STATE_HANDSHAKE) {
[email protected]a3ff5e92009-10-13 04:48:061145 // In handshake phase.
1146 OnHandshakeIOComplete(result);
1147 LeaveFunction("");
1148 return;
[email protected]a6eb576292009-06-30 16:19:001149 }
[email protected]a3ff5e92009-10-13 04:48:061150
1151 // OnSendComplete may need to call DoPayloadRead while the renegotiation
1152 // handshake is in progress.
1153 int rv_read = ERR_IO_PENDING;
1154 int rv_write = ERR_IO_PENDING;
1155 bool network_moved;
1156 do {
1157 if (user_read_buf_)
1158 rv_read = DoPayloadRead();
1159 if (user_write_buf_)
1160 rv_write = DoPayloadWrite();
1161 network_moved = DoTransportIO();
1162 } while (rv_read == ERR_IO_PENDING &&
1163 rv_write == ERR_IO_PENDING &&
1164 network_moved);
1165
1166 if (user_read_buf_ && rv_read != ERR_IO_PENDING)
1167 DoReadCallback(rv_read);
1168 if (user_write_buf_ && rv_write != ERR_IO_PENDING)
1169 DoWriteCallback(rv_write);
1170
1171 LeaveFunction("");
1172}
1173
1174void SSLClientSocketNSS::OnRecvComplete(int result) {
1175 EnterFunction(result);
[email protected]45965de2010-02-25 23:23:311176 if (next_handshake_state_ == STATE_HANDSHAKE) {
[email protected]a3ff5e92009-10-13 04:48:061177 // In handshake phase.
1178 OnHandshakeIOComplete(result);
1179 LeaveFunction("");
1180 return;
1181 }
1182
1183 // Network layer received some data, check if client requested to read
[email protected]7a8de3072010-10-01 16:25:541184 // decrypted data or if we're waiting for the first write for Snap Start.
1185 if (!user_read_buf_ || !completed_handshake_) {
[email protected]a3ff5e92009-10-13 04:48:061186 LeaveFunction("");
1187 return;
1188 }
1189
1190 int rv = DoReadLoop(result);
1191 if (rv != ERR_IO_PENDING)
1192 DoReadCallback(rv);
[email protected]e17b4c12008-11-05 22:04:081193 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:581194}
1195
[email protected]ffeb0882009-04-30 21:51:251196// Do network I/O between the given buffer and the given socket.
[email protected]a3ff5e92009-10-13 04:48:061197// Return true if some I/O performed, false otherwise (error or ERR_IO_PENDING)
1198bool SSLClientSocketNSS::DoTransportIO() {
1199 EnterFunction("");
1200 bool network_moved = false;
1201 if (nss_bufs_ != NULL) {
1202 int nsent = BufferSend();
1203 int nreceived = BufferRecv();
1204 network_moved = (nsent > 0 || nreceived >= 0);
1205 }
1206 LeaveFunction(network_moved);
1207 return network_moved;
1208}
1209
[email protected]ffeb0882009-04-30 21:51:251210// Return 0 for EOF,
1211// > 0 for bytes transferred immediately,
1212// < 0 for error (or the non-error ERR_IO_PENDING).
[email protected]b43c97c2008-10-22 19:50:581213int SSLClientSocketNSS::BufferSend(void) {
[email protected]9ae2ee02010-09-08 16:41:141214 if (transport_send_busy_)
1215 return ERR_IO_PENDING;
[email protected]b43c97c2008-10-22 19:50:581216
[email protected]914286d62009-12-10 23:06:441217 EnterFunction("");
[email protected]9ae2ee02010-09-08 16:41:141218 const char* buf1;
1219 const char* buf2;
1220 unsigned int len1, len2;
1221 memio_GetWriteParams(nss_bufs_, &buf1, &len1, &buf2, &len2);
1222 const unsigned int len = len1 + len2;
[email protected]b43c97c2008-10-22 19:50:581223
[email protected]9ae2ee02010-09-08 16:41:141224 if (corked_ && len < kRecvBufferSize / 2)
1225 return 0;
1226
1227 int rv = 0;
1228 if (len) {
[email protected]ad8e04a2010-11-01 04:16:271229 scoped_refptr<IOBuffer> send_buffer(new IOBuffer(len));
[email protected]9ae2ee02010-09-08 16:41:141230 memcpy(send_buffer->data(), buf1, len1);
1231 memcpy(send_buffer->data() + len1, buf2, len2);
1232 rv = transport_->socket()->Write(send_buffer, len,
1233 &buffer_send_callback_);
[email protected]914286d62009-12-10 23:06:441234 if (rv == ERR_IO_PENDING) {
[email protected]b43c97c2008-10-22 19:50:581235 transport_send_busy_ = true;
[email protected]914286d62009-12-10 23:06:441236 } else {
[email protected]b43c97c2008-10-22 19:50:581237 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv));
[email protected]914286d62009-12-10 23:06:441238 }
[email protected]b43c97c2008-10-22 19:50:581239 }
1240
[email protected]9ae2ee02010-09-08 16:41:141241 LeaveFunction(rv);
1242 return rv;
[email protected]b43c97c2008-10-22 19:50:581243}
1244
1245void SSLClientSocketNSS::BufferSendComplete(int result) {
[email protected]e17b4c12008-11-05 22:04:081246 EnterFunction(result);
[email protected]7f7e92392010-10-26 18:29:291247
1248 // In the case of TCP FastOpen, connect is now finished.
1249 if (!peername_initialized_ && UsingTCPFastOpen())
1250 InitializeSSLPeerName();
1251
[email protected]b0735462009-11-04 22:11:261252 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(result));
[email protected]b43c97c2008-10-22 19:50:581253 transport_send_busy_ = false;
[email protected]a3ff5e92009-10-13 04:48:061254 OnSendComplete(result);
[email protected]e17b4c12008-11-05 22:04:081255 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:581256}
1257
1258
1259int SSLClientSocketNSS::BufferRecv(void) {
[email protected]b43c97c2008-10-22 19:50:581260 if (transport_recv_busy_) return ERR_IO_PENDING;
1261
1262 char *buf;
1263 int nb = memio_GetReadParams(nss_bufs_, &buf);
[email protected]e17b4c12008-11-05 22:04:081264 EnterFunction(nb);
[email protected]b43c97c2008-10-22 19:50:581265 int rv;
1266 if (!nb) {
1267 // buffer too full to read into, so no I/O possible at moment
1268 rv = ERR_IO_PENDING;
1269 } else {
[email protected]ffeb0882009-04-30 21:51:251270 recv_buffer_ = new IOBuffer(nb);
[email protected]e60e47a2010-07-14 03:37:181271 rv = transport_->socket()->Read(recv_buffer_, nb, &buffer_recv_callback_);
[email protected]ffeb0882009-04-30 21:51:251272 if (rv == ERR_IO_PENDING) {
[email protected]b43c97c2008-10-22 19:50:581273 transport_recv_busy_ = true;
[email protected]ffeb0882009-04-30 21:51:251274 } else {
1275 if (rv > 0)
1276 memcpy(buf, recv_buffer_->data(), rv);
[email protected]b43c97c2008-10-22 19:50:581277 memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv));
[email protected]ffeb0882009-04-30 21:51:251278 recv_buffer_ = NULL;
1279 }
[email protected]b43c97c2008-10-22 19:50:581280 }
[email protected]e17b4c12008-11-05 22:04:081281 LeaveFunction(rv);
[email protected]b43c97c2008-10-22 19:50:581282 return rv;
1283}
1284
1285void SSLClientSocketNSS::BufferRecvComplete(int result) {
[email protected]e17b4c12008-11-05 22:04:081286 EnterFunction(result);
[email protected]ffeb0882009-04-30 21:51:251287 if (result > 0) {
1288 char *buf;
1289 memio_GetReadParams(nss_bufs_, &buf);
1290 memcpy(buf, recv_buffer_->data(), result);
1291 }
1292 recv_buffer_ = NULL;
[email protected]b0735462009-11-04 22:11:261293 memio_PutReadResult(nss_bufs_, MapErrorToNSS(result));
[email protected]b43c97c2008-10-22 19:50:581294 transport_recv_busy_ = false;
[email protected]a3ff5e92009-10-13 04:48:061295 OnRecvComplete(result);
[email protected]e17b4c12008-11-05 22:04:081296 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:581297}
1298
[email protected]a3ff5e92009-10-13 04:48:061299int SSLClientSocketNSS::DoHandshakeLoop(int last_io_result) {
[email protected]e17b4c12008-11-05 22:04:081300 EnterFunction(last_io_result);
[email protected]b43c97c2008-10-22 19:50:581301 bool network_moved;
1302 int rv = last_io_result;
1303 do {
[email protected]e17b4c12008-11-05 22:04:081304 // Default to STATE_NONE for next state.
[email protected]ea224582008-12-07 20:25:461305 // (This is a quirk carried over from the windows
[email protected]e17b4c12008-11-05 22:04:081306 // implementation. It makes reading the logs a bit harder.)
[email protected]ea224582008-12-07 20:25:461307 // State handlers can and often do call GotoState just
[email protected]e17b4c12008-11-05 22:04:081308 // to stay in the current state.
[email protected]a3ff5e92009-10-13 04:48:061309 State state = next_handshake_state_;
[email protected]e17b4c12008-11-05 22:04:081310 GotoState(STATE_NONE);
[email protected]b43c97c2008-10-22 19:50:581311 switch (state) {
[email protected]e17b4c12008-11-05 22:04:081312 case STATE_NONE:
1313 // we're just pumping data between the buffer and the network
1314 break;
[email protected]7a8de3072010-10-01 16:25:541315 case STATE_SNAP_START_LOAD_INFO:
1316 rv = DoSnapStartLoadInfo();
1317 break;
1318 case STATE_SNAP_START_WAIT_FOR_WRITE:
1319 rv = DoSnapStartWaitForWrite();
1320 break;
[email protected]a3ff5e92009-10-13 04:48:061321 case STATE_HANDSHAKE:
1322 rv = DoHandshake();
[email protected]b43c97c2008-10-22 19:50:581323 break;
[email protected]899c3e92010-08-28 15:53:501324 case STATE_VERIFY_DNSSEC:
1325 rv = DoVerifyDNSSEC(rv);
1326 break;
1327 case STATE_VERIFY_DNSSEC_COMPLETE:
1328 rv = DoVerifyDNSSECComplete(rv);
1329 break;
[email protected]2345cc52009-06-04 09:18:471330 case STATE_VERIFY_CERT:
1331 DCHECK(rv == OK);
1332 rv = DoVerifyCert(rv);
1333 break;
1334 case STATE_VERIFY_CERT_COMPLETE:
1335 rv = DoVerifyCertComplete(rv);
1336 break;
[email protected]b43c97c2008-10-22 19:50:581337 default:
1338 rv = ERR_UNEXPECTED;
[email protected]4e91b5c2010-09-22 01:04:381339 LOG(DFATAL) << "unexpected state " << state;
[email protected]b43c97c2008-10-22 19:50:581340 break;
1341 }
1342
1343 // Do the actual network I/O
[email protected]a3ff5e92009-10-13 04:48:061344 network_moved = DoTransportIO();
[email protected]72d1e592009-03-10 17:39:461345 } while ((rv != ERR_IO_PENDING || network_moved) &&
[email protected]7a8de3072010-10-01 16:25:541346 next_handshake_state_ != STATE_NONE);
[email protected]a3ff5e92009-10-13 04:48:061347 LeaveFunction("");
1348 return rv;
1349}
1350
1351int SSLClientSocketNSS::DoReadLoop(int result) {
1352 EnterFunction("");
1353 DCHECK(completed_handshake_);
1354 DCHECK(next_handshake_state_ == STATE_NONE);
1355
1356 if (result < 0)
1357 return result;
1358
[email protected]4e91b5c2010-09-22 01:04:381359 if (!nss_bufs_) {
1360 LOG(DFATAL) << "!nss_bufs_";
[email protected]7cbc6df12010-10-04 16:25:391361 int rv = ERR_UNEXPECTED;
[email protected]00cd9c42010-11-02 20:15:571362 net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR,
1363 make_scoped_refptr(new SSLErrorParams(rv, 0)));
[email protected]7cbc6df12010-10-04 16:25:391364 return rv;
[email protected]4e91b5c2010-09-22 01:04:381365 }
[email protected]a3ff5e92009-10-13 04:48:061366
1367 bool network_moved;
1368 int rv;
1369 do {
1370 rv = DoPayloadRead();
1371 network_moved = DoTransportIO();
1372 } while (rv == ERR_IO_PENDING && network_moved);
1373
1374 LeaveFunction("");
1375 return rv;
1376}
1377
1378int SSLClientSocketNSS::DoWriteLoop(int result) {
1379 EnterFunction("");
1380 DCHECK(completed_handshake_);
1381 DCHECK(next_handshake_state_ == STATE_NONE);
1382
1383 if (result < 0)
1384 return result;
1385
[email protected]4e91b5c2010-09-22 01:04:381386 if (!nss_bufs_) {
1387 LOG(DFATAL) << "!nss_bufs_";
[email protected]7cbc6df12010-10-04 16:25:391388 int rv = ERR_UNEXPECTED;
[email protected]00cd9c42010-11-02 20:15:571389 net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR,
1390 make_scoped_refptr(new SSLErrorParams(rv, 0)));
[email protected]7cbc6df12010-10-04 16:25:391391 return rv;
[email protected]4e91b5c2010-09-22 01:04:381392 }
[email protected]a3ff5e92009-10-13 04:48:061393
1394 bool network_moved;
1395 int rv;
1396 do {
1397 rv = DoPayloadWrite();
1398 network_moved = DoTransportIO();
1399 } while (rv == ERR_IO_PENDING && network_moved);
1400
[email protected]e17b4c12008-11-05 22:04:081401 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:581402 return rv;
1403}
1404
[email protected]bacff652009-03-31 17:50:331405// static
1406// NSS calls this if an incoming certificate needs to be verified.
[email protected]2345cc52009-06-04 09:18:471407// Do nothing but return SECSuccess.
1408// This is called only in full handshake mode.
1409// Peer certificate is retrieved in HandshakeCallback() later, which is called
1410// in full handshake mode or in resumption handshake mode.
[email protected]bacff652009-03-31 17:50:331411SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg,
1412 PRFileDesc* socket,
1413 PRBool checksig,
1414 PRBool is_server) {
[email protected]9ae2ee02010-09-08 16:41:141415#ifdef SSL_ENABLE_FALSE_START
1416 // In the event that we are False Starting this connection, we wish to send
1417 // out the Finished message and first application data record in the same
1418 // packet. This prevents non-determinism when talking to False Start
1419 // intolerant servers which, otherwise, might see the two messages in
1420 // different reads or not, depending on network conditions.
1421 PRBool false_start = 0;
1422 SECStatus rv = SSL_OptionGet(socket, SSL_ENABLE_FALSE_START, &false_start);
[email protected]79ba2d82010-11-05 14:07:461423 DCHECK_EQ(SECSuccess, rv);
1424
[email protected]9ae2ee02010-09-08 16:41:141425 if (false_start) {
1426 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
[email protected]563cbcc62010-10-11 23:07:521427
1428 // ESET anti-virus is capable of intercepting HTTPS connections on Windows.
1429 // However, it is False Start intolerant and causes the connections to hang
1430 // forever. We detect ESET by the issuer of the leaf certificate and set a
1431 // flag to return a specific error, giving the user instructions for
1432 // reconfiguring ESET.
1433 CERTCertificate* cert = SSL_PeerCertificate(that->nss_fd_);
1434 if (cert) {
1435 char* common_name = CERT_GetCommonName(&cert->issuer);
1436 if (common_name) {
1437 if (strcmp(common_name, "ESET_RootSslCert") == 0)
1438 that->eset_mitm_detected_ = true;
[email protected]081b0942010-12-13 19:34:141439 if (strcmp(common_name,
1440 "ContentWatch Root Certificate Authority") == 0) {
[email protected]79ba2d82010-11-05 14:07:461441 // This is NetNanny. NetNanny are updating their product so we
1442 // silently disable False Start for now.
1443 rv = SSL_OptionSet(socket, SSL_ENABLE_FALSE_START, PR_FALSE);
1444 DCHECK_EQ(SECSuccess, rv);
1445 false_start = 0;
1446 }
[email protected]563cbcc62010-10-11 23:07:521447 PORT_Free(common_name);
1448 }
1449 CERT_DestroyCertificate(cert);
1450 }
[email protected]79ba2d82010-11-05 14:07:461451
1452 if (false_start && !that->handshake_callback_called_) {
1453 that->corked_ = true;
1454 that->uncork_timer_.Start(
1455 base::TimeDelta::FromMilliseconds(kCorkTimeoutMs),
1456 that, &SSLClientSocketNSS::UncorkAfterTimeout);
1457 }
[email protected]9ae2ee02010-09-08 16:41:141458 }
1459#endif
1460
[email protected]2345cc52009-06-04 09:18:471461 // Tell NSS to not verify the certificate.
1462 return SECSuccess;
1463}
1464
[email protected]4a842342010-11-04 16:21:331465#if defined(NSS_PLATFORM_CLIENT_AUTH)
[email protected]2345cc52009-06-04 09:18:471466// static
[email protected]d84b3722009-10-15 21:23:371467// NSS calls this if a client certificate is needed.
[email protected]4a842342010-11-04 16:21:331468SECStatus SSLClientSocketNSS::PlatformClientAuthHandler(
[email protected]d84b3722009-10-15 21:23:371469 void* arg,
1470 PRFileDesc* socket,
1471 CERTDistNames* ca_names,
[email protected]4a842342010-11-04 16:21:331472 CERTCertList** result_certs,
1473 void** result_private_key) {
[email protected]d84b3722009-10-15 21:23:371474 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
1475
1476 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert;
[email protected]1d583612010-03-12 17:47:141477#if defined(OS_WIN)
1478 if (that->ssl_config_.send_client_cert) {
[email protected]4a842342010-11-04 16:21:331479 if (that->ssl_config_.client_cert) {
1480 PCCERT_CONTEXT cert_context =
1481 that->ssl_config_.client_cert->os_cert_handle();
[email protected]b493c0b92010-11-11 05:12:421482 if (VLOG_IS_ON(1)) {
1483 do {
1484 DWORD size_needed = 0;
1485 BOOL got_info = CertGetCertificateContextProperty(
1486 cert_context, CERT_KEY_PROV_INFO_PROP_ID, NULL, &size_needed);
1487 if (!got_info) {
1488 VLOG(1) << "Failed to get key prov info size " << GetLastError();
1489 break;
1490 }
1491 std::vector<BYTE> raw_info(size_needed);
1492 got_info = CertGetCertificateContextProperty(
1493 cert_context, CERT_KEY_PROV_INFO_PROP_ID, &raw_info[0],
1494 &size_needed);
1495 if (!got_info) {
1496 VLOG(1) << "Failed to get key prov info " << GetLastError();
1497 break;
1498 }
1499 PCRYPT_KEY_PROV_INFO info =
1500 reinterpret_cast<PCRYPT_KEY_PROV_INFO>(&raw_info[0]);
1501 VLOG(1) << "Container Name: " << info->pwszContainerName
1502 << "\nProvider Name: " << info->pwszProvName
1503 << "\nProvider Type: " << info->dwProvType
1504 << "\nFlags: " << info->dwFlags
1505 << "\nProvider Param Count: " << info->cProvParam
1506 << "\nKey Specifier: " << info->dwKeySpec;
1507 } while (false);
1508
1509 do {
1510 DWORD size_needed = 0;
1511 BOOL got_identifier = CertGetCertificateContextProperty(
1512 cert_context, CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size_needed);
1513 if (!got_identifier) {
1514 VLOG(1) << "Failed to get key identifier size "
1515 << GetLastError();
1516 break;
1517 }
1518 std::vector<BYTE> raw_id(size_needed);
1519 got_identifier = CertGetCertificateContextProperty(
1520 cert_context, CERT_KEY_IDENTIFIER_PROP_ID, &raw_id[0],
1521 &size_needed);
1522 if (!got_identifier) {
1523 VLOG(1) << "Failed to get key identifier " << GetLastError();
1524 break;
1525 }
1526 VLOG(1) << "Key Identifier: " << base::HexEncode(&raw_id[0],
1527 size_needed);
1528 } while (false);
1529 }
[email protected]4a842342010-11-04 16:21:331530 HCRYPTPROV provider = NULL;
1531 DWORD key_spec = AT_KEYEXCHANGE;
1532 BOOL must_free = FALSE;
1533 BOOL acquired_key = CryptAcquireCertificatePrivateKey(
1534 cert_context,
1535 CRYPT_ACQUIRE_CACHE_FLAG | CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
1536 NULL, &provider, &key_spec, &must_free);
1537 if (acquired_key && provider) {
1538 DCHECK_NE(key_spec, CERT_NCRYPT_KEY_SPEC);
1539
1540 // The certificate cache may have been updated/used, in which case,
1541 // duplicate the existing handle, since NSS will free it when no
1542 // longer in use.
1543 if (!must_free)
1544 CryptContextAddRef(provider, NULL, 0);
1545
1546 SECItem der_cert;
1547 der_cert.type = siDERCertBuffer;
1548 der_cert.data = cert_context->pbCertEncoded;
1549 der_cert.len = cert_context->cbCertEncoded;
1550
1551 // TODO(rsleevi): Error checking for NSS allocation errors.
1552 *result_certs = CERT_NewCertList();
1553 CERTCertDBHandle* db_handle = CERT_GetDefaultCertDB();
1554 CERTCertificate* user_cert = CERT_NewTempCertificate(
1555 db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE);
1556 CERT_AddCertToListTail(*result_certs, user_cert);
1557
1558 // Add the intermediates.
1559 X509Certificate::OSCertHandles intermediates =
1560 that->ssl_config_.client_cert->GetIntermediateCertificates();
1561 for (X509Certificate::OSCertHandles::const_iterator it =
1562 intermediates.begin(); it != intermediates.end(); ++it) {
1563 der_cert.data = (*it)->pbCertEncoded;
1564 der_cert.len = (*it)->cbCertEncoded;
1565
1566 CERTCertificate* intermediate = CERT_NewTempCertificate(
1567 db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE);
1568 CERT_AddCertToListTail(*result_certs, intermediate);
1569 }
1570 // TODO(wtc): |key_spec| should be passed along with |provider|.
1571 *result_private_key = reinterpret_cast<void*>(provider);
1572 return SECSuccess;
1573 }
1574 LOG(WARNING) << "Client cert found without private key";
1575 }
[email protected]1d583612010-03-12 17:47:141576 // Send no client certificate.
1577 return SECFailure;
1578 }
1579
1580 that->client_certs_.clear();
1581
1582 std::vector<CERT_NAME_BLOB> issuer_list(ca_names->nnames);
1583 for (int i = 0; i < ca_names->nnames; ++i) {
1584 issuer_list[i].cbData = ca_names->names[i].len;
1585 issuer_list[i].pbData = ca_names->names[i].data;
1586 }
1587
1588 // Client certificates of the user are in the "MY" system certificate store.
1589 HCERTSTORE my_cert_store = CertOpenSystemStore(NULL, L"MY");
1590 if (!my_cert_store) {
1591 LOG(ERROR) << "Could not open the \"MY\" system certificate store: "
1592 << GetLastError();
1593 return SECFailure;
1594 }
1595
1596 // Enumerate the client certificates.
1597 CERT_CHAIN_FIND_BY_ISSUER_PARA find_by_issuer_para;
1598 memset(&find_by_issuer_para, 0, sizeof(find_by_issuer_para));
1599 find_by_issuer_para.cbSize = sizeof(find_by_issuer_para);
1600 find_by_issuer_para.pszUsageIdentifier = szOID_PKIX_KP_CLIENT_AUTH;
1601 find_by_issuer_para.cIssuer = ca_names->nnames;
1602 find_by_issuer_para.rgIssuer = ca_names->nnames ? &issuer_list[0] : NULL;
[email protected]01640f62010-08-10 19:42:121603 find_by_issuer_para.pfnFindCallback = ClientCertFindCallback;
[email protected]1d583612010-03-12 17:47:141604
1605 PCCERT_CHAIN_CONTEXT chain_context = NULL;
1606
1607 for (;;) {
1608 // Find a certificate chain.
1609 chain_context = CertFindChainInStore(my_cert_store,
1610 X509_ASN_ENCODING,
1611 0,
1612 CERT_CHAIN_FIND_BY_ISSUER,
1613 &find_by_issuer_para,
1614 chain_context);
1615 if (!chain_context) {
1616 DWORD err = GetLastError();
1617 if (err != CRYPT_E_NOT_FOUND)
1618 DLOG(ERROR) << "CertFindChainInStore failed: " << err;
1619 break;
1620 }
1621
1622 // Get the leaf certificate.
1623 PCCERT_CONTEXT cert_context =
1624 chain_context->rgpChain[0]->rgpElement[0]->pCertContext;
1625 // Copy it to our own certificate store, so that we can close the "MY"
1626 // certificate store before returning from this function.
1627 PCCERT_CONTEXT cert_context2;
[email protected]670dca92010-10-26 13:27:091628 BOOL ok = CertAddCertificateContextToStore(X509Certificate::cert_store(),
1629 cert_context,
[email protected]1d583612010-03-12 17:47:141630 CERT_STORE_ADD_USE_EXISTING,
1631 &cert_context2);
1632 if (!ok) {
1633 NOTREACHED();
1634 continue;
1635 }
[email protected]4a842342010-11-04 16:21:331636
1637 // Copy the rest of the chain to our own store as well. Copying the chain
1638 // stops gracefully if an error is encountered, with the partial chain
1639 // being used as the intermediates, rather than failing to consider the
1640 // client certificate.
1641 net::X509Certificate::OSCertHandles intermediates;
1642 for (DWORD i = 1; i < chain_context->rgpChain[0]->cElement; i++) {
1643 PCCERT_CONTEXT intermediate_copy;
1644 ok = CertAddCertificateContextToStore(X509Certificate::cert_store(),
1645 chain_context->rgpChain[0]->rgpElement[i]->pCertContext,
1646 CERT_STORE_ADD_USE_EXISTING, &intermediate_copy);
1647 if (!ok) {
1648 NOTREACHED();
1649 break;
1650 }
1651 intermediates.push_back(intermediate_copy);
1652 }
1653
[email protected]1d583612010-03-12 17:47:141654 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
1655 cert_context2, X509Certificate::SOURCE_LONE_CERT_IMPORT,
[email protected]4a842342010-11-04 16:21:331656 intermediates);
[email protected]1d583612010-03-12 17:47:141657 that->client_certs_.push_back(cert);
[email protected]4a842342010-11-04 16:21:331658
1659 X509Certificate::FreeOSCertHandle(cert_context2);
1660 for (net::X509Certificate::OSCertHandles::iterator it =
1661 intermediates.begin(); it != intermediates.end(); ++it) {
1662 net::X509Certificate::FreeOSCertHandle(*it);
1663 }
[email protected]1d583612010-03-12 17:47:141664 }
1665
1666 BOOL ok = CertCloseStore(my_cert_store, CERT_CLOSE_STORE_CHECK_FLAG);
1667 DCHECK(ok);
1668
1669 // Tell NSS to suspend the client authentication. We will then abort the
1670 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
1671 return SECWouldBlock;
[email protected]3dd6f5e2010-06-01 20:28:031672#elif defined(OS_MACOSX)
[email protected]fd4f139f2010-06-11 17:02:201673 if (that->ssl_config_.send_client_cert) {
[email protected]4a842342010-11-04 16:21:331674 if (that->ssl_config_.client_cert) {
1675 OSStatus os_error = noErr;
1676 SecIdentityRef identity = NULL;
1677 SecKeyRef private_key = NULL;
1678 CFArrayRef chain =
1679 that->ssl_config_.client_cert->CreateClientCertificateChain();
1680 if (chain) {
1681 identity = reinterpret_cast<SecIdentityRef>(
1682 const_cast<void*>(CFArrayGetValueAtIndex(chain, 0)));
1683 }
1684 if (identity)
1685 os_error = SecIdentityCopyPrivateKey(identity, &private_key);
1686
1687 if (chain && identity && os_error == noErr) {
1688 // TODO(rsleevi): Error checking for NSS allocation errors.
1689 *result_certs = CERT_NewCertList();
1690 *result_private_key = reinterpret_cast<void*>(private_key);
1691
1692 for (CFIndex i = 0; i < CFArrayGetCount(chain); ++i) {
1693 CSSM_DATA cert_data;
1694 SecCertificateRef cert_ref;
1695 if (i == 0) {
1696 cert_ref = that->ssl_config_.client_cert->os_cert_handle();
1697 } else {
1698 cert_ref = reinterpret_cast<SecCertificateRef>(
1699 const_cast<void*>(CFArrayGetValueAtIndex(chain, i)));
1700 }
1701 os_error = SecCertificateGetData(cert_ref, &cert_data);
1702 if (os_error != noErr)
1703 break;
1704
1705 SECItem der_cert;
1706 der_cert.type = siDERCertBuffer;
1707 der_cert.data = cert_data.Data;
1708 der_cert.len = cert_data.Length;
1709 CERTCertificate* nss_cert = CERT_NewTempCertificate(
1710 CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE);
1711 CERT_AddCertToListTail(*result_certs, nss_cert);
1712 }
1713 }
1714 if (os_error == noErr) {
1715 CFRelease(chain);
1716 return SECSuccess;
1717 }
1718 LOG(WARNING) << "Client cert found, but could not be used: "
1719 << os_error;
1720 if (*result_certs) {
1721 CERT_DestroyCertList(*result_certs);
1722 *result_certs = NULL;
1723 }
1724 if (*result_private_key)
1725 *result_private_key = NULL;
1726 if (private_key)
1727 CFRelease(private_key);
1728 if (chain)
1729 CFRelease(chain);
1730 }
[email protected]fd4f139f2010-06-11 17:02:201731 // Send no client certificate.
1732 return SECFailure;
1733 }
1734
1735 that->client_certs_.clear();
1736
1737 // First, get the cert issuer names allowed by the server.
1738 std::vector<CertPrincipal> valid_issuers;
1739 int n = ca_names->nnames;
1740 for (int i = 0; i < n; i++) {
1741 // Parse each name into a CertPrincipal object.
1742 CertPrincipal p;
1743 if (p.ParseDistinguishedName(ca_names->names[i].data,
1744 ca_names->names[i].len)) {
1745 valid_issuers.push_back(p);
1746 }
1747 }
1748
1749 // Now get the available client certs whose issuers are allowed by the server.
[email protected]4f4de7e62010-11-12 19:55:271750 X509Certificate::GetSSLClientCertificates(that->host_and_port_.host(),
[email protected]fd4f139f2010-06-11 17:02:201751 valid_issuers,
1752 &that->client_certs_);
1753
1754 // Tell NSS to suspend the client authentication. We will then abort the
1755 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
1756 return SECWouldBlock;
[email protected]1d583612010-03-12 17:47:141757#else
[email protected]4a842342010-11-04 16:21:331758 return SECFailure;
1759#endif
1760}
1761
1762#else // NSS_PLATFORM_CLIENT_AUTH
1763
1764// static
1765// NSS calls this if a client certificate is needed.
1766// Based on Mozilla's NSS_GetClientAuthData.
1767SECStatus SSLClientSocketNSS::ClientAuthHandler(
1768 void* arg,
1769 PRFileDesc* socket,
1770 CERTDistNames* ca_names,
1771 CERTCertificate** result_certificate,
1772 SECKEYPrivateKey** result_private_key) {
1773 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
1774
1775 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert;
[email protected]b8fee152009-10-24 03:39:311776 void* wincx = SSL_RevealPinArg(socket);
1777
[email protected]d84b3722009-10-15 21:23:371778 // Second pass: a client certificate should have been selected.
1779 if (that->ssl_config_.send_client_cert) {
1780 if (that->ssl_config_.client_cert) {
[email protected]701e8692010-08-17 20:00:431781 CERTCertificate* cert = CERT_DupCertificate(
[email protected]d84b3722009-10-15 21:23:371782 that->ssl_config_.client_cert->os_cert_handle());
[email protected]701e8692010-08-17 20:00:431783 SECKEYPrivateKey* privkey = PK11_FindKeyByAnyCert(cert, wincx);
[email protected]d84b3722009-10-15 21:23:371784 if (privkey) {
1785 // TODO(jsorianopastor): We should wait for server certificate
1786 // verification before sending our credentials. See
1787 // http://crbug.com/13934.
1788 *result_certificate = cert;
1789 *result_private_key = privkey;
1790 return SECSuccess;
1791 }
1792 LOG(WARNING) << "Client cert found without private key";
1793 }
1794 // Send no client certificate.
1795 return SECFailure;
1796 }
1797
[email protected]701e8692010-08-17 20:00:431798 // Iterate over all client certificates.
1799 CERTCertList* client_certs = CERT_FindUserCertsByUsage(
1800 CERT_GetDefaultCertDB(), certUsageSSLClient,
1801 PR_FALSE, PR_FALSE, wincx);
1802 if (client_certs) {
1803 for (CERTCertListNode* node = CERT_LIST_HEAD(client_certs);
1804 !CERT_LIST_END(node, client_certs);
1805 node = CERT_LIST_NEXT(node)) {
1806 // Only offer unexpired certificates.
1807 if (CERT_CheckCertValidTimes(node->cert, PR_Now(), PR_TRUE) !=
1808 secCertTimeValid)
[email protected]b8fee152009-10-24 03:39:311809 continue;
[email protected]701e8692010-08-17 20:00:431810 // Filter by issuer.
1811 //
1812 // TODO(davidben): This does a binary comparison of the DER-encoded
1813 // issuers. We should match according to RFC 5280 sec. 7.1. We should find
1814 // an appropriate NSS function or add one if needbe.
1815 if (ca_names->nnames &&
1816 NSS_CmpCertChainWCANames(node->cert, ca_names) != SECSuccess)
1817 continue;
1818 X509Certificate* x509_cert = X509Certificate::CreateFromHandle(
1819 node->cert, X509Certificate::SOURCE_LONE_CERT_IMPORT,
1820 net::X509Certificate::OSCertHandles());
1821 that->client_certs_.push_back(x509_cert);
[email protected]b8fee152009-10-24 03:39:311822 }
[email protected]701e8692010-08-17 20:00:431823 CERT_DestroyCertList(client_certs);
[email protected]b8fee152009-10-24 03:39:311824 }
[email protected]d84b3722009-10-15 21:23:371825
[email protected]f6ee0a012010-03-05 22:00:241826 // Tell NSS to suspend the client authentication. We will then abort the
1827 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
1828 return SECWouldBlock;
[email protected]d84b3722009-10-15 21:23:371829}
[email protected]4a842342010-11-04 16:21:331830#endif // NSS_PLATFORM_CLIENT_AUTH
[email protected]d84b3722009-10-15 21:23:371831
1832// static
[email protected]2345cc52009-06-04 09:18:471833// NSS calls this when handshake is completed.
1834// After the SSL handshake is finished, use CertVerifier to verify
1835// the saved server certificate.
1836void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket,
1837 void* arg) {
[email protected]bacff652009-03-31 17:50:331838 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
1839
[email protected]7a8de3072010-10-01 16:25:541840 that->handshake_callback_called_ = true;
[email protected]39afe642010-04-29 14:55:181841
[email protected]2345cc52009-06-04 09:18:471842 that->UpdateServerCert();
[email protected]757f2e2b2010-10-27 23:28:351843 that->UpdateConnectionStatus();
[email protected]2345cc52009-06-04 09:18:471844}
[email protected]bacff652009-03-31 17:50:331845
[email protected]7a8de3072010-10-01 16:25:541846int SSLClientSocketNSS::DoSnapStartLoadInfo() {
1847 EnterFunction("");
[email protected]7ab5bbd12010-10-19 13:33:211848 int rv = ssl_host_info_->WaitForDataReady(&handshake_io_callback_);
[email protected]09125792010-11-03 23:23:221849 GotoState(STATE_HANDSHAKE);
[email protected]7a8de3072010-10-01 16:25:541850
1851 if (rv == OK) {
[email protected]09125792010-11-03 23:23:221852 if (ssl_host_info_->WaitForCertVerification(NULL) == OK) {
1853 if (LoadSnapStartInfo()) {
1854 pseudo_connected_ = true;
1855 GotoState(STATE_SNAP_START_WAIT_FOR_WRITE);
1856 if (user_connect_callback_)
1857 DoConnectCallback(OK);
1858 }
1859 } else if (!ssl_host_info_->state().server_hello.empty()) {
1860 // A non-empty ServerHello suggests that we would have tried a Snap Start
1861 // connection.
1862 base::TimeTicks now = base::TimeTicks::Now();
1863 const base::TimeDelta duration =
1864 now - ssl_host_info_->verification_start_time();
1865 UMA_HISTOGRAM_TIMES("Net.SSLSnapStartNeededVerificationInMs", duration);
1866 VLOG(1) << "Cannot snap start because verification isn't ready. "
1867 << "Wanted verification after "
1868 << duration.InMilliseconds() << "ms";
[email protected]7a8de3072010-10-01 16:25:541869 }
1870 } else {
1871 DCHECK_EQ(ERR_IO_PENDING, rv);
1872 GotoState(STATE_SNAP_START_LOAD_INFO);
1873 }
1874
1875 LeaveFunction("");
1876 return rv;
1877}
1878
1879int SSLClientSocketNSS::DoSnapStartWaitForWrite() {
1880 EnterFunction("");
1881 // In this state, we're waiting for the first Write call so that we can merge
1882 // it into the Snap Start handshake.
1883 if (!user_write_buf_) {
1884 // We'll lie and say that we're connected in order that someone will call
1885 // Write.
1886 GotoState(STATE_SNAP_START_WAIT_FOR_WRITE);
1887 DCHECK(!user_connect_callback_);
1888 LeaveFunction("");
1889 return ERR_IO_PENDING;
1890 }
1891
1892 // This is the largest Snap Start application data payload that we'll try to
1893 // use. A TCP client can only send three frames of data without an ACK and,
1894 // at 2048 bytes, this leaves some space for the rest of the ClientHello
1895 // (including possible session ticket).
1896 static const int kMaxSnapStartPayloadSize = 2048;
1897
1898 if (user_write_buf_len_ > kMaxSnapStartPayloadSize) {
1899 user_write_buf_len_ = kMaxSnapStartPayloadSize;
1900 // When we complete the handshake and call user_write_callback_ we'll say
1901 // that we only wrote |kMaxSnapStartPayloadSize| bytes. That way the rest
1902 // of the payload will be presented to |Write| again and transmitted as
1903 // normal application data.
1904 }
1905
1906 SECStatus rv = SSL_SetSnapStartApplicationData(
1907 nss_fd_, reinterpret_cast<const unsigned char*>(user_write_buf_->data()),
1908 user_write_buf_len_);
1909 DCHECK_EQ(SECSuccess, rv);
[email protected]7a8de3072010-10-01 16:25:541910
1911 GotoState(STATE_HANDSHAKE);
1912 LeaveFunction("");
1913 return OK;
1914}
1915
[email protected]a3ff5e92009-10-13 04:48:061916int SSLClientSocketNSS::DoHandshake() {
[email protected]2345cc52009-06-04 09:18:471917 EnterFunction("");
1918 int net_error = net::OK;
[email protected]d84b3722009-10-15 21:23:371919 SECStatus rv = SSL_ForceHandshake(nss_fd_);
[email protected]2345cc52009-06-04 09:18:471920
[email protected]d84b3722009-10-15 21:23:371921 if (client_auth_cert_needed_) {
1922 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
[email protected]7cbc6df12010-10-04 16:25:391923 net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR,
[email protected]00cd9c42010-11-02 20:15:571924 make_scoped_refptr(new SSLErrorParams(net_error, 0)));
[email protected]d84b3722009-10-15 21:23:371925 // If the handshake already succeeded (because the server requests but
1926 // doesn't require a client cert), we need to invalidate the SSL session
1927 // so that we won't try to resume the non-client-authenticated session in
1928 // the next handshake. This will cause the server to ask for a client
1929 // cert again.
1930 if (rv == SECSuccess && SSL_InvalidateSession(nss_fd_) != SECSuccess) {
1931 LOG(WARNING) << "Couldn't invalidate SSL session: " << PR_GetError();
1932 }
1933 } else if (rv == SECSuccess) {
[email protected]39afe642010-04-29 14:55:181934 if (handshake_callback_called_) {
[email protected]563cbcc62010-10-11 23:07:521935 if (eset_mitm_detected_) {
1936 net_error = ERR_ESET_ANTI_VIRUS_SSL_INTERCEPTION;
[email protected]7a8de3072010-10-01 16:25:541937 } else {
[email protected]3b1d3db2010-10-28 16:39:401938 // We need to see if the predicted certificate chain (in
1939 // |ssl_host_info_->state().certs) matches the actual certificate chain
1940 // before we call SaveSnapStartInfo, as that will update
1941 // |ssl_host_info_|.
1942 if (ssl_host_info_.get() && !ssl_host_info_->state().certs.empty()) {
1943 PeerCertificateChain certs(nss_fd_);
1944 const SSLHostInfo::State& state = ssl_host_info_->state();
1945 predicted_cert_chain_correct_ = certs.size() == state.certs.size();
1946 if (predicted_cert_chain_correct_) {
1947 for (unsigned i = 0; i < certs.size(); i++) {
1948 if (certs[i]->derCert.len != state.certs[i].size() ||
1949 memcmp(certs[i]->derCert.data, state.certs[i].data(),
1950 certs[i]->derCert.len) != 0) {
1951 predicted_cert_chain_correct_ = false;
1952 break;
1953 }
1954 }
1955 }
1956 }
1957
[email protected]563cbcc62010-10-11 23:07:521958 SaveSnapStartInfo();
[email protected]b30a3f52010-10-16 01:05:461959 // SSL handshake is completed. It's possible that we mispredicted the
1960 // NPN agreed protocol. In this case, we've just sent a request in the
1961 // wrong protocol! The higher levels of this network stack aren't
1962 // prepared for switching the protocol like that so we make up an error
1963 // and rely on the fact that the request will be retried.
[email protected]563cbcc62010-10-11 23:07:521964 if (IsNPNProtocolMispredicted()) {
[email protected]4f4de7e62010-11-12 19:55:271965 LOG(WARNING) << "Mispredicted NPN protocol for "
1966 << host_and_port_.ToString();
[email protected]563cbcc62010-10-11 23:07:521967 net_error = ERR_SSL_SNAP_START_NPN_MISPREDICTION;
1968 } else {
1969 // Let's verify the certificate.
1970 GotoState(STATE_VERIFY_DNSSEC);
1971 }
[email protected]7a8de3072010-10-01 16:25:541972 }
[email protected]39afe642010-04-29 14:55:181973 // Done!
1974 } else {
[email protected]e3ad1a8f12010-10-06 18:21:171975 // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=562434 -
[email protected]39afe642010-04-29 14:55:181976 // SSL_ForceHandshake returned SECSuccess prematurely.
1977 rv = SECFailure;
1978 net_error = ERR_SSL_PROTOCOL_ERROR;
[email protected]7cbc6df12010-10-04 16:25:391979 net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR,
[email protected]00cd9c42010-11-02 20:15:571980 make_scoped_refptr(new SSLErrorParams(net_error, 0)));
[email protected]39afe642010-04-29 14:55:181981 }
[email protected]2345cc52009-06-04 09:18:471982 } else {
1983 PRErrorCode prerr = PR_GetError();
[email protected]f61c3972010-12-23 09:54:151984 net_error = MapNSSHandshakeError(prerr);
[email protected]2345cc52009-06-04 09:18:471985
1986 // If not done, stay in this state
1987 if (net_error == ERR_IO_PENDING) {
[email protected]a3ff5e92009-10-13 04:48:061988 GotoState(STATE_HANDSHAKE);
[email protected]2345cc52009-06-04 09:18:471989 } else {
1990 LOG(ERROR) << "handshake failed; NSS error code " << prerr
1991 << ", net_error " << net_error;
[email protected]00cd9c42010-11-02 20:15:571992 net_log_.AddEvent(
1993 NetLog::TYPE_SSL_HANDSHAKE_ERROR,
1994 make_scoped_refptr(new SSLErrorParams(net_error, prerr)));
[email protected]2345cc52009-06-04 09:18:471995 }
1996 }
1997
1998 LeaveFunction("");
1999 return net_error;
2000}
2001
[email protected]899c3e92010-08-28 15:53:502002// DNSValidationResult enumerates the possible outcomes from processing a
2003// set of DNS records.
2004enum DNSValidationResult {
[email protected]4e91b5c2010-09-22 01:04:382005 DNSVR_SUCCESS, // the cert is immediately acceptable.
2006 DNSVR_FAILURE, // the cert is unconditionally rejected.
2007 DNSVR_CONTINUE, // perform CA validation as usual.
[email protected]899c3e92010-08-28 15:53:502008};
2009
2010// VerifyTXTRecords processes the RRDATA for a number of DNS TXT records and
2011// checks them against the given certificate.
2012// dnssec: if true then the TXT records are DNSSEC validated. In this case,
2013// DNSVR_SUCCESS may be returned.
2014// server_cert_nss: the certificate to validate
2015// rrdatas: the TXT records for the current domain.
2016static DNSValidationResult VerifyTXTRecords(
2017 bool dnssec,
2018 CERTCertificate* server_cert_nss,
2019 const std::vector<base::StringPiece>& rrdatas) {
2020 bool found_well_formed_record = false;
2021 bool matched_record = false;
2022
2023 for (std::vector<base::StringPiece>::const_iterator
2024 i = rrdatas.begin(); i != rrdatas.end(); ++i) {
2025 std::map<std::string, std::string> m(
2026 DNSSECChainVerifier::ParseTLSTXTRecord(*i));
2027 if (m.empty())
2028 continue;
2029
2030 std::map<std::string, std::string>::const_iterator j;
2031 j = m.find("v");
2032 if (j == m.end() || j->second != "tls1")
2033 continue;
2034
2035 j = m.find("ha");
2036
2037 HASH_HashType hash_algorithm;
2038 unsigned hash_length;
2039 if (j == m.end() || j->second == "sha1") {
2040 hash_algorithm = HASH_AlgSHA1;
2041 hash_length = SHA1_LENGTH;
2042 } else if (j->second == "sha256") {
2043 hash_algorithm = HASH_AlgSHA256;
2044 hash_length = SHA256_LENGTH;
2045 } else {
2046 continue;
2047 }
2048
2049 j = m.find("h");
2050 if (j == m.end())
2051 continue;
2052
2053 std::vector<uint8> given_hash;
2054 if (!base::HexStringToBytes(j->second, &given_hash))
2055 continue;
2056
2057 if (given_hash.size() != hash_length)
2058 continue;
2059
2060 uint8 calculated_hash[SHA256_LENGTH]; // SHA256 is the largest.
2061 SECStatus rv;
2062
2063 j = m.find("hr");
[email protected]b40f05a2010-09-09 20:13:232064 if (j == m.end() || j->second == "pubkey") {
[email protected]899c3e92010-08-28 15:53:502065 rv = HASH_HashBuf(hash_algorithm, calculated_hash,
2066 server_cert_nss->derPublicKey.data,
2067 server_cert_nss->derPublicKey.len);
[email protected]b40f05a2010-09-09 20:13:232068 } else if (j->second == "cert") {
2069 rv = HASH_HashBuf(hash_algorithm, calculated_hash,
2070 server_cert_nss->derCert.data,
2071 server_cert_nss->derCert.len);
[email protected]899c3e92010-08-28 15:53:502072 } else {
2073 continue;
2074 }
2075
2076 if (rv != SECSuccess)
2077 NOTREACHED();
2078
2079 found_well_formed_record = true;
2080
2081 if (memcmp(calculated_hash, &given_hash[0], hash_length) == 0) {
2082 matched_record = true;
2083 if (dnssec)
2084 return DNSVR_SUCCESS;
2085 }
2086 }
2087
2088 if (found_well_formed_record && !matched_record)
2089 return DNSVR_FAILURE;
2090
2091 return DNSVR_CONTINUE;
2092}
2093
2094
[email protected]b24713592010-08-11 19:50:022095// CheckDNSSECChain tries to validate a DNSSEC chain embedded in
2096// |server_cert_nss_|. It returns true iff a chain is found that proves the
[email protected]899c3e92010-08-28 15:53:502097// value of a TXT record that contains a valid public key fingerprint.
2098static DNSValidationResult CheckDNSSECChain(
2099 const std::string& hostname,
2100 CERTCertificate* server_cert_nss) {
2101 if (!server_cert_nss)
2102 return DNSVR_CONTINUE;
[email protected]b24713592010-08-11 19:50:022103
[email protected]b24713592010-08-11 19:50:022104 // CERT_FindCertExtensionByOID isn't exported so we have to install an OID,
2105 // get a tag for it and find the extension by using that tag.
2106 static SECOidTag dnssec_chain_tag;
2107 static bool dnssec_chain_tag_valid;
2108 if (!dnssec_chain_tag_valid) {
2109 // It's harmless if multiple threads enter this block concurrently.
2110 static const uint8 kDNSSECChainOID[] =
[email protected]b736e502010-10-14 18:23:542111 // 1.3.6.1.4.1.11129.2.1.4
2112 // (iso.org.dod.internet.private.enterprises.google.googleSecurity.
2113 // certificateExtensions.dnssecEmbeddedChain)
2114 {0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x01, 0x04};
[email protected]b24713592010-08-11 19:50:022115 SECOidData oid_data;
2116 memset(&oid_data, 0, sizeof(oid_data));
2117 oid_data.oid.data = const_cast<uint8*>(kDNSSECChainOID);
2118 oid_data.oid.len = sizeof(kDNSSECChainOID);
2119 oid_data.desc = "DNSSEC chain";
2120 oid_data.supportedExtension = SUPPORTED_CERT_EXTENSION;
2121 dnssec_chain_tag = SECOID_AddEntry(&oid_data);
2122 DCHECK_NE(SEC_OID_UNKNOWN, dnssec_chain_tag);
2123 dnssec_chain_tag_valid = true;
2124 }
2125
2126 SECItem dnssec_embedded_chain;
[email protected]899c3e92010-08-28 15:53:502127 SECStatus rv = CERT_FindCertExtension(server_cert_nss,
[email protected]b24713592010-08-11 19:50:022128 dnssec_chain_tag, &dnssec_embedded_chain);
2129 if (rv != SECSuccess)
[email protected]899c3e92010-08-28 15:53:502130 return DNSVR_CONTINUE;
[email protected]b24713592010-08-11 19:50:022131
2132 base::StringPiece chain(
2133 reinterpret_cast<char*>(dnssec_embedded_chain.data),
2134 dnssec_embedded_chain.len);
2135 std::string dns_hostname;
[email protected]899c3e92010-08-28 15:53:502136 if (!DNSDomainFromDot(hostname, &dns_hostname))
2137 return DNSVR_CONTINUE;
[email protected]b24713592010-08-11 19:50:022138 DNSSECChainVerifier verifier(dns_hostname, chain);
2139 DNSSECChainVerifier::Error err = verifier.Verify();
2140 if (err != DNSSECChainVerifier::OK) {
2141 LOG(ERROR) << "DNSSEC chain verification failed: " << err;
[email protected]899c3e92010-08-28 15:53:502142 return DNSVR_CONTINUE;
[email protected]b24713592010-08-11 19:50:022143 }
2144
[email protected]899c3e92010-08-28 15:53:502145 if (verifier.rrtype() != kDNS_TXT)
2146 return DNSVR_CONTINUE;
[email protected]b24713592010-08-11 19:50:022147
[email protected]899c3e92010-08-28 15:53:502148 DNSValidationResult r = VerifyTXTRecords(
2149 true /* DNSSEC verified */, server_cert_nss, verifier.rrdatas());
2150 SECITEM_FreeItem(&dnssec_embedded_chain, PR_FALSE);
2151 return r;
2152}
[email protected]b24713592010-08-11 19:50:022153
[email protected]899c3e92010-08-28 15:53:502154int SSLClientSocketNSS::DoVerifyDNSSEC(int result) {
[email protected]345c613b2010-11-22 19:33:182155 if (ssl_config_.dns_cert_provenance_checking_enabled &&
2156 dns_cert_checker_) {
2157 PeerCertificateChain certs(nss_fd_);
2158 dns_cert_checker_->DoAsyncVerification(
2159 host_and_port_.host(), certs.AsStringPieceVector());
2160 }
2161
[email protected]899c3e92010-08-28 15:53:502162 if (ssl_config_.dnssec_enabled) {
[email protected]4f4de7e62010-11-12 19:55:272163 DNSValidationResult r = CheckDNSSECChain(host_and_port_.host(),
2164 server_cert_nss_);
[email protected]899c3e92010-08-28 15:53:502165 if (r == DNSVR_SUCCESS) {
[email protected]3b1d3db2010-10-28 16:39:402166 local_server_cert_verify_result_.cert_status |= CERT_STATUS_IS_DNSSEC;
2167 server_cert_verify_result_ = &local_server_cert_verify_result_;
[email protected]899c3e92010-08-28 15:53:502168 GotoState(STATE_VERIFY_CERT_COMPLETE);
2169 return OK;
[email protected]b24713592010-08-11 19:50:022170 }
2171 }
2172
[email protected]899c3e92010-08-28 15:53:502173 if (dnssec_provider_ == NULL) {
2174 GotoState(STATE_VERIFY_CERT);
2175 return OK;
2176 }
2177
2178 GotoState(STATE_VERIFY_DNSSEC_COMPLETE);
2179 RRResponse* response;
2180 dnssec_wait_start_time_ = base::Time::Now();
2181 return dnssec_provider_->GetDNSSECRecords(&response, &handshake_io_callback_);
2182}
2183
2184int SSLClientSocketNSS::DoVerifyDNSSECComplete(int result) {
2185 RRResponse* response;
2186 int err = dnssec_provider_->GetDNSSECRecords(&response, NULL);
2187 DCHECK_EQ(err, OK);
2188
2189 const base::TimeDelta elapsed = base::Time::Now() - dnssec_wait_start_time_;
2190 HISTOGRAM_TIMES("Net.DNSSECWaitTime", elapsed);
2191
2192 GotoState(STATE_VERIFY_CERT);
2193 if (!response || response->rrdatas.empty())
2194 return OK;
2195
2196 std::vector<base::StringPiece> records;
2197 records.resize(response->rrdatas.size());
2198 for (unsigned i = 0; i < response->rrdatas.size(); i++)
2199 records[i] = base::StringPiece(response->rrdatas[i]);
2200 DNSValidationResult r =
2201 VerifyTXTRecords(response->dnssec, server_cert_nss_, records);
2202
2203 if (!ssl_config_.dnssec_enabled) {
2204 // If DNSSEC is not enabled we don't take any action based on the result,
2205 // except to record the latency, above.
[email protected]899c3e92010-08-28 15:53:502206 return OK;
2207 }
2208
2209 switch (r) {
2210 case DNSVR_FAILURE:
2211 GotoState(STATE_VERIFY_CERT_COMPLETE);
[email protected]3b1d3db2010-10-28 16:39:402212 local_server_cert_verify_result_.cert_status |= CERT_STATUS_NOT_IN_DNS;
2213 server_cert_verify_result_ = &local_server_cert_verify_result_;
[email protected]899c3e92010-08-28 15:53:502214 return ERR_CERT_NOT_IN_DNS;
2215 case DNSVR_CONTINUE:
2216 GotoState(STATE_VERIFY_CERT);
2217 break;
2218 case DNSVR_SUCCESS:
[email protected]3b1d3db2010-10-28 16:39:402219 local_server_cert_verify_result_.cert_status |= CERT_STATUS_IS_DNSSEC;
2220 server_cert_verify_result_ = &local_server_cert_verify_result_;
[email protected]899c3e92010-08-28 15:53:502221 GotoState(STATE_VERIFY_CERT_COMPLETE);
2222 break;
2223 default:
2224 NOTREACHED();
2225 GotoState(STATE_VERIFY_CERT);
2226 }
2227
2228 return OK;
[email protected]b24713592010-08-11 19:50:022229}
2230
[email protected]2345cc52009-06-04 09:18:472231int SSLClientSocketNSS::DoVerifyCert(int result) {
2232 DCHECK(server_cert_);
[email protected]a89eda42010-02-18 01:45:392233
[email protected]3b1d3db2010-10-28 16:39:402234 GotoState(STATE_VERIFY_CERT_COMPLETE);
[email protected]081b0942010-12-13 19:34:142235 start_cert_verification_time_ = base::TimeTicks::Now();
[email protected]3b1d3db2010-10-28 16:39:402236
2237 if (ssl_host_info_.get() && !ssl_host_info_->state().certs.empty() &&
2238 predicted_cert_chain_correct_) {
2239 // If the SSLHostInfo had a prediction for the certificate chain of this
2240 // server then it will have optimistically started a verification of that
2241 // chain. So, if the prediction was correct, we should wait for that
2242 // verification to finish rather than start our own.
[email protected]09125792010-11-03 23:23:222243 net_log_.AddEvent(NetLog::TYPE_SSL_VERIFICATION_MERGED, NULL);
2244 UMA_HISTOGRAM_ENUMERATION("Net.SSLVerificationMerged", 1 /* true */, 2);
[email protected]2bbe2d52010-12-15 16:12:412245 base::TimeTicks end_time = ssl_host_info_->verification_end_time();
2246 if (end_time.is_null())
2247 end_time = base::TimeTicks::Now();
[email protected]09125792010-11-03 23:23:222248 UMA_HISTOGRAM_TIMES("Net.SSLVerificationMergedMsSaved",
[email protected]2bbe2d52010-12-15 16:12:412249 end_time - ssl_host_info_->verification_start_time());
[email protected]3b1d3db2010-10-28 16:39:402250 server_cert_verify_result_ = &ssl_host_info_->cert_verify_result();
2251 return ssl_host_info_->WaitForCertVerification(&handshake_io_callback_);
[email protected]09125792010-11-03 23:23:222252 } else {
2253 UMA_HISTOGRAM_ENUMERATION("Net.SSLVerificationMerged", 0 /* false */, 2);
[email protected]3b1d3db2010-10-28 16:39:402254 }
2255
2256 int flags = 0;
[email protected]dd681aa2010-07-26 20:35:182257 if (ssl_config_.rev_checking_enabled)
[email protected]f6555ad2009-06-23 06:35:052258 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED;
2259 if (ssl_config_.verify_ev_cert)
2260 flags |= X509Certificate::VERIFY_EV_CERT;
[email protected]822581d2010-12-16 17:27:152261 verifier_.reset(new SingleRequestCertVerifier(cert_verifier_));
[email protected]3b1d3db2010-10-28 16:39:402262 server_cert_verify_result_ = &local_server_cert_verify_result_;
[email protected]4f4de7e62010-11-12 19:55:272263 return verifier_->Verify(server_cert_, host_and_port_.host(), flags,
[email protected]3b1d3db2010-10-28 16:39:402264 &local_server_cert_verify_result_,
[email protected]a3ff5e92009-10-13 04:48:062265 &handshake_io_callback_);
[email protected]2345cc52009-06-04 09:18:472266}
2267
2268// Derived from AuthCertificateCallback() in
2269// mozilla/source/security/manager/ssl/src/nsNSSCallbacks.cpp.
2270int SSLClientSocketNSS::DoVerifyCertComplete(int result) {
[email protected]92d9cad2009-06-25 23:40:242271 verifier_.reset();
2272
[email protected]fd348122010-12-16 22:17:352273
[email protected]081b0942010-12-13 19:34:142274 if (!start_cert_verification_time_.is_null()) {
2275 base::TimeDelta verify_time =
2276 base::TimeTicks::Now() - start_cert_verification_time_;
2277 if (result == OK)
2278 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTime", verify_time);
2279 else
2280 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTimeError", verify_time);
2281 }
2282
[email protected]4feca4b2010-10-28 16:50:322283 // We used to remember the intermediate CA certs in the NSS database
2284 // persistently. However, NSS opens a connection to the SQLite database
2285 // during NSS initialization and doesn't close the connection until NSS
2286 // shuts down. If the file system where the database resides is gone,
2287 // the database connection goes bad. What's worse, the connection won't
2288 // recover when the file system comes back. Until this NSS or SQLite bug
2289 // is fixed, we need to avoid using the NSS database for non-essential
2290 // purposes. See https://bugzilla.mozilla.org/show_bug.cgi?id=508081 and
2291 // http://crbug.com/15630 for more info.
[email protected]bf0136d2009-05-29 05:55:042292
[email protected]2345cc52009-06-04 09:18:472293 // If we have been explicitly told to accept this certificate, override the
2294 // result of verifier_.Verify.
2295 // Eventually, we should cache the cert verification results so that we don't
2296 // need to call verifier_.Verify repeatedly. But for now we need to do this.
[email protected]127017872009-08-13 17:54:422297 // Alternatively, we could use the cert's status that we stored along with
2298 // the cert in the allowed_bad_certs vector.
[email protected]2345cc52009-06-04 09:18:472299 if (IsCertificateError(result) &&
[email protected]127017872009-08-13 17:54:422300 ssl_config_.IsAllowedBadCert(server_cert_)) {
[email protected]b30a3f52010-10-16 01:05:462301 VLOG(1) << "accepting bad SSL certificate, as user told us to";
[email protected]2345cc52009-06-04 09:18:472302 result = OK;
[email protected]b43c97c2008-10-22 19:50:582303 }
[email protected]ea224582008-12-07 20:25:462304
[email protected]757f2e2b2010-10-27 23:28:352305 if (result == OK)
2306 LogConnectionTypeMetrics();
2307
[email protected]2345cc52009-06-04 09:18:472308 completed_handshake_ = true;
[email protected]7a8de3072010-10-01 16:25:542309
[email protected]ff730e52010-11-03 19:46:242310 // If we merged a Write call into the handshake we need to make the
[email protected]7a8de3072010-10-01 16:25:542311 // callback now.
2312 if (user_write_callback_) {
2313 corked_ = false;
[email protected]ff730e52010-11-03 19:46:242314 if (result != OK) {
2315 DoWriteCallback(result);
2316 } else {
2317 SSLSnapStartResult snap_start_type;
2318 SECStatus rv = SSL_GetSnapStartResult(nss_fd_, &snap_start_type);
2319 DCHECK_EQ(rv, SECSuccess);
2320 DCHECK_NE(snap_start_type, SSL_SNAP_START_NONE);
2321 if (snap_start_type == SSL_SNAP_START_RECOVERY ||
2322 snap_start_type == SSL_SNAP_START_RESUME_RECOVERY) {
2323 // If we mispredicted the server's handshake then Snap Start will have
2324 // triggered a recovery mode. The misprediction could have been caused
2325 // by the server having a different certificate so the application data
2326 // wasn't resent. Now that we have verified the certificate, we need to
2327 // resend the application data.
2328 int bytes_written = DoPayloadWrite();
2329 if (bytes_written != ERR_IO_PENDING)
2330 DoWriteCallback(bytes_written);
2331 } else {
2332 DoWriteCallback(user_write_buf_len_);
2333 }
2334 }
[email protected]7a8de3072010-10-01 16:25:542335 }
2336
[email protected]09125792010-11-03 23:23:222337 if (user_read_callback_) {
2338 int rv = DoReadLoop(OK);
2339 if (rv != ERR_IO_PENDING)
2340 DoReadCallback(rv);
2341 }
2342
[email protected]a3ff5e92009-10-13 04:48:062343 // Exit DoHandshakeLoop and return the result to the caller to Connect.
2344 DCHECK(next_handshake_state_ == STATE_NONE);
[email protected]2345cc52009-06-04 09:18:472345 return result;
[email protected]b43c97c2008-10-22 19:50:582346}
[email protected]ea224582008-12-07 20:25:462347
[email protected]b43c97c2008-10-22 19:50:582348int SSLClientSocketNSS::DoPayloadRead() {
[email protected]a3ff5e92009-10-13 04:48:062349 EnterFunction(user_read_buf_len_);
2350 DCHECK(user_read_buf_);
[email protected]1d583612010-03-12 17:47:142351 DCHECK_GT(user_read_buf_len_, 0);
[email protected]a3ff5e92009-10-13 04:48:062352 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_);
[email protected]d84b3722009-10-15 21:23:372353 if (client_auth_cert_needed_) {
2354 // We don't need to invalidate the non-client-authenticated SSL session
2355 // because the server will renegotiate anyway.
2356 LeaveFunction("");
[email protected]7cbc6df12010-10-04 16:25:392357 rv = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
2358 net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR,
[email protected]00cd9c42010-11-02 20:15:572359 make_scoped_refptr(new SSLErrorParams(rv, 0)));
[email protected]7cbc6df12010-10-04 16:25:392360 return rv;
[email protected]d84b3722009-10-15 21:23:372361 }
[email protected]e17b4c12008-11-05 22:04:082362 if (rv >= 0) {
[email protected]a3ff5e92009-10-13 04:48:062363 LogData(user_read_buf_->data(), rv);
[email protected]e17b4c12008-11-05 22:04:082364 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:582365 return rv;
[email protected]e17b4c12008-11-05 22:04:082366 }
[email protected]b43c97c2008-10-22 19:50:582367 PRErrorCode prerr = PR_GetError();
2368 if (prerr == PR_WOULD_BLOCK_ERROR) {
[email protected]e17b4c12008-11-05 22:04:082369 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:582370 return ERR_IO_PENDING;
2371 }
[email protected]e17b4c12008-11-05 22:04:082372 LeaveFunction("");
[email protected]f61c3972010-12-23 09:54:152373 rv = MapNSSError(prerr);
[email protected]00cd9c42010-11-02 20:15:572374 net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR,
2375 make_scoped_refptr(new SSLErrorParams(rv, prerr)));
[email protected]7cbc6df12010-10-04 16:25:392376 return rv;
[email protected]b43c97c2008-10-22 19:50:582377}
2378
2379int SSLClientSocketNSS::DoPayloadWrite() {
[email protected]a3ff5e92009-10-13 04:48:062380 EnterFunction(user_write_buf_len_);
2381 DCHECK(user_write_buf_);
2382 int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_);
[email protected]e17b4c12008-11-05 22:04:082383 if (rv >= 0) {
[email protected]a3ff5e92009-10-13 04:48:062384 LogData(user_write_buf_->data(), rv);
[email protected]e17b4c12008-11-05 22:04:082385 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:582386 return rv;
[email protected]e17b4c12008-11-05 22:04:082387 }
[email protected]b43c97c2008-10-22 19:50:582388 PRErrorCode prerr = PR_GetError();
2389 if (prerr == PR_WOULD_BLOCK_ERROR) {
[email protected]4d3040f42010-04-14 02:40:202390 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:582391 return ERR_IO_PENDING;
2392 }
[email protected]e17b4c12008-11-05 22:04:082393 LeaveFunction("");
[email protected]f61c3972010-12-23 09:54:152394 rv = MapNSSError(prerr);
[email protected]7cbc6df12010-10-04 16:25:392395 net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR,
[email protected]00cd9c42010-11-02 20:15:572396 make_scoped_refptr(new SSLErrorParams(rv, prerr)));
[email protected]7cbc6df12010-10-04 16:25:392397 return rv;
[email protected]b43c97c2008-10-22 19:50:582398}
2399
[email protected]757f2e2b2010-10-27 23:28:352400void SSLClientSocketNSS::LogConnectionTypeMetrics() const {
2401 UpdateConnectionTypeHistograms(CONNECTION_SSL);
[email protected]3b1d3db2010-10-28 16:39:402402 if (server_cert_verify_result_->has_md5)
[email protected]757f2e2b2010-10-27 23:28:352403 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5);
[email protected]3b1d3db2010-10-28 16:39:402404 if (server_cert_verify_result_->has_md2)
[email protected]757f2e2b2010-10-27 23:28:352405 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2);
[email protected]3b1d3db2010-10-28 16:39:402406 if (server_cert_verify_result_->has_md4)
[email protected]757f2e2b2010-10-27 23:28:352407 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD4);
[email protected]3b1d3db2010-10-28 16:39:402408 if (server_cert_verify_result_->has_md5_ca)
[email protected]757f2e2b2010-10-27 23:28:352409 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5_CA);
[email protected]3b1d3db2010-10-28 16:39:402410 if (server_cert_verify_result_->has_md2_ca)
[email protected]757f2e2b2010-10-27 23:28:352411 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2_CA);
2412 int ssl_version = SSLConnectionStatusToVersion(ssl_connection_status_);
2413 switch (ssl_version) {
2414 case SSL_CONNECTION_VERSION_SSL2:
2415 UpdateConnectionTypeHistograms(CONNECTION_SSL_SSL2);
2416 break;
2417 case SSL_CONNECTION_VERSION_SSL3:
2418 UpdateConnectionTypeHistograms(CONNECTION_SSL_SSL3);
2419 break;
2420 case SSL_CONNECTION_VERSION_TLS1:
2421 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1);
2422 break;
2423 case SSL_CONNECTION_VERSION_TLS1_1:
2424 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_1);
2425 break;
2426 case SSL_CONNECTION_VERSION_TLS1_2:
2427 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_2);
2428 break;
2429 };
2430}
2431
[email protected]b43c97c2008-10-22 19:50:582432} // namespace net