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

Side by Side Diff: net/cert/multi_log_ct_verifier.cc

Issue 2400183002: Cleanup: More accurate output parameter type for CTVerifier (Closed)
Patch Set: IWYU, review comments Created 4 years, 2 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/cert/multi_log_ct_verifier.h ('k') | net/cert/multi_log_ct_verifier_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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/cert/multi_log_ct_verifier.h" 5 #include "net/cert/multi_log_ct_verifier.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
11 #include "base/metrics/histogram_macros.h" 11 #include "base/metrics/histogram_macros.h"
12 #include "base/values.h" 12 #include "base/values.h"
13 #include "net/base/net_errors.h" 13 #include "net/base/net_errors.h"
14 #include "net/cert/ct_log_verifier.h" 14 #include "net/cert/ct_log_verifier.h"
15 #include "net/cert/ct_objects_extractor.h" 15 #include "net/cert/ct_objects_extractor.h"
16 #include "net/cert/ct_serialization.h" 16 #include "net/cert/ct_serialization.h"
17 #include "net/cert/ct_signed_certificate_timestamp_log_param.h" 17 #include "net/cert/ct_signed_certificate_timestamp_log_param.h"
18 #include "net/cert/ct_verify_result.h"
19 #include "net/cert/sct_status_flags.h" 18 #include "net/cert/sct_status_flags.h"
19 #include "net/cert/signed_certificate_timestamp_and_status.h"
20 #include "net/cert/x509_certificate.h" 20 #include "net/cert/x509_certificate.h"
21 #include "net/log/net_log_event_type.h" 21 #include "net/log/net_log_event_type.h"
22 #include "net/log/net_log_parameters_callback.h" 22 #include "net/log/net_log_parameters_callback.h"
23 #include "net/log/net_log_with_source.h" 23 #include "net/log/net_log_with_source.h"
24 24
25 namespace net { 25 namespace net {
26 26
27 namespace { 27 namespace {
28 28
29 // Record SCT verification status. This metric would help detecting presence 29 // Record SCT verification status. This metric would help detecting presence
(...skipping 13 matching lines...) Expand all
43 UMA_HISTOGRAM_ENUMERATION("Net.CertificateTransparency.SCTOrigin", 43 UMA_HISTOGRAM_ENUMERATION("Net.CertificateTransparency.SCTOrigin",
44 origin, 44 origin,
45 ct::SignedCertificateTimestamp::SCT_ORIGIN_MAX); 45 ct::SignedCertificateTimestamp::SCT_ORIGIN_MAX);
46 } 46 }
47 47
48 // Count the number of SCTs that were available for each SSL connection 48 // Count the number of SCTs that were available for each SSL connection
49 // (including SCTs embedded in the certificate). 49 // (including SCTs embedded in the certificate).
50 // This metric would allow measuring: 50 // This metric would allow measuring:
51 // * Of all SSL connections, how many had SCTs available for validation. 51 // * Of all SSL connections, how many had SCTs available for validation.
52 // * When SCTs are available, how many are available per connection. 52 // * When SCTs are available, how many are available per connection.
53 void LogNumSCTsToUMA(const ct::CTVerifyResult& result) { 53 void LogNumSCTsToUMA(const SignedCertificateTimestampAndStatusList& scts) {
54 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.CertificateTransparency.SCTsPerConnection", 54 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.CertificateTransparency.SCTsPerConnection",
55 result.scts.size(), 1, 10, 11); 55 scts.size(), 1, 10, 11);
56 } 56 }
57 57
58 void AddSCTAndLogStatus(scoped_refptr<ct::SignedCertificateTimestamp> sct, 58 void AddSCTAndLogStatus(scoped_refptr<ct::SignedCertificateTimestamp> sct,
59 ct::SCTVerifyStatus status, 59 ct::SCTVerifyStatus status,
60 SignedCertificateTimestampAndStatusList* sct_list) { 60 SignedCertificateTimestampAndStatusList* sct_list) {
61 LogSCTStatusToUMA(status); 61 LogSCTStatusToUMA(status);
62 sct_list->push_back(SignedCertificateTimestampAndStatus(sct, status)); 62 sct_list->push_back(SignedCertificateTimestampAndStatus(sct, status));
63 } 63 }
64 64
65 } // namespace 65 } // namespace
66 66
67 MultiLogCTVerifier::MultiLogCTVerifier() : observer_(nullptr) { 67 MultiLogCTVerifier::MultiLogCTVerifier() : observer_(nullptr) {
68 } 68 }
69 69
70 MultiLogCTVerifier::~MultiLogCTVerifier() { } 70 MultiLogCTVerifier::~MultiLogCTVerifier() { }
71 71
72 void MultiLogCTVerifier::AddLogs( 72 void MultiLogCTVerifier::AddLogs(
73 const std::vector<scoped_refptr<const CTLogVerifier>>& log_verifiers) { 73 const std::vector<scoped_refptr<const CTLogVerifier>>& log_verifiers) {
74 for (const auto& log_verifier : log_verifiers) { 74 for (const auto& log_verifier : log_verifiers) {
75 VLOG(1) << "Adding CT log: " << log_verifier->description(); 75 VLOG(1) << "Adding CT log: " << log_verifier->description();
76 logs_[log_verifier->key_id()] = log_verifier; 76 logs_[log_verifier->key_id()] = log_verifier;
77 } 77 }
78 } 78 }
79 79
80 void MultiLogCTVerifier::SetObserver(Observer* observer) { 80 void MultiLogCTVerifier::SetObserver(Observer* observer) {
81 observer_ = observer; 81 observer_ = observer;
82 } 82 }
83 83
84 int MultiLogCTVerifier::Verify(X509Certificate* cert, 84 int MultiLogCTVerifier::Verify(
85 const std::string& stapled_ocsp_response, 85 X509Certificate* cert,
86 const std::string& sct_list_from_tls_extension, 86 const std::string& stapled_ocsp_response,
87 ct::CTVerifyResult* result, 87 const std::string& sct_list_from_tls_extension,
88 const NetLogWithSource& net_log) { 88 SignedCertificateTimestampAndStatusList* output_scts,
89 const NetLogWithSource& net_log) {
89 DCHECK(cert); 90 DCHECK(cert);
90 DCHECK(result); 91 DCHECK(output_scts);
91 92
92 result->scts.clear(); 93 output_scts->clear();
93 94
94 bool has_verified_scts = false; 95 bool has_verified_scts = false;
95 96
96 std::string embedded_scts; 97 std::string embedded_scts;
97 if (!cert->GetIntermediateCertificates().empty() && 98 if (!cert->GetIntermediateCertificates().empty() &&
98 ct::ExtractEmbeddedSCTList( 99 ct::ExtractEmbeddedSCTList(
99 cert->os_cert_handle(), 100 cert->os_cert_handle(),
100 &embedded_scts)) { 101 &embedded_scts)) {
101 ct::LogEntry precert_entry; 102 ct::LogEntry precert_entry;
102 103
103 has_verified_scts = 104 has_verified_scts =
104 ct::GetPrecertLogEntry(cert->os_cert_handle(), 105 ct::GetPrecertLogEntry(cert->os_cert_handle(),
105 cert->GetIntermediateCertificates().front(), 106 cert->GetIntermediateCertificates().front(),
106 &precert_entry) && 107 &precert_entry) &&
107 VerifySCTs(embedded_scts, precert_entry, 108 VerifySCTs(embedded_scts, precert_entry,
108 ct::SignedCertificateTimestamp::SCT_EMBEDDED, cert, result); 109 ct::SignedCertificateTimestamp::SCT_EMBEDDED, cert,
110 output_scts);
109 } 111 }
110 112
111 std::string sct_list_from_ocsp; 113 std::string sct_list_from_ocsp;
112 if (!stapled_ocsp_response.empty() && 114 if (!stapled_ocsp_response.empty() &&
113 !cert->GetIntermediateCertificates().empty()) { 115 !cert->GetIntermediateCertificates().empty()) {
114 ct::ExtractSCTListFromOCSPResponse( 116 ct::ExtractSCTListFromOCSPResponse(
115 cert->GetIntermediateCertificates().front(), cert->serial_number(), 117 cert->GetIntermediateCertificates().front(), cert->serial_number(),
116 stapled_ocsp_response, &sct_list_from_ocsp); 118 stapled_ocsp_response, &sct_list_from_ocsp);
117 } 119 }
118 120
119 // Log to Net Log, after extracting SCTs but before possibly failing on 121 // Log to Net Log, after extracting SCTs but before possibly failing on
120 // X.509 entry creation. 122 // X.509 entry creation.
121 NetLogParametersCallback net_log_callback = 123 NetLogParametersCallback net_log_callback =
122 base::Bind(&NetLogRawSignedCertificateTimestampCallback, &embedded_scts, 124 base::Bind(&NetLogRawSignedCertificateTimestampCallback, &embedded_scts,
123 &sct_list_from_ocsp, &sct_list_from_tls_extension); 125 &sct_list_from_ocsp, &sct_list_from_tls_extension);
124 126
125 net_log.AddEvent(NetLogEventType::SIGNED_CERTIFICATE_TIMESTAMPS_RECEIVED, 127 net_log.AddEvent(NetLogEventType::SIGNED_CERTIFICATE_TIMESTAMPS_RECEIVED,
126 net_log_callback); 128 net_log_callback);
127 129
128 ct::LogEntry x509_entry; 130 ct::LogEntry x509_entry;
129 if (ct::GetX509LogEntry(cert->os_cert_handle(), &x509_entry)) { 131 if (ct::GetX509LogEntry(cert->os_cert_handle(), &x509_entry)) {
130 has_verified_scts |= VerifySCTs( 132 has_verified_scts |=
131 sct_list_from_ocsp, x509_entry, 133 VerifySCTs(sct_list_from_ocsp, x509_entry,
132 ct::SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE, cert, result); 134 ct::SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE, cert,
135 output_scts);
133 136
134 has_verified_scts |= VerifySCTs( 137 has_verified_scts |=
135 sct_list_from_tls_extension, x509_entry, 138 VerifySCTs(sct_list_from_tls_extension, x509_entry,
136 ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, cert, result); 139 ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, cert,
140 output_scts);
137 } 141 }
138 142
139 NetLogParametersCallback net_log_checked_callback = 143 NetLogParametersCallback net_log_checked_callback =
140 base::Bind(&NetLogSignedCertificateTimestampCallback, result); 144 base::Bind(&NetLogSignedCertificateTimestampCallback, output_scts);
141 145
142 net_log.AddEvent(NetLogEventType::SIGNED_CERTIFICATE_TIMESTAMPS_CHECKED, 146 net_log.AddEvent(NetLogEventType::SIGNED_CERTIFICATE_TIMESTAMPS_CHECKED,
143 net_log_checked_callback); 147 net_log_checked_callback);
144 148
145 LogNumSCTsToUMA(*result); 149 LogNumSCTsToUMA(*output_scts);
146 150
147 if (has_verified_scts) 151 if (has_verified_scts)
148 return OK; 152 return OK;
149 153
150 return ERR_CT_NO_SCTS_VERIFIED_OK; 154 return ERR_CT_NO_SCTS_VERIFIED_OK;
151 } 155 }
152 156
153 bool MultiLogCTVerifier::VerifySCTs( 157 bool MultiLogCTVerifier::VerifySCTs(
154 const std::string& encoded_sct_list, 158 const std::string& encoded_sct_list,
155 const ct::LogEntry& expected_entry, 159 const ct::LogEntry& expected_entry,
156 ct::SignedCertificateTimestamp::Origin origin, 160 ct::SignedCertificateTimestamp::Origin origin,
157 X509Certificate* cert, 161 X509Certificate* cert,
158 ct::CTVerifyResult* result) { 162 SignedCertificateTimestampAndStatusList* output_scts) {
159 if (logs_.empty()) 163 if (logs_.empty())
160 return false; 164 return false;
161 165
162 base::StringPiece temp(encoded_sct_list); 166 base::StringPiece temp(encoded_sct_list);
163 std::vector<base::StringPiece> sct_list; 167 std::vector<base::StringPiece> sct_list;
164 168
165 if (!ct::DecodeSCTList(&temp, &sct_list)) 169 if (!ct::DecodeSCTList(&temp, &sct_list))
166 return false; 170 return false;
167 171
168 bool verified = false; 172 bool verified = false;
169 for (std::vector<base::StringPiece>::const_iterator it = sct_list.begin(); 173 for (std::vector<base::StringPiece>::const_iterator it = sct_list.begin();
170 it != sct_list.end(); ++it) { 174 it != sct_list.end(); ++it) {
171 base::StringPiece encoded_sct(*it); 175 base::StringPiece encoded_sct(*it);
172 LogSCTOriginToUMA(origin); 176 LogSCTOriginToUMA(origin);
173 177
174 scoped_refptr<ct::SignedCertificateTimestamp> decoded_sct; 178 scoped_refptr<ct::SignedCertificateTimestamp> decoded_sct;
175 if (!DecodeSignedCertificateTimestamp(&encoded_sct, &decoded_sct)) { 179 if (!DecodeSignedCertificateTimestamp(&encoded_sct, &decoded_sct)) {
176 LogSCTStatusToUMA(ct::SCT_STATUS_NONE); 180 LogSCTStatusToUMA(ct::SCT_STATUS_NONE);
177 // XXX(rsleevi): Should we really just skip over bad SCTs? 181 // XXX(rsleevi): Should we really just skip over bad SCTs?
178 continue; 182 continue;
179 } 183 }
180 decoded_sct->origin = origin; 184 decoded_sct->origin = origin;
181 185
182 verified |= VerifySingleSCT(decoded_sct, expected_entry, cert, result); 186 verified |= VerifySingleSCT(decoded_sct, expected_entry, cert, output_scts);
183 } 187 }
184 188
185 return verified; 189 return verified;
186 } 190 }
187 191
188 bool MultiLogCTVerifier::VerifySingleSCT( 192 bool MultiLogCTVerifier::VerifySingleSCT(
189 scoped_refptr<ct::SignedCertificateTimestamp> sct, 193 scoped_refptr<ct::SignedCertificateTimestamp> sct,
190 const ct::LogEntry& expected_entry, 194 const ct::LogEntry& expected_entry,
191 X509Certificate* cert, 195 X509Certificate* cert,
192 ct::CTVerifyResult* result) { 196 SignedCertificateTimestampAndStatusList* output_scts) {
193 // Assume this SCT is untrusted until proven otherwise. 197 // Assume this SCT is untrusted until proven otherwise.
194 const auto& it = logs_.find(sct->log_id); 198 const auto& it = logs_.find(sct->log_id);
195 if (it == logs_.end()) { 199 if (it == logs_.end()) {
196 DVLOG(1) << "SCT does not match any known log."; 200 DVLOG(1) << "SCT does not match any known log.";
197 AddSCTAndLogStatus(sct, ct::SCT_STATUS_LOG_UNKNOWN, &(result->scts)); 201 AddSCTAndLogStatus(sct, ct::SCT_STATUS_LOG_UNKNOWN, output_scts);
198 return false; 202 return false;
199 } 203 }
200 204
201 sct->log_description = it->second->description(); 205 sct->log_description = it->second->description();
202 206
203 if (!it->second->Verify(expected_entry, *sct.get())) { 207 if (!it->second->Verify(expected_entry, *sct.get())) {
204 DVLOG(1) << "Unable to verify SCT signature."; 208 DVLOG(1) << "Unable to verify SCT signature.";
205 AddSCTAndLogStatus(sct, ct::SCT_STATUS_INVALID_SIGNATURE, &(result->scts)); 209 AddSCTAndLogStatus(sct, ct::SCT_STATUS_INVALID_SIGNATURE, output_scts);
206 return false; 210 return false;
207 } 211 }
208 212
209 // SCT verified ok, just make sure the timestamp is legitimate. 213 // SCT verified ok, just make sure the timestamp is legitimate.
210 if (sct->timestamp > base::Time::Now()) { 214 if (sct->timestamp > base::Time::Now()) {
211 DVLOG(1) << "SCT is from the future!"; 215 DVLOG(1) << "SCT is from the future!";
212 AddSCTAndLogStatus(sct, ct::SCT_STATUS_INVALID_TIMESTAMP, &(result->scts)); 216 AddSCTAndLogStatus(sct, ct::SCT_STATUS_INVALID_TIMESTAMP, output_scts);
213 return false; 217 return false;
214 } 218 }
215 219
216 AddSCTAndLogStatus(sct, ct::SCT_STATUS_OK, &(result->scts)); 220 AddSCTAndLogStatus(sct, ct::SCT_STATUS_OK, output_scts);
217 if (observer_) 221 if (observer_)
218 observer_->OnSCTVerified(cert, sct.get()); 222 observer_->OnSCTVerified(cert, sct.get());
219 return true; 223 return true;
220 } 224 }
221 225
222 } // namespace net 226 } // namespace net
OLDNEW
« no previous file with comments | « net/cert/multi_log_ct_verifier.h ('k') | net/cert/multi_log_ct_verifier_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698