| OLD | NEW |
| 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 <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
| 10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 der_test_cert.length()); | 63 der_test_cert.length()); |
| 64 ASSERT_TRUE(chain_.get()); | 64 ASSERT_TRUE(chain_.get()); |
| 65 | 65 |
| 66 embedded_sct_chain_ = | 66 embedded_sct_chain_ = |
| 67 CreateCertificateChainFromFile(GetTestCertsDirectory(), | 67 CreateCertificateChainFromFile(GetTestCertsDirectory(), |
| 68 "ct-test-embedded-cert.pem", | 68 "ct-test-embedded-cert.pem", |
| 69 X509Certificate::FORMAT_AUTO); | 69 X509Certificate::FORMAT_AUTO); |
| 70 ASSERT_TRUE(embedded_sct_chain_.get()); | 70 ASSERT_TRUE(embedded_sct_chain_.get()); |
| 71 } | 71 } |
| 72 | 72 |
| 73 bool CheckForSingleVerifiedSCTInResult(const ct::CTVerifyResult& result) { | |
| 74 return (result.verified_scts.size() == 1U) && | |
| 75 result.invalid_scts.empty() && | |
| 76 result.unknown_logs_scts.empty() && | |
| 77 result.verified_scts[0]->log_description == kLogDescription; | |
| 78 } | |
| 79 | |
| 80 bool CheckForSCTOrigin( | |
| 81 const ct::CTVerifyResult& result, | |
| 82 ct::SignedCertificateTimestamp::Origin origin) { | |
| 83 return (result.verified_scts.size() > 0) && | |
| 84 (result.verified_scts[0]->origin == origin); | |
| 85 } | |
| 86 | |
| 87 bool CheckForEmbeddedSCTInNetLog(TestNetLog& net_log) { | 73 bool CheckForEmbeddedSCTInNetLog(TestNetLog& net_log) { |
| 88 TestNetLogEntry::List entries; | 74 TestNetLogEntry::List entries; |
| 89 net_log.GetEntries(&entries); | 75 net_log.GetEntries(&entries); |
| 90 if (entries.size() != 2) | 76 if (entries.size() != 2) |
| 91 return false; | 77 return false; |
| 92 | 78 |
| 93 const TestNetLogEntry& received = entries[0]; | 79 const TestNetLogEntry& received = entries[0]; |
| 94 std::string embedded_scts; | 80 std::string embedded_scts; |
| 95 if (!received.GetStringValue("embedded_scts", &embedded_scts)) | 81 if (!received.GetStringValue("embedded_scts", &embedded_scts)) |
| 96 return false; | 82 return false; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 121 } | 107 } |
| 122 | 108 |
| 123 if (!parsed.GetListValue("unknown_logs_scts", &other_scts) || | 109 if (!parsed.GetListValue("unknown_logs_scts", &other_scts) || |
| 124 !other_scts->empty()) { | 110 !other_scts->empty()) { |
| 125 return false; | 111 return false; |
| 126 } | 112 } |
| 127 | 113 |
| 128 return true; | 114 return true; |
| 129 } | 115 } |
| 130 | 116 |
| 131 std::string GetSCTListWithInvalidSCT() { | |
| 132 std::string sct(ct::GetTestSignedCertificateTimestamp()); | |
| 133 | |
| 134 // Change a byte inside the Log ID part of the SCT so it does | |
| 135 // not match the log used in the tests | |
| 136 sct[15] = 't'; | |
| 137 | |
| 138 std::string sct_list; | |
| 139 ct::EncodeSCTListForTesting(sct, &sct_list); | |
| 140 return sct_list; | |
| 141 } | |
| 142 | |
| 143 bool VerifySinglePrecertificateChain(scoped_refptr<X509Certificate> chain, | 117 bool VerifySinglePrecertificateChain(scoped_refptr<X509Certificate> chain, |
| 144 const BoundNetLog& bound_net_log, | 118 const BoundNetLog& bound_net_log, |
| 145 ct::CTVerifyResult* result) { | 119 ct::CTVerifyResult* result) { |
| 146 return verifier_->Verify(chain.get(), | 120 return verifier_->Verify(chain.get(), |
| 147 std::string(), | 121 std::string(), |
| 148 std::string(), | 122 std::string(), |
| 149 result, | 123 result, |
| 150 bound_net_log) == OK; | 124 bound_net_log) == OK; |
| 151 } | 125 } |
| 152 | 126 |
| 153 bool VerifySinglePrecertificateChain(scoped_refptr<X509Certificate> chain) { | 127 bool VerifySinglePrecertificateChain(scoped_refptr<X509Certificate> chain) { |
| 154 ct::CTVerifyResult result; | 128 ct::CTVerifyResult result; |
| 155 TestNetLog net_log; | 129 TestNetLog net_log; |
| 156 BoundNetLog bound_net_log = | 130 BoundNetLog bound_net_log = |
| 157 BoundNetLog::Make(&net_log, NetLog::SOURCE_CONNECT_JOB); | 131 BoundNetLog::Make(&net_log, NetLog::SOURCE_CONNECT_JOB); |
| 158 | 132 |
| 159 return verifier_->Verify(chain.get(), | 133 return verifier_->Verify(chain.get(), |
| 160 std::string(), | 134 std::string(), |
| 161 std::string(), | 135 std::string(), |
| 162 &result, | 136 &result, |
| 163 bound_net_log) == OK; | 137 bound_net_log) == OK; |
| 164 } | 138 } |
| 165 | 139 |
| 166 bool CheckPrecertificateVerification(scoped_refptr<X509Certificate> chain) { | 140 bool CheckPrecertificateVerification(scoped_refptr<X509Certificate> chain) { |
| 167 ct::CTVerifyResult result; | 141 ct::CTVerifyResult result; |
| 168 TestNetLog net_log; | 142 TestNetLog net_log; |
| 169 BoundNetLog bound_net_log = | 143 BoundNetLog bound_net_log = |
| 170 BoundNetLog::Make(&net_log, NetLog::SOURCE_CONNECT_JOB); | 144 BoundNetLog::Make(&net_log, NetLog::SOURCE_CONNECT_JOB); |
| 171 return (VerifySinglePrecertificateChain(chain, bound_net_log, &result) && | 145 return (VerifySinglePrecertificateChain(chain, bound_net_log, &result) && |
| 172 CheckForSingleVerifiedSCTInResult(result) && | 146 ct::CheckForSingleVerifiedSCTInResult(result, kLogDescription) && |
| 173 CheckForSCTOrigin(result, | 147 ct::CheckForSCTOrigin( |
| 174 ct::SignedCertificateTimestamp::SCT_EMBEDDED) && | 148 result, ct::SignedCertificateTimestamp::SCT_EMBEDDED) && |
| 175 CheckForEmbeddedSCTInNetLog(net_log)); | 149 CheckForEmbeddedSCTInNetLog(net_log)); |
| 176 } | 150 } |
| 177 | 151 |
| 178 // Histogram-related helper methods | 152 // Histogram-related helper methods |
| 179 int GetValueFromHistogram(const std::string& histogram_name, | 153 int GetValueFromHistogram(const std::string& histogram_name, |
| 180 int sample_index) { | 154 int sample_index) { |
| 181 base::Histogram* histogram = static_cast<base::Histogram*>( | 155 base::Histogram* histogram = static_cast<base::Histogram*>( |
| 182 base::StatisticsRecorder::FindHistogram(histogram_name)); | 156 base::StatisticsRecorder::FindHistogram(histogram_name)); |
| 183 | 157 |
| 184 if (histogram == NULL) | 158 if (histogram == NULL) |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 TEST_F(MultiLogCTVerifierTest, | 208 TEST_F(MultiLogCTVerifierTest, |
| 235 VerifiesEmbeddedSCTWithIntermediateAndPreCA) { | 209 VerifiesEmbeddedSCTWithIntermediateAndPreCA) { |
| 236 scoped_refptr<X509Certificate> chain(CreateCertificateChainFromFile( | 210 scoped_refptr<X509Certificate> chain(CreateCertificateChainFromFile( |
| 237 GetTestCertsDirectory(), | 211 GetTestCertsDirectory(), |
| 238 "ct-test-embedded-with-intermediate-preca-chain.pem", | 212 "ct-test-embedded-with-intermediate-preca-chain.pem", |
| 239 X509Certificate::FORMAT_AUTO)); | 213 X509Certificate::FORMAT_AUTO)); |
| 240 ASSERT_TRUE(chain.get()); | 214 ASSERT_TRUE(chain.get()); |
| 241 ASSERT_TRUE(CheckPrecertificateVerification(chain)); | 215 ASSERT_TRUE(CheckPrecertificateVerification(chain)); |
| 242 } | 216 } |
| 243 | 217 |
| 244 TEST_F(MultiLogCTVerifierTest, | 218 TEST_F(MultiLogCTVerifierTest, VerifiesSCTOverX509Cert) { |
| 245 VerifiesSCTOverX509Cert) { | 219 std::string sct_list = ct::GetSCTListForTesting(); |
| 246 std::string sct(ct::GetTestSignedCertificateTimestamp()); | |
| 247 | |
| 248 std::string sct_list; | |
| 249 ASSERT_TRUE(ct::EncodeSCTListForTesting(sct, &sct_list)); | |
| 250 | 220 |
| 251 ct::CTVerifyResult result; | 221 ct::CTVerifyResult result; |
| 252 EXPECT_EQ(OK, | 222 EXPECT_EQ(OK, |
| 253 verifier_->Verify( | 223 verifier_->Verify( |
| 254 chain_.get(), std::string(), sct_list, &result, BoundNetLog())); | 224 chain_.get(), std::string(), sct_list, &result, BoundNetLog())); |
| 255 ASSERT_TRUE(CheckForSingleVerifiedSCTInResult(result)); | 225 ASSERT_TRUE(ct::CheckForSingleVerifiedSCTInResult(result, kLogDescription)); |
| 256 ASSERT_TRUE(CheckForSCTOrigin( | 226 ASSERT_TRUE(ct::CheckForSCTOrigin( |
| 257 result, ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION)); | 227 result, ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION)); |
| 258 } | 228 } |
| 259 | 229 |
| 260 TEST_F(MultiLogCTVerifierTest, | 230 TEST_F(MultiLogCTVerifierTest, IdentifiesSCTFromUnknownLog) { |
| 261 IdentifiesSCTFromUnknownLog) { | 231 std::string sct_list = ct::GetSCTListWithInvalidSCT(); |
| 262 std::string sct_list = GetSCTListWithInvalidSCT(); | |
| 263 ct::CTVerifyResult result; | 232 ct::CTVerifyResult result; |
| 264 | 233 |
| 265 EXPECT_NE(OK, | 234 EXPECT_NE(OK, |
| 266 verifier_->Verify( | 235 verifier_->Verify( |
| 267 chain_.get(), std::string(), sct_list, &result, BoundNetLog())); | 236 chain_.get(), std::string(), sct_list, &result, BoundNetLog())); |
| 268 EXPECT_EQ(1U, result.unknown_logs_scts.size()); | 237 EXPECT_EQ(1U, result.unknown_logs_scts.size()); |
| 269 EXPECT_EQ("", result.unknown_logs_scts[0]->log_description); | 238 EXPECT_EQ("", result.unknown_logs_scts[0]->log_description); |
| 270 } | 239 } |
| 271 | 240 |
| 272 TEST_F(MultiLogCTVerifierTest, CountsValidSCTsInStatusHistogram) { | 241 TEST_F(MultiLogCTVerifierTest, CountsValidSCTsInStatusHistogram) { |
| 273 int num_valid_scts = NumValidSCTsInStatusHistogram(); | 242 int num_valid_scts = NumValidSCTsInStatusHistogram(); |
| 274 | 243 |
| 275 ASSERT_TRUE(VerifySinglePrecertificateChain(embedded_sct_chain_)); | 244 ASSERT_TRUE(VerifySinglePrecertificateChain(embedded_sct_chain_)); |
| 276 | 245 |
| 277 EXPECT_EQ(num_valid_scts + 1, NumValidSCTsInStatusHistogram()); | 246 EXPECT_EQ(num_valid_scts + 1, NumValidSCTsInStatusHistogram()); |
| 278 } | 247 } |
| 279 | 248 |
| 280 TEST_F(MultiLogCTVerifierTest, CountsInvalidSCTsInStatusHistogram) { | 249 TEST_F(MultiLogCTVerifierTest, CountsInvalidSCTsInStatusHistogram) { |
| 281 std::string sct_list = GetSCTListWithInvalidSCT(); | 250 std::string sct_list = ct::GetSCTListWithInvalidSCT(); |
| 282 ct::CTVerifyResult result; | 251 ct::CTVerifyResult result; |
| 283 int num_valid_scts = NumValidSCTsInStatusHistogram(); | 252 int num_valid_scts = NumValidSCTsInStatusHistogram(); |
| 284 int num_invalid_scts = GetValueFromHistogram( | 253 int num_invalid_scts = GetValueFromHistogram( |
| 285 "Net.CertificateTransparency.SCTStatus", ct::SCT_STATUS_LOG_UNKNOWN); | 254 "Net.CertificateTransparency.SCTStatus", ct::SCT_STATUS_LOG_UNKNOWN); |
| 286 | 255 |
| 287 EXPECT_NE(OK, | 256 EXPECT_NE(OK, |
| 288 verifier_->Verify( | 257 verifier_->Verify( |
| 289 chain_.get(), std::string(), sct_list, &result, BoundNetLog())); | 258 chain_.get(), std::string(), sct_list, &result, BoundNetLog())); |
| 290 | 259 |
| 291 ASSERT_EQ(num_valid_scts, NumValidSCTsInStatusHistogram()); | 260 ASSERT_EQ(num_valid_scts, NumValidSCTsInStatusHistogram()); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 Mock::VerifyAndClearExpectations(&observer); | 299 Mock::VerifyAndClearExpectations(&observer); |
| 331 | 300 |
| 332 EXPECT_CALL(observer, OnSCTVerified(embedded_sct_chain_.get(), _)).Times(0); | 301 EXPECT_CALL(observer, OnSCTVerified(embedded_sct_chain_.get(), _)).Times(0); |
| 333 verifier_->SetObserver(nullptr); | 302 verifier_->SetObserver(nullptr); |
| 334 ASSERT_TRUE(VerifySinglePrecertificateChain(embedded_sct_chain_)); | 303 ASSERT_TRUE(VerifySinglePrecertificateChain(embedded_sct_chain_)); |
| 335 } | 304 } |
| 336 | 305 |
| 337 } // namespace | 306 } // namespace |
| 338 | 307 |
| 339 } // namespace net | 308 } // namespace net |
| OLD | NEW |