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_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) { |
| 31 unsigned char* cert_data = NULL; |
| 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; |
| 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 SSLServerSocketContext context; |
35 new SSLServerSocketOpenSSL(socket.Pass(), certificate, key, ssl_config)); | 83 return scoped_ptr<SSLServerSocket>(new SSLServerSocketOpenSSL( |
| 84 socket.Pass(), certificate, key, ssl_server_config, context)); |
| 85 } |
| 86 |
| 87 scoped_ptr<SSLServerSocket> CreateSSLServerSocket( |
| 88 scoped_ptr<StreamSocket> socket, |
| 89 X509Certificate* certificate, |
| 90 crypto::RSAPrivateKey* key, |
| 91 const SSLServerConfig& ssl_server_config, |
| 92 const SSLServerSocketContext& context) { |
| 93 crypto::EnsureOpenSSLInit(); |
| 94 return scoped_ptr<SSLServerSocket>(new SSLServerSocketOpenSSL( |
| 95 socket.Pass(), certificate, key, ssl_server_config, context)); |
36 } | 96 } |
37 | 97 |
38 SSLServerSocketOpenSSL::SSLServerSocketOpenSSL( | 98 SSLServerSocketOpenSSL::SSLServerSocketOpenSSL( |
39 scoped_ptr<StreamSocket> transport_socket, | 99 scoped_ptr<StreamSocket> transport_socket, |
40 scoped_refptr<X509Certificate> certificate, | 100 scoped_refptr<X509Certificate> certificate, |
41 crypto::RSAPrivateKey* key, | 101 crypto::RSAPrivateKey* key, |
42 const SSLServerConfig& ssl_config) | 102 const SSLServerConfig& ssl_server_config, |
| 103 const SSLServerSocketContext& context) |
43 : transport_send_busy_(false), | 104 : transport_send_busy_(false), |
44 transport_recv_busy_(false), | 105 transport_recv_busy_(false), |
45 transport_recv_eof_(false), | 106 transport_recv_eof_(false), |
46 user_read_buf_len_(0), | 107 user_read_buf_len_(0), |
47 user_write_buf_len_(0), | 108 user_write_buf_len_(0), |
48 transport_write_error_(OK), | 109 transport_write_error_(OK), |
49 ssl_(NULL), | 110 ssl_(NULL), |
50 transport_bio_(NULL), | 111 transport_bio_(NULL), |
51 transport_socket_(transport_socket.Pass()), | 112 transport_socket_(transport_socket.Pass()), |
52 ssl_config_(ssl_config), | 113 ssl_server_config_(ssl_server_config), |
| 114 context_(context), |
53 cert_(certificate), | 115 cert_(certificate), |
54 next_handshake_state_(STATE_NONE), | 116 next_handshake_state_(STATE_NONE), |
55 completed_handshake_(false) { | 117 completed_handshake_(false) { |
56 // TODO(byungchul): Need a better way to clone a key. | 118 // TODO(byungchul): Need a better way to clone a key. |
57 std::vector<uint8> key_bytes; | 119 std::vector<uint8> key_bytes; |
58 CHECK(key->ExportPrivateKey(&key_bytes)); | 120 CHECK(key->ExportPrivateKey(&key_bytes)); |
59 key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes)); | 121 key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes)); |
60 CHECK(key_.get()); | 122 CHECK(key_.get()); |
61 } | 123 } |
62 | 124 |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 NOTIMPLEMENTED(); | 299 NOTIMPLEMENTED(); |
238 return false; | 300 return false; |
239 } | 301 } |
240 | 302 |
241 NextProto SSLServerSocketOpenSSL::GetNegotiatedProtocol() const { | 303 NextProto SSLServerSocketOpenSSL::GetNegotiatedProtocol() const { |
242 // NPN is not supported by this class. | 304 // NPN is not supported by this class. |
243 return kProtoUnknown; | 305 return kProtoUnknown; |
244 } | 306 } |
245 | 307 |
246 bool SSLServerSocketOpenSSL::GetSSLInfo(SSLInfo* ssl_info) { | 308 bool SSLServerSocketOpenSSL::GetSSLInfo(SSLInfo* ssl_info) { |
247 NOTIMPLEMENTED(); | 309 ssl_info->Reset(); |
248 return false; | 310 if (!completed_handshake_) { |
| 311 return false; |
| 312 } |
| 313 ExtractClientCert(); |
| 314 ssl_info->cert = client_cert_; |
| 315 ssl_info->client_cert_sent = |
| 316 ssl_server_config_.require_client_cert && client_cert_.get(); |
| 317 |
| 318 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl_); |
| 319 CHECK(cipher); |
| 320 ssl_info->security_bits = SSL_CIPHER_get_bits(cipher, NULL); |
| 321 |
| 322 ssl_info->connection_status = |
| 323 EncodeSSLConnectionStatus(SSL_CIPHER_get_id(cipher), |
| 324 0 /* no compression */, GetNetSSLVersion(ssl_)); |
| 325 |
| 326 if (!SSL_get_secure_renegotiation_support(ssl_)) |
| 327 ssl_info->connection_status |= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION; |
| 328 |
| 329 ssl_info->handshake_type = SSL_session_reused(ssl_) |
| 330 ? SSLInfo::HANDSHAKE_RESUME |
| 331 : SSLInfo::HANDSHAKE_FULL; |
| 332 |
| 333 return true; |
249 } | 334 } |
250 | 335 |
251 void SSLServerSocketOpenSSL::GetConnectionAttempts( | 336 void SSLServerSocketOpenSSL::GetConnectionAttempts( |
252 ConnectionAttempts* out) const { | 337 ConnectionAttempts* out) const { |
253 out->clear(); | 338 out->clear(); |
254 } | 339 } |
255 | 340 |
256 int64_t SSLServerSocketOpenSSL::GetTotalReceivedBytes() const { | 341 int64_t SSLServerSocketOpenSSL::GetTotalReceivedBytes() const { |
257 return transport_socket_->GetTotalReceivedBytes(); | 342 return transport_socket_->GetTotalReceivedBytes(); |
258 } | 343 } |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 int net_error = OK; | 651 int net_error = OK; |
567 int rv = SSL_do_handshake(ssl_); | 652 int rv = SSL_do_handshake(ssl_); |
568 | 653 |
569 if (rv == 1) { | 654 if (rv == 1) { |
570 completed_handshake_ = true; | 655 completed_handshake_ = true; |
571 } else { | 656 } else { |
572 int ssl_error = SSL_get_error(ssl_, rv); | 657 int ssl_error = SSL_get_error(ssl_, rv); |
573 OpenSSLErrorInfo error_info; | 658 OpenSSLErrorInfo error_info; |
574 net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info); | 659 net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info); |
575 | 660 |
| 661 // This hack is necessary because the mapping of SSL error codes to |
| 662 // net_errors assumes (correctly for client sockets, but erroneously for |
| 663 // server sockets) that peer cert verification failure can only occur if |
| 664 // the cert changed during a renego. |
| 665 if (net_error == ERR_SSL_SERVER_CERT_CHANGED) |
| 666 net_error = ERR_BAD_SSL_CLIENT_AUTH_CERT; |
| 667 |
576 // If not done, stay in this state | 668 // If not done, stay in this state |
577 if (net_error == ERR_IO_PENDING) { | 669 if (net_error == ERR_IO_PENDING) { |
578 GotoState(STATE_HANDSHAKE); | 670 GotoState(STATE_HANDSHAKE); |
579 } else { | 671 } else { |
580 LOG(ERROR) << "handshake failed; returned " << rv | 672 LOG(ERROR) << "handshake failed; returned " << rv |
581 << ", SSL error code " << ssl_error | 673 << ", SSL error code " << ssl_error |
582 << ", net_error " << net_error; | 674 << ", net_error " << net_error; |
583 net_log_.AddEvent( | 675 net_log_.AddEvent( |
584 NetLog::TYPE_SSL_HANDSHAKE_ERROR, | 676 NetLog::TYPE_SSL_HANDSHAKE_ERROR, |
585 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info)); | 677 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info)); |
(...skipping 25 matching lines...) Expand all Loading... |
611 ResetAndReturn(&user_write_callback_).Run(rv); | 703 ResetAndReturn(&user_write_callback_).Run(rv); |
612 } | 704 } |
613 | 705 |
614 int SSLServerSocketOpenSSL::Init() { | 706 int SSLServerSocketOpenSSL::Init() { |
615 DCHECK(!ssl_); | 707 DCHECK(!ssl_); |
616 DCHECK(!transport_bio_); | 708 DCHECK(!transport_bio_); |
617 | 709 |
618 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 710 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
619 | 711 |
620 ScopedSSL_CTX ssl_ctx(SSL_CTX_new(SSLv23_server_method())); | 712 ScopedSSL_CTX ssl_ctx(SSL_CTX_new(SSLv23_server_method())); |
621 | 713 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); | 714 SSL_CTX_set_verify(ssl_ctx.get(), SSL_VERIFY_PEER, NULL); |
624 | 715 SSL_CTX_set_cert_verify_callback(ssl_ctx.get(), CertVerifyCallback, this); |
625 ssl_ = SSL_new(ssl_ctx.get()); | 716 ssl_ = SSL_new(ssl_ctx.get()); |
626 if (!ssl_) | 717 if (!ssl_) |
627 return ERR_UNEXPECTED; | 718 return ERR_UNEXPECTED; |
628 | 719 |
629 BIO* ssl_bio = NULL; | 720 BIO* ssl_bio = NULL; |
630 // 0 => use default buffer sizes. | 721 // 0 => use default buffer sizes. |
631 if (!BIO_new_bio_pair(&ssl_bio, 0, &transport_bio_, 0)) | 722 if (!BIO_new_bio_pair(&ssl_bio, 0, &transport_bio_, 0)) |
632 return ERR_UNEXPECTED; | 723 return ERR_UNEXPECTED; |
633 DCHECK(ssl_bio); | 724 DCHECK(ssl_bio); |
634 DCHECK(transport_bio_); | 725 DCHECK(transport_bio_); |
(...skipping 26 matching lines...) Expand all Loading... |
661 return ERR_UNEXPECTED; | 752 return ERR_UNEXPECTED; |
662 } | 753 } |
663 #endif // USE_OPENSSL_CERTS | 754 #endif // USE_OPENSSL_CERTS |
664 | 755 |
665 DCHECK(key_->key()); | 756 DCHECK(key_->key()); |
666 if (SSL_use_PrivateKey(ssl_, key_->key()) != 1) { | 757 if (SSL_use_PrivateKey(ssl_, key_->key()) != 1) { |
667 LOG(ERROR) << "Cannot set private key."; | 758 LOG(ERROR) << "Cannot set private key."; |
668 return ERR_UNEXPECTED; | 759 return ERR_UNEXPECTED; |
669 } | 760 } |
670 | 761 |
671 DCHECK_LT(SSL3_VERSION, ssl_config_.version_min); | 762 DCHECK_LT(SSL3_VERSION, ssl_server_config_.version_min); |
672 DCHECK_LT(SSL3_VERSION, ssl_config_.version_max); | 763 DCHECK_LT(SSL3_VERSION, ssl_server_config_.version_max); |
673 SSL_set_min_version(ssl_, ssl_config_.version_min); | 764 SSL_set_min_version(ssl_, ssl_server_config_.version_min); |
674 SSL_set_max_version(ssl_, ssl_config_.version_max); | 765 SSL_set_max_version(ssl_, ssl_server_config_.version_max); |
675 | 766 |
676 // OpenSSL defaults some options to on, others to off. To avoid ambiguity, | 767 // OpenSSL defaults some options to on, others to off. To avoid ambiguity, |
677 // set everything we care about to an absolute value. | 768 // set everything we care about to an absolute value. |
678 SslSetClearMask options; | 769 SslSetClearMask options; |
679 options.ConfigureFlag(SSL_OP_NO_COMPRESSION, true); | 770 options.ConfigureFlag(SSL_OP_NO_COMPRESSION, true); |
680 | 771 |
681 SSL_set_options(ssl_, options.set_mask); | 772 SSL_set_options(ssl_, options.set_mask); |
682 SSL_clear_options(ssl_, options.clear_mask); | 773 SSL_clear_options(ssl_, options.clear_mask); |
683 | 774 |
684 // Same as above, this time for the SSL mode. | 775 // Same as above, this time for the SSL mode. |
685 SslSetClearMask mode; | 776 SslSetClearMask mode; |
686 | 777 |
687 mode.ConfigureFlag(SSL_MODE_RELEASE_BUFFERS, true); | 778 mode.ConfigureFlag(SSL_MODE_RELEASE_BUFFERS, true); |
688 | 779 |
689 SSL_set_mode(ssl_, mode.set_mask); | 780 SSL_set_mode(ssl_, mode.set_mask); |
690 SSL_clear_mode(ssl_, mode.clear_mask); | 781 SSL_clear_mode(ssl_, mode.clear_mask); |
691 | 782 |
692 // See SSLServerConfig::disabled_cipher_suites for description of the suites | 783 // See SSLServerConfig::disabled_cipher_suites for description of the suites |
693 // disabled by default. Note that !SHA256 and !SHA384 only remove HMAC-SHA256 | 784 // 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 | 785 // and HMAC-SHA384 cipher suites, not GCM cipher suites with SHA256 or SHA384 |
695 // as the handshake hash. | 786 // as the handshake hash. |
696 std::string command("DEFAULT:!SHA256:!SHA384:!AESGCM+AES256:!aPSK"); | 787 std::string command("DEFAULT:!SHA256:!SHA384:!AESGCM+AES256:!aPSK"); |
697 | 788 |
698 if (ssl_config_.require_ecdhe) | 789 if (ssl_server_config_.require_ecdhe) |
699 command.append(":!kRSA:!kDHE"); | 790 command.append(":!kRSA:!kDHE"); |
700 | 791 |
701 // Remove any disabled ciphers. | 792 // Remove any disabled ciphers. |
702 for (uint16_t id : ssl_config_.disabled_cipher_suites) { | 793 for (uint16_t id : ssl_server_config_.disabled_cipher_suites) { |
703 const SSL_CIPHER* cipher = SSL_get_cipher_by_value(id); | 794 const SSL_CIPHER* cipher = SSL_get_cipher_by_value(id); |
704 if (cipher) { | 795 if (cipher) { |
705 command.append(":!"); | 796 command.append(":!"); |
706 command.append(SSL_CIPHER_get_name(cipher)); | 797 command.append(SSL_CIPHER_get_name(cipher)); |
707 } | 798 } |
708 } | 799 } |
709 | 800 |
710 int rv = SSL_set_cipher_list(ssl_, command.c_str()); | 801 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. | 802 // 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 | 803 // 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. | 804 // handshake at which point the appropriate error is bubbled up to the client. |
714 LOG_IF(WARNING, rv != 1) << "SSL_set_cipher_list('" << command | 805 LOG_IF(WARNING, rv != 1) << "SSL_set_cipher_list('" << command |
715 << "') returned " << rv; | 806 << "') returned " << rv; |
716 | 807 |
| 808 if (ssl_server_config_.require_client_cert) { |
| 809 if (context_.client_cert_verifier) |
| 810 ssl_->verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; |
| 811 if (!ssl_server_config_.client_cert_ca_list.empty()) { |
| 812 ScopedX509NameStack stack(sk_X509_NAME_new_null()); |
| 813 for (const auto& certificate : ssl_server_config_.client_cert_ca_list) { |
| 814 ScopedX509 ca_cert = |
| 815 OSCertHandleToOpenSSL(certificate->os_cert_handle()); |
| 816 ScopedX509Name subj(X509_NAME_dup(ca_cert->cert_info->subject)); |
| 817 sk_X509_NAME_push(stack.get(), subj.release()); |
| 818 } |
| 819 SSL_set_client_CA_list(ssl_, stack.release()); |
| 820 } |
| 821 } |
| 822 |
717 return OK; | 823 return OK; |
718 } | 824 } |
719 | 825 |
| 826 void SSLServerSocketOpenSSL::ExtractClientCert() { |
| 827 if (client_cert_.get() || !completed_handshake_) { |
| 828 return; |
| 829 } |
| 830 X509* cert = SSL_get_peer_certificate(ssl_); |
| 831 STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl_); |
| 832 client_cert_ = CreateX509Certificate(cert, chain); |
| 833 } |
| 834 |
| 835 // static |
| 836 int SSLServerSocketOpenSSL::CertVerifyCallback(X509_STORE_CTX* store_ctx, |
| 837 void* arg) { |
| 838 SSLServerSocketOpenSSL* self = reinterpret_cast<SSLServerSocketOpenSSL*>(arg); |
| 839 DCHECK(self); |
| 840 if (!self->context_.client_cert_verifier) |
| 841 return 1; |
| 842 SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data( |
| 843 store_ctx, SSL_get_ex_data_X509_STORE_CTX_idx())); |
| 844 DCHECK(ssl); |
| 845 X509* x = store_ctx->cert; |
| 846 STACK_OF(X509)* chain = store_ctx->chain; |
| 847 scoped_refptr<X509Certificate> client_cert(CreateX509Certificate(x, chain)); |
| 848 |
| 849 int res = self->context_.client_cert_verifier->Verify(client_cert.get(), |
| 850 self->net_log_); |
| 851 if (res == OK) { |
| 852 self->client_cert_ = client_cert; |
| 853 return 1; |
| 854 } else { |
| 855 X509_STORE_CTX_set_error(store_ctx, X509_V_ERR_CERT_REJECTED); |
| 856 return 0; |
| 857 } |
| 858 } |
| 859 |
720 } // namespace net | 860 } // namespace net |
OLD | NEW |