| 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 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #if defined(OS_WIN) | 9 #if defined(OS_WIN) |
| 10 #include <winsock2.h> | 10 #include <winsock2.h> |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 g_nss_ssl_server_init_singleton = LAZY_INSTANCE_INITIALIZER; | 76 g_nss_ssl_server_init_singleton = LAZY_INSTANCE_INITIALIZER; |
| 77 | 77 |
| 78 } // namespace | 78 } // namespace |
| 79 | 79 |
| 80 void EnableSSLServerSockets() { | 80 void EnableSSLServerSockets() { |
| 81 g_nss_ssl_server_init_singleton.Get(); | 81 g_nss_ssl_server_init_singleton.Get(); |
| 82 } | 82 } |
| 83 | 83 |
| 84 scoped_ptr<SSLServerSocket> CreateSSLServerSocket( | 84 scoped_ptr<SSLServerSocket> CreateSSLServerSocket( |
| 85 scoped_ptr<StreamSocket> socket, | 85 scoped_ptr<StreamSocket> socket, |
| 86 X509Certificate* cert, | 86 X509Certificate* certificate, |
| 87 const crypto::RSAPrivateKey& key, | 87 const crypto::RSAPrivateKey& key, |
| 88 const SSLServerConfig& ssl_config) { | 88 const SSLServerConfig& ssl_server_config) { |
| 89 DCHECK(g_nss_server_sockets_init) << "EnableSSLServerSockets() has not been" | 89 DCHECK(g_nss_server_sockets_init) << "EnableSSLServerSockets() has not been" |
| 90 << " called yet!"; | 90 << " called yet!"; |
| 91 | 91 |
| 92 return scoped_ptr<SSLServerSocket>( | 92 return scoped_ptr<SSLServerSocket>(new SSLServerSocketNSS( |
| 93 new SSLServerSocketNSS(std::move(socket), cert, key, ssl_config)); | 93 std::move(socket), certificate, key, ssl_server_config)); |
| 94 } | 94 } |
| 95 | 95 |
| 96 SSLServerSocketNSS::SSLServerSocketNSS( | 96 SSLServerSocketNSS::SSLServerSocketNSS( |
| 97 scoped_ptr<StreamSocket> transport_socket, | 97 scoped_ptr<StreamSocket> transport_socket, |
| 98 scoped_refptr<X509Certificate> cert, | 98 scoped_refptr<X509Certificate> cert, |
| 99 const crypto::RSAPrivateKey& key, | 99 const crypto::RSAPrivateKey& key, |
| 100 const SSLServerConfig& ssl_config) | 100 const SSLServerConfig& ssl_server_config) |
| 101 : transport_send_busy_(false), | 101 : transport_send_busy_(false), |
| 102 transport_recv_busy_(false), | 102 transport_recv_busy_(false), |
| 103 user_read_buf_len_(0), | 103 user_read_buf_len_(0), |
| 104 user_write_buf_len_(0), | 104 user_write_buf_len_(0), |
| 105 nss_fd_(NULL), | 105 nss_fd_(NULL), |
| 106 nss_bufs_(NULL), | 106 nss_bufs_(NULL), |
| 107 transport_socket_(std::move(transport_socket)), | 107 transport_socket_(std::move(transport_socket)), |
| 108 ssl_config_(ssl_config), | 108 ssl_server_config_(ssl_server_config), |
| 109 cert_(cert), | 109 cert_(cert), |
| 110 key_(key.Copy()), | 110 key_(key.Copy()), |
| 111 next_handshake_state_(STATE_NONE), | 111 next_handshake_state_(STATE_NONE), |
| 112 completed_handshake_(false) { | 112 completed_handshake_(false) { |
| 113 CHECK(key_); | 113 CHECK(key_); |
| 114 } | 114 } |
| 115 | 115 |
| 116 SSLServerSocketNSS::~SSLServerSocketNSS() { | 116 SSLServerSocketNSS::~SSLServerSocketNSS() { |
| 117 if (nss_fd_ != NULL) { | 117 if (nss_fd_ != NULL) { |
| 118 PR_Close(nss_fd_); | 118 PR_Close(nss_fd_); |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 /* Push SSL onto our fake I/O socket */ | 330 /* Push SSL onto our fake I/O socket */ |
| 331 nss_fd_ = SSL_ImportFD(NULL, nss_fd_); | 331 nss_fd_ = SSL_ImportFD(NULL, nss_fd_); |
| 332 if (nss_fd_ == NULL) { | 332 if (nss_fd_ == NULL) { |
| 333 LogFailedNSSFunction(net_log_, "SSL_ImportFD", ""); | 333 LogFailedNSSFunction(net_log_, "SSL_ImportFD", ""); |
| 334 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR/NSS error code. | 334 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR/NSS error code. |
| 335 } | 335 } |
| 336 // TODO(port): set more ssl options! Check errors! | 336 // TODO(port): set more ssl options! Check errors! |
| 337 | 337 |
| 338 int rv; | 338 int rv; |
| 339 | 339 |
| 340 if (ssl_config_.require_client_cert) { | 340 if (ssl_server_config_.client_cert_type == |
| 341 SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT) { |
| 341 rv = SSL_OptionSet(nss_fd_, SSL_REQUEST_CERTIFICATE, PR_TRUE); | 342 rv = SSL_OptionSet(nss_fd_, SSL_REQUEST_CERTIFICATE, PR_TRUE); |
| 342 if (rv != SECSuccess) { | 343 if (rv != SECSuccess) { |
| 343 LogFailedNSSFunction(net_log_, "SSL_OptionSet", | 344 LogFailedNSSFunction(net_log_, "SSL_OptionSet", |
| 344 "SSL_REQUEST_CERTIFICATE"); | 345 "SSL_REQUEST_CERTIFICATE"); |
| 345 return ERR_UNEXPECTED; | 346 return ERR_UNEXPECTED; |
| 346 } | 347 } |
| 347 } | 348 } |
| 348 | 349 |
| 349 rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE); | 350 rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE); |
| 350 if (rv != SECSuccess) { | 351 if (rv != SECSuccess) { |
| 351 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_SECURITY"); | 352 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_SECURITY"); |
| 352 return ERR_UNEXPECTED; | 353 return ERR_UNEXPECTED; |
| 353 } | 354 } |
| 354 | 355 |
| 355 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL2, PR_FALSE); | 356 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL2, PR_FALSE); |
| 356 if (rv != SECSuccess) { | 357 if (rv != SECSuccess) { |
| 357 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL2"); | 358 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL2"); |
| 358 return ERR_UNEXPECTED; | 359 return ERR_UNEXPECTED; |
| 359 } | 360 } |
| 360 | 361 |
| 361 SSLVersionRange version_range; | 362 SSLVersionRange version_range; |
| 362 version_range.min = ssl_config_.version_min; | 363 version_range.min = ssl_server_config_.version_min; |
| 363 version_range.max = ssl_config_.version_max; | 364 version_range.max = ssl_server_config_.version_max; |
| 364 rv = SSL_VersionRangeSet(nss_fd_, &version_range); | 365 rv = SSL_VersionRangeSet(nss_fd_, &version_range); |
| 365 if (rv != SECSuccess) { | 366 if (rv != SECSuccess) { |
| 366 LogFailedNSSFunction(net_log_, "SSL_VersionRangeSet", ""); | 367 LogFailedNSSFunction(net_log_, "SSL_VersionRangeSet", ""); |
| 367 return ERR_NO_SSL_VERSIONS_ENABLED; | 368 return ERR_NO_SSL_VERSIONS_ENABLED; |
| 368 } | 369 } |
| 369 | 370 |
| 370 if (ssl_config_.require_ecdhe) { | 371 if (ssl_server_config_.require_ecdhe) { |
| 371 const PRUint16* const ssl_ciphers = SSL_GetImplementedCiphers(); | 372 const PRUint16* const ssl_ciphers = SSL_GetImplementedCiphers(); |
| 372 const PRUint16 num_ciphers = SSL_GetNumImplementedCiphers(); | 373 const PRUint16 num_ciphers = SSL_GetNumImplementedCiphers(); |
| 373 | 374 |
| 374 // Iterate over the cipher suites and disable those that don't use ECDHE. | 375 // Iterate over the cipher suites and disable those that don't use ECDHE. |
| 375 for (unsigned i = 0; i < num_ciphers; i++) { | 376 for (unsigned i = 0; i < num_ciphers; i++) { |
| 376 SSLCipherSuiteInfo info; | 377 SSLCipherSuiteInfo info; |
| 377 if (SSL_GetCipherSuiteInfo(ssl_ciphers[i], &info, sizeof(info)) == | 378 if (SSL_GetCipherSuiteInfo(ssl_ciphers[i], &info, sizeof(info)) == |
| 378 SECSuccess) { | 379 SECSuccess) { |
| 379 if (strcmp(info.keaTypeName, "ECDHE") != 0) { | 380 if (strcmp(info.keaTypeName, "ECDHE") != 0) { |
| 380 SSL_CipherPrefSet(nss_fd_, ssl_ciphers[i], PR_FALSE); | 381 SSL_CipherPrefSet(nss_fd_, ssl_ciphers[i], PR_FALSE); |
| 381 } | 382 } |
| 382 } | 383 } |
| 383 } | 384 } |
| 384 } | 385 } |
| 385 | 386 |
| 386 for (std::vector<uint16_t>::const_iterator it = | 387 for (std::vector<uint16_t>::const_iterator it = |
| 387 ssl_config_.disabled_cipher_suites.begin(); | 388 ssl_server_config_.disabled_cipher_suites.begin(); |
| 388 it != ssl_config_.disabled_cipher_suites.end(); ++it) { | 389 it != ssl_server_config_.disabled_cipher_suites.end(); ++it) { |
| 389 // This will fail if the specified cipher is not implemented by NSS, but | 390 // This will fail if the specified cipher is not implemented by NSS, but |
| 390 // the failure is harmless. | 391 // the failure is harmless. |
| 391 SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE); | 392 SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE); |
| 392 } | 393 } |
| 393 | 394 |
| 394 // Server socket doesn't need session tickets. | 395 // Server socket doesn't need session tickets. |
| 395 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_FALSE); | 396 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_FALSE); |
| 396 if (rv != SECSuccess) { | 397 if (rv != SECSuccess) { |
| 397 LogFailedNSSFunction( | 398 LogFailedNSSFunction( |
| 398 net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS"); | 399 net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS"); |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 847 // initializes the NSS base library. | 848 // initializes the NSS base library. |
| 848 EnsureNSSSSLInit(); | 849 EnsureNSSSSLInit(); |
| 849 if (!NSS_IsInitialized()) | 850 if (!NSS_IsInitialized()) |
| 850 return ERR_UNEXPECTED; | 851 return ERR_UNEXPECTED; |
| 851 | 852 |
| 852 EnableSSLServerSockets(); | 853 EnableSSLServerSockets(); |
| 853 return OK; | 854 return OK; |
| 854 } | 855 } |
| 855 | 856 |
| 856 } // namespace net | 857 } // namespace net |
| OLD | NEW |