Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(379)

Side by Side Diff: net/base/ssl_client_socket_nss.cc

Issue 12930: Third time's a charm?... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/base/ssl_client_socket_nss.h ('k') | net/base/ssl_test_util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/ssl_client_socket_nss.h" 5 #include "net/base/ssl_client_socket_nss.h"
6 6
7 #include <nspr.h> 7 #include <nspr.h>
8 #include <nss.h> 8 #include <nss.h>
9 #include <secerr.h>
9 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424 10 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424
10 // until NSS 3.12.2 comes out and we update to it. 11 // until NSS 3.12.2 comes out and we update to it.
11 #define Lock FOO_NSS_Lock 12 #define Lock FOO_NSS_Lock
12 #include <ssl.h> 13 #include <ssl.h>
14 #include <sslerr.h>
13 #include <pk11pub.h> 15 #include <pk11pub.h>
14 #undef Lock 16 #undef Lock
15 17
16 #include "base/logging.h" 18 #include "base/logging.h"
17 #include "base/nss_init.h" 19 #include "base/nss_init.h"
18 #include "base/string_util.h" 20 #include "base/string_util.h"
19 #include "net/base/net_errors.h" 21 #include "net/base/net_errors.h"
20 #include "net/base/ssl_info.h" 22 #include "net/base/ssl_info.h"
21 23
22 static const int kRecvBufferSize = 4096; 24 static const int kRecvBufferSize = 4096;
23 25
24 /* 26 // nss calls this if an incoming certificate is invalid.
25 * nss calls this if an incoming certificate is invalid. 27 static SECStatus ownBadCertHandler(void* arg, PRFileDesc* socket) {
26 * TODO(port): expose to app via GetSSLInfo so it can put up 28 PRErrorCode err = PR_GetError();
27 * the appropriate GUI and retry with override if desired 29 LOG(INFO) << "server certificate is invalid; NSS error code " << err;
28 */ 30 // Return SECSuccess to override the problem,
29 static SECStatus 31 // or SECFailure to let the original function fail
30 ownBadCertHandler(void * arg, PRFileDesc * socket) 32 // Chromium wants it to fail here, and may retry it later.
31 { 33 return SECFailure;
32 PRErrorCode err = PR_GetError();
33 LOG(ERROR) << "server certificate is invalid; NSS error code " << err;
34 // Return SECSuccess to override the problem, SECFailure to let the original function fail
35 return SECSuccess; /* override, say it's OK. */
36 } 34 }
37 35
38 36
39 namespace net { 37 namespace net {
40 38
41 // State machines are easier to debug if you log state transitions. 39 // State machines are easier to debug if you log state transitions.
42 // Enable these if you want to see what's going on. 40 // Enable these if you want to see what's going on.
43 #if 1 41 #if 1
44 #define EnterFunction(x) 42 #define EnterFunction(x)
45 #define LeaveFunction(x) 43 #define LeaveFunction(x)
46 #define GotoState(s) next_state_ = s 44 #define GotoState(s) next_state_ = s
45 #define LogData(s, len)
47 #else 46 #else
48 #define EnterFunction(x) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \ 47 #define EnterFunction(x) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \
49 " enter " << x << "; next_state " << next_state_ 48 " enter " << x << "; next_state " << next_state_
50 #define LeaveFunction(x) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \ 49 #define LeaveFunction(x) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \
51 " leave " << x << "; next_state " << next_state_ 50 " leave " << x << "; next_state " << next_state_
52 #define GotoState(s) do { LOG(INFO) << (void *)this << " " << __FUNCTION__ << \ 51 #define GotoState(s) do { LOG(INFO) << (void *)this << " " << __FUNCTION__ << \
53 " jump to state " << s; next_state_ = s; } while (0) 52 " jump to state " << s; next_state_ = s; } while (0)
53 #define LogData(s, len) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \
54 " data [" << std::string(s, len) << "]";
55
54 #endif 56 #endif
55 57
58 namespace {
59
60 int NetErrorFromNSPRError(PRErrorCode err) {
61 // TODO(port): fill this out as we learn what's important
62 switch (err) {
63 case PR_WOULD_BLOCK_ERROR:
64 return ERR_IO_PENDING;
65 case SSL_ERROR_NO_CYPHER_OVERLAP:
66 return ERR_SSL_VERSION_OR_CIPHER_MISMATCH;
67 case SSL_ERROR_BAD_CERT_DOMAIN:
68 return ERR_CERT_COMMON_NAME_INVALID;
69 case SEC_ERROR_EXPIRED_CERTIFICATE:
70 return ERR_CERT_DATE_INVALID;
71 case SEC_ERROR_BAD_SIGNATURE:
72 return ERR_CERT_INVALID;
73 case SSL_ERROR_REVOKED_CERT_ALERT:
74 case SEC_ERROR_REVOKED_CERTIFICATE:
75 case SEC_ERROR_REVOKED_KEY:
76 return ERR_CERT_REVOKED;
77 case SEC_ERROR_UNKNOWN_ISSUER:
78 return ERR_CERT_AUTHORITY_INVALID;
79
80 default: {
81 if (IS_SSL_ERROR(err)) {
82 LOG(WARNING) << "Unknown SSL error " << err <<
83 " mapped to net::ERR_SSL_PROTOCOL_ERROR";
84 return ERR_SSL_PROTOCOL_ERROR;
85 }
86 if (IS_SEC_ERROR(err)) {
87 // TODO(port): Probably not the best mapping
88 LOG(WARNING) << "Unknown SEC error " << err <<
89 " mapped to net::ERR_CERT_INVALID";
90 return ERR_CERT_INVALID;
91 }
92 LOG(WARNING) << "Unknown error " << err <<
93 " mapped to net::ERR_FAILED";
94 return ERR_FAILED;
95 }
96 }
97 }
98
99 // Shared with the Windows code. TODO(avi): merge to a common place
100 int CertStatusFromNetError(int error) {
101 switch (error) {
102 case ERR_CERT_COMMON_NAME_INVALID:
103 return CERT_STATUS_COMMON_NAME_INVALID;
104 case ERR_CERT_DATE_INVALID:
105 return CERT_STATUS_DATE_INVALID;
106 case ERR_CERT_AUTHORITY_INVALID:
107 return CERT_STATUS_AUTHORITY_INVALID;
108 case ERR_CERT_NO_REVOCATION_MECHANISM:
109 return CERT_STATUS_NO_REVOCATION_MECHANISM;
110 case ERR_CERT_UNABLE_TO_CHECK_REVOCATION:
111 return CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
112 case ERR_CERT_REVOKED:
113 return CERT_STATUS_REVOKED;
114 case ERR_CERT_CONTAINS_ERRORS:
115 NOTREACHED();
116 // Falls through.
117 case ERR_CERT_INVALID:
118 return CERT_STATUS_INVALID;
119 default:
120 return 0;
121 }
122 }
123
124 } // namespace
125
56 bool SSLClientSocketNSS::nss_options_initialized_ = false; 126 bool SSLClientSocketNSS::nss_options_initialized_ = false;
57 127
58 SSLClientSocketNSS::SSLClientSocketNSS(ClientSocket* transport_socket, 128 SSLClientSocketNSS::SSLClientSocketNSS(ClientSocket* transport_socket,
59 const std::string& hostname, 129 const std::string& hostname,
60 const SSLConfig& ssl_config) 130 const SSLConfig& ssl_config)
61 : 131 :
62 buffer_send_callback_(this, &SSLClientSocketNSS::BufferSendComplete), 132 buffer_send_callback_(this, &SSLClientSocketNSS::BufferSendComplete),
63 buffer_recv_callback_(this, &SSLClientSocketNSS::BufferRecvComplete), 133 buffer_recv_callback_(this, &SSLClientSocketNSS::BufferRecvComplete),
64 transport_send_busy_(false), 134 transport_send_busy_(false),
65 transport_recv_busy_(false), 135 transport_recv_busy_(false),
66 io_callback_(this, &SSLClientSocketNSS::OnIOComplete), 136 io_callback_(this, &SSLClientSocketNSS::OnIOComplete),
67 transport_(transport_socket), 137 transport_(transport_socket),
68 hostname_(hostname), 138 hostname_(hostname),
69 ssl_config_(ssl_config), 139 ssl_config_(ssl_config),
70 user_callback_(NULL), 140 user_callback_(NULL),
71 user_buf_(NULL), 141 user_buf_(NULL),
72 user_buf_len_(0), 142 user_buf_len_(0),
143 server_cert_status_(0),
73 completed_handshake_(false), 144 completed_handshake_(false),
74 next_state_(STATE_NONE), 145 next_state_(STATE_NONE),
75 nss_fd_(NULL), 146 nss_fd_(NULL),
76 nss_bufs_(NULL) { 147 nss_bufs_(NULL) {
77 EnterFunction(""); 148 EnterFunction("");
78 } 149 }
79 150
80 SSLClientSocketNSS::~SSLClientSocketNSS() { 151 SSLClientSocketNSS::~SSLClientSocketNSS() {
81 EnterFunction(""); 152 EnterFunction("");
82 Disconnect(); 153 Disconnect();
(...skipping 17 matching lines...) Expand all
100 171
101 GotoState(STATE_CONNECT); 172 GotoState(STATE_CONNECT);
102 int rv = DoLoop(OK); 173 int rv = DoLoop(OK);
103 if (rv == ERR_IO_PENDING) 174 if (rv == ERR_IO_PENDING)
104 user_callback_ = callback; 175 user_callback_ = callback;
105 176
106 LeaveFunction(""); 177 LeaveFunction("");
107 return rv; 178 return rv;
108 } 179 }
109 180
110 int SSLClientSocketNSS::ReconnectIgnoringLastError(CompletionCallback* callback) { 181 int SSLClientSocketNSS::ReconnectIgnoringLastError(
182 CompletionCallback* callback) {
111 EnterFunction(""); 183 EnterFunction("");
112 // TODO(darin): implement me! 184 // TODO(darin): implement me!
113 LeaveFunction(""); 185 LeaveFunction("");
114 return ERR_FAILED; 186 return ERR_FAILED;
115 } 187 }
116 188
117 void SSLClientSocketNSS::Disconnect() { 189 void SSLClientSocketNSS::Disconnect() {
118 EnterFunction(""); 190 EnterFunction("");
119 // TODO(wtc): Send SSL close_notify alert. 191 // TODO(wtc): Send SSL close_notify alert.
120 if (nss_fd_ != NULL) { 192 if (nss_fd_ != NULL) {
121 PR_Close(nss_fd_); 193 PR_Close(nss_fd_);
122 nss_fd_ = NULL; 194 nss_fd_ = NULL;
123 } 195 }
124 completed_handshake_ = false; 196 completed_handshake_ = false;
125 transport_->Disconnect(); 197 transport_->Disconnect();
126 LeaveFunction(""); 198 LeaveFunction("");
127 } 199 }
128 200
129 bool SSLClientSocketNSS::IsConnected() const { 201 bool SSLClientSocketNSS::IsConnected() const {
130 EnterFunction(""); 202 EnterFunction("");
131 bool ret = completed_handshake_ && transport_->IsConnected(); 203 bool ret = completed_handshake_ && transport_->IsConnected();
132 LeaveFunction(""); 204 LeaveFunction("");
133 return ret; 205 return ret;
134 } 206 }
135 207
136 int SSLClientSocketNSS::Read(char* buf, int buf_len, 208 int SSLClientSocketNSS::Read(char* buf, int buf_len,
137 CompletionCallback* callback) { 209 CompletionCallback* callback) {
138 EnterFunction(buf_len); 210 EnterFunction(buf_len);
139 DCHECK(completed_handshake_); 211 DCHECK(completed_handshake_);
140 DCHECK(next_state_ == STATE_NONE); 212 DCHECK(next_state_ == STATE_NONE);
141 DCHECK(!user_callback_); 213 DCHECK(!user_callback_);
142 DCHECK(!user_buf_); 214 DCHECK(!user_buf_);
143 215
144 user_buf_ = buf; 216 user_buf_ = buf;
145 user_buf_len_ = buf_len; 217 user_buf_len_ = buf_len;
146 218
147 GotoState(STATE_PAYLOAD_READ); 219 GotoState(STATE_PAYLOAD_READ);
148 int rv = DoLoop(OK); 220 int rv = DoLoop(OK);
149 if (rv == ERR_IO_PENDING) 221 if (rv == ERR_IO_PENDING)
150 user_callback_ = callback; 222 user_callback_ = callback;
151 LeaveFunction(""); 223 LeaveFunction(rv);
152 return rv; 224 return rv;
153 } 225 }
154 226
155 int SSLClientSocketNSS::Write(const char* buf, int buf_len, 227 int SSLClientSocketNSS::Write(const char* buf, int buf_len,
156 CompletionCallback* callback) { 228 CompletionCallback* callback) {
157 EnterFunction(buf_len); 229 EnterFunction(buf_len);
158 DCHECK(completed_handshake_); 230 DCHECK(completed_handshake_);
159 DCHECK(next_state_ == STATE_NONE); 231 DCHECK(next_state_ == STATE_NONE);
160 DCHECK(!user_callback_); 232 DCHECK(!user_callback_);
161 DCHECK(!user_buf_); 233 DCHECK(!user_buf_);
162 234
163 user_buf_ = const_cast<char*>(buf); 235 user_buf_ = const_cast<char*>(buf);
164 user_buf_len_ = buf_len; 236 user_buf_len_ = buf_len;
165 237
166 GotoState(STATE_PAYLOAD_WRITE); 238 GotoState(STATE_PAYLOAD_WRITE);
167 int rv = DoLoop(OK); 239 int rv = DoLoop(OK);
168 if (rv == ERR_IO_PENDING) 240 if (rv == ERR_IO_PENDING)
169 user_callback_ = callback; 241 user_callback_ = callback;
170 LeaveFunction(""); 242 LeaveFunction(rv);
171 return rv; 243 return rv;
172 } 244 }
173 245
174 void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) { 246 void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) {
175 EnterFunction(""); 247 EnterFunction("");
176 // TODO(port): implement!
177 ssl_info->Reset(); 248 ssl_info->Reset();
249 SSLChannelInfo channel_info;
250 SECStatus ok = SSL_GetChannelInfo(nss_fd_,
251 &channel_info, sizeof(channel_info));
252 if (ok == SECSuccess) {
253 SSLCipherSuiteInfo cipher_info;
254 ok = SSL_GetCipherSuiteInfo(channel_info.cipherSuite,
255 &cipher_info, sizeof(cipher_info));
256 if (ok == SECSuccess) {
257 ssl_info->security_bits = cipher_info.effectiveKeyBits;
258 } else {
259 ssl_info->security_bits = -1;
260 NOTREACHED();
261 }
262 }
263 ssl_info->cert_status = server_cert_status_;
264 // TODO(port): implement X509Certificate so we can set the cert field!
265 // CERTCertificate *nssCert = SSL_PeerCertificate(nss_fd_);
178 LeaveFunction(""); 266 LeaveFunction("");
179 } 267 }
180 268
181 void SSLClientSocketNSS::DoCallback(int rv) { 269 void SSLClientSocketNSS::DoCallback(int rv) {
182 EnterFunction(rv); 270 EnterFunction(rv);
183 DCHECK(rv != ERR_IO_PENDING); 271 DCHECK(rv != ERR_IO_PENDING);
184 DCHECK(user_callback_); 272 DCHECK(user_callback_);
185 273
186 // since Run may result in Read being called, clear user_callback_ up front. 274 // since Run may result in Read being called, clear user_callback_ up front.
187 CompletionCallback* c = user_callback_; 275 CompletionCallback* c = user_callback_;
(...skipping 14 matching lines...) Expand all
202 // See _MD_unix_map_default_error in the NSS source 290 // See _MD_unix_map_default_error in the NSS source
203 // tree for inspiration. 291 // tree for inspiration.
204 static PRErrorCode MapErrorToNSS(int result) { 292 static PRErrorCode MapErrorToNSS(int result) {
205 if (result >=0) 293 if (result >=0)
206 return result; 294 return result;
207 // TODO(port): add real table 295 // TODO(port): add real table
208 LOG(ERROR) << "MapErrorToNSS " << result; 296 LOG(ERROR) << "MapErrorToNSS " << result;
209 return PR_UNKNOWN_ERROR; 297 return PR_UNKNOWN_ERROR;
210 } 298 }
211 299
212 /* 300 /*
213 * Do network I/O between the given buffer and the given socket. 301 * Do network I/O between the given buffer and the given socket.
214 * Return 0 for EOF, 302 * Return 0 for EOF,
215 * > 0 for bytes transferred immediately, 303 * > 0 for bytes transferred immediately,
216 * < 0 for error (or the non-error ERR_IO_PENDING). 304 * < 0 for error (or the non-error ERR_IO_PENDING).
217 */ 305 */
218 int SSLClientSocketNSS::BufferSend(void) { 306 int SSLClientSocketNSS::BufferSend(void) {
219 if (transport_send_busy_) return ERR_IO_PENDING; 307 if (transport_send_busy_) return ERR_IO_PENDING;
220 308
221 const char *buf; 309 const char *buf;
222 int nb = memio_GetWriteParams(nss_bufs_, &buf); 310 int nb = memio_GetWriteParams(nss_bufs_, &buf);
223 EnterFunction(nb); 311 EnterFunction(nb);
224 312
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 } 364 }
277 365
278 366
279 int SSLClientSocketNSS::DoLoop(int last_io_result) { 367 int SSLClientSocketNSS::DoLoop(int last_io_result) {
280 EnterFunction(last_io_result); 368 EnterFunction(last_io_result);
281 bool network_moved; 369 bool network_moved;
282 int rv = last_io_result; 370 int rv = last_io_result;
283 do { 371 do {
284 network_moved = false; 372 network_moved = false;
285 // Default to STATE_NONE for next state. 373 // Default to STATE_NONE for next state.
286 // (This is a quirk carried over from the windows 374 // (This is a quirk carried over from the windows
287 // implementation. It makes reading the logs a bit harder.) 375 // implementation. It makes reading the logs a bit harder.)
288 // State handlers can and often do call GotoState just 376 // State handlers can and often do call GotoState just
289 // to stay in the current state. 377 // to stay in the current state.
290 State state = next_state_; 378 State state = next_state_;
291 GotoState(STATE_NONE); 379 GotoState(STATE_NONE);
292 switch (state) { 380 switch (state) {
293 case STATE_NONE: 381 case STATE_NONE:
294 // we're just pumping data between the buffer and the network 382 // we're just pumping data between the buffer and the network
295 break; 383 break;
296 case STATE_CONNECT: 384 case STATE_CONNECT:
297 rv = DoConnect(); 385 rv = DoConnect();
298 break; 386 break;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 // Tell NSS who we're connected to 438 // Tell NSS who we're connected to
351 PRNetAddr peername; 439 PRNetAddr peername;
352 socklen_t len = sizeof(PRNetAddr); 440 socklen_t len = sizeof(PRNetAddr);
353 int err = transport_->GetPeerName((struct sockaddr *)&peername, &len); 441 int err = transport_->GetPeerName((struct sockaddr *)&peername, &len);
354 if (err) { 442 if (err) {
355 DLOG(ERROR) << "GetPeerName failed"; 443 DLOG(ERROR) << "GetPeerName failed";
356 return 9999; // TODO(port): real error 444 return 9999; // TODO(port): real error
357 } 445 }
358 memio_SetPeerName(nss_fd_, &peername); 446 memio_SetPeerName(nss_fd_, &peername);
359 447
360 // Grab pointer to buffers 448 // Grab pointer to buffers
361 nss_bufs_ = memio_GetSecret(nss_fd_); 449 nss_bufs_ = memio_GetSecret(nss_fd_);
362 450
363 /* Create SSL state machine */ 451 /* Create SSL state machine */
364 /* Push SSL onto our fake I/O socket */ 452 /* Push SSL onto our fake I/O socket */
365 nss_fd_ = SSL_ImportFD(NULL, nss_fd_); 453 nss_fd_ = SSL_ImportFD(NULL, nss_fd_);
366 if (nss_fd_ == NULL) { 454 if (nss_fd_ == NULL) {
367 return ERR_SSL_PROTOCOL_ERROR; // TODO(port): real error 455 return ERR_SSL_PROTOCOL_ERROR; // TODO(port): real error
368 } 456 }
369 // TODO(port): set more ssl options! Check errors! 457 // TODO(port): set more ssl options! Check errors!
370 458
371 int rv; 459 int rv;
372 460
373 rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE); 461 rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE);
374 if (rv != SECSuccess) 462 if (rv != SECSuccess)
375 return ERR_UNEXPECTED; 463 return ERR_UNEXPECTED;
376 464
377 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL2, ssl_config_.ssl2_enabled); 465 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL2, ssl_config_.ssl2_enabled);
378 if (rv != SECSuccess) 466 if (rv != SECSuccess)
379 return ERR_UNEXPECTED; 467 return ERR_UNEXPECTED;
380 468
469 // SNI is enabled automatically if TLS is enabled -- as long as
470 // SSL_V2_COMPATIBLE_HELLO isn't.
471 // So don't do V2 compatible hellos unless we're really using SSL2,
472 // to avoid errors like
473 // "common name `mail.google.com' != requested host name `gmail.com'"
474 rv = SSL_OptionSet(nss_fd_, SSL_V2_COMPATIBLE_HELLO,
475 ssl_config_.ssl2_enabled);
476 if (rv != SECSuccess)
477 return ERR_UNEXPECTED;
478
381 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL3, ssl_config_.ssl3_enabled); 479 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL3, ssl_config_.ssl3_enabled);
382 if (rv != SECSuccess) 480 if (rv != SECSuccess)
383 return ERR_UNEXPECTED; 481 return ERR_UNEXPECTED;
384 482
385 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL3, ssl_config_.tls1_enabled); 483 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_TLS, ssl_config_.tls1_enabled);
386 if (rv != SECSuccess) 484 if (rv != SECSuccess)
387 return ERR_UNEXPECTED; 485 return ERR_UNEXPECTED;
388 486
487 #ifdef SSL_ENABLE_SESSION_TICKETS
488 // Support RFC 5077
489 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_TRUE);
490 if (rv != SECSuccess)
491 LOG(INFO) << "SSL_ENABLE_SESSION_TICKETS failed. Old system nss?";
492 #else
493 #error "You need to install NSS-3.12 or later to build chromium"
494 #endif
495
389 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); 496 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
390 if (rv != SECSuccess) 497 if (rv != SECSuccess)
391 return ERR_UNEXPECTED; 498 return ERR_UNEXPECTED;
392 499
393 rv = SSL_BadCertHook(nss_fd_, ownBadCertHandler, NULL); 500 rv = SSL_BadCertHook(nss_fd_, ownBadCertHandler, NULL);
394 if (rv != SECSuccess) 501 if (rv != SECSuccess)
395 return ERR_UNEXPECTED; 502 return ERR_UNEXPECTED;
396 503
397 // Tell SSL the hostname we're trying to connect to. 504 // Tell SSL the hostname we're trying to connect to.
398 SSL_SetURL(nss_fd_, hostname_.c_str()); 505 SSL_SetURL(nss_fd_, hostname_.c_str());
399 506
400 // Tell SSL we're a client; needed if not letting NSPR do socket I/O 507 // Tell SSL we're a client; needed if not letting NSPR do socket I/O
401 SSL_ResetHandshake(nss_fd_, 0); 508 SSL_ResetHandshake(nss_fd_, 0);
402 GotoState(STATE_HANDSHAKE_READ); 509 GotoState(STATE_HANDSHAKE_READ);
403 // Return OK so DoLoop tries handshaking 510 // Return OK so DoLoop tries handshaking
404 LeaveFunction(""); 511 LeaveFunction("");
405 return OK; 512 return OK;
406 } 513 }
407 514
408 int SSLClientSocketNSS::DoHandshakeRead() { 515 int SSLClientSocketNSS::DoHandshakeRead() {
409 EnterFunction(""); 516 EnterFunction("");
517 int net_error;
410 int rv = SSL_ForceHandshake(nss_fd_); 518 int rv = SSL_ForceHandshake(nss_fd_);
519
411 if (rv == SECSuccess) { 520 if (rv == SECSuccess) {
521 net_error = OK;
412 // there's a callback for this, too 522 // there's a callback for this, too
413 completed_handshake_ = true; 523 completed_handshake_ = true;
414 // Indicate we're ready to handle I/O. Badly named? 524 // Indicate we're ready to handle I/O. Badly named?
415 GotoState(STATE_NONE); 525 GotoState(STATE_NONE);
416 LeaveFunction(""); 526 } else {
417 return OK; 527 PRErrorCode prerr = PR_GetError();
528 net_error = NetErrorFromNSPRError(prerr);
529
530 // If not done, stay in this state
531 if (net_error == ERR_IO_PENDING) {
532 GotoState(STATE_HANDSHAKE_READ);
533 } else {
534 server_cert_status_ = CertStatusFromNetError(net_error);
535 LOG(ERROR) << "handshake failed; NSS error code " << prerr
536 << ", net_error " << net_error << ", server_cert_status "
537 << server_cert_status_;
538 }
418 } 539 }
419 PRErrorCode prerr = PR_GetError(); 540
420 if (prerr == PR_WOULD_BLOCK_ERROR) {
421 // at this point, it should have tried to send some bytes
422 GotoState(STATE_HANDSHAKE_READ);
423 LeaveFunction("");
424 return ERR_IO_PENDING;
425 }
426 // TODO: map rv to net error code properly
427 LeaveFunction(""); 541 LeaveFunction("");
428 return ERR_SSL_PROTOCOL_ERROR; 542 return net_error;
429 } 543 }
430 544
431 int SSLClientSocketNSS::DoPayloadRead() { 545 int SSLClientSocketNSS::DoPayloadRead() {
432 EnterFunction(user_buf_len_); 546 EnterFunction(user_buf_len_);
433 int rv = PR_Read(nss_fd_, user_buf_, user_buf_len_); 547 int rv = PR_Read(nss_fd_, user_buf_, user_buf_len_);
434 if (rv >= 0) { 548 if (rv >= 0) {
549 LogData(user_buf_, rv);
435 user_buf_ = NULL; 550 user_buf_ = NULL;
436 LeaveFunction(""); 551 LeaveFunction("");
437 return rv; 552 return rv;
438 } 553 }
439 PRErrorCode prerr = PR_GetError(); 554 PRErrorCode prerr = PR_GetError();
440 if (prerr == PR_WOULD_BLOCK_ERROR) { 555 if (prerr == PR_WOULD_BLOCK_ERROR) {
441 GotoState(STATE_PAYLOAD_READ); 556 GotoState(STATE_PAYLOAD_READ);
442 LeaveFunction(""); 557 LeaveFunction("");
443 return ERR_IO_PENDING; 558 return ERR_IO_PENDING;
444 } 559 }
445 user_buf_ = NULL; 560 user_buf_ = NULL;
446 LeaveFunction(""); 561 LeaveFunction("");
447 // TODO: map rv to net error code properly 562 return NetErrorFromNSPRError(prerr);
448 return ERR_SSL_PROTOCOL_ERROR;
449 } 563 }
450 564
451 int SSLClientSocketNSS::DoPayloadWrite() { 565 int SSLClientSocketNSS::DoPayloadWrite() {
452 EnterFunction(user_buf_len_); 566 EnterFunction(user_buf_len_);
453 int rv = PR_Write(nss_fd_, user_buf_, user_buf_len_); 567 int rv = PR_Write(nss_fd_, user_buf_, user_buf_len_);
454 if (rv >= 0) { 568 if (rv >= 0) {
569 LogData(user_buf_, rv);
455 user_buf_ = NULL; 570 user_buf_ = NULL;
456 LeaveFunction(""); 571 LeaveFunction("");
457 return rv; 572 return rv;
458 } 573 }
459 PRErrorCode prerr = PR_GetError(); 574 PRErrorCode prerr = PR_GetError();
460 if (prerr == PR_WOULD_BLOCK_ERROR) { 575 if (prerr == PR_WOULD_BLOCK_ERROR) {
461 GotoState(STATE_PAYLOAD_WRITE); 576 GotoState(STATE_PAYLOAD_WRITE);
462 return ERR_IO_PENDING; 577 return ERR_IO_PENDING;
463 } 578 }
464 user_buf_ = NULL; 579 user_buf_ = NULL;
465 LeaveFunction(""); 580 LeaveFunction("");
466 // TODO: map rv to net error code properly 581 return NetErrorFromNSPRError(prerr);
467 return ERR_SSL_PROTOCOL_ERROR;
468 } 582 }
469 583
470 } // namespace net 584 } // namespace net
471 585
OLDNEW
« no previous file with comments | « net/base/ssl_client_socket_nss.h ('k') | net/base/ssl_test_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698