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

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

Issue 1474983003: Support for client certs in ssl_server_socket. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed nits on utils 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_openssl.h" 5 #include "net/socket/ssl_server_socket_openssl.h"
6 6
7 #include <openssl/err.h> 7 #include <openssl/err.h>
8 #include <openssl/ssl.h> 8 #include <openssl/ssl.h>
9 9
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
13 #include "crypto/openssl_util.h" 13 #include "crypto/openssl_util.h"
14 #include "crypto/rsa_private_key.h" 14 #include "crypto/rsa_private_key.h"
15 #include "crypto/scoped_openssl_types.h" 15 #include "crypto/scoped_openssl_types.h"
16 #include "net/base/net_errors.h" 16 #include "net/base/net_errors.h"
17 #include "net/cert/cert_verify_result.h"
18 #include "net/cert/client_cert_verifier.h"
17 #include "net/ssl/openssl_ssl_util.h" 19 #include "net/ssl/openssl_ssl_util.h"
18 #include "net/ssl/scoped_openssl_types.h" 20 #include "net/ssl/scoped_openssl_types.h"
21 #include "net/ssl/ssl_connection_status_flags.h"
22 #include "net/ssl/ssl_info.h"
19 23
20 #define GotoState(s) next_handshake_state_ = s 24 #define GotoState(s) next_handshake_state_ = s
21 25
22 namespace net { 26 namespace net {
23 27
28 namespace {
29
30 bool GetDERFromX509(X509* cert, base::StringPiece* sp) {
davidben 2015/12/14 23:56:49 Use net::x509_util::GetDER from x509_util_openssl.
ryanchung 2015/12/16 22:40:01 Done.
31 unsigned char* cert_data = NULL;
davidben 2015/12/14 23:56:49 uint8_t
ryanchung 2015/12/16 22:40:01 Done.
32 int cert_data_length = i2d_X509(cert, &cert_data);
33 if (!cert_data_length || !cert_data) {
34 return false;
35 }
36 sp->set(reinterpret_cast<char*>(cert_data), cert_data_length);
37 return true;
38 }
39
40 scoped_refptr<X509Certificate> CreateX509Certificate(X509* cert,
41 STACK_OF(X509) * chain) {
42 DCHECK(cert);
43 std::vector<base::StringPiece> der_chain;
44 base::StringPiece der_cert;
45 scoped_refptr<X509Certificate> client_cert;
46 if (!GetDERFromX509(cert, &der_cert))
47 return client_cert;
48 der_chain.push_back(der_cert);
49
50 ScopedX509Stack openssl_chain(X509_chain_up_ref(chain));
51 for (size_t i = 0; i < sk_X509_num(openssl_chain.get()); ++i) {
52 X509* x = sk_X509_value(openssl_chain.get(), i);
53 if (GetDERFromX509(x, &der_cert)) {
54 der_chain.push_back(der_cert);
55 }
56 }
57
58 client_cert = X509Certificate::CreateFromDERCertChain(der_chain);
59
60 for (size_t i = 0; i < der_chain.size(); ++i) {
61 OPENSSL_free(const_cast<char*>(der_chain[i].data()));
62 }
63 if (der_chain.size() - 1 !=
64 static_cast<size_t>(sk_X509_num(openssl_chain.get()))) {
65 client_cert = NULL;
davidben 2015/12/14 23:56:49 nullptr
ryanchung 2015/12/16 22:40:01 Done.
66 }
67 return client_cert;
68 }
69
70 } // namespace
71
24 void EnableSSLServerSockets() { 72 void EnableSSLServerSockets() {
25 // No-op because CreateSSLServerSocket() calls crypto::EnsureOpenSSLInit(). 73 // No-op because CreateSSLServerSocket() calls crypto::EnsureOpenSSLInit().
26 } 74 }
27 75
28 scoped_ptr<SSLServerSocket> CreateSSLServerSocket( 76 scoped_ptr<SSLServerSocket> CreateSSLServerSocket(
29 scoped_ptr<StreamSocket> socket, 77 scoped_ptr<StreamSocket> socket,
30 X509Certificate* certificate, 78 X509Certificate* certificate,
31 crypto::RSAPrivateKey* key, 79 crypto::RSAPrivateKey* key,
32 const SSLServerConfig& ssl_config) { 80 const SSLServerConfig& ssl_server_config) {
33 crypto::EnsureOpenSSLInit(); 81 crypto::EnsureOpenSSLInit();
34 return scoped_ptr<SSLServerSocket>( 82 return scoped_ptr<SSLServerSocket>(new SSLServerSocketOpenSSL(
35 new SSLServerSocketOpenSSL(socket.Pass(), certificate, key, ssl_config)); 83 socket.Pass(), certificate, key, ssl_server_config));
36 } 84 }
37 85
38 SSLServerSocketOpenSSL::SSLServerSocketOpenSSL( 86 SSLServerSocketOpenSSL::SSLServerSocketOpenSSL(
39 scoped_ptr<StreamSocket> transport_socket, 87 scoped_ptr<StreamSocket> transport_socket,
40 scoped_refptr<X509Certificate> certificate, 88 scoped_refptr<X509Certificate> certificate,
41 crypto::RSAPrivateKey* key, 89 crypto::RSAPrivateKey* key,
42 const SSLServerConfig& ssl_config) 90 const SSLServerConfig& ssl_server_config)
43 : transport_send_busy_(false), 91 : transport_send_busy_(false),
44 transport_recv_busy_(false), 92 transport_recv_busy_(false),
45 transport_recv_eof_(false), 93 transport_recv_eof_(false),
46 user_read_buf_len_(0), 94 user_read_buf_len_(0),
47 user_write_buf_len_(0), 95 user_write_buf_len_(0),
48 transport_write_error_(OK), 96 transport_write_error_(OK),
49 ssl_(NULL), 97 ssl_(NULL),
50 transport_bio_(NULL), 98 transport_bio_(NULL),
51 transport_socket_(transport_socket.Pass()), 99 transport_socket_(transport_socket.Pass()),
52 ssl_config_(ssl_config), 100 ssl_server_config_(ssl_server_config),
53 cert_(certificate), 101 cert_(certificate),
54 next_handshake_state_(STATE_NONE), 102 next_handshake_state_(STATE_NONE),
55 completed_handshake_(false) { 103 completed_handshake_(false) {
56 // TODO(byungchul): Need a better way to clone a key. 104 // TODO(byungchul): Need a better way to clone a key.
57 std::vector<uint8> key_bytes; 105 std::vector<uint8> key_bytes;
58 CHECK(key->ExportPrivateKey(&key_bytes)); 106 CHECK(key->ExportPrivateKey(&key_bytes));
59 key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes)); 107 key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes));
60 CHECK(key_.get()); 108 CHECK(key_.get());
61 } 109 }
62 110
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 NOTIMPLEMENTED(); 285 NOTIMPLEMENTED();
238 return false; 286 return false;
239 } 287 }
240 288
241 NextProto SSLServerSocketOpenSSL::GetNegotiatedProtocol() const { 289 NextProto SSLServerSocketOpenSSL::GetNegotiatedProtocol() const {
242 // NPN is not supported by this class. 290 // NPN is not supported by this class.
243 return kProtoUnknown; 291 return kProtoUnknown;
244 } 292 }
245 293
246 bool SSLServerSocketOpenSSL::GetSSLInfo(SSLInfo* ssl_info) { 294 bool SSLServerSocketOpenSSL::GetSSLInfo(SSLInfo* ssl_info) {
247 NOTIMPLEMENTED(); 295 ssl_info->Reset();
248 return false; 296 if (!completed_handshake_) {
297 return false;
298 }
299 ExtractClientCert();
300 ssl_info->cert = client_cert_;
301 ssl_info->client_cert_sent =
302 ssl_server_config_.require_client_cert && client_cert_.get();
davidben 2015/12/14 23:56:49 Just client_cert_.get() seems right. Alternatively
ryanchung 2015/12/16 22:40:01 Done. Leaving it false. We can know whether we rec
303
304 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl_);
305 CHECK(cipher);
306 ssl_info->security_bits = SSL_CIPHER_get_bits(cipher, NULL);
307
308 ssl_info->connection_status =
309 EncodeSSLConnectionStatus(SSL_CIPHER_get_id(cipher),
310 0 /* no compression */, GetNetSSLVersion(ssl_));
311
312 if (!SSL_get_secure_renegotiation_support(ssl_))
313 ssl_info->connection_status |= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION;
314
315 ssl_info->handshake_type = SSL_session_reused(ssl_)
316 ? SSLInfo::HANDSHAKE_RESUME
317 : SSLInfo::HANDSHAKE_FULL;
318
319 return true;
249 } 320 }
250 321
251 void SSLServerSocketOpenSSL::GetConnectionAttempts( 322 void SSLServerSocketOpenSSL::GetConnectionAttempts(
252 ConnectionAttempts* out) const { 323 ConnectionAttempts* out) const {
253 out->clear(); 324 out->clear();
254 } 325 }
255 326
256 int64_t SSLServerSocketOpenSSL::GetTotalReceivedBytes() const { 327 int64_t SSLServerSocketOpenSSL::GetTotalReceivedBytes() const {
257 return transport_socket_->GetTotalReceivedBytes(); 328 return transport_socket_->GetTotalReceivedBytes();
258 } 329 }
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 int net_error = OK; 637 int net_error = OK;
567 int rv = SSL_do_handshake(ssl_); 638 int rv = SSL_do_handshake(ssl_);
568 639
569 if (rv == 1) { 640 if (rv == 1) {
570 completed_handshake_ = true; 641 completed_handshake_ = true;
571 } else { 642 } else {
572 int ssl_error = SSL_get_error(ssl_, rv); 643 int ssl_error = SSL_get_error(ssl_, rv);
573 OpenSSLErrorInfo error_info; 644 OpenSSLErrorInfo error_info;
574 net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info); 645 net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info);
575 646
647 // This hack is necessary because the mapping of SSL error codes to
648 // net_errors assumes (correctly for client sockets, but erroneously for
649 // server sockets) that peer cert verification failure can only occur if
650 // the cert changed during a renego.
davidben 2015/12/14 23:56:49 Want to file a bug about this? This is sort of a s
ryanchung 2015/12/16 22:40:01 Done. Created http://crbug.com/570351
651 if (net_error == ERR_SSL_SERVER_CERT_CHANGED)
652 net_error = ERR_BAD_SSL_CLIENT_AUTH_CERT;
653
576 // If not done, stay in this state 654 // If not done, stay in this state
577 if (net_error == ERR_IO_PENDING) { 655 if (net_error == ERR_IO_PENDING) {
578 GotoState(STATE_HANDSHAKE); 656 GotoState(STATE_HANDSHAKE);
579 } else { 657 } else {
580 LOG(ERROR) << "handshake failed; returned " << rv 658 LOG(ERROR) << "handshake failed; returned " << rv
581 << ", SSL error code " << ssl_error 659 << ", SSL error code " << ssl_error
582 << ", net_error " << net_error; 660 << ", net_error " << net_error;
583 net_log_.AddEvent( 661 net_log_.AddEvent(
584 NetLog::TYPE_SSL_HANDSHAKE_ERROR, 662 NetLog::TYPE_SSL_HANDSHAKE_ERROR,
585 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info)); 663 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
(...skipping 25 matching lines...) Expand all
611 ResetAndReturn(&user_write_callback_).Run(rv); 689 ResetAndReturn(&user_write_callback_).Run(rv);
612 } 690 }
613 691
614 int SSLServerSocketOpenSSL::Init() { 692 int SSLServerSocketOpenSSL::Init() {
615 DCHECK(!ssl_); 693 DCHECK(!ssl_);
616 DCHECK(!transport_bio_); 694 DCHECK(!transport_bio_);
617 695
618 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 696 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
619 697
620 ScopedSSL_CTX ssl_ctx(SSL_CTX_new(SSLv23_server_method())); 698 ScopedSSL_CTX ssl_ctx(SSL_CTX_new(SSLv23_server_method()));
621 699 if (ssl_server_config_.require_client_cert)
622 if (ssl_config_.require_client_cert)
623 SSL_CTX_set_verify(ssl_ctx.get(), SSL_VERIFY_PEER, NULL); 700 SSL_CTX_set_verify(ssl_ctx.get(), SSL_VERIFY_PEER, NULL);
624 701 SSL_CTX_set_cert_verify_callback(ssl_ctx.get(), CertVerifyCallback,
702 ssl_server_config_.client_cert_verifier);
625 ssl_ = SSL_new(ssl_ctx.get()); 703 ssl_ = SSL_new(ssl_ctx.get());
626 if (!ssl_) 704 if (!ssl_)
627 return ERR_UNEXPECTED; 705 return ERR_UNEXPECTED;
628 706
629 BIO* ssl_bio = NULL; 707 BIO* ssl_bio = NULL;
630 // 0 => use default buffer sizes. 708 // 0 => use default buffer sizes.
631 if (!BIO_new_bio_pair(&ssl_bio, 0, &transport_bio_, 0)) 709 if (!BIO_new_bio_pair(&ssl_bio, 0, &transport_bio_, 0))
632 return ERR_UNEXPECTED; 710 return ERR_UNEXPECTED;
633 DCHECK(ssl_bio); 711 DCHECK(ssl_bio);
634 DCHECK(transport_bio_); 712 DCHECK(transport_bio_);
(...skipping 26 matching lines...) Expand all
661 return ERR_UNEXPECTED; 739 return ERR_UNEXPECTED;
662 } 740 }
663 #endif // USE_OPENSSL_CERTS 741 #endif // USE_OPENSSL_CERTS
664 742
665 DCHECK(key_->key()); 743 DCHECK(key_->key());
666 if (SSL_use_PrivateKey(ssl_, key_->key()) != 1) { 744 if (SSL_use_PrivateKey(ssl_, key_->key()) != 1) {
667 LOG(ERROR) << "Cannot set private key."; 745 LOG(ERROR) << "Cannot set private key.";
668 return ERR_UNEXPECTED; 746 return ERR_UNEXPECTED;
669 } 747 }
670 748
671 DCHECK_LT(SSL3_VERSION, ssl_config_.version_min); 749 DCHECK_LT(SSL3_VERSION, ssl_server_config_.version_min);
672 DCHECK_LT(SSL3_VERSION, ssl_config_.version_max); 750 DCHECK_LT(SSL3_VERSION, ssl_server_config_.version_max);
673 SSL_set_min_version(ssl_, ssl_config_.version_min); 751 SSL_set_min_version(ssl_, ssl_server_config_.version_min);
674 SSL_set_max_version(ssl_, ssl_config_.version_max); 752 SSL_set_max_version(ssl_, ssl_server_config_.version_max);
675 753
676 // OpenSSL defaults some options to on, others to off. To avoid ambiguity, 754 // OpenSSL defaults some options to on, others to off. To avoid ambiguity,
677 // set everything we care about to an absolute value. 755 // set everything we care about to an absolute value.
678 SslSetClearMask options; 756 SslSetClearMask options;
679 options.ConfigureFlag(SSL_OP_NO_COMPRESSION, true); 757 options.ConfigureFlag(SSL_OP_NO_COMPRESSION, true);
680 758
681 SSL_set_options(ssl_, options.set_mask); 759 SSL_set_options(ssl_, options.set_mask);
682 SSL_clear_options(ssl_, options.clear_mask); 760 SSL_clear_options(ssl_, options.clear_mask);
683 761
684 // Same as above, this time for the SSL mode. 762 // Same as above, this time for the SSL mode.
685 SslSetClearMask mode; 763 SslSetClearMask mode;
686 764
687 mode.ConfigureFlag(SSL_MODE_RELEASE_BUFFERS, true); 765 mode.ConfigureFlag(SSL_MODE_RELEASE_BUFFERS, true);
688 766
689 SSL_set_mode(ssl_, mode.set_mask); 767 SSL_set_mode(ssl_, mode.set_mask);
690 SSL_clear_mode(ssl_, mode.clear_mask); 768 SSL_clear_mode(ssl_, mode.clear_mask);
691 769
692 // See SSLServerConfig::disabled_cipher_suites for description of the suites 770 // See SSLServerConfig::disabled_cipher_suites for description of the suites
693 // disabled by default. Note that !SHA256 and !SHA384 only remove HMAC-SHA256 771 // disabled by default. Note that !SHA256 and !SHA384 only remove HMAC-SHA256
694 // and HMAC-SHA384 cipher suites, not GCM cipher suites with SHA256 or SHA384 772 // and HMAC-SHA384 cipher suites, not GCM cipher suites with SHA256 or SHA384
695 // as the handshake hash. 773 // as the handshake hash.
696 std::string command("DEFAULT:!SHA256:!SHA384:!AESGCM+AES256:!aPSK"); 774 std::string command("DEFAULT:!SHA256:!SHA384:!AESGCM+AES256:!aPSK");
697 775
698 if (ssl_config_.require_ecdhe) 776 if (ssl_server_config_.require_ecdhe)
699 command.append(":!kRSA:!kDHE"); 777 command.append(":!kRSA:!kDHE");
700 778
701 // Remove any disabled ciphers. 779 // Remove any disabled ciphers.
702 for (uint16_t id : ssl_config_.disabled_cipher_suites) { 780 for (uint16_t id : ssl_server_config_.disabled_cipher_suites) {
703 const SSL_CIPHER* cipher = SSL_get_cipher_by_value(id); 781 const SSL_CIPHER* cipher = SSL_get_cipher_by_value(id);
704 if (cipher) { 782 if (cipher) {
705 command.append(":!"); 783 command.append(":!");
706 command.append(SSL_CIPHER_get_name(cipher)); 784 command.append(SSL_CIPHER_get_name(cipher));
707 } 785 }
708 } 786 }
709 787
710 int rv = SSL_set_cipher_list(ssl_, command.c_str()); 788 int rv = SSL_set_cipher_list(ssl_, command.c_str());
711 // If this fails (rv = 0) it means there are no ciphers enabled on this SSL. 789 // If this fails (rv = 0) it means there are no ciphers enabled on this SSL.
712 // This will almost certainly result in the socket failing to complete the 790 // This will almost certainly result in the socket failing to complete the
713 // handshake at which point the appropriate error is bubbled up to the client. 791 // handshake at which point the appropriate error is bubbled up to the client.
714 LOG_IF(WARNING, rv != 1) << "SSL_set_cipher_list('" << command 792 LOG_IF(WARNING, rv != 1) << "SSL_set_cipher_list('" << command
715 << "') returned " << rv; 793 << "') returned " << rv;
716 794
795 if (ssl_server_config_.require_client_cert) {
796 if (ssl_server_config_.client_cert_verifier)
797 ssl_->verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
davidben 2015/12/14 23:56:49 Please don't reach into BoringSSL's internal struc
ryanchung 2015/12/16 22:40:01 Done.
798 if (!ssl_server_config_.client_cert_ca_list.empty()) {
799 ScopedX509NameStack stack(sk_X509_NAME_new_null());
800 for (const auto& certificate : ssl_server_config_.client_cert_ca_list) {
801 ScopedX509 ca_cert =
802 OSCertHandleToOpenSSL(certificate->os_cert_handle());
803 ScopedX509Name subj(X509_NAME_dup(ca_cert->cert_info->subject));
804 sk_X509_NAME_push(stack.get(), subj.release());
805 }
806 SSL_set_client_CA_list(ssl_, stack.release());
807 }
808 }
809
717 return OK; 810 return OK;
718 } 811 }
719 812
813 void SSLServerSocketOpenSSL::ExtractClientCert() {
814 if (client_cert_.get() || !completed_handshake_) {
815 return;
davidben 2015/12/14 23:56:49 Rather than being a function that caches stuff and
ryanchung 2015/12/16 22:40:01 Done. Will call this function only after handshake
816 }
817 X509* cert = SSL_get_peer_certificate(ssl_);
818 STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl_);
davidben 2015/12/14 23:56:49 NB: This is NOT the verified chain. It is the list
819 client_cert_ = CreateX509Certificate(cert, chain);
820 }
821
822 // static
823 int SSLServerSocketOpenSSL::CertVerifyCallback(X509_STORE_CTX* store_ctx,
824 void* arg) {
825 ClientCertVerifier* verifier = reinterpret_cast<ClientCertVerifier*>(arg);
826 DCHECK(verifier);
davidben 2015/12/14 23:56:49 This DCHECK is false. You sometimes install NULL o
ryanchung 2015/12/16 22:40:01 Done.
827 if (!verifier)
828 return 1;
829 SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(
830 store_ctx, SSL_get_ex_data_X509_STORE_CTX_idx()));
831 DCHECK(ssl);
832 X509* x = store_ctx->cert;
833 STACK_OF(X509)* chain = store_ctx->chain;
davidben 2015/12/14 23:56:49 I believe this is always NULL. You want store_ctx-
ryanchung 2015/12/16 22:40:01 Done.
834 scoped_refptr<X509Certificate> client_cert(CreateX509Certificate(x, chain));
835
836 int res = verifier->Verify(client_cert.get());
837 if (res == OK) {
838 return 1;
839 } else {
840 X509_STORE_CTX_set_error(store_ctx, X509_V_ERR_CERT_REJECTED);
davidben 2015/12/14 23:56:49 Optional: If you also want to preserve res, OpenSS
841 return 0;
842 }
843 }
844
720 } // namespace net 845 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698