blob: 0a81a4852f0dd7aaa86a9446a28404931499ae9b [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]829296f2010-01-27 02:58:0350#if defined(USE_SYSTEM_SSL)
51#include <dlfcn.h>
52#endif
[email protected]bf0136d2009-05-29 05:55:0453#include <certdb.h>
[email protected]d84b3722009-10-15 21:23:3754#include <keyhi.h>
[email protected]b43c97c2008-10-22 19:50:5855#include <nspr.h>
56#include <nss.h>
[email protected]ea224582008-12-07 20:25:4657#include <secerr.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]b43c97c2008-10-22 19:50:5860#include <pk11pub.h>
[email protected]b43c97c2008-10-22 19:50:5861
[email protected]bacff652009-03-31 17:50:3362#include "base/compiler_specific.h"
[email protected]fc7de492010-07-12 14:49:0463#include "base/histogram.h"
[email protected]b43c97c2008-10-22 19:50:5864#include "base/logging.h"
[email protected]1b1a264a2010-01-14 22:36:3565#include "base/nss_util.h"
[email protected]829296f2010-01-27 02:58:0366#include "base/singleton.h"
[email protected]b43c97c2008-10-22 19:50:5867#include "base/string_util.h"
[email protected]ac9eec62010-02-20 18:50:3868#include "net/base/address_list.h"
[email protected]92d9cad2009-06-25 23:40:2469#include "net/base/cert_verifier.h"
[email protected]597cf6e2009-05-29 09:43:2670#include "net/base/io_buffer.h"
[email protected]9e743cd2010-03-16 07:03:5371#include "net/base/net_log.h"
[email protected]b43c97c2008-10-22 19:50:5872#include "net/base/net_errors.h"
[email protected]d84b3722009-10-15 21:23:3773#include "net/base/ssl_cert_request_info.h"
[email protected]fc7de492010-07-12 14:49:0474#include "net/base/ssl_connection_status_flags.h"
[email protected]b43c97c2008-10-22 19:50:5875#include "net/base/ssl_info.h"
[email protected]ac9eec62010-02-20 18:50:3876#include "net/base/sys_addrinfo.h"
[email protected]2a0c0a52009-07-31 07:51:3277#include "net/ocsp/nss_ocsp.h"
[email protected]e60e47a2010-07-14 03:37:1878#include "net/socket/client_socket_handle.h"
[email protected]b43c97c2008-10-22 19:50:5879
80static const int kRecvBufferSize = 4096;
81
[email protected]b43c97c2008-10-22 19:50:5882namespace net {
83
[email protected]e17b4c12008-11-05 22:04:0884// State machines are easier to debug if you log state transitions.
85// Enable these if you want to see what's going on.
86#if 1
87#define EnterFunction(x)
88#define LeaveFunction(x)
[email protected]a3ff5e92009-10-13 04:48:0689#define GotoState(s) next_handshake_state_ = s
[email protected]ea224582008-12-07 20:25:4690#define LogData(s, len)
[email protected]e17b4c12008-11-05 22:04:0891#else
92#define EnterFunction(x) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \
[email protected]a3ff5e92009-10-13 04:48:0693 " enter " << x << \
94 "; next_handshake_state " << next_handshake_state_
[email protected]e17b4c12008-11-05 22:04:0895#define LeaveFunction(x) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \
[email protected]a3ff5e92009-10-13 04:48:0696 " leave " << x << \
97 "; next_handshake_state " << next_handshake_state_
[email protected]e17b4c12008-11-05 22:04:0898#define GotoState(s) do { LOG(INFO) << (void *)this << " " << __FUNCTION__ << \
[email protected]a3ff5e92009-10-13 04:48:0699 " jump to state " << s; \
100 next_handshake_state_ = s; } while (0)
[email protected]ea224582008-12-07 20:25:46101#define LogData(s, len) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \
102 " data [" << std::string(s, len) << "]";
103
[email protected]e17b4c12008-11-05 22:04:08104#endif
105
[email protected]ea224582008-12-07 20:25:46106namespace {
107
[email protected]829296f2010-01-27 02:58:03108class NSSSSLInitSingleton {
109 public:
110 NSSSSLInitSingleton() {
111 base::EnsureNSSInit();
112
113 NSS_SetDomesticPolicy();
114
115#if defined(USE_SYSTEM_SSL)
116 // Use late binding to avoid scary but benign warning
117 // "Symbol `SSL_ImplementedCiphers' has different size in shared object,
118 // consider re-linking"
[email protected]4d3040f42010-04-14 02:40:20119 // TODO(wtc): Use the new SSL_GetImplementedCiphers and
120 // SSL_GetNumImplementedCiphers functions when we require NSS 3.12.6.
121 // See https://bugzilla.mozilla.org/show_bug.cgi?id=496993.
[email protected]829296f2010-01-27 02:58:03122 const PRUint16* pSSL_ImplementedCiphers = static_cast<const PRUint16*>(
123 dlsym(RTLD_DEFAULT, "SSL_ImplementedCiphers"));
124 if (pSSL_ImplementedCiphers == NULL) {
125 NOTREACHED() << "Can't get list of supported ciphers";
126 return;
127 }
128#else
129#define pSSL_ImplementedCiphers SSL_ImplementedCiphers
130#endif
131
132 // Explicitly enable exactly those ciphers with keys of at least 80 bits
133 for (int i = 0; i < SSL_NumImplementedCiphers; i++) {
134 SSLCipherSuiteInfo info;
135 if (SSL_GetCipherSuiteInfo(pSSL_ImplementedCiphers[i], &info,
136 sizeof(info)) == SECSuccess) {
137 SSL_CipherPrefSetDefault(pSSL_ImplementedCiphers[i],
138 (info.effectiveKeyBits >= 80));
139 }
140 }
141
142 // Enable SSL.
143 SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE);
144
145 // All other SSL options are set per-session by SSLClientSocket.
146 }
147
148 ~NSSSSLInitSingleton() {
149 // Have to clear the cache, or NSS_Shutdown fails with SEC_ERROR_BUSY.
150 SSL_ClearSessionCache();
151 }
152};
153
154// Initialize the NSS SSL library if it isn't already initialized. This must
155// be called before any other NSS SSL functions. This function is
156// thread-safe, and the NSS SSL library will only ever be initialized once.
157// The NSS SSL library will be properly shut down on program exit.
158void EnsureNSSSSLInit() {
159 Singleton<NSSSSLInitSingleton>::get();
160}
161
[email protected]2e9a5b6982010-01-15 22:29:03162// The default error mapping function.
163// Maps an NSPR error code to a network error code.
164int MapNSPRError(PRErrorCode err) {
[email protected]ea224582008-12-07 20:25:46165 // TODO(port): fill this out as we learn what's important
166 switch (err) {
167 case PR_WOULD_BLOCK_ERROR:
168 return ERR_IO_PENDING;
[email protected]b0735462009-11-04 22:11:26169 case PR_ADDRESS_NOT_SUPPORTED_ERROR: // For connect.
170 case PR_NO_ACCESS_RIGHTS_ERROR:
171 return ERR_ACCESS_DENIED;
172 case PR_IO_TIMEOUT_ERROR:
173 return ERR_TIMED_OUT;
174 case PR_CONNECT_RESET_ERROR:
175 return ERR_CONNECTION_RESET;
176 case PR_CONNECT_ABORTED_ERROR:
177 return ERR_CONNECTION_ABORTED;
178 case PR_CONNECT_REFUSED_ERROR:
179 return ERR_CONNECTION_REFUSED;
180 case PR_HOST_UNREACHABLE_ERROR:
181 case PR_NETWORK_UNREACHABLE_ERROR:
182 return ERR_ADDRESS_UNREACHABLE;
183 case PR_ADDRESS_NOT_AVAILABLE_ERROR:
184 return ERR_ADDRESS_INVALID;
185
[email protected]4d3040f42010-04-14 02:40:20186 case SSL_ERROR_SSL_DISABLED:
187 return ERR_NO_SSL_VERSIONS_ENABLED;
[email protected]ea224582008-12-07 20:25:46188 case SSL_ERROR_NO_CYPHER_OVERLAP:
[email protected]2e9a5b6982010-01-15 22:29:03189 case SSL_ERROR_UNSUPPORTED_VERSION:
[email protected]ea224582008-12-07 20:25:46190 return ERR_SSL_VERSION_OR_CIPHER_MISMATCH;
[email protected]d84b3722009-10-15 21:23:37191 case SSL_ERROR_HANDSHAKE_FAILURE_ALERT:
[email protected]4d3040f42010-04-14 02:40:20192 case SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT:
193 case SSL_ERROR_ILLEGAL_PARAMETER_ALERT:
[email protected]d84b3722009-10-15 21:23:37194 return ERR_SSL_PROTOCOL_ERROR;
[email protected]aeaca1f2010-04-20 22:05:21195 case SSL_ERROR_DECOMPRESSION_FAILURE_ALERT:
196 return ERR_SSL_DECOMPRESSION_FAILURE_ALERT;
[email protected]0ed94682010-05-18 15:09:00197 case SSL_ERROR_BAD_MAC_ALERT:
198 return ERR_SSL_BAD_RECORD_MAC_ALERT;
[email protected]d102f542010-06-30 14:51:05199 case SSL_ERROR_UNSAFE_NEGOTIATION:
200 return ERR_SSL_UNSAFE_NEGOTIATION;
[email protected]ea224582008-12-07 20:25:46201
202 default: {
203 if (IS_SSL_ERROR(err)) {
204 LOG(WARNING) << "Unknown SSL error " << err <<
205 " mapped to net::ERR_SSL_PROTOCOL_ERROR";
206 return ERR_SSL_PROTOCOL_ERROR;
207 }
[email protected]ea224582008-12-07 20:25:46208 LOG(WARNING) << "Unknown error " << err <<
209 " mapped to net::ERR_FAILED";
210 return ERR_FAILED;
211 }
212 }
213}
214
[email protected]2e9a5b6982010-01-15 22:29:03215// Context-sensitive error mapping functions.
216
217int MapHandshakeError(PRErrorCode err) {
218 switch (err) {
219 // If the server closed on us, it is a protocol error.
220 // Some TLS-intolerant servers do this when we request TLS.
221 case PR_END_OF_FILE_ERROR:
222 // The handshake may fail because some signature (for example, the
223 // signature in the ServerKeyExchange message for an ephemeral
224 // Diffie-Hellman cipher suite) is invalid.
225 case SEC_ERROR_BAD_SIGNATURE:
226 return ERR_SSL_PROTOCOL_ERROR;
227 default:
228 return MapNSPRError(err);
229 }
230}
231
[email protected]37a0b112010-05-08 02:23:46232#if defined(OS_WIN)
233
234// A certificate for COMODO EV SGC CA, issued by AddTrust External CA Root,
235// causes CertGetCertificateChain to report CERT_TRUST_IS_NOT_VALID_FOR_USAGE.
236// It seems to be caused by the szOID_APPLICATION_CERT_POLICIES extension in
237// that certificate.
238//
239// This function is used in the workaround for http://crbug.com/43538
240bool IsProblematicComodoEVCACert(const CERTCertificate& cert) {
241 // Issuer:
242 // CN = AddTrust External CA Root
243 // OU = AddTrust External TTP Network
244 // O = AddTrust AB
245 // C = SE
246 static const uint8 kIssuer[] = {
247 0x30, 0x6f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
248 0x06, 0x13, 0x02, 0x53, 0x45, 0x31, 0x14, 0x30, 0x12, 0x06,
249 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x64, 0x64, 0x54,
250 0x72, 0x75, 0x73, 0x74, 0x20, 0x41, 0x42, 0x31, 0x26, 0x30,
251 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x64,
252 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74,
253 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x54, 0x54, 0x50, 0x20,
254 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x22, 0x30,
255 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x41, 0x64,
256 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74,
257 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x52,
258 0x6f, 0x6f, 0x74
259 };
260
261 // Serial number: 79:0A:83:4D:48:40:6B:AB:6C:35:2A:D5:1F:42:83:FE.
262 static const uint8 kSerialNumber[] = {
263 0x79, 0x0a, 0x83, 0x4d, 0x48, 0x40, 0x6b, 0xab, 0x6c, 0x35,
264 0x2a, 0xd5, 0x1f, 0x42, 0x83, 0xfe
265 };
266
267 return cert.derIssuer.len == sizeof(kIssuer) &&
268 memcmp(cert.derIssuer.data, kIssuer, cert.derIssuer.len) == 0 &&
269 cert.serialNumber.len == sizeof(kSerialNumber) &&
270 memcmp(cert.serialNumber.data, kSerialNumber,
271 cert.serialNumber.len) == 0;
272}
273
274#endif
275
[email protected]ea224582008-12-07 20:25:46276} // namespace
277
[email protected]f505a9b2010-01-28 19:44:02278#if defined(OS_WIN)
279// static
280HCERTSTORE SSLClientSocketNSS::cert_store_ = NULL;
281#endif
[email protected]b43c97c2008-10-22 19:50:58282
[email protected]e60e47a2010-07-14 03:37:18283SSLClientSocketNSS::SSLClientSocketNSS(ClientSocketHandle* transport_socket,
[email protected]b43c97c2008-10-22 19:50:58284 const std::string& hostname,
285 const SSLConfig& ssl_config)
[email protected]f505a9b2010-01-28 19:44:02286 : ALLOW_THIS_IN_INITIALIZER_LIST(buffer_send_callback_(
287 this, &SSLClientSocketNSS::BufferSendComplete)),
288 ALLOW_THIS_IN_INITIALIZER_LIST(buffer_recv_callback_(
289 this, &SSLClientSocketNSS::BufferRecvComplete)),
[email protected]b43c97c2008-10-22 19:50:58290 transport_send_busy_(false),
291 transport_recv_busy_(false),
[email protected]f505a9b2010-01-28 19:44:02292 ALLOW_THIS_IN_INITIALIZER_LIST(handshake_io_callback_(
293 this, &SSLClientSocketNSS::OnHandshakeIOComplete)),
[email protected]b43c97c2008-10-22 19:50:58294 transport_(transport_socket),
295 hostname_(hostname),
296 ssl_config_(ssl_config),
[email protected]a6eb576292009-06-30 16:19:00297 user_connect_callback_(NULL),
[email protected]a3ff5e92009-10-13 04:48:06298 user_read_callback_(NULL),
299 user_write_callback_(NULL),
300 user_read_buf_len_(0),
301 user_write_buf_len_(0),
[email protected]f505a9b2010-01-28 19:44:02302 server_cert_nss_(NULL),
[email protected]d84b3722009-10-15 21:23:37303 client_auth_cert_needed_(false),
[email protected]39afe642010-04-29 14:55:18304 handshake_callback_called_(false),
[email protected]b43c97c2008-10-22 19:50:58305 completed_handshake_(false),
[email protected]a3ff5e92009-10-13 04:48:06306 next_handshake_state_(STATE_NONE),
[email protected]b43c97c2008-10-22 19:50:58307 nss_fd_(NULL),
[email protected]a2006ece2010-04-23 16:44:02308 nss_bufs_(NULL),
[email protected]e60e47a2010-07-14 03:37:18309 net_log_(transport_socket->socket()->NetLog()) {
[email protected]e17b4c12008-11-05 22:04:08310 EnterFunction("");
[email protected]b43c97c2008-10-22 19:50:58311}
312
313SSLClientSocketNSS::~SSLClientSocketNSS() {
[email protected]e17b4c12008-11-05 22:04:08314 EnterFunction("");
[email protected]b43c97c2008-10-22 19:50:58315 Disconnect();
[email protected]e17b4c12008-11-05 22:04:08316 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:58317}
318
319int SSLClientSocketNSS::Init() {
[email protected]e17b4c12008-11-05 22:04:08320 EnterFunction("");
[email protected]829296f2010-01-27 02:58:03321 // Initialize the NSS SSL library in a threadsafe way. This also
322 // initializes the NSS base library.
323 EnsureNSSSSLInit();
[email protected]dbc13b52010-04-16 00:59:56324 if (!NSS_IsInitialized())
325 return ERR_UNEXPECTED;
[email protected]3dd6f5e2010-06-01 20:28:03326#if !defined(OS_MACOSX) && !defined(OS_WIN)
[email protected]2a0c0a52009-07-31 07:51:32327 // We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop
328 // by MessageLoopForIO::current().
329 // X509Certificate::Verify() runs on a worker thread of CertVerifier.
330 EnsureOCSPInit();
[email protected]f505a9b2010-01-28 19:44:02331#endif
[email protected]b43c97c2008-10-22 19:50:58332
[email protected]e17b4c12008-11-05 22:04:08333 LeaveFunction("");
334 return OK;
[email protected]b43c97c2008-10-22 19:50:58335}
336
[email protected]a2006ece2010-04-23 16:44:02337int SSLClientSocketNSS::Connect(CompletionCallback* callback) {
[email protected]e17b4c12008-11-05 22:04:08338 EnterFunction("");
[email protected]b43c97c2008-10-22 19:50:58339 DCHECK(transport_.get());
[email protected]a3ff5e92009-10-13 04:48:06340 DCHECK(next_handshake_state_ == STATE_NONE);
341 DCHECK(!user_read_callback_);
342 DCHECK(!user_write_callback_);
[email protected]a6eb576292009-06-30 16:19:00343 DCHECK(!user_connect_callback_);
[email protected]a3ff5e92009-10-13 04:48:06344 DCHECK(!user_read_buf_);
345 DCHECK(!user_write_buf_);
[email protected]b43c97c2008-10-22 19:50:58346
[email protected]ec11be62010-04-28 19:28:09347 net_log_.BeginEvent(NetLog::TYPE_SSL_CONNECT, NULL);
[email protected]5a05c47a2009-11-02 23:25:19348
[email protected]dbc13b52010-04-16 00:59:56349 int rv = Init();
350 if (rv != OK) {
[email protected]ec11be62010-04-28 19:28:09351 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL);
[email protected]dbc13b52010-04-16 00:59:56352 return rv;
[email protected]0ef0bcf2009-04-03 20:39:43353 }
354
[email protected]dbc13b52010-04-16 00:59:56355 rv = InitializeSSLOptions();
[email protected]5a05c47a2009-11-02 23:25:19356 if (rv != OK) {
[email protected]ec11be62010-04-28 19:28:09357 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL);
[email protected]5a05c47a2009-11-02 23:25:19358 return rv;
359 }
360
361 GotoState(STATE_HANDSHAKE);
362 rv = DoHandshakeLoop(OK);
363 if (rv == ERR_IO_PENDING) {
364 user_connect_callback_ = callback;
[email protected]5a05c47a2009-11-02 23:25:19365 } else {
[email protected]ec11be62010-04-28 19:28:09366 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL);
[email protected]5a05c47a2009-11-02 23:25:19367 }
368
369 LeaveFunction("");
370 return rv > OK ? OK : rv;
371}
372
373int SSLClientSocketNSS::InitializeSSLOptions() {
[email protected]0ef0bcf2009-04-03 20:39:43374 // Transport connected, now hook it up to nss
375 // TODO(port): specify rx and tx buffer sizes separately
376 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize);
377 if (nss_fd_ == NULL) {
[email protected]38a18722009-12-04 00:09:04378 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR error code.
[email protected]0ef0bcf2009-04-03 20:39:43379 }
380
381 // Tell NSS who we're connected to
[email protected]ac9eec62010-02-20 18:50:38382 AddressList peer_address;
[email protected]e60e47a2010-07-14 03:37:18383 int err = transport_->socket()->GetPeerAddress(&peer_address);
[email protected]ac9eec62010-02-20 18:50:38384 if (err != OK)
385 return err;
[email protected]f32c1732010-03-31 05:12:02386
[email protected]ac9eec62010-02-20 18:50:38387 const struct addrinfo* ai = peer_address.head();
[email protected]f32c1732010-03-31 05:12:02388
389 PRNetAddr peername;
390 memset(&peername, 0, sizeof(peername));
391 DCHECK_LE(ai->ai_addrlen, sizeof(peername));
392 size_t len = std::min(static_cast<size_t>(ai->ai_addrlen), sizeof(peername));
393 memcpy(&peername, ai->ai_addr, len);
394
395 // Adjust the address family field for BSD, whose sockaddr
396 // structure has a one-byte length and one-byte address family
397 // field at the beginning. PRNetAddr has a two-byte address
398 // family field at the beginning.
399 peername.raw.family = ai->ai_addr->sa_family;
400
401 memio_SetPeerName(nss_fd_, &peername);
[email protected]0ef0bcf2009-04-03 20:39:43402
403 // Grab pointer to buffers
404 nss_bufs_ = memio_GetSecret(nss_fd_);
405
406 /* Create SSL state machine */
407 /* Push SSL onto our fake I/O socket */
408 nss_fd_ = SSL_ImportFD(NULL, nss_fd_);
409 if (nss_fd_ == NULL) {
[email protected]38a18722009-12-04 00:09:04410 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR/NSS error code.
[email protected]0ef0bcf2009-04-03 20:39:43411 }
412 // TODO(port): set more ssl options! Check errors!
413
414 int rv;
415
416 rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE);
417 if (rv != SECSuccess)
418 return ERR_UNEXPECTED;
419
420 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL2, ssl_config_.ssl2_enabled);
421 if (rv != SECSuccess)
422 return ERR_UNEXPECTED;
423
424 // SNI is enabled automatically if TLS is enabled -- as long as
425 // SSL_V2_COMPATIBLE_HELLO isn't.
426 // So don't do V2 compatible hellos unless we're really using SSL2,
427 // to avoid errors like
428 // "common name `mail.google.com' != requested host name `gmail.com'"
429 rv = SSL_OptionSet(nss_fd_, SSL_V2_COMPATIBLE_HELLO,
430 ssl_config_.ssl2_enabled);
431 if (rv != SECSuccess)
432 return ERR_UNEXPECTED;
433
434 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL3, ssl_config_.ssl3_enabled);
435 if (rv != SECSuccess)
436 return ERR_UNEXPECTED;
437
438 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_TLS, ssl_config_.tls1_enabled);
439 if (rv != SECSuccess)
440 return ERR_UNEXPECTED;
441
442#ifdef SSL_ENABLE_SESSION_TICKETS
443 // Support RFC 5077
444 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_TRUE);
445 if (rv != SECSuccess)
446 LOG(INFO) << "SSL_ENABLE_SESSION_TICKETS failed. Old system nss?";
447#else
448 #error "You need to install NSS-3.12 or later to build chromium"
449#endif
450
[email protected]7e52ed72009-11-17 00:40:12451#ifdef SSL_ENABLE_DEFLATE
[email protected]074c1582010-01-08 21:38:28452 // Some web servers have been found to break if TLS is used *or* if DEFLATE
453 // is advertised. Thus, if TLS is disabled (probably because we are doing
454 // SSLv3 fallback), we disable DEFLATE also.
455 // See http://crbug.com/31628
456 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_DEFLATE, ssl_config_.tls1_enabled);
[email protected]7e52ed72009-11-17 00:40:12457 if (rv != SECSuccess)
458 LOG(INFO) << "SSL_ENABLE_DEFLATE failed. Old system nss?";
459#endif
460
[email protected]c2def1c2010-03-02 21:40:34461#ifdef SSL_ENABLE_FALSE_START
462 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_FALSE_START, PR_TRUE);
463 if (rv != SECSuccess)
464 LOG(INFO) << "SSL_ENABLE_FALSE_START failed. Old system nss?";
465#endif
466
[email protected]33b3eb92010-01-06 01:35:04467#ifdef SSL_ENABLE_RENEGOTIATION
[email protected]d102f542010-06-30 14:51:05468 if (SSLConfigService::IsKnownStrictTLSServer(hostname_)) {
469 rv = SSL_OptionSet(nss_fd_, SSL_REQUIRE_SAFE_NEGOTIATION, PR_TRUE);
470 if (rv != SECSuccess)
471 LOG(INFO) << "SSL_REQUIRE_SAFE_NEGOTIATION failed.";
472 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION,
473 SSL_RENEGOTIATE_REQUIRES_XTN);
474 } else {
475 // We allow servers to request renegotiation. Since we're a client,
476 // prohibiting this is rather a waste of time. Only servers are in a
477 // position to prevent renegotiation attacks.
478 // http://extendedsubset.com/?p=8
479
480 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION,
481 SSL_RENEGOTIATE_UNRESTRICTED);
482 }
[email protected]33b3eb92010-01-06 01:35:04483 if (rv != SECSuccess)
484 LOG(INFO) << "SSL_ENABLE_RENEGOTIATION failed.";
[email protected]d102f542010-06-30 14:51:05485#endif // SSL_ENABLE_RENEGOTIATION
[email protected]33b3eb92010-01-06 01:35:04486
[email protected]644bdca2009-11-30 20:40:53487#ifdef SSL_NEXT_PROTO_NEGOTIATED
488 if (!ssl_config_.next_protos.empty()) {
489 rv = SSL_SetNextProtoNego(
490 nss_fd_,
491 reinterpret_cast<const unsigned char *>(ssl_config_.next_protos.data()),
492 ssl_config_.next_protos.size());
493 if (rv != SECSuccess)
494 LOG(INFO) << "SSL_SetNextProtoNego failed.";
495 }
496#endif
497
[email protected]0ef0bcf2009-04-03 20:39:43498 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
499 if (rv != SECSuccess)
500 return ERR_UNEXPECTED;
501
502 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this);
503 if (rv != SECSuccess)
504 return ERR_UNEXPECTED;
505
[email protected]d84b3722009-10-15 21:23:37506 rv = SSL_GetClientAuthDataHook(nss_fd_, ClientAuthHandler, this);
507 if (rv != SECSuccess)
508 return ERR_UNEXPECTED;
509
[email protected]2345cc52009-06-04 09:18:47510 rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this);
[email protected]0ef0bcf2009-04-03 20:39:43511 if (rv != SECSuccess)
[email protected]2345cc52009-06-04 09:18:47512 return ERR_UNEXPECTED;
[email protected]0ef0bcf2009-04-03 20:39:43513
514 // Tell SSL the hostname we're trying to connect to.
515 SSL_SetURL(nss_fd_, hostname_.c_str());
516
[email protected]52c27fb2009-11-30 22:40:23517 // Set the peer ID for session reuse. This is necessary when we create an
518 // SSL tunnel through a proxy -- GetPeerName returns the proxy's address
519 // rather than the destination server's address in that case.
[email protected]ac9eec62010-02-20 18:50:38520 // TODO(wtc): port in |peer_address| is not the server's port when a proxy is
521 // used.
[email protected]52c27fb2009-11-30 22:40:23522 std::string peer_id = StringPrintf("%s:%d", hostname_.c_str(),
[email protected]ac9eec62010-02-20 18:50:38523 peer_address.GetPort());
[email protected]52c27fb2009-11-30 22:40:23524 rv = SSL_SetSockPeerID(nss_fd_, const_cast<char*>(peer_id.c_str()));
525 if (rv != SECSuccess)
526 LOG(INFO) << "SSL_SetSockPeerID failed: peer_id=" << peer_id;
527
[email protected]0ef0bcf2009-04-03 20:39:43528 // Tell SSL we're a client; needed if not letting NSPR do socket I/O
529 SSL_ResetHandshake(nss_fd_, 0);
530
[email protected]5a05c47a2009-11-02 23:25:19531 return OK;
[email protected]b43c97c2008-10-22 19:50:58532}
533
[email protected]bacff652009-03-31 17:50:33534void SSLClientSocketNSS::InvalidateSessionIfBadCertificate() {
535 if (UpdateServerCert() != NULL &&
[email protected]127017872009-08-13 17:54:42536 ssl_config_.IsAllowedBadCert(server_cert_)) {
[email protected]bacff652009-03-31 17:50:33537 SSL_InvalidateSession(nss_fd_);
538 }
[email protected]b43c97c2008-10-22 19:50:58539}
540
541void SSLClientSocketNSS::Disconnect() {
[email protected]e17b4c12008-11-05 22:04:08542 EnterFunction("");
[email protected]bacff652009-03-31 17:50:33543
[email protected]b43c97c2008-10-22 19:50:58544 // TODO(wtc): Send SSL close_notify alert.
545 if (nss_fd_ != NULL) {
[email protected]bacff652009-03-31 17:50:33546 InvalidateSessionIfBadCertificate();
[email protected]b43c97c2008-10-22 19:50:58547 PR_Close(nss_fd_);
548 nss_fd_ = NULL;
549 }
[email protected]bacff652009-03-31 17:50:33550
[email protected]92d9cad2009-06-25 23:40:24551 // Shut down anything that may call us back (through buffer_send_callback_,
[email protected]a3ff5e92009-10-13 04:48:06552 // buffer_recv_callback, or handshake_io_callback_).
[email protected]92d9cad2009-06-25 23:40:24553 verifier_.reset();
[email protected]e60e47a2010-07-14 03:37:18554 transport_->socket()->Disconnect();
[email protected]bf0136d2009-05-29 05:55:04555
556 // Reset object state
[email protected]a6eb576292009-06-30 16:19:00557 transport_send_busy_ = false;
558 transport_recv_busy_ = false;
559 user_connect_callback_ = NULL;
[email protected]a3ff5e92009-10-13 04:48:06560 user_read_callback_ = NULL;
561 user_write_callback_ = NULL;
562 user_read_buf_ = NULL;
563 user_read_buf_len_ = 0;
564 user_write_buf_ = NULL;
565 user_write_buf_len_ = 0;
[email protected]a6eb576292009-06-30 16:19:00566 server_cert_ = NULL;
[email protected]f505a9b2010-01-28 19:44:02567 if (server_cert_nss_) {
568 CERT_DestroyCertificate(server_cert_nss_);
569 server_cert_nss_ = NULL;
570 }
[email protected]2345cc52009-06-04 09:18:47571 server_cert_verify_result_.Reset();
[email protected]a6eb576292009-06-30 16:19:00572 completed_handshake_ = false;
573 nss_bufs_ = NULL;
[email protected]b8fee152009-10-24 03:39:31574 client_certs_.clear();
[email protected]d84b3722009-10-15 21:23:37575 client_auth_cert_needed_ = false;
[email protected]bf0136d2009-05-29 05:55:04576
[email protected]e17b4c12008-11-05 22:04:08577 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:58578}
579
580bool SSLClientSocketNSS::IsConnected() const {
[email protected]b2197852009-02-19 23:27:33581 // Ideally, we should also check if we have received the close_notify alert
582 // message from the server, and return false in that case. We're not doing
583 // that, so this function may return a false positive. Since the upper
584 // layer (HttpNetworkTransaction) needs to handle a persistent connection
585 // closed by the server when we send a request anyway, a false positive in
586 // exchange for simpler code is a good trade-off.
[email protected]e17b4c12008-11-05 22:04:08587 EnterFunction("");
[email protected]e60e47a2010-07-14 03:37:18588 bool ret = completed_handshake_ && transport_->socket()->IsConnected();
[email protected]e17b4c12008-11-05 22:04:08589 LeaveFunction("");
590 return ret;
[email protected]b43c97c2008-10-22 19:50:58591}
592
[email protected]b2197852009-02-19 23:27:33593bool SSLClientSocketNSS::IsConnectedAndIdle() const {
594 // Unlike IsConnected, this method doesn't return a false positive.
595 //
596 // Strictly speaking, we should check if we have received the close_notify
597 // alert message from the server, and return false in that case. Although
598 // the close_notify alert message means EOF in the SSL layer, it is just
[email protected]e60e47a2010-07-14 03:37:18599 // bytes to the transport layer below, so
600 // transport_->socket()->IsConnectedAndIdle() returns the desired false
601 // when we receive close_notify.
[email protected]b2197852009-02-19 23:27:33602 EnterFunction("");
[email protected]e60e47a2010-07-14 03:37:18603 bool ret = completed_handshake_ && transport_->socket()->IsConnectedAndIdle();
[email protected]b2197852009-02-19 23:27:33604 LeaveFunction("");
605 return ret;
606}
607
[email protected]ac9eec62010-02-20 18:50:38608int SSLClientSocketNSS::GetPeerAddress(AddressList* address) const {
[email protected]e60e47a2010-07-14 03:37:18609 return transport_->socket()->GetPeerAddress(address);
[email protected]9f864b32010-01-20 15:01:16610}
611
[email protected]ffeb0882009-04-30 21:51:25612int SSLClientSocketNSS::Read(IOBuffer* buf, int buf_len,
[email protected]ea224582008-12-07 20:25:46613 CompletionCallback* callback) {
[email protected]e17b4c12008-11-05 22:04:08614 EnterFunction(buf_len);
[email protected]b43c97c2008-10-22 19:50:58615 DCHECK(completed_handshake_);
[email protected]a3ff5e92009-10-13 04:48:06616 DCHECK(next_handshake_state_ == STATE_NONE);
617 DCHECK(!user_read_callback_);
[email protected]a6eb576292009-06-30 16:19:00618 DCHECK(!user_connect_callback_);
[email protected]a3ff5e92009-10-13 04:48:06619 DCHECK(!user_read_buf_);
620 DCHECK(nss_bufs_);
[email protected]b43c97c2008-10-22 19:50:58621
[email protected]a3ff5e92009-10-13 04:48:06622 user_read_buf_ = buf;
623 user_read_buf_len_ = buf_len;
[email protected]b43c97c2008-10-22 19:50:58624
[email protected]a3ff5e92009-10-13 04:48:06625 int rv = DoReadLoop(OK);
626
[email protected]1d583612010-03-12 17:47:14627 if (rv == ERR_IO_PENDING) {
[email protected]a3ff5e92009-10-13 04:48:06628 user_read_callback_ = callback;
[email protected]1d583612010-03-12 17:47:14629 } else {
[email protected]a3ff5e92009-10-13 04:48:06630 user_read_buf_ = NULL;
631 user_read_buf_len_ = 0;
632 }
[email protected]ea224582008-12-07 20:25:46633 LeaveFunction(rv);
[email protected]b43c97c2008-10-22 19:50:58634 return rv;
635}
636
[email protected]ffeb0882009-04-30 21:51:25637int SSLClientSocketNSS::Write(IOBuffer* buf, int buf_len,
[email protected]a3ff5e92009-10-13 04:48:06638 CompletionCallback* callback) {
[email protected]e17b4c12008-11-05 22:04:08639 EnterFunction(buf_len);
[email protected]b43c97c2008-10-22 19:50:58640 DCHECK(completed_handshake_);
[email protected]a3ff5e92009-10-13 04:48:06641 DCHECK(next_handshake_state_ == STATE_NONE);
642 DCHECK(!user_write_callback_);
[email protected]a6eb576292009-06-30 16:19:00643 DCHECK(!user_connect_callback_);
[email protected]a3ff5e92009-10-13 04:48:06644 DCHECK(!user_write_buf_);
645 DCHECK(nss_bufs_);
[email protected]b43c97c2008-10-22 19:50:58646
[email protected]a3ff5e92009-10-13 04:48:06647 user_write_buf_ = buf;
648 user_write_buf_len_ = buf_len;
[email protected]b43c97c2008-10-22 19:50:58649
[email protected]a3ff5e92009-10-13 04:48:06650 int rv = DoWriteLoop(OK);
651
[email protected]1d583612010-03-12 17:47:14652 if (rv == ERR_IO_PENDING) {
[email protected]a3ff5e92009-10-13 04:48:06653 user_write_callback_ = callback;
[email protected]1d583612010-03-12 17:47:14654 } else {
[email protected]a3ff5e92009-10-13 04:48:06655 user_write_buf_ = NULL;
656 user_write_buf_len_ = 0;
657 }
[email protected]ea224582008-12-07 20:25:46658 LeaveFunction(rv);
[email protected]b43c97c2008-10-22 19:50:58659 return rv;
660}
661
[email protected]d3f66572009-09-09 22:38:04662bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) {
[email protected]e60e47a2010-07-14 03:37:18663 return transport_->socket()->SetReceiveBufferSize(size);
[email protected]d3f66572009-09-09 22:38:04664}
665
666bool SSLClientSocketNSS::SetSendBufferSize(int32 size) {
[email protected]e60e47a2010-07-14 03:37:18667 return transport_->socket()->SetSendBufferSize(size);
[email protected]d3f66572009-09-09 22:38:04668}
669
[email protected]e9b084c2010-06-04 18:17:23670#if defined(OS_WIN)
671// static
672X509Certificate::OSCertHandle SSLClientSocketNSS::CreateOSCert(
673 const SECItem& der_cert) {
674 // TODO(wtc): close cert_store_ at shutdown.
675 if (!cert_store_)
676 cert_store_ = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL);
677
678 X509Certificate::OSCertHandle cert_handle = NULL;
679 BOOL ok = CertAddEncodedCertificateToStore(
680 cert_store_, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
681 der_cert.data, der_cert.len, CERT_STORE_ADD_USE_EXISTING, &cert_handle);
682 return ok ? cert_handle : NULL;
683}
684#elif defined(OS_MACOSX)
685// static
686X509Certificate::OSCertHandle SSLClientSocketNSS::CreateOSCert(
687 const SECItem& der_cert) {
688 return X509Certificate::CreateOSCertHandleFromBytes(
689 reinterpret_cast<char*>(der_cert.data), der_cert.len);
690}
691#endif
692
[email protected]bacff652009-03-31 17:50:33693X509Certificate *SSLClientSocketNSS::UpdateServerCert() {
694 // We set the server_cert_ from OwnAuthCertHandler(), but this handler
695 // does not necessarily get called if we are continuing a cached SSL
696 // session.
697 if (server_cert_ == NULL) {
[email protected]f505a9b2010-01-28 19:44:02698 server_cert_nss_ = SSL_PeerCertificate(nss_fd_);
699 if (server_cert_nss_) {
[email protected]3dd6f5e2010-06-01 20:28:03700#if defined(OS_MACOSX) || defined(OS_WIN)
[email protected]4bee851c2010-03-05 23:44:45701 // Get each of the intermediate certificates in the server's chain.
702 // These will be added to the server's X509Certificate object, making
703 // them available to X509Certificate::Verify() for chain building.
704 X509Certificate::OSCertHandles intermediate_ca_certs;
[email protected]3dd6f5e2010-06-01 20:28:03705 X509Certificate::OSCertHandle cert_handle = NULL;
[email protected]4bee851c2010-03-05 23:44:45706 CERTCertList* cert_list = CERT_GetCertChainFromCert(
707 server_cert_nss_, PR_Now(), certUsageSSLCA);
708 if (cert_list) {
709 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
710 !CERT_LIST_END(node, cert_list);
711 node = CERT_LIST_NEXT(node)) {
[email protected]37a0b112010-05-08 02:23:46712 if (node->cert == server_cert_nss_)
713 continue;
[email protected]3dd6f5e2010-06-01 20:28:03714#if defined(OS_WIN)
[email protected]37a0b112010-05-08 02:23:46715 // Work around http://crbug.com/43538 by not importing the
716 // problematic COMODO EV SGC CA certificate. CryptoAPI will
717 // download a good certificate for that CA, issued by COMODO
718 // Certification Authority, using the AIA extension in the server
719 // certificate.
720 if (IsProblematicComodoEVCACert(*node->cert))
721 continue;
[email protected]3dd6f5e2010-06-01 20:28:03722#endif
[email protected]e9b084c2010-06-04 18:17:23723 cert_handle = CreateOSCert(node->cert->derCert);
[email protected]3dd6f5e2010-06-01 20:28:03724 DCHECK(cert_handle);
725 intermediate_ca_certs.push_back(cert_handle);
[email protected]4bee851c2010-03-05 23:44:45726 }
727 CERT_DestroyCertList(cert_list);
728 }
729
730 // Finally create the X509Certificate object.
[email protected]e9b084c2010-06-04 18:17:23731 cert_handle = CreateOSCert(server_cert_nss_->derCert);
[email protected]3dd6f5e2010-06-01 20:28:03732 DCHECK(cert_handle);
[email protected]bacff652009-03-31 17:50:33733 server_cert_ = X509Certificate::CreateFromHandle(
[email protected]3dd6f5e2010-06-01 20:28:03734 cert_handle,
[email protected]4bee851c2010-03-05 23:44:45735 X509Certificate::SOURCE_FROM_NETWORK,
736 intermediate_ca_certs);
[email protected]1c8857bc2010-06-26 18:44:05737 X509Certificate::FreeOSCertHandle(cert_handle);
[email protected]4bee851c2010-03-05 23:44:45738 for (size_t i = 0; i < intermediate_ca_certs.size(); ++i)
[email protected]3dd6f5e2010-06-01 20:28:03739 X509Certificate::FreeOSCertHandle(intermediate_ca_certs[i]);
[email protected]f505a9b2010-01-28 19:44:02740#else
741 server_cert_ = X509Certificate::CreateFromHandle(
[email protected]1c8857bc2010-06-26 18:44:05742 server_cert_nss_,
[email protected]4bee851c2010-03-05 23:44:45743 X509Certificate::SOURCE_FROM_NETWORK,
744 X509Certificate::OSCertHandles());
[email protected]f505a9b2010-01-28 19:44:02745#endif
[email protected]bacff652009-03-31 17:50:33746 }
747 }
748 return server_cert_;
749}
750
[email protected]1e7cd2c72010-02-27 01:31:19751// Log an informational message if the server does not support secure
752// renegotiation (RFC 5746).
753void SSLClientSocketNSS::CheckSecureRenegotiation() const {
754 // SSL_HandshakeNegotiatedExtension was added in NSS 3.12.6.
755 // Since SSL_MAX_EXTENSIONS was added at the same time, we can test
756 // SSL_MAX_EXTENSIONS for the presence of SSL_HandshakeNegotiatedExtension.
757#if defined(SSL_MAX_EXTENSIONS)
758 PRBool received_renego_info;
759 if (SSL_HandshakeNegotiatedExtension(nss_fd_, ssl_renegotiation_info_xtn,
760 &received_renego_info) == SECSuccess &&
761 !received_renego_info) {
762 LOG(INFO) << "The server " << hostname_
[email protected]d48fd7b2010-03-03 22:46:13763 << " does not support the TLS renegotiation_info extension.";
[email protected]1e7cd2c72010-02-27 01:31:19764 }
765#endif
766}
767
[email protected]b43c97c2008-10-22 19:50:58768void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) {
[email protected]e17b4c12008-11-05 22:04:08769 EnterFunction("");
[email protected]b43c97c2008-10-22 19:50:58770 ssl_info->Reset();
[email protected]2345cc52009-06-04 09:18:47771 if (!server_cert_)
772 return;
773
[email protected]ea224582008-12-07 20:25:46774 SSLChannelInfo channel_info;
775 SECStatus ok = SSL_GetChannelInfo(nss_fd_,
776 &channel_info, sizeof(channel_info));
[email protected]9f8821ed2008-12-09 18:02:37777 if (ok == SECSuccess &&
778 channel_info.length == sizeof(channel_info) &&
779 channel_info.cipherSuite) {
[email protected]ea224582008-12-07 20:25:46780 SSLCipherSuiteInfo cipher_info;
781 ok = SSL_GetCipherSuiteInfo(channel_info.cipherSuite,
782 &cipher_info, sizeof(cipher_info));
783 if (ok == SECSuccess) {
784 ssl_info->security_bits = cipher_info.effectiveKeyBits;
785 } else {
786 ssl_info->security_bits = -1;
[email protected]9f8821ed2008-12-09 18:02:37787 LOG(DFATAL) << "SSL_GetCipherSuiteInfo returned " << PR_GetError()
788 << " for cipherSuite " << channel_info.cipherSuite;
[email protected]ea224582008-12-07 20:25:46789 }
[email protected]d8654bf2010-07-18 16:01:32790 ssl_info->connection_status |=
791 (((int)channel_info.cipherSuite) & SSL_CONNECTION_CIPHERSUITE_MASK) <<
792 SSL_CONNECTION_CIPHERSUITE_SHIFT;
793
794 ssl_info->connection_status |=
795 (((int)channel_info.compressionMethod) &
796 SSL_CONNECTION_COMPRESSION_MASK) <<
797 SSL_CONNECTION_COMPRESSION_SHIFT;
798
[email protected]bacff652009-03-31 17:50:33799 UpdateServerCert();
[email protected]ea224582008-12-07 20:25:46800 }
[email protected]2345cc52009-06-04 09:18:47801 ssl_info->cert_status = server_cert_verify_result_.cert_status;
[email protected]bacff652009-03-31 17:50:33802 DCHECK(server_cert_ != NULL);
803 ssl_info->cert = server_cert_;
[email protected]644bdca2009-11-30 20:40:53804
[email protected]fc7de492010-07-12 14:49:04805 PRBool peer_supports_renego_ext;
806 ok = SSL_HandshakeNegotiatedExtension(nss_fd_, ssl_renegotiation_info_xtn,
807 &peer_supports_renego_ext);
808 if (ok == SECSuccess) {
809 if (!peer_supports_renego_ext)
810 ssl_info->connection_status |= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION;
811 UMA_HISTOGRAM_ENUMERATION("Net.RenegotiationExtensionSupported",
812 (int)peer_supports_renego_ext, 2);
813 }
814
815 if (ssl_config_.ssl3_fallback)
816 ssl_info->connection_status |= SSL_CONNECTION_SSL3_FALLBACK;
817
[email protected]e17b4c12008-11-05 22:04:08818 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:58819}
820
[email protected]0b45559b2009-06-12 21:45:11821void SSLClientSocketNSS::GetSSLCertRequestInfo(
822 SSLCertRequestInfo* cert_request_info) {
[email protected]d84b3722009-10-15 21:23:37823 EnterFunction("");
[email protected]1d583612010-03-12 17:47:14824 cert_request_info->host_and_port = hostname_; // TODO(wtc): no port!
[email protected]b8fee152009-10-24 03:39:31825 cert_request_info->client_certs = client_certs_;
[email protected]d84b3722009-10-15 21:23:37826 LeaveFunction(cert_request_info->client_certs.size());
[email protected]0b45559b2009-06-12 21:45:11827}
828
[email protected]b28f19d72009-12-10 21:52:27829SSLClientSocket::NextProtoStatus
[email protected]f49ea7d2009-12-11 20:03:50830SSLClientSocketNSS::GetNextProto(std::string* proto) {
831#if defined(SSL_NEXT_PROTO_NEGOTIATED)
832 unsigned char buf[255];
[email protected]b28f19d72009-12-10 21:52:27833 int state;
834 unsigned len;
835 SECStatus rv = SSL_GetNextProto(nss_fd_, &state, buf, &len, sizeof(buf));
836 if (rv != SECSuccess) {
837 NOTREACHED() << "Error return from SSL_GetNextProto: " << rv;
838 proto->clear();
839 return kNextProtoUnsupported;
840 }
[email protected]f49ea7d2009-12-11 20:03:50841 // We don't check for truncation because sizeof(buf) is large enough to hold
842 // the maximum protocol size.
[email protected]829296f2010-01-27 02:58:03843 switch (state) {
[email protected]f49ea7d2009-12-11 20:03:50844 case SSL_NEXT_PROTO_NO_SUPPORT:
845 proto->clear();
846 return kNextProtoUnsupported;
847 case SSL_NEXT_PROTO_NEGOTIATED:
848 *proto = std::string(reinterpret_cast<char*>(buf), len);
849 return kNextProtoNegotiated;
850 case SSL_NEXT_PROTO_NO_OVERLAP:
851 *proto = std::string(reinterpret_cast<char*>(buf), len);
852 return kNextProtoNoOverlap;
853 default:
854 NOTREACHED() << "Unknown status from SSL_GetNextProto: " << state;
855 proto->clear();
856 return kNextProtoUnsupported;
[email protected]b28f19d72009-12-10 21:52:27857 }
[email protected]f49ea7d2009-12-11 20:03:50858#else
859 // No NPN support in the libssl that we are building with.
860 proto->clear();
861 return kNextProtoUnsupported;
[email protected]b28f19d72009-12-10 21:52:27862#endif
863}
864
[email protected]a3ff5e92009-10-13 04:48:06865void SSLClientSocketNSS::DoReadCallback(int rv) {
[email protected]e17b4c12008-11-05 22:04:08866 EnterFunction(rv);
[email protected]b43c97c2008-10-22 19:50:58867 DCHECK(rv != ERR_IO_PENDING);
[email protected]a3ff5e92009-10-13 04:48:06868 DCHECK(user_read_callback_);
[email protected]b43c97c2008-10-22 19:50:58869
[email protected]a3ff5e92009-10-13 04:48:06870 // Since Run may result in Read being called, clear |user_read_callback_|
871 // up front.
872 CompletionCallback* c = user_read_callback_;
873 user_read_callback_ = NULL;
874 user_read_buf_ = NULL;
875 user_read_buf_len_ = 0;
876 c->Run(rv);
877 LeaveFunction("");
878}
879
880void SSLClientSocketNSS::DoWriteCallback(int rv) {
881 EnterFunction(rv);
882 DCHECK(rv != ERR_IO_PENDING);
883 DCHECK(user_write_callback_);
884
885 // Since Run may result in Write being called, clear |user_write_callback_|
886 // up front.
887 CompletionCallback* c = user_write_callback_;
888 user_write_callback_ = NULL;
889 user_write_buf_ = NULL;
890 user_write_buf_len_ = 0;
[email protected]b43c97c2008-10-22 19:50:58891 c->Run(rv);
[email protected]e17b4c12008-11-05 22:04:08892 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:58893}
894
[email protected]a6eb576292009-06-30 16:19:00895// As part of Connect(), the SSLClientSocketNSS object performs an SSL
896// handshake. This requires network IO, which in turn calls
897// BufferRecvComplete() with a non-zero byte count. This byte count eventually
898// winds its way through the state machine and ends up being passed to the
899// callback. For Read() and Write(), that's what we want. But for Connect(),
900// the caller expects OK (i.e. 0) for success.
901//
902void SSLClientSocketNSS::DoConnectCallback(int rv) {
903 EnterFunction(rv);
904 DCHECK_NE(rv, ERR_IO_PENDING);
905 DCHECK(user_connect_callback_);
906
[email protected]a6eb576292009-06-30 16:19:00907 CompletionCallback* c = user_connect_callback_;
908 user_connect_callback_ = NULL;
909 c->Run(rv > OK ? OK : rv);
910 LeaveFunction("");
911}
912
[email protected]a3ff5e92009-10-13 04:48:06913void SSLClientSocketNSS::OnHandshakeIOComplete(int result) {
[email protected]e17b4c12008-11-05 22:04:08914 EnterFunction(result);
[email protected]a3ff5e92009-10-13 04:48:06915 int rv = DoHandshakeLoop(result);
[email protected]5a05c47a2009-11-02 23:25:19916 if (rv != ERR_IO_PENDING) {
[email protected]ec11be62010-04-28 19:28:09917 net_log_.EndEvent(net::NetLog::TYPE_SSL_CONNECT, NULL);
[email protected]a3ff5e92009-10-13 04:48:06918 DoConnectCallback(rv);
[email protected]5a05c47a2009-11-02 23:25:19919 }
[email protected]a3ff5e92009-10-13 04:48:06920 LeaveFunction("");
921}
922
923void SSLClientSocketNSS::OnSendComplete(int result) {
924 EnterFunction(result);
[email protected]45965de2010-02-25 23:23:31925 if (next_handshake_state_ == STATE_HANDSHAKE) {
[email protected]a3ff5e92009-10-13 04:48:06926 // In handshake phase.
927 OnHandshakeIOComplete(result);
928 LeaveFunction("");
929 return;
[email protected]a6eb576292009-06-30 16:19:00930 }
[email protected]a3ff5e92009-10-13 04:48:06931
932 // OnSendComplete may need to call DoPayloadRead while the renegotiation
933 // handshake is in progress.
934 int rv_read = ERR_IO_PENDING;
935 int rv_write = ERR_IO_PENDING;
936 bool network_moved;
937 do {
938 if (user_read_buf_)
939 rv_read = DoPayloadRead();
940 if (user_write_buf_)
941 rv_write = DoPayloadWrite();
942 network_moved = DoTransportIO();
943 } while (rv_read == ERR_IO_PENDING &&
944 rv_write == ERR_IO_PENDING &&
945 network_moved);
946
947 if (user_read_buf_ && rv_read != ERR_IO_PENDING)
948 DoReadCallback(rv_read);
949 if (user_write_buf_ && rv_write != ERR_IO_PENDING)
950 DoWriteCallback(rv_write);
951
952 LeaveFunction("");
953}
954
955void SSLClientSocketNSS::OnRecvComplete(int result) {
956 EnterFunction(result);
[email protected]45965de2010-02-25 23:23:31957 if (next_handshake_state_ == STATE_HANDSHAKE) {
[email protected]a3ff5e92009-10-13 04:48:06958 // In handshake phase.
959 OnHandshakeIOComplete(result);
960 LeaveFunction("");
961 return;
962 }
963
964 // Network layer received some data, check if client requested to read
965 // decrypted data.
966 if (!user_read_buf_) {
967 LeaveFunction("");
968 return;
969 }
970
971 int rv = DoReadLoop(result);
972 if (rv != ERR_IO_PENDING)
973 DoReadCallback(rv);
[email protected]e17b4c12008-11-05 22:04:08974 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:58975}
976
[email protected]b0735462009-11-04 22:11:26977// Map a Chromium net error code to an NSS error code.
[email protected]b43c97c2008-10-22 19:50:58978// See _MD_unix_map_default_error in the NSS source
979// tree for inspiration.
980static PRErrorCode MapErrorToNSS(int result) {
981 if (result >=0)
982 return result;
[email protected]b0735462009-11-04 22:11:26983
984 switch (result) {
985 case ERR_IO_PENDING:
986 return PR_WOULD_BLOCK_ERROR;
987 case ERR_ACCESS_DENIED:
988 // For connect, this could be mapped to PR_ADDRESS_NOT_SUPPORTED_ERROR.
989 return PR_NO_ACCESS_RIGHTS_ERROR;
990 case ERR_INTERNET_DISCONNECTED: // Equivalent to ENETDOWN.
991 return PR_NETWORK_UNREACHABLE_ERROR; // Best approximation.
992 case ERR_CONNECTION_TIMED_OUT:
993 case ERR_TIMED_OUT:
994 return PR_IO_TIMEOUT_ERROR;
995 case ERR_CONNECTION_RESET:
996 return PR_CONNECT_RESET_ERROR;
997 case ERR_CONNECTION_ABORTED:
998 return PR_CONNECT_ABORTED_ERROR;
999 case ERR_CONNECTION_REFUSED:
1000 return PR_CONNECT_REFUSED_ERROR;
1001 case ERR_ADDRESS_UNREACHABLE:
1002 return PR_HOST_UNREACHABLE_ERROR; // Also PR_NETWORK_UNREACHABLE_ERROR.
1003 case ERR_ADDRESS_INVALID:
1004 return PR_ADDRESS_NOT_AVAILABLE_ERROR;
[email protected]4d3040f42010-04-14 02:40:201005 case ERR_NAME_NOT_RESOLVED:
1006 return PR_DIRECTORY_LOOKUP_ERROR;
[email protected]b0735462009-11-04 22:11:261007 default:
1008 LOG(WARNING) << "MapErrorToNSS " << result
1009 << " mapped to PR_UNKNOWN_ERROR";
1010 return PR_UNKNOWN_ERROR;
1011 }
[email protected]b43c97c2008-10-22 19:50:581012}
1013
[email protected]ffeb0882009-04-30 21:51:251014// Do network I/O between the given buffer and the given socket.
[email protected]a3ff5e92009-10-13 04:48:061015// Return true if some I/O performed, false otherwise (error or ERR_IO_PENDING)
1016bool SSLClientSocketNSS::DoTransportIO() {
1017 EnterFunction("");
1018 bool network_moved = false;
1019 if (nss_bufs_ != NULL) {
1020 int nsent = BufferSend();
1021 int nreceived = BufferRecv();
1022 network_moved = (nsent > 0 || nreceived >= 0);
1023 }
1024 LeaveFunction(network_moved);
1025 return network_moved;
1026}
1027
[email protected]ffeb0882009-04-30 21:51:251028// Return 0 for EOF,
1029// > 0 for bytes transferred immediately,
1030// < 0 for error (or the non-error ERR_IO_PENDING).
[email protected]b43c97c2008-10-22 19:50:581031int SSLClientSocketNSS::BufferSend(void) {
1032 if (transport_send_busy_) return ERR_IO_PENDING;
1033
[email protected]914286d62009-12-10 23:06:441034 int nsent = 0;
1035 EnterFunction("");
1036 // nss_bufs_ is a circular buffer. It may have two contiguous parts
1037 // (before and after the wrap). So this for loop needs two iterations.
1038 for (int i = 0; i < 2; ++i) {
1039 const char* buf;
1040 int nb = memio_GetWriteParams(nss_bufs_, &buf);
1041 if (!nb)
1042 break;
[email protected]b43c97c2008-10-22 19:50:581043
[email protected]ffeb0882009-04-30 21:51:251044 scoped_refptr<IOBuffer> send_buffer = new IOBuffer(nb);
1045 memcpy(send_buffer->data(), buf, nb);
[email protected]e60e47a2010-07-14 03:37:181046 int rv = transport_->socket()->Write(send_buffer, nb,
1047 &buffer_send_callback_);
[email protected]914286d62009-12-10 23:06:441048 if (rv == ERR_IO_PENDING) {
[email protected]b43c97c2008-10-22 19:50:581049 transport_send_busy_ = true;
[email protected]914286d62009-12-10 23:06:441050 break;
1051 } else {
[email protected]b43c97c2008-10-22 19:50:581052 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv));
[email protected]914286d62009-12-10 23:06:441053 if (rv < 0) {
1054 // Return the error even if the previous Write succeeded.
1055 nsent = rv;
1056 break;
1057 }
1058 nsent += rv;
1059 }
[email protected]b43c97c2008-10-22 19:50:581060 }
1061
[email protected]914286d62009-12-10 23:06:441062 LeaveFunction(nsent);
1063 return nsent;
[email protected]b43c97c2008-10-22 19:50:581064}
1065
1066void SSLClientSocketNSS::BufferSendComplete(int result) {
[email protected]e17b4c12008-11-05 22:04:081067 EnterFunction(result);
[email protected]b0735462009-11-04 22:11:261068 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(result));
[email protected]b43c97c2008-10-22 19:50:581069 transport_send_busy_ = false;
[email protected]a3ff5e92009-10-13 04:48:061070 OnSendComplete(result);
[email protected]e17b4c12008-11-05 22:04:081071 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:581072}
1073
1074
1075int SSLClientSocketNSS::BufferRecv(void) {
[email protected]b43c97c2008-10-22 19:50:581076 if (transport_recv_busy_) return ERR_IO_PENDING;
1077
1078 char *buf;
1079 int nb = memio_GetReadParams(nss_bufs_, &buf);
[email protected]e17b4c12008-11-05 22:04:081080 EnterFunction(nb);
[email protected]b43c97c2008-10-22 19:50:581081 int rv;
1082 if (!nb) {
1083 // buffer too full to read into, so no I/O possible at moment
1084 rv = ERR_IO_PENDING;
1085 } else {
[email protected]ffeb0882009-04-30 21:51:251086 recv_buffer_ = new IOBuffer(nb);
[email protected]e60e47a2010-07-14 03:37:181087 rv = transport_->socket()->Read(recv_buffer_, nb, &buffer_recv_callback_);
[email protected]ffeb0882009-04-30 21:51:251088 if (rv == ERR_IO_PENDING) {
[email protected]b43c97c2008-10-22 19:50:581089 transport_recv_busy_ = true;
[email protected]ffeb0882009-04-30 21:51:251090 } else {
1091 if (rv > 0)
1092 memcpy(buf, recv_buffer_->data(), rv);
[email protected]b43c97c2008-10-22 19:50:581093 memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv));
[email protected]ffeb0882009-04-30 21:51:251094 recv_buffer_ = NULL;
1095 }
[email protected]b43c97c2008-10-22 19:50:581096 }
[email protected]e17b4c12008-11-05 22:04:081097 LeaveFunction(rv);
[email protected]b43c97c2008-10-22 19:50:581098 return rv;
1099}
1100
1101void SSLClientSocketNSS::BufferRecvComplete(int result) {
[email protected]e17b4c12008-11-05 22:04:081102 EnterFunction(result);
[email protected]ffeb0882009-04-30 21:51:251103 if (result > 0) {
1104 char *buf;
1105 memio_GetReadParams(nss_bufs_, &buf);
1106 memcpy(buf, recv_buffer_->data(), result);
1107 }
1108 recv_buffer_ = NULL;
[email protected]b0735462009-11-04 22:11:261109 memio_PutReadResult(nss_bufs_, MapErrorToNSS(result));
[email protected]b43c97c2008-10-22 19:50:581110 transport_recv_busy_ = false;
[email protected]a3ff5e92009-10-13 04:48:061111 OnRecvComplete(result);
[email protected]e17b4c12008-11-05 22:04:081112 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:581113}
1114
[email protected]a3ff5e92009-10-13 04:48:061115int SSLClientSocketNSS::DoHandshakeLoop(int last_io_result) {
[email protected]e17b4c12008-11-05 22:04:081116 EnterFunction(last_io_result);
[email protected]b43c97c2008-10-22 19:50:581117 bool network_moved;
1118 int rv = last_io_result;
1119 do {
[email protected]e17b4c12008-11-05 22:04:081120 // Default to STATE_NONE for next state.
[email protected]ea224582008-12-07 20:25:461121 // (This is a quirk carried over from the windows
[email protected]e17b4c12008-11-05 22:04:081122 // implementation. It makes reading the logs a bit harder.)
[email protected]ea224582008-12-07 20:25:461123 // State handlers can and often do call GotoState just
[email protected]e17b4c12008-11-05 22:04:081124 // to stay in the current state.
[email protected]a3ff5e92009-10-13 04:48:061125 State state = next_handshake_state_;
[email protected]e17b4c12008-11-05 22:04:081126 GotoState(STATE_NONE);
[email protected]b43c97c2008-10-22 19:50:581127 switch (state) {
[email protected]e17b4c12008-11-05 22:04:081128 case STATE_NONE:
1129 // we're just pumping data between the buffer and the network
1130 break;
[email protected]a3ff5e92009-10-13 04:48:061131 case STATE_HANDSHAKE:
1132 rv = DoHandshake();
[email protected]b43c97c2008-10-22 19:50:581133 break;
[email protected]2345cc52009-06-04 09:18:471134 case STATE_VERIFY_CERT:
1135 DCHECK(rv == OK);
1136 rv = DoVerifyCert(rv);
1137 break;
1138 case STATE_VERIFY_CERT_COMPLETE:
1139 rv = DoVerifyCertComplete(rv);
1140 break;
[email protected]b43c97c2008-10-22 19:50:581141 default:
1142 rv = ERR_UNEXPECTED;
1143 NOTREACHED() << "unexpected state";
1144 break;
1145 }
1146
1147 // Do the actual network I/O
[email protected]a3ff5e92009-10-13 04:48:061148 network_moved = DoTransportIO();
[email protected]72d1e592009-03-10 17:39:461149 } while ((rv != ERR_IO_PENDING || network_moved) &&
[email protected]a3ff5e92009-10-13 04:48:061150 next_handshake_state_ != STATE_NONE);
1151 LeaveFunction("");
1152 return rv;
1153}
1154
1155int SSLClientSocketNSS::DoReadLoop(int result) {
1156 EnterFunction("");
1157 DCHECK(completed_handshake_);
1158 DCHECK(next_handshake_state_ == STATE_NONE);
1159
1160 if (result < 0)
1161 return result;
1162
1163 if (!nss_bufs_)
1164 return ERR_UNEXPECTED;
1165
1166 bool network_moved;
1167 int rv;
1168 do {
1169 rv = DoPayloadRead();
1170 network_moved = DoTransportIO();
1171 } while (rv == ERR_IO_PENDING && network_moved);
1172
1173 LeaveFunction("");
1174 return rv;
1175}
1176
1177int SSLClientSocketNSS::DoWriteLoop(int result) {
1178 EnterFunction("");
1179 DCHECK(completed_handshake_);
1180 DCHECK(next_handshake_state_ == STATE_NONE);
1181
1182 if (result < 0)
1183 return result;
1184
1185 if (!nss_bufs_)
1186 return ERR_UNEXPECTED;
1187
1188 bool network_moved;
1189 int rv;
1190 do {
1191 rv = DoPayloadWrite();
1192 network_moved = DoTransportIO();
1193 } while (rv == ERR_IO_PENDING && network_moved);
1194
[email protected]e17b4c12008-11-05 22:04:081195 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:581196 return rv;
1197}
1198
[email protected]bacff652009-03-31 17:50:331199// static
1200// NSS calls this if an incoming certificate needs to be verified.
[email protected]2345cc52009-06-04 09:18:471201// Do nothing but return SECSuccess.
1202// This is called only in full handshake mode.
1203// Peer certificate is retrieved in HandshakeCallback() later, which is called
1204// in full handshake mode or in resumption handshake mode.
[email protected]bacff652009-03-31 17:50:331205SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg,
1206 PRFileDesc* socket,
1207 PRBool checksig,
1208 PRBool is_server) {
[email protected]2345cc52009-06-04 09:18:471209 // Tell NSS to not verify the certificate.
1210 return SECSuccess;
1211}
1212
1213// static
[email protected]d84b3722009-10-15 21:23:371214// NSS calls this if a client certificate is needed.
1215// Based on Mozilla's NSS_GetClientAuthData.
1216SECStatus SSLClientSocketNSS::ClientAuthHandler(
1217 void* arg,
1218 PRFileDesc* socket,
1219 CERTDistNames* ca_names,
1220 CERTCertificate** result_certificate,
1221 SECKEYPrivateKey** result_private_key) {
1222 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
1223
1224 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert;
1225
[email protected]1d583612010-03-12 17:47:141226#if defined(OS_WIN)
1227 if (that->ssl_config_.send_client_cert) {
1228 // TODO(wtc): SSLClientSocketNSS can't do SSL client authentication using
1229 // CryptoAPI yet (http://crbug.com/37560), so client_cert must be NULL.
1230 DCHECK(!that->ssl_config_.client_cert);
1231 // Send no client certificate.
1232 return SECFailure;
1233 }
1234
1235 that->client_certs_.clear();
1236
1237 std::vector<CERT_NAME_BLOB> issuer_list(ca_names->nnames);
1238 for (int i = 0; i < ca_names->nnames; ++i) {
1239 issuer_list[i].cbData = ca_names->names[i].len;
1240 issuer_list[i].pbData = ca_names->names[i].data;
1241 }
1242
1243 // Client certificates of the user are in the "MY" system certificate store.
1244 HCERTSTORE my_cert_store = CertOpenSystemStore(NULL, L"MY");
1245 if (!my_cert_store) {
1246 LOG(ERROR) << "Could not open the \"MY\" system certificate store: "
1247 << GetLastError();
1248 return SECFailure;
1249 }
1250
1251 // Enumerate the client certificates.
1252 CERT_CHAIN_FIND_BY_ISSUER_PARA find_by_issuer_para;
1253 memset(&find_by_issuer_para, 0, sizeof(find_by_issuer_para));
1254 find_by_issuer_para.cbSize = sizeof(find_by_issuer_para);
1255 find_by_issuer_para.pszUsageIdentifier = szOID_PKIX_KP_CLIENT_AUTH;
1256 find_by_issuer_para.cIssuer = ca_names->nnames;
1257 find_by_issuer_para.rgIssuer = ca_names->nnames ? &issuer_list[0] : NULL;
1258
1259 PCCERT_CHAIN_CONTEXT chain_context = NULL;
1260
[email protected]3dd6f5e2010-06-01 20:28:031261 // TODO(wtc): close cert_store_ at shutdown.
1262 if (!cert_store_)
1263 cert_store_ = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL);
1264
[email protected]1d583612010-03-12 17:47:141265 for (;;) {
1266 // Find a certificate chain.
1267 chain_context = CertFindChainInStore(my_cert_store,
1268 X509_ASN_ENCODING,
1269 0,
1270 CERT_CHAIN_FIND_BY_ISSUER,
1271 &find_by_issuer_para,
1272 chain_context);
1273 if (!chain_context) {
1274 DWORD err = GetLastError();
1275 if (err != CRYPT_E_NOT_FOUND)
1276 DLOG(ERROR) << "CertFindChainInStore failed: " << err;
1277 break;
1278 }
1279
1280 // Get the leaf certificate.
1281 PCCERT_CONTEXT cert_context =
1282 chain_context->rgpChain[0]->rgpElement[0]->pCertContext;
1283 // Copy it to our own certificate store, so that we can close the "MY"
1284 // certificate store before returning from this function.
1285 PCCERT_CONTEXT cert_context2;
1286 BOOL ok = CertAddCertificateContextToStore(cert_store_, cert_context,
1287 CERT_STORE_ADD_USE_EXISTING,
1288 &cert_context2);
1289 if (!ok) {
1290 NOTREACHED();
1291 continue;
1292 }
1293 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
1294 cert_context2, X509Certificate::SOURCE_LONE_CERT_IMPORT,
[email protected]1c8857bc2010-06-26 18:44:051295 X509Certificate::OSCertHandles());
1296 X509Certificate::FreeOSCertHandle(cert_context2);
[email protected]1d583612010-03-12 17:47:141297 that->client_certs_.push_back(cert);
1298 }
1299
1300 BOOL ok = CertCloseStore(my_cert_store, CERT_CLOSE_STORE_CHECK_FLAG);
1301 DCHECK(ok);
1302
1303 // Tell NSS to suspend the client authentication. We will then abort the
1304 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
1305 return SECWouldBlock;
[email protected]3dd6f5e2010-06-01 20:28:031306#elif defined(OS_MACOSX)
[email protected]fd4f139f2010-06-11 17:02:201307 if (that->ssl_config_.send_client_cert) {
1308 // TODO(wtc): SSLClientSocketNSS can't do SSL client authentication using
1309 // CDSA/CSSM yet (http://crbug.com/45369), so client_cert must be NULL.
1310 DCHECK(!that->ssl_config_.client_cert);
1311 // Send no client certificate.
1312 return SECFailure;
1313 }
1314
1315 that->client_certs_.clear();
1316
1317 // First, get the cert issuer names allowed by the server.
1318 std::vector<CertPrincipal> valid_issuers;
1319 int n = ca_names->nnames;
1320 for (int i = 0; i < n; i++) {
1321 // Parse each name into a CertPrincipal object.
1322 CertPrincipal p;
1323 if (p.ParseDistinguishedName(ca_names->names[i].data,
1324 ca_names->names[i].len)) {
1325 valid_issuers.push_back(p);
1326 }
1327 }
1328
1329 // Now get the available client certs whose issuers are allowed by the server.
1330 X509Certificate::GetSSLClientCertificates(that->hostname_,
1331 valid_issuers,
1332 &that->client_certs_);
1333
1334 // Tell NSS to suspend the client authentication. We will then abort the
1335 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
1336 return SECWouldBlock;
[email protected]1d583612010-03-12 17:47:141337#else
[email protected]b8fee152009-10-24 03:39:311338 CERTCertificate* cert = NULL;
1339 SECKEYPrivateKey* privkey = NULL;
1340 void* wincx = SSL_RevealPinArg(socket);
1341
[email protected]d84b3722009-10-15 21:23:371342 // Second pass: a client certificate should have been selected.
1343 if (that->ssl_config_.send_client_cert) {
1344 if (that->ssl_config_.client_cert) {
[email protected]b8fee152009-10-24 03:39:311345 cert = CERT_DupCertificate(
[email protected]d84b3722009-10-15 21:23:371346 that->ssl_config_.client_cert->os_cert_handle());
[email protected]b8fee152009-10-24 03:39:311347 privkey = PK11_FindKeyByAnyCert(cert, wincx);
[email protected]d84b3722009-10-15 21:23:371348 if (privkey) {
1349 // TODO(jsorianopastor): We should wait for server certificate
1350 // verification before sending our credentials. See
1351 // http://crbug.com/13934.
1352 *result_certificate = cert;
1353 *result_private_key = privkey;
1354 return SECSuccess;
1355 }
1356 LOG(WARNING) << "Client cert found without private key";
1357 }
1358 // Send no client certificate.
1359 return SECFailure;
1360 }
1361
[email protected]b8fee152009-10-24 03:39:311362 CERTCertNicknames* names = CERT_GetCertNicknames(
1363 CERT_GetDefaultCertDB(), SEC_CERT_NICKNAMES_USER, wincx);
1364 if (names) {
1365 for (int i = 0; i < names->numnicknames; ++i) {
1366 cert = CERT_FindUserCertByUsage(
1367 CERT_GetDefaultCertDB(), names->nicknames[i],
1368 certUsageSSLClient, PR_FALSE, wincx);
1369 if (!cert)
1370 continue;
1371 // Only check unexpired certs.
1372 if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_TRUE) ==
[email protected]4d3040f42010-04-14 02:40:201373 secCertTimeValid && (!ca_names->nnames ||
1374 NSS_CmpCertChainWCANames(cert, ca_names) == SECSuccess)) {
[email protected]b8fee152009-10-24 03:39:311375 privkey = PK11_FindKeyByAnyCert(cert, wincx);
1376 if (privkey) {
1377 X509Certificate* x509_cert = X509Certificate::CreateFromHandle(
[email protected]4bee851c2010-03-05 23:44:451378 cert, X509Certificate::SOURCE_LONE_CERT_IMPORT,
1379 net::X509Certificate::OSCertHandles());
[email protected]b8fee152009-10-24 03:39:311380 that->client_certs_.push_back(x509_cert);
[email protected]1c8857bc2010-06-26 18:44:051381 CERT_DestroyCertificate(cert);
[email protected]b8fee152009-10-24 03:39:311382 SECKEY_DestroyPrivateKey(privkey);
1383 continue;
1384 }
1385 }
1386 CERT_DestroyCertificate(cert);
1387 }
1388 CERT_FreeNicknames(names);
1389 }
[email protected]d84b3722009-10-15 21:23:371390
[email protected]f6ee0a012010-03-05 22:00:241391 // Tell NSS to suspend the client authentication. We will then abort the
1392 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
1393 return SECWouldBlock;
[email protected]f505a9b2010-01-28 19:44:021394#endif
[email protected]d84b3722009-10-15 21:23:371395}
1396
1397// static
[email protected]2345cc52009-06-04 09:18:471398// NSS calls this when handshake is completed.
1399// After the SSL handshake is finished, use CertVerifier to verify
1400// the saved server certificate.
1401void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket,
1402 void* arg) {
[email protected]bacff652009-03-31 17:50:331403 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
1404
[email protected]39afe642010-04-29 14:55:181405 that->set_handshake_callback_called();
1406
[email protected]2345cc52009-06-04 09:18:471407 that->UpdateServerCert();
[email protected]1e7cd2c72010-02-27 01:31:191408
1409 that->CheckSecureRenegotiation();
[email protected]2345cc52009-06-04 09:18:471410}
[email protected]bacff652009-03-31 17:50:331411
[email protected]a3ff5e92009-10-13 04:48:061412int SSLClientSocketNSS::DoHandshake() {
[email protected]2345cc52009-06-04 09:18:471413 EnterFunction("");
1414 int net_error = net::OK;
[email protected]d84b3722009-10-15 21:23:371415 SECStatus rv = SSL_ForceHandshake(nss_fd_);
[email protected]2345cc52009-06-04 09:18:471416
[email protected]d84b3722009-10-15 21:23:371417 if (client_auth_cert_needed_) {
1418 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
1419 // If the handshake already succeeded (because the server requests but
1420 // doesn't require a client cert), we need to invalidate the SSL session
1421 // so that we won't try to resume the non-client-authenticated session in
1422 // the next handshake. This will cause the server to ask for a client
1423 // cert again.
1424 if (rv == SECSuccess && SSL_InvalidateSession(nss_fd_) != SECSuccess) {
1425 LOG(WARNING) << "Couldn't invalidate SSL session: " << PR_GetError();
1426 }
1427 } else if (rv == SECSuccess) {
[email protected]39afe642010-04-29 14:55:181428 if (handshake_callback_called_) {
1429 // SSL handshake is completed. Let's verify the certificate.
1430 GotoState(STATE_VERIFY_CERT);
1431 // Done!
1432 } else {
1433 // SSL_ForceHandshake returned SECSuccess prematurely.
1434 rv = SECFailure;
1435 net_error = ERR_SSL_PROTOCOL_ERROR;
1436 }
[email protected]2345cc52009-06-04 09:18:471437 } else {
1438 PRErrorCode prerr = PR_GetError();
[email protected]2e9a5b6982010-01-15 22:29:031439 net_error = MapHandshakeError(prerr);
[email protected]2345cc52009-06-04 09:18:471440
1441 // If not done, stay in this state
1442 if (net_error == ERR_IO_PENDING) {
[email protected]a3ff5e92009-10-13 04:48:061443 GotoState(STATE_HANDSHAKE);
[email protected]2345cc52009-06-04 09:18:471444 } else {
1445 LOG(ERROR) << "handshake failed; NSS error code " << prerr
1446 << ", net_error " << net_error;
1447 }
1448 }
1449
1450 LeaveFunction("");
1451 return net_error;
1452}
1453
1454int SSLClientSocketNSS::DoVerifyCert(int result) {
1455 DCHECK(server_cert_);
1456 GotoState(STATE_VERIFY_CERT_COMPLETE);
[email protected]f6555ad2009-06-23 06:35:051457 int flags = 0;
[email protected]a89eda42010-02-18 01:45:391458
1459 /* Disable revocation checking for SPDY. This is a hack, but we ignore
1460 * certificate errors for SPDY anyway so it's no loss in security. This lets
1461 * us benchmark as if we had OCSP stapling.
1462 *
1463 * http://crbug.com/32020
1464 */
1465 unsigned char buf[255];
1466 int state;
1467 unsigned int len;
1468 SECStatus rv = SSL_GetNextProto(nss_fd_, &state, buf, &len, sizeof(buf));
1469 bool spdy = (rv == SECSuccess && state == SSL_NEXT_PROTO_NEGOTIATED &&
1470 len == 4 && memcmp(buf, "spdy", 4) == 0);
1471
1472 if (ssl_config_.rev_checking_enabled && !spdy)
[email protected]f6555ad2009-06-23 06:35:051473 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED;
1474 if (ssl_config_.verify_ev_cert)
1475 flags |= X509Certificate::VERIFY_EV_CERT;
[email protected]92d9cad2009-06-25 23:40:241476 verifier_.reset(new CertVerifier);
1477 return verifier_->Verify(server_cert_, hostname_, flags,
[email protected]a3ff5e92009-10-13 04:48:061478 &server_cert_verify_result_,
1479 &handshake_io_callback_);
[email protected]2345cc52009-06-04 09:18:471480}
1481
1482// Derived from AuthCertificateCallback() in
1483// mozilla/source/security/manager/ssl/src/nsNSSCallbacks.cpp.
1484int SSLClientSocketNSS::DoVerifyCertComplete(int result) {
[email protected]92d9cad2009-06-25 23:40:241485 DCHECK(verifier_.get());
1486 verifier_.reset();
1487
[email protected]c07a2eb2009-06-08 04:49:351488 if (result == OK) {
[email protected]bf0136d2009-05-29 05:55:041489 // Remember the intermediate CA certs if the server sends them to us.
[email protected]52f3fad2009-09-21 19:27:361490 //
1491 // We used to remember the intermediate CA certs in the NSS database
1492 // persistently. However, NSS opens a connection to the SQLite database
1493 // during NSS initialization and doesn't close the connection until NSS
1494 // shuts down. If the file system where the database resides is gone,
1495 // the database connection goes bad. What's worse, the connection won't
1496 // recover when the file system comes back. Until this NSS or SQLite bug
1497 // is fixed, we need to avoid using the NSS database for non-essential
1498 // purposes. See https://bugzilla.mozilla.org/show_bug.cgi?id=508081 and
1499 // http://crbug.com/15630 for more info.
[email protected]c07a2eb2009-06-08 04:49:351500 CERTCertList* cert_list = CERT_GetCertChainFromCert(
[email protected]f505a9b2010-01-28 19:44:021501 server_cert_nss_, PR_Now(), certUsageSSLCA);
[email protected]c07a2eb2009-06-08 04:49:351502 if (cert_list) {
1503 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
1504 !CERT_LIST_END(node, cert_list);
1505 node = CERT_LIST_NEXT(node)) {
1506 if (node->cert->slot || node->cert->isRoot || node->cert->isperm ||
[email protected]f505a9b2010-01-28 19:44:021507 node->cert == server_cert_nss_) {
[email protected]c07a2eb2009-06-08 04:49:351508 // Some certs we don't want to remember are:
1509 // - found on a token.
1510 // - the root cert.
1511 // - already stored in perm db.
1512 // - the server cert itself.
1513 continue;
1514 }
[email protected]bf0136d2009-05-29 05:55:041515
[email protected]c07a2eb2009-06-08 04:49:351516 // We have found a CA cert that we want to remember.
[email protected]52f3fad2009-09-21 19:27:361517 // TODO(wtc): Remember the intermediate CA certs in a std::set
1518 // temporarily (http://crbug.com/15630).
[email protected]bf0136d2009-05-29 05:55:041519 }
[email protected]c07a2eb2009-06-08 04:49:351520 CERT_DestroyCertList(cert_list);
[email protected]bf0136d2009-05-29 05:55:041521 }
1522 }
1523
[email protected]2345cc52009-06-04 09:18:471524 // If we have been explicitly told to accept this certificate, override the
1525 // result of verifier_.Verify.
1526 // Eventually, we should cache the cert verification results so that we don't
1527 // need to call verifier_.Verify repeatedly. But for now we need to do this.
[email protected]127017872009-08-13 17:54:421528 // Alternatively, we could use the cert's status that we stored along with
1529 // the cert in the allowed_bad_certs vector.
[email protected]2345cc52009-06-04 09:18:471530 if (IsCertificateError(result) &&
[email protected]127017872009-08-13 17:54:421531 ssl_config_.IsAllowedBadCert(server_cert_)) {
[email protected]bacff652009-03-31 17:50:331532 LOG(INFO) << "accepting bad SSL certificate, as user told us to";
[email protected]2345cc52009-06-04 09:18:471533 result = OK;
[email protected]b43c97c2008-10-22 19:50:581534 }
[email protected]ea224582008-12-07 20:25:461535
[email protected]2345cc52009-06-04 09:18:471536 completed_handshake_ = true;
[email protected]f6ee0a012010-03-05 22:00:241537 // TODO(ukai): we may not need this call because it is now harmless to have a
[email protected]2345cc52009-06-04 09:18:471538 // session with a bad cert.
1539 InvalidateSessionIfBadCertificate();
[email protected]a3ff5e92009-10-13 04:48:061540 // Exit DoHandshakeLoop and return the result to the caller to Connect.
1541 DCHECK(next_handshake_state_ == STATE_NONE);
[email protected]2345cc52009-06-04 09:18:471542 return result;
[email protected]b43c97c2008-10-22 19:50:581543}
[email protected]ea224582008-12-07 20:25:461544
[email protected]b43c97c2008-10-22 19:50:581545int SSLClientSocketNSS::DoPayloadRead() {
[email protected]a3ff5e92009-10-13 04:48:061546 EnterFunction(user_read_buf_len_);
1547 DCHECK(user_read_buf_);
[email protected]1d583612010-03-12 17:47:141548 DCHECK_GT(user_read_buf_len_, 0);
[email protected]a3ff5e92009-10-13 04:48:061549 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_);
[email protected]d84b3722009-10-15 21:23:371550 if (client_auth_cert_needed_) {
1551 // We don't need to invalidate the non-client-authenticated SSL session
1552 // because the server will renegotiate anyway.
1553 LeaveFunction("");
1554 return ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
1555 }
[email protected]e17b4c12008-11-05 22:04:081556 if (rv >= 0) {
[email protected]a3ff5e92009-10-13 04:48:061557 LogData(user_read_buf_->data(), rv);
[email protected]e17b4c12008-11-05 22:04:081558 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:581559 return rv;
[email protected]e17b4c12008-11-05 22:04:081560 }
[email protected]b43c97c2008-10-22 19:50:581561 PRErrorCode prerr = PR_GetError();
1562 if (prerr == PR_WOULD_BLOCK_ERROR) {
[email protected]e17b4c12008-11-05 22:04:081563 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:581564 return ERR_IO_PENDING;
1565 }
[email protected]e17b4c12008-11-05 22:04:081566 LeaveFunction("");
[email protected]2e9a5b6982010-01-15 22:29:031567 return MapNSPRError(prerr);
[email protected]b43c97c2008-10-22 19:50:581568}
1569
1570int SSLClientSocketNSS::DoPayloadWrite() {
[email protected]a3ff5e92009-10-13 04:48:061571 EnterFunction(user_write_buf_len_);
1572 DCHECK(user_write_buf_);
1573 int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_);
[email protected]e17b4c12008-11-05 22:04:081574 if (rv >= 0) {
[email protected]a3ff5e92009-10-13 04:48:061575 LogData(user_write_buf_->data(), rv);
[email protected]e17b4c12008-11-05 22:04:081576 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:581577 return rv;
[email protected]e17b4c12008-11-05 22:04:081578 }
[email protected]b43c97c2008-10-22 19:50:581579 PRErrorCode prerr = PR_GetError();
1580 if (prerr == PR_WOULD_BLOCK_ERROR) {
[email protected]4d3040f42010-04-14 02:40:201581 LeaveFunction("");
[email protected]b43c97c2008-10-22 19:50:581582 return ERR_IO_PENDING;
1583 }
[email protected]e17b4c12008-11-05 22:04:081584 LeaveFunction("");
[email protected]2e9a5b6982010-01-15 22:29:031585 return MapNSPRError(prerr);
[email protected]b43c97c2008-10-22 19:50:581586}
1587
1588} // namespace net