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

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

Issue 16207: Make ssl_client_socket_unittest use a local server (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 10 months 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_client_socket_unittest.cc » ('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 #include <secerr.h>
10 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424 10 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424
11 // 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.
12 #define Lock FOO_NSS_Lock 12 #define Lock FOO_NSS_Lock
13 #include <ssl.h> 13 #include <ssl.h>
14 #include <sslerr.h> 14 #include <sslerr.h>
15 #include <pk11pub.h> 15 #include <pk11pub.h>
16 #undef Lock 16 #undef Lock
17 17
18 #include "base/logging.h" 18 #include "base/logging.h"
19 #include "base/nss_init.h" 19 #include "base/nss_init.h"
20 #include "base/string_util.h" 20 #include "base/string_util.h"
21 #include "net/base/net_errors.h" 21 #include "net/base/net_errors.h"
22 #include "net/base/ssl_info.h" 22 #include "net/base/ssl_info.h"
23 23
24 static const int kRecvBufferSize = 4096; 24 static const int kRecvBufferSize = 4096;
25 25
26 namespace {
27
28 // NSS calls this if an incoming certificate is invalid.
29 SECStatus OwnBadCertHandler(void* arg, PRFileDesc* socket) {
30 PRErrorCode err = PR_GetError();
31 LOG(INFO) << "server certificate is invalid; NSS error code " << err;
32 // Return SECSuccess to override the problem,
33 // or SECFailure to let the original function fail
34 // Chromium wants it to fail here, and may retry it later.
35 LOG(WARNING) << "TODO(dkegel): return SECFailure here";
36 return SECSuccess;
37 }
38
39 } // anonymous namespace
40
41 namespace net { 26 namespace net {
42 27
43 // State machines are easier to debug if you log state transitions. 28 // State machines are easier to debug if you log state transitions.
44 // Enable these if you want to see what's going on. 29 // Enable these if you want to see what's going on.
45 #if 1 30 #if 1
46 #define EnterFunction(x) 31 #define EnterFunction(x)
47 #define LeaveFunction(x) 32 #define LeaveFunction(x)
48 #define GotoState(s) next_state_ = s 33 #define GotoState(s) next_state_ = s
49 #define LogData(s, len) 34 #define LogData(s, len)
50 #else 35 #else
(...skipping 21 matching lines...) Expand all
72 return ERR_CERT_COMMON_NAME_INVALID; 57 return ERR_CERT_COMMON_NAME_INVALID;
73 case SEC_ERROR_EXPIRED_CERTIFICATE: 58 case SEC_ERROR_EXPIRED_CERTIFICATE:
74 return ERR_CERT_DATE_INVALID; 59 return ERR_CERT_DATE_INVALID;
75 case SEC_ERROR_BAD_SIGNATURE: 60 case SEC_ERROR_BAD_SIGNATURE:
76 return ERR_CERT_INVALID; 61 return ERR_CERT_INVALID;
77 case SSL_ERROR_REVOKED_CERT_ALERT: 62 case SSL_ERROR_REVOKED_CERT_ALERT:
78 case SEC_ERROR_REVOKED_CERTIFICATE: 63 case SEC_ERROR_REVOKED_CERTIFICATE:
79 case SEC_ERROR_REVOKED_KEY: 64 case SEC_ERROR_REVOKED_KEY:
80 return ERR_CERT_REVOKED; 65 return ERR_CERT_REVOKED;
81 case SEC_ERROR_UNKNOWN_ISSUER: 66 case SEC_ERROR_UNKNOWN_ISSUER:
67 case SEC_ERROR_UNTRUSTED_CERT:
68 case SEC_ERROR_UNTRUSTED_ISSUER:
82 return ERR_CERT_AUTHORITY_INVALID; 69 return ERR_CERT_AUTHORITY_INVALID;
83 70
84 default: { 71 default: {
85 if (IS_SSL_ERROR(err)) { 72 if (IS_SSL_ERROR(err)) {
86 LOG(WARNING) << "Unknown SSL error " << err << 73 LOG(WARNING) << "Unknown SSL error " << err <<
87 " mapped to net::ERR_SSL_PROTOCOL_ERROR"; 74 " mapped to net::ERR_SSL_PROTOCOL_ERROR";
88 return ERR_SSL_PROTOCOL_ERROR; 75 return ERR_SSL_PROTOCOL_ERROR;
89 } 76 }
90 if (IS_SEC_ERROR(err)) { 77 if (IS_SEC_ERROR(err)) {
91 // TODO(port): Probably not the best mapping 78 // TODO(port): Probably not the best mapping
(...skipping 20 matching lines...) Expand all
112 buffer_recv_callback_(this, &SSLClientSocketNSS::BufferRecvComplete), 99 buffer_recv_callback_(this, &SSLClientSocketNSS::BufferRecvComplete),
113 transport_send_busy_(false), 100 transport_send_busy_(false),
114 transport_recv_busy_(false), 101 transport_recv_busy_(false),
115 io_callback_(this, &SSLClientSocketNSS::OnIOComplete), 102 io_callback_(this, &SSLClientSocketNSS::OnIOComplete),
116 transport_(transport_socket), 103 transport_(transport_socket),
117 hostname_(hostname), 104 hostname_(hostname),
118 ssl_config_(ssl_config), 105 ssl_config_(ssl_config),
119 user_callback_(NULL), 106 user_callback_(NULL),
120 user_buf_(NULL), 107 user_buf_(NULL),
121 user_buf_len_(0), 108 user_buf_len_(0),
122 server_cert_status_(0), 109 server_cert_error_(0),
123 completed_handshake_(false), 110 completed_handshake_(false),
124 next_state_(STATE_NONE), 111 next_state_(STATE_NONE),
125 nss_fd_(NULL), 112 nss_fd_(NULL),
126 nss_bufs_(NULL) { 113 nss_bufs_(NULL) {
127 EnterFunction(""); 114 EnterFunction("");
128 } 115 }
129 116
130 SSLClientSocketNSS::~SSLClientSocketNSS() { 117 SSLClientSocketNSS::~SSLClientSocketNSS() {
131 EnterFunction(""); 118 EnterFunction("");
132 Disconnect(); 119 Disconnect();
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 ok = SSL_GetCipherSuiteInfo(channel_info.cipherSuite, 222 ok = SSL_GetCipherSuiteInfo(channel_info.cipherSuite,
236 &cipher_info, sizeof(cipher_info)); 223 &cipher_info, sizeof(cipher_info));
237 if (ok == SECSuccess) { 224 if (ok == SECSuccess) {
238 ssl_info->security_bits = cipher_info.effectiveKeyBits; 225 ssl_info->security_bits = cipher_info.effectiveKeyBits;
239 } else { 226 } else {
240 ssl_info->security_bits = -1; 227 ssl_info->security_bits = -1;
241 LOG(DFATAL) << "SSL_GetCipherSuiteInfo returned " << PR_GetError() 228 LOG(DFATAL) << "SSL_GetCipherSuiteInfo returned " << PR_GetError()
242 << " for cipherSuite " << channel_info.cipherSuite; 229 << " for cipherSuite " << channel_info.cipherSuite;
243 } 230 }
244 } 231 }
245 ssl_info->cert_status = server_cert_status_; 232 if (server_cert_error_ != net::OK)
246 // TODO(port): implement X509Certificate so we can set the cert field! 233 ssl_info->SetCertError(server_cert_error_);
247 // CERTCertificate *nssCert = SSL_PeerCertificate(nss_fd_); 234 X509Certificate::OSCertHandle nss_cert = SSL_PeerCertificate(nss_fd_);
235 if (nss_cert)
236 ssl_info->cert = X509Certificate::CreateFromHandle(nss_cert,
237 X509Certificate::SOURCE_FROM_NETWORK);
248 LeaveFunction(""); 238 LeaveFunction("");
249 } 239 }
250 240
251 void SSLClientSocketNSS::DoCallback(int rv) { 241 void SSLClientSocketNSS::DoCallback(int rv) {
252 EnterFunction(rv); 242 EnterFunction(rv);
253 DCHECK(rv != ERR_IO_PENDING); 243 DCHECK(rv != ERR_IO_PENDING);
254 DCHECK(user_callback_); 244 DCHECK(user_callback_);
255 245
256 // since Run may result in Read being called, clear user_callback_ up front. 246 // since Run may result in Read being called, clear user_callback_ up front.
257 CompletionCallback* c = user_callback_; 247 CompletionCallback* c = user_callback_;
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 LeaveFunction(""); 384 LeaveFunction("");
395 return rv; 385 return rv;
396 } 386 }
397 387
398 int SSLClientSocketNSS::DoConnect() { 388 int SSLClientSocketNSS::DoConnect() {
399 EnterFunction(""); 389 EnterFunction("");
400 GotoState(STATE_CONNECT_COMPLETE); 390 GotoState(STATE_CONNECT_COMPLETE);
401 return transport_->Connect(&io_callback_); 391 return transport_->Connect(&io_callback_);
402 } 392 }
403 393
394 // static
395 // NSS calls this if an incoming certificate is invalid.
396 SECStatus SSLClientSocketNSS::OwnBadCertHandler(void* arg, PRFileDesc* socket) {
397 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
398 PRErrorCode prerr = PR_GetError();
399 that->server_cert_error_ = NetErrorFromNSPRError(prerr);
400 LOG(INFO) << "server certificate is invalid; NSS error code " << prerr
401 << ", net error " << that->server_cert_error_;
402 // Return SECSuccess to override the problem.
403 // Chromium wants it to succeed here, and may abort the connection later.
404 return SECSuccess;
405 }
406
404 int SSLClientSocketNSS::DoConnectComplete(int result) { 407 int SSLClientSocketNSS::DoConnectComplete(int result) {
405 EnterFunction(result); 408 EnterFunction(result);
406 if (result < 0) 409 if (result < 0)
407 return result; 410 return result;
408 411
409 if (Init() != OK) { 412 if (Init() != OK) {
410 NOTREACHED() << "Couldn't initialize nss"; 413 NOTREACHED() << "Couldn't initialize nss";
411 } 414 }
412 415
413 // Transport connected, now hook it up to nss 416 // Transport connected, now hook it up to nss
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 if (rv != SECSuccess) 475 if (rv != SECSuccess)
473 LOG(INFO) << "SSL_ENABLE_SESSION_TICKETS failed. Old system nss?"; 476 LOG(INFO) << "SSL_ENABLE_SESSION_TICKETS failed. Old system nss?";
474 #else 477 #else
475 #error "You need to install NSS-3.12 or later to build chromium" 478 #error "You need to install NSS-3.12 or later to build chromium"
476 #endif 479 #endif
477 480
478 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); 481 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
479 if (rv != SECSuccess) 482 if (rv != SECSuccess)
480 return ERR_UNEXPECTED; 483 return ERR_UNEXPECTED;
481 484
482 rv = SSL_BadCertHook(nss_fd_, OwnBadCertHandler, NULL); 485 rv = SSL_BadCertHook(nss_fd_, OwnBadCertHandler, this);
483 if (rv != SECSuccess) 486 if (rv != SECSuccess)
484 return ERR_UNEXPECTED; 487 return ERR_UNEXPECTED;
485 488
486 // Tell SSL the hostname we're trying to connect to. 489 // Tell SSL the hostname we're trying to connect to.
487 SSL_SetURL(nss_fd_, hostname_.c_str()); 490 SSL_SetURL(nss_fd_, hostname_.c_str());
488 491
489 // Tell SSL we're a client; needed if not letting NSPR do socket I/O 492 // Tell SSL we're a client; needed if not letting NSPR do socket I/O
490 SSL_ResetHandshake(nss_fd_, 0); 493 SSL_ResetHandshake(nss_fd_, 0);
491 GotoState(STATE_HANDSHAKE_READ); 494 GotoState(STATE_HANDSHAKE_READ);
492 // Return OK so DoLoop tries handshaking 495 // Return OK so DoLoop tries handshaking
493 LeaveFunction(""); 496 LeaveFunction("");
494 return OK; 497 return OK;
495 } 498 }
496 499
497 int SSLClientSocketNSS::DoHandshakeRead() { 500 int SSLClientSocketNSS::DoHandshakeRead() {
498 EnterFunction(""); 501 EnterFunction("");
499 int net_error; 502 int net_error;
500 int rv = SSL_ForceHandshake(nss_fd_); 503 int rv = SSL_ForceHandshake(nss_fd_);
501 504
502 if (rv == SECSuccess) { 505 if (rv == SECSuccess) {
503 net_error = OK; 506 net_error = server_cert_error_;
504 // there's a callback for this, too 507 // there's a callback for this, too
505 completed_handshake_ = true; 508 completed_handshake_ = true;
506 // Indicate we're ready to handle I/O. Badly named? 509 // Done!
507 GotoState(STATE_NONE);
508 } else { 510 } else {
509 PRErrorCode prerr = PR_GetError(); 511 PRErrorCode prerr = PR_GetError();
510 net_error = NetErrorFromNSPRError(prerr); 512 net_error = NetErrorFromNSPRError(prerr);
511 513
512 // If not done, stay in this state 514 // If not done, stay in this state
513 if (net_error == ERR_IO_PENDING) { 515 if (net_error == ERR_IO_PENDING) {
514 GotoState(STATE_HANDSHAKE_READ); 516 GotoState(STATE_HANDSHAKE_READ);
515 } else { 517 } else {
516 server_cert_status_ = MapNetErrorToCertStatus(net_error); 518 server_cert_error_ = net_error;
517 LOG(ERROR) << "handshake failed; NSS error code " << prerr 519 LOG(ERROR) << "handshake failed; NSS error code " << prerr
518 << ", net_error " << net_error << ", server_cert_status " 520 << ", net_error " << net_error;
519 << server_cert_status_;
520 } 521 }
521 } 522 }
522 523
523 LeaveFunction(""); 524 LeaveFunction("");
524 return net_error; 525 return net_error;
525 } 526 }
526 527
527 int SSLClientSocketNSS::DoPayloadRead() { 528 int SSLClientSocketNSS::DoPayloadRead() {
528 EnterFunction(user_buf_len_); 529 EnterFunction(user_buf_len_);
529 int rv = PR_Read(nss_fd_, user_buf_, user_buf_len_); 530 int rv = PR_Read(nss_fd_, user_buf_, user_buf_len_);
(...skipping 28 matching lines...) Expand all
558 GotoState(STATE_PAYLOAD_WRITE); 559 GotoState(STATE_PAYLOAD_WRITE);
559 return ERR_IO_PENDING; 560 return ERR_IO_PENDING;
560 } 561 }
561 user_buf_ = NULL; 562 user_buf_ = NULL;
562 LeaveFunction(""); 563 LeaveFunction("");
563 return NetErrorFromNSPRError(prerr); 564 return NetErrorFromNSPRError(prerr);
564 } 565 }
565 566
566 } // namespace net 567 } // namespace net
567 568
OLDNEW
« no previous file with comments | « net/base/ssl_client_socket_nss.h ('k') | net/base/ssl_client_socket_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698