1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/cert/cert_verify_proc.h"
6
7 #include <memory>
8 #include <string_view>
9 #include <vector>
10
11 #include "base/files/file_path.h"
12 #include "base/files/file_util.h"
13 #include "base/functional/bind.h"
14 #include "base/functional/callback_helpers.h"
15 #include "base/logging.h"
16 #include "base/memory/raw_ptr.h"
17 #include "base/message_loop/message_pump_type.h"
18 #include "base/rand_util.h"
19 #include "base/ranges/algorithm.h"
20 #include "base/strings/string_number_conversions.h"
21 #include "base/strings/string_util.h"
22 #include "base/test/metrics/histogram_tester.h"
23 #include "base/test/scoped_feature_list.h"
24 #include "base/test/task_environment.h"
25 #include "base/threading/thread.h"
26 #include "base/time/time.h"
27 #include "build/build_config.h"
28 #include "crypto/sha2.h"
29 #include "net/base/net_errors.h"
30 #include "net/cert/asn1_util.h"
31 #include "net/cert/cert_net_fetcher.h"
32 #include "net/cert/cert_status_flags.h"
33 #include "net/cert/cert_verifier.h"
34 #include "net/cert/cert_verify_proc_builtin.h"
35 #include "net/cert/cert_verify_result.h"
36 #include "net/cert/crl_set.h"
37 #include "net/cert/ct_policy_enforcer.h"
38 #include "net/cert/do_nothing_ct_verifier.h"
39 #include "net/cert/ev_root_ca_metadata.h"
40 #include "net/cert/internal/system_trust_store.h"
41 #include "net/cert/test_root_certs.h"
42 #include "net/cert/x509_certificate.h"
43 #include "net/cert/x509_util.h"
44 #include "net/cert_net/cert_net_fetcher_url_request.h"
45 #include "net/log/test_net_log.h"
46 #include "net/proxy_resolution/proxy_config.h"
47 #include "net/proxy_resolution/proxy_config_service_fixed.h"
48 #include "net/test/cert_builder.h"
49 #include "net/test/cert_test_util.h"
50 #include "net/test/embedded_test_server/embedded_test_server.h"
51 #include "net/test/embedded_test_server/http_request.h"
52 #include "net/test/embedded_test_server/http_response.h"
53 #include "net/test/gtest_util.h"
54 #include "net/test/revocation_builder.h"
55 #include "net/test/test_certificate_data.h"
56 #include "net/test/test_data_directory.h"
57 #include "net/url_request/url_request_context.h"
58 #include "net/url_request/url_request_context_builder.h"
59 #include "net/url_request/url_request_context_getter.h"
60 #include "testing/gmock/include/gmock/gmock.h"
61 #include "testing/gtest/include/gtest/gtest.h"
62 #include "third_party/boringssl/src/include/openssl/bytestring.h"
63 #include "third_party/boringssl/src/include/openssl/mem.h"
64 #include "third_party/boringssl/src/include/openssl/pool.h"
65 #include "third_party/boringssl/src/pki/extended_key_usage.h"
66 #include "third_party/boringssl/src/pki/input.h"
67 #include "third_party/boringssl/src/pki/ocsp_revocation_status.h"
68 #include "third_party/boringssl/src/pki/parse_certificate.h"
69 #include "third_party/boringssl/src/pki/parser.h"
70 #include "third_party/boringssl/src/pki/pem.h"
71 #include "third_party/boringssl/src/pki/signature_algorithm.h"
72 #include "third_party/boringssl/src/pki/trust_store.h"
73
74 #if BUILDFLAG(IS_ANDROID)
75 #include "net/cert/cert_verify_proc_android.h"
76 #elif BUILDFLAG(IS_IOS)
77 #include "base/ios/ios_util.h"
78 #include "net/cert/cert_verify_proc_ios.h"
79 #elif BUILDFLAG(IS_MAC)
80 #include "base/mac/mac_util.h"
81 #endif
82
83 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
84 #include "net/cert/internal/trust_store_chrome.h"
85 #endif
86
87 // TODO(crbug.com/649017): Add tests that only certificates with
88 // serverAuth are accepted.
89
90 using net::test::IsError;
91 using net::test::IsOk;
92
93 using base::HexEncode;
94
95 namespace net {
96
97 namespace {
98
99 const char kTrustAnchorVerifyHistogram[] = "Net.Certificate.TrustAnchor.Verify";
100 const char kTrustAnchorVerifyOutOfDateHistogram[] =
101 "Net.Certificate.TrustAnchor.VerifyOutOfDate";
102
103 // Returns a TLV to use as an unknown signature algorithm when building a cert.
104 // The specific contents are as follows (the OID is from
105 // https://davidben.net/oid):
106 //
107 // SEQUENCE {
108 // OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.0 }
109 // NULL {}
110 // }
TestOid0SignatureAlgorithmTLV()111 std::string TestOid0SignatureAlgorithmTLV() {
112 constexpr uint8_t kTestOid0SigAlgTLV[] = {0x30, 0x10, 0x06, 0x0c, 0x2a, 0x86,
113 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01,
114 0x84, 0xb7, 0x09, 0x00, 0x05, 0x00};
115 return std::string(std::begin(kTestOid0SigAlgTLV),
116 std::end(kTestOid0SigAlgTLV));
117 }
118
119 // An OID for use in tests, from https://davidben.net/oid
120 // OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.0 }
TestOid0()121 bssl::der::Input TestOid0() {
122 static uint8_t kTestOid0[] = {0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7,
123 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x00};
124 return bssl::der::Input(kTestOid0);
125 }
126
127 // Mock CertVerifyProc that sets the CertVerifyResult to a given value for
128 // all certificates that are Verify()'d
129 class MockCertVerifyProc : public CertVerifyProc {
130 public:
MockCertVerifyProc(const CertVerifyResult & result)131 explicit MockCertVerifyProc(const CertVerifyResult& result)
132 : CertVerifyProc(CRLSet::BuiltinCRLSet()), result_(result) {}
MockCertVerifyProc(const CertVerifyResult & result,int error)133 MockCertVerifyProc(const CertVerifyResult& result, int error)
134 : CertVerifyProc(CRLSet::BuiltinCRLSet()),
135 result_(result),
136 error_(error) {}
137
138 MockCertVerifyProc(const MockCertVerifyProc&) = delete;
139 MockCertVerifyProc& operator=(const MockCertVerifyProc&) = delete;
140
141 protected:
142 ~MockCertVerifyProc() override = default;
143
144 private:
145 int VerifyInternal(X509Certificate* cert,
146 const std::string& hostname,
147 const std::string& ocsp_response,
148 const std::string& sct_list,
149 int flags,
150 CertVerifyResult* verify_result,
151 const NetLogWithSource& net_log,
152 std::optional<base::Time> time_now) override;
153
154 const CertVerifyResult result_;
155 const int error_ = OK;
156 };
157
VerifyInternal(X509Certificate * cert,const std::string & hostname,const std::string & ocsp_response,const std::string & sct_list,int flags,CertVerifyResult * verify_result,const NetLogWithSource & net_log,std::optional<base::Time> time_now)158 int MockCertVerifyProc::VerifyInternal(X509Certificate* cert,
159 const std::string& hostname,
160 const std::string& ocsp_response,
161 const std::string& sct_list,
162 int flags,
163 CertVerifyResult* verify_result,
164 const NetLogWithSource& net_log,
165 std::optional<base::Time> time_now) {
166 *verify_result = result_;
167 verify_result->verified_cert = cert;
168 return error_;
169 }
170
171 // This enum identifies a concrete implemenation of CertVerifyProc.
172 //
173 // The type is erased by CreateCertVerifyProc(), however needs to be known for
174 // some of the test expectations.
175 enum CertVerifyProcType {
176 CERT_VERIFY_PROC_ANDROID,
177 CERT_VERIFY_PROC_IOS,
178 CERT_VERIFY_PROC_BUILTIN,
179 CERT_VERIFY_PROC_BUILTIN_CHROME_ROOTS,
180 };
181
182 // Returns a textual description of the CertVerifyProc implementation
183 // that is being tested, used to give better names to parameterized
184 // tests.
VerifyProcTypeToName(const testing::TestParamInfo<CertVerifyProcType> & params)185 std::string VerifyProcTypeToName(
186 const testing::TestParamInfo<CertVerifyProcType>& params) {
187 switch (params.param) {
188 case CERT_VERIFY_PROC_ANDROID:
189 return "CertVerifyProcAndroid";
190 case CERT_VERIFY_PROC_IOS:
191 return "CertVerifyProcIOS";
192 case CERT_VERIFY_PROC_BUILTIN:
193 return "CertVerifyProcBuiltin";
194 case CERT_VERIFY_PROC_BUILTIN_CHROME_ROOTS:
195 return "CertVerifyProcBuiltinChromeRoots";
196 }
197
198 return "";
199 }
200
CreateCertVerifyProc(CertVerifyProcType type,scoped_refptr<CertNetFetcher> cert_net_fetcher,scoped_refptr<CRLSet> crl_set,CertificateList additional_trust_anchors,CertificateList additional_untrusted_authorities)201 scoped_refptr<CertVerifyProc> CreateCertVerifyProc(
202 CertVerifyProcType type,
203 scoped_refptr<CertNetFetcher> cert_net_fetcher,
204 scoped_refptr<CRLSet> crl_set,
205 CertificateList additional_trust_anchors,
206 CertificateList additional_untrusted_authorities) {
207 CertVerifyProc::InstanceParams instance_params;
208 instance_params.additional_trust_anchors =
209 net::x509_util::ParseAllValidCerts(additional_trust_anchors);
210 instance_params.additional_untrusted_authorities =
211 net::x509_util::ParseAllValidCerts(additional_untrusted_authorities);
212 switch (type) {
213 #if BUILDFLAG(IS_ANDROID)
214 case CERT_VERIFY_PROC_ANDROID:
215 return base::MakeRefCounted<CertVerifyProcAndroid>(
216 std::move(cert_net_fetcher), std::move(crl_set));
217 #elif BUILDFLAG(IS_IOS)
218 case CERT_VERIFY_PROC_IOS:
219 return base::MakeRefCounted<CertVerifyProcIOS>(std::move(crl_set));
220 #endif
221 #if BUILDFLAG(IS_FUCHSIA)
222 case CERT_VERIFY_PROC_BUILTIN:
223 return CreateCertVerifyProcBuiltin(
224 std::move(cert_net_fetcher), std::move(crl_set),
225 std::make_unique<DoNothingCTVerifier>(),
226 base::MakeRefCounted<DefaultCTPolicyEnforcer>(),
227 CreateSslSystemTrustStore(), instance_params);
228 #endif
229 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
230 case CERT_VERIFY_PROC_BUILTIN_CHROME_ROOTS:
231 return CreateCertVerifyProcBuiltin(
232 std::move(cert_net_fetcher), std::move(crl_set),
233 std::make_unique<DoNothingCTVerifier>(),
234 base::MakeRefCounted<DefaultCTPolicyEnforcer>(),
235 CreateSslSystemTrustStoreChromeRoot(
236 std::make_unique<net::TrustStoreChrome>()),
237 instance_params);
238 #endif
239 default:
240 return nullptr;
241 }
242 }
243
244 // The set of all CertVerifyProcTypes that tests should be parameterized on.
245 // This needs to be kept in sync with CertVerifyProc::CreateSystemVerifyProc()
246 // and the platforms where CreateSslSystemTrustStore() is not a dummy store.
247 // TODO(crbug.com/649017): Enable CERT_VERIFY_PROC_BUILTIN everywhere. Right
248 // now this is gated on having CertVerifyProcBuiltin understand the roots added
249 // via TestRootCerts.
250 constexpr CertVerifyProcType kAllCertVerifiers[] = {
251 #if BUILDFLAG(IS_ANDROID)
252 CERT_VERIFY_PROC_ANDROID,
253 #elif BUILDFLAG(IS_IOS)
254 CERT_VERIFY_PROC_IOS,
255 #elif BUILDFLAG(IS_FUCHSIA)
256 CERT_VERIFY_PROC_BUILTIN,
257 #endif
258 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
259 CERT_VERIFY_PROC_BUILTIN_CHROME_ROOTS,
260 #endif
261 };
262 static_assert(std::size(kAllCertVerifiers) != 0, "Unsupported platform");
263
264 // Returns true if a test root added through ScopedTestRoot can verify
265 // successfully as a target certificate with chain of length 1 on the given
266 // CertVerifyProcType.
ScopedTestRootCanTrustTargetCert(CertVerifyProcType verify_proc_type)267 bool ScopedTestRootCanTrustTargetCert(CertVerifyProcType verify_proc_type) {
268 return verify_proc_type == CERT_VERIFY_PROC_IOS ||
269 verify_proc_type == CERT_VERIFY_PROC_ANDROID;
270 }
271
272 // Returns true if a non-self-signed CA certificate added through
273 // ScopedTestRoot can verify successfully as the root of a chain by the given
274 // CertVerifyProcType.
ScopedTestRootCanTrustIntermediateCert(CertVerifyProcType verify_proc_type)275 bool ScopedTestRootCanTrustIntermediateCert(
276 CertVerifyProcType verify_proc_type) {
277 return verify_proc_type == CERT_VERIFY_PROC_IOS ||
278 verify_proc_type == CERT_VERIFY_PROC_BUILTIN ||
279 verify_proc_type == CERT_VERIFY_PROC_BUILTIN_CHROME_ROOTS ||
280 verify_proc_type == CERT_VERIFY_PROC_ANDROID;
281 }
282
MakeRandomHexString(size_t num_bytes)283 std::string MakeRandomHexString(size_t num_bytes) {
284 std::vector<uint8_t> rand_bytes(num_bytes);
285 base::RandBytes(rand_bytes);
286 return base::HexEncode(rand_bytes);
287 }
288
289 } // namespace
290
291 // This fixture is for tests that apply to concrete implementations of
292 // CertVerifyProc. It will be run for all of the concrete CertVerifyProc types.
293 //
294 // It is called "Internal" as it tests the internal methods like
295 // "VerifyInternal()".
296 class CertVerifyProcInternalTest
297 : public testing::TestWithParam<CertVerifyProcType> {
298 protected:
SetUp()299 void SetUp() override { SetUpCertVerifyProc(CRLSet::BuiltinCRLSet()); }
300
301 // CertNetFetcher may be initialized by subclasses that want to use net
302 // fetching by calling SetUpWithCertNetFetcher instead of SetUp.
SetUpWithCertNetFetcher(scoped_refptr<CertNetFetcher> cert_net_fetcher,scoped_refptr<CRLSet> crl_set,CertificateList additional_trust_anchors,CertificateList additional_untrusted_authorities)303 void SetUpWithCertNetFetcher(
304 scoped_refptr<CertNetFetcher> cert_net_fetcher,
305 scoped_refptr<CRLSet> crl_set,
306 CertificateList additional_trust_anchors,
307 CertificateList additional_untrusted_authorities) {
308 CertVerifyProcType type = verify_proc_type();
309 verify_proc_ = CreateCertVerifyProc(
310 type, std::move(cert_net_fetcher), std::move(crl_set),
311 additional_trust_anchors, additional_untrusted_authorities);
312 ASSERT_TRUE(verify_proc_);
313 }
314
SetUpCertVerifyProc(scoped_refptr<CRLSet> crl_set)315 virtual void SetUpCertVerifyProc(scoped_refptr<CRLSet> crl_set) {
316 SetUpWithCertNetFetcher(nullptr, std::move(crl_set),
317 /*additional_trust_anchors=*/{},
318 /*additional_untrusted_authorities=*/{});
319 }
320
SetUpWithAdditionalCerts(CertificateList additional_trust_anchors,CertificateList additional_untrusted_authorities)321 virtual void SetUpWithAdditionalCerts(
322 CertificateList additional_trust_anchors,
323 CertificateList additional_untrusted_authorities) {
324 SetUpWithCertNetFetcher(nullptr, CRLSet::BuiltinCRLSet(),
325 additional_trust_anchors,
326 additional_untrusted_authorities);
327 }
328
Verify(X509Certificate * cert,const std::string & hostname,int flags,CertVerifyResult * verify_result,const NetLogWithSource & net_log)329 int Verify(X509Certificate* cert,
330 const std::string& hostname,
331 int flags,
332 CertVerifyResult* verify_result,
333 const NetLogWithSource& net_log) {
334 return verify_proc_->Verify(cert, hostname, /*ocsp_response=*/std::string(),
335 /*sct_list=*/std::string(), flags,
336 verify_result, net_log);
337 }
338
Verify(X509Certificate * cert,const std::string & hostname,int flags,CertVerifyResult * verify_result)339 int Verify(X509Certificate* cert,
340 const std::string& hostname,
341 int flags,
342 CertVerifyResult* verify_result) {
343 return Verify(cert, hostname, flags, verify_result, NetLogWithSource());
344 }
345
Verify(X509Certificate * cert,const std::string & hostname)346 int Verify(X509Certificate* cert, const std::string& hostname) {
347 CertVerifyResult verify_result;
348 int flags = 0;
349 return Verify(cert, hostname, flags, &verify_result);
350 }
351
verify_proc_type() const352 CertVerifyProcType verify_proc_type() const { return GetParam(); }
353
354 // Returns true if the RSA/DSA keysize will be considered weak on the current
355 // platform. IsInvalidRsaDsaKeySize should be checked prior, since some very
356 // weak keys may be considered invalid.
IsWeakRsaDsaKeySize(int size) const357 bool IsWeakRsaDsaKeySize(int size) const {
358 #if BUILDFLAG(IS_IOS)
359 // Beginning with iOS 13, the minimum key size for RSA/DSA algorithms is
360 // 2048 bits. See https://support.apple.com/en-us/HT210176
361 if (verify_proc_type() == CERT_VERIFY_PROC_IOS) {
362 return size < 2048;
363 }
364 #endif
365
366 return size < 1024;
367 }
368
369 // Returns true if the RSA/DSA keysize will be considered invalid on the
370 // current platform.
IsInvalidRsaDsaKeySize(int size) const371 bool IsInvalidRsaDsaKeySize(int size) const {
372 #if BUILDFLAG(IS_IOS)
373 // On iOS using SecTrustEvaluateWithError it is not possible to
374 // distinguish between weak and invalid key sizes.
375 return IsWeakRsaDsaKeySize(size);
376 #else
377 // This platform does not mark certificates with weak keys as invalid.
378 return false;
379 #endif
380 }
381
ParseKeyType(const std::string & key_type,std::string * type,int * size)382 static bool ParseKeyType(const std::string& key_type,
383 std::string* type,
384 int* size) {
385 size_t pos = key_type.find("-");
386 *type = key_type.substr(0, pos);
387 std::string size_str = key_type.substr(pos + 1);
388 return base::StringToInt(size_str, size);
389 }
390
391 // Some platforms may reject certificates with very weak keys as invalid.
IsInvalidKeyType(const std::string & key_type) const392 bool IsInvalidKeyType(const std::string& key_type) const {
393 std::string type;
394 int size = 0;
395 if (!ParseKeyType(key_type, &type, &size))
396 return false;
397
398 if (type == "rsa" || type == "dsa")
399 return IsInvalidRsaDsaKeySize(size);
400
401 return false;
402 }
403
404 // Currently, only RSA and DSA keys are checked for weakness, and our example
405 // weak size is 768. These could change in the future.
406 //
407 // Note that this means there may be false negatives: keys for other
408 // algorithms and which are weak will pass this test.
409 //
410 // Also, IsInvalidKeyType should be checked prior, since some weak keys may be
411 // considered invalid.
IsWeakKeyType(const std::string & key_type) const412 bool IsWeakKeyType(const std::string& key_type) const {
413 std::string type;
414 int size = 0;
415 if (!ParseKeyType(key_type, &type, &size))
416 return false;
417
418 if (type == "rsa" || type == "dsa")
419 return IsWeakRsaDsaKeySize(size);
420
421 return false;
422 }
423
SupportsCRLSet() const424 bool SupportsCRLSet() const { return VerifyProcTypeIsBuiltin(); }
425
SupportsCRLSetsInPathBuilding() const426 bool SupportsCRLSetsInPathBuilding() const {
427 return VerifyProcTypeIsBuiltin();
428 }
429
SupportsEV() const430 bool SupportsEV() const {
431 // Android and iOS do not support EV. See https://crbug.com/117478#7
432 #if defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
433 return true;
434 #else
435 return false;
436 #endif
437 }
438
SupportsSoftFailRevChecking() const439 bool SupportsSoftFailRevChecking() const { return VerifyProcTypeIsBuiltin(); }
440
SupportsRevCheckingRequiredLocalAnchors() const441 bool SupportsRevCheckingRequiredLocalAnchors() const {
442 return VerifyProcTypeIsBuiltin();
443 }
444
VerifyProcTypeIsBuiltin() const445 bool VerifyProcTypeIsBuiltin() const {
446 return verify_proc_type() == CERT_VERIFY_PROC_BUILTIN ||
447 verify_proc_type() == CERT_VERIFY_PROC_BUILTIN_CHROME_ROOTS;
448 }
449
VerifyProcTypeIsIOSAtMostOS14() const450 bool VerifyProcTypeIsIOSAtMostOS14() const {
451 return false;
452 }
453
VerifyProcTypeIsIOSAtMostOS15() const454 bool VerifyProcTypeIsIOSAtMostOS15() const {
455 #if BUILDFLAG(IS_IOS)
456 if (verify_proc_type() == CERT_VERIFY_PROC_IOS &&
457 !base::ios::IsRunningOnIOS16OrLater()) {
458 return true;
459 }
460 #endif
461 return false;
462 }
463
verify_proc() const464 CertVerifyProc* verify_proc() const { return verify_proc_.get(); }
465
466 private:
467 scoped_refptr<CertVerifyProc> verify_proc_;
468 };
469
470 INSTANTIATE_TEST_SUITE_P(All,
471 CertVerifyProcInternalTest,
472 testing::ValuesIn(kAllCertVerifiers),
473 VerifyProcTypeToName);
474
TEST_P(CertVerifyProcInternalTest,DistrustedIntermediate)475 TEST_P(CertVerifyProcInternalTest, DistrustedIntermediate) {
476 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
477 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
478 constexpr char kHostname[] = "www.example.com";
479
480 // Chain should not verify without any ScopedTestRoots.
481 EXPECT_THAT(Verify(chain.get(), kHostname),
482 IsError(ERR_CERT_AUTHORITY_INVALID));
483
484 // Trusting root should cause chain to verify successfully.
485 ScopedTestRoot trust_root(root->GetX509Certificate(),
486 bssl::CertificateTrust::ForTrustAnchor());
487 EXPECT_THAT(Verify(chain.get(), kHostname), IsOk());
488
489 ScopedTestRoot distrust_intermediate(intermediate->GetX509Certificate(),
490 bssl::CertificateTrust::ForDistrusted());
491 if (VerifyProcTypeIsBuiltin()) {
492 // Distrusting intermediate should cause chain to not verify again.
493 EXPECT_THAT(Verify(chain.get(), kHostname),
494 IsError(ERR_CERT_AUTHORITY_INVALID));
495 } else {
496 // Specifying trust types for the platform verifiers through ScopedTestRoot
497 // is not supported, so this should still verify successfully.
498 EXPECT_THAT(Verify(chain.get(), kHostname), IsOk());
499 }
500 }
501
502 // Tests that a certificate is recognized as EV, when the valid EV policy OID
503 // for the trust anchor is the second candidate EV oid in the target
504 // certificate. This is a regression test for crbug.com/705285.
TEST_P(CertVerifyProcInternalTest,EVVerificationMultipleOID)505 TEST_P(CertVerifyProcInternalTest, EVVerificationMultipleOID) {
506 if (!SupportsEV()) {
507 LOG(INFO) << "Skipping test as EV verification is not yet supported";
508 return;
509 }
510
511 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
512
513 // The policies that target certificate asserts.
514 static const char kOtherTestCertPolicy[] = "2.23.140.1.1";
515 static const char kEVTestCertPolicy[] = "1.2.3.4";
516 // Specify the extraneous policy first, then the actual policy.
517 leaf->SetCertificatePolicies({kOtherTestCertPolicy, kEVTestCertPolicy});
518
519 scoped_refptr<X509Certificate> cert = leaf->GetX509Certificate();
520 ScopedTestRoot test_root(root->GetX509Certificate());
521
522 // Build a CRLSet that covers the target certificate.
523 //
524 // This way CRLSet coverage will be sufficient for EV revocation checking,
525 // so this test does not depend on online revocation checking.
526 std::string_view spki;
527 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(
528 x509_util::CryptoBufferAsStringPiece(root->GetCertBuffer()), &spki));
529 SHA256HashValue spki_sha256;
530 crypto::SHA256HashString(spki, spki_sha256.data, sizeof(spki_sha256.data));
531 SetUpCertVerifyProc(CRLSet::ForTesting(false, &spki_sha256, "", "", {}));
532
533 // Consider the root of the test chain a valid EV root for the test policy.
534 ScopedTestEVPolicy scoped_test_ev_policy(
535 EVRootCAMetadata::GetInstance(),
536 X509Certificate::CalculateFingerprint256(root->GetCertBuffer()),
537 kEVTestCertPolicy);
538 ScopedTestEVPolicy scoped_test_other_policy(
539 EVRootCAMetadata::GetInstance(), SHA256HashValue(), kOtherTestCertPolicy);
540
541 CertVerifyResult verify_result;
542 int flags = 0;
543 int error = Verify(cert.get(), "www.example.com", flags, &verify_result);
544 EXPECT_THAT(error, IsOk());
545 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV);
546 }
547
548 // Target cert has an EV policy, and verifies successfully, but has a chain of
549 // length 1 because the target cert was directly trusted in the trust store.
550 // Should verify OK but not with STATUS_IS_EV.
TEST_P(CertVerifyProcInternalTest,TrustedTargetCertWithEVPolicy)551 TEST_P(CertVerifyProcInternalTest, TrustedTargetCertWithEVPolicy) {
552 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
553
554 static const char kEVTestCertPolicy[] = "1.2.3.4";
555 leaf->SetCertificatePolicies({kEVTestCertPolicy});
556 ScopedTestEVPolicy scoped_test_ev_policy(
557 EVRootCAMetadata::GetInstance(), SHA256HashValue(), kEVTestCertPolicy);
558
559 scoped_refptr<X509Certificate> cert = leaf->GetX509Certificate();
560 ScopedTestRoot scoped_test_root(cert);
561
562 CertVerifyResult verify_result;
563 int flags = 0;
564 int error = Verify(cert.get(), "www.example.com", flags, &verify_result);
565 if (ScopedTestRootCanTrustTargetCert(verify_proc_type())) {
566 EXPECT_THAT(error, IsOk());
567 ASSERT_TRUE(verify_result.verified_cert);
568 EXPECT_TRUE(verify_result.verified_cert->intermediate_buffers().empty());
569 } else {
570 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
571 }
572 EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_IS_EV);
573 }
574
575 // Target cert has an EV policy, and verifies successfully with a chain of
576 // length 1, and its fingerprint matches the cert fingerprint for that ev
577 // policy. This should never happen in reality, but just test that things don't
578 // explode if it does.
TEST_P(CertVerifyProcInternalTest,TrustedTargetCertWithEVPolicyAndEVFingerprint)579 TEST_P(CertVerifyProcInternalTest,
580 TrustedTargetCertWithEVPolicyAndEVFingerprint) {
581 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
582
583 static const char kEVTestCertPolicy[] = "1.2.3.4";
584 leaf->SetCertificatePolicies({kEVTestCertPolicy});
585 ScopedTestEVPolicy scoped_test_ev_policy(
586 EVRootCAMetadata::GetInstance(),
587 X509Certificate::CalculateFingerprint256(leaf->GetCertBuffer()),
588 kEVTestCertPolicy);
589 scoped_refptr<X509Certificate> cert = leaf->GetX509Certificate();
590 ScopedTestRoot scoped_test_root(cert);
591
592 CertVerifyResult verify_result;
593 int flags = 0;
594 int error = Verify(cert.get(), "www.example.com", flags, &verify_result);
595 if (ScopedTestRootCanTrustTargetCert(verify_proc_type())) {
596 EXPECT_THAT(error, IsOk());
597 ASSERT_TRUE(verify_result.verified_cert);
598 EXPECT_TRUE(verify_result.verified_cert->intermediate_buffers().empty());
599 } else {
600 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
601 }
602 // An EV Root certificate should never be used as an end-entity certificate.
603 EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_IS_EV);
604 }
605
606 // Target cert has an EV policy, and has a valid path to the EV root, but the
607 // intermediate has been trusted directly. Should stop building the path at the
608 // intermediate and verify OK but not with STATUS_IS_EV.
609 // See https://crbug.com/979801
TEST_P(CertVerifyProcInternalTest,TrustedIntermediateCertWithEVPolicy)610 TEST_P(CertVerifyProcInternalTest, TrustedIntermediateCertWithEVPolicy) {
611 if (!SupportsEV()) {
612 LOG(INFO) << "Skipping test as EV verification is not yet supported";
613 return;
614 }
615 if (!ScopedTestRootCanTrustIntermediateCert(verify_proc_type())) {
616 LOG(INFO) << "Skipping test as intermediate cert cannot be trusted";
617 return;
618 }
619
620 for (bool trust_the_intermediate : {false, true}) {
621 SCOPED_TRACE(trust_the_intermediate);
622
623 // Need to build unique certs for each try otherwise caching can break
624 // things.
625 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
626
627 static const char kEVTestCertPolicy[] = "1.2.3.4";
628 leaf->SetCertificatePolicies({kEVTestCertPolicy});
629 intermediate->SetCertificatePolicies({kEVTestCertPolicy});
630 // Consider the root of the test chain a valid EV root for the test policy.
631 ScopedTestEVPolicy scoped_test_ev_policy(
632 EVRootCAMetadata::GetInstance(),
633 X509Certificate::CalculateFingerprint256(root->GetCertBuffer()),
634 kEVTestCertPolicy);
635
636 scoped_refptr<X509Certificate> cert = leaf->GetX509CertificateChain();
637 ASSERT_TRUE(cert.get());
638
639 scoped_refptr<X509Certificate> intermediate_cert =
640 intermediate->GetX509Certificate();
641 ASSERT_TRUE(intermediate_cert.get());
642
643 scoped_refptr<X509Certificate> root_cert = root->GetX509Certificate();
644 ASSERT_TRUE(root_cert.get());
645
646 if (!trust_the_intermediate) {
647 // First trust just the root. This verifies that the test setup is
648 // actually correct.
649 ScopedTestRoot scoped_test_root({root_cert});
650 CertVerifyResult verify_result;
651 int flags = 0;
652 int error = Verify(cert.get(), "www.example.com", flags, &verify_result);
653 EXPECT_THAT(error, IsOk());
654 ASSERT_TRUE(verify_result.verified_cert);
655 // Verified chain should include the intermediate and the root.
656 EXPECT_EQ(2U, verify_result.verified_cert->intermediate_buffers().size());
657 // Should be EV.
658 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV);
659 } else {
660 // Now try with trusting both the intermediate and the root.
661 ScopedTestRoot scoped_test_root({intermediate_cert, root_cert});
662 CertVerifyResult verify_result;
663 int flags = 0;
664 int error = Verify(cert.get(), "www.example.com", flags, &verify_result);
665 EXPECT_THAT(error, IsOk());
666 ASSERT_TRUE(verify_result.verified_cert);
667 // Verified chain should only go to the trusted intermediate, not the
668 // root.
669 EXPECT_EQ(1U, verify_result.verified_cert->intermediate_buffers().size());
670 // Should not be EV.
671 EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_IS_EV);
672 }
673 }
674 }
675
TEST_P(CertVerifyProcInternalTest,CertWithNullInCommonNameAndNoSAN)676 TEST_P(CertVerifyProcInternalTest, CertWithNullInCommonNameAndNoSAN) {
677 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
678
679 leaf->EraseExtension(bssl::der::Input(bssl::kSubjectAltNameOid));
680
681 std::string common_name;
682 common_name += "www.fake.com";
683 common_name += '\0';
684 common_name += "a" + MakeRandomHexString(12) + ".example.com";
685 leaf->SetSubjectCommonName(common_name);
686
687 // Trust the root and build a chain to verify that includes the intermediate.
688 ScopedTestRoot scoped_root(root->GetX509Certificate());
689 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
690 ASSERT_TRUE(chain.get());
691
692 int flags = 0;
693 CertVerifyResult verify_result;
694 int error = Verify(chain.get(), "www.fake.com", flags, &verify_result);
695
696 // This actually fails because Chrome only looks for hostnames in
697 // SubjectAltNames now and no SubjectAltName is present.
698 EXPECT_THAT(error, IsError(ERR_CERT_COMMON_NAME_INVALID));
699 }
700
TEST_P(CertVerifyProcInternalTest,CertWithNullInCommonNameAndValidSAN)701 TEST_P(CertVerifyProcInternalTest, CertWithNullInCommonNameAndValidSAN) {
702 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
703
704 leaf->SetSubjectAltName("www.fake.com");
705
706 std::string common_name;
707 common_name += "www.fake.com";
708 common_name += '\0';
709 common_name += "a" + MakeRandomHexString(12) + ".example.com";
710 leaf->SetSubjectCommonName(common_name);
711
712 // Trust the root and build a chain to verify that includes the intermediate.
713 ScopedTestRoot scoped_root(root->GetX509Certificate());
714 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
715 ASSERT_TRUE(chain.get());
716
717 int flags = 0;
718 CertVerifyResult verify_result;
719 int error = Verify(chain.get(), "www.fake.com", flags, &verify_result);
720
721 // SubjectAltName is valid and Chrome does not use the common name.
722 EXPECT_THAT(error, IsOk());
723 }
724
TEST_P(CertVerifyProcInternalTest,CertWithNullInSAN)725 TEST_P(CertVerifyProcInternalTest, CertWithNullInSAN) {
726 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
727
728 std::string hostname;
729 hostname += "www.fake.com";
730 hostname += '\0';
731 hostname += "a" + MakeRandomHexString(12) + ".example.com";
732 leaf->SetSubjectAltName(hostname);
733
734 // Trust the root and build a chain to verify that includes the intermediate.
735 ScopedTestRoot scoped_root(root->GetX509Certificate());
736 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
737 ASSERT_TRUE(chain.get());
738
739 int flags = 0;
740 CertVerifyResult verify_result;
741 int error = Verify(chain.get(), "www.fake.com", flags, &verify_result);
742
743 // SubjectAltName is invalid.
744 EXPECT_THAT(error, IsError(ERR_CERT_COMMON_NAME_INVALID));
745 }
746
747 // Tests the case where the target certificate is accepted by
748 // X509CertificateBytes, but has errors that should cause verification to fail.
TEST_P(CertVerifyProcInternalTest,InvalidTarget)749 TEST_P(CertVerifyProcInternalTest, InvalidTarget) {
750 base::FilePath certs_dir =
751 GetTestNetDataDirectory().AppendASCII("parse_certificate_unittest");
752 scoped_refptr<X509Certificate> bad_cert;
753 if (VerifyProcTypeIsBuiltin()) {
754 // Builtin verifier doesn't distinguish between invalid signature algorithm
755 // and unknown signature algorithm, so use a different test file that will
756 // fail in bssl::ParsedCertificate::Create. The other verifiers use a
757 // different test file since the platform verifiers don't all consider empty
758 // extensions sequence invalid.
759 bad_cert = ImportCertFromFile(certs_dir, "extensions_empty_sequence.pem");
760 } else {
761 bad_cert = ImportCertFromFile(certs_dir, "signature_algorithm_null.pem");
762 }
763 ASSERT_TRUE(bad_cert);
764
765 scoped_refptr<X509Certificate> ok_cert(
766 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
767 ASSERT_TRUE(ok_cert);
768
769 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
770 intermediates.push_back(bssl::UpRef(ok_cert->cert_buffer()));
771 scoped_refptr<X509Certificate> cert_with_bad_target(
772 X509Certificate::CreateFromBuffer(bssl::UpRef(bad_cert->cert_buffer()),
773 std::move(intermediates)));
774 ASSERT_TRUE(cert_with_bad_target);
775 EXPECT_EQ(1U, cert_with_bad_target->intermediate_buffers().size());
776
777 int flags = 0;
778 CertVerifyResult verify_result;
779 int error =
780 Verify(cert_with_bad_target.get(), "127.0.0.1", flags, &verify_result);
781
782 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID);
783 EXPECT_THAT(error, IsError(ERR_CERT_INVALID));
784 }
785
786 // Tests the case where an intermediate certificate is accepted by
787 // X509CertificateBytes, but has errors that should prevent using it during
788 // verification. The verification should succeed, since the intermediate
789 // wasn't necessary.
TEST_P(CertVerifyProcInternalTest,UnnecessaryInvalidIntermediate)790 TEST_P(CertVerifyProcInternalTest, UnnecessaryInvalidIntermediate) {
791 ScopedTestRoot test_root(
792 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem"));
793
794 base::FilePath certs_dir =
795 GetTestNetDataDirectory().AppendASCII("parse_certificate_unittest");
796 bssl::UniquePtr<CRYPTO_BUFFER> bad_cert =
797 x509_util::CreateCryptoBuffer(std::string_view("invalid"));
798 ASSERT_TRUE(bad_cert);
799
800 scoped_refptr<X509Certificate> ok_cert(
801 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
802 ASSERT_TRUE(ok_cert);
803
804 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
805 intermediates.push_back(std::move(bad_cert));
806 scoped_refptr<X509Certificate> cert_with_bad_intermediate(
807 X509Certificate::CreateFromBuffer(bssl::UpRef(ok_cert->cert_buffer()),
808 std::move(intermediates)));
809 ASSERT_TRUE(cert_with_bad_intermediate);
810 EXPECT_EQ(1U, cert_with_bad_intermediate->intermediate_buffers().size());
811
812 RecordingNetLogObserver net_log_observer(NetLogCaptureMode::kDefault);
813 NetLogWithSource net_log(NetLogWithSource::Make(
814 net::NetLog::Get(), net::NetLogSourceType::CERT_VERIFIER_TASK));
815 int flags = 0;
816 CertVerifyResult verify_result;
817 int error = Verify(cert_with_bad_intermediate.get(), "127.0.0.1", flags,
818 &verify_result, net_log);
819
820 EXPECT_THAT(error, IsOk());
821 EXPECT_EQ(0u, verify_result.cert_status);
822
823 auto events = net_log_observer.GetEntriesForSource(net_log.source());
824 EXPECT_FALSE(events.empty());
825
826 auto event = base::ranges::find(events, NetLogEventType::CERT_VERIFY_PROC,
827 &NetLogEntry::type);
828 ASSERT_NE(event, events.end());
829 EXPECT_EQ(net::NetLogEventPhase::BEGIN, event->phase);
830 const std::string* host = event->params.FindString("host");
831 ASSERT_TRUE(host);
832 EXPECT_EQ("127.0.0.1", *host);
833
834 if (VerifyProcTypeIsBuiltin()) {
835 event =
836 base::ranges::find(events, NetLogEventType::CERT_VERIFY_PROC_INPUT_CERT,
837 &NetLogEntry::type);
838 ASSERT_NE(event, events.end());
839 EXPECT_EQ(net::NetLogEventPhase::NONE, event->phase);
840 const std::string* errors = event->params.FindString("errors");
841 ASSERT_TRUE(errors);
842 EXPECT_EQ(
843 "ERROR: Failed parsing Certificate SEQUENCE\nERROR: Failed parsing "
844 "Certificate\n",
845 *errors);
846 }
847 }
848
TEST_P(CertVerifyProcInternalTest,RejectExpiredCert)849 TEST_P(CertVerifyProcInternalTest, RejectExpiredCert) {
850 base::FilePath certs_dir = GetTestCertsDirectory();
851
852 // Load root_ca_cert.pem into the test root store.
853 ScopedTestRoot test_root(ImportCertFromFile(certs_dir, "root_ca_cert.pem"));
854
855 scoped_refptr<X509Certificate> cert = CreateCertificateChainFromFile(
856 certs_dir, "expired_cert.pem", X509Certificate::FORMAT_AUTO);
857 ASSERT_TRUE(cert);
858 ASSERT_EQ(0U, cert->intermediate_buffers().size());
859
860 int flags = 0;
861 CertVerifyResult verify_result;
862 int error = Verify(cert.get(), "127.0.0.1", flags, &verify_result);
863 EXPECT_THAT(error, IsError(ERR_CERT_DATE_INVALID));
864 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_DATE_INVALID);
865 }
866
TEST_P(CertVerifyProcInternalTest,RejectWeakKeys)867 TEST_P(CertVerifyProcInternalTest, RejectWeakKeys) {
868 base::FilePath certs_dir = GetTestCertsDirectory();
869 typedef std::vector<std::string> Strings;
870 Strings key_types;
871
872 // These values mush match the prefixes of the key filenames generated by
873 // generate-test-keys.sh:
874 key_types.push_back("rsa-768");
875 key_types.push_back("rsa-1024");
876 key_types.push_back("rsa-2048");
877 key_types.push_back("ec-prime256v1");
878
879 // Now test each chain.
880 for (const std::string& ee_type : key_types) {
881 for (const std::string& signer_type : key_types) {
882 SCOPED_TRACE("ee_type:" + ee_type + " signer_type:" + signer_type);
883
884 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
885
886 ASSERT_TRUE(
887 leaf->UseKeyFromFile(certs_dir.AppendASCII(ee_type + "-1.key")));
888 ASSERT_TRUE(intermediate->UseKeyFromFile(
889 certs_dir.AppendASCII(signer_type + "-2.key")));
890
891 ScopedTestRoot scoped_root(root->GetX509Certificate());
892
893 CertVerifyResult verify_result;
894 int error = Verify(leaf->GetX509CertificateChain().get(),
895 "www.example.com", 0, &verify_result);
896
897 if (IsInvalidKeyType(ee_type) || IsInvalidKeyType(signer_type)) {
898 EXPECT_NE(OK, error);
899 EXPECT_EQ(CERT_STATUS_INVALID,
900 verify_result.cert_status & CERT_STATUS_INVALID);
901 } else if (IsWeakKeyType(ee_type) || IsWeakKeyType(signer_type)) {
902 EXPECT_NE(OK, error);
903 EXPECT_EQ(CERT_STATUS_WEAK_KEY,
904 verify_result.cert_status & CERT_STATUS_WEAK_KEY);
905 EXPECT_EQ(0u, verify_result.cert_status & CERT_STATUS_INVALID);
906 } else {
907 EXPECT_THAT(error, IsOk());
908 EXPECT_EQ(0U, verify_result.cert_status & CERT_STATUS_WEAK_KEY);
909 }
910 }
911 }
912 }
913
914 // Regression test for http://crbug.com/108514.
915 // Generates a chain with a root with a SHA256 signature, and another root with
916 // the same name/SPKI/keyid but with a SHA1 signature. The SHA256 root is
917 // trusted. The SHA1 certificate is supplied as an extra cert, but should be
918 // ignored as the verifier should prefer the trusted cert when path building
919 // from the leaf, generating the shortest chain of "leaf -> sha256root". If the
920 // path builder doesn't prioritize it could build an unoptimal but valid path
921 // like "leaf -> sha1root -> sha256root".
TEST_P(CertVerifyProcInternalTest,ExtraneousRootCert)922 TEST_P(CertVerifyProcInternalTest, ExtraneousRootCert) {
923 auto [leaf_builder, root_builder] = CertBuilder::CreateSimpleChain2();
924
925 root_builder->SetSignatureAlgorithm(bssl::SignatureAlgorithm::kEcdsaSha256);
926 scoped_refptr<X509Certificate> root_cert = root_builder->GetX509Certificate();
927
928 scoped_refptr<X509Certificate> server_cert =
929 leaf_builder->GetX509Certificate();
930
931 // Use the same root_builder but with a new serial number and setting the
932 // signature to SHA1, to generate an extraneous self-signed certificate that
933 // also signs the leaf cert and which could be used in path-building if the
934 // path builder doesn't prioritize trusted roots above other certs.
935 root_builder->SetRandomSerialNumber();
936 root_builder->SetSignatureAlgorithm(bssl::SignatureAlgorithm::kEcdsaSha1);
937 scoped_refptr<X509Certificate> extra_cert =
938 root_builder->GetX509Certificate();
939
940 ScopedTestRoot scoped_root(root_cert);
941
942 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
943 intermediates.push_back(bssl::UpRef(extra_cert->cert_buffer()));
944 scoped_refptr<X509Certificate> cert_chain = X509Certificate::CreateFromBuffer(
945 bssl::UpRef(server_cert->cert_buffer()), std::move(intermediates));
946 ASSERT_TRUE(cert_chain);
947
948 CertVerifyResult verify_result;
949 int flags = 0;
950 int error =
951 Verify(cert_chain.get(), "www.example.com", flags, &verify_result);
952 EXPECT_THAT(error, IsOk());
953
954 // The extra root should be discarded.
955 ASSERT_TRUE(verify_result.verified_cert.get());
956 ASSERT_EQ(1u, verify_result.verified_cert->intermediate_buffers().size());
957 EXPECT_TRUE(x509_util::CryptoBufferEqual(
958 verify_result.verified_cert->intermediate_buffers().front().get(),
959 root_cert->cert_buffer()));
960 }
961
962 // Test for bug 94673.
TEST_P(CertVerifyProcInternalTest,GoogleDigiNotarTest)963 TEST_P(CertVerifyProcInternalTest, GoogleDigiNotarTest) {
964 base::FilePath certs_dir = GetTestCertsDirectory();
965
966 scoped_refptr<X509Certificate> server_cert =
967 ImportCertFromFile(certs_dir, "google_diginotar.pem");
968 ASSERT_NE(static_cast<X509Certificate*>(nullptr), server_cert.get());
969
970 scoped_refptr<X509Certificate> intermediate_cert =
971 ImportCertFromFile(certs_dir, "diginotar_public_ca_2025.pem");
972 ASSERT_NE(static_cast<X509Certificate*>(nullptr), intermediate_cert.get());
973
974 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
975 intermediates.push_back(bssl::UpRef(intermediate_cert->cert_buffer()));
976 scoped_refptr<X509Certificate> cert_chain = X509Certificate::CreateFromBuffer(
977 bssl::UpRef(server_cert->cert_buffer()), std::move(intermediates));
978 ASSERT_TRUE(cert_chain);
979
980 CertVerifyResult verify_result;
981 int flags = CertVerifyProc::VERIFY_REV_CHECKING_ENABLED;
982 int error =
983 Verify(cert_chain.get(), "mail.google.com", flags, &verify_result);
984 EXPECT_NE(OK, error);
985
986 // Now turn off revocation checking. Certificate verification should still
987 // fail.
988 flags = 0;
989 error = Verify(cert_chain.get(), "mail.google.com", flags, &verify_result);
990 EXPECT_NE(OK, error);
991 }
992
TEST_P(CertVerifyProcInternalTest,NameConstraintsOk)993 TEST_P(CertVerifyProcInternalTest, NameConstraintsOk) {
994 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
995
996 // Use the private key matching the public_key_hash of the kDomainsTest
997 // constraint in CertVerifyProc::HasNameConstraintsViolation.
998 ASSERT_TRUE(leaf->UseKeyFromFile(
999 GetTestCertsDirectory().AppendASCII("name_constrained_key.pem")));
1000 // example.com is allowed by kDomainsTest, and notarealtld is not a known
1001 // TLD, so that's allowed too.
1002 leaf->SetSubjectAltNames({"test.ExAmPlE.CoM", "example.notarealtld",
1003 "*.test2.ExAmPlE.CoM", "*.example2.notarealtld"},
1004 {});
1005
1006 ScopedTestRoot test_root(root->GetX509Certificate());
1007
1008 scoped_refptr<X509Certificate> leaf_cert = leaf->GetX509Certificate();
1009
1010 int flags = 0;
1011 CertVerifyResult verify_result;
1012 int error =
1013 Verify(leaf_cert.get(), "test.example.com", flags, &verify_result);
1014 EXPECT_THAT(error, IsOk());
1015 EXPECT_EQ(0U, verify_result.cert_status);
1016
1017 error =
1018 Verify(leaf_cert.get(), "foo.test2.example.com", flags, &verify_result);
1019 EXPECT_THAT(error, IsOk());
1020 EXPECT_EQ(0U, verify_result.cert_status);
1021 }
1022
TEST_P(CertVerifyProcInternalTest,NameConstraintsFailure)1023 TEST_P(CertVerifyProcInternalTest, NameConstraintsFailure) {
1024 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
1025
1026 // Use the private key matching the public_key_hash of the kDomainsTest
1027 // constraint in CertVerifyProc::HasNameConstraintsViolation.
1028 ASSERT_TRUE(leaf->UseKeyFromFile(
1029 GetTestCertsDirectory().AppendASCII("name_constrained_key.pem")));
1030 // example.com is allowed by kDomainsTest, but example.org is not.
1031 leaf->SetSubjectAltNames({"test.ExAmPlE.CoM", "test.ExAmPlE.OrG"}, {});
1032
1033 ScopedTestRoot test_root(root->GetX509Certificate());
1034
1035 scoped_refptr<X509Certificate> leaf_cert = leaf->GetX509Certificate();
1036
1037 int flags = 0;
1038 CertVerifyResult verify_result;
1039 int error =
1040 Verify(leaf_cert.get(), "test.example.com", flags, &verify_result);
1041 EXPECT_THAT(error, IsError(ERR_CERT_NAME_CONSTRAINT_VIOLATION));
1042 EXPECT_EQ(CERT_STATUS_NAME_CONSTRAINT_VIOLATION,
1043 verify_result.cert_status & CERT_STATUS_NAME_CONSTRAINT_VIOLATION);
1044 }
1045
1046 // This fixture is for testing the verification of a certificate chain which
1047 // has some sort of mismatched signature algorithm (i.e.
1048 // Certificate.signatureAlgorithm and TBSCertificate.algorithm are different).
1049 class CertVerifyProcInspectSignatureAlgorithmsTest : public ::testing::Test {
1050 protected:
1051 // In the test setup, SHA384 is given special treatment as an unknown
1052 // algorithm.
1053 static constexpr bssl::DigestAlgorithm kUnknownDigestAlgorithm =
1054 bssl::DigestAlgorithm::Sha384;
1055
1056 struct CertParams {
1057 // Certificate.signatureAlgorithm
1058 bssl::DigestAlgorithm cert_algorithm;
1059
1060 // TBSCertificate.algorithm
1061 bssl::DigestAlgorithm tbs_algorithm;
1062 };
1063
1064 // Shorthand for VerifyChain() where only the leaf's parameters need
1065 // to be specified.
VerifyLeaf(const CertParams & leaf_params)1066 [[nodiscard]] int VerifyLeaf(const CertParams& leaf_params) {
1067 return VerifyChain(
1068 {// Target
1069 leaf_params,
1070 // Root
1071 {bssl::DigestAlgorithm::Sha256, bssl::DigestAlgorithm::Sha256}});
1072 }
1073
1074 // Shorthand for VerifyChain() where only the intermediate's parameters need
1075 // to be specified.
VerifyIntermediate(const CertParams & intermediate_params)1076 [[nodiscard]] int VerifyIntermediate(const CertParams& intermediate_params) {
1077 return VerifyChain(
1078 {// Target
1079 {bssl::DigestAlgorithm::Sha256, bssl::DigestAlgorithm::Sha256},
1080 // Intermediate
1081 intermediate_params,
1082 // Root
1083 {bssl::DigestAlgorithm::Sha256, bssl::DigestAlgorithm::Sha256}});
1084 }
1085
1086 // Shorthand for VerifyChain() where only the root's parameters need to be
1087 // specified.
VerifyRoot(const CertParams & root_params)1088 [[nodiscard]] int VerifyRoot(const CertParams& root_params) {
1089 return VerifyChain(
1090 {// Target
1091 {bssl::DigestAlgorithm::Sha256, bssl::DigestAlgorithm::Sha256},
1092 // Intermediate
1093 {bssl::DigestAlgorithm::Sha256, bssl::DigestAlgorithm::Sha256},
1094 // Root
1095 root_params});
1096 }
1097
1098 // Manufactures a certificate chain where each certificate has the indicated
1099 // signature algorithms, and then returns the result of verifying this chain.
1100 //
1101 // TODO(mattm): Replace the custom cert mangling code in this test with
1102 // CertBuilder.
VerifyChain(const std::vector<CertParams> & chain_params)1103 [[nodiscard]] int VerifyChain(const std::vector<CertParams>& chain_params) {
1104 auto chain = CreateChain(chain_params);
1105 if (!chain) {
1106 ADD_FAILURE() << "Failed creating certificate chain";
1107 return ERR_UNEXPECTED;
1108 }
1109
1110 int flags = 0;
1111 CertVerifyResult dummy_result;
1112 CertVerifyResult verify_result;
1113
1114 auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(dummy_result);
1115
1116 return verify_proc->Verify(
1117 chain.get(), "127.0.0.1", /*ocsp_response=*/std::string(),
1118 /*sct_list=*/std::string(), flags, &verify_result, NetLogWithSource());
1119 }
1120
1121 private:
1122 // Overwrites the AlgorithmIdentifier pointed to by |algorithm_sequence| with
1123 // |algorithm|. Note this violates the constness of StringPiece.
SetAlgorithmSequence(bssl::DigestAlgorithm algorithm,std::string_view * algorithm_sequence)1124 [[nodiscard]] static bool SetAlgorithmSequence(
1125 bssl::DigestAlgorithm algorithm,
1126 std::string_view* algorithm_sequence) {
1127 // This string of bytes is the full SEQUENCE for an AlgorithmIdentifier.
1128 std::vector<uint8_t> replacement_sequence;
1129 switch (algorithm) {
1130 case bssl::DigestAlgorithm::Sha1:
1131 // sha1WithRSAEncryption
1132 replacement_sequence = {0x30, 0x0D, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
1133 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00};
1134 break;
1135 case bssl::DigestAlgorithm::Sha256:
1136 // sha256WithRSAEncryption
1137 replacement_sequence = {0x30, 0x0D, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
1138 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00};
1139 break;
1140 case kUnknownDigestAlgorithm:
1141 // This shouldn't be anything meaningful (modified numbers at random).
1142 replacement_sequence = {0x30, 0x0D, 0x06, 0x09, 0x8a, 0x87, 0x18, 0x46,
1143 0xd7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00};
1144 break;
1145 default:
1146 ADD_FAILURE() << "Unsupported digest algorithm";
1147 return false;
1148 }
1149
1150 // For this simple replacement to work (without modifying any
1151 // other sequence lengths) the original algorithm and replacement
1152 // algorithm must have the same encoded length.
1153 if (algorithm_sequence->size() != replacement_sequence.size()) {
1154 ADD_FAILURE() << "AlgorithmIdentifier must have length "
1155 << replacement_sequence.size();
1156 return false;
1157 }
1158
1159 memcpy(const_cast<char*>(algorithm_sequence->data()),
1160 replacement_sequence.data(), replacement_sequence.size());
1161 return true;
1162 }
1163
1164 // Locate the serial number bytes.
ExtractSerialNumberFromDERCert(std::string_view der_cert,std::string_view * serial_value)1165 [[nodiscard]] static bool ExtractSerialNumberFromDERCert(
1166 std::string_view der_cert,
1167 std::string_view* serial_value) {
1168 bssl::der::Parser parser((bssl::der::Input(der_cert)));
1169 bssl::der::Parser certificate;
1170 if (!parser.ReadSequence(&certificate)) {
1171 return false;
1172 }
1173
1174 bssl::der::Parser tbs_certificate;
1175 if (!certificate.ReadSequence(&tbs_certificate)) {
1176 return false;
1177 }
1178
1179 bool unused;
1180 if (!tbs_certificate.SkipOptionalTag(
1181 CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0, &unused)) {
1182 return false;
1183 }
1184
1185 // serialNumber
1186 bssl::der::Input serial_value_der;
1187 if (!tbs_certificate.ReadTag(CBS_ASN1_INTEGER, &serial_value_der)) {
1188 return false;
1189 }
1190
1191 *serial_value = serial_value_der.AsStringView();
1192 return true;
1193 }
1194
1195 // Creates a certificate (based on some base certificate file) using the
1196 // specified signature algorithms.
CreateCertificate(const CertParams & params)1197 static scoped_refptr<X509Certificate> CreateCertificate(
1198 const CertParams& params) {
1199 // Dosn't really matter which base certificate is used, so long as it is
1200 // valid and uses a signature AlgorithmIdentifier with the same encoded
1201 // length as sha1WithRSASignature.
1202 const char* kLeafFilename = "ok_cert.pem";
1203
1204 auto cert = CreateCertificateChainFromFile(
1205 GetTestCertsDirectory(), kLeafFilename, X509Certificate::FORMAT_AUTO);
1206 if (!cert) {
1207 ADD_FAILURE() << "Failed to load certificate: " << kLeafFilename;
1208 return nullptr;
1209 }
1210
1211 // Start with the DER bytes of a valid certificate. The der data is copied
1212 // to a new std::string as it will modified to create a new certificate.
1213 std::string cert_der(
1214 x509_util::CryptoBufferAsStringPiece(cert->cert_buffer()));
1215
1216 // Parse the certificate and identify the locations of interest within
1217 // |cert_der|.
1218 std::string_view cert_algorithm_sequence;
1219 std::string_view tbs_algorithm_sequence;
1220 if (!asn1::ExtractSignatureAlgorithmsFromDERCert(
1221 cert_der, &cert_algorithm_sequence, &tbs_algorithm_sequence)) {
1222 ADD_FAILURE() << "Failed parsing certificate algorithms";
1223 return nullptr;
1224 }
1225
1226 std::string_view serial_value;
1227 if (!ExtractSerialNumberFromDERCert(cert_der, &serial_value)) {
1228 ADD_FAILURE() << "Failed parsing certificate serial number";
1229 return nullptr;
1230 }
1231
1232 // Give each certificate a unique serial number based on its content (which
1233 // in turn is a function of |params|, otherwise importing it may fail.
1234
1235 // Upper bound for last entry in DigestAlgorithm
1236 const int kNumDigestAlgorithms = 15;
1237 *const_cast<char*>(serial_value.data()) +=
1238 static_cast<int>(params.tbs_algorithm) * kNumDigestAlgorithms +
1239 static_cast<int>(params.cert_algorithm);
1240
1241 // Change the signature AlgorithmIdentifiers.
1242 if (!SetAlgorithmSequence(params.cert_algorithm,
1243 &cert_algorithm_sequence) ||
1244 !SetAlgorithmSequence(params.tbs_algorithm, &tbs_algorithm_sequence)) {
1245 return nullptr;
1246 }
1247
1248 // NOTE: The signature is NOT recomputed over TBSCertificate -- for these
1249 // tests it isn't needed.
1250 return X509Certificate::CreateFromBytes(base::as_byte_span(cert_der));
1251 }
1252
CreateChain(const std::vector<CertParams> & params)1253 static scoped_refptr<X509Certificate> CreateChain(
1254 const std::vector<CertParams>& params) {
1255 // Manufacture a chain with the given combinations of signature algorithms.
1256 // This chain isn't actually a valid chain, but it is good enough for
1257 // testing the base CertVerifyProc.
1258 CertificateList certs;
1259 for (const auto& cert_params : params) {
1260 certs.push_back(CreateCertificate(cert_params));
1261 if (!certs.back())
1262 return nullptr;
1263 }
1264
1265 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
1266 for (size_t i = 1; i < certs.size(); ++i)
1267 intermediates.push_back(bssl::UpRef(certs[i]->cert_buffer()));
1268
1269 return X509Certificate::CreateFromBuffer(
1270 bssl::UpRef(certs[0]->cert_buffer()), std::move(intermediates));
1271 }
1272 };
1273
1274 // This is a control test to make sure that the test helper
1275 // VerifyLeaf() works as expected. There is no actual mismatch in the
1276 // algorithms used here.
1277 //
1278 // Certificate.signatureAlgorithm: sha1WithRSASignature
1279 // TBSCertificate.algorithm: sha1WithRSAEncryption
TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest,LeafSha1Sha1)1280 TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, LeafSha1Sha1) {
1281 int rv =
1282 VerifyLeaf({bssl::DigestAlgorithm::Sha1, bssl::DigestAlgorithm::Sha1});
1283 ASSERT_THAT(rv, IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM));
1284 }
1285
1286 // This is a control test to make sure that the test helper
1287 // VerifyLeaf() works as expected. There is no actual mismatch in the
1288 // algorithms used here.
1289 //
1290 // Certificate.signatureAlgorithm: sha256WithRSASignature
1291 // TBSCertificate.algorithm: sha256WithRSAEncryption
TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest,LeafSha256Sha256)1292 TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, LeafSha256Sha256) {
1293 int rv = VerifyLeaf(
1294 {bssl::DigestAlgorithm::Sha256, bssl::DigestAlgorithm::Sha256});
1295 ASSERT_THAT(rv, IsOk());
1296 }
1297
1298 // Mismatched signature algorithms in the leaf certificate.
1299 //
1300 // Certificate.signatureAlgorithm: sha1WithRSASignature
1301 // TBSCertificate.algorithm: sha256WithRSAEncryption
TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest,LeafSha1Sha256)1302 TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, LeafSha1Sha256) {
1303 int rv =
1304 VerifyLeaf({bssl::DigestAlgorithm::Sha1, bssl::DigestAlgorithm::Sha256});
1305 ASSERT_THAT(rv, IsError(ERR_CERT_INVALID));
1306 }
1307
1308 // Mismatched signature algorithms in the leaf certificate.
1309 //
1310 // Certificate.signatureAlgorithm: sha256WithRSAEncryption
1311 // TBSCertificate.algorithm: sha1WithRSASignature
TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest,LeafSha256Sha1)1312 TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, LeafSha256Sha1) {
1313 int rv =
1314 VerifyLeaf({bssl::DigestAlgorithm::Sha256, bssl::DigestAlgorithm::Sha1});
1315 ASSERT_THAT(rv, IsError(ERR_CERT_INVALID));
1316 }
1317
1318 // Unrecognized signature algorithm in the leaf certificate.
1319 //
1320 // Certificate.signatureAlgorithm: sha256WithRSAEncryption
1321 // TBSCertificate.algorithm: ?
TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest,LeafSha256Unknown)1322 TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, LeafSha256Unknown) {
1323 int rv = VerifyLeaf({bssl::DigestAlgorithm::Sha256, kUnknownDigestAlgorithm});
1324 ASSERT_THAT(rv, IsError(ERR_CERT_INVALID));
1325 }
1326
1327 // Unrecognized signature algorithm in the leaf certificate.
1328 //
1329 // Certificate.signatureAlgorithm: ?
1330 // TBSCertificate.algorithm: sha256WithRSAEncryption
TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest,LeafUnknownSha256)1331 TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, LeafUnknownSha256) {
1332 int rv = VerifyLeaf({kUnknownDigestAlgorithm, bssl::DigestAlgorithm::Sha256});
1333 ASSERT_THAT(rv, IsError(ERR_CERT_INVALID));
1334 }
1335
1336 // Mismatched signature algorithms in the intermediate certificate.
1337 //
1338 // Certificate.signatureAlgorithm: sha1WithRSASignature
1339 // TBSCertificate.algorithm: sha256WithRSAEncryption
TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest,IntermediateSha1Sha256)1340 TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, IntermediateSha1Sha256) {
1341 int rv = VerifyIntermediate(
1342 {bssl::DigestAlgorithm::Sha1, bssl::DigestAlgorithm::Sha256});
1343 ASSERT_THAT(rv, IsError(ERR_CERT_INVALID));
1344 }
1345
1346 // Mismatched signature algorithms in the intermediate certificate.
1347 //
1348 // Certificate.signatureAlgorithm: sha256WithRSAEncryption
1349 // TBSCertificate.algorithm: sha1WithRSASignature
TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest,IntermediateSha256Sha1)1350 TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, IntermediateSha256Sha1) {
1351 int rv = VerifyIntermediate(
1352 {bssl::DigestAlgorithm::Sha256, bssl::DigestAlgorithm::Sha1});
1353 ASSERT_THAT(rv, IsError(ERR_CERT_INVALID));
1354 }
1355
1356 // Mismatched signature algorithms in the root certificate.
1357 //
1358 // Certificate.signatureAlgorithm: sha256WithRSAEncryption
1359 // TBSCertificate.algorithm: sha1WithRSASignature
TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest,RootSha256Sha1)1360 TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, RootSha256Sha1) {
1361 int rv =
1362 VerifyRoot({bssl::DigestAlgorithm::Sha256, bssl::DigestAlgorithm::Sha1});
1363 ASSERT_THAT(rv, IsOk());
1364 }
1365
1366 // Unrecognized signature algorithm in the root certificate.
1367 //
1368 // Certificate.signatureAlgorithm: ?
1369 // TBSCertificate.algorithm: sha256WithRSAEncryption
TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest,RootUnknownSha256)1370 TEST_F(CertVerifyProcInspectSignatureAlgorithmsTest, RootUnknownSha256) {
1371 int rv = VerifyRoot({kUnknownDigestAlgorithm, bssl::DigestAlgorithm::Sha256});
1372 ASSERT_THAT(rv, IsOk());
1373 }
1374
TEST(CertVerifyProcTest,TestHasTooLongValidity)1375 TEST(CertVerifyProcTest, TestHasTooLongValidity) {
1376 struct {
1377 const char* const file;
1378 bool is_valid_too_long;
1379 } tests[] = {
1380 {"start_after_expiry.pem", true},
1381 {"pre_br_validity_ok.pem", true},
1382 {"pre_br_validity_bad_121.pem", true},
1383 {"pre_br_validity_bad_2020.pem", true},
1384 {"10_year_validity.pem", true},
1385 {"11_year_validity.pem", true},
1386 {"39_months_after_2015_04.pem", true},
1387 {"40_months_after_2015_04.pem", true},
1388 {"60_months_after_2012_07.pem", true},
1389 {"61_months_after_2012_07.pem", true},
1390 {"825_days_after_2018_03_01.pem", true},
1391 {"826_days_after_2018_03_01.pem", true},
1392 {"825_days_1_second_after_2018_03_01.pem", true},
1393 {"39_months_based_on_last_day.pem", true},
1394 {"398_days_after_2020_09_01.pem", false},
1395 {"399_days_after_2020_09_01.pem", true},
1396 {"398_days_1_second_after_2020_09_01.pem", true},
1397 };
1398
1399 base::FilePath certs_dir = GetTestCertsDirectory();
1400
1401 for (const auto& test : tests) {
1402 SCOPED_TRACE(test.file);
1403
1404 scoped_refptr<X509Certificate> certificate =
1405 ImportCertFromFile(certs_dir, test.file);
1406 ASSERT_TRUE(certificate);
1407 EXPECT_EQ(test.is_valid_too_long,
1408 CertVerifyProc::HasTooLongValidity(*certificate));
1409 }
1410 }
1411
1412 // Integration test for CertVerifyProc::HasTooLongValidity.
1413 // There isn't a way to add test entries to the known roots list for testing
1414 // the full CertVerifyProc implementations, but HasTooLongValidity is checked
1415 // by the outer CertVerifyProc::Verify. Thus the test can mock the
1416 // VerifyInternal result to pretend there was a successful verification with
1417 // is_issued_by_known_root and see that Verify overrides that with error.
TEST(CertVerifyProcTest,VerifyCertValidityTooLong)1418 TEST(CertVerifyProcTest, VerifyCertValidityTooLong) {
1419 scoped_refptr<X509Certificate> cert(ImportCertFromFile(
1420 GetTestCertsDirectory(), "900_days_after_2019_07_01.pem"));
1421 ASSERT_TRUE(cert);
1422
1423 {
1424 // Locally trusted cert should be ok.
1425 CertVerifyResult dummy_result;
1426 dummy_result.is_issued_by_known_root = false;
1427 auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(dummy_result);
1428 CertVerifyResult verify_result;
1429 int error = verify_proc->Verify(
1430 cert.get(), "127.0.0.1", /*ocsp_response=*/std::string(),
1431 /*sct_list=*/std::string(), 0, &verify_result, NetLogWithSource());
1432 EXPECT_THAT(error, IsOk());
1433 EXPECT_EQ(0u, verify_result.cert_status & CERT_STATUS_ALL_ERRORS);
1434 }
1435
1436 {
1437 // Publicly trusted cert that was otherwise okay should get changed to
1438 // ERR_CERT_VALIDITY_TOO_LONG.
1439 CertVerifyResult dummy_result;
1440 dummy_result.is_issued_by_known_root = true;
1441 auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(dummy_result);
1442 CertVerifyResult verify_result;
1443 int error = verify_proc->Verify(
1444 cert.get(), "127.0.0.1", /*ocsp_response=*/std::string(),
1445 /*sct_list=*/std::string(), 0, &verify_result, NetLogWithSource());
1446 EXPECT_THAT(error, IsError(ERR_CERT_VALIDITY_TOO_LONG));
1447 // TODO(mattm): generate a dedicated cert or use CertBuilder so that this
1448 // test doesn't also hit CERT_STATUS_NON_UNIQUE_NAME.
1449 EXPECT_EQ(CERT_STATUS_VALIDITY_TOO_LONG | CERT_STATUS_NON_UNIQUE_NAME,
1450 verify_result.cert_status & CERT_STATUS_ALL_ERRORS);
1451 }
1452
1453 {
1454 // Publicly trusted cert that had some other error should retain the
1455 // original error, but CERT_STATUS_VALIDITY_TOO_LONG should be added to
1456 // cert_status.
1457 CertVerifyResult dummy_result;
1458 dummy_result.is_issued_by_known_root = true;
1459 dummy_result.cert_status = CERT_STATUS_AUTHORITY_INVALID;
1460 auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(
1461 dummy_result, ERR_CERT_AUTHORITY_INVALID);
1462 CertVerifyResult verify_result;
1463 int error = verify_proc->Verify(
1464 cert.get(), "127.0.0.1", /*ocsp_response=*/std::string(),
1465 /*sct_list=*/std::string(), 0, &verify_result, NetLogWithSource());
1466 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1467 // TODO(mattm): generate a dedicated cert or use CertBuilder so that this
1468 // test doesn't also hit CERT_STATUS_NON_UNIQUE_NAME.
1469 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID | CERT_STATUS_VALIDITY_TOO_LONG |
1470 CERT_STATUS_NON_UNIQUE_NAME,
1471 verify_result.cert_status & CERT_STATUS_ALL_ERRORS);
1472 }
1473 }
1474
TEST_P(CertVerifyProcInternalTest,TestKnownRoot)1475 TEST_P(CertVerifyProcInternalTest, TestKnownRoot) {
1476 base::FilePath certs_dir = GetTestCertsDirectory();
1477 scoped_refptr<X509Certificate> cert_chain = CreateCertificateChainFromFile(
1478 certs_dir, "leaf_from_known_root.pem", X509Certificate::FORMAT_AUTO);
1479 ASSERT_TRUE(cert_chain);
1480
1481 int flags = 0;
1482 CertVerifyResult verify_result;
1483 int error =
1484 Verify(cert_chain.get(), "foo.chickentools.org", flags, &verify_result);
1485 EXPECT_THAT(error, IsOk())
1486 << "This test relies on a real certificate that "
1487 << "expires on May 11 2025. If failing on/after "
1488 << "that date, please disable and file a bug "
1489 << "against mattm. Current time: " << base::Time::Now();
1490 EXPECT_TRUE(verify_result.is_issued_by_known_root);
1491 }
1492
1493 // This tests that on successful certificate verification,
1494 // CertVerifyResult::public_key_hashes is filled with a SHA256 hash for each
1495 // of the certificates in the chain.
TEST_P(CertVerifyProcInternalTest,PublicKeyHashes)1496 TEST_P(CertVerifyProcInternalTest, PublicKeyHashes) {
1497 base::FilePath certs_dir = GetTestCertsDirectory();
1498 CertificateList certs = CreateCertificateListFromFile(
1499 certs_dir, "x509_verify_results.chain.pem", X509Certificate::FORMAT_AUTO);
1500 ASSERT_EQ(3U, certs.size());
1501
1502 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
1503 intermediates.push_back(bssl::UpRef(certs[1]->cert_buffer()));
1504 intermediates.push_back(bssl::UpRef(certs[2]->cert_buffer()));
1505
1506 ScopedTestRoot scoped_root(certs[2]);
1507 scoped_refptr<X509Certificate> cert_chain = X509Certificate::CreateFromBuffer(
1508 bssl::UpRef(certs[0]->cert_buffer()), std::move(intermediates));
1509 ASSERT_TRUE(cert_chain);
1510 ASSERT_EQ(2U, cert_chain->intermediate_buffers().size());
1511
1512 int flags = 0;
1513 CertVerifyResult verify_result;
1514 int error = Verify(cert_chain.get(), "127.0.0.1", flags, &verify_result);
1515 EXPECT_THAT(error, IsOk());
1516
1517 EXPECT_EQ(3u, verify_result.public_key_hashes.size());
1518
1519 // Convert |public_key_hashes| to strings for ease of comparison.
1520 std::vector<std::string> public_key_hash_strings;
1521 for (const auto& public_key_hash : verify_result.public_key_hashes)
1522 public_key_hash_strings.push_back(public_key_hash.ToString());
1523
1524 std::vector<std::string> expected_public_key_hashes = {
1525 // Target
1526 "sha256/Ru/08Ru275Zlf42sbI6lqi2OUun3r4YgrrK/vJ3+Yzk=",
1527
1528 // Intermediate
1529 "sha256/D9u0epgvPYlG9YiVp7V+IMT+xhUpB5BhsS/INjDXc4Y=",
1530
1531 // Trust anchor
1532 "sha256/VypP3VWL7OaqTJ7mIBehWYlv8khPuFHpWiearZI2YjI="};
1533
1534 // |public_key_hashes| does not have an ordering guarantee.
1535 EXPECT_THAT(expected_public_key_hashes,
1536 testing::UnorderedElementsAreArray(public_key_hash_strings));
1537 }
1538
1539 // Basic test for returning the chain in CertVerifyResult. Note that the
1540 // returned chain may just be a reflection of the originally supplied chain;
1541 // that is, if any errors occur, the default chain returned is an exact copy
1542 // of the certificate to be verified. The remaining VerifyReturn* tests are
1543 // used to ensure that the actual, verified chain is being returned by
1544 // Verify().
TEST_P(CertVerifyProcInternalTest,VerifyReturnChainBasic)1545 TEST_P(CertVerifyProcInternalTest, VerifyReturnChainBasic) {
1546 base::FilePath certs_dir = GetTestCertsDirectory();
1547 CertificateList certs = CreateCertificateListFromFile(
1548 certs_dir, "x509_verify_results.chain.pem", X509Certificate::FORMAT_AUTO);
1549 ASSERT_EQ(3U, certs.size());
1550
1551 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
1552 intermediates.push_back(bssl::UpRef(certs[1]->cert_buffer()));
1553 intermediates.push_back(bssl::UpRef(certs[2]->cert_buffer()));
1554
1555 ScopedTestRoot scoped_root(certs[2]);
1556
1557 scoped_refptr<X509Certificate> google_full_chain =
1558 X509Certificate::CreateFromBuffer(bssl::UpRef(certs[0]->cert_buffer()),
1559 std::move(intermediates));
1560 ASSERT_NE(static_cast<X509Certificate*>(nullptr), google_full_chain.get());
1561 ASSERT_EQ(2U, google_full_chain->intermediate_buffers().size());
1562
1563 CertVerifyResult verify_result;
1564 EXPECT_EQ(static_cast<X509Certificate*>(nullptr),
1565 verify_result.verified_cert.get());
1566 int error = Verify(google_full_chain.get(), "127.0.0.1", 0, &verify_result);
1567 EXPECT_THAT(error, IsOk());
1568 ASSERT_NE(static_cast<X509Certificate*>(nullptr),
1569 verify_result.verified_cert.get());
1570
1571 EXPECT_TRUE(
1572 x509_util::CryptoBufferEqual(google_full_chain->cert_buffer(),
1573 verify_result.verified_cert->cert_buffer()));
1574 const auto& return_intermediates =
1575 verify_result.verified_cert->intermediate_buffers();
1576 ASSERT_EQ(2U, return_intermediates.size());
1577 EXPECT_TRUE(x509_util::CryptoBufferEqual(return_intermediates[0].get(),
1578 certs[1]->cert_buffer()));
1579 EXPECT_TRUE(x509_util::CryptoBufferEqual(return_intermediates[1].get(),
1580 certs[2]->cert_buffer()));
1581 }
1582
1583 // Test that certificates issued for 'intranet' names (that is, containing no
1584 // known public registry controlled domain information) issued by well-known
1585 // CAs are flagged appropriately, while certificates that are issued by
1586 // internal CAs are not flagged.
TEST(CertVerifyProcTest,IntranetHostsRejected)1587 TEST(CertVerifyProcTest, IntranetHostsRejected) {
1588 const std::string kIntranetHostname = "webmail";
1589
1590 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
1591 leaf->SetSubjectAltName(kIntranetHostname);
1592
1593 scoped_refptr<X509Certificate> cert(leaf->GetX509Certificate());
1594
1595 CertVerifyResult verify_result;
1596 int error = 0;
1597
1598 // Intranet names for public CAs should be flagged:
1599 CertVerifyResult dummy_result;
1600 dummy_result.is_issued_by_known_root = true;
1601 auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(dummy_result);
1602 error = verify_proc->Verify(cert.get(), kIntranetHostname,
1603 /*ocsp_response=*/std::string(),
1604 /*sct_list=*/std::string(), 0, &verify_result,
1605 NetLogWithSource());
1606 EXPECT_THAT(error, IsOk());
1607 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME);
1608
1609 // However, if the CA is not well known, these should not be flagged:
1610 dummy_result.Reset();
1611 dummy_result.is_issued_by_known_root = false;
1612 verify_proc = base::MakeRefCounted<MockCertVerifyProc>(dummy_result);
1613 error = verify_proc->Verify(cert.get(), kIntranetHostname,
1614 /*ocsp_response=*/std::string(),
1615 /*sct_list=*/std::string(), 0, &verify_result,
1616 NetLogWithSource());
1617 EXPECT_THAT(error, IsOk());
1618 EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME);
1619 }
1620
1621 // Tests that certificates issued by Symantec's legacy infrastructure
1622 // are rejected according to the policies outlined in
1623 // https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html
1624 // unless the caller has explicitly disabled that enforcement.
TEST(CertVerifyProcTest,SymantecCertsRejected)1625 TEST(CertVerifyProcTest, SymantecCertsRejected) {
1626 constexpr SHA256HashValue kSymantecHashValue = {
1627 {0xb2, 0xde, 0xf5, 0x36, 0x2a, 0xd3, 0xfa, 0xcd, 0x04, 0xbd, 0x29,
1628 0x04, 0x7a, 0x43, 0x84, 0x4f, 0x76, 0x70, 0x34, 0xea, 0x48, 0x92,
1629 0xf8, 0x0e, 0x56, 0xbe, 0xe6, 0x90, 0x24, 0x3e, 0x25, 0x02}};
1630 constexpr SHA256HashValue kGoogleHashValue = {
1631 {0xec, 0x72, 0x29, 0x69, 0xcb, 0x64, 0x20, 0x0a, 0xb6, 0x63, 0x8f,
1632 0x68, 0xac, 0x53, 0x8e, 0x40, 0xab, 0xab, 0x5b, 0x19, 0xa6, 0x48,
1633 0x56, 0x61, 0x04, 0x2a, 0x10, 0x61, 0xc4, 0x61, 0x27, 0x76}};
1634
1635 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
1636
1637 static constexpr base::Time may_1_2016 = base::Time::FromTimeT(1462060800);
1638 leaf->SetValidity(may_1_2016, may_1_2016 + base::Days(1));
1639 scoped_refptr<X509Certificate> leaf_pre_june_2016 =
1640 leaf->GetX509Certificate();
1641
1642 static constexpr base::Time june_1_2016 = base::Time::FromTimeT(1464739200);
1643 leaf->SetValidity(june_1_2016, june_1_2016 + base::Days(1));
1644 scoped_refptr<X509Certificate> leaf_post_june_2016 =
1645 leaf->GetX509Certificate();
1646
1647 static constexpr base::Time dec_20_2017 = base::Time::FromTimeT(1513728000);
1648 leaf->SetValidity(dec_20_2017, dec_20_2017 + base::Days(1));
1649 scoped_refptr<X509Certificate> leaf_dec_2017 = leaf->GetX509Certificate();
1650
1651 // Test that certificates from the legacy Symantec infrastructure are
1652 // rejected:
1653 // leaf_dec_2017: A certificate issued after 2017-12-01, which is rejected
1654 // as of M65
1655 // leaf_pre_june_2016: A certificate issued prior to 2016-06-01, which is
1656 // rejected as of M66.
1657 for (X509Certificate* cert :
1658 {leaf_dec_2017.get(), leaf_pre_june_2016.get()}) {
1659 scoped_refptr<CertVerifyProc> verify_proc;
1660 int error = 0;
1661
1662 // Test that a legacy Symantec certificate is rejected.
1663 CertVerifyResult symantec_result;
1664 symantec_result.verified_cert = cert;
1665 symantec_result.public_key_hashes.push_back(HashValue(kSymantecHashValue));
1666 symantec_result.is_issued_by_known_root = true;
1667 verify_proc = base::MakeRefCounted<MockCertVerifyProc>(symantec_result);
1668
1669 CertVerifyResult test_result_1;
1670 error = verify_proc->Verify(
1671 cert, "www.example.com", /*ocsp_response=*/std::string(),
1672 /*sct_list=*/std::string(), 0, &test_result_1, NetLogWithSource());
1673 EXPECT_THAT(error, IsError(ERR_CERT_SYMANTEC_LEGACY));
1674 EXPECT_TRUE(test_result_1.cert_status & CERT_STATUS_SYMANTEC_LEGACY);
1675
1676 // ... Unless the Symantec cert chains through a allowlisted intermediate.
1677 CertVerifyResult allowlisted_result;
1678 allowlisted_result.verified_cert = cert;
1679 allowlisted_result.public_key_hashes.push_back(
1680 HashValue(kSymantecHashValue));
1681 allowlisted_result.public_key_hashes.push_back(HashValue(kGoogleHashValue));
1682 allowlisted_result.is_issued_by_known_root = true;
1683 verify_proc = base::MakeRefCounted<MockCertVerifyProc>(allowlisted_result);
1684
1685 CertVerifyResult test_result_2;
1686 error = verify_proc->Verify(
1687 cert, "www.example.com", /*ocsp_response=*/std::string(),
1688 /*sct_list=*/std::string(), 0, &test_result_2, NetLogWithSource());
1689 EXPECT_THAT(error, IsOk());
1690 EXPECT_FALSE(test_result_2.cert_status & CERT_STATUS_AUTHORITY_INVALID);
1691
1692 // ... Or the caller disabled enforcement of Symantec policies.
1693 CertVerifyResult test_result_3;
1694 error = verify_proc->Verify(
1695 cert, "www.example.com", /*ocsp_response=*/std::string(),
1696 /*sct_list=*/std::string(),
1697 CertVerifyProc::VERIFY_DISABLE_SYMANTEC_ENFORCEMENT, &test_result_3,
1698 NetLogWithSource());
1699 EXPECT_THAT(error, IsOk());
1700 EXPECT_FALSE(test_result_3.cert_status & CERT_STATUS_SYMANTEC_LEGACY);
1701 }
1702
1703 // Test that certificates from the legacy Symantec infrastructure issued
1704 // after 2016-06-01 appropriately rejected.
1705 scoped_refptr<X509Certificate> cert = leaf_post_june_2016;
1706
1707 scoped_refptr<CertVerifyProc> verify_proc;
1708 int error = 0;
1709
1710 // Test that a legacy Symantec certificate is rejected if the feature
1711 // flag is enabled, and accepted if it is not.
1712 CertVerifyResult symantec_result;
1713 symantec_result.verified_cert = cert;
1714 symantec_result.public_key_hashes.push_back(HashValue(kSymantecHashValue));
1715 symantec_result.is_issued_by_known_root = true;
1716 verify_proc = base::MakeRefCounted<MockCertVerifyProc>(symantec_result);
1717
1718 CertVerifyResult test_result_1;
1719 error = verify_proc->Verify(cert.get(), "www.example.com",
1720 /*ocsp_response=*/std::string(),
1721 /*sct_list=*/std::string(), 0, &test_result_1,
1722 NetLogWithSource());
1723 EXPECT_THAT(error, IsError(ERR_CERT_SYMANTEC_LEGACY));
1724 EXPECT_TRUE(test_result_1.cert_status & CERT_STATUS_SYMANTEC_LEGACY);
1725
1726 // ... Unless the Symantec cert chains through a allowlisted intermediate.
1727 CertVerifyResult allowlisted_result;
1728 allowlisted_result.verified_cert = cert;
1729 allowlisted_result.public_key_hashes.push_back(HashValue(kSymantecHashValue));
1730 allowlisted_result.public_key_hashes.push_back(HashValue(kGoogleHashValue));
1731 allowlisted_result.is_issued_by_known_root = true;
1732 verify_proc = base::MakeRefCounted<MockCertVerifyProc>(allowlisted_result);
1733
1734 CertVerifyResult test_result_2;
1735 error = verify_proc->Verify(cert.get(), "www.example.com",
1736 /*ocsp_response=*/std::string(),
1737 /*sct_list=*/std::string(), 0, &test_result_2,
1738 NetLogWithSource());
1739 EXPECT_THAT(error, IsOk());
1740 EXPECT_FALSE(test_result_2.cert_status & CERT_STATUS_AUTHORITY_INVALID);
1741
1742 // ... Or the caller disabled enforcement of Symantec policies.
1743 CertVerifyResult test_result_3;
1744 error = verify_proc->Verify(
1745 cert.get(), "www.example.com", /*ocsp_response=*/std::string(),
1746 /*sct_list=*/std::string(),
1747 CertVerifyProc::VERIFY_DISABLE_SYMANTEC_ENFORCEMENT, &test_result_3,
1748 NetLogWithSource());
1749 EXPECT_THAT(error, IsOk());
1750 EXPECT_FALSE(test_result_3.cert_status & CERT_STATUS_SYMANTEC_LEGACY);
1751 }
1752
1753 // Test that the certificate returned in CertVerifyResult is able to reorder
1754 // certificates that are not ordered from end-entity to root. While this is
1755 // a protocol violation if sent during a TLS handshake, if multiple sources
1756 // of intermediate certificates are combined, it's possible that order may
1757 // not be maintained.
TEST_P(CertVerifyProcInternalTest,VerifyReturnChainProperlyOrdered)1758 TEST_P(CertVerifyProcInternalTest, VerifyReturnChainProperlyOrdered) {
1759 base::FilePath certs_dir = GetTestCertsDirectory();
1760 CertificateList certs = CreateCertificateListFromFile(
1761 certs_dir, "x509_verify_results.chain.pem", X509Certificate::FORMAT_AUTO);
1762 ASSERT_EQ(3U, certs.size());
1763
1764 // Construct the chain out of order.
1765 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
1766 intermediates.push_back(bssl::UpRef(certs[2]->cert_buffer()));
1767 intermediates.push_back(bssl::UpRef(certs[1]->cert_buffer()));
1768
1769 ScopedTestRoot scoped_root(certs[2]);
1770
1771 scoped_refptr<X509Certificate> google_full_chain =
1772 X509Certificate::CreateFromBuffer(bssl::UpRef(certs[0]->cert_buffer()),
1773 std::move(intermediates));
1774 ASSERT_TRUE(google_full_chain);
1775 ASSERT_EQ(2U, google_full_chain->intermediate_buffers().size());
1776
1777 CertVerifyResult verify_result;
1778 EXPECT_FALSE(verify_result.verified_cert);
1779 int error = Verify(google_full_chain.get(), "127.0.0.1", 0, &verify_result);
1780 EXPECT_THAT(error, IsOk());
1781 ASSERT_TRUE(verify_result.verified_cert);
1782
1783 EXPECT_NE(google_full_chain, verify_result.verified_cert);
1784 EXPECT_TRUE(
1785 x509_util::CryptoBufferEqual(google_full_chain->cert_buffer(),
1786 verify_result.verified_cert->cert_buffer()));
1787 const auto& return_intermediates =
1788 verify_result.verified_cert->intermediate_buffers();
1789 ASSERT_EQ(2U, return_intermediates.size());
1790 EXPECT_TRUE(x509_util::CryptoBufferEqual(return_intermediates[0].get(),
1791 certs[1]->cert_buffer()));
1792 EXPECT_TRUE(x509_util::CryptoBufferEqual(return_intermediates[1].get(),
1793 certs[2]->cert_buffer()));
1794 }
1795
1796 // Test that Verify() filters out certificates which are not related to
1797 // or part of the certificate chain being verified.
TEST_P(CertVerifyProcInternalTest,VerifyReturnChainFiltersUnrelatedCerts)1798 TEST_P(CertVerifyProcInternalTest, VerifyReturnChainFiltersUnrelatedCerts) {
1799 base::FilePath certs_dir = GetTestCertsDirectory();
1800 CertificateList certs = CreateCertificateListFromFile(
1801 certs_dir, "x509_verify_results.chain.pem", X509Certificate::FORMAT_AUTO);
1802 ASSERT_EQ(3U, certs.size());
1803 ScopedTestRoot scoped_root(certs[2]);
1804
1805 scoped_refptr<X509Certificate> unrelated_certificate =
1806 ImportCertFromFile(certs_dir, "duplicate_cn_1.pem");
1807 scoped_refptr<X509Certificate> unrelated_certificate2 =
1808 ImportCertFromFile(certs_dir, "google.single.pem");
1809 ASSERT_NE(static_cast<X509Certificate*>(nullptr),
1810 unrelated_certificate.get());
1811 ASSERT_NE(static_cast<X509Certificate*>(nullptr),
1812 unrelated_certificate2.get());
1813
1814 // Interject unrelated certificates into the list of intermediates.
1815 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
1816 intermediates.push_back(bssl::UpRef(unrelated_certificate->cert_buffer()));
1817 intermediates.push_back(bssl::UpRef(certs[1]->cert_buffer()));
1818 intermediates.push_back(bssl::UpRef(unrelated_certificate2->cert_buffer()));
1819 intermediates.push_back(bssl::UpRef(certs[2]->cert_buffer()));
1820
1821 scoped_refptr<X509Certificate> google_full_chain =
1822 X509Certificate::CreateFromBuffer(bssl::UpRef(certs[0]->cert_buffer()),
1823 std::move(intermediates));
1824 ASSERT_TRUE(google_full_chain);
1825 ASSERT_EQ(4U, google_full_chain->intermediate_buffers().size());
1826
1827 CertVerifyResult verify_result;
1828 EXPECT_FALSE(verify_result.verified_cert);
1829 int error = Verify(google_full_chain.get(), "127.0.0.1", 0, &verify_result);
1830 EXPECT_THAT(error, IsOk());
1831 ASSERT_TRUE(verify_result.verified_cert);
1832
1833 EXPECT_NE(google_full_chain, verify_result.verified_cert);
1834 EXPECT_TRUE(
1835 x509_util::CryptoBufferEqual(google_full_chain->cert_buffer(),
1836 verify_result.verified_cert->cert_buffer()));
1837 const auto& return_intermediates =
1838 verify_result.verified_cert->intermediate_buffers();
1839 ASSERT_EQ(2U, return_intermediates.size());
1840 EXPECT_TRUE(x509_util::CryptoBufferEqual(return_intermediates[0].get(),
1841 certs[1]->cert_buffer()));
1842 EXPECT_TRUE(x509_util::CryptoBufferEqual(return_intermediates[1].get(),
1843 certs[2]->cert_buffer()));
1844 }
1845
TEST_P(CertVerifyProcInternalTest,AdditionalTrustAnchors)1846 TEST_P(CertVerifyProcInternalTest, AdditionalTrustAnchors) {
1847 if (!VerifyProcTypeIsBuiltin()) {
1848 LOG(INFO) << "Skipping this test in this platform.";
1849 return;
1850 }
1851
1852 // |ca_cert| is the issuer of |cert|.
1853 CertificateList ca_cert_list =
1854 CreateCertificateListFromFile(GetTestCertsDirectory(), "root_ca_cert.pem",
1855 X509Certificate::FORMAT_AUTO);
1856 ASSERT_EQ(1U, ca_cert_list.size());
1857 scoped_refptr<X509Certificate> ca_cert(ca_cert_list[0]);
1858
1859 CertificateList cert_list = CreateCertificateListFromFile(
1860 GetTestCertsDirectory(), "ok_cert.pem", X509Certificate::FORMAT_AUTO);
1861 ASSERT_EQ(1U, cert_list.size());
1862 scoped_refptr<X509Certificate> cert(cert_list[0]);
1863
1864 // Verification of |cert| fails when |ca_cert| is not in the trust anchors
1865 // list.
1866 int flags = 0;
1867 CertVerifyResult verify_result;
1868 int error = Verify(cert.get(), "127.0.0.1", flags, &verify_result);
1869 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1870 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status);
1871 EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor);
1872
1873 // Now add the |ca_cert| to the |trust_anchors|, and verification should pass.
1874 CertificateList trust_anchors;
1875 trust_anchors.push_back(ca_cert);
1876 SetUpWithAdditionalCerts(trust_anchors, {});
1877 error = Verify(cert.get(), "127.0.0.1", flags, &verify_result);
1878 EXPECT_THAT(error, IsOk());
1879 EXPECT_EQ(0U, verify_result.cert_status);
1880 EXPECT_TRUE(verify_result.is_issued_by_additional_trust_anchor);
1881
1882 // Clearing the |trust_anchors| makes verification fail again (the cache
1883 // should be skipped).
1884 SetUpWithAdditionalCerts({}, {});
1885 error = Verify(cert.get(), "127.0.0.1", flags, &verify_result);
1886 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1887 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status);
1888 EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor);
1889 }
1890
TEST_P(CertVerifyProcInternalTest,AdditionalIntermediates)1891 TEST_P(CertVerifyProcInternalTest, AdditionalIntermediates) {
1892 if (!VerifyProcTypeIsBuiltin()) {
1893 LOG(INFO) << "Skipping this test in this platform.";
1894 return;
1895 }
1896
1897 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
1898 scoped_refptr<X509Certificate> leaf_cert = leaf->GetX509Certificate();
1899 scoped_refptr<X509Certificate> intermediate_cert =
1900 intermediate->GetX509Certificate();
1901 scoped_refptr<X509Certificate> root_cert = root->GetX509Certificate();
1902 constexpr char kHostname[] = "www.example.com";
1903
1904 ScopedTestRoot trust_root(root_cert);
1905 // Leaf should not verify without intermediate found
1906 EXPECT_THAT(Verify(leaf_cert.get(), kHostname),
1907 IsError(ERR_CERT_AUTHORITY_INVALID));
1908
1909 // Leaf should verify after intermediate is passed in to CertVerifyProc. Chain
1910 // should be {leaf, intermediate, root}.
1911 SetUpWithAdditionalCerts({}, {intermediate->GetX509Certificate()});
1912 CertVerifyResult verify_result;
1913 int error = Verify(leaf_cert.get(), kHostname, /*flags=*/0, &verify_result);
1914 EXPECT_THAT(error, IsOk());
1915 ASSERT_TRUE(verify_result.verified_cert);
1916 EXPECT_EQ(verify_result.verified_cert->intermediate_buffers().size(), 2U);
1917 EXPECT_TRUE(x509_util::CryptoBufferEqual(
1918 verify_result.verified_cert->intermediate_buffers().back().get(),
1919 root_cert->cert_buffer()));
1920 EXPECT_TRUE(x509_util::CryptoBufferEqual(
1921 verify_result.verified_cert->intermediate_buffers().front().get(),
1922 intermediate_cert->cert_buffer()));
1923 }
1924
TEST_P(CertVerifyProcInternalTest,AdditionalTrustAnchorDuplicateIntermediate)1925 TEST_P(CertVerifyProcInternalTest, AdditionalTrustAnchorDuplicateIntermediate) {
1926 if (!VerifyProcTypeIsBuiltin()) {
1927 LOG(INFO) << "Skipping this test in this platform.";
1928 return;
1929 }
1930
1931 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
1932 constexpr char kHostname[] = "www.example.com";
1933
1934 // Leaf should not verify without anything set up.
1935 EXPECT_THAT(Verify(leaf->GetX509Certificate().get(), kHostname),
1936 IsError(ERR_CERT_AUTHORITY_INVALID));
1937
1938 // Leaf should verify with intermediate and root added.
1939 CertificateList trust_anchors, intermediates;
1940 intermediates.push_back(intermediate->GetX509Certificate());
1941 trust_anchors.push_back(root->GetX509Certificate());
1942 SetUpWithAdditionalCerts(trust_anchors, intermediates);
1943 EXPECT_THAT(Verify(leaf->GetX509Certificate().get(), kHostname), IsOk());
1944
1945 // Leaf should still verify after root is also in intermediates list.
1946 intermediates.push_back(root->GetX509Certificate());
1947 SetUpWithAdditionalCerts(trust_anchors, intermediates);
1948 EXPECT_THAT(Verify(leaf->GetX509Certificate().get(), kHostname), IsOk());
1949 }
1950
1951 // Tests that certificates issued by user-supplied roots are not flagged as
1952 // issued by a known root. This should pass whether or not the platform supports
1953 // detecting known roots.
TEST_P(CertVerifyProcInternalTest,IsIssuedByKnownRootIgnoresTestRoots)1954 TEST_P(CertVerifyProcInternalTest, IsIssuedByKnownRootIgnoresTestRoots) {
1955 // Load root_ca_cert.pem into the test root store.
1956 ScopedTestRoot test_root(
1957 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem"));
1958
1959 scoped_refptr<X509Certificate> cert(
1960 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
1961
1962 // Verification should pass.
1963 int flags = 0;
1964 CertVerifyResult verify_result;
1965 int error = Verify(cert.get(), "127.0.0.1", flags, &verify_result);
1966 EXPECT_THAT(error, IsOk());
1967 EXPECT_EQ(0U, verify_result.cert_status);
1968 // But should not be marked as a known root.
1969 EXPECT_FALSE(verify_result.is_issued_by_known_root);
1970 }
1971
1972 // Test that CRLSets are effective in making a certificate appear to be
1973 // revoked.
TEST_P(CertVerifyProcInternalTest,CRLSet)1974 TEST_P(CertVerifyProcInternalTest, CRLSet) {
1975 if (!SupportsCRLSet()) {
1976 LOG(INFO) << "Skipping test as verifier doesn't support CRLSet";
1977 return;
1978 }
1979
1980 CertificateList ca_cert_list =
1981 CreateCertificateListFromFile(GetTestCertsDirectory(), "root_ca_cert.pem",
1982 X509Certificate::FORMAT_AUTO);
1983 ASSERT_EQ(1U, ca_cert_list.size());
1984 ScopedTestRoot test_root(ca_cert_list[0]);
1985
1986 CertificateList cert_list = CreateCertificateListFromFile(
1987 GetTestCertsDirectory(), "ok_cert.pem", X509Certificate::FORMAT_AUTO);
1988 ASSERT_EQ(1U, cert_list.size());
1989 scoped_refptr<X509Certificate> cert(cert_list[0]);
1990
1991 int flags = 0;
1992 CertVerifyResult verify_result;
1993 int error = Verify(cert.get(), "127.0.0.1", flags, &verify_result);
1994 EXPECT_THAT(error, IsOk());
1995 EXPECT_EQ(0U, verify_result.cert_status);
1996
1997 scoped_refptr<CRLSet> crl_set;
1998 std::string crl_set_bytes;
1999
2000 // First test blocking by SPKI.
2001 EXPECT_TRUE(base::ReadFileToString(
2002 GetTestCertsDirectory().AppendASCII("crlset_by_leaf_spki.raw"),
2003 &crl_set_bytes));
2004 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
2005
2006 SetUpCertVerifyProc(crl_set);
2007 error = Verify(cert.get(), "127.0.0.1", flags, &verify_result);
2008 EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
2009
2010 // Second, test revocation by serial number of a cert directly under the
2011 // root.
2012 crl_set_bytes.clear();
2013 EXPECT_TRUE(base::ReadFileToString(
2014 GetTestCertsDirectory().AppendASCII("crlset_by_root_serial.raw"),
2015 &crl_set_bytes));
2016 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
2017
2018 SetUpCertVerifyProc(crl_set);
2019 error = Verify(cert.get(), "127.0.0.1", flags, &verify_result);
2020 EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
2021 }
2022
TEST_P(CertVerifyProcInternalTest,CRLSetLeafSerial)2023 TEST_P(CertVerifyProcInternalTest, CRLSetLeafSerial) {
2024 if (!SupportsCRLSet()) {
2025 LOG(INFO) << "Skipping test as verifier doesn't support CRLSet";
2026 return;
2027 }
2028
2029 CertificateList ca_cert_list =
2030 CreateCertificateListFromFile(GetTestCertsDirectory(), "root_ca_cert.pem",
2031 X509Certificate::FORMAT_AUTO);
2032 ASSERT_EQ(1U, ca_cert_list.size());
2033 ScopedTestRoot test_root(ca_cert_list[0]);
2034
2035 scoped_refptr<X509Certificate> leaf = CreateCertificateChainFromFile(
2036 GetTestCertsDirectory(), "ok_cert_by_intermediate.pem",
2037 X509Certificate::FORMAT_AUTO);
2038 ASSERT_TRUE(leaf);
2039 ASSERT_EQ(1U, leaf->intermediate_buffers().size());
2040
2041 int flags = 0;
2042 CertVerifyResult verify_result;
2043 int error = Verify(leaf.get(), "127.0.0.1", flags, &verify_result);
2044 EXPECT_THAT(error, IsOk());
2045
2046 // Test revocation by serial number of a certificate not under the root.
2047 scoped_refptr<CRLSet> crl_set;
2048 std::string crl_set_bytes;
2049 ASSERT_TRUE(base::ReadFileToString(
2050 GetTestCertsDirectory().AppendASCII("crlset_by_intermediate_serial.raw"),
2051 &crl_set_bytes));
2052 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
2053
2054 SetUpCertVerifyProc(crl_set);
2055 error = Verify(leaf.get(), "127.0.0.1", flags, &verify_result);
2056 EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
2057 }
2058
TEST_P(CertVerifyProcInternalTest,CRLSetRootReturnsChain)2059 TEST_P(CertVerifyProcInternalTest, CRLSetRootReturnsChain) {
2060 if (!SupportsCRLSet()) {
2061 LOG(INFO) << "Skipping test as verifier doesn't support CRLSet";
2062 return;
2063 }
2064
2065 CertificateList ca_cert_list =
2066 CreateCertificateListFromFile(GetTestCertsDirectory(), "root_ca_cert.pem",
2067 X509Certificate::FORMAT_AUTO);
2068 ASSERT_EQ(1U, ca_cert_list.size());
2069 ScopedTestRoot test_root(ca_cert_list[0]);
2070
2071 scoped_refptr<X509Certificate> leaf = CreateCertificateChainFromFile(
2072 GetTestCertsDirectory(), "ok_cert_by_intermediate.pem",
2073 X509Certificate::FORMAT_AUTO);
2074 ASSERT_TRUE(leaf);
2075 ASSERT_EQ(1U, leaf->intermediate_buffers().size());
2076
2077 int flags = 0;
2078 CertVerifyResult verify_result;
2079 int error = Verify(leaf.get(), "127.0.0.1", flags, &verify_result);
2080 EXPECT_THAT(error, IsOk());
2081
2082 // Test revocation of the root itself.
2083 scoped_refptr<CRLSet> crl_set;
2084 std::string crl_set_bytes;
2085 ASSERT_TRUE(base::ReadFileToString(
2086 GetTestCertsDirectory().AppendASCII("crlset_by_root_spki.raw"),
2087 &crl_set_bytes));
2088 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
2089
2090 SetUpCertVerifyProc(crl_set);
2091 error = Verify(leaf.get(), "127.0.0.1", flags, &verify_result);
2092 EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
2093
2094 EXPECT_EQ(3u, verify_result.public_key_hashes.size());
2095 ASSERT_TRUE(verify_result.verified_cert);
2096 EXPECT_EQ(2u, verify_result.verified_cert->intermediate_buffers().size());
2097 }
2098
2099 // Tests that CertVerifyProc implementations apply CRLSet revocations by
2100 // subject.
TEST_P(CertVerifyProcInternalTest,CRLSetRevokedBySubject)2101 TEST_P(CertVerifyProcInternalTest, CRLSetRevokedBySubject) {
2102 if (!SupportsCRLSet()) {
2103 LOG(INFO) << "Skipping test as verifier doesn't support CRLSet";
2104 return;
2105 }
2106
2107 scoped_refptr<X509Certificate> root(
2108 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem"));
2109 ASSERT_TRUE(root);
2110
2111 scoped_refptr<X509Certificate> leaf(
2112 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
2113 ASSERT_TRUE(leaf);
2114
2115 ScopedTestRoot scoped_root(root);
2116
2117 int flags = 0;
2118 CertVerifyResult verify_result;
2119
2120 // Confirm that verifying the certificate chain with an empty CRLSet succeeds.
2121 SetUpCertVerifyProc(CRLSet::EmptyCRLSetForTesting());
2122 int error = Verify(leaf.get(), "127.0.0.1", flags, &verify_result);
2123 EXPECT_THAT(error, IsOk());
2124
2125 std::string crl_set_bytes;
2126 scoped_refptr<CRLSet> crl_set;
2127
2128 // Revoke the leaf by subject. Verification should now fail.
2129 ASSERT_TRUE(base::ReadFileToString(
2130 GetTestCertsDirectory().AppendASCII("crlset_by_leaf_subject_no_spki.raw"),
2131 &crl_set_bytes));
2132 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
2133
2134 SetUpCertVerifyProc(crl_set);
2135 error = Verify(leaf.get(), "127.0.0.1", flags, &verify_result);
2136 EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
2137
2138 // Revoke the root by subject. Verification should now fail.
2139 ASSERT_TRUE(base::ReadFileToString(
2140 GetTestCertsDirectory().AppendASCII("crlset_by_root_subject_no_spki.raw"),
2141 &crl_set_bytes));
2142 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
2143
2144 SetUpCertVerifyProc(crl_set);
2145 error = Verify(leaf.get(), "127.0.0.1", flags, &verify_result);
2146 EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
2147
2148 // Revoke the leaf by subject, but only if the SPKI doesn't match the given
2149 // one. Verification should pass when using the certificate's actual SPKI.
2150 ASSERT_TRUE(base::ReadFileToString(
2151 GetTestCertsDirectory().AppendASCII("crlset_by_root_subject.raw"),
2152 &crl_set_bytes));
2153 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
2154
2155 SetUpCertVerifyProc(crl_set);
2156 error = Verify(leaf.get(), "127.0.0.1", flags, &verify_result);
2157 EXPECT_THAT(error, IsOk());
2158 }
2159
2160 // Ensures that CRLSets can be used to block known interception roots on
2161 // platforms that support CRLSets, while otherwise detect known interception
2162 // on platforms that do not.
TEST_P(CertVerifyProcInternalTest,BlockedInterceptionByRoot)2163 TEST_P(CertVerifyProcInternalTest, BlockedInterceptionByRoot) {
2164 scoped_refptr<X509Certificate> root =
2165 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem");
2166 ASSERT_TRUE(root);
2167 ScopedTestRoot test_root(root);
2168
2169 scoped_refptr<X509Certificate> cert = CreateCertificateChainFromFile(
2170 GetTestCertsDirectory(), "ok_cert_by_intermediate.pem",
2171 X509Certificate::FORMAT_AUTO);
2172 ASSERT_TRUE(cert);
2173
2174 // A default/built-in CRLSet should not block
2175 scoped_refptr<CRLSet> crl_set = CRLSet::BuiltinCRLSet();
2176 SetUpCertVerifyProc(crl_set);
2177 int flags = 0;
2178 CertVerifyResult verify_result;
2179 int error = Verify(cert.get(), "127.0.0.1", flags, &verify_result);
2180 EXPECT_THAT(error, IsOk());
2181 EXPECT_EQ(0U, verify_result.cert_status);
2182
2183 // Read in a CRLSet that marks the root as blocked for interception.
2184 std::string crl_set_bytes;
2185 ASSERT_TRUE(
2186 base::ReadFileToString(GetTestCertsDirectory().AppendASCII(
2187 "crlset_blocked_interception_by_root.raw"),
2188 &crl_set_bytes));
2189 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
2190
2191 SetUpCertVerifyProc(crl_set);
2192 error = Verify(cert.get(), "127.0.0.1", flags, &verify_result);
2193 if (SupportsCRLSet()) {
2194 EXPECT_THAT(error, IsError(ERR_CERT_KNOWN_INTERCEPTION_BLOCKED));
2195 EXPECT_TRUE(verify_result.cert_status &
2196 CERT_STATUS_KNOWN_INTERCEPTION_BLOCKED);
2197 } else {
2198 EXPECT_THAT(error, IsOk());
2199 EXPECT_TRUE(verify_result.cert_status &
2200 CERT_STATUS_KNOWN_INTERCEPTION_DETECTED);
2201 }
2202 }
2203
2204 // Ensures that CRLSets can be used to block known interception intermediates,
2205 // while still allowing other certificates from that root..
TEST_P(CertVerifyProcInternalTest,BlockedInterceptionByIntermediate)2206 TEST_P(CertVerifyProcInternalTest, BlockedInterceptionByIntermediate) {
2207 scoped_refptr<X509Certificate> root =
2208 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem");
2209 ASSERT_TRUE(root);
2210 ScopedTestRoot test_root(root);
2211
2212 scoped_refptr<X509Certificate> cert = CreateCertificateChainFromFile(
2213 GetTestCertsDirectory(), "ok_cert_by_intermediate.pem",
2214 X509Certificate::FORMAT_AUTO);
2215 ASSERT_TRUE(cert);
2216
2217 // A default/built-in CRLSEt should not block
2218 scoped_refptr<CRLSet> crl_set = CRLSet::BuiltinCRLSet();
2219 SetUpCertVerifyProc(crl_set);
2220 int flags = 0;
2221 CertVerifyResult verify_result;
2222 int error = Verify(cert.get(), "127.0.0.1", flags, &verify_result);
2223 EXPECT_THAT(error, IsOk());
2224 EXPECT_EQ(0U, verify_result.cert_status);
2225
2226 // Read in a CRLSet that marks the intermediate as blocked for interception.
2227 std::string crl_set_bytes;
2228 ASSERT_TRUE(base::ReadFileToString(
2229 GetTestCertsDirectory().AppendASCII(
2230 "crlset_blocked_interception_by_intermediate.raw"),
2231 &crl_set_bytes));
2232 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
2233
2234 SetUpCertVerifyProc(crl_set);
2235 error = Verify(cert.get(), "127.0.0.1", flags, &verify_result);
2236 if (SupportsCRLSet()) {
2237 EXPECT_THAT(error, IsError(ERR_CERT_KNOWN_INTERCEPTION_BLOCKED));
2238 EXPECT_TRUE(verify_result.cert_status &
2239 CERT_STATUS_KNOWN_INTERCEPTION_BLOCKED);
2240 } else {
2241 EXPECT_THAT(error, IsOk());
2242 EXPECT_TRUE(verify_result.cert_status &
2243 CERT_STATUS_KNOWN_INTERCEPTION_DETECTED);
2244 }
2245
2246 // Load a different certificate from that root, which should be unaffected.
2247 scoped_refptr<X509Certificate> second_cert = CreateCertificateChainFromFile(
2248 GetTestCertsDirectory(), "ok_cert.pem", X509Certificate::FORMAT_AUTO);
2249 ASSERT_TRUE(second_cert);
2250
2251 SetUpCertVerifyProc(crl_set);
2252 error = Verify(second_cert.get(), "127.0.0.1", flags, &verify_result);
2253 EXPECT_THAT(error, IsOk());
2254 EXPECT_EQ(0U, verify_result.cert_status);
2255 }
2256
2257 // Ensures that CRLSets can be used to flag known interception roots, even
2258 // when they are not blocked.
TEST_P(CertVerifyProcInternalTest,DetectsInterceptionByRoot)2259 TEST_P(CertVerifyProcInternalTest, DetectsInterceptionByRoot) {
2260 scoped_refptr<X509Certificate> root =
2261 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem");
2262 ASSERT_TRUE(root);
2263 ScopedTestRoot test_root(root);
2264
2265 scoped_refptr<X509Certificate> cert = CreateCertificateChainFromFile(
2266 GetTestCertsDirectory(), "ok_cert_by_intermediate.pem",
2267 X509Certificate::FORMAT_AUTO);
2268 ASSERT_TRUE(cert);
2269
2270 // A default/built-in CRLSet should not block
2271 scoped_refptr<CRLSet> crl_set = CRLSet::BuiltinCRLSet();
2272 SetUpCertVerifyProc(crl_set);
2273 int flags = 0;
2274 CertVerifyResult verify_result;
2275 int error = Verify(cert.get(), "127.0.0.1", flags, &verify_result);
2276 EXPECT_THAT(error, IsOk());
2277 EXPECT_EQ(0U, verify_result.cert_status);
2278
2279 // Read in a CRLSet that marks the root as blocked for interception.
2280 std::string crl_set_bytes;
2281 ASSERT_TRUE(
2282 base::ReadFileToString(GetTestCertsDirectory().AppendASCII(
2283 "crlset_known_interception_by_root.raw"),
2284 &crl_set_bytes));
2285 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
2286
2287 SetUpCertVerifyProc(crl_set);
2288 error = Verify(cert.get(), "127.0.0.1", flags, &verify_result);
2289 EXPECT_THAT(error, IsOk());
2290 EXPECT_TRUE(verify_result.cert_status &
2291 CERT_STATUS_KNOWN_INTERCEPTION_DETECTED);
2292 }
2293
2294 // Tests that CRLSets participate in path building functions, and that as
2295 // long as a valid path exists within the verification graph, verification
2296 // succeeds.
2297 //
2298 // In this test, there are two roots (D and E), and three possible paths
2299 // to validate a leaf (A):
2300 // 1. A(B) -> B(C) -> C(D) -> D(D)
2301 // 2. A(B) -> B(C) -> C(E) -> E(E)
2302 // 3. A(B) -> B(F) -> F(E) -> E(E)
2303 //
2304 // Each permutation of revocation is tried:
2305 // 1. Revoking E by SPKI, so that only Path 1 is valid (as E is in Paths 2 & 3)
2306 // 2. Revoking C(D) and F(E) by serial, so that only Path 2 is valid.
2307 // 3. Revoking C by SPKI, so that only Path 3 is valid (as C is in Paths 1 & 2)
TEST_P(CertVerifyProcInternalTest,CRLSetDuringPathBuilding)2308 TEST_P(CertVerifyProcInternalTest, CRLSetDuringPathBuilding) {
2309 if (!SupportsCRLSetsInPathBuilding()) {
2310 LOG(INFO) << "Skipping this test on this platform.";
2311 return;
2312 }
2313
2314 CertificateList path_1_certs;
2315 ASSERT_TRUE(
2316 LoadCertificateFiles({"multi-root-A-by-B.pem", "multi-root-B-by-C.pem",
2317 "multi-root-C-by-D.pem", "multi-root-D-by-D.pem"},
2318 &path_1_certs));
2319
2320 CertificateList path_2_certs;
2321 ASSERT_TRUE(
2322 LoadCertificateFiles({"multi-root-A-by-B.pem", "multi-root-B-by-C.pem",
2323 "multi-root-C-by-E.pem", "multi-root-E-by-E.pem"},
2324 &path_2_certs));
2325
2326 CertificateList path_3_certs;
2327 ASSERT_TRUE(
2328 LoadCertificateFiles({"multi-root-A-by-B.pem", "multi-root-B-by-F.pem",
2329 "multi-root-F-by-E.pem", "multi-root-E-by-E.pem"},
2330 &path_3_certs));
2331
2332 // Add D and E as trust anchors.
2333 ScopedTestRoot test_root_D(path_1_certs[3]); // D-by-D
2334 ScopedTestRoot test_root_E(path_2_certs[3]); // E-by-E
2335
2336 // Create a chain that contains all the certificate paths possible.
2337 // CertVerifyProcInternalTest.VerifyReturnChainFiltersUnrelatedCerts already
2338 // ensures that it's safe to send additional certificates as inputs, and
2339 // that they're ignored if not necessary.
2340 // This is to avoid relying on AIA or internal object caches when
2341 // interacting with the underlying library.
2342 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
2343 intermediates.push_back(
2344 bssl::UpRef(path_1_certs[1]->cert_buffer())); // B-by-C
2345 intermediates.push_back(
2346 bssl::UpRef(path_1_certs[2]->cert_buffer())); // C-by-D
2347 intermediates.push_back(
2348 bssl::UpRef(path_2_certs[2]->cert_buffer())); // C-by-E
2349 intermediates.push_back(
2350 bssl::UpRef(path_3_certs[1]->cert_buffer())); // B-by-F
2351 intermediates.push_back(
2352 bssl::UpRef(path_3_certs[2]->cert_buffer())); // F-by-E
2353 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromBuffer(
2354 bssl::UpRef(path_1_certs[0]->cert_buffer()), std::move(intermediates));
2355 ASSERT_TRUE(cert);
2356
2357 struct TestPermutations {
2358 const char* crlset;
2359 bool expect_valid;
2360 scoped_refptr<X509Certificate> expected_intermediate;
2361 } kTests[] = {
2362 {"multi-root-crlset-D-and-E.raw", false, nullptr},
2363 {"multi-root-crlset-E.raw", true, path_1_certs[2].get()},
2364 {"multi-root-crlset-CD-and-FE.raw", true, path_2_certs[2].get()},
2365 {"multi-root-crlset-C.raw", true, path_3_certs[2].get()},
2366 {"multi-root-crlset-unrelated.raw", true, nullptr}};
2367
2368 for (const auto& testcase : kTests) {
2369 SCOPED_TRACE(testcase.crlset);
2370 scoped_refptr<CRLSet> crl_set;
2371 std::string crl_set_bytes;
2372 EXPECT_TRUE(base::ReadFileToString(
2373 GetTestCertsDirectory().AppendASCII(testcase.crlset), &crl_set_bytes));
2374 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
2375
2376 SetUpCertVerifyProc(crl_set);
2377 int flags = 0;
2378 CertVerifyResult verify_result;
2379 int error = Verify(cert.get(), "127.0.0.1", flags, &verify_result);
2380
2381 if (!testcase.expect_valid) {
2382 EXPECT_NE(OK, error);
2383 EXPECT_NE(0U, verify_result.cert_status);
2384 continue;
2385 }
2386
2387 ASSERT_THAT(error, IsOk());
2388 ASSERT_EQ(0U, verify_result.cert_status);
2389 ASSERT_TRUE(verify_result.verified_cert.get());
2390
2391 if (!testcase.expected_intermediate)
2392 continue;
2393
2394 const auto& verified_intermediates =
2395 verify_result.verified_cert->intermediate_buffers();
2396 ASSERT_EQ(3U, verified_intermediates.size());
2397
2398 scoped_refptr<X509Certificate> intermediate =
2399 X509Certificate::CreateFromBuffer(
2400 bssl::UpRef(verified_intermediates[1].get()), {});
2401 ASSERT_TRUE(intermediate);
2402
2403 EXPECT_TRUE(testcase.expected_intermediate->EqualsExcludingChain(
2404 intermediate.get()))
2405 << "Expected: " << testcase.expected_intermediate->subject().common_name
2406 << " issued by " << testcase.expected_intermediate->issuer().common_name
2407 << "; Got: " << intermediate->subject().common_name << " issued by "
2408 << intermediate->issuer().common_name;
2409 }
2410 }
2411
TEST_P(CertVerifyProcInternalTest,ValidityDayPlus5MinutesBeforeNotBefore)2412 TEST_P(CertVerifyProcInternalTest, ValidityDayPlus5MinutesBeforeNotBefore) {
2413 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
2414 base::Time not_before = base::Time::Now() + base::Days(1) + base::Minutes(5);
2415 base::Time not_after = base::Time::Now() + base::Days(30);
2416 leaf->SetValidity(not_before, not_after);
2417
2418 // Trust the root and build a chain to verify that includes the intermediate.
2419 ScopedTestRoot scoped_root(root->GetX509Certificate());
2420 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
2421 ASSERT_TRUE(chain.get());
2422
2423 int flags = 0;
2424 CertVerifyResult verify_result;
2425 int error = Verify(chain.get(), "www.example.com", flags, &verify_result);
2426 // Current time is before certificate's notBefore. Verification should fail.
2427 EXPECT_THAT(error, IsError(ERR_CERT_DATE_INVALID));
2428 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_DATE_INVALID);
2429 }
2430
TEST_P(CertVerifyProcInternalTest,ValidityDayBeforeNotBefore)2431 TEST_P(CertVerifyProcInternalTest, ValidityDayBeforeNotBefore) {
2432 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
2433 base::Time not_before = base::Time::Now() + base::Days(1);
2434 base::Time not_after = base::Time::Now() + base::Days(30);
2435 leaf->SetValidity(not_before, not_after);
2436
2437 // Trust the root and build a chain to verify that includes the intermediate.
2438 ScopedTestRoot scoped_root(root->GetX509Certificate());
2439 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
2440 ASSERT_TRUE(chain.get());
2441
2442 int flags = 0;
2443 CertVerifyResult verify_result;
2444 int error = Verify(chain.get(), "www.example.com", flags, &verify_result);
2445 // Current time is before certificate's notBefore. Verification should fail.
2446 EXPECT_THAT(error, IsError(ERR_CERT_DATE_INVALID));
2447 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_DATE_INVALID);
2448 }
2449
TEST_P(CertVerifyProcInternalTest,ValidityJustBeforeNotBefore)2450 TEST_P(CertVerifyProcInternalTest, ValidityJustBeforeNotBefore) {
2451 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
2452 base::Time not_before = base::Time::Now() + base::Minutes(5);
2453 base::Time not_after = base::Time::Now() + base::Days(30);
2454 leaf->SetValidity(not_before, not_after);
2455
2456 // Trust the root and build a chain to verify that includes the intermediate.
2457 ScopedTestRoot scoped_root(root->GetX509Certificate());
2458 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
2459 ASSERT_TRUE(chain.get());
2460
2461 int flags = 0;
2462 CertVerifyResult verify_result;
2463 int error = Verify(chain.get(), "www.example.com", flags, &verify_result);
2464 // Current time is before certificate's notBefore. Verification should fail.
2465 EXPECT_THAT(error, IsError(ERR_CERT_DATE_INVALID));
2466 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_DATE_INVALID);
2467 }
2468
TEST_P(CertVerifyProcInternalTest,ValidityJustAfterNotBefore)2469 TEST_P(CertVerifyProcInternalTest, ValidityJustAfterNotBefore) {
2470 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
2471 base::Time not_before = base::Time::Now() - base::Seconds(1);
2472 base::Time not_after = base::Time::Now() + base::Days(30);
2473 leaf->SetValidity(not_before, not_after);
2474
2475 // Trust the root and build a chain to verify that includes the intermediate.
2476 ScopedTestRoot scoped_root(root->GetX509Certificate());
2477 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
2478 ASSERT_TRUE(chain.get());
2479
2480 int flags = 0;
2481 CertVerifyResult verify_result;
2482 int error = Verify(chain.get(), "www.example.com", flags, &verify_result);
2483 // Current time is between notBefore and notAfter. Verification should
2484 // succeed.
2485 EXPECT_THAT(error, IsOk());
2486 }
2487
TEST_P(CertVerifyProcInternalTest,ValidityJustBeforeNotAfter)2488 TEST_P(CertVerifyProcInternalTest, ValidityJustBeforeNotAfter) {
2489 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
2490 base::Time not_before = base::Time::Now() - base::Days(30);
2491 base::Time not_after = base::Time::Now() + base::Minutes(5);
2492 leaf->SetValidity(not_before, not_after);
2493
2494 // Trust the root and build a chain to verify that includes the intermediate.
2495 ScopedTestRoot scoped_root(root->GetX509Certificate());
2496 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
2497 ASSERT_TRUE(chain.get());
2498
2499 int flags = 0;
2500 CertVerifyResult verify_result;
2501 int error = Verify(chain.get(), "www.example.com", flags, &verify_result);
2502 // Current time is between notBefore and notAfter. Verification should
2503 // succeed.
2504 EXPECT_THAT(error, IsOk());
2505 }
2506
TEST_P(CertVerifyProcInternalTest,ValidityJustAfterNotAfter)2507 TEST_P(CertVerifyProcInternalTest, ValidityJustAfterNotAfter) {
2508 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
2509 base::Time not_before = base::Time::Now() - base::Days(30);
2510 base::Time not_after = base::Time::Now() - base::Seconds(1);
2511 leaf->SetValidity(not_before, not_after);
2512
2513 // Trust the root and build a chain to verify that includes the intermediate.
2514 ScopedTestRoot scoped_root(root->GetX509Certificate());
2515 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
2516 ASSERT_TRUE(chain.get());
2517
2518 int flags = 0;
2519 CertVerifyResult verify_result;
2520 int error = Verify(chain.get(), "www.example.com", flags, &verify_result);
2521 // Current time is after certificate's notAfter. Verification should fail.
2522 EXPECT_THAT(error, IsError(ERR_CERT_DATE_INVALID));
2523 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_DATE_INVALID);
2524 }
2525
TEST_P(CertVerifyProcInternalTest,FailedIntermediateSignatureValidation)2526 TEST_P(CertVerifyProcInternalTest, FailedIntermediateSignatureValidation) {
2527 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
2528
2529 // Intermediate has no authorityKeyIdentifier. Also remove
2530 // subjectKeyIdentifier from root for good measure.
2531 intermediate->EraseExtension(
2532 bssl::der::Input(bssl::kAuthorityKeyIdentifierOid));
2533 root->EraseExtension(bssl::der::Input(bssl::kSubjectKeyIdentifierOid));
2534
2535 // Get the chain with the leaf and the intermediate signed by the original
2536 // key of |root|.
2537 scoped_refptr<X509Certificate> cert = leaf->GetX509CertificateChain();
2538
2539 // Generate a new key for root.
2540 root->GenerateECKey();
2541
2542 // Trust the new root certificate.
2543 ScopedTestRoot scoped_root(root->GetX509Certificate());
2544
2545 int flags = 0;
2546 CertVerifyResult verify_result;
2547 int error = Verify(cert.get(), "www.example.com", flags, &verify_result);
2548
2549 // The intermediate was signed by a different root with a different key but
2550 // with the same name as the trusted one, and the intermediate has no
2551 // authorityKeyIdentifier, so the verifier must try verifying the signature.
2552 // Should fail with AUTHORITY_INVALID.
2553 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID);
2554 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
2555 }
2556
TEST_P(CertVerifyProcInternalTest,FailedTargetSignatureValidation)2557 TEST_P(CertVerifyProcInternalTest, FailedTargetSignatureValidation) {
2558 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
2559
2560 // Leaf has no authorityKeyIdentifier. Also remove subjectKeyIdentifier from
2561 // intermediate for good measure.
2562 leaf->EraseExtension(bssl::der::Input(bssl::kAuthorityKeyIdentifierOid));
2563 intermediate->EraseExtension(
2564 bssl::der::Input(bssl::kSubjectKeyIdentifierOid));
2565
2566 // Get a copy of the leaf signed by the original key of intermediate.
2567 bssl::UniquePtr<CRYPTO_BUFFER> leaf_wrong_signature = leaf->DupCertBuffer();
2568
2569 // Generate a new key for intermediate.
2570 intermediate->GenerateECKey();
2571
2572 // Make a chain that includes the original leaf with the wrong signature and
2573 // the new intermediate.
2574 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
2575 intermediates.push_back(intermediate->DupCertBuffer());
2576
2577 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromBuffer(
2578 bssl::UpRef(leaf_wrong_signature), std::move(intermediates));
2579 ASSERT_TRUE(cert.get());
2580
2581 // Trust the root certificate.
2582 ScopedTestRoot scoped_root(root->GetX509Certificate());
2583
2584 int flags = 0;
2585 CertVerifyResult verify_result;
2586 int error = Verify(cert.get(), "www.example.com", flags, &verify_result);
2587
2588 // The leaf was signed by a different intermediate with a different key but
2589 // with the same name as the one in the chain, and the leaf has no
2590 // authorityKeyIdentifier, so the verifier must try verifying the signature.
2591 // Should fail with AUTHORITY_INVALID.
2592 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID);
2593 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
2594 }
2595
2596 class CertVerifyProcNameNormalizationTest : public CertVerifyProcInternalTest {
2597 protected:
HistogramName() const2598 std::string HistogramName() const {
2599 std::string prefix("Net.CertVerifier.NameNormalizationPrivateRoots.");
2600 switch (verify_proc_type()) {
2601 case CERT_VERIFY_PROC_ANDROID:
2602 return prefix + "Android";
2603 case CERT_VERIFY_PROC_IOS:
2604 return prefix + "IOS";
2605 case CERT_VERIFY_PROC_BUILTIN:
2606 case CERT_VERIFY_PROC_BUILTIN_CHROME_ROOTS:
2607 return prefix + "Builtin";
2608 }
2609 }
2610
ExpectNormalizationHistogram(int verify_error)2611 void ExpectNormalizationHistogram(int verify_error) {
2612 if (verify_error == OK) {
2613 histograms_.ExpectUniqueSample(
2614 HistogramName(), CertVerifyProc::NameNormalizationResult::kNormalized,
2615 1);
2616 } else {
2617 histograms_.ExpectTotalCount(HistogramName(), 0);
2618 }
2619 }
2620
ExpectByteEqualHistogram()2621 void ExpectByteEqualHistogram() {
2622 histograms_.ExpectUniqueSample(
2623 HistogramName(), CertVerifyProc::NameNormalizationResult::kByteEqual,
2624 1);
2625 }
2626
2627 private:
2628 base::HistogramTester histograms_;
2629 };
2630
2631 INSTANTIATE_TEST_SUITE_P(All,
2632 CertVerifyProcNameNormalizationTest,
2633 testing::ValuesIn(kAllCertVerifiers),
2634 VerifyProcTypeToName);
2635
2636 // Tries to verify a chain where the leaf's issuer CN is PrintableString, while
2637 // the intermediate's subject CN is UTF8String, and verifies the proper
2638 // histogram is logged.
TEST_P(CertVerifyProcNameNormalizationTest,StringType)2639 TEST_P(CertVerifyProcNameNormalizationTest, StringType) {
2640 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
2641
2642 std::string issuer_cn = CertBuilder::MakeRandomHexString(12);
2643 leaf->SetIssuerTLV(CertBuilder::BuildNameWithCommonNameOfType(
2644 issuer_cn, CBS_ASN1_PRINTABLESTRING));
2645 intermediate->SetSubjectTLV(CertBuilder::BuildNameWithCommonNameOfType(
2646 issuer_cn, CBS_ASN1_UTF8STRING));
2647
2648 ScopedTestRoot scoped_root(root->GetX509Certificate());
2649
2650 int flags = 0;
2651 CertVerifyResult verify_result;
2652 int error = Verify(leaf->GetX509CertificateChain().get(), "www.example.com",
2653 flags, &verify_result);
2654
2655 switch (verify_proc_type()) {
2656 case CERT_VERIFY_PROC_IOS:
2657 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
2658 break;
2659 case CERT_VERIFY_PROC_ANDROID:
2660 case CERT_VERIFY_PROC_BUILTIN:
2661 case CERT_VERIFY_PROC_BUILTIN_CHROME_ROOTS:
2662 EXPECT_THAT(error, IsOk());
2663 break;
2664 }
2665
2666 ExpectNormalizationHistogram(error);
2667 }
2668
2669 // Tries to verify a chain where the leaf's issuer CN and intermediate's
2670 // subject CN are both PrintableString but have differing case on the first
2671 // character, and verifies the proper histogram is logged.
TEST_P(CertVerifyProcNameNormalizationTest,CaseFolding)2672 TEST_P(CertVerifyProcNameNormalizationTest, CaseFolding) {
2673 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
2674
2675 std::string issuer_hex = CertBuilder::MakeRandomHexString(12);
2676 leaf->SetIssuerTLV(CertBuilder::BuildNameWithCommonNameOfType(
2677 "Z" + issuer_hex, CBS_ASN1_PRINTABLESTRING));
2678 intermediate->SetSubjectTLV(CertBuilder::BuildNameWithCommonNameOfType(
2679 "z" + issuer_hex, CBS_ASN1_PRINTABLESTRING));
2680
2681 ScopedTestRoot scoped_root(root->GetX509Certificate());
2682
2683 int flags = 0;
2684 CertVerifyResult verify_result;
2685 int error = Verify(leaf->GetX509CertificateChain().get(), "www.example.com",
2686 flags, &verify_result);
2687
2688 EXPECT_THAT(error, IsOk());
2689 ExpectNormalizationHistogram(error);
2690 }
2691
2692 // Confirms that a chain generated by the same pattern as the other
2693 // NameNormalizationTest cases which does not require normalization validates
2694 // ok, and that the ByteEqual histogram is logged.
TEST_P(CertVerifyProcNameNormalizationTest,ByteEqual)2695 TEST_P(CertVerifyProcNameNormalizationTest, ByteEqual) {
2696 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
2697
2698 std::string issuer_hex = CertBuilder::MakeRandomHexString(12);
2699 leaf->SetIssuerTLV(CertBuilder::BuildNameWithCommonNameOfType(
2700 issuer_hex, CBS_ASN1_PRINTABLESTRING));
2701 intermediate->SetSubjectTLV(CertBuilder::BuildNameWithCommonNameOfType(
2702 issuer_hex, CBS_ASN1_PRINTABLESTRING));
2703
2704 ScopedTestRoot scoped_root(root->GetX509Certificate());
2705
2706 int flags = 0;
2707 CertVerifyResult verify_result;
2708 int error = Verify(leaf->GetX509CertificateChain().get(), "www.example.com",
2709 flags, &verify_result);
2710
2711 EXPECT_THAT(error, IsOk());
2712 ExpectByteEqualHistogram();
2713 }
2714
Md5WithRSAEncryption()2715 std::string Md5WithRSAEncryption() {
2716 const uint8_t kMd5WithRSAEncryption[] = {0x30, 0x0d, 0x06, 0x09, 0x2a,
2717 0x86, 0x48, 0x86, 0xf7, 0x0d,
2718 0x01, 0x01, 0x04, 0x05, 0x00};
2719 return std::string(std::begin(kMd5WithRSAEncryption),
2720 std::end(kMd5WithRSAEncryption));
2721 }
2722
2723 // This is the same as CertVerifyProcInternalTest, but it additionally sets up
2724 // networking capabilities for the cert verifiers, and a test server that can be
2725 // used to serve mock responses for AIA/OCSP/CRL.
2726 //
2727 // An actual HTTP test server is used rather than simply mocking the network
2728 // layer, since the certificate fetching networking layer is not mockable for
2729 // all of the cert verifier implementations.
2730 //
2731 // The approach taken in this test fixture is to generate certificates
2732 // on the fly so they use randomly chosen URLs, subjects, and serial
2733 // numbers, in order to defeat global caching effects from the platform
2734 // verifiers. Moreover, the AIA needs to be chosen dynamically since the
2735 // test server's port number cannot be known statically.
2736 class CertVerifyProcInternalWithNetFetchingTest
2737 : public CertVerifyProcInternalTest {
2738 protected:
CertVerifyProcInternalWithNetFetchingTest()2739 CertVerifyProcInternalWithNetFetchingTest()
2740 : task_environment_(
2741 base::test::TaskEnvironment::MainThreadType::DEFAULT) {}
2742
SetUp()2743 void SetUp() override {
2744 // Create a network thread to be used for network fetches, and wait for
2745 // initialization to complete on that thread.
2746 base::Thread::Options options(base::MessagePumpType::IO, 0);
2747 network_thread_ = std::make_unique<base::Thread>("network_thread");
2748 CHECK(network_thread_->StartWithOptions(std::move(options)));
2749
2750 base::WaitableEvent initialization_complete_event(
2751 base::WaitableEvent::ResetPolicy::MANUAL,
2752 base::WaitableEvent::InitialState::NOT_SIGNALED);
2753 network_thread_->task_runner()->PostTask(
2754 FROM_HERE,
2755 base::BindOnce(&SetUpOnNetworkThread, &context_, &cert_net_fetcher_,
2756 &initialization_complete_event));
2757 initialization_complete_event.Wait();
2758 EXPECT_TRUE(cert_net_fetcher_);
2759
2760 CertVerifyProcInternalTest::SetUp();
2761
2762 EXPECT_FALSE(test_server_.Started());
2763
2764 // Register a single request handler with the EmbeddedTestServer, that in
2765 // turn dispatches to the internally managed registry of request handlers.
2766 //
2767 // This allows registering subsequent handlers dynamically during the course
2768 // of the test, since EmbeddedTestServer requires its handlers be registered
2769 // prior to Start().
2770 test_server_.RegisterRequestHandler(base::BindRepeating(
2771 &CertVerifyProcInternalWithNetFetchingTest::DispatchToRequestHandler,
2772 base::Unretained(this)));
2773 EXPECT_TRUE(test_server_.Start());
2774 }
2775
SetUpCertVerifyProc(scoped_refptr<CRLSet> crl_set)2776 void SetUpCertVerifyProc(scoped_refptr<CRLSet> crl_set) override {
2777 EXPECT_TRUE(cert_net_fetcher_);
2778 SetUpWithCertNetFetcher(cert_net_fetcher_, std::move(crl_set),
2779 /*additional_trust_anchors=*/{},
2780 /*additional_untrusted_authorities=*/{});
2781 }
2782
TearDown()2783 void TearDown() override {
2784 // Do cleanup on network thread.
2785 network_thread_->task_runner()->PostTask(
2786 FROM_HERE, base::BindOnce(&ShutdownOnNetworkThread, &context_,
2787 &cert_net_fetcher_));
2788 network_thread_->Stop();
2789 network_thread_.reset();
2790
2791 CertVerifyProcInternalTest::TearDown();
2792 }
2793
2794 // Registers a handler with the test server that responds with the given
2795 // Content-Type, HTTP status code, and response body, for GET requests
2796 // to |path|.
2797 // Returns the full URL to |path| for the current test server.
RegisterSimpleTestServerHandler(std::string path,HttpStatusCode status_code,std::string content_type,std::string content)2798 GURL RegisterSimpleTestServerHandler(std::string path,
2799 HttpStatusCode status_code,
2800 std::string content_type,
2801 std::string content) {
2802 GURL handler_url(GetTestServerAbsoluteUrl(path));
2803 base::AutoLock lock(request_handlers_lock_);
2804 request_handlers_.push_back(base::BindRepeating(
2805 &SimpleTestServerHandler, std::move(path), status_code,
2806 std::move(content_type), std::move(content)));
2807 return handler_url;
2808 }
2809
2810 // Returns a random URL path (starting with /) that has the given suffix.
MakeRandomPath(std::string_view suffix)2811 static std::string MakeRandomPath(std::string_view suffix) {
2812 return "/" + MakeRandomHexString(12) + std::string(suffix);
2813 }
2814
2815 // Returns a URL to |path| for the current test server.
GetTestServerAbsoluteUrl(const std::string & path)2816 GURL GetTestServerAbsoluteUrl(const std::string& path) {
2817 return test_server_.GetURL(path);
2818 }
2819
2820 // Creates a certificate chain for www.example.com, where the leaf certificate
2821 // has an AIA URL pointing to the test server.
CreateSimpleChainWithAIA(scoped_refptr<X509Certificate> * out_leaf,std::string * ca_issuers_path,bssl::UniquePtr<CRYPTO_BUFFER> * out_intermediate,scoped_refptr<X509Certificate> * out_root)2822 void CreateSimpleChainWithAIA(
2823 scoped_refptr<X509Certificate>* out_leaf,
2824 std::string* ca_issuers_path,
2825 bssl::UniquePtr<CRYPTO_BUFFER>* out_intermediate,
2826 scoped_refptr<X509Certificate>* out_root) {
2827 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
2828
2829 // Make the leaf certificate have an AIA (CA Issuers) that points to the
2830 // embedded test server. This uses a random URL for predictable behavior in
2831 // the presence of global caching.
2832 *ca_issuers_path = MakeRandomPath(".cer");
2833 GURL ca_issuers_url = GetTestServerAbsoluteUrl(*ca_issuers_path);
2834 leaf->SetCaIssuersUrl(ca_issuers_url);
2835
2836 // The chain being verified is solely the leaf certificate (missing the
2837 // intermediate and root).
2838 *out_leaf = leaf->GetX509Certificate();
2839 *out_root = root->GetX509Certificate();
2840 *out_intermediate = intermediate->DupCertBuffer();
2841 }
2842
2843 // Creates a CRL issued and signed by |crl_issuer|, marking |revoked_serials|
2844 // as revoked, and registers it to be served by the test server.
2845 // Returns the full URL to retrieve the CRL from the test server.
CreateAndServeCrl(CertBuilder * crl_issuer,const std::vector<uint64_t> & revoked_serials,std::optional<bssl::SignatureAlgorithm> signature_algorithm=std::nullopt)2846 GURL CreateAndServeCrl(CertBuilder* crl_issuer,
2847 const std::vector<uint64_t>& revoked_serials,
2848 std::optional<bssl::SignatureAlgorithm>
2849 signature_algorithm = std::nullopt) {
2850 std::string crl = BuildCrl(crl_issuer->GetSubject(), crl_issuer->GetKey(),
2851 revoked_serials, signature_algorithm);
2852 std::string crl_path = MakeRandomPath(".crl");
2853 return RegisterSimpleTestServerHandler(crl_path, HTTP_OK,
2854 "application/pkix-crl", crl);
2855 }
2856
CreateAndServeCrlWithAlgorithmTlvAndDigest(CertBuilder * crl_issuer,const std::vector<uint64_t> & revoked_serials,const std::string & signature_algorithm_tlv,const EVP_MD * digest)2857 GURL CreateAndServeCrlWithAlgorithmTlvAndDigest(
2858 CertBuilder* crl_issuer,
2859 const std::vector<uint64_t>& revoked_serials,
2860 const std::string& signature_algorithm_tlv,
2861 const EVP_MD* digest) {
2862 std::string crl = BuildCrlWithAlgorithmTlvAndDigest(
2863 crl_issuer->GetSubject(), crl_issuer->GetKey(), revoked_serials,
2864 signature_algorithm_tlv, digest);
2865 std::string crl_path = MakeRandomPath(".crl");
2866 return RegisterSimpleTestServerHandler(crl_path, HTTP_OK,
2867 "application/pkix-crl", crl);
2868 }
2869
2870 private:
DispatchToRequestHandler(const test_server::HttpRequest & request)2871 std::unique_ptr<test_server::HttpResponse> DispatchToRequestHandler(
2872 const test_server::HttpRequest& request) {
2873 // Called on the embedded test server's IO thread.
2874 base::AutoLock lock(request_handlers_lock_);
2875 for (const auto& handler : request_handlers_) {
2876 auto response = handler.Run(request);
2877 if (response)
2878 return response;
2879 }
2880
2881 return nullptr;
2882 }
2883
2884 // Serves (|status_code|, |content_type|, |content|) in response to GET
2885 // requests for |path|.
SimpleTestServerHandler(const std::string & path,HttpStatusCode status_code,const std::string & content_type,const std::string & content,const test_server::HttpRequest & request)2886 static std::unique_ptr<test_server::HttpResponse> SimpleTestServerHandler(
2887 const std::string& path,
2888 HttpStatusCode status_code,
2889 const std::string& content_type,
2890 const std::string& content,
2891 const test_server::HttpRequest& request) {
2892 if (request.relative_url != path)
2893 return nullptr;
2894
2895 auto http_response = std::make_unique<test_server::BasicHttpResponse>();
2896
2897 http_response->set_code(status_code);
2898 http_response->set_content_type(content_type);
2899 http_response->set_content(content);
2900 return http_response;
2901 }
2902
SetUpOnNetworkThread(std::unique_ptr<URLRequestContext> * context,scoped_refptr<CertNetFetcherURLRequest> * cert_net_fetcher,base::WaitableEvent * initialization_complete_event)2903 static void SetUpOnNetworkThread(
2904 std::unique_ptr<URLRequestContext>* context,
2905 scoped_refptr<CertNetFetcherURLRequest>* cert_net_fetcher,
2906 base::WaitableEvent* initialization_complete_event) {
2907 URLRequestContextBuilder url_request_context_builder;
2908 url_request_context_builder.set_user_agent("cert_verify_proc_unittest/0.1");
2909 url_request_context_builder.set_proxy_config_service(
2910 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation()));
2911 *context = url_request_context_builder.Build();
2912
2913 *cert_net_fetcher = base::MakeRefCounted<net::CertNetFetcherURLRequest>();
2914 (*cert_net_fetcher)->SetURLRequestContext(context->get());
2915 initialization_complete_event->Signal();
2916 }
2917
ShutdownOnNetworkThread(std::unique_ptr<URLRequestContext> * context,scoped_refptr<net::CertNetFetcherURLRequest> * cert_net_fetcher)2918 static void ShutdownOnNetworkThread(
2919 std::unique_ptr<URLRequestContext>* context,
2920 scoped_refptr<net::CertNetFetcherURLRequest>* cert_net_fetcher) {
2921 (*cert_net_fetcher)->Shutdown();
2922 cert_net_fetcher->reset();
2923 context->reset();
2924 }
2925
2926 base::test::TaskEnvironment task_environment_;
2927
2928 std::unique_ptr<base::Thread> network_thread_;
2929
2930 // Owned by this thread, but initialized, used, and shutdown on the network
2931 // thread.
2932 std::unique_ptr<URLRequestContext> context_;
2933 scoped_refptr<CertNetFetcherURLRequest> cert_net_fetcher_;
2934
2935 EmbeddedTestServer test_server_;
2936
2937 // The list of registered handlers. Can only be accessed when the lock is
2938 // held, as this data is shared between the embedded server's IO thread, and
2939 // the test main thread.
2940 base::Lock request_handlers_lock_;
2941 std::vector<test_server::EmbeddedTestServer::HandleRequestCallback>
2942 request_handlers_;
2943 };
2944
2945 INSTANTIATE_TEST_SUITE_P(All,
2946 CertVerifyProcInternalWithNetFetchingTest,
2947 testing::ValuesIn(kAllCertVerifiers),
2948 VerifyProcTypeToName);
2949
2950 // Tries verifying a certificate chain that is missing an intermediate. The
2951 // intermediate is available via AIA, however the server responds with a 404.
2952 //
2953 // NOTE: This test is separate from IntermediateFromAia200 as a different URL
2954 // needs to be used to avoid having the result depend on globally cached success
2955 // or failure of the fetch.
2956 // Test is flaky on iOS crbug.com/860189
2957 #if BUILDFLAG(IS_IOS)
2958 #define MAYBE_IntermediateFromAia404 DISABLED_IntermediateFromAia404
2959 #else
2960 #define MAYBE_IntermediateFromAia404 IntermediateFromAia404
2961 #endif
TEST_P(CertVerifyProcInternalWithNetFetchingTest,MAYBE_IntermediateFromAia404)2962 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
2963 MAYBE_IntermediateFromAia404) {
2964 const char kHostname[] = "www.example.com";
2965
2966 // Create a chain where the leaf has an AIA that points to test server.
2967 scoped_refptr<X509Certificate> leaf;
2968 std::string ca_issuers_path;
2969 bssl::UniquePtr<CRYPTO_BUFFER> intermediate;
2970 scoped_refptr<X509Certificate> root;
2971 CreateSimpleChainWithAIA(&leaf, &ca_issuers_path, &intermediate, &root);
2972
2973 // Serve a 404 for the AIA url.
2974 RegisterSimpleTestServerHandler(ca_issuers_path, HTTP_NOT_FOUND, "text/plain",
2975 "Not Found");
2976
2977 // Trust the root certificate.
2978 ScopedTestRoot scoped_root(root);
2979
2980 // The chain being verified is solely the leaf certificate (missing the
2981 // intermediate and root).
2982 ASSERT_EQ(0u, leaf->intermediate_buffers().size());
2983
2984 const int flags = 0;
2985 int error;
2986 CertVerifyResult verify_result;
2987
2988 // Verifying the chain should fail as the intermediate is missing, and
2989 // cannot be fetched via AIA.
2990 error = Verify(leaf.get(), kHostname, flags, &verify_result);
2991 EXPECT_NE(OK, error);
2992
2993 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
2994 }
2995 #undef MAYBE_IntermediateFromAia404
2996
2997 // Tries verifying a certificate chain that is missing an intermediate. The
2998 // intermediate is available via AIA.
2999 // TODO(crbug.com/860189): Failing on iOS
3000 #if BUILDFLAG(IS_IOS)
3001 #define MAYBE_IntermediateFromAia200Der DISABLED_IntermediateFromAia200Der
3002 #else
3003 #define MAYBE_IntermediateFromAia200Der IntermediateFromAia200Der
3004 #endif
TEST_P(CertVerifyProcInternalWithNetFetchingTest,MAYBE_IntermediateFromAia200Der)3005 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3006 MAYBE_IntermediateFromAia200Der) {
3007 const char kHostname[] = "www.example.com";
3008
3009 // Create a chain where the leaf has an AIA that points to test server.
3010 scoped_refptr<X509Certificate> leaf;
3011 std::string ca_issuers_path;
3012 bssl::UniquePtr<CRYPTO_BUFFER> intermediate;
3013 scoped_refptr<X509Certificate> root;
3014 CreateSimpleChainWithAIA(&leaf, &ca_issuers_path, &intermediate, &root);
3015
3016 // Setup the test server to reply with the correct intermediate.
3017 RegisterSimpleTestServerHandler(
3018 ca_issuers_path, HTTP_OK, "application/pkix-cert",
3019 std::string(x509_util::CryptoBufferAsStringPiece(intermediate.get())));
3020
3021 // Trust the root certificate.
3022 ScopedTestRoot scoped_root(root);
3023
3024 // The chain being verified is solely the leaf certificate (missing the
3025 // intermediate and root).
3026 ASSERT_EQ(0u, leaf->intermediate_buffers().size());
3027
3028 // VERIFY_DISABLE_NETWORK_FETCHES flag is not implemented in
3029 // CertVerifyProcIOS, only test it on other verifiers.
3030 if (verify_proc_type() != CERT_VERIFY_PROC_IOS) {
3031 CertVerifyResult verify_result;
3032 // If VERIFY_DISABLE_NETWORK_FETCHES is specified, AIA should not be
3033 // attempted and verifying the chain should fail since the intermediate
3034 // can't be found.
3035 int error =
3036 Verify(leaf.get(), kHostname,
3037 CertVerifyProc::VERIFY_DISABLE_NETWORK_FETCHES, &verify_result);
3038 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
3039 EXPECT_EQ(0u, verify_result.verified_cert->intermediate_buffers().size());
3040 }
3041
3042 {
3043 CertVerifyResult verify_result;
3044 // Verifying the chain should succeed as the missing intermediate can be
3045 // fetched via AIA.
3046 int error = Verify(leaf.get(), kHostname, /*flags=*/0, &verify_result);
3047 EXPECT_THAT(error, IsOk());
3048 }
3049 }
3050
3051 // This test is the same as IntermediateFromAia200Der, except the certificate is
3052 // served as PEM rather than DER.
3053 //
3054 // Tries verifying a certificate chain that is missing an intermediate. The
3055 // intermediate is available via AIA, however is served as a PEM file rather
3056 // than DER.
3057 // TODO(crbug.com/860189): Failing on iOS
3058 #if BUILDFLAG(IS_IOS)
3059 #define MAYBE_IntermediateFromAia200Pem DISABLED_IntermediateFromAia200Pem
3060 #else
3061 #define MAYBE_IntermediateFromAia200Pem IntermediateFromAia200Pem
3062 #endif
TEST_P(CertVerifyProcInternalWithNetFetchingTest,MAYBE_IntermediateFromAia200Pem)3063 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3064 MAYBE_IntermediateFromAia200Pem) {
3065 const char kHostname[] = "www.example.com";
3066
3067 // Create a chain where the leaf has an AIA that points to test server.
3068 scoped_refptr<X509Certificate> leaf;
3069 std::string ca_issuers_path;
3070 bssl::UniquePtr<CRYPTO_BUFFER> intermediate;
3071 scoped_refptr<X509Certificate> root;
3072 CreateSimpleChainWithAIA(&leaf, &ca_issuers_path, &intermediate, &root);
3073
3074 std::string intermediate_pem;
3075 ASSERT_TRUE(
3076 X509Certificate::GetPEMEncoded(intermediate.get(), &intermediate_pem));
3077
3078 // Setup the test server to reply with the correct intermediate.
3079 RegisterSimpleTestServerHandler(
3080 ca_issuers_path, HTTP_OK, "application/x-x509-ca-cert", intermediate_pem);
3081
3082 // Trust the root certificate.
3083 ScopedTestRoot scoped_root(root);
3084
3085 // The chain being verified is solely the leaf certificate (missing the
3086 // intermediate and root).
3087 ASSERT_EQ(0u, leaf->intermediate_buffers().size());
3088
3089 const int flags = 0;
3090 int error;
3091 CertVerifyResult verify_result;
3092
3093 // Verifying the chain should succeed as the missing intermediate can be
3094 // fetched via AIA.
3095 error = Verify(leaf.get(), kHostname, flags, &verify_result);
3096
3097 if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
3098 // Android doesn't support PEM - https://crbug.com/725180
3099 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
3100 } else {
3101 EXPECT_THAT(error, IsOk());
3102 }
3103
3104 }
3105
3106 // This test is the same as IntermediateFromAia200Pem, but with a different
3107 // formatting on the PEM data.
3108 //
3109 // TODO(crbug.com/860189): Failing on iOS
3110 #if BUILDFLAG(IS_IOS)
3111 #define MAYBE_IntermediateFromAia200Pem2 DISABLED_IntermediateFromAia200Pem2
3112 #else
3113 #define MAYBE_IntermediateFromAia200Pem2 IntermediateFromAia200Pem2
3114 #endif
TEST_P(CertVerifyProcInternalWithNetFetchingTest,MAYBE_IntermediateFromAia200Pem2)3115 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3116 MAYBE_IntermediateFromAia200Pem2) {
3117 const char kHostname[] = "www.example.com";
3118
3119 // Create a chain where the leaf has an AIA that points to test server.
3120 scoped_refptr<X509Certificate> leaf;
3121 std::string ca_issuers_path;
3122 bssl::UniquePtr<CRYPTO_BUFFER> intermediate;
3123 scoped_refptr<X509Certificate> root;
3124 CreateSimpleChainWithAIA(&leaf, &ca_issuers_path, &intermediate, &root);
3125
3126 std::string intermediate_pem;
3127 ASSERT_TRUE(
3128 X509Certificate::GetPEMEncoded(intermediate.get(), &intermediate_pem));
3129 intermediate_pem = "Text at start of file\n" + intermediate_pem;
3130
3131 // Setup the test server to reply with the correct intermediate.
3132 RegisterSimpleTestServerHandler(
3133 ca_issuers_path, HTTP_OK, "application/x-x509-ca-cert", intermediate_pem);
3134
3135 // Trust the root certificate.
3136 ScopedTestRoot scoped_root(root);
3137
3138 // The chain being verified is solely the leaf certificate (missing the
3139 // intermediate and root).
3140 ASSERT_EQ(0u, leaf->intermediate_buffers().size());
3141
3142 const int flags = 0;
3143 int error;
3144 CertVerifyResult verify_result;
3145
3146 // Verifying the chain should succeed as the missing intermediate can be
3147 // fetched via AIA.
3148 error = Verify(leaf.get(), kHostname, flags, &verify_result);
3149
3150 if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
3151 // Android doesn't support PEM - https://crbug.com/725180
3152 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
3153 } else {
3154 EXPECT_THAT(error, IsOk());
3155 }
3156 }
3157
3158 // Tries verifying a certificate chain that uses a SHA1 intermediate,
3159 // however, chasing the AIA can discover a SHA256 version of the intermediate.
3160 //
3161 // Path building should discover the stronger intermediate and use it.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,Sha1IntermediateButAIAHasSha256)3162 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3163 Sha1IntermediateButAIAHasSha256) {
3164 const char kHostname[] = "www.example.com";
3165
3166 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
3167
3168 // Make the leaf certificate have an AIA (CA Issuers) that points to the
3169 // embedded test server. This uses a random URL for predictable behavior in
3170 // the presence of global caching.
3171 std::string ca_issuers_path = MakeRandomPath(".cer");
3172 GURL ca_issuers_url = GetTestServerAbsoluteUrl(ca_issuers_path);
3173 leaf->SetCaIssuersUrl(ca_issuers_url);
3174 leaf->SetSubjectAltName(kHostname);
3175
3176 // Make two versions of the intermediate - one that is SHA256 signed, and one
3177 // that is SHA1 signed. Note that the subjectKeyIdentifier for `intermediate`
3178 // is intentionally not changed, so that path building will consider both
3179 // certificate paths.
3180 intermediate->SetSignatureAlgorithm(bssl::SignatureAlgorithm::kEcdsaSha256);
3181 intermediate->SetRandomSerialNumber();
3182 auto intermediate_sha256 = intermediate->DupCertBuffer();
3183
3184 intermediate->SetSignatureAlgorithm(bssl::SignatureAlgorithm::kEcdsaSha1);
3185 intermediate->SetRandomSerialNumber();
3186 auto intermediate_sha1 = intermediate->DupCertBuffer();
3187
3188 // Trust the root certificate.
3189 auto root_cert = root->GetX509Certificate();
3190 ScopedTestRoot scoped_root(root_cert);
3191
3192 // Setup the test server to reply with the SHA256 intermediate.
3193 RegisterSimpleTestServerHandler(
3194 ca_issuers_path, HTTP_OK, "application/pkix-cert",
3195 std::string(
3196 x509_util::CryptoBufferAsStringPiece(intermediate_sha256.get())));
3197
3198 // Build a chain to verify that includes the SHA1 intermediate.
3199 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
3200 intermediates.push_back(bssl::UpRef(intermediate_sha1.get()));
3201 scoped_refptr<X509Certificate> chain_sha1 = X509Certificate::CreateFromBuffer(
3202 leaf->DupCertBuffer(), std::move(intermediates));
3203 ASSERT_TRUE(chain_sha1.get());
3204
3205 const int flags = 0;
3206 CertVerifyResult verify_result;
3207 int error = Verify(chain_sha1.get(), kHostname, flags, &verify_result);
3208
3209 if (VerifyProcTypeIsBuiltin()) {
3210 // Should have built a chain through the SHA256 intermediate. This was only
3211 // available via AIA, and not the (SHA1) one provided directly to path
3212 // building.
3213 ASSERT_EQ(2u, verify_result.verified_cert->intermediate_buffers().size());
3214 EXPECT_TRUE(x509_util::CryptoBufferEqual(
3215 verify_result.verified_cert->intermediate_buffers()[0].get(),
3216 intermediate_sha256.get()));
3217 ASSERT_EQ(2u, verify_result.verified_cert->intermediate_buffers().size());
3218
3219 EXPECT_FALSE(verify_result.has_sha1);
3220 EXPECT_THAT(error, IsOk());
3221 } else {
3222 EXPECT_NE(OK, error);
3223 if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID &&
3224 error == ERR_CERT_AUTHORITY_INVALID) {
3225 // Newer Android versions reject the chain due to the SHA1 intermediate,
3226 // but do not build the correct chain by AIA. Since only the partial
3227 // chain is returned, CertVerifyProc does not mark it as SHA1 as it does
3228 // not examine the last cert in the chain. Therefore, if
3229 // ERR_CERT_AUTHORITY_INVALID is returned, don't check the rest of the
3230 // statuses. See https://crbug.com/1191795.
3231 return;
3232 }
3233 EXPECT_TRUE(verify_result.cert_status &
3234 CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
3235 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT);
3236 EXPECT_TRUE(verify_result.has_sha1);
3237 }
3238 }
3239
TEST_P(CertVerifyProcInternalWithNetFetchingTest,RevocationHardFailNoCrls)3240 TEST_P(CertVerifyProcInternalWithNetFetchingTest, RevocationHardFailNoCrls) {
3241 if (!SupportsRevCheckingRequiredLocalAnchors()) {
3242 LOG(INFO) << "Skipping test as verifier doesn't support "
3243 "VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS";
3244 return;
3245 }
3246
3247 // Create certs which have no AIA or CRL distribution points.
3248 const char kHostname[] = "www.example.com";
3249 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
3250
3251 // Trust the root and build a chain to verify that includes the intermediate.
3252 ScopedTestRoot scoped_root(root->GetX509Certificate());
3253 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
3254 ASSERT_TRUE(chain.get());
3255
3256 // Verify with hard-fail revocation checking for local anchors.
3257 const int flags = CertVerifyProc::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS;
3258 CertVerifyResult verify_result;
3259 int error = Verify(chain.get(), kHostname, flags, &verify_result);
3260
3261 EXPECT_THAT(error, IsError(ERR_CERT_NO_REVOCATION_MECHANISM));
3262 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3263 }
3264
TEST_P(CertVerifyProcInternalWithNetFetchingTest,RevocationHardFailNoCrlsDisableNetworkFetches)3265 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3266 RevocationHardFailNoCrlsDisableNetworkFetches) {
3267 if (!SupportsRevCheckingRequiredLocalAnchors()) {
3268 LOG(INFO) << "Skipping test as verifier doesn't support "
3269 "VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS";
3270 return;
3271 }
3272
3273 // Create certs which have no AIA or CRL distribution points.
3274 const char kHostname[] = "www.example.com";
3275 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
3276
3277 // Trust the root and build a chain to verify that includes the intermediate.
3278 ScopedTestRoot scoped_root(root->GetX509Certificate());
3279 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
3280 ASSERT_TRUE(chain.get());
3281
3282 // Verify with flags for both hard-fail revocation checking for local anchors
3283 // and disabling network fetches.
3284 const int flags = CertVerifyProc::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS |
3285 CertVerifyProc::VERIFY_DISABLE_NETWORK_FETCHES;
3286 CertVerifyResult verify_result;
3287 int error = Verify(chain.get(), kHostname, flags, &verify_result);
3288
3289 // Should succeed, VERIFY_DISABLE_NETWORK_FETCHES takes priority.
3290 EXPECT_THAT(error, IsOk());
3291 EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3292 }
3293
3294 // CRL hard fail test where both leaf and intermediate are covered by valid
3295 // CRLs which have empty (non-present) revokedCertificates list. Verification
3296 // should succeed.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,RevocationHardFailCrlGoodNoRevokedCertificates)3297 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3298 RevocationHardFailCrlGoodNoRevokedCertificates) {
3299 if (!SupportsRevCheckingRequiredLocalAnchors()) {
3300 LOG(INFO) << "Skipping test as verifier doesn't support "
3301 "VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS";
3302 return;
3303 }
3304
3305 const char kHostname[] = "www.example.com";
3306 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
3307
3308 // Serve a root-issued CRL which does not revoke intermediate.
3309 intermediate->SetCrlDistributionPointUrl(CreateAndServeCrl(root.get(), {}));
3310
3311 // Serve an intermediate-issued CRL which does not revoke leaf.
3312 leaf->SetCrlDistributionPointUrl(CreateAndServeCrl(intermediate.get(), {}));
3313
3314 // Trust the root and build a chain to verify that includes the intermediate.
3315 ScopedTestRoot scoped_root(root->GetX509Certificate());
3316 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
3317 ASSERT_TRUE(chain.get());
3318
3319 // Verify with hard-fail revocation checking for local anchors.
3320 const int flags = CertVerifyProc::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS;
3321 CertVerifyResult verify_result;
3322 int error = Verify(chain.get(), kHostname, flags, &verify_result);
3323
3324 // Should pass, leaf and intermediate were covered by CRLs and were not
3325 // revoked.
3326 EXPECT_THAT(error, IsOk());
3327 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3328 }
3329
3330 // CRL hard fail test where both leaf and intermediate are covered by valid
3331 // CRLs which have revokedCertificates lists that revoke other irrelevant
3332 // serial numbers. Verification should succeed.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,RevocationHardFailCrlGoodIrrelevantSerialsRevoked)3333 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3334 RevocationHardFailCrlGoodIrrelevantSerialsRevoked) {
3335 if (!SupportsRevCheckingRequiredLocalAnchors()) {
3336 LOG(INFO) << "Skipping test as verifier doesn't support "
3337 "VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS";
3338 return;
3339 }
3340
3341 const char kHostname[] = "www.example.com";
3342 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
3343
3344 // Root-issued CRL revokes leaf's serial number. This is irrelevant.
3345 intermediate->SetCrlDistributionPointUrl(
3346 CreateAndServeCrl(root.get(), {leaf->GetSerialNumber()}));
3347
3348 // Intermediate-issued CRL revokes intermediates's serial number. This is
3349 // irrelevant.
3350 leaf->SetCrlDistributionPointUrl(
3351 CreateAndServeCrl(intermediate.get(), {intermediate->GetSerialNumber()}));
3352
3353 // Trust the root and build a chain to verify that includes the intermediate.
3354 ScopedTestRoot scoped_root(root->GetX509Certificate());
3355 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
3356 ASSERT_TRUE(chain.get());
3357
3358 // Verify with hard-fail revocation checking for local anchors.
3359 const int flags = CertVerifyProc::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS;
3360 CertVerifyResult verify_result;
3361 int error = Verify(chain.get(), kHostname, flags, &verify_result);
3362
3363 // Should pass, leaf and intermediate were covered by CRLs and were not
3364 // revoked.
3365 EXPECT_THAT(error, IsOk());
3366 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3367 }
3368
TEST_P(CertVerifyProcInternalWithNetFetchingTest,RevocationHardFailLeafRevokedByCrl)3369 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3370 RevocationHardFailLeafRevokedByCrl) {
3371 if (!SupportsRevCheckingRequiredLocalAnchors()) {
3372 LOG(INFO) << "Skipping test as verifier doesn't support "
3373 "VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS";
3374 return;
3375 }
3376
3377 const char kHostname[] = "www.example.com";
3378 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
3379
3380 // Root-issued CRL which does not revoke intermediate.
3381 intermediate->SetCrlDistributionPointUrl(CreateAndServeCrl(root.get(), {}));
3382
3383 // Leaf is revoked by intermediate issued CRL.
3384 leaf->SetCrlDistributionPointUrl(
3385 CreateAndServeCrl(intermediate.get(), {leaf->GetSerialNumber()}));
3386
3387 // Trust the root and build a chain to verify that includes the intermediate.
3388 ScopedTestRoot scoped_root(root->GetX509Certificate());
3389 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
3390 ASSERT_TRUE(chain.get());
3391
3392 // Verify with hard-fail revocation checking for local anchors.
3393 const int flags = CertVerifyProc::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS;
3394 CertVerifyResult verify_result;
3395 int error = Verify(chain.get(), kHostname, flags, &verify_result);
3396
3397 // Should fail, leaf is revoked.
3398 EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
3399 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3400 }
3401
TEST_P(CertVerifyProcInternalWithNetFetchingTest,RevocationHardFailIntermediateRevokedByCrl)3402 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3403 RevocationHardFailIntermediateRevokedByCrl) {
3404 if (!SupportsRevCheckingRequiredLocalAnchors()) {
3405 LOG(INFO) << "Skipping test as verifier doesn't support "
3406 "VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS";
3407 return;
3408 }
3409
3410 const char kHostname[] = "www.example.com";
3411 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
3412
3413 // Intermediate is revoked by root issued CRL.
3414 intermediate->SetCrlDistributionPointUrl(
3415 CreateAndServeCrl(root.get(), {intermediate->GetSerialNumber()}));
3416
3417 // Intermediate-issued CRL which does not revoke leaf.
3418 leaf->SetCrlDistributionPointUrl(CreateAndServeCrl(intermediate.get(), {}));
3419
3420 // Trust the root and build a chain to verify that includes the intermediate.
3421 ScopedTestRoot scoped_root(root->GetX509Certificate());
3422 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
3423 ASSERT_TRUE(chain.get());
3424
3425 // Verify with hard-fail revocation checking for local anchors.
3426 const int flags = CertVerifyProc::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS;
3427 CertVerifyResult verify_result;
3428 int error = Verify(chain.get(), kHostname, flags, &verify_result);
3429
3430 // Should fail, intermediate is revoked.
3431 EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
3432 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3433 }
3434
3435 // CRL hard fail test where the intermediate certificate has a good CRL, but
3436 // the leaf's distribution point returns an http error. Verification should
3437 // fail.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,RevocationHardFailLeafCrlDpHttpError)3438 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3439 RevocationHardFailLeafCrlDpHttpError) {
3440 if (!SupportsRevCheckingRequiredLocalAnchors()) {
3441 LOG(INFO) << "Skipping test as verifier doesn't support "
3442 "VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS";
3443 return;
3444 }
3445
3446 const char kHostname[] = "www.example.com";
3447 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
3448
3449 // Serve a root-issued CRL which does not revoke intermediate.
3450 intermediate->SetCrlDistributionPointUrl(CreateAndServeCrl(root.get(), {}));
3451
3452 // Serve a 404 for the intermediate-issued CRL distribution point url.
3453 leaf->SetCrlDistributionPointUrl(RegisterSimpleTestServerHandler(
3454 MakeRandomPath(".crl"), HTTP_NOT_FOUND, "text/plain", "Not Found"));
3455
3456 // Trust the root and build a chain to verify that includes the intermediate.
3457 ScopedTestRoot scoped_root(root->GetX509Certificate());
3458 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
3459 ASSERT_TRUE(chain.get());
3460
3461 // Verify with hard-fail revocation checking for local anchors.
3462 const int flags = CertVerifyProc::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS;
3463 CertVerifyResult verify_result;
3464 int error = Verify(chain.get(), kHostname, flags, &verify_result);
3465
3466 // Should fail since no revocation information was available for the leaf.
3467 EXPECT_THAT(error, IsError(ERR_CERT_UNABLE_TO_CHECK_REVOCATION));
3468 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3469 }
3470
3471 // CRL hard fail test where the leaf certificate has a good CRL, but
3472 // the intermediate's distribution point returns an http error. Verification
3473 // should fail.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,RevocationHardFailIntermediateCrlDpHttpError)3474 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3475 RevocationHardFailIntermediateCrlDpHttpError) {
3476 if (!SupportsRevCheckingRequiredLocalAnchors()) {
3477 LOG(INFO) << "Skipping test as verifier doesn't support "
3478 "VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS";
3479 return;
3480 }
3481
3482 const char kHostname[] = "www.example.com";
3483 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
3484
3485 // Serve a 404 for the root-issued CRL distribution point url.
3486 intermediate->SetCrlDistributionPointUrl(RegisterSimpleTestServerHandler(
3487 MakeRandomPath(".crl"), HTTP_NOT_FOUND, "text/plain", "Not Found"));
3488
3489 // Serve an intermediate-issued CRL which does not revoke leaf.
3490 leaf->SetCrlDistributionPointUrl(CreateAndServeCrl(intermediate.get(), {}));
3491
3492 // Trust the root and build a chain to verify that includes the intermediate.
3493 ScopedTestRoot scoped_root(root->GetX509Certificate());
3494 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
3495 ASSERT_TRUE(chain.get());
3496
3497 // Verify with hard-fail revocation checking for local anchors.
3498 const int flags = CertVerifyProc::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS;
3499 CertVerifyResult verify_result;
3500 int error = Verify(chain.get(), kHostname, flags, &verify_result);
3501
3502 // Should fail since no revocation information was available for the
3503 // intermediate.
3504 EXPECT_THAT(error, IsError(ERR_CERT_UNABLE_TO_CHECK_REVOCATION));
3505 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3506 }
3507
TEST_P(CertVerifyProcInternalWithNetFetchingTest,RevocationSoftFailNoCrls)3508 TEST_P(CertVerifyProcInternalWithNetFetchingTest, RevocationSoftFailNoCrls) {
3509 if (!SupportsSoftFailRevChecking()) {
3510 LOG(INFO) << "Skipping test as verifier doesn't support "
3511 "VERIFY_REV_CHECKING_ENABLED";
3512 return;
3513 }
3514
3515 // Create certs which have no AIA or CRL distribution points.
3516 const char kHostname[] = "www.example.com";
3517 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
3518
3519 // Trust the root and build a chain to verify that includes the intermediate.
3520 ScopedTestRoot scoped_root(root->GetX509Certificate());
3521 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
3522 ASSERT_TRUE(chain.get());
3523
3524 // Verify with soft-fail revocation checking.
3525 const int flags = CertVerifyProc::VERIFY_REV_CHECKING_ENABLED;
3526 CertVerifyResult verify_result;
3527 int error = Verify(chain.get(), kHostname, flags, &verify_result);
3528
3529 EXPECT_THAT(error, IsOk());
3530 EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_NO_REVOCATION_MECHANISM);
3531 EXPECT_FALSE(verify_result.cert_status &
3532 CERT_STATUS_UNABLE_TO_CHECK_REVOCATION);
3533 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3534 }
3535
3536 // CRL soft fail test where both leaf and intermediate are covered by valid
3537 // CRLs which have empty (non-present) revokedCertificates list. Verification
3538 // should succeed.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,RevocationSoftFailCrlGoodNoRevokedCertificates)3539 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3540 RevocationSoftFailCrlGoodNoRevokedCertificates) {
3541 if (!SupportsSoftFailRevChecking()) {
3542 LOG(INFO) << "Skipping test as verifier doesn't support "
3543 "VERIFY_REV_CHECKING_ENABLED";
3544 return;
3545 }
3546
3547 const char kHostname[] = "www.example.com";
3548 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
3549
3550 // Serve a root-issued CRL which does not revoke intermediate.
3551 intermediate->SetCrlDistributionPointUrl(CreateAndServeCrl(root.get(), {}));
3552
3553 // Serve an intermediate-issued CRL which does not revoke leaf.
3554 leaf->SetCrlDistributionPointUrl(CreateAndServeCrl(intermediate.get(), {}));
3555
3556 // Trust the root and build a chain to verify that includes the intermediate.
3557 ScopedTestRoot scoped_root(root->GetX509Certificate());
3558 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
3559 ASSERT_TRUE(chain.get());
3560
3561 // Verify with soft-fail revocation checking.
3562 const int flags = CertVerifyProc::VERIFY_REV_CHECKING_ENABLED;
3563 CertVerifyResult verify_result;
3564 int error = Verify(chain.get(), kHostname, flags, &verify_result);
3565
3566 EXPECT_THAT(error, IsOk());
3567 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3568 }
3569
3570 // CRL soft fail test where both leaf and intermediate are covered by valid
3571 // CRLs which have revokedCertificates lists that revoke other irrelevant
3572 // serial numbers. Verification should succeed.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,RevocationSoftFailCrlGoodIrrelevantSerialsRevoked)3573 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3574 RevocationSoftFailCrlGoodIrrelevantSerialsRevoked) {
3575 if (!SupportsSoftFailRevChecking()) {
3576 LOG(INFO) << "Skipping test as verifier doesn't support "
3577 "VERIFY_REV_CHECKING_ENABLED";
3578 return;
3579 }
3580
3581 const char kHostname[] = "www.example.com";
3582 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
3583
3584 // Root-issued CRL revokes leaf's serial number. This is irrelevant.
3585 intermediate->SetCrlDistributionPointUrl(
3586 CreateAndServeCrl(root.get(), {leaf->GetSerialNumber()}));
3587
3588 // Intermediate-issued CRL revokes intermediates's serial number. This is
3589 // irrelevant.
3590 leaf->SetCrlDistributionPointUrl(
3591 CreateAndServeCrl(intermediate.get(), {intermediate->GetSerialNumber()}));
3592
3593 // Trust the root and build a chain to verify that includes the intermediate.
3594 ScopedTestRoot scoped_root(root->GetX509Certificate());
3595 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
3596 ASSERT_TRUE(chain.get());
3597
3598 // Verify with soft-fail revocation checking.
3599 const int flags = CertVerifyProc::VERIFY_REV_CHECKING_ENABLED;
3600 CertVerifyResult verify_result;
3601 int error = Verify(chain.get(), kHostname, flags, &verify_result);
3602
3603 EXPECT_THAT(error, IsOk());
3604 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3605 }
3606
TEST_P(CertVerifyProcInternalWithNetFetchingTest,RevocationSoftFailLeafRevokedByCrl)3607 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3608 RevocationSoftFailLeafRevokedByCrl) {
3609 if (!SupportsSoftFailRevChecking()) {
3610 LOG(INFO) << "Skipping test as verifier doesn't support "
3611 "VERIFY_REV_CHECKING_ENABLED";
3612 return;
3613 }
3614
3615 const char kHostname[] = "www.example.com";
3616 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
3617
3618 // Root-issued CRL which does not revoke intermediate.
3619 intermediate->SetCrlDistributionPointUrl(CreateAndServeCrl(root.get(), {}));
3620
3621 // Leaf is revoked by intermediate issued CRL.
3622 leaf->SetCrlDistributionPointUrl(
3623 CreateAndServeCrl(intermediate.get(), {leaf->GetSerialNumber()}));
3624
3625 // Trust the root and build a chain to verify that includes the intermediate.
3626 ScopedTestRoot scoped_root(root->GetX509Certificate());
3627 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
3628 ASSERT_TRUE(chain.get());
3629
3630 // Verify with soft-fail revocation checking.
3631 const int flags = CertVerifyProc::VERIFY_REV_CHECKING_ENABLED;
3632 CertVerifyResult verify_result;
3633 int error = Verify(chain.get(), kHostname, flags, &verify_result);
3634
3635 // Should fail, leaf is revoked.
3636 EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
3637 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3638 }
3639
TEST_P(CertVerifyProcInternalWithNetFetchingTest,RevocationSoftFailLeafRevokedByCrlDisableNetworkFetches)3640 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3641 RevocationSoftFailLeafRevokedByCrlDisableNetworkFetches) {
3642 if (!SupportsSoftFailRevChecking()) {
3643 LOG(INFO) << "Skipping test as verifier doesn't support "
3644 "VERIFY_REV_CHECKING_ENABLED";
3645 return;
3646 }
3647
3648 const char kHostname[] = "www.example.com";
3649 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
3650
3651 // Root-issued CRL which does not revoke intermediate.
3652 intermediate->SetCrlDistributionPointUrl(CreateAndServeCrl(root.get(), {}));
3653
3654 // Leaf is revoked by intermediate issued CRL.
3655 leaf->SetCrlDistributionPointUrl(
3656 CreateAndServeCrl(intermediate.get(), {leaf->GetSerialNumber()}));
3657
3658 // Trust the root and build a chain to verify that includes the intermediate.
3659 ScopedTestRoot scoped_root(root->GetX509Certificate());
3660 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
3661 ASSERT_TRUE(chain.get());
3662
3663 // Verify with flags for both soft-fail revocation checking and disabling
3664 // network fetches.
3665 const int flags = CertVerifyProc::VERIFY_REV_CHECKING_ENABLED |
3666 CertVerifyProc::VERIFY_DISABLE_NETWORK_FETCHES;
3667 CertVerifyResult verify_result;
3668 int error = Verify(chain.get(), kHostname, flags, &verify_result);
3669
3670 // Should succeed, VERIFY_DISABLE_NETWORK_FETCHES takes priority.
3671 EXPECT_THAT(error, IsOk());
3672 EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3673 }
3674
TEST_P(CertVerifyProcInternalWithNetFetchingTest,RevocationSoftFailIntermediateRevokedByCrl)3675 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3676 RevocationSoftFailIntermediateRevokedByCrl) {
3677 if (!SupportsSoftFailRevChecking()) {
3678 LOG(INFO) << "Skipping test as verifier doesn't support "
3679 "VERIFY_REV_CHECKING_ENABLED";
3680 return;
3681 }
3682
3683 const char kHostname[] = "www.example.com";
3684 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
3685
3686 // Intermediate is revoked by root issued CRL.
3687 intermediate->SetCrlDistributionPointUrl(
3688 CreateAndServeCrl(root.get(), {intermediate->GetSerialNumber()}));
3689
3690 // Intermediate-issued CRL which does not revoke leaf.
3691 leaf->SetCrlDistributionPointUrl(CreateAndServeCrl(intermediate.get(), {}));
3692
3693 // Trust the root and build a chain to verify that includes the intermediate.
3694 ScopedTestRoot scoped_root(root->GetX509Certificate());
3695 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
3696 ASSERT_TRUE(chain.get());
3697
3698 // Verify with soft-fail revocation checking.
3699 const int flags = CertVerifyProc::VERIFY_REV_CHECKING_ENABLED;
3700 CertVerifyResult verify_result;
3701 int error = Verify(chain.get(), kHostname, flags, &verify_result);
3702
3703 // Should fail, intermediate is revoked.
3704 EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
3705 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3706 }
3707
TEST_P(CertVerifyProcInternalWithNetFetchingTest,RevocationSoftFailLeafRevokedBySha1Crl)3708 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3709 RevocationSoftFailLeafRevokedBySha1Crl) {
3710 if (!SupportsSoftFailRevChecking()) {
3711 LOG(INFO) << "Skipping test as verifier doesn't support "
3712 "VERIFY_REV_CHECKING_ENABLED";
3713 return;
3714 }
3715
3716 const char kHostname[] = "www.example.com";
3717 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
3718
3719 // Root-issued CRL which does not revoke intermediate.
3720 intermediate->SetCrlDistributionPointUrl(CreateAndServeCrl(root.get(), {}));
3721
3722 // Leaf is revoked by intermediate issued CRL which is signed with
3723 // ecdsaWithSha256.
3724 leaf->SetCrlDistributionPointUrl(
3725 CreateAndServeCrl(intermediate.get(), {leaf->GetSerialNumber()},
3726 bssl::SignatureAlgorithm::kEcdsaSha1));
3727
3728 // Trust the root and build a chain to verify that includes the intermediate.
3729 ScopedTestRoot scoped_root(root->GetX509Certificate());
3730 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
3731 ASSERT_TRUE(chain.get());
3732
3733 // Verify with soft-fail revocation checking.
3734 const int flags = CertVerifyProc::VERIFY_REV_CHECKING_ENABLED;
3735 CertVerifyResult verify_result;
3736 int error = Verify(chain.get(), kHostname, flags, &verify_result);
3737
3738 // Should fail, leaf is revoked.
3739 EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
3740 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3741 }
3742
TEST_P(CertVerifyProcInternalWithNetFetchingTest,RevocationSoftFailLeafRevokedByMd5Crl)3743 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3744 RevocationSoftFailLeafRevokedByMd5Crl) {
3745 if (!SupportsSoftFailRevChecking()) {
3746 LOG(INFO) << "Skipping test as verifier doesn't support "
3747 "VERIFY_REV_CHECKING_ENABLED";
3748 return;
3749 }
3750
3751 const char kHostname[] = "www.example.com";
3752 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
3753
3754 // Root-issued CRL which does not revoke intermediate.
3755 intermediate->SetCrlDistributionPointUrl(CreateAndServeCrl(root.get(), {}));
3756 // This test wants to check handling of MD5 CRLs, but ecdsa-with-md5
3757 // signatureAlgorithm does not exist. Use an RSA private key for intermediate
3758 // so that the CRL will be signed with the md5WithRSAEncryption algorithm.
3759 ASSERT_TRUE(intermediate->UseKeyFromFile(
3760 GetTestCertsDirectory().AppendASCII("rsa-2048-1.key")));
3761 leaf->SetSignatureAlgorithm(bssl::SignatureAlgorithm::kRsaPkcs1Sha256);
3762
3763 // Leaf is revoked by intermediate issued CRL which is signed with
3764 // md5WithRSAEncryption.
3765 leaf->SetCrlDistributionPointUrl(CreateAndServeCrlWithAlgorithmTlvAndDigest(
3766 intermediate.get(), {leaf->GetSerialNumber()}, Md5WithRSAEncryption(),
3767 EVP_md5()));
3768
3769 // Trust the root and build a chain to verify that includes the intermediate.
3770 ScopedTestRoot scoped_root(root->GetX509Certificate());
3771 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
3772 ASSERT_TRUE(chain.get());
3773
3774 // Verify with soft-fail revocation checking.
3775 const int flags = CertVerifyProc::VERIFY_REV_CHECKING_ENABLED;
3776 CertVerifyResult verify_result;
3777 int error = Verify(chain.get(), kHostname, flags, &verify_result);
3778
3779 // Verification should succeed: MD5 signature algorithm is not supported
3780 // and soft-fail checking will ignore the inability to get revocation
3781 // status.
3782 EXPECT_THAT(error, IsOk());
3783 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3784 }
3785
3786 // CRL soft fail test where the intermediate certificate has a good CRL, but
3787 // the leaf's distribution point returns an http error. Verification should
3788 // succeed.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,RevocationSoftFailLeafCrlDpHttpError)3789 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3790 RevocationSoftFailLeafCrlDpHttpError) {
3791 if (!SupportsSoftFailRevChecking()) {
3792 LOG(INFO) << "Skipping test as verifier doesn't support "
3793 "VERIFY_REV_CHECKING_ENABLED";
3794 return;
3795 }
3796
3797 const char kHostname[] = "www.example.com";
3798 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
3799
3800 // Serve a root-issued CRL which does not revoke intermediate.
3801 intermediate->SetCrlDistributionPointUrl(CreateAndServeCrl(root.get(), {}));
3802
3803 // Serve a 404 for the intermediate-issued CRL distribution point url.
3804 leaf->SetCrlDistributionPointUrl(RegisterSimpleTestServerHandler(
3805 MakeRandomPath(".crl"), HTTP_NOT_FOUND, "text/plain", "Not Found"));
3806
3807 // Trust the root and build a chain to verify that includes the intermediate.
3808 ScopedTestRoot scoped_root(root->GetX509Certificate());
3809 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
3810 ASSERT_TRUE(chain.get());
3811
3812 // Verify with soft-fail revocation checking.
3813 const int flags = CertVerifyProc::VERIFY_REV_CHECKING_ENABLED;
3814 CertVerifyResult verify_result;
3815 int error = Verify(chain.get(), kHostname, flags, &verify_result);
3816
3817 // Should succeed due to soft-fail revocation checking.
3818 EXPECT_THAT(error, IsOk());
3819 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3820 }
3821
3822 // CRL soft fail test where the leaf certificate has a good CRL, but
3823 // the intermediate's distribution point returns an http error. Verification
3824 // should succeed.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,RevocationSoftFailIntermediateCrlDpHttpError)3825 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3826 RevocationSoftFailIntermediateCrlDpHttpError) {
3827 if (!SupportsSoftFailRevChecking()) {
3828 LOG(INFO) << "Skipping test as verifier doesn't support "
3829 "VERIFY_REV_CHECKING_ENABLED";
3830 return;
3831 }
3832
3833 const char kHostname[] = "www.example.com";
3834 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
3835
3836 // Serve a 404 for the root-issued CRL distribution point url.
3837 intermediate->SetCrlDistributionPointUrl(RegisterSimpleTestServerHandler(
3838 MakeRandomPath(".crl"), HTTP_NOT_FOUND, "text/plain", "Not Found"));
3839
3840 // Serve an intermediate-issued CRL which does not revoke leaf.
3841 leaf->SetCrlDistributionPointUrl(CreateAndServeCrl(intermediate.get(), {}));
3842
3843 // Trust the root and build a chain to verify that includes the intermediate.
3844 ScopedTestRoot scoped_root(root->GetX509Certificate());
3845 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
3846 ASSERT_TRUE(chain.get());
3847
3848 // Verify with soft-fail revocation checking.
3849 const int flags = CertVerifyProc::VERIFY_REV_CHECKING_ENABLED;
3850 CertVerifyResult verify_result;
3851 int error = Verify(chain.get(), kHostname, flags, &verify_result);
3852
3853 // Should succeed due to soft-fail revocation checking.
3854 EXPECT_THAT(error, IsOk());
3855 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3856 }
3857
3858 // Tests that an EV cert verification with successful online OCSP revocation
3859 // checks is marked as CERT_STATUS_IS_EV.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,EVOnlineOCSPRevocationCheckingGood)3860 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3861 EVOnlineOCSPRevocationCheckingGood) {
3862 if (!SupportsEV()) {
3863 LOG(INFO) << "Skipping test as EV verification is not yet supported";
3864 return;
3865 }
3866
3867 const char kEVTestCertPolicy[] = "1.2.3.4";
3868 EmbeddedTestServer::ServerCertificateConfig cert_config;
3869 cert_config.policy_oids = {kEVTestCertPolicy};
3870 cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig(
3871 {{bssl::OCSPRevocationStatus::GOOD,
3872 EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kValid}});
3873
3874 EmbeddedTestServer ocsp_test_server(EmbeddedTestServer::TYPE_HTTPS);
3875 ocsp_test_server.SetSSLConfig(cert_config);
3876 EXPECT_TRUE(ocsp_test_server.Start());
3877
3878 scoped_refptr<X509Certificate> root =
3879 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem");
3880 ASSERT_TRUE(root.get());
3881
3882 scoped_refptr<X509Certificate> chain = ocsp_test_server.GetCertificate();
3883 ASSERT_TRUE(chain.get());
3884
3885 // Consider the root of the test chain a valid EV root for the test policy.
3886 ScopedTestEVPolicy scoped_test_ev_policy(
3887 EVRootCAMetadata::GetInstance(),
3888 X509Certificate::CalculateFingerprint256(root->cert_buffer()),
3889 kEVTestCertPolicy);
3890
3891 CertVerifyResult verify_result;
3892 int flags = 0;
3893 int error = Verify(chain.get(), ocsp_test_server.host_port_pair().host(),
3894 flags, &verify_result);
3895 EXPECT_THAT(error, IsOk());
3896 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV);
3897 EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3898 }
3899
3900 // Tests that an EV cert verification with that could not retrieve online OCSP
3901 // revocation information is verified but still marked as CERT_STATUS_IS_EV.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,EVOnlineOCSPRevocationCheckingSoftFail)3902 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3903 EVOnlineOCSPRevocationCheckingSoftFail) {
3904 if (!SupportsEV()) {
3905 LOG(INFO) << "Skipping test as EV verification is not yet supported";
3906 return;
3907 }
3908
3909 const char kEVTestCertPolicy[] = "1.2.3.4";
3910 EmbeddedTestServer::ServerCertificateConfig cert_config;
3911 cert_config.policy_oids = {kEVTestCertPolicy};
3912 // Retrieving OCSP status returns an error.
3913 cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig(
3914 EmbeddedTestServer::OCSPConfig::ResponseType::kInternalError);
3915
3916 EmbeddedTestServer ocsp_test_server(EmbeddedTestServer::TYPE_HTTPS);
3917 ocsp_test_server.SetSSLConfig(cert_config);
3918 EXPECT_TRUE(ocsp_test_server.Start());
3919
3920 scoped_refptr<X509Certificate> root =
3921 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem");
3922 ASSERT_TRUE(root.get());
3923
3924 scoped_refptr<X509Certificate> chain = ocsp_test_server.GetCertificate();
3925 ASSERT_TRUE(chain.get());
3926
3927 // Consider the root of the test chain a valid EV root for the test policy.
3928 ScopedTestEVPolicy scoped_test_ev_policy(
3929 EVRootCAMetadata::GetInstance(),
3930 X509Certificate::CalculateFingerprint256(root->cert_buffer()),
3931 kEVTestCertPolicy);
3932
3933 CertVerifyResult verify_result;
3934 int flags = 0;
3935 int error = Verify(chain.get(), ocsp_test_server.host_port_pair().host(),
3936 flags, &verify_result);
3937 EXPECT_THAT(error, IsOk());
3938 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV);
3939 EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3940 }
3941
3942 // Tests that an EV cert verification with online OCSP returning affirmatively
3943 // revoked is marked as CERT_STATUS_IS_EV.
TEST_P(CertVerifyProcInternalWithNetFetchingTest,EVOnlineOCSPRevocationCheckingRevoked)3944 TEST_P(CertVerifyProcInternalWithNetFetchingTest,
3945 EVOnlineOCSPRevocationCheckingRevoked) {
3946 if (!SupportsEV()) {
3947 LOG(INFO) << "Skipping test as EV verification is not yet supported";
3948 return;
3949 }
3950
3951 const char kEVTestCertPolicy[] = "1.2.3.4";
3952 EmbeddedTestServer::ServerCertificateConfig cert_config;
3953 cert_config.policy_oids = {kEVTestCertPolicy};
3954 cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig(
3955 {{bssl::OCSPRevocationStatus::REVOKED,
3956 EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kValid}});
3957
3958 EmbeddedTestServer ocsp_test_server(EmbeddedTestServer::TYPE_HTTPS);
3959 ocsp_test_server.SetSSLConfig(cert_config);
3960 EXPECT_TRUE(ocsp_test_server.Start());
3961
3962 scoped_refptr<X509Certificate> root =
3963 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem");
3964 ASSERT_TRUE(root.get());
3965
3966 scoped_refptr<X509Certificate> chain = ocsp_test_server.GetCertificate();
3967 ASSERT_TRUE(chain.get());
3968
3969 // Consider the root of the test chain a valid EV root for the test policy.
3970 ScopedTestEVPolicy scoped_test_ev_policy(
3971 EVRootCAMetadata::GetInstance(),
3972 X509Certificate::CalculateFingerprint256(root->cert_buffer()),
3973 kEVTestCertPolicy);
3974
3975 CertVerifyResult verify_result;
3976 int flags = 0;
3977 int error = Verify(chain.get(), ocsp_test_server.host_port_pair().host(),
3978 flags, &verify_result);
3979 EXPECT_THAT(error, IsOk());
3980 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV);
3981 EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
3982 }
3983
3984 // A set of tests that check how various constraints are enforced when they
3985 // appear at different points in the chain, such as on the trust anchor versus
3986 // on intermediates.
3987 class CertVerifyProcConstraintsTest : public CertVerifyProcInternalTest {
3988 protected:
SetUp()3989 void SetUp() override {
3990 CertVerifyProcInternalTest::SetUp();
3991
3992 chain_ = CertBuilder::CreateSimpleChain(/*chain_length=*/4);
3993 }
3994
VerifyWithTrust(bssl::CertificateTrust trust)3995 int VerifyWithTrust(bssl::CertificateTrust trust) {
3996 ScopedTestRoot test_root(chain_.back()->GetX509Certificate(), trust);
3997 CertVerifyResult verify_result;
3998 int flags = 0;
3999 return CertVerifyProcInternalTest::Verify(
4000 chain_.front()->GetX509CertificateChain().get(), "www.example.com",
4001 flags, &verify_result);
4002 }
4003
Verify()4004 int Verify() {
4005 return VerifyWithTrust(bssl::CertificateTrust::ForTrustAnchor());
4006 }
4007
VerifyWithExpiryAndConstraints()4008 int VerifyWithExpiryAndConstraints() {
4009 return VerifyWithTrust(bssl::CertificateTrust::ForTrustAnchor()
4010 .WithEnforceAnchorExpiry()
4011 .WithEnforceAnchorConstraints());
4012 }
4013
VerifyWithExpiryAndFullConstraints()4014 int VerifyWithExpiryAndFullConstraints() {
4015 return VerifyWithTrust(bssl::CertificateTrust::ForTrustAnchor()
4016 .WithEnforceAnchorExpiry()
4017 .WithEnforceAnchorConstraints()
4018 .WithRequireAnchorBasicConstraints());
4019 }
4020
ExpectedIntermediateConstraintError()4021 int ExpectedIntermediateConstraintError() {
4022 if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID)
4023 return ERR_CERT_AUTHORITY_INVALID;
4024 return ERR_CERT_INVALID;
4025 }
4026
4027 std::vector<std::unique_ptr<CertBuilder>> chain_;
4028 };
4029
4030 INSTANTIATE_TEST_SUITE_P(All,
4031 CertVerifyProcConstraintsTest,
4032 testing::ValuesIn(kAllCertVerifiers),
4033 VerifyProcTypeToName);
4034
TEST_P(CertVerifyProcConstraintsTest,BaseCase)4035 TEST_P(CertVerifyProcConstraintsTest, BaseCase) {
4036 // Without changing anything on the test chain, it should validate
4037 // successfully. If this is not true then the rest of the tests in this class
4038 // are unlikely to be useful.
4039 EXPECT_THAT(Verify(), IsOk());
4040 if (VerifyProcTypeIsBuiltin()) {
4041 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsOk());
4042 EXPECT_THAT(VerifyWithExpiryAndFullConstraints(), IsOk());
4043 EXPECT_THAT(VerifyWithTrust(bssl::CertificateTrust::ForTrustAnchorOrLeaf()),
4044 IsOk());
4045 EXPECT_THAT(VerifyWithTrust(bssl::CertificateTrust::ForTrustedLeaf()),
4046 IsError(ERR_CERT_AUTHORITY_INVALID));
4047 }
4048 }
4049
TEST_P(CertVerifyProcConstraintsTest,BasicConstraintsNotCaRoot)4050 TEST_P(CertVerifyProcConstraintsTest, BasicConstraintsNotCaRoot) {
4051 chain_[3]->SetBasicConstraints(/*is_ca=*/false, /*path_len=*/-1);
4052
4053 if (VerifyProcTypeIsBuiltin()) {
4054 EXPECT_THAT(Verify(), IsOk());
4055 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsError(ERR_CERT_INVALID));
4056 EXPECT_THAT(VerifyWithExpiryAndFullConstraints(),
4057 IsError(ERR_CERT_INVALID));
4058 } else if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
4059 EXPECT_THAT(Verify(), IsOk());
4060 } else {
4061 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
4062 }
4063 }
4064
TEST_P(CertVerifyProcConstraintsTest,BasicConstraintsNotCaIntermediate)4065 TEST_P(CertVerifyProcConstraintsTest, BasicConstraintsNotCaIntermediate) {
4066 chain_[2]->SetBasicConstraints(/*is_ca=*/false, /*path_len=*/-1);
4067
4068 EXPECT_THAT(Verify(), IsError(ExpectedIntermediateConstraintError()));
4069 }
4070
TEST_P(CertVerifyProcConstraintsTest,BasicConstraintsIsCaLeaf)4071 TEST_P(CertVerifyProcConstraintsTest, BasicConstraintsIsCaLeaf) {
4072 for (bool has_key_usage_cert_sign : {false, true}) {
4073 chain_[0]->SetBasicConstraints(/*is_ca=*/true, /*path_len=*/-1);
4074
4075 if (has_key_usage_cert_sign) {
4076 chain_[0]->SetKeyUsages({bssl::KEY_USAGE_BIT_KEY_CERT_SIGN,
4077 bssl::KEY_USAGE_BIT_DIGITAL_SIGNATURE});
4078 } else {
4079 chain_[0]->SetKeyUsages({bssl::KEY_USAGE_BIT_DIGITAL_SIGNATURE});
4080 }
4081 EXPECT_THAT(Verify(), IsOk());
4082 }
4083 }
4084
TEST_P(CertVerifyProcConstraintsTest,BasicConstraintsPathlen0Root)4085 TEST_P(CertVerifyProcConstraintsTest, BasicConstraintsPathlen0Root) {
4086 chain_[3]->SetBasicConstraints(/*is_ca=*/true, /*path_len=*/0);
4087
4088 if (VerifyProcTypeIsBuiltin()) {
4089 EXPECT_THAT(Verify(), IsOk());
4090 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsError(ERR_CERT_INVALID));
4091 } else if (VerifyProcTypeIsIOSAtMostOS14() ||
4092 verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
4093 EXPECT_THAT(Verify(), IsOk());
4094 } else {
4095 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
4096 }
4097 }
4098
TEST_P(CertVerifyProcConstraintsTest,BasicConstraintsPathlen1Root)4099 TEST_P(CertVerifyProcConstraintsTest, BasicConstraintsPathlen1Root) {
4100 chain_[3]->SetBasicConstraints(/*is_ca=*/true, /*path_len=*/1);
4101
4102 if (VerifyProcTypeIsBuiltin()) {
4103 EXPECT_THAT(Verify(), IsOk());
4104 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsError(ERR_CERT_INVALID));
4105 } else if (VerifyProcTypeIsIOSAtMostOS14() ||
4106 verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
4107 EXPECT_THAT(Verify(), IsOk());
4108 } else {
4109 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
4110 }
4111 }
4112
TEST_P(CertVerifyProcConstraintsTest,BasicConstraintsPathlen2Root)4113 TEST_P(CertVerifyProcConstraintsTest, BasicConstraintsPathlen2Root) {
4114 chain_[3]->SetBasicConstraints(/*is_ca=*/true, /*path_len=*/2);
4115
4116 EXPECT_THAT(Verify(), IsOk());
4117 if (VerifyProcTypeIsBuiltin()) {
4118 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsOk());
4119 }
4120 }
4121
TEST_P(CertVerifyProcConstraintsTest,BasicConstraintsPathlen0IntermediateParent)4122 TEST_P(CertVerifyProcConstraintsTest,
4123 BasicConstraintsPathlen0IntermediateParent) {
4124 chain_[2]->SetBasicConstraints(/*is_ca=*/true, /*path_len=*/0);
4125
4126 EXPECT_THAT(Verify(), IsError(ExpectedIntermediateConstraintError()));
4127 }
4128
TEST_P(CertVerifyProcConstraintsTest,BasicConstraintsPathlen1IntermediateParent)4129 TEST_P(CertVerifyProcConstraintsTest,
4130 BasicConstraintsPathlen1IntermediateParent) {
4131 chain_[2]->SetBasicConstraints(/*is_ca=*/true, /*path_len=*/1);
4132
4133 EXPECT_THAT(Verify(), IsOk());
4134 }
4135
TEST_P(CertVerifyProcConstraintsTest,BasicConstraintsPathlen0IntermediateChild)4136 TEST_P(CertVerifyProcConstraintsTest,
4137 BasicConstraintsPathlen0IntermediateChild) {
4138 chain_[1]->SetBasicConstraints(/*is_ca=*/true, /*path_len=*/0);
4139
4140 EXPECT_THAT(Verify(), IsOk());
4141 }
4142
TEST_P(CertVerifyProcConstraintsTest,BasicConstraintsNotPresentRoot)4143 TEST_P(CertVerifyProcConstraintsTest, BasicConstraintsNotPresentRoot) {
4144 chain_[3]->EraseExtension(bssl::der::Input(bssl::kBasicConstraintsOid));
4145
4146 if (VerifyProcTypeIsBuiltin()) {
4147 EXPECT_THAT(Verify(), IsOk());
4148 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsOk());
4149 EXPECT_THAT(VerifyWithExpiryAndFullConstraints(),
4150 IsError(ERR_CERT_INVALID));
4151 } else if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
4152 EXPECT_THAT(Verify(), IsOk());
4153 } else {
4154 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
4155 }
4156 }
4157
TEST_P(CertVerifyProcConstraintsTest,BasicConstraintsNotPresentRootX509V1)4158 TEST_P(CertVerifyProcConstraintsTest, BasicConstraintsNotPresentRootX509V1) {
4159 chain_[3]->SetCertificateVersion(bssl::CertificateVersion::V1);
4160 chain_[3]->ClearExtensions();
4161
4162 EXPECT_THAT(Verify(), IsOk());
4163 if (VerifyProcTypeIsBuiltin()) {
4164 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsOk());
4165 EXPECT_THAT(VerifyWithExpiryAndFullConstraints(), IsOk());
4166 }
4167 }
4168
TEST_P(CertVerifyProcConstraintsTest,BasicConstraintsNotPresentIntermediate)4169 TEST_P(CertVerifyProcConstraintsTest, BasicConstraintsNotPresentIntermediate) {
4170 chain_[2]->EraseExtension(bssl::der::Input(bssl::kBasicConstraintsOid));
4171
4172 EXPECT_THAT(Verify(), IsError(ExpectedIntermediateConstraintError()));
4173 }
4174
TEST_P(CertVerifyProcConstraintsTest,BasicConstraintsNotPresentLeaf)4175 TEST_P(CertVerifyProcConstraintsTest, BasicConstraintsNotPresentLeaf) {
4176 chain_[0]->EraseExtension(bssl::der::Input(bssl::kBasicConstraintsOid));
4177
4178 EXPECT_THAT(Verify(), IsOk());
4179 }
4180
TEST_P(CertVerifyProcConstraintsTest,NameConstraintsNotMatchingRoot)4181 TEST_P(CertVerifyProcConstraintsTest, NameConstraintsNotMatchingRoot) {
4182 chain_[3]->SetNameConstraintsDnsNames(/*permitted_dns_names=*/{"example.org"},
4183 /*excluded_dns_names=*/{});
4184
4185 if (VerifyProcTypeIsBuiltin()) {
4186 EXPECT_THAT(Verify(), IsOk());
4187 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsError(ERR_CERT_INVALID));
4188 } else if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
4189 EXPECT_THAT(Verify(), IsOk());
4190 } else {
4191 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
4192 }
4193 }
4194
TEST_P(CertVerifyProcConstraintsTest,NameConstraintsNotMatchingIntermediate)4195 TEST_P(CertVerifyProcConstraintsTest, NameConstraintsNotMatchingIntermediate) {
4196 chain_[2]->SetNameConstraintsDnsNames(
4197 /*permitted_dns_names=*/{"example.org"},
4198 /*excluded_dns_names=*/{});
4199
4200 EXPECT_THAT(Verify(), IsError(ExpectedIntermediateConstraintError()));
4201 }
4202
TEST_P(CertVerifyProcConstraintsTest,NameConstraintsMatchingRoot)4203 TEST_P(CertVerifyProcConstraintsTest, NameConstraintsMatchingRoot) {
4204 chain_[3]->SetNameConstraintsDnsNames(/*permitted_dns_names=*/{"example.com"},
4205 /*excluded_dns_names=*/{});
4206
4207 EXPECT_THAT(Verify(), IsOk());
4208 if (VerifyProcTypeIsBuiltin()) {
4209 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsOk());
4210 }
4211 }
4212
TEST_P(CertVerifyProcConstraintsTest,NameConstraintsMatchingIntermediate)4213 TEST_P(CertVerifyProcConstraintsTest, NameConstraintsMatchingIntermediate) {
4214 chain_[2]->SetNameConstraintsDnsNames(
4215 /*permitted_dns_names=*/{"example.com"},
4216 /*excluded_dns_names=*/{});
4217
4218 EXPECT_THAT(Verify(), IsOk());
4219 }
4220
TEST_P(CertVerifyProcConstraintsTest,NameConstraintsOnLeaf)4221 TEST_P(CertVerifyProcConstraintsTest, NameConstraintsOnLeaf) {
4222 chain_[0]->SetNameConstraintsDnsNames(
4223 /*permitted_dns_names=*/{"example.com"},
4224 /*excluded_dns_names=*/{});
4225
4226 // TODO(mattm): this should be an error
4227 // RFC 5280 4.2.1.10 says: "The name constraints extension, which MUST be
4228 // used only in a CA certificate, ..."
4229 EXPECT_THAT(Verify(), IsOk());
4230 }
4231
TEST_P(CertVerifyProcConstraintsTest,ValidityExpiredRoot)4232 TEST_P(CertVerifyProcConstraintsTest, ValidityExpiredRoot) {
4233 chain_[3]->SetValidity(base::Time::Now() - base::Days(14),
4234 base::Time::Now() - base::Days(7));
4235
4236 if (VerifyProcTypeIsBuiltin()) {
4237 EXPECT_THAT(Verify(), IsOk());
4238 EXPECT_THAT(VerifyWithExpiryAndConstraints(),
4239 IsError(ERR_CERT_DATE_INVALID));
4240 EXPECT_THAT(VerifyWithExpiryAndFullConstraints(),
4241 IsError(ERR_CERT_DATE_INVALID));
4242 } else if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
4243 EXPECT_THAT(Verify(), IsOk());
4244 } else {
4245 EXPECT_THAT(Verify(), IsError(ERR_CERT_DATE_INVALID));
4246 }
4247 }
4248
TEST_P(CertVerifyProcConstraintsTest,ValidityNotYetValidRoot)4249 TEST_P(CertVerifyProcConstraintsTest, ValidityNotYetValidRoot) {
4250 chain_[3]->SetValidity(base::Time::Now() + base::Days(7),
4251 base::Time::Now() + base::Days(14));
4252
4253 if (VerifyProcTypeIsBuiltin()) {
4254 EXPECT_THAT(Verify(), IsOk());
4255 EXPECT_THAT(VerifyWithExpiryAndConstraints(),
4256 IsError(ERR_CERT_DATE_INVALID));
4257 EXPECT_THAT(VerifyWithExpiryAndFullConstraints(),
4258 IsError(ERR_CERT_DATE_INVALID));
4259 } else if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
4260 EXPECT_THAT(Verify(), IsOk());
4261 } else {
4262 EXPECT_THAT(Verify(), IsError(ERR_CERT_DATE_INVALID));
4263 }
4264 }
4265
TEST_P(CertVerifyProcConstraintsTest,ValidityExpiredIntermediate)4266 TEST_P(CertVerifyProcConstraintsTest, ValidityExpiredIntermediate) {
4267 chain_[2]->SetValidity(base::Time::Now() - base::Days(14),
4268 base::Time::Now() - base::Days(7));
4269
4270 if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
4271 EXPECT_THAT(Verify(), IsError(ERR_CERT_AUTHORITY_INVALID));
4272 } else {
4273 EXPECT_THAT(Verify(), IsError(ERR_CERT_DATE_INVALID));
4274 }
4275 }
4276
TEST_P(CertVerifyProcConstraintsTest,ValidityNotYetValidIntermediate)4277 TEST_P(CertVerifyProcConstraintsTest, ValidityNotYetValidIntermediate) {
4278 chain_[2]->SetValidity(base::Time::Now() + base::Days(7),
4279 base::Time::Now() + base::Days(14));
4280
4281 if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
4282 EXPECT_THAT(Verify(), IsError(ERR_CERT_AUTHORITY_INVALID));
4283 } else {
4284 EXPECT_THAT(Verify(), IsError(ERR_CERT_DATE_INVALID));
4285 }
4286 }
4287
TEST_P(CertVerifyProcConstraintsTest,PolicyConstraints0Root)4288 TEST_P(CertVerifyProcConstraintsTest, PolicyConstraints0Root) {
4289 for (bool leaf_has_policy : {false, true}) {
4290 SCOPED_TRACE(leaf_has_policy);
4291
4292 static const char kPolicy1[] = "1.2.3.4";
4293 static const char kPolicy2[] = "1.2.3.4.5";
4294 static const char kPolicy3[] = "1.2.3.5";
4295 chain_[3]->SetPolicyConstraints(
4296 /*require_explicit_policy=*/0,
4297 /*inhibit_policy_mapping=*/std::nullopt);
4298 chain_[3]->SetCertificatePolicies({kPolicy1, kPolicy2});
4299 chain_[2]->SetCertificatePolicies({kPolicy3, kPolicy1});
4300 chain_[1]->SetCertificatePolicies({kPolicy1});
4301
4302 if (leaf_has_policy) {
4303 chain_[0]->SetCertificatePolicies({kPolicy1});
4304 EXPECT_THAT(Verify(), IsOk());
4305 if (VerifyProcTypeIsBuiltin()) {
4306 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsOk());
4307 }
4308 } else {
4309 chain_[0]->SetCertificatePolicies({});
4310 if (VerifyProcTypeIsBuiltin()) {
4311 EXPECT_THAT(Verify(), IsOk());
4312 EXPECT_THAT(VerifyWithExpiryAndConstraints(),
4313 IsError(ERR_CERT_INVALID));
4314 } else if (verify_proc_type() == CERT_VERIFY_PROC_IOS ||
4315 verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
4316 EXPECT_THAT(Verify(), IsOk());
4317 } else {
4318 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
4319 }
4320 }
4321 }
4322 }
4323
TEST_P(CertVerifyProcConstraintsTest,PolicyConstraints4Root)4324 TEST_P(CertVerifyProcConstraintsTest, PolicyConstraints4Root) {
4325 // Explicit policy is required after 4 certs. Since the chain is 4 certs
4326 // long, an explicit policy is never required.
4327 chain_[3]->SetPolicyConstraints(
4328 /*require_explicit_policy=*/4,
4329 /*inhibit_policy_mapping=*/std::nullopt);
4330
4331 EXPECT_THAT(Verify(), IsOk());
4332 if (VerifyProcTypeIsBuiltin()) {
4333 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsOk());
4334 }
4335 }
4336
TEST_P(CertVerifyProcConstraintsTest,PolicyConstraints3Root)4337 TEST_P(CertVerifyProcConstraintsTest, PolicyConstraints3Root) {
4338 // Explicit policy is required after 3 certs. Since the chain is 4 certs
4339 // long, an explicit policy is required and the chain should fail if anchor
4340 // constraints are enforced.
4341 chain_[3]->SetPolicyConstraints(
4342 /*require_explicit_policy=*/3,
4343 /*inhibit_policy_mapping=*/std::nullopt);
4344
4345 if (VerifyProcTypeIsBuiltin()) {
4346 EXPECT_THAT(Verify(), IsOk());
4347 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsError(ERR_CERT_INVALID));
4348 } else {
4349 // Windows seems to have an off-by-one error in how it enforces
4350 // requireExplicitPolicy.
4351 // (The mac/android verifiers are Ok here since they don't enforce
4352 // policyConstraints on anchors.)
4353 EXPECT_THAT(Verify(), IsOk());
4354 }
4355 }
4356
TEST_P(CertVerifyProcConstraintsTest,PolicyConstraints2Root)4357 TEST_P(CertVerifyProcConstraintsTest, PolicyConstraints2Root) {
4358 // Explicit policy is required after 2 certs. Since the chain is 4 certs
4359 // long, an explicit policy is required and the chain should fail if anchor
4360 // constraints are enforced.
4361 chain_[3]->SetPolicyConstraints(
4362 /*require_explicit_policy=*/2,
4363 /*inhibit_policy_mapping=*/std::nullopt);
4364
4365 if (VerifyProcTypeIsBuiltin()) {
4366 EXPECT_THAT(Verify(), IsOk());
4367 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsError(ERR_CERT_INVALID));
4368 } else if (verify_proc_type() == CERT_VERIFY_PROC_IOS ||
4369 verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
4370 EXPECT_THAT(Verify(), IsOk());
4371 } else {
4372 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
4373 }
4374 }
4375
4376 // This is also a regression test for https://crbug.com/31497: If an
4377 // intermediate has requireExplicitPolicy in its policyConstraints extension,
4378 // verification should still succeed as long as some policy is valid for the
4379 // chain, since Chrome does not specify any required policy as an input to
4380 // certificate verification (allows anyPolicy).
TEST_P(CertVerifyProcConstraintsTest,PolicyConstraints0Intermediate)4381 TEST_P(CertVerifyProcConstraintsTest, PolicyConstraints0Intermediate) {
4382 for (bool leaf_has_policy : {false, true}) {
4383 SCOPED_TRACE(leaf_has_policy);
4384
4385 static const char kPolicy1[] = "1.2.3.4";
4386 static const char kPolicy2[] = "1.2.3.4.5";
4387 static const char kPolicy3[] = "1.2.3.5";
4388 chain_[2]->SetPolicyConstraints(
4389 /*require_explicit_policy=*/0,
4390 /*inhibit_policy_mapping=*/std::nullopt);
4391 chain_[2]->SetCertificatePolicies({kPolicy1, kPolicy2});
4392 chain_[1]->SetCertificatePolicies({kPolicy3, kPolicy1});
4393
4394 if (leaf_has_policy) {
4395 chain_[0]->SetCertificatePolicies({kPolicy1});
4396 EXPECT_THAT(Verify(), IsOk());
4397 if (VerifyProcTypeIsBuiltin()) {
4398 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsOk());
4399 }
4400 } else {
4401 chain_[0]->SetCertificatePolicies({});
4402 EXPECT_THAT(Verify(), IsError(ExpectedIntermediateConstraintError()));
4403 if (VerifyProcTypeIsBuiltin()) {
4404 EXPECT_THAT(VerifyWithExpiryAndConstraints(),
4405 IsError(ERR_CERT_INVALID));
4406 }
4407 }
4408 }
4409 }
4410
TEST_P(CertVerifyProcConstraintsTest,PolicyConstraints3Intermediate)4411 TEST_P(CertVerifyProcConstraintsTest, PolicyConstraints3Intermediate) {
4412 // Explicit policy is required after 3 certs. Since the chain up to
4413 // |chain_[2]| is 3 certs long, an explicit policy is never required.
4414 chain_[2]->SetPolicyConstraints(
4415 /*require_explicit_policy=*/3,
4416 /*inhibit_policy_mapping=*/std::nullopt);
4417
4418 EXPECT_THAT(Verify(), IsOk());
4419 if (VerifyProcTypeIsBuiltin()) {
4420 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsOk());
4421 }
4422 }
4423
TEST_P(CertVerifyProcConstraintsTest,PolicyConstraints2Intermediate)4424 TEST_P(CertVerifyProcConstraintsTest, PolicyConstraints2Intermediate) {
4425 // Explicit policy is required after 2 certs. Since the chain up to
4426 // |chain_[2]| is 3 certs long, an explicit policy will be required and this
4427 // should fail to verify.
4428 chain_[2]->SetPolicyConstraints(
4429 /*require_explicit_policy=*/2,
4430 /*inhibit_policy_mapping=*/std::nullopt);
4431
4432 EXPECT_THAT(Verify(), IsError(ExpectedIntermediateConstraintError()));
4433 if (VerifyProcTypeIsBuiltin()) {
4434 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsError(ERR_CERT_INVALID));
4435 }
4436 }
4437
TEST_P(CertVerifyProcConstraintsTest,PolicyConstraints1Intermediate)4438 TEST_P(CertVerifyProcConstraintsTest, PolicyConstraints1Intermediate) {
4439 // Explicit policy is required after 1 cert. Since the chain up to
4440 // |chain_[2]| is 3 certs long, an explicit policy will be required and this
4441 // should fail to verify.
4442 chain_[2]->SetPolicyConstraints(
4443 /*require_explicit_policy=*/1,
4444 /*inhibit_policy_mapping=*/std::nullopt);
4445
4446 EXPECT_THAT(Verify(), IsError(ExpectedIntermediateConstraintError()));
4447 if (VerifyProcTypeIsBuiltin()) {
4448 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsError(ERR_CERT_INVALID));
4449 }
4450 }
4451
TEST_P(CertVerifyProcConstraintsTest,PolicyConstraints0Leaf)4452 TEST_P(CertVerifyProcConstraintsTest, PolicyConstraints0Leaf) {
4453 // Setting requireExplicitPolicy to 0 on the target certificate should make
4454 // an explicit policy required for the chain. (Ref: RFC 5280 section 6.1.5.b
4455 // and the final paragraph of 6.1.5)
4456 chain_[0]->SetPolicyConstraints(
4457 /*require_explicit_policy=*/0,
4458 /*inhibit_policy_mapping=*/std::nullopt);
4459
4460 EXPECT_THAT(Verify(), IsError(ExpectedIntermediateConstraintError()));
4461 }
4462
TEST_P(CertVerifyProcConstraintsTest,InhibitPolicyMapping0Root)4463 TEST_P(CertVerifyProcConstraintsTest, InhibitPolicyMapping0Root) {
4464 static const char kPolicy1[] = "1.2.3.4";
4465 static const char kPolicy2[] = "1.2.3.5";
4466
4467 // Root inhibits policy mapping immediately.
4468 chain_[3]->SetPolicyConstraints(
4469 /*require_explicit_policy=*/std::nullopt,
4470 /*inhibit_policy_mapping=*/0);
4471
4472 // Policy constraints are specified on an intermediate so that an explicit
4473 // policy will be required regardless if root constraints are applied.
4474 chain_[2]->SetPolicyConstraints(
4475 /*require_explicit_policy=*/0,
4476 /*inhibit_policy_mapping=*/std::nullopt);
4477
4478 // Intermediate uses policy mappings. This should not be allowed if the root
4479 // constraints were enforced.
4480 chain_[2]->SetCertificatePolicies({kPolicy1});
4481 chain_[2]->SetPolicyMappings({{kPolicy1, kPolicy2}});
4482
4483 // Children require the policy mapping to have a valid policy.
4484 chain_[1]->SetCertificatePolicies({kPolicy2});
4485 chain_[0]->SetCertificatePolicies({kPolicy2});
4486
4487 if (VerifyProcTypeIsBuiltin()) {
4488 EXPECT_THAT(Verify(), IsOk());
4489 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsError(ERR_CERT_INVALID));
4490 } else if (verify_proc_type() == CERT_VERIFY_PROC_IOS ||
4491 verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
4492 EXPECT_THAT(Verify(), IsOk());
4493 } else {
4494 // Windows enforces inhibitPolicyMapping on the root.
4495 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
4496 }
4497 }
4498
TEST_P(CertVerifyProcConstraintsTest,InhibitPolicyMapping1Root)4499 TEST_P(CertVerifyProcConstraintsTest, InhibitPolicyMapping1Root) {
4500 static const char kPolicy1[] = "1.2.3.4";
4501 static const char kPolicy2[] = "1.2.3.5";
4502
4503 // Root inhibits policy mapping after 1 cert.
4504 chain_[3]->SetPolicyConstraints(
4505 /*require_explicit_policy=*/std::nullopt,
4506 /*inhibit_policy_mapping=*/1);
4507
4508 // Policy constraints are specified on an intermediate so that an explicit
4509 // policy will be required regardless if root constraints are applied.
4510 chain_[2]->SetPolicyConstraints(
4511 /*require_explicit_policy=*/0,
4512 /*inhibit_policy_mapping=*/std::nullopt);
4513
4514 // Intermediate uses policy mappings. This should be allowed even if the root
4515 // constraints were enforced, since policy mapping was allowed for 1 cert
4516 // following the root.
4517 chain_[2]->SetCertificatePolicies({kPolicy1});
4518 chain_[2]->SetPolicyMappings({{kPolicy1, kPolicy2}});
4519
4520 // Children require the policy mapping to have a valid policy.
4521 chain_[1]->SetCertificatePolicies({kPolicy2});
4522 chain_[0]->SetCertificatePolicies({kPolicy2});
4523
4524 EXPECT_THAT(Verify(), IsOk());
4525 if (VerifyProcTypeIsBuiltin()) {
4526 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsOk());
4527 }
4528 }
4529
TEST_P(CertVerifyProcConstraintsTest,InhibitAnyPolicy0Root)4530 TEST_P(CertVerifyProcConstraintsTest, InhibitAnyPolicy0Root) {
4531 static const char kAnyPolicy[] = "2.5.29.32.0";
4532 static const char kPolicy1[] = "1.2.3.4";
4533
4534 // Since inhibitAnyPolicy is 0, anyPolicy should not be allow for any certs
4535 // after the root.
4536 chain_[3]->SetInhibitAnyPolicy(0);
4537 chain_[3]->SetCertificatePolicies({kAnyPolicy});
4538
4539 // Policy constraints are specified on an intermediate so that an explicit
4540 // policy will be required regardless if root constraints are applied.
4541 chain_[2]->SetPolicyConstraints(
4542 /*require_explicit_policy=*/0,
4543 /*inhibit_policy_mapping=*/std::nullopt);
4544
4545 // This intermediate only asserts anyPolicy, so this chain should
4546 // be invalid if policyConstraints from the root cert are enforced.
4547 chain_[2]->SetCertificatePolicies({kAnyPolicy});
4548
4549 chain_[1]->SetCertificatePolicies({kPolicy1});
4550 chain_[0]->SetCertificatePolicies({kPolicy1});
4551
4552 if (VerifyProcTypeIsBuiltin()) {
4553 EXPECT_THAT(Verify(), IsOk());
4554 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsError(ERR_CERT_INVALID));
4555 } else if (verify_proc_type() == CERT_VERIFY_PROC_IOS ||
4556 verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
4557 EXPECT_THAT(Verify(), IsOk());
4558 } else {
4559 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
4560 }
4561 }
4562
TEST_P(CertVerifyProcConstraintsTest,InhibitAnyPolicy1Root)4563 TEST_P(CertVerifyProcConstraintsTest, InhibitAnyPolicy1Root) {
4564 for (bool chain_1_has_any_policy : {false, true}) {
4565 SCOPED_TRACE(chain_1_has_any_policy);
4566
4567 static const char kAnyPolicy[] = "2.5.29.32.0";
4568 static const char kPolicy1[] = "1.2.3.4";
4569
4570 // Since inhibitAnyPolicy is 1, anyPolicy should be allowed for the root's
4571 // immediate child, but not after that.
4572 chain_[3]->SetInhibitAnyPolicy(1);
4573 chain_[3]->SetCertificatePolicies({kAnyPolicy});
4574
4575 // Policy constraints are specified on an intermediate so that an explicit
4576 // policy will be required regardless if root constraints are applied.
4577 chain_[2]->SetPolicyConstraints(
4578 /*require_explicit_policy=*/0,
4579 /*inhibit_policy_mapping=*/std::nullopt);
4580
4581 // AnyPolicy should be allowed in this cert.
4582 chain_[2]->SetCertificatePolicies({kAnyPolicy});
4583
4584 chain_[0]->SetCertificatePolicies({kPolicy1});
4585
4586 if (chain_1_has_any_policy) {
4587 // AnyPolicy should not be allowed in this cert if the inhibitAnyPolicy
4588 // constraint from the root is honored.
4589 chain_[1]->SetCertificatePolicies({kAnyPolicy});
4590
4591 if (VerifyProcTypeIsBuiltin()) {
4592 EXPECT_THAT(Verify(), IsOk());
4593 EXPECT_THAT(VerifyWithExpiryAndConstraints(),
4594 IsError(ERR_CERT_INVALID));
4595 } else if (verify_proc_type() == CERT_VERIFY_PROC_IOS ||
4596 verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
4597 EXPECT_THAT(Verify(), IsOk());
4598 } else {
4599 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
4600 }
4601 } else {
4602 chain_[1]->SetCertificatePolicies({kPolicy1});
4603
4604 EXPECT_THAT(Verify(), IsOk());
4605 if (VerifyProcTypeIsBuiltin()) {
4606 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsOk());
4607 }
4608 }
4609 }
4610 }
4611
TEST_P(CertVerifyProcConstraintsTest,InhibitAnyPolicy0Intermediate)4612 TEST_P(CertVerifyProcConstraintsTest, InhibitAnyPolicy0Intermediate) {
4613 static const char kAnyPolicy[] = "2.5.29.32.0";
4614 static const char kPolicy1[] = "1.2.3.4";
4615
4616 chain_[2]->SetInhibitAnyPolicy(0);
4617 chain_[2]->SetPolicyConstraints(
4618 /*require_explicit_policy=*/0,
4619 /*inhibit_policy_mapping=*/std::nullopt);
4620
4621 chain_[2]->SetCertificatePolicies({kAnyPolicy});
4622 // This shouldn't be allowed as the parent cert set inhibitAnyPolicy=0.
4623 chain_[1]->SetCertificatePolicies({kAnyPolicy});
4624 chain_[0]->SetCertificatePolicies({kPolicy1});
4625
4626 EXPECT_THAT(Verify(), IsError(ExpectedIntermediateConstraintError()));
4627 }
4628
TEST_P(CertVerifyProcConstraintsTest,InhibitAnyPolicy1Intermediate)4629 TEST_P(CertVerifyProcConstraintsTest, InhibitAnyPolicy1Intermediate) {
4630 static const char kAnyPolicy[] = "2.5.29.32.0";
4631 static const char kPolicy1[] = "1.2.3.4";
4632
4633 chain_[2]->SetInhibitAnyPolicy(1);
4634 chain_[2]->SetPolicyConstraints(
4635 /*require_explicit_policy=*/0,
4636 /*inhibit_policy_mapping=*/std::nullopt);
4637
4638 chain_[2]->SetCertificatePolicies({kAnyPolicy});
4639 // This is okay as the parent cert set inhibitAnyPolicy=1.
4640 chain_[1]->SetCertificatePolicies({kAnyPolicy});
4641 chain_[0]->SetCertificatePolicies({kPolicy1});
4642
4643 EXPECT_THAT(Verify(), IsOk());
4644 }
4645
TEST_P(CertVerifyProcConstraintsTest,PoliciesRoot)4646 TEST_P(CertVerifyProcConstraintsTest, PoliciesRoot) {
4647 static const char kPolicy1[] = "1.2.3.4";
4648 static const char kPolicy2[] = "1.2.3.5";
4649
4650 for (bool root_has_matching_policy : {false, true}) {
4651 SCOPED_TRACE(root_has_matching_policy);
4652
4653 if (root_has_matching_policy) {
4654 // This chain should be valid whether or not policies from the root are
4655 // processed.
4656 chain_[3]->SetCertificatePolicies({kPolicy1});
4657 } else {
4658 // If the policies from the root are processed, this chain will not be
4659 // valid for any policy.
4660 chain_[3]->SetCertificatePolicies({kPolicy2});
4661 }
4662
4663 // Policy constraints are specified on an intermediate so that an explicit
4664 // policy will be required regardless if root constraints are applied.
4665 chain_[2]->SetPolicyConstraints(
4666 /*require_explicit_policy=*/0,
4667 /*inhibit_policy_mapping=*/std::nullopt);
4668
4669 chain_[2]->SetCertificatePolicies({kPolicy1});
4670 chain_[1]->SetCertificatePolicies({kPolicy1});
4671 chain_[0]->SetCertificatePolicies({kPolicy1});
4672
4673 if (root_has_matching_policy) {
4674 EXPECT_THAT(Verify(), IsOk());
4675 if (VerifyProcTypeIsBuiltin()) {
4676 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsOk());
4677 }
4678 } else {
4679 if (VerifyProcTypeIsBuiltin()) {
4680 EXPECT_THAT(Verify(), IsOk());
4681 EXPECT_THAT(VerifyWithExpiryAndConstraints(),
4682 IsError(ERR_CERT_INVALID));
4683 } else if (verify_proc_type() == CERT_VERIFY_PROC_IOS ||
4684 verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
4685 EXPECT_THAT(Verify(), IsOk());
4686 } else {
4687 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
4688 }
4689 }
4690 }
4691 }
4692
TEST_P(CertVerifyProcConstraintsTest,PolicyMappingsRoot)4693 TEST_P(CertVerifyProcConstraintsTest, PolicyMappingsRoot) {
4694 static const char kPolicy1[] = "1.2.3.4";
4695 static const char kPolicy2[] = "1.2.3.5";
4696 static const char kPolicy3[] = "1.2.3.6";
4697
4698 for (bool root_has_matching_policy_mapping : {false, true}) {
4699 SCOPED_TRACE(root_has_matching_policy_mapping);
4700
4701 if (root_has_matching_policy_mapping) {
4702 // This chain should be valid if the policies and policy mapping on the
4703 // root are processed, or if neither is processed. It will not be valid
4704 // if the policies were processed and the policyMappings were not.
4705 chain_[3]->SetCertificatePolicies({kPolicy1});
4706 chain_[3]->SetPolicyMappings({{kPolicy1, kPolicy2}});
4707 } else {
4708 // This chain should not be valid if the policies and policyMappings on
4709 // the root were processed. It will be valid if the policies were
4710 // processed and policyMappings were not.
4711 chain_[3]->SetCertificatePolicies({kPolicy2});
4712 chain_[3]->SetPolicyMappings({{kPolicy2, kPolicy3}});
4713 }
4714
4715 // Policy constraints are specified on an intermediate so that an explicit
4716 // policy will be required regardless if root constraints are applied.
4717 chain_[2]->SetPolicyConstraints(
4718 /*require_explicit_policy=*/0,
4719 /*inhibit_policy_mapping=*/std::nullopt);
4720
4721 chain_[2]->SetCertificatePolicies({kPolicy2});
4722 chain_[1]->SetCertificatePolicies({kPolicy2});
4723 chain_[0]->SetCertificatePolicies({kPolicy2});
4724
4725 if (root_has_matching_policy_mapping) {
4726 EXPECT_THAT(Verify(), IsOk());
4727 if (VerifyProcTypeIsBuiltin()) {
4728 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsOk());
4729 }
4730 } else {
4731 if (VerifyProcTypeIsBuiltin()) {
4732 EXPECT_THAT(Verify(), IsOk());
4733 EXPECT_THAT(VerifyWithExpiryAndConstraints(),
4734 IsError(ERR_CERT_INVALID));
4735 } else if (verify_proc_type() == CERT_VERIFY_PROC_IOS ||
4736 verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
4737 EXPECT_THAT(Verify(), IsOk());
4738 } else {
4739 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
4740 }
4741 }
4742 }
4743 }
4744
TEST_P(CertVerifyProcConstraintsTest,KeyUsageNoCertSignRoot)4745 TEST_P(CertVerifyProcConstraintsTest, KeyUsageNoCertSignRoot) {
4746 chain_[3]->SetKeyUsages({bssl::KEY_USAGE_BIT_CRL_SIGN});
4747
4748 if (VerifyProcTypeIsBuiltin()) {
4749 EXPECT_THAT(Verify(), IsOk());
4750 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsError(ERR_CERT_INVALID));
4751 EXPECT_THAT(VerifyWithExpiryAndFullConstraints(),
4752 IsError(ERR_CERT_INVALID));
4753 } else if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
4754 EXPECT_THAT(Verify(), IsOk());
4755 } else {
4756 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
4757 }
4758 }
4759
TEST_P(CertVerifyProcConstraintsTest,KeyUsageNotPresentRoot)4760 TEST_P(CertVerifyProcConstraintsTest, KeyUsageNotPresentRoot) {
4761 chain_[3]->EraseExtension(bssl::der::Input(bssl::kKeyUsageOid));
4762
4763 EXPECT_THAT(Verify(), IsOk());
4764 if (VerifyProcTypeIsBuiltin()) {
4765 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsOk());
4766 EXPECT_THAT(VerifyWithExpiryAndFullConstraints(), IsOk());
4767 }
4768 }
4769
TEST_P(CertVerifyProcConstraintsTest,KeyUsageNoCertSignIntermediate)4770 TEST_P(CertVerifyProcConstraintsTest, KeyUsageNoCertSignIntermediate) {
4771 chain_[2]->SetKeyUsages({bssl::KEY_USAGE_BIT_CRL_SIGN});
4772
4773 EXPECT_THAT(Verify(), IsError(ExpectedIntermediateConstraintError()));
4774 }
4775
TEST_P(CertVerifyProcConstraintsTest,KeyUsageNotPresentIntermediate)4776 TEST_P(CertVerifyProcConstraintsTest, KeyUsageNotPresentIntermediate) {
4777 chain_[2]->EraseExtension(bssl::der::Input(bssl::kKeyUsageOid));
4778
4779 EXPECT_THAT(Verify(), IsOk());
4780 }
4781
TEST_P(CertVerifyProcConstraintsTest,KeyUsageNoDigitalSignatureLeaf)4782 TEST_P(CertVerifyProcConstraintsTest, KeyUsageNoDigitalSignatureLeaf) {
4783 // This test is mostly uninteresting since keyUsage on the end-entity is only
4784 // checked at the TLS layer, not during cert verification.
4785 chain_[0]->SetKeyUsages({bssl::KEY_USAGE_BIT_CRL_SIGN});
4786
4787 EXPECT_THAT(Verify(), IsOk());
4788 }
4789
TEST_P(CertVerifyProcConstraintsTest,KeyUsageNotPresentLeaf)4790 TEST_P(CertVerifyProcConstraintsTest, KeyUsageNotPresentLeaf) {
4791 // This test is mostly uninteresting since keyUsage on the end-entity is only
4792 // checked at the TLS layer, not during cert verification.
4793 chain_[0]->EraseExtension(bssl::der::Input(bssl::kKeyUsageOid));
4794
4795 EXPECT_THAT(Verify(), IsOk());
4796 }
4797
TEST_P(CertVerifyProcConstraintsTest,KeyUsageCertSignLeaf)4798 TEST_P(CertVerifyProcConstraintsTest, KeyUsageCertSignLeaf) {
4799 // Test a leaf that has keyUsage asserting keyCertSign and basicConstraints
4800 // asserting CA=false. This should be an error according to 5280 section
4801 // 4.2.1.3 and 4.2.1.9, however most implementations seem to allow it.
4802 // Perhaps because 5280 section 6 does not explicitly say to enforce this on
4803 // the target cert.
4804 chain_[0]->SetKeyUsages({bssl::KEY_USAGE_BIT_KEY_CERT_SIGN,
4805 bssl::KEY_USAGE_BIT_DIGITAL_SIGNATURE});
4806
4807 EXPECT_THAT(Verify(), IsOk());
4808 if (VerifyProcTypeIsBuiltin()) {
4809 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsOk());
4810 EXPECT_THAT(VerifyWithExpiryAndFullConstraints(), IsOk());
4811 }
4812 }
4813
TEST_P(CertVerifyProcConstraintsTest,ExtendedKeyUsageNoServerAuthRoot)4814 TEST_P(CertVerifyProcConstraintsTest, ExtendedKeyUsageNoServerAuthRoot) {
4815 chain_[3]->SetExtendedKeyUsages({bssl::der::Input(bssl::kCodeSigning)});
4816
4817 if (VerifyProcTypeIsBuiltin()) {
4818 EXPECT_THAT(Verify(), IsOk());
4819 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsError(ERR_CERT_INVALID));
4820 EXPECT_THAT(VerifyWithExpiryAndFullConstraints(),
4821 IsError(ERR_CERT_INVALID));
4822 } else if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID ||
4823 verify_proc_type() == CERT_VERIFY_PROC_IOS) {
4824 EXPECT_THAT(Verify(), IsOk());
4825 } else {
4826 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
4827 }
4828 }
4829
TEST_P(CertVerifyProcConstraintsTest,ExtendedKeyUsageServerAuthRoot)4830 TEST_P(CertVerifyProcConstraintsTest, ExtendedKeyUsageServerAuthRoot) {
4831 chain_[3]->SetExtendedKeyUsages({bssl::der::Input(bssl::kServerAuth)});
4832
4833 EXPECT_THAT(Verify(), IsOk());
4834 if (VerifyProcTypeIsBuiltin()) {
4835 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsOk());
4836 }
4837 }
4838
TEST_P(CertVerifyProcConstraintsTest,ExtendedKeyUsageNoServerAuthIntermediate)4839 TEST_P(CertVerifyProcConstraintsTest,
4840 ExtendedKeyUsageNoServerAuthIntermediate) {
4841 chain_[2]->SetExtendedKeyUsages({bssl::der::Input(bssl::kCodeSigning)});
4842
4843 if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID ||
4844 VerifyProcTypeIsIOSAtMostOS15()) {
4845 EXPECT_THAT(Verify(), IsOk());
4846 } else {
4847 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
4848 }
4849 }
4850
TEST_P(CertVerifyProcConstraintsTest,ExtendedKeyUsageServerAuthIntermediate)4851 TEST_P(CertVerifyProcConstraintsTest, ExtendedKeyUsageServerAuthIntermediate) {
4852 chain_[2]->SetExtendedKeyUsages({bssl::der::Input(bssl::kServerAuth)});
4853
4854 EXPECT_THAT(Verify(), IsOk());
4855 }
4856
TEST_P(CertVerifyProcConstraintsTest,ExtendedKeyUsageNoServerAuthLeaf)4857 TEST_P(CertVerifyProcConstraintsTest, ExtendedKeyUsageNoServerAuthLeaf) {
4858 chain_[0]->SetExtendedKeyUsages({bssl::der::Input(bssl::kCodeSigning)});
4859
4860 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
4861 }
4862
TEST_P(CertVerifyProcConstraintsTest,UnknownSignatureAlgorithmRoot)4863 TEST_P(CertVerifyProcConstraintsTest, UnknownSignatureAlgorithmRoot) {
4864 chain_[3]->SetSignatureAlgorithmTLV(TestOid0SignatureAlgorithmTLV());
4865
4866 EXPECT_THAT(Verify(), IsOk());
4867 if (VerifyProcTypeIsBuiltin()) {
4868 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsOk());
4869 }
4870 }
4871
TEST_P(CertVerifyProcConstraintsTest,UnknownSignatureAlgorithmIntermediate)4872 TEST_P(CertVerifyProcConstraintsTest, UnknownSignatureAlgorithmIntermediate) {
4873 chain_[2]->SetSignatureAlgorithmTLV(TestOid0SignatureAlgorithmTLV());
4874
4875 if (verify_proc_type() == CERT_VERIFY_PROC_IOS) {
4876 EXPECT_THAT(Verify(), IsError(ERR_CERT_AUTHORITY_INVALID));
4877 } else {
4878 EXPECT_THAT(Verify(), IsError(ExpectedIntermediateConstraintError()));
4879 }
4880 }
4881
TEST_P(CertVerifyProcConstraintsTest,UnknownSignatureAlgorithmLeaf)4882 TEST_P(CertVerifyProcConstraintsTest, UnknownSignatureAlgorithmLeaf) {
4883 chain_[0]->SetSignatureAlgorithmTLV(TestOid0SignatureAlgorithmTLV());
4884
4885 if (verify_proc_type() == CERT_VERIFY_PROC_IOS) {
4886 EXPECT_THAT(Verify(), IsError(ERR_CERT_AUTHORITY_INVALID));
4887 } else {
4888 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
4889 }
4890 }
4891
TEST_P(CertVerifyProcConstraintsTest,UnknownExtensionRoot)4892 TEST_P(CertVerifyProcConstraintsTest, UnknownExtensionRoot) {
4893 for (bool critical : {true, false}) {
4894 SCOPED_TRACE(critical);
4895 chain_[3]->SetExtension(TestOid0(), "hello world", critical);
4896
4897 if (critical) {
4898 if (VerifyProcTypeIsBuiltin()) {
4899 EXPECT_THAT(Verify(), IsOk());
4900 EXPECT_THAT(VerifyWithExpiryAndConstraints(),
4901 IsError(ERR_CERT_INVALID));
4902 EXPECT_THAT(VerifyWithExpiryAndFullConstraints(),
4903 IsError(ERR_CERT_INVALID));
4904 } else if (verify_proc_type() == CERT_VERIFY_PROC_IOS ||
4905 verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
4906 EXPECT_THAT(Verify(), IsOk());
4907 } else {
4908 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
4909 }
4910 } else {
4911 EXPECT_THAT(Verify(), IsOk());
4912 if (VerifyProcTypeIsBuiltin()) {
4913 EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsOk());
4914 }
4915 }
4916 }
4917 }
4918
TEST_P(CertVerifyProcConstraintsTest,UnknownExtensionIntermediate)4919 TEST_P(CertVerifyProcConstraintsTest, UnknownExtensionIntermediate) {
4920 for (bool critical : {true, false}) {
4921 SCOPED_TRACE(critical);
4922 chain_[2]->SetExtension(TestOid0(), "hello world", critical);
4923
4924 if (critical) {
4925 EXPECT_THAT(Verify(), IsError(ExpectedIntermediateConstraintError()));
4926 } else {
4927 EXPECT_THAT(Verify(), IsOk());
4928 }
4929 }
4930 }
4931
TEST_P(CertVerifyProcConstraintsTest,UnknownExtensionLeaf)4932 TEST_P(CertVerifyProcConstraintsTest, UnknownExtensionLeaf) {
4933 for (bool critical : {true, false}) {
4934 SCOPED_TRACE(critical);
4935 chain_[0]->SetExtension(TestOid0(), "hello world", critical);
4936
4937 if (critical) {
4938 EXPECT_THAT(Verify(), IsError(ExpectedIntermediateConstraintError()));
4939 } else {
4940 EXPECT_THAT(Verify(), IsOk());
4941 }
4942 }
4943 }
4944
4945 // A set of tests that check how various constraints are enforced when they
4946 // are applied to a directly trusted non-self-signed leaf certificate.
4947 class CertVerifyProcConstraintsTrustedLeafTest
4948 : public CertVerifyProcInternalTest {
4949 protected:
SetUp()4950 void SetUp() override {
4951 CertVerifyProcInternalTest::SetUp();
4952
4953 chain_ = CertBuilder::CreateSimpleChain(/*chain_length=*/2);
4954 }
4955
VerifyWithTrust(bssl::CertificateTrust trust)4956 int VerifyWithTrust(bssl::CertificateTrust trust) {
4957 ScopedTestRoot test_root(chain_[0]->GetX509Certificate(), trust);
4958 CertVerifyResult verify_result;
4959 int flags = 0;
4960 return CertVerifyProcInternalTest::Verify(
4961 chain_.front()->GetX509Certificate().get(), "www.example.com", flags,
4962 &verify_result);
4963 }
4964
Verify()4965 int Verify() {
4966 return VerifyWithTrust(bssl::CertificateTrust::ForTrustAnchor());
4967 }
4968
VerifyAsTrustedLeaf()4969 int VerifyAsTrustedLeaf() {
4970 return VerifyWithTrust(bssl::CertificateTrust::ForTrustedLeaf());
4971 }
4972
4973 std::vector<std::unique_ptr<CertBuilder>> chain_;
4974 };
4975
4976 INSTANTIATE_TEST_SUITE_P(All,
4977 CertVerifyProcConstraintsTrustedLeafTest,
4978 testing::ValuesIn(kAllCertVerifiers),
4979 VerifyProcTypeToName);
4980
TEST_P(CertVerifyProcConstraintsTrustedLeafTest,BaseCase)4981 TEST_P(CertVerifyProcConstraintsTrustedLeafTest, BaseCase) {
4982 // Without changing anything on the test chain, it should validate
4983 // successfully. If this is not true then the rest of the tests in this class
4984 // are unlikely to be useful.
4985 if (VerifyProcTypeIsBuiltin()) {
4986 EXPECT_THAT(Verify(), IsError(ERR_CERT_AUTHORITY_INVALID));
4987 EXPECT_THAT(VerifyAsTrustedLeaf(), IsOk());
4988 EXPECT_THAT(VerifyWithTrust(bssl::CertificateTrust::ForTrustAnchorOrLeaf()),
4989 IsOk());
4990 EXPECT_THAT(VerifyWithTrust(bssl::CertificateTrust::ForTrustedLeaf()
4991 .WithRequireLeafSelfSigned()),
4992 IsError(ERR_CERT_AUTHORITY_INVALID));
4993 EXPECT_THAT(VerifyWithTrust(bssl::CertificateTrust::ForTrustAnchorOrLeaf()
4994 .WithRequireLeafSelfSigned()),
4995 IsError(ERR_CERT_AUTHORITY_INVALID));
4996 } else {
4997 EXPECT_THAT(Verify(), IsOk());
4998 }
4999 }
5000
TEST_P(CertVerifyProcConstraintsTrustedLeafTest,RootAlsoTrusted)5001 TEST_P(CertVerifyProcConstraintsTrustedLeafTest, RootAlsoTrusted) {
5002 // Test verifying a chain where both the leaf and the root are marked as
5003 // trusted.
5004 // (Repeating the ScopedTestRoot before each call is due to the limitation
5005 // with destroying any ScopedTestRoot removing all test roots.)
5006 {
5007 ScopedTestRoot test_root(chain_[1]->GetX509Certificate());
5008 EXPECT_THAT(Verify(), IsOk());
5009 }
5010
5011 if (VerifyProcTypeIsBuiltin()) {
5012 {
5013 ScopedTestRoot test_root1(chain_[1]->GetX509Certificate());
5014 // An explicit trust entry for the leaf with a value of Unspecified
5015 // should be no different than the leaf not being in the trust store at
5016 // all.
5017 EXPECT_THAT(VerifyWithTrust(bssl::CertificateTrust::ForUnspecified()),
5018 IsOk());
5019 }
5020 {
5021 ScopedTestRoot test_root1(chain_[1]->GetX509Certificate());
5022 // If the leaf is explicitly distrusted, verification should fail even if
5023 // the root is trusted.
5024 EXPECT_THAT(VerifyWithTrust(bssl::CertificateTrust::ForDistrusted()),
5025 IsError(ERR_CERT_AUTHORITY_INVALID));
5026 }
5027 {
5028 ScopedTestRoot test_root(chain_[1]->GetX509Certificate());
5029 EXPECT_THAT(VerifyAsTrustedLeaf(), IsOk());
5030 }
5031 {
5032 ScopedTestRoot test_root(chain_[1]->GetX509Certificate());
5033 EXPECT_THAT(
5034 VerifyWithTrust(bssl::CertificateTrust::ForTrustAnchorOrLeaf()),
5035 IsOk());
5036 }
5037 {
5038 ScopedTestRoot test_root(chain_[1]->GetX509Certificate());
5039 EXPECT_THAT(
5040 VerifyWithTrust(bssl::CertificateTrust::ForTrustAnchorOrLeaf()),
5041 IsOk());
5042 }
5043 {
5044 ScopedTestRoot test_root(chain_[1]->GetX509Certificate());
5045 EXPECT_THAT(VerifyWithTrust(bssl::CertificateTrust::ForTrustAnchorOrLeaf()
5046 .WithRequireLeafSelfSigned()),
5047 IsOk());
5048 }
5049 }
5050 }
5051
TEST_P(CertVerifyProcConstraintsTrustedLeafTest,BasicConstraintsIsCa)5052 TEST_P(CertVerifyProcConstraintsTrustedLeafTest, BasicConstraintsIsCa) {
5053 for (bool has_key_usage_cert_sign : {false, true}) {
5054 chain_[0]->SetBasicConstraints(/*is_ca=*/true, /*path_len=*/-1);
5055
5056 if (has_key_usage_cert_sign) {
5057 chain_[0]->SetKeyUsages({bssl::KEY_USAGE_BIT_KEY_CERT_SIGN,
5058 bssl::KEY_USAGE_BIT_DIGITAL_SIGNATURE});
5059 } else {
5060 chain_[0]->SetKeyUsages({bssl::KEY_USAGE_BIT_DIGITAL_SIGNATURE});
5061 }
5062
5063 if (VerifyProcTypeIsBuiltin()) {
5064 EXPECT_THAT(Verify(), IsError(ERR_CERT_AUTHORITY_INVALID));
5065 EXPECT_THAT(VerifyAsTrustedLeaf(), IsOk());
5066 } else {
5067 EXPECT_THAT(Verify(), IsOk());
5068 }
5069 }
5070 }
5071
TEST_P(CertVerifyProcConstraintsTrustedLeafTest,BasicConstraintsPathlen)5072 TEST_P(CertVerifyProcConstraintsTrustedLeafTest, BasicConstraintsPathlen) {
5073 chain_[0]->SetBasicConstraints(/*is_ca=*/false, /*path_len=*/0);
5074
5075 if (VerifyProcTypeIsBuiltin()) {
5076 EXPECT_THAT(Verify(), IsError(ERR_CERT_AUTHORITY_INVALID));
5077 } else {
5078 EXPECT_THAT(Verify(), IsOk());
5079 }
5080 }
5081
TEST_P(CertVerifyProcConstraintsTrustedLeafTest,BasicConstraintsMissing)5082 TEST_P(CertVerifyProcConstraintsTrustedLeafTest, BasicConstraintsMissing) {
5083 chain_[0]->EraseExtension(bssl::der::Input(bssl::kBasicConstraintsOid));
5084
5085 if (VerifyProcTypeIsBuiltin()) {
5086 EXPECT_THAT(Verify(), IsError(ERR_CERT_AUTHORITY_INVALID));
5087 EXPECT_THAT(VerifyAsTrustedLeaf(), IsOk());
5088 } else {
5089 EXPECT_THAT(Verify(), IsOk());
5090 }
5091 }
5092
TEST_P(CertVerifyProcConstraintsTrustedLeafTest,NameConstraintsNotMatching)5093 TEST_P(CertVerifyProcConstraintsTrustedLeafTest, NameConstraintsNotMatching) {
5094 chain_[0]->SetNameConstraintsDnsNames(/*permitted_dns_names=*/{"example.org"},
5095 /*excluded_dns_names=*/{});
5096
5097 if (VerifyProcTypeIsBuiltin()) {
5098 EXPECT_THAT(Verify(), IsError(ERR_CERT_AUTHORITY_INVALID));
5099 } else {
5100 EXPECT_THAT(Verify(), IsOk());
5101 }
5102 }
5103
TEST_P(CertVerifyProcConstraintsTrustedLeafTest,ValidityExpired)5104 TEST_P(CertVerifyProcConstraintsTrustedLeafTest, ValidityExpired) {
5105 chain_[0]->SetValidity(base::Time::Now() - base::Days(14),
5106 base::Time::Now() - base::Days(7));
5107
5108 if (VerifyProcTypeIsBuiltin()) {
5109 EXPECT_THAT(Verify(), IsError(ERR_CERT_AUTHORITY_INVALID));
5110 EXPECT_THAT(VerifyAsTrustedLeaf(), IsError(ERR_CERT_DATE_INVALID));
5111 } else {
5112 EXPECT_THAT(Verify(), IsError(ERR_CERT_DATE_INVALID));
5113 }
5114 }
5115
TEST_P(CertVerifyProcConstraintsTrustedLeafTest,PolicyConstraints)5116 TEST_P(CertVerifyProcConstraintsTrustedLeafTest, PolicyConstraints) {
5117 static const char kPolicy1[] = "1.2.3.4";
5118
5119 for (bool leaf_has_policy : {false, true}) {
5120 SCOPED_TRACE(leaf_has_policy);
5121
5122 chain_[0]->SetPolicyConstraints(
5123 /*require_explicit_policy=*/0,
5124 /*inhibit_policy_mapping=*/std::nullopt);
5125 if (leaf_has_policy) {
5126 chain_[0]->SetCertificatePolicies({kPolicy1});
5127 } else {
5128 chain_[0]->SetCertificatePolicies({});
5129 }
5130
5131 if (VerifyProcTypeIsBuiltin()) {
5132 EXPECT_THAT(Verify(), IsError(ERR_CERT_AUTHORITY_INVALID));
5133 EXPECT_THAT(VerifyAsTrustedLeaf(), IsOk());
5134 } else {
5135 // Succeeds since the ios/android verifiers appear to not enforce
5136 // this constraint in the "directly trusted leaf" case.
5137 EXPECT_THAT(Verify(), IsOk());
5138 }
5139 }
5140 }
5141
TEST_P(CertVerifyProcConstraintsTrustedLeafTest,InhibitAnyPolicy)5142 TEST_P(CertVerifyProcConstraintsTrustedLeafTest, InhibitAnyPolicy) {
5143 static const char kAnyPolicy[] = "2.5.29.32.0";
5144 chain_[0]->SetPolicyConstraints(
5145 /*require_explicit_policy=*/0,
5146 /*inhibit_policy_mapping=*/std::nullopt);
5147 chain_[0]->SetInhibitAnyPolicy(0);
5148 chain_[0]->SetCertificatePolicies({kAnyPolicy});
5149
5150 if (VerifyProcTypeIsBuiltin()) {
5151 EXPECT_THAT(Verify(), IsError(ERR_CERT_AUTHORITY_INVALID));
5152 EXPECT_THAT(VerifyAsTrustedLeaf(), IsOk());
5153 } else {
5154 EXPECT_THAT(Verify(), IsOk());
5155 }
5156 }
5157
TEST_P(CertVerifyProcConstraintsTrustedLeafTest,KeyUsageNoDigitalSignature)5158 TEST_P(CertVerifyProcConstraintsTrustedLeafTest, KeyUsageNoDigitalSignature) {
5159 // This test is mostly uninteresting since keyUsage on the end-entity is only
5160 // checked at the TLS layer, not during cert verification.
5161 chain_[0]->SetKeyUsages({bssl::KEY_USAGE_BIT_CRL_SIGN});
5162
5163 if (VerifyProcTypeIsBuiltin()) {
5164 EXPECT_THAT(Verify(), IsError(ERR_CERT_AUTHORITY_INVALID));
5165 EXPECT_THAT(VerifyAsTrustedLeaf(), IsOk());
5166 } else {
5167 EXPECT_THAT(Verify(), IsOk());
5168 }
5169 }
5170
TEST_P(CertVerifyProcConstraintsTrustedLeafTest,KeyUsageCertSignLeaf)5171 TEST_P(CertVerifyProcConstraintsTrustedLeafTest, KeyUsageCertSignLeaf) {
5172 // Test a leaf that has keyUsage asserting keyCertSign with basicConstraints
5173 // CA=false, which is an error according to 5280 (4.2.1.3 and 4.2.1.9).
5174 chain_[0]->SetKeyUsages({bssl::KEY_USAGE_BIT_KEY_CERT_SIGN,
5175 bssl::KEY_USAGE_BIT_DIGITAL_SIGNATURE});
5176
5177 if (VerifyProcTypeIsBuiltin()) {
5178 EXPECT_THAT(Verify(), IsError(ERR_CERT_AUTHORITY_INVALID));
5179 EXPECT_THAT(VerifyAsTrustedLeaf(), IsOk());
5180 } else {
5181 EXPECT_THAT(Verify(), IsOk());
5182 }
5183 }
5184
TEST_P(CertVerifyProcConstraintsTrustedLeafTest,ExtendedKeyUsageNoServerAuth)5185 TEST_P(CertVerifyProcConstraintsTrustedLeafTest, ExtendedKeyUsageNoServerAuth) {
5186 chain_[0]->SetExtendedKeyUsages({bssl::der::Input(bssl::kCodeSigning)});
5187
5188 if (VerifyProcTypeIsBuiltin()) {
5189 EXPECT_THAT(Verify(), IsError(ERR_CERT_AUTHORITY_INVALID));
5190 EXPECT_THAT(VerifyAsTrustedLeaf(), IsError(ERR_CERT_INVALID));
5191 } else {
5192 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
5193 }
5194 }
5195
TEST_P(CertVerifyProcConstraintsTrustedLeafTest,UnknownSignatureAlgorithm)5196 TEST_P(CertVerifyProcConstraintsTrustedLeafTest, UnknownSignatureAlgorithm) {
5197 chain_[0]->SetSignatureAlgorithmTLV(TestOid0SignatureAlgorithmTLV());
5198
5199 if (VerifyProcTypeIsBuiltin()) {
5200 // Since no chain is found, signature is not checked, fails with generic
5201 // error for untrusted chain.
5202 EXPECT_THAT(Verify(), IsError(ERR_CERT_AUTHORITY_INVALID));
5203 // Valid since signature on directly trusted leaf is not checked.
5204 EXPECT_THAT(VerifyAsTrustedLeaf(), IsOk());
5205 } else {
5206 EXPECT_THAT(Verify(), IsOk());
5207 }
5208 }
5209
TEST_P(CertVerifyProcConstraintsTrustedLeafTest,WeakSignatureAlgorithm)5210 TEST_P(CertVerifyProcConstraintsTrustedLeafTest, WeakSignatureAlgorithm) {
5211 chain_[0]->SetSignatureAlgorithm(bssl::SignatureAlgorithm::kEcdsaSha1);
5212
5213 if (VerifyProcTypeIsBuiltin()) {
5214 // Since no chain is found, signature is not checked, fails with generic
5215 // error for untrusted chain.
5216 EXPECT_THAT(Verify(), IsError(ERR_CERT_AUTHORITY_INVALID));
5217
5218 // Valid since signature on directly trusted leaf is not checked.
5219 EXPECT_THAT(VerifyAsTrustedLeaf(), IsOk());
5220
5221 // Cert is not self-signed so directly trusted leaf with
5222 // require_leaf_selfsigned should fail.
5223 EXPECT_THAT(VerifyWithTrust(bssl::CertificateTrust::ForTrustedLeaf()
5224 .WithRequireLeafSelfSigned()),
5225 IsError(ERR_CERT_AUTHORITY_INVALID));
5226 } else if (verify_proc_type() == CERT_VERIFY_PROC_IOS) {
5227 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
5228 } else {
5229 EXPECT_THAT(Verify(), IsOk());
5230 }
5231 }
5232
TEST_P(CertVerifyProcConstraintsTrustedLeafTest,UnknownExtension)5233 TEST_P(CertVerifyProcConstraintsTrustedLeafTest, UnknownExtension) {
5234 for (bool critical : {true, false}) {
5235 SCOPED_TRACE(critical);
5236 chain_[0]->SetExtension(TestOid0(), "hello world", critical);
5237
5238 if (VerifyProcTypeIsBuiltin()) {
5239 EXPECT_THAT(Verify(), IsError(ERR_CERT_AUTHORITY_INVALID));
5240 if (critical) {
5241 EXPECT_THAT(VerifyAsTrustedLeaf(), IsError(ERR_CERT_INVALID));
5242 } else {
5243 EXPECT_THAT(VerifyAsTrustedLeaf(), IsOk());
5244 }
5245 } else {
5246 EXPECT_THAT(Verify(), IsOk());
5247 }
5248 }
5249 }
5250
5251 // A set of tests that check how various constraints are enforced when they
5252 // are applied to a directly trusted self-signed leaf certificate.
5253 class CertVerifyProcConstraintsTrustedSelfSignedTest
5254 : public CertVerifyProcInternalTest {
5255 protected:
SetUp()5256 void SetUp() override {
5257 CertVerifyProcInternalTest::SetUp();
5258
5259 cert_ = std::move(CertBuilder::CreateSimpleChain(/*chain_length=*/1)[0]);
5260 }
5261
VerifyWithTrust(bssl::CertificateTrust trust)5262 int VerifyWithTrust(bssl::CertificateTrust trust) {
5263 ScopedTestRoot test_root(cert_->GetX509Certificate(), trust);
5264 CertVerifyResult verify_result;
5265 int flags = 0;
5266 return CertVerifyProcInternalTest::Verify(cert_->GetX509Certificate().get(),
5267 "www.example.com", flags,
5268 &verify_result);
5269 }
5270
Verify()5271 int Verify() {
5272 return VerifyWithTrust(bssl::CertificateTrust::ForTrustAnchor());
5273 }
5274
VerifyAsTrustedSelfSignedLeaf()5275 int VerifyAsTrustedSelfSignedLeaf() {
5276 return VerifyWithTrust(
5277 bssl::CertificateTrust::ForTrustedLeaf().WithRequireLeafSelfSigned());
5278 }
5279
5280 std::unique_ptr<CertBuilder> cert_;
5281 };
5282
5283 INSTANTIATE_TEST_SUITE_P(All,
5284 CertVerifyProcConstraintsTrustedSelfSignedTest,
5285 testing::ValuesIn(kAllCertVerifiers),
5286 VerifyProcTypeToName);
5287
TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,BaseCase)5288 TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest, BaseCase) {
5289 // Without changing anything on the test cert, it should validate
5290 // successfully. If this is not true then the rest of the tests in this class
5291 // are unlikely to be useful.
5292 if (VerifyProcTypeIsBuiltin()) {
5293 // Should succeed when verified as a trusted leaf.
5294 EXPECT_THAT(VerifyAsTrustedSelfSignedLeaf(), IsOk());
5295 EXPECT_THAT(VerifyWithTrust(bssl::CertificateTrust::ForTrustedLeaf()),
5296 IsOk());
5297 EXPECT_THAT(VerifyWithTrust(bssl::CertificateTrust::ForTrustAnchorOrLeaf()),
5298 IsOk());
5299
5300 // Should also be allowed by verifying as anchor for itself.
5301 EXPECT_THAT(Verify(), IsOk());
5302
5303 // Should fail if verified as anchor of itself with constraints enabled,
5304 // enforcing the basicConstraints on the anchor will fail since the cert
5305 // has CA=false.
5306 EXPECT_THAT(VerifyWithTrust(bssl::CertificateTrust::ForTrustAnchor()
5307 .WithEnforceAnchorConstraints()),
5308 IsError(ERR_CERT_INVALID));
5309
5310 // Should be allowed since it will be evaluated as a trusted leaf, so
5311 // anchor constraints being enabled doesn't matter.
5312 EXPECT_THAT(VerifyWithTrust(bssl::CertificateTrust::ForTrustAnchorOrLeaf()
5313 .WithEnforceAnchorConstraints()),
5314 IsOk());
5315 } else {
5316 EXPECT_THAT(Verify(), IsOk());
5317 }
5318 }
5319
TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,BasicConstraintsIsCa)5320 TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest, BasicConstraintsIsCa) {
5321 for (bool has_key_usage_cert_sign : {false, true}) {
5322 cert_->SetBasicConstraints(/*is_ca=*/true, /*path_len=*/-1);
5323
5324 if (has_key_usage_cert_sign) {
5325 cert_->SetKeyUsages({bssl::KEY_USAGE_BIT_KEY_CERT_SIGN,
5326 bssl::KEY_USAGE_BIT_DIGITAL_SIGNATURE});
5327 } else {
5328 cert_->SetKeyUsages({bssl::KEY_USAGE_BIT_DIGITAL_SIGNATURE});
5329 }
5330 EXPECT_THAT(Verify(), IsOk());
5331 if (VerifyProcTypeIsBuiltin()) {
5332 EXPECT_THAT(VerifyAsTrustedSelfSignedLeaf(), IsOk());
5333 }
5334 }
5335 }
5336
TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,BasicConstraintsNotCaPathlen)5337 TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,
5338 BasicConstraintsNotCaPathlen) {
5339 cert_->SetBasicConstraints(/*is_ca=*/false, /*path_len=*/0);
5340
5341 EXPECT_THAT(Verify(), IsOk());
5342 if (VerifyProcTypeIsBuiltin()) {
5343 EXPECT_THAT(VerifyAsTrustedSelfSignedLeaf(), IsOk());
5344 }
5345 }
5346
TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,BasicConstraintsIsCaPathlen)5347 TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,
5348 BasicConstraintsIsCaPathlen) {
5349 cert_->SetBasicConstraints(/*is_ca=*/true, /*path_len=*/0);
5350
5351 EXPECT_THAT(Verify(), IsOk());
5352 if (VerifyProcTypeIsBuiltin()) {
5353 EXPECT_THAT(VerifyAsTrustedSelfSignedLeaf(), IsOk());
5354 }
5355 }
5356
TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,BasicConstraintsMissing)5357 TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,
5358 BasicConstraintsMissing) {
5359 cert_->EraseExtension(bssl::der::Input(bssl::kBasicConstraintsOid));
5360
5361 EXPECT_THAT(Verify(), IsOk());
5362 if (VerifyProcTypeIsBuiltin()) {
5363 EXPECT_THAT(VerifyAsTrustedSelfSignedLeaf(), IsOk());
5364 }
5365 }
5366
TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,NameConstraintsNotMatching)5367 TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,
5368 NameConstraintsNotMatching) {
5369 cert_->SetNameConstraintsDnsNames(/*permitted_dns_names=*/{"example.org"},
5370 /*excluded_dns_names=*/{});
5371
5372 EXPECT_THAT(Verify(), IsOk());
5373 if (VerifyProcTypeIsBuiltin()) {
5374 EXPECT_THAT(VerifyAsTrustedSelfSignedLeaf(), IsOk());
5375 }
5376 }
5377
TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,ValidityExpired)5378 TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest, ValidityExpired) {
5379 cert_->SetValidity(base::Time::Now() - base::Days(14),
5380 base::Time::Now() - base::Days(7));
5381
5382 EXPECT_THAT(Verify(), IsError(ERR_CERT_DATE_INVALID));
5383 if (VerifyProcTypeIsBuiltin()) {
5384 EXPECT_THAT(VerifyAsTrustedSelfSignedLeaf(),
5385 IsError(ERR_CERT_DATE_INVALID));
5386 }
5387 }
5388
TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,PolicyConstraints)5389 TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest, PolicyConstraints) {
5390 static const char kPolicy1[] = "1.2.3.4";
5391
5392 for (bool leaf_has_policy : {false, true}) {
5393 SCOPED_TRACE(leaf_has_policy);
5394
5395 cert_->SetPolicyConstraints(
5396 /*require_explicit_policy=*/0,
5397 /*inhibit_policy_mapping=*/std::nullopt);
5398 if (leaf_has_policy) {
5399 cert_->SetCertificatePolicies({kPolicy1});
5400
5401 EXPECT_THAT(Verify(), IsOk());
5402 } else {
5403 cert_->SetCertificatePolicies({});
5404
5405 if (VerifyProcTypeIsBuiltin()) {
5406 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
5407 EXPECT_THAT(VerifyAsTrustedSelfSignedLeaf(), IsOk());
5408 } else {
5409 EXPECT_THAT(Verify(), IsOk());
5410 }
5411 }
5412 }
5413 }
5414
TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,InhibitAnyPolicy)5415 TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest, InhibitAnyPolicy) {
5416 static const char kAnyPolicy[] = "2.5.29.32.0";
5417 cert_->SetPolicyConstraints(
5418 /*require_explicit_policy=*/0,
5419 /*inhibit_policy_mapping=*/std::nullopt);
5420 cert_->SetInhibitAnyPolicy(0);
5421 cert_->SetCertificatePolicies({kAnyPolicy});
5422
5423 EXPECT_THAT(Verify(), IsOk());
5424 if (VerifyProcTypeIsBuiltin()) {
5425 EXPECT_THAT(VerifyAsTrustedSelfSignedLeaf(), IsOk());
5426 }
5427 }
5428
TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,KeyUsageNoDigitalSignature)5429 TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,
5430 KeyUsageNoDigitalSignature) {
5431 // This test is mostly uninteresting since keyUsage on the end-entity is only
5432 // checked at the TLS layer, not during cert verification.
5433 cert_->SetKeyUsages({bssl::KEY_USAGE_BIT_CRL_SIGN});
5434
5435 EXPECT_THAT(Verify(), IsOk());
5436 if (VerifyProcTypeIsBuiltin()) {
5437 EXPECT_THAT(VerifyAsTrustedSelfSignedLeaf(), IsOk());
5438 }
5439 }
5440
TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,KeyUsageCertSignLeaf)5441 TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest, KeyUsageCertSignLeaf) {
5442 // Test a leaf that has keyUsage asserting keyCertSign with basicConstraints
5443 // CA=false, which is an error according to 5280 (4.2.1.3 and 4.2.1.9).
5444 cert_->SetKeyUsages({bssl::KEY_USAGE_BIT_KEY_CERT_SIGN,
5445 bssl::KEY_USAGE_BIT_DIGITAL_SIGNATURE});
5446
5447 EXPECT_THAT(Verify(), IsOk());
5448 if (VerifyProcTypeIsBuiltin()) {
5449 EXPECT_THAT(VerifyWithTrust(bssl::CertificateTrust::ForTrustAnchor()
5450 .WithEnforceAnchorConstraints()),
5451 IsError(ERR_CERT_INVALID));
5452 EXPECT_THAT(VerifyAsTrustedSelfSignedLeaf(), IsOk());
5453 EXPECT_THAT(VerifyWithTrust(bssl::CertificateTrust::ForTrustAnchorOrLeaf()
5454 .WithEnforceAnchorConstraints()
5455 .WithRequireLeafSelfSigned()),
5456 IsOk());
5457 }
5458 }
5459
TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,ExtendedKeyUsageNoServerAuth)5460 TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,
5461 ExtendedKeyUsageNoServerAuth) {
5462 cert_->SetExtendedKeyUsages({bssl::der::Input(bssl::kCodeSigning)});
5463
5464 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
5465 if (VerifyProcTypeIsBuiltin()) {
5466 EXPECT_THAT(VerifyAsTrustedSelfSignedLeaf(), IsError(ERR_CERT_INVALID));
5467 }
5468 }
5469
TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,UnknownSignatureAlgorithm)5470 TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,
5471 UnknownSignatureAlgorithm) {
5472 cert_->SetSignatureAlgorithmTLV(TestOid0SignatureAlgorithmTLV());
5473 if (VerifyProcTypeIsBuiltin()) {
5474 // Attempts to verify as anchor of itself, which fails when verifying the
5475 // signature.
5476 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
5477
5478 // Signature not checked when verified as a directly trusted leaf without
5479 // require_leaf_selfsigned.
5480 EXPECT_THAT(VerifyWithTrust(bssl::CertificateTrust::ForTrustedLeaf()),
5481 IsOk());
5482
5483 // PathBuilder override ignores require_leaf_selfsigned due to the
5484 // self-signed check returning false (due to the invalid signature
5485 // algorithm), thus this fails with AUTHORITY_INVALID due to failing to
5486 // find a chain to another root.
5487 EXPECT_THAT(VerifyAsTrustedSelfSignedLeaf(),
5488 IsError(ERR_CERT_AUTHORITY_INVALID));
5489
5490 // PathBuilder override ignores require_leaf_selfsigned due to the invalid
5491 // signature algorithm, thus this tries to verify as anchor of itself,
5492 // which fails when verifying the signature.
5493 EXPECT_THAT(VerifyWithTrust(bssl::CertificateTrust::ForTrustAnchorOrLeaf()
5494 .WithRequireLeafSelfSigned()),
5495 IsError(ERR_CERT_INVALID));
5496 } else {
5497 EXPECT_THAT(Verify(), IsOk());
5498 }
5499 }
5500
TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,WeakSignatureAlgorithm)5501 TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest, WeakSignatureAlgorithm) {
5502 cert_->SetSignatureAlgorithm(bssl::SignatureAlgorithm::kEcdsaSha1);
5503 if (VerifyProcTypeIsBuiltin()) {
5504 // Attempts to verify as anchor of itself, which fails due to the weak
5505 // signature algorithm.
5506 EXPECT_THAT(Verify(), IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM));
5507
5508 // Signature not checked when verified as a directly trusted leaf without
5509 // require_leaf_selfsigned.
5510 EXPECT_THAT(VerifyWithTrust(bssl::CertificateTrust::ForTrustedLeaf()),
5511 IsOk());
5512
5513 // require_leaf_selfsigned allows any supported signature algorithm when
5514 // doing the self-signed check, so this is okay.
5515 EXPECT_THAT(VerifyAsTrustedSelfSignedLeaf(), IsOk());
5516 EXPECT_THAT(VerifyWithTrust(bssl::CertificateTrust::ForTrustAnchorOrLeaf()
5517 .WithRequireLeafSelfSigned()),
5518 IsOk());
5519 } else {
5520 EXPECT_THAT(Verify(), IsOk());
5521 }
5522 }
5523
TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest,UnknownExtension)5524 TEST_P(CertVerifyProcConstraintsTrustedSelfSignedTest, UnknownExtension) {
5525 for (bool critical : {true, false}) {
5526 SCOPED_TRACE(critical);
5527 cert_->SetExtension(TestOid0(), "hello world", critical);
5528
5529 if (VerifyProcTypeIsBuiltin()) {
5530 if (critical) {
5531 EXPECT_THAT(Verify(), IsError(ERR_CERT_INVALID));
5532 EXPECT_THAT(VerifyAsTrustedSelfSignedLeaf(), IsError(ERR_CERT_INVALID));
5533 } else {
5534 EXPECT_THAT(Verify(), IsOk());
5535 EXPECT_THAT(VerifyAsTrustedSelfSignedLeaf(), IsOk());
5536 }
5537 } else {
5538 EXPECT_THAT(Verify(), IsOk());
5539 }
5540 }
5541 }
5542
TEST(CertVerifyProcTest,RejectsPublicSHA1)5543 TEST(CertVerifyProcTest, RejectsPublicSHA1) {
5544 scoped_refptr<X509Certificate> cert(
5545 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
5546 ASSERT_TRUE(cert);
5547
5548 CertVerifyResult result;
5549 result.has_sha1 = true;
5550 result.is_issued_by_known_root = true;
5551 auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(result);
5552
5553 int flags = 0;
5554 CertVerifyResult verify_result;
5555 int error = verify_proc->Verify(
5556 cert.get(), "127.0.0.1", /*ocsp_response=*/std::string(),
5557 /*sct_list=*/std::string(), flags, &verify_result, NetLogWithSource());
5558 EXPECT_THAT(error, IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM));
5559 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
5560
5561 // VERIFY_ENABLE_SHA1_LOCAL_ANCHORS should not impact this.
5562 flags = CertVerifyProc::VERIFY_ENABLE_SHA1_LOCAL_ANCHORS;
5563 verify_result.Reset();
5564 error = verify_proc->Verify(
5565 cert.get(), "127.0.0.1", /*ocsp_response=*/std::string(),
5566 /*sct_list=*/std::string(), flags, &verify_result, NetLogWithSource());
5567 EXPECT_THAT(error, IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM));
5568 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
5569 }
5570
TEST(CertVerifyProcTest,RejectsPrivateSHA1UnlessFlag)5571 TEST(CertVerifyProcTest, RejectsPrivateSHA1UnlessFlag) {
5572 scoped_refptr<X509Certificate> cert(
5573 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
5574 ASSERT_TRUE(cert);
5575
5576 CertVerifyResult result;
5577 result.has_sha1 = true;
5578 result.is_issued_by_known_root = false;
5579 auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(result);
5580
5581 // SHA-1 should be rejected by default for private roots...
5582 int flags = 0;
5583 CertVerifyResult verify_result;
5584 int error = verify_proc->Verify(
5585 cert.get(), "127.0.0.1", /*ocsp_response=*/std::string(),
5586 /*sct_list=*/std::string(), flags, &verify_result, NetLogWithSource());
5587 EXPECT_THAT(error, IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM));
5588 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT);
5589
5590 // ... unless VERIFY_ENABLE_SHA1_LOCAL_ANCHORS was supplied.
5591 flags = CertVerifyProc::VERIFY_ENABLE_SHA1_LOCAL_ANCHORS;
5592 verify_result.Reset();
5593 error = verify_proc->Verify(
5594 cert.get(), "127.0.0.1", /*ocsp_response=*/std::string(),
5595 /*sct_list=*/std::string(), flags, &verify_result, NetLogWithSource());
5596 EXPECT_THAT(error, IsOk());
5597 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT);
5598 }
5599
5600 enum ExpectedAlgorithms {
5601 EXPECT_SHA1 = 1 << 0,
5602 EXPECT_STATUS_INVALID = 1 << 1,
5603 };
5604
5605 struct WeakDigestTestData {
5606 const char* root_cert_filename;
5607 const char* intermediate_cert_filename;
5608 const char* ee_cert_filename;
5609 int expected_algorithms;
5610 };
5611
StringOrDefault(const char * str,const char * default_value)5612 const char* StringOrDefault(const char* str, const char* default_value) {
5613 if (!str)
5614 return default_value;
5615 return str;
5616 }
5617
5618 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
5619 // to output the parameter that was passed. Without this, it will simply
5620 // attempt to print out the first twenty bytes of the object, which depending
5621 // on platform and alignment, may result in an invalid read.
PrintTo(const WeakDigestTestData & data,std::ostream * os)5622 void PrintTo(const WeakDigestTestData& data, std::ostream* os) {
5623 *os << "root: " << StringOrDefault(data.root_cert_filename, "none")
5624 << "; intermediate: "
5625 << StringOrDefault(data.intermediate_cert_filename, "none")
5626 << "; end-entity: " << data.ee_cert_filename;
5627 }
5628
5629 class CertVerifyProcWeakDigestTest
5630 : public testing::TestWithParam<WeakDigestTestData> {
5631 public:
5632 CertVerifyProcWeakDigestTest() = default;
5633 ~CertVerifyProcWeakDigestTest() override = default;
5634 };
5635
5636 // Tests that the CertVerifyProc::Verify() properly surfaces the (weak) hash
5637 // algorithms used in the chain.
TEST_P(CertVerifyProcWeakDigestTest,VerifyDetectsAlgorithm)5638 TEST_P(CertVerifyProcWeakDigestTest, VerifyDetectsAlgorithm) {
5639 WeakDigestTestData data = GetParam();
5640 base::FilePath certs_dir = GetTestCertsDirectory();
5641
5642 // Build |intermediates| as the full chain (including trust anchor).
5643 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
5644
5645 if (data.intermediate_cert_filename) {
5646 scoped_refptr<X509Certificate> intermediate_cert =
5647 ImportCertFromFile(certs_dir, data.intermediate_cert_filename);
5648 ASSERT_TRUE(intermediate_cert);
5649 intermediates.push_back(bssl::UpRef(intermediate_cert->cert_buffer()));
5650 }
5651
5652 if (data.root_cert_filename) {
5653 scoped_refptr<X509Certificate> root_cert =
5654 ImportCertFromFile(certs_dir, data.root_cert_filename);
5655 ASSERT_TRUE(root_cert);
5656 intermediates.push_back(bssl::UpRef(root_cert->cert_buffer()));
5657 }
5658
5659 scoped_refptr<X509Certificate> ee_cert =
5660 ImportCertFromFile(certs_dir, data.ee_cert_filename);
5661 ASSERT_TRUE(ee_cert);
5662
5663 scoped_refptr<X509Certificate> ee_chain = X509Certificate::CreateFromBuffer(
5664 bssl::UpRef(ee_cert->cert_buffer()), std::move(intermediates));
5665 ASSERT_TRUE(ee_chain);
5666
5667 int flags = 0;
5668 CertVerifyResult verify_result;
5669
5670 // Use a mock CertVerifyProc that returns success with a verified_cert of
5671 // |ee_chain|.
5672 //
5673 // This is sufficient for the purposes of this test, as the checking for weak
5674 // hash algorithms is done by CertVerifyProc::Verify().
5675 auto proc = base::MakeRefCounted<MockCertVerifyProc>(CertVerifyResult());
5676 int error = proc->Verify(ee_chain.get(), "127.0.0.1",
5677 /*ocsp_response=*/std::string(),
5678 /*sct_list=*/std::string(), flags, &verify_result,
5679 NetLogWithSource());
5680 EXPECT_EQ(!!(data.expected_algorithms & EXPECT_SHA1), verify_result.has_sha1);
5681 EXPECT_EQ(!!(data.expected_algorithms & EXPECT_STATUS_INVALID),
5682 !!(verify_result.cert_status & CERT_STATUS_INVALID));
5683 EXPECT_EQ(!!(data.expected_algorithms & EXPECT_STATUS_INVALID),
5684 error == ERR_CERT_INVALID);
5685 }
5686
5687 // The signature algorithm of the root CA should not matter.
5688 const WeakDigestTestData kVerifyRootCATestData[] = {
5689 {"weak_digest_md5_root.pem", "weak_digest_sha1_intermediate.pem",
5690 "weak_digest_sha1_ee.pem", EXPECT_SHA1},
5691 {"weak_digest_md4_root.pem", "weak_digest_sha1_intermediate.pem",
5692 "weak_digest_sha1_ee.pem", EXPECT_SHA1},
5693 {"weak_digest_md2_root.pem", "weak_digest_sha1_intermediate.pem",
5694 "weak_digest_sha1_ee.pem", EXPECT_SHA1},
5695 };
5696 INSTANTIATE_TEST_SUITE_P(VerifyRoot,
5697 CertVerifyProcWeakDigestTest,
5698 testing::ValuesIn(kVerifyRootCATestData));
5699
5700 // The signature algorithm of intermediates should be properly detected.
5701 const WeakDigestTestData kVerifyIntermediateCATestData[] = {
5702 {"weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
5703 "weak_digest_sha1_ee.pem", EXPECT_STATUS_INVALID | EXPECT_SHA1},
5704 {"weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
5705 "weak_digest_sha1_ee.pem", EXPECT_STATUS_INVALID | EXPECT_SHA1},
5706 {"weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
5707 "weak_digest_sha1_ee.pem", EXPECT_STATUS_INVALID | EXPECT_SHA1},
5708 };
5709
5710 INSTANTIATE_TEST_SUITE_P(VerifyIntermediate,
5711 CertVerifyProcWeakDigestTest,
5712 testing::ValuesIn(kVerifyIntermediateCATestData));
5713
5714 // The signature algorithm of end-entity should be properly detected.
5715 const WeakDigestTestData kVerifyEndEntityTestData[] = {
5716 {"weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
5717 "weak_digest_md5_ee.pem", EXPECT_STATUS_INVALID},
5718 {"weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
5719 "weak_digest_md4_ee.pem", EXPECT_STATUS_INVALID},
5720 {"weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
5721 "weak_digest_md2_ee.pem", EXPECT_STATUS_INVALID},
5722 };
5723
5724 INSTANTIATE_TEST_SUITE_P(VerifyEndEntity,
5725 CertVerifyProcWeakDigestTest,
5726 testing::ValuesIn(kVerifyEndEntityTestData));
5727
5728 // Incomplete chains do not report the status of the intermediate.
5729 // Note: really each of these tests should also expect the digest algorithm of
5730 // the intermediate (included as a comment). However CertVerifyProc::Verify() is
5731 // unable to distinguish that this is an intermediate and not a trust anchor, so
5732 // this intermediate is treated like a trust anchor.
5733 const WeakDigestTestData kVerifyIncompleteIntermediateTestData[] = {
5734 {nullptr, "weak_digest_md5_intermediate.pem", "weak_digest_sha1_ee.pem",
5735 EXPECT_SHA1},
5736 {nullptr, "weak_digest_md4_intermediate.pem", "weak_digest_sha1_ee.pem",
5737 EXPECT_SHA1},
5738 {nullptr, "weak_digest_md2_intermediate.pem", "weak_digest_sha1_ee.pem",
5739 EXPECT_SHA1},
5740 };
5741
5742 INSTANTIATE_TEST_SUITE_P(
5743 MAYBE_VerifyIncompleteIntermediate,
5744 CertVerifyProcWeakDigestTest,
5745 testing::ValuesIn(kVerifyIncompleteIntermediateTestData));
5746
5747 // Incomplete chains should report the status of the end-entity.
5748 // since the intermediate is treated as a trust anchor these should
5749 // be still simply be invalid.
5750 const WeakDigestTestData kVerifyIncompleteEETestData[] = {
5751 {nullptr, "weak_digest_sha1_intermediate.pem", "weak_digest_md5_ee.pem",
5752 EXPECT_STATUS_INVALID},
5753 {nullptr, "weak_digest_sha1_intermediate.pem", "weak_digest_md4_ee.pem",
5754 EXPECT_STATUS_INVALID},
5755 {nullptr, "weak_digest_sha1_intermediate.pem", "weak_digest_md2_ee.pem",
5756 EXPECT_STATUS_INVALID},
5757 };
5758
5759 INSTANTIATE_TEST_SUITE_P(VerifyIncompleteEndEntity,
5760 CertVerifyProcWeakDigestTest,
5761 testing::ValuesIn(kVerifyIncompleteEETestData));
5762
5763 // Md2, Md4, and Md5 are all considered invalid.
5764 const WeakDigestTestData kVerifyMixedTestData[] = {
5765 {"weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
5766 "weak_digest_md2_ee.pem", EXPECT_STATUS_INVALID},
5767 {"weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
5768 "weak_digest_md5_ee.pem", EXPECT_STATUS_INVALID},
5769 {"weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
5770 "weak_digest_md2_ee.pem", EXPECT_STATUS_INVALID},
5771 };
5772
5773 INSTANTIATE_TEST_SUITE_P(VerifyMixed,
5774 CertVerifyProcWeakDigestTest,
5775 testing::ValuesIn(kVerifyMixedTestData));
5776
5777 // The EE is a trusted certificate. Even though it uses weak hashes, these
5778 // should not be reported.
5779 const WeakDigestTestData kVerifyTrustedEETestData[] = {
5780 {nullptr, nullptr, "weak_digest_md5_ee.pem", 0},
5781 {nullptr, nullptr, "weak_digest_md4_ee.pem", 0},
5782 {nullptr, nullptr, "weak_digest_md2_ee.pem", 0},
5783 {nullptr, nullptr, "weak_digest_sha1_ee.pem", 0},
5784 };
5785
5786 INSTANTIATE_TEST_SUITE_P(VerifyTrustedEE,
5787 CertVerifyProcWeakDigestTest,
5788 testing::ValuesIn(kVerifyTrustedEETestData));
5789
5790 // Test fixture for verifying certificate names.
5791 class CertVerifyProcNameTest : public ::testing::Test {
5792 protected:
VerifyCertName(const char * hostname,bool valid)5793 void VerifyCertName(const char* hostname, bool valid) {
5794 scoped_refptr<X509Certificate> cert(ImportCertFromFile(
5795 GetTestCertsDirectory(), "subjectAltName_sanity_check.pem"));
5796 ASSERT_TRUE(cert);
5797 CertVerifyResult result;
5798 result.is_issued_by_known_root = false;
5799 auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(result);
5800
5801 CertVerifyResult verify_result;
5802 int error = verify_proc->Verify(
5803 cert.get(), hostname, /*ocsp_response=*/std::string(),
5804 /*sct_list=*/std::string(), 0, &verify_result, NetLogWithSource());
5805 if (valid) {
5806 EXPECT_THAT(error, IsOk());
5807 EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_COMMON_NAME_INVALID);
5808 } else {
5809 EXPECT_THAT(error, IsError(ERR_CERT_COMMON_NAME_INVALID));
5810 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_COMMON_NAME_INVALID);
5811 }
5812 }
5813 };
5814
5815 // Don't match the common name
TEST_F(CertVerifyProcNameTest,DontMatchCommonName)5816 TEST_F(CertVerifyProcNameTest, DontMatchCommonName) {
5817 VerifyCertName("127.0.0.1", false);
5818 }
5819
5820 // Matches the iPAddress SAN (IPv4)
TEST_F(CertVerifyProcNameTest,MatchesIpSanIpv4)5821 TEST_F(CertVerifyProcNameTest, MatchesIpSanIpv4) {
5822 VerifyCertName("127.0.0.2", true);
5823 }
5824
5825 // Matches the iPAddress SAN (IPv6)
TEST_F(CertVerifyProcNameTest,MatchesIpSanIpv6)5826 TEST_F(CertVerifyProcNameTest, MatchesIpSanIpv6) {
5827 VerifyCertName("FE80:0:0:0:0:0:0:1", true);
5828 }
5829
5830 // Should not match the iPAddress SAN
TEST_F(CertVerifyProcNameTest,DoesntMatchIpSanIpv6)5831 TEST_F(CertVerifyProcNameTest, DoesntMatchIpSanIpv6) {
5832 VerifyCertName("[FE80:0:0:0:0:0:0:1]", false);
5833 }
5834
5835 // Compressed form matches the iPAddress SAN (IPv6)
TEST_F(CertVerifyProcNameTest,MatchesIpSanCompressedIpv6)5836 TEST_F(CertVerifyProcNameTest, MatchesIpSanCompressedIpv6) {
5837 VerifyCertName("FE80::1", true);
5838 }
5839
5840 // IPv6 mapped form should NOT match iPAddress SAN
TEST_F(CertVerifyProcNameTest,DoesntMatchIpSanIPv6Mapped)5841 TEST_F(CertVerifyProcNameTest, DoesntMatchIpSanIPv6Mapped) {
5842 VerifyCertName("::127.0.0.2", false);
5843 }
5844
5845 // Matches the dNSName SAN
TEST_F(CertVerifyProcNameTest,MatchesDnsSan)5846 TEST_F(CertVerifyProcNameTest, MatchesDnsSan) {
5847 VerifyCertName("test.example", true);
5848 }
5849
5850 // Matches the dNSName SAN (trailing . ignored)
TEST_F(CertVerifyProcNameTest,MatchesDnsSanTrailingDot)5851 TEST_F(CertVerifyProcNameTest, MatchesDnsSanTrailingDot) {
5852 VerifyCertName("test.example.", true);
5853 }
5854
5855 // Should not match the dNSName SAN
TEST_F(CertVerifyProcNameTest,DoesntMatchDnsSan)5856 TEST_F(CertVerifyProcNameTest, DoesntMatchDnsSan) {
5857 VerifyCertName("www.test.example", false);
5858 }
5859
5860 // Should not match the dNSName SAN
TEST_F(CertVerifyProcNameTest,DoesntMatchDnsSanInvalid)5861 TEST_F(CertVerifyProcNameTest, DoesntMatchDnsSanInvalid) {
5862 VerifyCertName("test..example", false);
5863 }
5864
5865 // Should not match the dNSName SAN
TEST_F(CertVerifyProcNameTest,DoesntMatchDnsSanTwoTrailingDots)5866 TEST_F(CertVerifyProcNameTest, DoesntMatchDnsSanTwoTrailingDots) {
5867 VerifyCertName("test.example..", false);
5868 }
5869
5870 // Should not match the dNSName SAN
TEST_F(CertVerifyProcNameTest,DoesntMatchDnsSanLeadingAndTrailingDot)5871 TEST_F(CertVerifyProcNameTest, DoesntMatchDnsSanLeadingAndTrailingDot) {
5872 VerifyCertName(".test.example.", false);
5873 }
5874
5875 // Should not match the dNSName SAN
TEST_F(CertVerifyProcNameTest,DoesntMatchDnsSanTrailingDot)5876 TEST_F(CertVerifyProcNameTest, DoesntMatchDnsSanTrailingDot) {
5877 VerifyCertName(".test.example", false);
5878 }
5879
5880 // Test that trust anchors are appropriately recorded via UMA.
TEST(CertVerifyProcTest,HasTrustAnchorVerifyUMA)5881 TEST(CertVerifyProcTest, HasTrustAnchorVerifyUMA) {
5882 base::HistogramTester histograms;
5883 scoped_refptr<X509Certificate> cert(
5884 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
5885 ASSERT_TRUE(cert);
5886
5887 CertVerifyResult result;
5888
5889 // Simulate a certificate chain issued by "C=US, O=Google Trust Services LLC,
5890 // CN=GTS Root R4". This publicly-trusted root was chosen as it was included
5891 // in 2017 and is not anticipated to be removed from all supported platforms
5892 // for a few decades.
5893 // Note: The actual cert in |cert| does not matter for this testing, so long
5894 // as it's not violating any CertVerifyProc::Verify() policies.
5895 SHA256HashValue leaf_hash = {{0}};
5896 SHA256HashValue intermediate_hash = {{1}};
5897 SHA256HashValue root_hash = {
5898 {0x98, 0x47, 0xe5, 0x65, 0x3e, 0x5e, 0x9e, 0x84, 0x75, 0x16, 0xe5,
5899 0xcb, 0x81, 0x86, 0x06, 0xaa, 0x75, 0x44, 0xa1, 0x9b, 0xe6, 0x7f,
5900 0xd7, 0x36, 0x6d, 0x50, 0x69, 0x88, 0xe8, 0xd8, 0x43, 0x47}};
5901 result.public_key_hashes.push_back(HashValue(leaf_hash));
5902 result.public_key_hashes.push_back(HashValue(intermediate_hash));
5903 result.public_key_hashes.push_back(HashValue(root_hash));
5904
5905 const base::HistogramBase::Sample kGTSRootR4HistogramID = 486;
5906
5907 auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(result);
5908
5909 histograms.ExpectTotalCount(kTrustAnchorVerifyHistogram, 0);
5910
5911 int flags = 0;
5912 CertVerifyResult verify_result;
5913 int error = verify_proc->Verify(
5914 cert.get(), "127.0.0.1", /*ocsp_response=*/std::string(),
5915 /*sct_list=*/std::string(), flags, &verify_result, NetLogWithSource());
5916 EXPECT_EQ(OK, error);
5917 histograms.ExpectUniqueSample(kTrustAnchorVerifyHistogram,
5918 kGTSRootR4HistogramID, 1);
5919 }
5920
5921 // Test that certificates with multiple trust anchors present result in
5922 // only a single trust anchor being recorded, and that being the most specific
5923 // trust anchor.
TEST(CertVerifyProcTest,LogsOnlyMostSpecificTrustAnchorUMA)5924 TEST(CertVerifyProcTest, LogsOnlyMostSpecificTrustAnchorUMA) {
5925 base::HistogramTester histograms;
5926 scoped_refptr<X509Certificate> cert(
5927 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
5928 ASSERT_TRUE(cert);
5929
5930 CertVerifyResult result;
5931
5932 // Simulate a chain of "C=US, O=Google Trust Services LLC, CN=GTS Root R4"
5933 // signing "C=US, O=Google Trust Services LLC, CN=GTS Root R3" signing an
5934 // intermediate and a leaf.
5935 // Note: The actual cert in |cert| does not matter for this testing, so long
5936 // as it's not violating any CertVerifyProc::Verify() policies.
5937 SHA256HashValue leaf_hash = {{0}};
5938 SHA256HashValue intermediate_hash = {{1}};
5939 SHA256HashValue gts_root_r3_hash = {
5940 {0x41, 0x79, 0xed, 0xd9, 0x81, 0xef, 0x74, 0x74, 0x77, 0xb4, 0x96,
5941 0x26, 0x40, 0x8a, 0xf4, 0x3d, 0xaa, 0x2c, 0xa7, 0xab, 0x7f, 0x9e,
5942 0x08, 0x2c, 0x10, 0x60, 0xf8, 0x40, 0x96, 0x77, 0x43, 0x48}};
5943 SHA256HashValue gts_root_r4_hash = {
5944 {0x98, 0x47, 0xe5, 0x65, 0x3e, 0x5e, 0x9e, 0x84, 0x75, 0x16, 0xe5,
5945 0xcb, 0x81, 0x86, 0x06, 0xaa, 0x75, 0x44, 0xa1, 0x9b, 0xe6, 0x7f,
5946 0xd7, 0x36, 0x6d, 0x50, 0x69, 0x88, 0xe8, 0xd8, 0x43, 0x47}};
5947 result.public_key_hashes.push_back(HashValue(leaf_hash));
5948 result.public_key_hashes.push_back(HashValue(intermediate_hash));
5949 result.public_key_hashes.push_back(HashValue(gts_root_r3_hash));
5950 result.public_key_hashes.push_back(HashValue(gts_root_r4_hash));
5951
5952 const base::HistogramBase::Sample kGTSRootR3HistogramID = 485;
5953
5954 auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(result);
5955
5956 histograms.ExpectTotalCount(kTrustAnchorVerifyHistogram, 0);
5957
5958 int flags = 0;
5959 CertVerifyResult verify_result;
5960 int error = verify_proc->Verify(
5961 cert.get(), "127.0.0.1", /*ocsp_response=*/std::string(),
5962 /*sct_list=*/std::string(), flags, &verify_result, NetLogWithSource());
5963 EXPECT_EQ(OK, error);
5964
5965 // Only GTS Root R3 should be recorded.
5966 histograms.ExpectUniqueSample(kTrustAnchorVerifyHistogram,
5967 kGTSRootR3HistogramID, 1);
5968 }
5969
5970 // Test that trust anchors histograms record whether or not
5971 // is_issued_by_known_root was derived from the OS.
TEST(CertVerifyProcTest,HasTrustAnchorVerifyOutOfDateUMA)5972 TEST(CertVerifyProcTest, HasTrustAnchorVerifyOutOfDateUMA) {
5973 base::HistogramTester histograms;
5974 // Since we are setting is_issued_by_known_root=true, the certificate to be
5975 // verified needs to have a validity period that satisfies
5976 // HasTooLongValidity.
5977 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
5978
5979 CertVerifyResult result;
5980
5981 // Simulate a certificate chain that is recognized as trusted (from a known
5982 // root), but no certificates in the chain are tracked as known trust
5983 // anchors.
5984 SHA256HashValue leaf_hash = {{0}};
5985 SHA256HashValue intermediate_hash = {{1}};
5986 SHA256HashValue root_hash = {{2}};
5987 result.public_key_hashes.push_back(HashValue(leaf_hash));
5988 result.public_key_hashes.push_back(HashValue(intermediate_hash));
5989 result.public_key_hashes.push_back(HashValue(root_hash));
5990 result.is_issued_by_known_root = true;
5991
5992 auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(result);
5993
5994 histograms.ExpectTotalCount(kTrustAnchorVerifyHistogram, 0);
5995 histograms.ExpectTotalCount(kTrustAnchorVerifyOutOfDateHistogram, 0);
5996
5997 int flags = 0;
5998 CertVerifyResult verify_result;
5999 int error = verify_proc->Verify(
6000 leaf->GetX509Certificate().get(), "www.example.com",
6001 /*ocsp_response=*/std::string(),
6002 /*sct_list=*/std::string(), flags, &verify_result, NetLogWithSource());
6003 EXPECT_EQ(OK, error);
6004 const base::HistogramBase::Sample kUnknownRootHistogramID = 0;
6005 histograms.ExpectUniqueSample(kTrustAnchorVerifyHistogram,
6006 kUnknownRootHistogramID, 1);
6007 histograms.ExpectUniqueSample(kTrustAnchorVerifyOutOfDateHistogram, true, 1);
6008 }
6009
6010 // If the CertVerifyProc::VerifyInternal implementation calculated the stapled
6011 // OCSP results in the CertVerifyResult, CertVerifyProc::Verify should not
6012 // re-calculate them.
TEST(CertVerifyProcTest,DoesNotRecalculateStapledOCSPResult)6013 TEST(CertVerifyProcTest, DoesNotRecalculateStapledOCSPResult) {
6014 scoped_refptr<X509Certificate> cert = CreateCertificateChainFromFile(
6015 GetTestCertsDirectory(), "ok_cert_by_intermediate.pem",
6016 X509Certificate::FORMAT_AUTO);
6017 ASSERT_TRUE(cert);
6018 ASSERT_EQ(1U, cert->intermediate_buffers().size());
6019
6020 CertVerifyResult result;
6021
6022 result.ocsp_result.response_status = bssl::OCSPVerifyResult::PROVIDED;
6023 result.ocsp_result.revocation_status = bssl::OCSPRevocationStatus::GOOD;
6024
6025 auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(result);
6026
6027 int flags = 0;
6028 CertVerifyResult verify_result;
6029 int error = verify_proc->Verify(cert.get(), "127.0.0.1",
6030 /*ocsp_response=*/"invalid OCSP data",
6031 /*sct_list=*/std::string(), flags,
6032 &verify_result, NetLogWithSource());
6033 EXPECT_EQ(OK, error);
6034
6035 EXPECT_EQ(bssl::OCSPVerifyResult::PROVIDED,
6036 verify_result.ocsp_result.response_status);
6037 EXPECT_EQ(bssl::OCSPRevocationStatus::GOOD,
6038 verify_result.ocsp_result.revocation_status);
6039 }
6040
TEST(CertVerifyProcTest,CalculateStapledOCSPResultIfNotAlreadyDone)6041 TEST(CertVerifyProcTest, CalculateStapledOCSPResultIfNotAlreadyDone) {
6042 scoped_refptr<X509Certificate> cert = CreateCertificateChainFromFile(
6043 GetTestCertsDirectory(), "ok_cert_by_intermediate.pem",
6044 X509Certificate::FORMAT_AUTO);
6045 ASSERT_TRUE(cert);
6046 ASSERT_EQ(1U, cert->intermediate_buffers().size());
6047
6048 CertVerifyResult result;
6049
6050 // Confirm the default-constructed values are as expected.
6051 EXPECT_EQ(bssl::OCSPVerifyResult::NOT_CHECKED,
6052 result.ocsp_result.response_status);
6053 EXPECT_EQ(bssl::OCSPRevocationStatus::UNKNOWN,
6054 result.ocsp_result.revocation_status);
6055
6056 auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(result);
6057
6058 int flags = 0;
6059 CertVerifyResult verify_result;
6060 int error = verify_proc->Verify(
6061 cert.get(), "127.0.0.1", /*ocsp_response=*/"invalid OCSP data",
6062 /*sct_list=*/std::string(), flags, &verify_result, NetLogWithSource());
6063 EXPECT_EQ(OK, error);
6064
6065 EXPECT_EQ(bssl::OCSPVerifyResult::PARSE_RESPONSE_ERROR,
6066 verify_result.ocsp_result.response_status);
6067 EXPECT_EQ(bssl::OCSPRevocationStatus::UNKNOWN,
6068 verify_result.ocsp_result.revocation_status);
6069 }
6070
6071 } // namespace net
6072