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

Side by Side Diff: net/socket/ssl_server_socket_nss.cc

Issue 1474983003: Support for client certs in ssl_server_socket. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 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
OLDNEW
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
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"
40 #include "net/log/net_log.h" 41 #include "net/log/net_log.h"
41 #include "net/socket/nss_ssl_util.h" 42 #include "net/socket/nss_ssl_util.h"
42 43
43 // SSL plaintext fragments are shorter than 16KB. Although the record layer 44 // 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 45 // 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 46 // smaller than 1KB. So a 17KB buffer should be large enough to hold an
46 // entire SSL record. 47 // entire SSL record.
47 static const int kRecvBufferSize = 17 * 1024; 48 static const int kRecvBufferSize = 17 * 1024;
48 static const int kSendBufferSize = 17 * 1024; 49 static const int kSendBufferSize = 17 * 1024;
49 50
(...skipping 24 matching lines...) Expand all
74 g_nss_ssl_server_init_singleton = LAZY_INSTANCE_INITIALIZER; 75 g_nss_ssl_server_init_singleton = LAZY_INSTANCE_INITIALIZER;
75 76
76 } // namespace 77 } // namespace
77 78
78 void EnableSSLServerSockets() { 79 void EnableSSLServerSockets() {
79 g_nss_ssl_server_init_singleton.Get(); 80 g_nss_ssl_server_init_singleton.Get();
80 } 81 }
81 82
82 scoped_ptr<SSLServerSocket> CreateSSLServerSocket( 83 scoped_ptr<SSLServerSocket> CreateSSLServerSocket(
83 scoped_ptr<StreamSocket> socket, 84 scoped_ptr<StreamSocket> socket,
84 X509Certificate* cert, 85 X509Certificate* certificate,
85 crypto::RSAPrivateKey* key, 86 crypto::RSAPrivateKey* key,
86 const SSLServerConfig& ssl_config) { 87 const SSLServerConfig& ssl_server_config) {
87 DCHECK(g_nss_server_sockets_init) << "EnableSSLServerSockets() has not been" 88 DCHECK(g_nss_server_sockets_init) << "EnableSSLServerSockets() has not been"
88 << " called yet!"; 89 << " called yet!";
89 90
90 return scoped_ptr<SSLServerSocket>( 91 return scoped_ptr<SSLServerSocket>(new SSLServerSocketNSS(
91 new SSLServerSocketNSS(socket.Pass(), cert, key, ssl_config)); 92 socket.Pass(), certificate, key, ssl_server_config));
93 }
94
95 scoped_ptr<SSLServerSocket> CreateSSLServerSocket(
96 scoped_ptr<StreamSocket> socket,
97 X509Certificate* certificate,
98 crypto::RSAPrivateKey* key,
99 const SSLServerConfig& ssl_server_config,
100 const SSLServerSocketContext context) {
101 return CreateSSLServerSocket(socket, certificate, key, ssl_server_config);
92 } 102 }
93 103
94 SSLServerSocketNSS::SSLServerSocketNSS( 104 SSLServerSocketNSS::SSLServerSocketNSS(
95 scoped_ptr<StreamSocket> transport_socket, 105 scoped_ptr<StreamSocket> transport_socket,
96 scoped_refptr<X509Certificate> cert, 106 scoped_refptr<X509Certificate> cert,
97 crypto::RSAPrivateKey* key, 107 crypto::RSAPrivateKey* key,
98 const SSLServerConfig& ssl_config) 108 const SSLServerConfig& ssl_server_config)
99 : transport_send_busy_(false), 109 : transport_send_busy_(false),
100 transport_recv_busy_(false), 110 transport_recv_busy_(false),
101 user_read_buf_len_(0), 111 user_read_buf_len_(0),
102 user_write_buf_len_(0), 112 user_write_buf_len_(0),
103 nss_fd_(NULL), 113 nss_fd_(NULL),
104 nss_bufs_(NULL), 114 nss_bufs_(NULL),
105 transport_socket_(transport_socket.Pass()), 115 transport_socket_(transport_socket.Pass()),
106 ssl_config_(ssl_config), 116 ssl_server_config_(ssl_server_config),
107 cert_(cert), 117 cert_(cert),
108 next_handshake_state_(STATE_NONE), 118 next_handshake_state_(STATE_NONE),
109 completed_handshake_(false) { 119 completed_handshake_(false) {
110 // TODO(hclam): Need a better way to clone a key. 120 // TODO(hclam): Need a better way to clone a key.
111 std::vector<uint8> key_bytes; 121 std::vector<uint8> key_bytes;
112 CHECK(key->ExportPrivateKey(&key_bytes)); 122 CHECK(key->ExportPrivateKey(&key_bytes));
113 key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes)); 123 key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes));
114 CHECK(key_.get()); 124 CHECK(key_.get());
115 } 125 }
116 126
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 /* Push SSL onto our fake I/O socket */ 341 /* Push SSL onto our fake I/O socket */
332 nss_fd_ = SSL_ImportFD(NULL, nss_fd_); 342 nss_fd_ = SSL_ImportFD(NULL, nss_fd_);
333 if (nss_fd_ == NULL) { 343 if (nss_fd_ == NULL) {
334 LogFailedNSSFunction(net_log_, "SSL_ImportFD", ""); 344 LogFailedNSSFunction(net_log_, "SSL_ImportFD", "");
335 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR/NSS error code. 345 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR/NSS error code.
336 } 346 }
337 // TODO(port): set more ssl options! Check errors! 347 // TODO(port): set more ssl options! Check errors!
338 348
339 int rv; 349 int rv;
340 350
341 if (ssl_config_.require_client_cert) { 351 if (ssl_server_config_.require_client_cert) {
342 rv = SSL_OptionSet(nss_fd_, SSL_REQUEST_CERTIFICATE, PR_TRUE); 352 rv = SSL_OptionSet(nss_fd_, SSL_REQUEST_CERTIFICATE, PR_TRUE);
343 if (rv != SECSuccess) { 353 if (rv != SECSuccess) {
344 LogFailedNSSFunction(net_log_, "SSL_OptionSet", 354 LogFailedNSSFunction(net_log_, "SSL_OptionSet",
345 "SSL_REQUEST_CERTIFICATE"); 355 "SSL_REQUEST_CERTIFICATE");
346 return ERR_UNEXPECTED; 356 return ERR_UNEXPECTED;
347 } 357 }
348 } 358 }
349 359
350 rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE); 360 rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE);
351 if (rv != SECSuccess) { 361 if (rv != SECSuccess) {
352 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_SECURITY"); 362 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_SECURITY");
353 return ERR_UNEXPECTED; 363 return ERR_UNEXPECTED;
354 } 364 }
355 365
356 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL2, PR_FALSE); 366 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL2, PR_FALSE);
357 if (rv != SECSuccess) { 367 if (rv != SECSuccess) {
358 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL2"); 368 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL2");
359 return ERR_UNEXPECTED; 369 return ERR_UNEXPECTED;
360 } 370 }
361 371
362 SSLVersionRange version_range; 372 SSLVersionRange version_range;
363 version_range.min = ssl_config_.version_min; 373 version_range.min = ssl_server_config_.version_min;
364 version_range.max = ssl_config_.version_max; 374 version_range.max = ssl_server_config_.version_max;
365 rv = SSL_VersionRangeSet(nss_fd_, &version_range); 375 rv = SSL_VersionRangeSet(nss_fd_, &version_range);
366 if (rv != SECSuccess) { 376 if (rv != SECSuccess) {
367 LogFailedNSSFunction(net_log_, "SSL_VersionRangeSet", ""); 377 LogFailedNSSFunction(net_log_, "SSL_VersionRangeSet", "");
368 return ERR_NO_SSL_VERSIONS_ENABLED; 378 return ERR_NO_SSL_VERSIONS_ENABLED;
369 } 379 }
370 380
371 if (ssl_config_.require_ecdhe) { 381 if (ssl_server_config_.require_ecdhe) {
372 const PRUint16* const ssl_ciphers = SSL_GetImplementedCiphers(); 382 const PRUint16* const ssl_ciphers = SSL_GetImplementedCiphers();
373 const PRUint16 num_ciphers = SSL_GetNumImplementedCiphers(); 383 const PRUint16 num_ciphers = SSL_GetNumImplementedCiphers();
374 384
375 // Iterate over the cipher suites and disable those that don't use ECDHE. 385 // Iterate over the cipher suites and disable those that don't use ECDHE.
376 for (unsigned i = 0; i < num_ciphers; i++) { 386 for (unsigned i = 0; i < num_ciphers; i++) {
377 SSLCipherSuiteInfo info; 387 SSLCipherSuiteInfo info;
378 if (SSL_GetCipherSuiteInfo(ssl_ciphers[i], &info, sizeof(info)) == 388 if (SSL_GetCipherSuiteInfo(ssl_ciphers[i], &info, sizeof(info)) ==
379 SECSuccess) { 389 SECSuccess) {
380 if (strcmp(info.keaTypeName, "ECDHE") != 0) { 390 if (strcmp(info.keaTypeName, "ECDHE") != 0) {
381 SSL_CipherPrefSet(nss_fd_, ssl_ciphers[i], PR_FALSE); 391 SSL_CipherPrefSet(nss_fd_, ssl_ciphers[i], PR_FALSE);
382 } 392 }
383 } 393 }
384 } 394 }
385 } 395 }
386 396
387 for (std::vector<uint16>::const_iterator it = 397 for (std::vector<uint16>::const_iterator it =
388 ssl_config_.disabled_cipher_suites.begin(); 398 ssl_server_config_.disabled_cipher_suites.begin();
389 it != ssl_config_.disabled_cipher_suites.end(); ++it) { 399 it != ssl_server_config_.disabled_cipher_suites.end(); ++it) {
390 // This will fail if the specified cipher is not implemented by NSS, but 400 // This will fail if the specified cipher is not implemented by NSS, but
391 // the failure is harmless. 401 // the failure is harmless.
392 SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE); 402 SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE);
393 } 403 }
394 404
395 // Server socket doesn't need session tickets. 405 // Server socket doesn't need session tickets.
396 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_FALSE); 406 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_FALSE);
397 if (rv != SECSuccess) { 407 if (rv != SECSuccess) {
398 LogFailedNSSFunction( 408 LogFailedNSSFunction(
399 net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS"); 409 net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS");
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 // initializes the NSS base library. 858 // initializes the NSS base library.
849 EnsureNSSSSLInit(); 859 EnsureNSSSSLInit();
850 if (!NSS_IsInitialized()) 860 if (!NSS_IsInitialized())
851 return ERR_UNEXPECTED; 861 return ERR_UNEXPECTED;
852 862
853 EnableSSLServerSockets(); 863 EnableSSLServerSockets();
854 return OK; 864 return OK;
855 } 865 }
856 866
857 } // namespace net 867 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698