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

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: Rebase only Created 4 years, 11 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
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 #include <utility> 9 #include <utility>
10 10
11 #include "base/callback_helpers.h" 11 #include "base/callback_helpers.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
14 #include "crypto/openssl_util.h" 14 #include "crypto/openssl_util.h"
15 #include "crypto/rsa_private_key.h" 15 #include "crypto/rsa_private_key.h"
16 #include "crypto/scoped_openssl_types.h" 16 #include "crypto/scoped_openssl_types.h"
17 #include "net/base/net_errors.h" 17 #include "net/base/net_errors.h"
18 #include "net/cert/cert_verify_result.h"
19 #include "net/cert/client_cert_verifier.h"
20 #include "net/cert/x509_util_openssl.h"
18 #include "net/ssl/openssl_ssl_util.h" 21 #include "net/ssl/openssl_ssl_util.h"
19 #include "net/ssl/scoped_openssl_types.h" 22 #include "net/ssl/scoped_openssl_types.h"
23 #include "net/ssl/ssl_connection_status_flags.h"
24 #include "net/ssl/ssl_info.h"
20 25
21 #define GotoState(s) next_handshake_state_ = s 26 #define GotoState(s) next_handshake_state_ = s
22 27
23 namespace net { 28 namespace net {
24 29
30 namespace {
31
32 scoped_refptr<X509Certificate> CreateX509Certificate(X509* cert,
33 STACK_OF(X509) * chain) {
34 std::vector<base::StringPiece> der_chain;
35 base::StringPiece der_cert;
36 scoped_refptr<X509Certificate> client_cert;
37 if (cert) {
davidben 2016/01/25 20:56:10 Bleh. This probably wants to be documented like:
ryanchung 2016/01/29 23:22:12 Done.
38 if (!x509_util::GetDER(cert, &der_cert))
39 return client_cert;
davidben 2016/01/25 20:56:10 If this fails, we should fail the connection, not
ryanchung 2016/01/29 23:22:12 Ok. I'm adding code to CertVerifyCallback to handl
40 der_chain.push_back(der_cert);
41 }
42
43 ScopedX509_STACK openssl_chain(X509_chain_up_ref(chain));
davidben 2016/01/25 20:56:10 What's the point of this copy?
ryanchung 2016/01/29 23:22:12 Done. Shouldn't need to copy. Removed.
44 for (size_t i = 0; i < sk_X509_num(openssl_chain.get()); ++i) {
45 X509* x = sk_X509_value(openssl_chain.get(), i);
46 if (x509_util::GetDER(x, &der_cert)) {
47 der_chain.push_back(der_cert);
48 } else {
49 return nullptr;
davidben 2016/01/25 20:56:10 Ditto re failing the connection.
ryanchung 2016/01/29 23:22:13 Ok. I'm adding code to CertVerifyCallback to handl
50 }
51 }
52
53 return X509Certificate::CreateFromDERCertChain(der_chain);
54 }
55
56 scoped_refptr<X509Certificate> GetClientCert(SSL* ssl) {
57 X509* cert = SSL_get_peer_certificate(ssl);
ryanchung 2016/01/29 23:22:13 I think this was a memory leak. SSL_get_peer_certi
58 STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl);
davidben 2016/01/25 20:56:10 Check if cert is NULL and, if so, this needs to re
ryanchung 2016/01/29 23:22:12 Done. Thanks.
59 return CreateX509Certificate(cert, chain);
60 }
61
62 void DoNothingOnCompletion(int ignore) {}
63
64 } // namespace
65
25 void EnableSSLServerSockets() { 66 void EnableSSLServerSockets() {
26 // No-op because CreateSSLServerSocket() calls crypto::EnsureOpenSSLInit(). 67 // No-op because CreateSSLServerSocket() calls crypto::EnsureOpenSSLInit().
27 } 68 }
28 69
29 scoped_ptr<SSLServerSocket> CreateSSLServerSocket( 70 scoped_ptr<SSLServerSocket> CreateSSLServerSocket(
30 scoped_ptr<StreamSocket> socket, 71 scoped_ptr<StreamSocket> socket,
31 X509Certificate* certificate, 72 X509Certificate* certificate,
32 const crypto::RSAPrivateKey& key, 73 const crypto::RSAPrivateKey& key,
33 const SSLServerConfig& ssl_config) { 74 const SSLServerConfig& ssl_server_config) {
34 crypto::EnsureOpenSSLInit(); 75 crypto::EnsureOpenSSLInit();
35 return scoped_ptr<SSLServerSocket>(new SSLServerSocketOpenSSL( 76 return scoped_ptr<SSLServerSocket>(new SSLServerSocketOpenSSL(
36 std::move(socket), certificate, key, ssl_config)); 77 std::move(socket), certificate, key, ssl_server_config));
37 } 78 }
38 79
39 SSLServerSocketOpenSSL::SSLServerSocketOpenSSL( 80 SSLServerSocketOpenSSL::SSLServerSocketOpenSSL(
40 scoped_ptr<StreamSocket> transport_socket, 81 scoped_ptr<StreamSocket> transport_socket,
41 scoped_refptr<X509Certificate> certificate, 82 scoped_refptr<X509Certificate> certificate,
42 const crypto::RSAPrivateKey& key, 83 const crypto::RSAPrivateKey& key,
43 const SSLServerConfig& ssl_config) 84 const SSLServerConfig& ssl_server_config)
44 : transport_send_busy_(false), 85 : transport_send_busy_(false),
45 transport_recv_busy_(false), 86 transport_recv_busy_(false),
46 transport_recv_eof_(false), 87 transport_recv_eof_(false),
47 user_read_buf_len_(0), 88 user_read_buf_len_(0),
48 user_write_buf_len_(0), 89 user_write_buf_len_(0),
49 transport_write_error_(OK), 90 transport_write_error_(OK),
50 ssl_(NULL), 91 ssl_(NULL),
51 transport_bio_(NULL), 92 transport_bio_(NULL),
52 transport_socket_(std::move(transport_socket)), 93 transport_socket_(std::move(transport_socket)),
53 ssl_config_(ssl_config), 94 ssl_server_config_(ssl_server_config),
54 cert_(certificate), 95 cert_(certificate),
55 key_(key.Copy()), 96 key_(key.Copy()),
56 next_handshake_state_(STATE_NONE), 97 next_handshake_state_(STATE_NONE),
57 completed_handshake_(false) { 98 completed_handshake_(false) {
58 CHECK(key_); 99 CHECK(key_);
59 } 100 }
60 101
61 SSLServerSocketOpenSSL::~SSLServerSocketOpenSSL() { 102 SSLServerSocketOpenSSL::~SSLServerSocketOpenSSL() {
62 if (ssl_) { 103 if (ssl_) {
63 // Calling SSL_shutdown prevents the session from being marked as 104 // Calling SSL_shutdown prevents the session from being marked as
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 NOTIMPLEMENTED(); 276 NOTIMPLEMENTED();
236 return false; 277 return false;
237 } 278 }
238 279
239 NextProto SSLServerSocketOpenSSL::GetNegotiatedProtocol() const { 280 NextProto SSLServerSocketOpenSSL::GetNegotiatedProtocol() const {
240 // NPN is not supported by this class. 281 // NPN is not supported by this class.
241 return kProtoUnknown; 282 return kProtoUnknown;
242 } 283 }
243 284
244 bool SSLServerSocketOpenSSL::GetSSLInfo(SSLInfo* ssl_info) { 285 bool SSLServerSocketOpenSSL::GetSSLInfo(SSLInfo* ssl_info) {
245 NOTIMPLEMENTED(); 286 ssl_info->Reset();
246 return false; 287 if (!completed_handshake_)
288 return false;
289
290 ssl_info->cert = client_cert_;
291
292 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl_);
293 CHECK(cipher);
294 ssl_info->security_bits = SSL_CIPHER_get_bits(cipher, NULL);
295
296 SSLConnectionStatusSetCipherSuite(
297 static_cast<uint16_t>(SSL_CIPHER_get_id(cipher)),
298 &ssl_info->connection_status);
299 SSLConnectionStatusSetVersion(GetNetSSLVersion(ssl_),
300 &ssl_info->connection_status);
301
302 if (!SSL_get_secure_renegotiation_support(ssl_))
303 ssl_info->connection_status |= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION;
304
305 ssl_info->handshake_type = SSL_session_reused(ssl_)
306 ? SSLInfo::HANDSHAKE_RESUME
307 : SSLInfo::HANDSHAKE_FULL;
308
309 return true;
247 } 310 }
248 311
249 void SSLServerSocketOpenSSL::GetConnectionAttempts( 312 void SSLServerSocketOpenSSL::GetConnectionAttempts(
250 ConnectionAttempts* out) const { 313 ConnectionAttempts* out) const {
251 out->clear(); 314 out->clear();
252 } 315 }
253 316
254 int64_t SSLServerSocketOpenSSL::GetTotalReceivedBytes() const { 317 int64_t SSLServerSocketOpenSSL::GetTotalReceivedBytes() const {
255 return transport_socket_->GetTotalReceivedBytes(); 318 return transport_socket_->GetTotalReceivedBytes();
256 } 319 }
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 return rv; 622 return rv;
560 } 623 }
561 624
562 int SSLServerSocketOpenSSL::DoHandshake() { 625 int SSLServerSocketOpenSSL::DoHandshake() {
563 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 626 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
564 int net_error = OK; 627 int net_error = OK;
565 int rv = SSL_do_handshake(ssl_); 628 int rv = SSL_do_handshake(ssl_);
566 629
567 if (rv == 1) { 630 if (rv == 1) {
568 completed_handshake_ = true; 631 completed_handshake_ = true;
632 client_cert_ = GetClientCert(ssl_);
569 } else { 633 } else {
570 int ssl_error = SSL_get_error(ssl_, rv); 634 int ssl_error = SSL_get_error(ssl_, rv);
571 OpenSSLErrorInfo error_info; 635 OpenSSLErrorInfo error_info;
572 net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info); 636 net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info);
573 637
638 // This hack is necessary because the mapping of SSL error codes to
639 // net_errors assumes (correctly for client sockets, but erroneously for
640 // server sockets) that peer cert verification failure can only occur if
641 // the cert changed during a renego. crbug.com/570351
642 if (net_error == ERR_SSL_SERVER_CERT_CHANGED)
643 net_error = ERR_BAD_SSL_CLIENT_AUTH_CERT;
644
574 // If not done, stay in this state 645 // If not done, stay in this state
575 if (net_error == ERR_IO_PENDING) { 646 if (net_error == ERR_IO_PENDING) {
576 GotoState(STATE_HANDSHAKE); 647 GotoState(STATE_HANDSHAKE);
577 } else { 648 } else {
578 LOG(ERROR) << "handshake failed; returned " << rv 649 LOG(ERROR) << "handshake failed; returned " << rv
579 << ", SSL error code " << ssl_error 650 << ", SSL error code " << ssl_error
580 << ", net_error " << net_error; 651 << ", net_error " << net_error;
581 net_log_.AddEvent( 652 net_log_.AddEvent(
582 NetLog::TYPE_SSL_HANDSHAKE_ERROR, 653 NetLog::TYPE_SSL_HANDSHAKE_ERROR,
583 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info)); 654 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
(...skipping 25 matching lines...) Expand all
609 ResetAndReturn(&user_write_callback_).Run(rv); 680 ResetAndReturn(&user_write_callback_).Run(rv);
610 } 681 }
611 682
612 int SSLServerSocketOpenSSL::Init() { 683 int SSLServerSocketOpenSSL::Init() {
613 DCHECK(!ssl_); 684 DCHECK(!ssl_);
614 DCHECK(!transport_bio_); 685 DCHECK(!transport_bio_);
615 686
616 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 687 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
617 688
618 ScopedSSL_CTX ssl_ctx(SSL_CTX_new(SSLv23_server_method())); 689 ScopedSSL_CTX ssl_ctx(SSL_CTX_new(SSLv23_server_method()));
619 690 if (ssl_server_config_.require_client_cert) {
620 if (ssl_config_.require_client_cert) 691 SSL_CTX_set_verify(ssl_ctx.get(),
621 SSL_CTX_set_verify(ssl_ctx.get(), SSL_VERIFY_PEER, NULL); 692 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
davidben 2016/01/25 20:56:10 NULL -> nullptr
ryanchung 2016/01/29 23:22:12 Done.
622 693 }
694 SSL_CTX_set_cert_verify_callback(ssl_ctx.get(), CertVerifyCallback,
695 ssl_server_config_.client_cert_verifier);
davidben 2016/01/25 20:56:10 This probably should also go in the conditional, n
ryanchung 2016/01/29 23:22:13 Done.
623 ssl_ = SSL_new(ssl_ctx.get()); 696 ssl_ = SSL_new(ssl_ctx.get());
624 if (!ssl_) 697 if (!ssl_)
625 return ERR_UNEXPECTED; 698 return ERR_UNEXPECTED;
626 699
627 BIO* ssl_bio = NULL; 700 BIO* ssl_bio = NULL;
628 // 0 => use default buffer sizes. 701 // 0 => use default buffer sizes.
629 if (!BIO_new_bio_pair(&ssl_bio, 0, &transport_bio_, 0)) 702 if (!BIO_new_bio_pair(&ssl_bio, 0, &transport_bio_, 0))
630 return ERR_UNEXPECTED; 703 return ERR_UNEXPECTED;
631 DCHECK(ssl_bio); 704 DCHECK(ssl_bio);
632 DCHECK(transport_bio_); 705 DCHECK(transport_bio_);
(...skipping 26 matching lines...) Expand all
659 return ERR_UNEXPECTED; 732 return ERR_UNEXPECTED;
660 } 733 }
661 #endif // USE_OPENSSL_CERTS 734 #endif // USE_OPENSSL_CERTS
662 735
663 DCHECK(key_->key()); 736 DCHECK(key_->key());
664 if (SSL_use_PrivateKey(ssl_, key_->key()) != 1) { 737 if (SSL_use_PrivateKey(ssl_, key_->key()) != 1) {
665 LOG(ERROR) << "Cannot set private key."; 738 LOG(ERROR) << "Cannot set private key.";
666 return ERR_UNEXPECTED; 739 return ERR_UNEXPECTED;
667 } 740 }
668 741
669 DCHECK_LT(SSL3_VERSION, ssl_config_.version_min); 742 DCHECK_LT(SSL3_VERSION, ssl_server_config_.version_min);
670 DCHECK_LT(SSL3_VERSION, ssl_config_.version_max); 743 DCHECK_LT(SSL3_VERSION, ssl_server_config_.version_max);
671 SSL_set_min_version(ssl_, ssl_config_.version_min); 744 SSL_set_min_version(ssl_, ssl_server_config_.version_min);
672 SSL_set_max_version(ssl_, ssl_config_.version_max); 745 SSL_set_max_version(ssl_, ssl_server_config_.version_max);
673 746
674 // OpenSSL defaults some options to on, others to off. To avoid ambiguity, 747 // OpenSSL defaults some options to on, others to off. To avoid ambiguity,
675 // set everything we care about to an absolute value. 748 // set everything we care about to an absolute value.
676 SslSetClearMask options; 749 SslSetClearMask options;
677 options.ConfigureFlag(SSL_OP_NO_COMPRESSION, true); 750 options.ConfigureFlag(SSL_OP_NO_COMPRESSION, true);
678 751
679 SSL_set_options(ssl_, options.set_mask); 752 SSL_set_options(ssl_, options.set_mask);
680 SSL_clear_options(ssl_, options.clear_mask); 753 SSL_clear_options(ssl_, options.clear_mask);
681 754
682 // Same as above, this time for the SSL mode. 755 // Same as above, this time for the SSL mode.
683 SslSetClearMask mode; 756 SslSetClearMask mode;
684 757
685 mode.ConfigureFlag(SSL_MODE_RELEASE_BUFFERS, true); 758 mode.ConfigureFlag(SSL_MODE_RELEASE_BUFFERS, true);
686 759
687 SSL_set_mode(ssl_, mode.set_mask); 760 SSL_set_mode(ssl_, mode.set_mask);
688 SSL_clear_mode(ssl_, mode.clear_mask); 761 SSL_clear_mode(ssl_, mode.clear_mask);
689 762
690 // See SSLServerConfig::disabled_cipher_suites for description of the suites 763 // See SSLServerConfig::disabled_cipher_suites for description of the suites
691 // disabled by default. Note that !SHA256 and !SHA384 only remove HMAC-SHA256 764 // disabled by default. Note that !SHA256 and !SHA384 only remove HMAC-SHA256
692 // and HMAC-SHA384 cipher suites, not GCM cipher suites with SHA256 or SHA384 765 // and HMAC-SHA384 cipher suites, not GCM cipher suites with SHA256 or SHA384
693 // as the handshake hash. 766 // as the handshake hash.
694 std::string command("DEFAULT:!SHA256:!SHA384:!AESGCM+AES256:!aPSK"); 767 std::string command("DEFAULT:!SHA256:!SHA384:!AESGCM+AES256:!aPSK");
695 768
696 if (ssl_config_.require_ecdhe) 769 if (ssl_server_config_.require_ecdhe)
697 command.append(":!kRSA:!kDHE"); 770 command.append(":!kRSA:!kDHE");
698 771
699 // Remove any disabled ciphers. 772 // Remove any disabled ciphers.
700 for (uint16_t id : ssl_config_.disabled_cipher_suites) { 773 for (uint16_t id : ssl_server_config_.disabled_cipher_suites) {
701 const SSL_CIPHER* cipher = SSL_get_cipher_by_value(id); 774 const SSL_CIPHER* cipher = SSL_get_cipher_by_value(id);
702 if (cipher) { 775 if (cipher) {
703 command.append(":!"); 776 command.append(":!");
704 command.append(SSL_CIPHER_get_name(cipher)); 777 command.append(SSL_CIPHER_get_name(cipher));
705 } 778 }
706 } 779 }
707 780
708 int rv = SSL_set_cipher_list(ssl_, command.c_str()); 781 int rv = SSL_set_cipher_list(ssl_, command.c_str());
709 // If this fails (rv = 0) it means there are no ciphers enabled on this SSL. 782 // If this fails (rv = 0) it means there are no ciphers enabled on this SSL.
710 // This will almost certainly result in the socket failing to complete the 783 // This will almost certainly result in the socket failing to complete the
711 // handshake at which point the appropriate error is bubbled up to the client. 784 // handshake at which point the appropriate error is bubbled up to the client.
712 LOG_IF(WARNING, rv != 1) << "SSL_set_cipher_list('" << command 785 LOG_IF(WARNING, rv != 1) << "SSL_set_cipher_list('" << command
713 << "') returned " << rv; 786 << "') returned " << rv;
714 787
788 if (ssl_server_config_.require_client_cert &&
789 !ssl_server_config_.cert_authorities_.empty()) {
790 ScopedX509_NAME_STACK stack(sk_X509_NAME_new_null());
791 for (const auto& authority : ssl_server_config_.cert_authorities_) {
792 const unsigned char* name =
793 reinterpret_cast<const unsigned char*>(authority.c_str());
davidben 2016/01/25 20:56:10 uint8_t, not unsigned char
ryanchung 2016/01/29 23:22:13 Done.
794 ScopedX509_NAME subj(d2i_X509_NAME(NULL, &name, authority.length()));
davidben 2016/01/25 20:56:10 This needs error-handling. d2i_X509_NAME parses th
davidben 2016/01/25 20:56:10 Nit: NULL -> nullptr
ryanchung 2016/01/29 23:22:13 Done.
ryanchung 2016/01/29 23:22:13 Done.
795 sk_X509_NAME_push(stack.get(), subj.release());
796 }
797 SSL_set_client_CA_list(ssl_, stack.release());
798 }
799
715 return OK; 800 return OK;
716 } 801 }
717 802
803 // static
804 int SSLServerSocketOpenSSL::CertVerifyCallback(X509_STORE_CTX* store_ctx,
805 void* arg) {
806 ClientCertVerifier* verifier = reinterpret_cast<ClientCertVerifier*>(arg);
807 // If a verifier was not supplied, all certificates are accepted.
808 if (!verifier)
809 return 1;
810 SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(
811 store_ctx, SSL_get_ex_data_X509_STORE_CTX_idx()));
davidben 2016/01/25 20:56:10 You don't seem to be doing anything with this vari
ryanchung 2016/01/29 23:22:12 Done. Removed.
812 DCHECK(ssl);
813 STACK_OF(X509)* chain = store_ctx->untrusted;
814 scoped_ptr<ClientCertVerifier::Request> ignore_async;
davidben 2016/01/25 20:56:10 Very nitpicky nit: declare variables near where th
ryanchung 2016/01/29 23:22:13 Done.
815 scoped_refptr<X509Certificate> client_cert(
816 CreateX509Certificate(nullptr, chain));
817
818 int res = verifier->Verify(client_cert.get(),
davidben 2016/01/25 20:56:10 This really needs a comment as to what's going on
ryanchung 2016/01/29 23:22:12 Done.
819 base::Bind(&DoNothingOnCompletion), &ignore_async);
820 if (res != OK) {
821 X509_STORE_CTX_set_error(store_ctx, X509_V_ERR_CERT_REJECTED);
822 return 0;
823 }
824 return 1;
825 }
826
718 } // namespace net 827 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698