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

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

Issue 517083002: Enable Certificate Transparency in the OpenSSL port. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ct-objects-extractor
Patch Set: move comment Created 6 years, 3 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
« no previous file with comments | « net/socket/ssl_client_socket_openssl.h ('k') | net/socket/ssl_client_socket_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // OpenSSL binding for SSLClientSocket. The class layout and general principle 5 // OpenSSL binding for SSLClientSocket. The class layout and general principle
6 // of operation is derived from SSLClientSocketNSS. 6 // of operation is derived from SSLClientSocketNSS.
7 7
8 #include "net/socket/ssl_client_socket_openssl.h" 8 #include "net/socket/ssl_client_socket_openssl.h"
9 9
10 #include <errno.h> 10 #include <errno.h>
11 #include <openssl/err.h> 11 #include <openssl/err.h>
12 #include <openssl/ssl.h> 12 #include <openssl/ssl.h>
13 13
14 #include "base/bind.h" 14 #include "base/bind.h"
15 #include "base/callback_helpers.h" 15 #include "base/callback_helpers.h"
16 #include "base/memory/singleton.h" 16 #include "base/memory/singleton.h"
17 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
18 #include "base/synchronization/lock.h" 18 #include "base/synchronization/lock.h"
19 #include "crypto/ec_private_key.h" 19 #include "crypto/ec_private_key.h"
20 #include "crypto/openssl_util.h" 20 #include "crypto/openssl_util.h"
21 #include "crypto/scoped_openssl_types.h" 21 #include "crypto/scoped_openssl_types.h"
22 #include "net/base/net_errors.h" 22 #include "net/base/net_errors.h"
23 #include "net/cert/cert_verifier.h" 23 #include "net/cert/cert_verifier.h"
24 #include "net/cert/ct_verifier.h"
24 #include "net/cert/single_request_cert_verifier.h" 25 #include "net/cert/single_request_cert_verifier.h"
25 #include "net/cert/x509_certificate_net_log_param.h" 26 #include "net/cert/x509_certificate_net_log_param.h"
26 #include "net/http/transport_security_state.h" 27 #include "net/http/transport_security_state.h"
27 #include "net/socket/ssl_session_cache_openssl.h" 28 #include "net/socket/ssl_session_cache_openssl.h"
28 #include "net/ssl/openssl_ssl_util.h" 29 #include "net/ssl/openssl_ssl_util.h"
29 #include "net/ssl/ssl_cert_request_info.h" 30 #include "net/ssl/ssl_cert_request_info.h"
30 #include "net/ssl/ssl_connection_status_flags.h" 31 #include "net/ssl/ssl_connection_status_flags.h"
31 #include "net/ssl/ssl_info.h" 32 #include "net/ssl/ssl_info.h"
32 33
33 #if defined(USE_OPENSSL_CERTS) 34 #if defined(USE_OPENSSL_CERTS)
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 : transport_send_busy_(false), 340 : transport_send_busy_(false),
340 transport_recv_busy_(false), 341 transport_recv_busy_(false),
341 pending_read_error_(kNoPendingReadResult), 342 pending_read_error_(kNoPendingReadResult),
342 transport_read_error_(OK), 343 transport_read_error_(OK),
343 transport_write_error_(OK), 344 transport_write_error_(OK),
344 server_cert_chain_(new PeerCertificateChain(NULL)), 345 server_cert_chain_(new PeerCertificateChain(NULL)),
345 completed_connect_(false), 346 completed_connect_(false),
346 was_ever_used_(false), 347 was_ever_used_(false),
347 client_auth_cert_needed_(false), 348 client_auth_cert_needed_(false),
348 cert_verifier_(context.cert_verifier), 349 cert_verifier_(context.cert_verifier),
350 cert_transparency_verifier_(context.cert_transparency_verifier),
349 channel_id_service_(context.channel_id_service), 351 channel_id_service_(context.channel_id_service),
350 ssl_(NULL), 352 ssl_(NULL),
351 transport_bio_(NULL), 353 transport_bio_(NULL),
352 transport_(transport_socket.Pass()), 354 transport_(transport_socket.Pass()),
353 host_and_port_(host_and_port), 355 host_and_port_(host_and_port),
354 ssl_config_(ssl_config), 356 ssl_config_(ssl_config),
355 ssl_session_cache_shard_(context.ssl_session_cache_shard), 357 ssl_session_cache_shard_(context.ssl_session_cache_shard),
356 trying_cached_session_(false), 358 trying_cached_session_(false),
357 next_handshake_state_(STATE_NONE), 359 next_handshake_state_(STATE_NONE),
358 npn_status_(kNextProtoUnsupported), 360 npn_status_(kNextProtoUnsupported),
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 ssl_info->cert_status = server_cert_verify_result_.cert_status; 594 ssl_info->cert_status = server_cert_verify_result_.cert_status;
593 ssl_info->is_issued_by_known_root = 595 ssl_info->is_issued_by_known_root =
594 server_cert_verify_result_.is_issued_by_known_root; 596 server_cert_verify_result_.is_issued_by_known_root;
595 ssl_info->public_key_hashes = 597 ssl_info->public_key_hashes =
596 server_cert_verify_result_.public_key_hashes; 598 server_cert_verify_result_.public_key_hashes;
597 ssl_info->client_cert_sent = 599 ssl_info->client_cert_sent =
598 ssl_config_.send_client_cert && ssl_config_.client_cert.get(); 600 ssl_config_.send_client_cert && ssl_config_.client_cert.get();
599 ssl_info->channel_id_sent = WasChannelIDSent(); 601 ssl_info->channel_id_sent = WasChannelIDSent();
600 ssl_info->pinning_failure_log = pinning_failure_log_; 602 ssl_info->pinning_failure_log = pinning_failure_log_;
601 603
604 AddSCTInfoToSSLInfo(ssl_info);
605
602 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl_); 606 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl_);
603 CHECK(cipher); 607 CHECK(cipher);
604 ssl_info->security_bits = SSL_CIPHER_get_bits(cipher, NULL); 608 ssl_info->security_bits = SSL_CIPHER_get_bits(cipher, NULL);
605 609
606 ssl_info->connection_status = EncodeSSLConnectionStatus( 610 ssl_info->connection_status = EncodeSSLConnectionStatus(
607 SSL_CIPHER_get_id(cipher), 0 /* no compression */, 611 SSL_CIPHER_get_id(cipher), 0 /* no compression */,
608 GetNetSSLVersion(ssl_)); 612 GetNetSSLVersion(ssl_));
609 613
610 if (!SSL_get_secure_renegotiation_support(ssl_)) 614 if (!SSL_get_secure_renegotiation_support(ssl_))
611 ssl_info->connection_status |= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION; 615 ssl_info->connection_status |= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION;
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 SSL_enable_tls_channel_id(ssl_); 805 SSL_enable_tls_channel_id(ssl_);
802 } 806 }
803 807
804 if (!ssl_config_.next_protos.empty()) { 808 if (!ssl_config_.next_protos.empty()) {
805 std::vector<uint8_t> wire_protos = 809 std::vector<uint8_t> wire_protos =
806 SerializeNextProtos(ssl_config_.next_protos); 810 SerializeNextProtos(ssl_config_.next_protos);
807 SSL_set_alpn_protos(ssl_, wire_protos.empty() ? NULL : &wire_protos[0], 811 SSL_set_alpn_protos(ssl_, wire_protos.empty() ? NULL : &wire_protos[0],
808 wire_protos.size()); 812 wire_protos.size());
809 } 813 }
810 814
815 if (ssl_config_.signed_cert_timestamps_enabled) {
816 SSL_enable_signed_cert_timestamps(ssl_);
817 SSL_enable_ocsp_stapling(ssl_);
818 }
819
820 // TODO(davidben): Enable OCSP stapling on platforms which support it and pass
821 // into the certificate verifier. https://crbug.com/398677
822
811 return OK; 823 return OK;
812 } 824 }
813 825
814 void SSLClientSocketOpenSSL::DoReadCallback(int rv) { 826 void SSLClientSocketOpenSSL::DoReadCallback(int rv) {
815 // Since Run may result in Read being called, clear |user_read_callback_| 827 // Since Run may result in Read being called, clear |user_read_callback_|
816 // up front. 828 // up front.
817 if (rv > 0) 829 if (rv > 0)
818 was_ever_used_ = true; 830 was_ever_used_ = true;
819 user_read_buf_ = NULL; 831 user_read_buf_ = NULL;
820 user_read_buf_len_ = 0; 832 user_read_buf_len_ = 0;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
896 npn_proto_.assign(reinterpret_cast<const char*>(alpn_proto), alpn_len); 908 npn_proto_.assign(reinterpret_cast<const char*>(alpn_proto), alpn_len);
897 npn_status_ = kNextProtoNegotiated; 909 npn_status_ = kNextProtoNegotiated;
898 } 910 }
899 } 911 }
900 912
901 RecordChannelIDSupport(channel_id_service_, 913 RecordChannelIDSupport(channel_id_service_,
902 channel_id_xtn_negotiated_, 914 channel_id_xtn_negotiated_,
903 ssl_config_.channel_id_enabled, 915 ssl_config_.channel_id_enabled,
904 crypto::ECPrivateKey::IsSupported()); 916 crypto::ECPrivateKey::IsSupported());
905 917
918 uint8_t* ocsp_response;
919 size_t ocsp_response_len;
920 SSL_get0_ocsp_response(ssl_, &ocsp_response, &ocsp_response_len);
921 set_stapled_ocsp_response_received(ocsp_response_len != 0);
922
923 uint8_t* sct_list;
924 size_t sct_list_len;
925 SSL_get0_signed_cert_timestamp_list(ssl_, &sct_list, &sct_list_len);
926 set_signed_cert_timestamps_received(sct_list_len != 0);
927
906 // Verify the certificate. 928 // Verify the certificate.
907 const bool got_cert = !!UpdateServerCert(); 929 const bool got_cert = !!UpdateServerCert();
908 DCHECK(got_cert); 930 DCHECK(got_cert);
909 net_log_.AddEvent( 931 net_log_.AddEvent(
910 NetLog::TYPE_SSL_CERTIFICATES_RECEIVED, 932 NetLog::TYPE_SSL_CERTIFICATES_RECEIVED,
911 base::Bind(&NetLogX509CertificateCallback, 933 base::Bind(&NetLogX509CertificateCallback,
912 base::Unretained(server_cert_.get()))); 934 base::Unretained(server_cert_.get())));
913 GotoState(STATE_VERIFY_CERT); 935 GotoState(STATE_VERIFY_CERT);
914 } else { 936 } else {
915 int ssl_error = SSL_get_error(ssl_, rv); 937 int ssl_error = SSL_get_error(ssl_, rv);
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 !transport_security_state_->CheckPublicKeyPins( 1074 !transport_security_state_->CheckPublicKeyPins(
1053 host_and_port_.host(), 1075 host_and_port_.host(),
1054 sni_available, 1076 sni_available,
1055 server_cert_verify_result_.is_issued_by_known_root, 1077 server_cert_verify_result_.is_issued_by_known_root,
1056 server_cert_verify_result_.public_key_hashes, 1078 server_cert_verify_result_.public_key_hashes,
1057 &pinning_failure_log_)) { 1079 &pinning_failure_log_)) {
1058 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; 1080 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
1059 } 1081 }
1060 1082
1061 if (result == OK) { 1083 if (result == OK) {
1084 // Only check Certificate Transparency if there were no other errors with
1085 // the connection.
1086 VerifyCT();
1087
1062 // TODO(joth): Work out if we need to remember the intermediate CA certs 1088 // TODO(joth): Work out if we need to remember the intermediate CA certs
1063 // when the server sends them to us, and do so here. 1089 // when the server sends them to us, and do so here.
1064 SSLContext::GetInstance()->session_cache()->MarkSSLSessionAsGood(ssl_); 1090 SSLContext::GetInstance()->session_cache()->MarkSSLSessionAsGood(ssl_);
1065 marked_session_as_good_ = true; 1091 marked_session_as_good_ = true;
1066 CheckIfHandshakeFinished(); 1092 CheckIfHandshakeFinished();
1067 } else { 1093 } else {
1068 DVLOG(1) << "DoVerifyCertComplete error " << ErrorToString(result) 1094 DVLOG(1) << "DoVerifyCertComplete error " << ErrorToString(result)
1069 << " (" << result << ")"; 1095 << " (" << result << ")";
1070 } 1096 }
1071 1097
(...skipping 17 matching lines...) Expand all
1089 X509Certificate* SSLClientSocketOpenSSL::UpdateServerCert() { 1115 X509Certificate* SSLClientSocketOpenSSL::UpdateServerCert() {
1090 server_cert_chain_->Reset(SSL_get_peer_cert_chain(ssl_)); 1116 server_cert_chain_->Reset(SSL_get_peer_cert_chain(ssl_));
1091 server_cert_ = server_cert_chain_->AsOSChain(); 1117 server_cert_ = server_cert_chain_->AsOSChain();
1092 1118
1093 if (!server_cert_chain_->IsValid()) 1119 if (!server_cert_chain_->IsValid())
1094 DVLOG(1) << "UpdateServerCert received invalid certificate chain from peer"; 1120 DVLOG(1) << "UpdateServerCert received invalid certificate chain from peer";
1095 1121
1096 return server_cert_.get(); 1122 return server_cert_.get();
1097 } 1123 }
1098 1124
1125 void SSLClientSocketOpenSSL::VerifyCT() {
1126 if (!cert_transparency_verifier_)
1127 return;
1128
1129 uint8_t* ocsp_response_raw;
1130 size_t ocsp_response_len;
1131 SSL_get0_ocsp_response(ssl_, &ocsp_response_raw, &ocsp_response_len);
1132 std::string ocsp_response;
1133 if (ocsp_response_len > 0) {
1134 ocsp_response.assign(reinterpret_cast<const char*>(ocsp_response_raw),
1135 ocsp_response_len);
1136 }
1137
1138 uint8_t* sct_list_raw;
1139 size_t sct_list_len;
1140 SSL_get0_signed_cert_timestamp_list(ssl_, &sct_list_raw, &sct_list_len);
1141 std::string sct_list;
1142 if (sct_list_len > 0)
1143 sct_list.assign(reinterpret_cast<const char*>(sct_list_raw), sct_list_len);
1144
1145 // Note that this is a completely synchronous operation: The CT Log Verifier
1146 // gets all the data it needs for SCT verification and does not do any
1147 // external communication.
1148 int result = cert_transparency_verifier_->Verify(
1149 server_cert_verify_result_.verified_cert.get(),
1150 ocsp_response, sct_list, &ct_verify_result_, net_log_);
1151
1152 VLOG(1) << "CT Verification complete: result " << result
1153 << " Invalid scts: " << ct_verify_result_.invalid_scts.size()
1154 << " Verified scts: " << ct_verify_result_.verified_scts.size()
1155 << " scts from unknown logs: "
1156 << ct_verify_result_.unknown_logs_scts.size();
1157 }
1158
1099 void SSLClientSocketOpenSSL::OnHandshakeIOComplete(int result) { 1159 void SSLClientSocketOpenSSL::OnHandshakeIOComplete(int result) {
1100 int rv = DoHandshakeLoop(result); 1160 int rv = DoHandshakeLoop(result);
1101 if (rv != ERR_IO_PENDING) { 1161 if (rv != ERR_IO_PENDING) {
1102 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv); 1162 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
1103 DoConnectCallback(rv); 1163 DoConnectCallback(rv);
1104 } 1164 }
1105 } 1165 }
1106 1166
1107 void SSLClientSocketOpenSSL::OnSendComplete(int result) { 1167 void SSLClientSocketOpenSSL::OnSendComplete(int result) {
1108 if (next_handshake_state_ == STATE_HANDSHAKE) { 1168 if (next_handshake_state_ == STATE_HANDSHAKE) {
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after
1650 // CheckIfHandshakeFinished is called twice per connection: once after 1710 // CheckIfHandshakeFinished is called twice per connection: once after
1651 // MarkSSLSessionAsGood, when the certificate has been verified, and 1711 // MarkSSLSessionAsGood, when the certificate has been verified, and
1652 // once via an OpenSSL callback when the handshake has completed. On the 1712 // once via an OpenSSL callback when the handshake has completed. On the
1653 // second call, when the certificate has been verified and the handshake 1713 // second call, when the certificate has been verified and the handshake
1654 // has completed, the connection's handshake completion callback is run. 1714 // has completed, the connection's handshake completion callback is run.
1655 void SSLClientSocketOpenSSL::CheckIfHandshakeFinished() { 1715 void SSLClientSocketOpenSSL::CheckIfHandshakeFinished() {
1656 if (handshake_succeeded_ && marked_session_as_good_) 1716 if (handshake_succeeded_ && marked_session_as_good_)
1657 OnHandshakeCompletion(); 1717 OnHandshakeCompletion();
1658 } 1718 }
1659 1719
1720 void SSLClientSocketOpenSSL::AddSCTInfoToSSLInfo(SSLInfo* ssl_info) const {
1721 for (ct::SCTList::const_iterator iter =
1722 ct_verify_result_.verified_scts.begin();
1723 iter != ct_verify_result_.verified_scts.end(); ++iter) {
1724 ssl_info->signed_certificate_timestamps.push_back(
1725 SignedCertificateTimestampAndStatus(*iter, ct::SCT_STATUS_OK));
1726 }
1727 for (ct::SCTList::const_iterator iter =
1728 ct_verify_result_.invalid_scts.begin();
1729 iter != ct_verify_result_.invalid_scts.end(); ++iter) {
1730 ssl_info->signed_certificate_timestamps.push_back(
1731 SignedCertificateTimestampAndStatus(*iter, ct::SCT_STATUS_INVALID));
1732 }
1733 for (ct::SCTList::const_iterator iter =
1734 ct_verify_result_.unknown_logs_scts.begin();
1735 iter != ct_verify_result_.unknown_logs_scts.end(); ++iter) {
1736 ssl_info->signed_certificate_timestamps.push_back(
1737 SignedCertificateTimestampAndStatus(*iter,
1738 ct::SCT_STATUS_LOG_UNKNOWN));
1739 }
1740 }
1741
1660 scoped_refptr<X509Certificate> 1742 scoped_refptr<X509Certificate>
1661 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { 1743 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const {
1662 return server_cert_; 1744 return server_cert_;
1663 } 1745 }
1664 1746
1665 } // namespace net 1747 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/ssl_client_socket_openssl.h ('k') | net/socket/ssl_client_socket_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698