OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/socket/ssl_server_socket_nss.h" | 5 #include "net/socket/ssl_server_socket_nss.h" |
6 | 6 |
7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
8 #include <winsock2.h> | 8 #include <winsock2.h> |
9 #endif | 9 #endif |
10 | 10 |
(...skipping 19 matching lines...) Expand all Loading... |
30 #include <limits> | 30 #include <limits> |
31 | 31 |
32 #include "base/callback_helpers.h" | 32 #include "base/callback_helpers.h" |
33 #include "base/lazy_instance.h" | 33 #include "base/lazy_instance.h" |
34 #include "base/logging.h" | 34 #include "base/logging.h" |
35 #include "base/memory/ref_counted.h" | 35 #include "base/memory/ref_counted.h" |
36 #include "crypto/nss_util_internal.h" | 36 #include "crypto/nss_util_internal.h" |
37 #include "crypto/rsa_private_key.h" | 37 #include "crypto/rsa_private_key.h" |
38 #include "net/base/io_buffer.h" | 38 #include "net/base/io_buffer.h" |
39 #include "net/base/net_errors.h" | 39 #include "net/base/net_errors.h" |
| 40 #include "net/cert/cert_verifier.h" |
| 41 #include "net/cert/cert_verify_result.h" |
40 #include "net/log/net_log.h" | 42 #include "net/log/net_log.h" |
41 #include "net/socket/nss_ssl_util.h" | 43 #include "net/socket/nss_ssl_util.h" |
| 44 #include "net/ssl/ssl_connection_status_flags.h" |
| 45 #include "net/ssl/ssl_info.h" |
42 | 46 |
43 // SSL plaintext fragments are shorter than 16KB. Although the record layer | 47 // SSL plaintext fragments are shorter than 16KB. Although the record layer |
44 // overhead is allowed to be 2K + 5 bytes, in practice the overhead is much | 48 // overhead is allowed to be 2K + 5 bytes, in practice the overhead is much |
45 // smaller than 1KB. So a 17KB buffer should be large enough to hold an | 49 // smaller than 1KB. So a 17KB buffer should be large enough to hold an |
46 // entire SSL record. | 50 // entire SSL record. |
47 static const int kRecvBufferSize = 17 * 1024; | 51 static const int kRecvBufferSize = 17 * 1024; |
48 static const int kSendBufferSize = 17 * 1024; | 52 static const int kSendBufferSize = 17 * 1024; |
49 | 53 |
50 #define GotoState(s) next_handshake_state_ = s | 54 #define GotoState(s) next_handshake_state_ = s |
51 | 55 |
(...skipping 11 matching lines...) Expand all Loading... |
63 SSL_ConfigServerSessionIDCache(64, 28800, 28800, NULL); | 67 SSL_ConfigServerSessionIDCache(64, 28800, 28800, NULL); |
64 g_nss_server_sockets_init = true; | 68 g_nss_server_sockets_init = true; |
65 } | 69 } |
66 | 70 |
67 ~NSSSSLServerInitSingleton() { | 71 ~NSSSSLServerInitSingleton() { |
68 SSL_ShutdownServerSessionIDCache(); | 72 SSL_ShutdownServerSessionIDCache(); |
69 g_nss_server_sockets_init = false; | 73 g_nss_server_sockets_init = false; |
70 } | 74 } |
71 }; | 75 }; |
72 | 76 |
| 77 void DoNothingOnCompletion(int ignore) {} |
| 78 |
73 static base::LazyInstance<NSSSSLServerInitSingleton>::Leaky | 79 static base::LazyInstance<NSSSSLServerInitSingleton>::Leaky |
74 g_nss_ssl_server_init_singleton = LAZY_INSTANCE_INITIALIZER; | 80 g_nss_ssl_server_init_singleton = LAZY_INSTANCE_INITIALIZER; |
75 | 81 |
76 } // namespace | 82 } // namespace |
77 | 83 |
78 void EnableSSLServerSockets() { | 84 void EnableSSLServerSockets() { |
79 g_nss_ssl_server_init_singleton.Get(); | 85 g_nss_ssl_server_init_singleton.Get(); |
80 } | 86 } |
81 | 87 |
82 scoped_ptr<SSLServerSocket> CreateSSLServerSocket( | 88 scoped_ptr<SSLServerSocket> CreateSSLServerSocket( |
83 scoped_ptr<StreamSocket> socket, | 89 scoped_ptr<StreamSocket> socket, |
84 X509Certificate* cert, | 90 X509Certificate* certificate, |
85 crypto::RSAPrivateKey* key, | 91 crypto::RSAPrivateKey* key, |
86 const SSLServerConfig& ssl_config) { | 92 const SSLServerConfig& ssl_config) { |
87 DCHECK(g_nss_server_sockets_init) << "EnableSSLServerSockets() has not been" | 93 DCHECK(g_nss_server_sockets_init) << "EnableSSLServerSockets() has not been" |
88 << " called yet!"; | 94 << " called yet!"; |
89 | 95 |
90 return scoped_ptr<SSLServerSocket>( | 96 return scoped_ptr<SSLServerSocket>( |
91 new SSLServerSocketNSS(socket.Pass(), cert, key, ssl_config)); | 97 new SSLServerSocketNSS(socket.Pass(), certificate, key, ssl_config)); |
92 } | 98 } |
93 | 99 |
94 SSLServerSocketNSS::SSLServerSocketNSS( | 100 SSLServerSocketNSS::SSLServerSocketNSS( |
95 scoped_ptr<StreamSocket> transport_socket, | 101 scoped_ptr<StreamSocket> transport_socket, |
96 scoped_refptr<X509Certificate> cert, | 102 scoped_refptr<X509Certificate> cert, |
97 crypto::RSAPrivateKey* key, | 103 crypto::RSAPrivateKey* key, |
98 const SSLServerConfig& ssl_config) | 104 const SSLServerConfig& ssl_config) |
99 : transport_send_busy_(false), | 105 : transport_send_busy_(false), |
100 transport_recv_busy_(false), | 106 transport_recv_busy_(false), |
101 user_read_buf_len_(0), | 107 user_read_buf_len_(0), |
102 user_write_buf_len_(0), | 108 user_write_buf_len_(0), |
103 nss_fd_(NULL), | 109 nss_fd_(NULL), |
104 nss_bufs_(NULL), | 110 nss_bufs_(NULL), |
105 transport_socket_(transport_socket.Pass()), | 111 transport_socket_(transport_socket.Pass()), |
106 ssl_config_(ssl_config), | 112 ssl_config_(ssl_config), |
107 cert_(cert), | 113 cert_(cert), |
108 next_handshake_state_(STATE_NONE), | 114 next_handshake_state_(STATE_NONE), |
109 completed_handshake_(false) { | 115 completed_handshake_(false), |
| 116 client_cert_ca_list_(), |
| 117 client_cert_verifier_(NULL) { |
110 // TODO(hclam): Need a better way to clone a key. | 118 // TODO(hclam): Need a better way to clone a key. |
111 std::vector<uint8> key_bytes; | 119 std::vector<uint8> key_bytes; |
112 CHECK(key->ExportPrivateKey(&key_bytes)); | 120 CHECK(key->ExportPrivateKey(&key_bytes)); |
113 key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes)); | 121 key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes)); |
114 CHECK(key_.get()); | 122 CHECK(key_.get()); |
115 } | 123 } |
116 | 124 |
117 SSLServerSocketNSS::~SSLServerSocketNSS() { | 125 SSLServerSocketNSS::~SSLServerSocketNSS() { |
118 if (nss_fd_ != NULL) { | 126 if (nss_fd_ != NULL) { |
119 PR_Close(nss_fd_); | 127 PR_Close(nss_fd_); |
(...skipping 28 matching lines...) Expand all Loading... |
148 rv = DoHandshakeLoop(OK); | 156 rv = DoHandshakeLoop(OK); |
149 if (rv == ERR_IO_PENDING) { | 157 if (rv == ERR_IO_PENDING) { |
150 user_handshake_callback_ = callback; | 158 user_handshake_callback_ = callback; |
151 } else { | 159 } else { |
152 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE, rv); | 160 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE, rv); |
153 } | 161 } |
154 | 162 |
155 return rv > OK ? OK : rv; | 163 return rv > OK ? OK : rv; |
156 } | 164 } |
157 | 165 |
| 166 void SSLServerSocketNSS::SetRequireClientCert(bool require_client_cert) { |
| 167 ssl_config_.require_client_cert = require_client_cert; |
| 168 } |
| 169 |
| 170 void SSLServerSocketNSS::SetClientCertCAList( |
| 171 const CertificateList& client_cert_ca_list) { |
| 172 client_cert_ca_list_ = client_cert_ca_list; |
| 173 } |
| 174 |
| 175 void SSLServerSocketNSS::SetClientCertVerifier( |
| 176 CertVerifier* client_cert_verifier) { |
| 177 client_cert_verifier_ = client_cert_verifier; |
| 178 } |
| 179 |
158 int SSLServerSocketNSS::ExportKeyingMaterial(const base::StringPiece& label, | 180 int SSLServerSocketNSS::ExportKeyingMaterial(const base::StringPiece& label, |
159 bool has_context, | 181 bool has_context, |
160 const base::StringPiece& context, | 182 const base::StringPiece& context, |
161 unsigned char* out, | 183 unsigned char* out, |
162 unsigned int outlen) { | 184 unsigned int outlen) { |
163 if (!IsConnected()) | 185 if (!IsConnected()) |
164 return ERR_SOCKET_NOT_CONNECTED; | 186 return ERR_SOCKET_NOT_CONNECTED; |
165 SECStatus result = SSL_ExportKeyingMaterial( | 187 SECStatus result = SSL_ExportKeyingMaterial( |
166 nss_fd_, label.data(), label.size(), has_context, | 188 nss_fd_, label.data(), label.size(), has_context, |
167 reinterpret_cast<const unsigned char*>(context.data()), | 189 reinterpret_cast<const unsigned char*>(context.data()), |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 NOTIMPLEMENTED(); | 319 NOTIMPLEMENTED(); |
298 return false; | 320 return false; |
299 } | 321 } |
300 | 322 |
301 NextProto SSLServerSocketNSS::GetNegotiatedProtocol() const { | 323 NextProto SSLServerSocketNSS::GetNegotiatedProtocol() const { |
302 // NPN is not supported by this class. | 324 // NPN is not supported by this class. |
303 return kProtoUnknown; | 325 return kProtoUnknown; |
304 } | 326 } |
305 | 327 |
306 bool SSLServerSocketNSS::GetSSLInfo(SSLInfo* ssl_info) { | 328 bool SSLServerSocketNSS::GetSSLInfo(SSLInfo* ssl_info) { |
307 NOTIMPLEMENTED(); | 329 ssl_info->Reset(); |
308 return false; | 330 if (!completed_handshake_) { |
| 331 return false; |
| 332 } |
| 333 ExtractClientCert(); |
| 334 ssl_info->cert = client_cert_; |
| 335 UpdateSSLConnectionStatus(nss_fd_, ssl_config_, &ssl_info->connection_status); |
| 336 ssl_info->client_cert_sent = client_cert_.get() ? true : false; |
| 337 PRUint16 cipher_suite = |
| 338 SSLConnectionStatusToCipherSuite(ssl_info->connection_status); |
| 339 SSLCipherSuiteInfo cipher_info; |
| 340 SECStatus ok = |
| 341 SSL_GetCipherSuiteInfo(cipher_suite, &cipher_info, sizeof(cipher_info)); |
| 342 if (ok == SECSuccess) { |
| 343 ssl_info->security_bits = cipher_info.effectiveKeyBits; |
| 344 } else { |
| 345 ssl_info->security_bits = -1; |
| 346 } |
| 347 PRBool last_handshake_resumed; |
| 348 SECStatus rv = SSL_HandshakeResumedSession(nss_fd_, &last_handshake_resumed); |
| 349 if (rv == SECSuccess && last_handshake_resumed) { |
| 350 ssl_info->handshake_type = SSLInfo::HANDSHAKE_RESUME; |
| 351 } else { |
| 352 ssl_info->handshake_type = SSLInfo::HANDSHAKE_FULL; |
| 353 } |
| 354 return true; |
309 } | 355 } |
310 | 356 |
311 void SSLServerSocketNSS::GetConnectionAttempts(ConnectionAttempts* out) const { | 357 void SSLServerSocketNSS::GetConnectionAttempts(ConnectionAttempts* out) const { |
312 out->clear(); | 358 out->clear(); |
313 } | 359 } |
314 | 360 |
315 int64_t SSLServerSocketNSS::GetTotalReceivedBytes() const { | 361 int64_t SSLServerSocketNSS::GetTotalReceivedBytes() const { |
316 NOTIMPLEMENTED(); | 362 NOTIMPLEMENTED(); |
317 return 0; | 363 return 0; |
318 } | 364 } |
(...skipping 12 matching lines...) Expand all Loading... |
331 /* Push SSL onto our fake I/O socket */ | 377 /* Push SSL onto our fake I/O socket */ |
332 nss_fd_ = SSL_ImportFD(NULL, nss_fd_); | 378 nss_fd_ = SSL_ImportFD(NULL, nss_fd_); |
333 if (nss_fd_ == NULL) { | 379 if (nss_fd_ == NULL) { |
334 LogFailedNSSFunction(net_log_, "SSL_ImportFD", ""); | 380 LogFailedNSSFunction(net_log_, "SSL_ImportFD", ""); |
335 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR/NSS error code. | 381 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR/NSS error code. |
336 } | 382 } |
337 // TODO(port): set more ssl options! Check errors! | 383 // TODO(port): set more ssl options! Check errors! |
338 | 384 |
339 int rv; | 385 int rv; |
340 | 386 |
341 if (ssl_config_.require_client_cert) { | |
342 rv = SSL_OptionSet(nss_fd_, SSL_REQUEST_CERTIFICATE, PR_TRUE); | |
343 if (rv != SECSuccess) { | |
344 LogFailedNSSFunction(net_log_, "SSL_OptionSet", | |
345 "SSL_REQUEST_CERTIFICATE"); | |
346 return ERR_UNEXPECTED; | |
347 } | |
348 } | |
349 | |
350 rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE); | 387 rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE); |
351 if (rv != SECSuccess) { | 388 if (rv != SECSuccess) { |
352 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_SECURITY"); | 389 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_SECURITY"); |
353 return ERR_UNEXPECTED; | 390 return ERR_UNEXPECTED; |
354 } | 391 } |
355 | 392 |
356 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL2, PR_FALSE); | 393 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL2, PR_FALSE); |
357 if (rv != SECSuccess) { | 394 if (rv != SECSuccess) { |
358 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL2"); | 395 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL2"); |
359 return ERR_UNEXPECTED; | 396 return ERR_UNEXPECTED; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); | 442 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); |
406 return ERR_UNEXPECTED; | 443 return ERR_UNEXPECTED; |
407 } | 444 } |
408 | 445 |
409 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_SERVER, PR_TRUE); | 446 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_SERVER, PR_TRUE); |
410 if (rv != SECSuccess) { | 447 if (rv != SECSuccess) { |
411 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_SERVER"); | 448 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_SERVER"); |
412 return ERR_UNEXPECTED; | 449 return ERR_UNEXPECTED; |
413 } | 450 } |
414 | 451 |
415 rv = SSL_OptionSet(nss_fd_, SSL_REQUEST_CERTIFICATE, PR_FALSE); | 452 rv = SSL_OptionSet(nss_fd_, SSL_REQUEST_CERTIFICATE, |
| 453 ssl_config_.require_client_cert ? PR_TRUE : PR_FALSE); |
416 if (rv != SECSuccess) { | 454 if (rv != SECSuccess) { |
417 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_REQUEST_CERTIFICATE"); | 455 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_REQUEST_CERTIFICATE"); |
418 return ERR_UNEXPECTED; | 456 return ERR_UNEXPECTED; |
419 } | 457 } |
420 | 458 |
421 rv = SSL_OptionSet(nss_fd_, SSL_REQUIRE_CERTIFICATE, PR_FALSE); | 459 rv = SSL_OptionSet(nss_fd_, SSL_REQUIRE_CERTIFICATE, |
| 460 ssl_config_.require_client_cert ? PR_TRUE : PR_FALSE); |
422 if (rv != SECSuccess) { | 461 if (rv != SECSuccess) { |
423 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_REQUIRE_CERTIFICATE"); | 462 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_REQUIRE_CERTIFICATE"); |
424 return ERR_UNEXPECTED; | 463 return ERR_UNEXPECTED; |
425 } | 464 } |
426 | 465 |
427 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this); | 466 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this); |
428 if (rv != SECSuccess) { | 467 if (rv != SECSuccess) { |
429 LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", ""); | 468 LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", ""); |
430 return ERR_UNEXPECTED; | 469 return ERR_UNEXPECTED; |
431 } | 470 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 return ERR_UNEXPECTED; | 540 return ERR_UNEXPECTED; |
502 } | 541 } |
503 | 542 |
504 // Tell SSL we're a server; needed if not letting NSPR do socket I/O | 543 // Tell SSL we're a server; needed if not letting NSPR do socket I/O |
505 rv = SSL_ResetHandshake(nss_fd_, PR_TRUE); | 544 rv = SSL_ResetHandshake(nss_fd_, PR_TRUE); |
506 if (rv != SECSuccess) { | 545 if (rv != SECSuccess) { |
507 LogFailedNSSFunction(net_log_, "SSL_ResetHandshake", ""); | 546 LogFailedNSSFunction(net_log_, "SSL_ResetHandshake", ""); |
508 return ERR_UNEXPECTED; | 547 return ERR_UNEXPECTED; |
509 } | 548 } |
510 | 549 |
| 550 // Set up the information needed for the CertificateRequest message |
| 551 if (!client_cert_ca_list_.empty()) { |
| 552 CERTCertList* certs = CERT_NewCertList(); |
| 553 if (!certs) { |
| 554 LogFailedNSSFunction(net_log_, "CERT_NewCertList", ""); |
| 555 return ERR_UNEXPECTED; |
| 556 } |
| 557 for (CertificateList::const_iterator it = client_cert_ca_list_.begin(); |
| 558 it != client_cert_ca_list_.end(); ++it) { |
| 559 CERT_AddCertToListTail(certs, |
| 560 CERT_DupCertificate((*it)->os_cert_handle())); |
| 561 } |
| 562 |
| 563 rv = SSL_SetTrustAnchors(nss_fd_, certs); |
| 564 CERT_DestroyCertList(certs); |
| 565 if (rv != SECSuccess) { |
| 566 LogFailedNSSFunction(net_log_, "SSL_SetTrustAnchors", ""); |
| 567 return ERR_UNEXPECTED; |
| 568 } |
| 569 } |
| 570 |
511 return OK; | 571 return OK; |
512 } | 572 } |
513 | 573 |
514 void SSLServerSocketNSS::OnSendComplete(int result) { | 574 void SSLServerSocketNSS::OnSendComplete(int result) { |
515 if (next_handshake_state_ == STATE_HANDSHAKE) { | 575 if (next_handshake_state_ == STATE_HANDSHAKE) { |
516 // In handshake phase. | 576 // In handshake phase. |
517 OnHandshakeIOComplete(result); | 577 OnHandshakeIOComplete(result); |
518 return; | 578 return; |
519 } | 579 } |
520 | 580 |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
815 DCHECK(rv != ERR_IO_PENDING); | 875 DCHECK(rv != ERR_IO_PENDING); |
816 DCHECK(!user_write_callback_.is_null()); | 876 DCHECK(!user_write_callback_.is_null()); |
817 | 877 |
818 user_write_buf_ = NULL; | 878 user_write_buf_ = NULL; |
819 user_write_buf_len_ = 0; | 879 user_write_buf_len_ = 0; |
820 ResetAndReturn(&user_write_callback_).Run(rv); | 880 ResetAndReturn(&user_write_callback_).Run(rv); |
821 } | 881 } |
822 | 882 |
823 // static | 883 // static |
824 // NSS calls this if an incoming certificate needs to be verified. | 884 // NSS calls this if an incoming certificate needs to be verified. |
825 // Do nothing but return SECSuccess. | |
826 // This is called only in full handshake mode. | 885 // This is called only in full handshake mode. |
827 // Peer certificate is retrieved in HandshakeCallback() later, which is called | 886 // Peer certificate is retrieved in HandshakeCallback() later, which is called |
828 // in full handshake mode or in resumption handshake mode. | 887 // in full handshake mode or in resumption handshake mode. |
829 SECStatus SSLServerSocketNSS::OwnAuthCertHandler(void* arg, | 888 SECStatus SSLServerSocketNSS::OwnAuthCertHandler(void* arg, |
830 PRFileDesc* socket, | 889 PRFileDesc* socket, |
831 PRBool checksig, | 890 PRBool checksig, |
832 PRBool is_server) { | 891 PRBool is_server) { |
833 // TODO(hclam): Implement. | 892 if (!is_server) |
834 // Tell NSS to not verify the certificate. | 893 return SECFailure; |
835 return SECSuccess; | 894 SSLServerSocketNSS* self = reinterpret_cast<SSLServerSocketNSS*>(arg); |
| 895 DCHECK(self); |
| 896 if (!self->client_cert_verifier_) |
| 897 return SECSuccess; |
| 898 self->ExtractClientCert(); |
| 899 X509Certificate* cert = self->client_cert_.get(); |
| 900 if (!cert) { |
| 901 PR_SetError(SSL_ERROR_NO_CERTIFICATE, 0); |
| 902 return SECFailure; |
| 903 } |
| 904 CertVerifyResult ignore_result; |
| 905 scoped_ptr<CertVerifier::Request> ignore_async; |
| 906 int res = self->client_cert_verifier_->Verify( |
| 907 cert, std::string(), std::string(), 0, NULL, &ignore_result, |
| 908 base::Bind(&DoNothingOnCompletion), &ignore_async, self->net_log_); |
| 909 if (res != OK) { |
| 910 PR_SetError(SSL_ERROR_BAD_CERTIFICATE, 0); |
| 911 } |
| 912 return res == OK ? SECSuccess : SECFailure; |
836 } | 913 } |
837 | 914 |
838 // static | 915 // static |
839 // NSS calls this when handshake is completed. | 916 // NSS calls this when handshake is completed. |
840 // After the SSL handshake is finished we need to verify the certificate. | 917 // After the SSL handshake is finished we need to verify the certificate. |
841 void SSLServerSocketNSS::HandshakeCallback(PRFileDesc* socket, | 918 void SSLServerSocketNSS::HandshakeCallback(PRFileDesc* socket, |
842 void* arg) { | 919 void* arg) { |
843 // TODO(hclam): Implement. | 920 // TODO(hclam): Implement. |
844 } | 921 } |
845 | 922 |
846 int SSLServerSocketNSS::Init() { | 923 int SSLServerSocketNSS::Init() { |
847 // Initialize the NSS SSL library in a threadsafe way. This also | 924 // Initialize the NSS SSL library in a threadsafe way. This also |
848 // initializes the NSS base library. | 925 // initializes the NSS base library. |
849 EnsureNSSSSLInit(); | 926 EnsureNSSSSLInit(); |
850 if (!NSS_IsInitialized()) | 927 if (!NSS_IsInitialized()) |
851 return ERR_UNEXPECTED; | 928 return ERR_UNEXPECTED; |
852 | 929 |
853 EnableSSLServerSockets(); | 930 EnableSSLServerSockets(); |
854 return OK; | 931 return OK; |
855 } | 932 } |
856 | 933 |
| 934 void SSLServerSocketNSS::ExtractClientCert() { |
| 935 if (client_cert_.get()) |
| 936 return; |
| 937 if (!completed_handshake_) |
| 938 return; |
| 939 CERTCertList* list = SSL_PeerCertificateChain(nss_fd_); |
| 940 if (list == NULL) |
| 941 return; |
| 942 std::vector<base::StringPiece> certs; |
| 943 for (CERTCertListNode* node = CERT_LIST_HEAD(list); |
| 944 !CERT_LIST_END(node, list); node = CERT_LIST_NEXT(node)) { |
| 945 SECItem& cert_der = node->cert->derCert; |
| 946 base::StringPiece cert(reinterpret_cast<char*>(cert_der.data), |
| 947 cert_der.len); |
| 948 certs.push_back(cert); |
| 949 } |
| 950 client_cert_ = X509Certificate::CreateFromDERCertChain(certs); |
| 951 CERT_DestroyCertList(list); |
| 952 } |
| 953 |
857 } // namespace net | 954 } // namespace net |
OLD | NEW |