1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/cert/cert_verify_proc.h"
9 #include "base/files/file_path.h"
10 #include "base/logging.h"
11 #include "base/sha1.h"
12 #include "base/string_number_conversions.h"
13 #include "crypto/sha2.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/test_data_directory.h"
16 #include "net/cert/asn1_util.h"
17 #include "net/cert/cert_status_flags.h"
18 #include "net/cert/cert_verifier.h"
19 #include "net/cert/cert_verify_result.h"
20 #include "net/cert/crl_set.h"
21 #include "net/cert/test_root_certs.h"
22 #include "net/cert/x509_certificate.h"
23 #include "net/test/cert_test_util.h"
24 #include "net/test/test_certificate_data.h"
25 #include "testing/gtest/include/gtest/gtest.h"
28 #include "base/win/windows_version.h"
29 #elif defined(OS_MACOSX) && !defined(OS_IOS)
30 #include "base/mac/mac_util.h"
33 using base::HexEncode
;
39 // A certificate for www.paypal.com with a NULL byte in the common name.
40 // From http://www.gossamer-threads.com/lists/fulldisc/full-disclosure/70363
41 unsigned char paypal_null_fingerprint
[] = {
42 0x4c, 0x88, 0x9e, 0x28, 0xd7, 0x7a, 0x44, 0x1e, 0x13, 0xf2, 0x6a, 0xba,
43 0x1f, 0xe8, 0x1b, 0xd6, 0xab, 0x7b, 0xe8, 0xd7
48 class CertVerifyProcTest
: public testing::Test
{
51 : verify_proc_(CertVerifyProc::CreateDefault()) {
53 virtual ~CertVerifyProcTest() {}
56 bool SupportsAdditionalTrustAnchors() {
57 return verify_proc_
->SupportsAdditionalTrustAnchors();
60 int Verify(X509Certificate
* cert
,
61 const std::string
& hostname
,
64 const CertificateList
& additional_trust_anchors
,
65 CertVerifyResult
* verify_result
) {
66 return verify_proc_
->Verify(cert
, hostname
, flags
, crl_set
,
67 additional_trust_anchors
, verify_result
);
70 const CertificateList empty_cert_list_
;
73 scoped_refptr
<CertVerifyProc
> verify_proc_
;
76 TEST_F(CertVerifyProcTest
, WithoutRevocationChecking
) {
77 // Check that verification without revocation checking works.
78 CertificateList certs
= CreateCertificateListFromFile(
79 GetTestCertsDirectory(),
80 "googlenew.chain.pem",
81 X509Certificate::FORMAT_PEM_CERT_SEQUENCE
);
83 X509Certificate::OSCertHandles intermediates
;
84 intermediates
.push_back(certs
[1]->os_cert_handle());
86 scoped_refptr
<X509Certificate
> google_full_chain
=
87 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
90 CertVerifyResult verify_result
;
91 EXPECT_EQ(OK
, Verify(google_full_chain
, "www.google.com", 0 /* flags */,
92 NULL
, empty_cert_list_
, &verify_result
));
95 #if defined(OS_ANDROID) || defined(USE_OPENSSL)
96 // TODO(jnd): http://crbug.com/117478 - EV verification is not yet supported.
97 #define MAYBE_EVVerification DISABLED_EVVerification
99 #define MAYBE_EVVerification EVVerification
101 TEST_F(CertVerifyProcTest
, MAYBE_EVVerification
) {
102 // This certificate will expire Jun 21, 2013.
103 CertificateList certs
= CreateCertificateListFromFile(
104 GetTestCertsDirectory(),
106 X509Certificate::FORMAT_PEM_CERT_SEQUENCE
);
107 ASSERT_EQ(3U, certs
.size());
109 X509Certificate::OSCertHandles intermediates
;
110 intermediates
.push_back(certs
[1]->os_cert_handle());
111 intermediates
.push_back(certs
[2]->os_cert_handle());
113 scoped_refptr
<X509Certificate
> comodo_chain
=
114 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
117 scoped_refptr
<CRLSet
> crl_set(CRLSet::EmptyCRLSetForTesting());
118 CertVerifyResult verify_result
;
119 int flags
= CertVerifier::VERIFY_EV_CERT
;
120 int error
= Verify(comodo_chain
, "comodo.com", flags
, crl_set
.get(),
121 empty_cert_list_
, &verify_result
);
122 EXPECT_EQ(OK
, error
);
123 EXPECT_TRUE(verify_result
.cert_status
& CERT_STATUS_IS_EV
);
126 TEST_F(CertVerifyProcTest
, PaypalNullCertParsing
) {
127 scoped_refptr
<X509Certificate
> paypal_null_cert(
128 X509Certificate::CreateFromBytes(
129 reinterpret_cast<const char*>(paypal_null_der
),
130 sizeof(paypal_null_der
)));
132 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), paypal_null_cert
);
134 const SHA1HashValue
& fingerprint
=
135 paypal_null_cert
->fingerprint();
136 for (size_t i
= 0; i
< 20; ++i
)
137 EXPECT_EQ(paypal_null_fingerprint
[i
], fingerprint
.data
[i
]);
140 CertVerifyResult verify_result
;
141 int error
= Verify(paypal_null_cert
, "www.paypal.com", flags
, NULL
,
142 empty_cert_list_
, &verify_result
);
143 #if defined(USE_NSS) || defined(OS_IOS) || defined(OS_ANDROID)
144 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID
, error
);
146 // TOOD(bulach): investigate why macosx and win aren't returning
147 // ERR_CERT_INVALID or ERR_CERT_COMMON_NAME_INVALID.
148 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID
, error
);
150 // Either the system crypto library should correctly report a certificate
151 // name mismatch, or our certificate blacklist should cause us to report an
152 // invalid certificate.
153 #if defined(USE_NSS) || defined(OS_WIN) || defined(OS_IOS)
154 EXPECT_TRUE(verify_result
.cert_status
&
155 (CERT_STATUS_COMMON_NAME_INVALID
| CERT_STATUS_INVALID
));
159 // A regression test for http://crbug.com/31497.
160 // This certificate will expire on 2012-04-08. The test will still
161 // pass if error == ERR_CERT_DATE_INVALID. TODO(wtc): generate test
162 // certificates for this unit test. http://crbug.com/111742
163 TEST_F(CertVerifyProcTest
, IntermediateCARequireExplicitPolicy
) {
164 base::FilePath certs_dir
= GetTestCertsDirectory();
166 scoped_refptr
<X509Certificate
> server_cert
=
167 ImportCertFromFile(certs_dir
, "www_us_army_mil_cert.der");
168 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), server_cert
);
170 // The intermediate CA certificate's policyConstraints extension has a
171 // requireExplicitPolicy field with SkipCerts=0.
172 scoped_refptr
<X509Certificate
> intermediate_cert
=
173 ImportCertFromFile(certs_dir
, "dod_ca_17_cert.der");
174 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), intermediate_cert
);
176 scoped_refptr
<X509Certificate
> root_cert
=
177 ImportCertFromFile(certs_dir
, "dod_root_ca_2_cert.der");
178 ScopedTestRoot
scoped_root(root_cert
);
180 X509Certificate::OSCertHandles intermediates
;
181 intermediates
.push_back(intermediate_cert
->os_cert_handle());
182 scoped_refptr
<X509Certificate
> cert_chain
=
183 X509Certificate::CreateFromHandle(server_cert
->os_cert_handle(),
187 CertVerifyResult verify_result
;
188 int error
= Verify(cert_chain
, "www.us.army.mil", flags
, NULL
,
189 empty_cert_list_
, &verify_result
);
191 EXPECT_EQ(0U, verify_result
.cert_status
);
193 EXPECT_EQ(ERR_CERT_DATE_INVALID
, error
);
194 EXPECT_EQ(CERT_STATUS_DATE_INVALID
, verify_result
.cert_status
);
199 // Test for bug 58437.
200 // This certificate will expire on 2011-12-21. The test will still
201 // pass if error == ERR_CERT_DATE_INVALID.
202 // This test is DISABLED because it appears that we cannot do
203 // certificate revocation checking when running all of the net unit tests.
204 // This test passes when run individually, but when run with all of the net
205 // unit tests, the call to PKIXVerifyCert returns the NSS error -8180, which is
206 // SEC_ERROR_REVOKED_CERTIFICATE. This indicates a lack of revocation
207 // status, i.e. that the revocation check is failing for some reason.
208 TEST_F(CertVerifyProcTest
, DISABLED_GlobalSignR3EVTest
) {
209 base::FilePath certs_dir
= GetTestCertsDirectory();
211 scoped_refptr
<X509Certificate
> server_cert
=
212 ImportCertFromFile(certs_dir
, "2029_globalsign_com_cert.pem");
213 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), server_cert
);
215 scoped_refptr
<X509Certificate
> intermediate_cert
=
216 ImportCertFromFile(certs_dir
, "globalsign_ev_sha256_ca_cert.pem");
217 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), intermediate_cert
);
219 X509Certificate::OSCertHandles intermediates
;
220 intermediates
.push_back(intermediate_cert
->os_cert_handle());
221 scoped_refptr
<X509Certificate
> cert_chain
=
222 X509Certificate::CreateFromHandle(server_cert
->os_cert_handle(),
225 CertVerifyResult verify_result
;
226 int flags
= CertVerifier::VERIFY_REV_CHECKING_ENABLED
|
227 CertVerifier::VERIFY_EV_CERT
;
228 int error
= Verify(cert_chain
, "2029.globalsign.com", flags
, NULL
,
229 empty_cert_list_
, &verify_result
);
231 EXPECT_TRUE(verify_result
.cert_status
& CERT_STATUS_IS_EV
);
233 EXPECT_EQ(ERR_CERT_DATE_INVALID
, error
);
236 // Test that verifying an ECDSA certificate doesn't crash on XP. (See
237 // crbug.com/144466).
238 TEST_F(CertVerifyProcTest
, ECDSA_RSA
) {
239 base::FilePath certs_dir
= GetTestCertsDirectory();
241 scoped_refptr
<X509Certificate
> cert
=
242 ImportCertFromFile(certs_dir
,
243 "prime256v1-ecdsa-ee-by-1024-rsa-intermediate.pem");
245 CertVerifyResult verify_result
;
246 Verify(cert
, "127.0.0.1", 0, NULL
, empty_cert_list_
, &verify_result
);
248 // We don't check verify_result because the certificate is signed by an
249 // unknown CA and will be considered invalid on XP because of the ECDSA
253 // Currently, only RSA and DSA keys are checked for weakness, and our example
254 // weak size is 768. These could change in the future.
256 // Note that this means there may be false negatives: keys for other
257 // algorithms and which are weak will pass this test.
258 static bool IsWeakKeyType(const std::string
& key_type
) {
259 size_t pos
= key_type
.find("-");
260 std::string size
= key_type
.substr(0, pos
);
261 std::string type
= key_type
.substr(pos
+ 1);
263 if (type
== "rsa" || type
== "dsa")
264 return size
== "768";
269 TEST_F(CertVerifyProcTest
, RejectWeakKeys
) {
270 base::FilePath certs_dir
= GetTestCertsDirectory();
271 typedef std::vector
<std::string
> Strings
;
274 // generate-weak-test-chains.sh currently has:
275 // key_types="768-rsa 1024-rsa 2048-rsa prime256v1-ecdsa"
276 // We must use the same key types here. The filenames generated look like:
277 // 2048-rsa-ee-by-768-rsa-intermediate.pem
278 key_types
.push_back("768-rsa");
279 key_types
.push_back("1024-rsa");
280 key_types
.push_back("2048-rsa");
282 bool use_ecdsa
= true;
284 use_ecdsa
= base::win::GetVersion() > base::win::VERSION_XP
;
288 key_types
.push_back("prime256v1-ecdsa");
290 // Add the root that signed the intermediates for this test.
291 scoped_refptr
<X509Certificate
> root_cert
=
292 ImportCertFromFile(certs_dir
, "2048-rsa-root.pem");
293 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), root_cert
);
294 ScopedTestRoot
scoped_root(root_cert
);
296 // Now test each chain.
297 for (Strings::const_iterator ee_type
= key_types
.begin();
298 ee_type
!= key_types
.end(); ++ee_type
) {
299 for (Strings::const_iterator signer_type
= key_types
.begin();
300 signer_type
!= key_types
.end(); ++signer_type
) {
301 std::string basename
= *ee_type
+ "-ee-by-" + *signer_type
+
303 SCOPED_TRACE(basename
);
304 scoped_refptr
<X509Certificate
> ee_cert
=
305 ImportCertFromFile(certs_dir
, basename
);
306 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), ee_cert
);
308 basename
= *signer_type
+ "-intermediate.pem";
309 scoped_refptr
<X509Certificate
> intermediate
=
310 ImportCertFromFile(certs_dir
, basename
);
311 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), intermediate
);
313 X509Certificate::OSCertHandles intermediates
;
314 intermediates
.push_back(intermediate
->os_cert_handle());
315 scoped_refptr
<X509Certificate
> cert_chain
=
316 X509Certificate::CreateFromHandle(ee_cert
->os_cert_handle(),
319 CertVerifyResult verify_result
;
320 int error
= Verify(cert_chain
, "127.0.0.1", 0, NULL
,
321 empty_cert_list_
, &verify_result
);
323 if (IsWeakKeyType(*ee_type
) || IsWeakKeyType(*signer_type
)) {
324 EXPECT_NE(OK
, error
);
325 EXPECT_EQ(CERT_STATUS_WEAK_KEY
,
326 verify_result
.cert_status
& CERT_STATUS_WEAK_KEY
);
327 EXPECT_NE(CERT_STATUS_INVALID
,
328 verify_result
.cert_status
& CERT_STATUS_INVALID
);
330 EXPECT_EQ(OK
, error
);
331 EXPECT_EQ(0U, verify_result
.cert_status
& CERT_STATUS_WEAK_KEY
);
337 // Test for bug 108514.
338 // The certificate will expire on 2012-07-20. The test will still
339 // pass if error == ERR_CERT_DATE_INVALID. TODO(rsleevi): generate test
340 // certificates for this unit test. http://crbug.com/111730
341 TEST_F(CertVerifyProcTest
, ExtraneousMD5RootCert
) {
342 base::FilePath certs_dir
= GetTestCertsDirectory();
344 scoped_refptr
<X509Certificate
> server_cert
=
345 ImportCertFromFile(certs_dir
, "images_etrade_wallst_com.pem");
346 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), server_cert
);
348 scoped_refptr
<X509Certificate
> intermediate_cert
=
349 ImportCertFromFile(certs_dir
, "globalsign_orgv1_ca.pem");
350 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), intermediate_cert
);
352 scoped_refptr
<X509Certificate
> md5_root_cert
=
353 ImportCertFromFile(certs_dir
, "globalsign_root_ca_md5.pem");
354 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), md5_root_cert
);
356 X509Certificate::OSCertHandles intermediates
;
357 intermediates
.push_back(intermediate_cert
->os_cert_handle());
358 intermediates
.push_back(md5_root_cert
->os_cert_handle());
359 scoped_refptr
<X509Certificate
> cert_chain
=
360 X509Certificate::CreateFromHandle(server_cert
->os_cert_handle(),
363 CertVerifyResult verify_result
;
365 int error
= Verify(cert_chain
, "images.etrade.wallst.com", flags
, NULL
,
366 empty_cert_list_
, &verify_result
);
368 EXPECT_EQ(ERR_CERT_DATE_INVALID
, error
);
370 EXPECT_FALSE(verify_result
.has_md5
);
371 EXPECT_FALSE(verify_result
.has_md5_ca
);
374 // Test for bug 94673.
375 TEST_F(CertVerifyProcTest
, GoogleDigiNotarTest
) {
376 base::FilePath certs_dir
= GetTestCertsDirectory();
378 scoped_refptr
<X509Certificate
> server_cert
=
379 ImportCertFromFile(certs_dir
, "google_diginotar.pem");
380 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), server_cert
);
382 scoped_refptr
<X509Certificate
> intermediate_cert
=
383 ImportCertFromFile(certs_dir
, "diginotar_public_ca_2025.pem");
384 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), intermediate_cert
);
386 X509Certificate::OSCertHandles intermediates
;
387 intermediates
.push_back(intermediate_cert
->os_cert_handle());
388 scoped_refptr
<X509Certificate
> cert_chain
=
389 X509Certificate::CreateFromHandle(server_cert
->os_cert_handle(),
392 CertVerifyResult verify_result
;
393 int flags
= CertVerifier::VERIFY_REV_CHECKING_ENABLED
;
394 int error
= Verify(cert_chain
, "mail.google.com", flags
, NULL
,
395 empty_cert_list_
, &verify_result
);
396 EXPECT_NE(OK
, error
);
398 // Now turn off revocation checking. Certificate verification should still
401 error
= Verify(cert_chain
, "mail.google.com", flags
, NULL
,
402 empty_cert_list_
, &verify_result
);
403 EXPECT_NE(OK
, error
);
406 TEST_F(CertVerifyProcTest
, DigiNotarCerts
) {
407 static const char* const kDigiNotarFilenames
[] = {
408 "diginotar_root_ca.pem",
409 "diginotar_cyber_ca.pem",
410 "diginotar_services_1024_ca.pem",
411 "diginotar_pkioverheid.pem",
412 "diginotar_pkioverheid_g2.pem",
416 base::FilePath certs_dir
= GetTestCertsDirectory();
418 for (size_t i
= 0; kDigiNotarFilenames
[i
]; i
++) {
419 scoped_refptr
<X509Certificate
> diginotar_cert
=
420 ImportCertFromFile(certs_dir
, kDigiNotarFilenames
[i
]);
421 std::string der_bytes
;
422 ASSERT_TRUE(X509Certificate::GetDEREncoded(
423 diginotar_cert
->os_cert_handle(), &der_bytes
));
425 base::StringPiece spki
;
426 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_bytes
, &spki
));
428 std::string spki_sha1
= base::SHA1HashString(spki
.as_string());
430 HashValueVector public_keys
;
431 HashValue
hash(HASH_VALUE_SHA1
);
432 ASSERT_EQ(hash
.size(), spki_sha1
.size());
433 memcpy(hash
.data(), spki_sha1
.data(), spki_sha1
.size());
434 public_keys
.push_back(hash
);
436 EXPECT_TRUE(CertVerifyProc::IsPublicKeyBlacklisted(public_keys
)) <<
437 "Public key not blocked for " << kDigiNotarFilenames
[i
];
441 TEST_F(CertVerifyProcTest
, TestKnownRoot
) {
442 base::FilePath certs_dir
= GetTestCertsDirectory();
443 CertificateList certs
= CreateCertificateListFromFile(
444 certs_dir
, "certse.pem", X509Certificate::FORMAT_AUTO
);
445 ASSERT_EQ(3U, certs
.size());
447 X509Certificate::OSCertHandles intermediates
;
448 intermediates
.push_back(certs
[1]->os_cert_handle());
449 intermediates
.push_back(certs
[2]->os_cert_handle());
451 scoped_refptr
<X509Certificate
> cert_chain
=
452 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
456 CertVerifyResult verify_result
;
457 // This will blow up, June 8th, 2014. Sorry! Please disable and file a bug
458 // against agl. See also PublicKeyHashes.
459 int error
= Verify(cert_chain
, "cert.se", flags
, NULL
,
460 empty_cert_list_
, &verify_result
);
461 EXPECT_EQ(OK
, error
);
462 EXPECT_EQ(0U, verify_result
.cert_status
);
463 EXPECT_TRUE(verify_result
.is_issued_by_known_root
);
466 TEST_F(CertVerifyProcTest
, PublicKeyHashes
) {
467 base::FilePath certs_dir
= GetTestCertsDirectory();
468 CertificateList certs
= CreateCertificateListFromFile(
469 certs_dir
, "certse.pem", X509Certificate::FORMAT_AUTO
);
470 ASSERT_EQ(3U, certs
.size());
472 X509Certificate::OSCertHandles intermediates
;
473 intermediates
.push_back(certs
[1]->os_cert_handle());
474 intermediates
.push_back(certs
[2]->os_cert_handle());
476 scoped_refptr
<X509Certificate
> cert_chain
=
477 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
480 CertVerifyResult verify_result
;
482 // This will blow up, June 8th, 2014. Sorry! Please disable and file a bug
483 // against agl. See also TestKnownRoot.
484 int error
= Verify(cert_chain
, "cert.se", flags
, NULL
,
485 empty_cert_list_
, &verify_result
);
486 EXPECT_EQ(OK
, error
);
487 EXPECT_EQ(0U, verify_result
.cert_status
);
488 ASSERT_LE(3u, verify_result
.public_key_hashes
.size());
490 HashValueVector sha1_hashes
;
491 for (size_t i
= 0; i
< verify_result
.public_key_hashes
.size(); ++i
) {
492 if (verify_result
.public_key_hashes
[i
].tag
!= HASH_VALUE_SHA1
)
494 sha1_hashes
.push_back(verify_result
.public_key_hashes
[i
]);
496 ASSERT_LE(3u, sha1_hashes
.size());
498 for (size_t i
= 0; i
< 3; ++i
) {
499 EXPECT_EQ(HexEncode(kCertSESPKIs
[i
], base::kSHA1Length
),
500 HexEncode(sha1_hashes
[i
].data(), base::kSHA1Length
));
503 HashValueVector sha256_hashes
;
504 for (size_t i
= 0; i
< verify_result
.public_key_hashes
.size(); ++i
) {
505 if (verify_result
.public_key_hashes
[i
].tag
!= HASH_VALUE_SHA256
)
507 sha256_hashes
.push_back(verify_result
.public_key_hashes
[i
]);
509 ASSERT_LE(3u, sha256_hashes
.size());
511 for (size_t i
= 0; i
< 3; ++i
) {
512 EXPECT_EQ(HexEncode(kCertSESPKIsSHA256
[i
], crypto::kSHA256Length
),
513 HexEncode(sha256_hashes
[i
].data(), crypto::kSHA256Length
));
517 // A regression test for http://crbug.com/70293.
518 // The Key Usage extension in this RSA SSL server certificate does not have
519 // the keyEncipherment bit.
520 TEST_F(CertVerifyProcTest
, InvalidKeyUsage
) {
521 base::FilePath certs_dir
= GetTestCertsDirectory();
523 scoped_refptr
<X509Certificate
> server_cert
=
524 ImportCertFromFile(certs_dir
, "invalid_key_usage_cert.der");
525 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), server_cert
);
528 CertVerifyResult verify_result
;
529 int error
= Verify(server_cert
, "jira.aquameta.com", flags
, NULL
,
530 empty_cert_list_
, &verify_result
);
531 #if defined(USE_OPENSSL) && !defined(OS_ANDROID)
532 // This certificate has two errors: "invalid key usage" and "untrusted CA".
533 // However, OpenSSL returns only one (the latter), and we can't detect
535 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID
, error
);
537 EXPECT_EQ(ERR_CERT_INVALID
, error
);
538 EXPECT_TRUE(verify_result
.cert_status
& CERT_STATUS_INVALID
);
540 // TODO(wtc): fix http://crbug.com/75520 to get all the certificate errors
542 #if !defined(USE_NSS) && !defined(OS_IOS) && !defined(OS_ANDROID)
543 // The certificate is issued by an unknown CA.
544 EXPECT_TRUE(verify_result
.cert_status
& CERT_STATUS_AUTHORITY_INVALID
);
548 // Basic test for returning the chain in CertVerifyResult. Note that the
549 // returned chain may just be a reflection of the originally supplied chain;
550 // that is, if any errors occur, the default chain returned is an exact copy
551 // of the certificate to be verified. The remaining VerifyReturn* tests are
552 // used to ensure that the actual, verified chain is being returned by
554 TEST_F(CertVerifyProcTest
, VerifyReturnChainBasic
) {
555 base::FilePath certs_dir
= GetTestCertsDirectory();
556 CertificateList certs
= CreateCertificateListFromFile(
557 certs_dir
, "x509_verify_results.chain.pem",
558 X509Certificate::FORMAT_AUTO
);
559 ASSERT_EQ(3U, certs
.size());
561 X509Certificate::OSCertHandles intermediates
;
562 intermediates
.push_back(certs
[1]->os_cert_handle());
563 intermediates
.push_back(certs
[2]->os_cert_handle());
565 ScopedTestRoot
scoped_root(certs
[2]);
567 scoped_refptr
<X509Certificate
> google_full_chain
=
568 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
570 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), google_full_chain
);
571 ASSERT_EQ(2U, google_full_chain
->GetIntermediateCertificates().size());
573 CertVerifyResult verify_result
;
574 EXPECT_EQ(static_cast<X509Certificate
*>(NULL
), verify_result
.verified_cert
);
575 int error
= Verify(google_full_chain
, "127.0.0.1", 0, NULL
,
576 empty_cert_list_
, &verify_result
);
577 EXPECT_EQ(OK
, error
);
578 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), verify_result
.verified_cert
);
580 EXPECT_NE(google_full_chain
, verify_result
.verified_cert
);
581 EXPECT_TRUE(X509Certificate::IsSameOSCert(
582 google_full_chain
->os_cert_handle(),
583 verify_result
.verified_cert
->os_cert_handle()));
584 const X509Certificate::OSCertHandles
& return_intermediates
=
585 verify_result
.verified_cert
->GetIntermediateCertificates();
586 ASSERT_EQ(2U, return_intermediates
.size());
587 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates
[0],
588 certs
[1]->os_cert_handle()));
589 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates
[1],
590 certs
[2]->os_cert_handle()));
593 // Test that the certificate returned in CertVerifyResult is able to reorder
594 // certificates that are not ordered from end-entity to root. While this is
595 // a protocol violation if sent during a TLS handshake, if multiple sources
596 // of intermediate certificates are combined, it's possible that order may
597 // not be maintained.
598 TEST_F(CertVerifyProcTest
, VerifyReturnChainProperlyOrdered
) {
599 base::FilePath certs_dir
= GetTestCertsDirectory();
600 CertificateList certs
= CreateCertificateListFromFile(
601 certs_dir
, "x509_verify_results.chain.pem",
602 X509Certificate::FORMAT_AUTO
);
603 ASSERT_EQ(3U, certs
.size());
605 // Construct the chain out of order.
606 X509Certificate::OSCertHandles intermediates
;
607 intermediates
.push_back(certs
[2]->os_cert_handle());
608 intermediates
.push_back(certs
[1]->os_cert_handle());
610 ScopedTestRoot
scoped_root(certs
[2]);
612 scoped_refptr
<X509Certificate
> google_full_chain
=
613 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
615 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), google_full_chain
);
616 ASSERT_EQ(2U, google_full_chain
->GetIntermediateCertificates().size());
618 CertVerifyResult verify_result
;
619 EXPECT_EQ(static_cast<X509Certificate
*>(NULL
), verify_result
.verified_cert
);
620 int error
= Verify(google_full_chain
, "127.0.0.1", 0, NULL
,
621 empty_cert_list_
, &verify_result
);
622 EXPECT_EQ(OK
, error
);
623 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), verify_result
.verified_cert
);
625 EXPECT_NE(google_full_chain
, verify_result
.verified_cert
);
626 EXPECT_TRUE(X509Certificate::IsSameOSCert(
627 google_full_chain
->os_cert_handle(),
628 verify_result
.verified_cert
->os_cert_handle()));
629 const X509Certificate::OSCertHandles
& return_intermediates
=
630 verify_result
.verified_cert
->GetIntermediateCertificates();
631 ASSERT_EQ(2U, return_intermediates
.size());
632 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates
[0],
633 certs
[1]->os_cert_handle()));
634 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates
[1],
635 certs
[2]->os_cert_handle()));
638 // Test that Verify() filters out certificates which are not related to
639 // or part of the certificate chain being verified.
640 TEST_F(CertVerifyProcTest
, VerifyReturnChainFiltersUnrelatedCerts
) {
641 base::FilePath certs_dir
= GetTestCertsDirectory();
642 CertificateList certs
= CreateCertificateListFromFile(
643 certs_dir
, "x509_verify_results.chain.pem",
644 X509Certificate::FORMAT_AUTO
);
645 ASSERT_EQ(3U, certs
.size());
646 ScopedTestRoot
scoped_root(certs
[2]);
648 scoped_refptr
<X509Certificate
> unrelated_dod_certificate
=
649 ImportCertFromFile(certs_dir
, "dod_ca_17_cert.der");
650 scoped_refptr
<X509Certificate
> unrelated_dod_certificate2
=
651 ImportCertFromFile(certs_dir
, "dod_root_ca_2_cert.der");
652 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), unrelated_dod_certificate
);
653 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), unrelated_dod_certificate2
);
655 // Interject unrelated certificates into the list of intermediates.
656 X509Certificate::OSCertHandles intermediates
;
657 intermediates
.push_back(unrelated_dod_certificate
->os_cert_handle());
658 intermediates
.push_back(certs
[1]->os_cert_handle());
659 intermediates
.push_back(unrelated_dod_certificate2
->os_cert_handle());
660 intermediates
.push_back(certs
[2]->os_cert_handle());
662 scoped_refptr
<X509Certificate
> google_full_chain
=
663 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
665 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), google_full_chain
);
666 ASSERT_EQ(4U, google_full_chain
->GetIntermediateCertificates().size());
668 CertVerifyResult verify_result
;
669 EXPECT_EQ(static_cast<X509Certificate
*>(NULL
), verify_result
.verified_cert
);
670 int error
= Verify(google_full_chain
, "127.0.0.1", 0, NULL
,
671 empty_cert_list_
, &verify_result
);
672 EXPECT_EQ(OK
, error
);
673 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), verify_result
.verified_cert
);
675 EXPECT_NE(google_full_chain
, verify_result
.verified_cert
);
676 EXPECT_TRUE(X509Certificate::IsSameOSCert(
677 google_full_chain
->os_cert_handle(),
678 verify_result
.verified_cert
->os_cert_handle()));
679 const X509Certificate::OSCertHandles
& return_intermediates
=
680 verify_result
.verified_cert
->GetIntermediateCertificates();
681 ASSERT_EQ(2U, return_intermediates
.size());
682 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates
[0],
683 certs
[1]->os_cert_handle()));
684 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates
[1],
685 certs
[2]->os_cert_handle()));
688 TEST_F(CertVerifyProcTest
, AdditionalTrustAnchors
) {
689 if (!SupportsAdditionalTrustAnchors()) {
690 LOG(INFO
) << "Skipping this test in this platform.";
694 // |ca_cert| is the issuer of |cert|.
695 CertificateList ca_cert_list
= CreateCertificateListFromFile(
696 GetTestCertsDirectory(), "root_ca_cert.crt",
697 X509Certificate::FORMAT_AUTO
);
698 ASSERT_EQ(1U, ca_cert_list
.size());
699 scoped_refptr
<X509Certificate
> ca_cert(ca_cert_list
[0]);
701 CertificateList cert_list
= CreateCertificateListFromFile(
702 GetTestCertsDirectory(), "ok_cert.pem",
703 X509Certificate::FORMAT_AUTO
);
704 ASSERT_EQ(1U, cert_list
.size());
705 scoped_refptr
<X509Certificate
> cert(cert_list
[0]);
707 // Verification of |cert| fails when |ca_cert| is not in the trust anchors
710 CertVerifyResult verify_result
;
711 int error
= Verify(cert
, "127.0.0.1", flags
, NULL
,
712 empty_cert_list_
, &verify_result
);
713 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID
, error
);
714 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID
, verify_result
.cert_status
);
715 EXPECT_FALSE(verify_result
.is_issued_by_additional_trust_anchor
);
717 // Now add the |ca_cert| to the |trust_anchors|, and verification should pass.
718 CertificateList trust_anchors
;
719 trust_anchors
.push_back(ca_cert
);
720 error
= Verify(cert
, "127.0.0.1", flags
, NULL
, trust_anchors
, &verify_result
);
721 EXPECT_EQ(OK
, error
);
722 EXPECT_EQ(0U, verify_result
.cert_status
);
723 EXPECT_TRUE(verify_result
.is_issued_by_additional_trust_anchor
);
725 // Clearing the |trust_anchors| makes verification fail again (the cache
726 // should be skipped).
727 error
= Verify(cert
, "127.0.0.1", flags
, NULL
,
728 empty_cert_list_
, &verify_result
);
729 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID
, error
);
730 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID
, verify_result
.cert_status
);
731 EXPECT_FALSE(verify_result
.is_issued_by_additional_trust_anchor
);
734 #if defined(USE_NSS) || defined(OS_IOS) || defined(OS_WIN) || defined(OS_MACOSX)
735 static const uint8 kCRLSetThawteSPKIBlocked
[] = {
736 0x8e, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a,
737 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
738 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22,
739 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22,
740 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c,
741 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a,
742 0x30, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b,
743 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x36, 0x58, 0x36, 0x4d, 0x78, 0x52, 0x37,
744 0x58, 0x70, 0x4d, 0x51, 0x4b, 0x78, 0x49, 0x41, 0x39, 0x50, 0x6a, 0x36, 0x37,
745 0x36, 0x38, 0x76, 0x74, 0x55, 0x6b, 0x6b, 0x7a, 0x48, 0x79, 0x7a, 0x41, 0x6f,
746 0x6d, 0x6f, 0x4f, 0x68, 0x4b, 0x55, 0x6e, 0x7a, 0x73, 0x55, 0x3d, 0x22, 0x5d,
750 static const uint8 kCRLSetThawteSerialBlocked
[] = {
751 0x60, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a,
752 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
753 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22,
754 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22,
755 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c,
756 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a,
757 0x31, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b,
758 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0xb1, 0x12, 0x41, 0x42, 0xa5, 0xa1,
759 0xa5, 0xa2, 0x88, 0x19, 0xc7, 0x35, 0x34, 0x0e, 0xff, 0x8c, 0x9e, 0x2f, 0x81,
760 0x68, 0xfe, 0xe3, 0xba, 0x18, 0x7f, 0x25, 0x3b, 0xc1, 0xa3, 0x92, 0xd7, 0xe2,
761 // Note that this is actually blocking two serial numbers because on XP and
762 // Vista, CryptoAPI finds a different Thawte certificate.
763 0x02, 0x00, 0x00, 0x00,
764 0x04, 0x30, 0x00, 0x00, 0x02,
765 0x04, 0x30, 0x00, 0x00, 0x06,
768 static const uint8 kCRLSetGoogleSerialBlocked
[] = {
769 0x60, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a,
770 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
771 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22,
772 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22,
773 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c,
774 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a,
775 0x31, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b,
776 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0xe9, 0x7e, 0x8c, 0xc5, 0x1e, 0xd7,
777 0xa4, 0xc4, 0x0a, 0xc4, 0x80, 0x3d, 0x3e, 0x3e, 0xbb, 0xeb, 0xcb, 0xed, 0x52,
778 0x49, 0x33, 0x1f, 0x2c, 0xc0, 0xa2, 0x6a, 0x0e, 0x84, 0xa5, 0x27, 0xce, 0xc5,
779 0x01, 0x00, 0x00, 0x00, 0x10, 0x4f, 0x9d, 0x96, 0xd9, 0x66, 0xb0, 0x99, 0x2b,
780 0x54, 0xc2, 0x95, 0x7c, 0xb4, 0x15, 0x7d, 0x4d,
783 // Test that CRLSets are effective in making a certificate appear to be
785 TEST_F(CertVerifyProcTest
, CRLSet
) {
786 CertificateList certs
= CreateCertificateListFromFile(
787 GetTestCertsDirectory(),
788 "googlenew.chain.pem",
789 X509Certificate::FORMAT_PEM_CERT_SEQUENCE
);
791 X509Certificate::OSCertHandles intermediates
;
792 intermediates
.push_back(certs
[1]->os_cert_handle());
794 scoped_refptr
<X509Certificate
> google_full_chain
=
795 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
798 CertVerifyResult verify_result
;
799 int error
= Verify(google_full_chain
, "www.google.com", 0, NULL
,
800 empty_cert_list_
, &verify_result
);
801 EXPECT_EQ(OK
, error
);
803 // First test blocking by SPKI.
804 base::StringPiece
crl_set_bytes(
805 reinterpret_cast<const char*>(kCRLSetThawteSPKIBlocked
),
806 sizeof(kCRLSetThawteSPKIBlocked
));
807 scoped_refptr
<CRLSet
> crl_set
;
808 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes
, &crl_set
));
810 error
= Verify(google_full_chain
, "www.google.com", 0, crl_set
.get(),
811 empty_cert_list_
, &verify_result
);
812 EXPECT_EQ(ERR_CERT_REVOKED
, error
);
814 // Second, test revocation by serial number of a cert directly under the
816 crl_set_bytes
= base::StringPiece(
817 reinterpret_cast<const char*>(kCRLSetThawteSerialBlocked
),
818 sizeof(kCRLSetThawteSerialBlocked
));
819 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes
, &crl_set
));
821 error
= Verify(google_full_chain
, "www.google.com", 0, crl_set
.get(),
822 empty_cert_list_
, &verify_result
);
823 EXPECT_EQ(ERR_CERT_REVOKED
, error
);
825 // Lastly, test revocation by serial number of a certificate not under the
827 crl_set_bytes
= base::StringPiece(
828 reinterpret_cast<const char*>(kCRLSetGoogleSerialBlocked
),
829 sizeof(kCRLSetGoogleSerialBlocked
));
830 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes
, &crl_set
));
832 error
= Verify(google_full_chain
, "www.google.com", 0, crl_set
.get(),
833 empty_cert_list_
, &verify_result
);
834 EXPECT_EQ(ERR_CERT_REVOKED
, error
);
838 struct WeakDigestTestData
{
839 const char* root_cert_filename
;
840 const char* intermediate_cert_filename
;
841 const char* ee_cert_filename
;
842 bool expected_has_md5
;
843 bool expected_has_md4
;
844 bool expected_has_md2
;
845 bool expected_has_md5_ca
;
846 bool expected_has_md2_ca
;
849 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
850 // to output the parameter that was passed. Without this, it will simply
851 // attempt to print out the first twenty bytes of the object, which depending
852 // on platform and alignment, may result in an invalid read.
853 void PrintTo(const WeakDigestTestData
& data
, std::ostream
* os
) {
855 << (data
.root_cert_filename
? data
.root_cert_filename
: "none")
856 << "; intermediate: " << data
.intermediate_cert_filename
857 << "; end-entity: " << data
.ee_cert_filename
;
860 class CertVerifyProcWeakDigestTest
861 : public CertVerifyProcTest
,
862 public testing::WithParamInterface
<WeakDigestTestData
> {
864 CertVerifyProcWeakDigestTest() {}
865 virtual ~CertVerifyProcWeakDigestTest() {}
868 TEST_P(CertVerifyProcWeakDigestTest
, Verify
) {
869 WeakDigestTestData data
= GetParam();
870 base::FilePath certs_dir
= GetTestCertsDirectory();
872 ScopedTestRoot test_root
;
873 if (data
.root_cert_filename
) {
874 scoped_refptr
<X509Certificate
> root_cert
=
875 ImportCertFromFile(certs_dir
, data
.root_cert_filename
);
876 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), root_cert
);
877 test_root
.Reset(root_cert
);
880 scoped_refptr
<X509Certificate
> intermediate_cert
=
881 ImportCertFromFile(certs_dir
, data
.intermediate_cert_filename
);
882 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), intermediate_cert
);
883 scoped_refptr
<X509Certificate
> ee_cert
=
884 ImportCertFromFile(certs_dir
, data
.ee_cert_filename
);
885 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), ee_cert
);
887 X509Certificate::OSCertHandles intermediates
;
888 intermediates
.push_back(intermediate_cert
->os_cert_handle());
890 scoped_refptr
<X509Certificate
> ee_chain
=
891 X509Certificate::CreateFromHandle(ee_cert
->os_cert_handle(),
893 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), ee_chain
);
896 CertVerifyResult verify_result
;
897 int rv
= Verify(ee_chain
, "127.0.0.1", flags
, NULL
,
898 empty_cert_list_
, &verify_result
);
899 EXPECT_EQ(data
.expected_has_md5
, verify_result
.has_md5
);
900 EXPECT_EQ(data
.expected_has_md4
, verify_result
.has_md4
);
901 EXPECT_EQ(data
.expected_has_md2
, verify_result
.has_md2
);
902 EXPECT_EQ(data
.expected_has_md5_ca
, verify_result
.has_md5_ca
);
903 EXPECT_EQ(data
.expected_has_md2_ca
, verify_result
.has_md2_ca
);
904 EXPECT_FALSE(verify_result
.is_issued_by_additional_trust_anchor
);
906 // Ensure that MD4 and MD2 are tagged as invalid.
907 if (data
.expected_has_md4
|| data
.expected_has_md2
) {
908 EXPECT_EQ(CERT_STATUS_INVALID
,
909 verify_result
.cert_status
& CERT_STATUS_INVALID
);
912 // Ensure that MD5 is flagged as weak.
913 if (data
.expected_has_md5
) {
915 CERT_STATUS_WEAK_SIGNATURE_ALGORITHM
,
916 verify_result
.cert_status
& CERT_STATUS_WEAK_SIGNATURE_ALGORITHM
);
919 // If a root cert is present, then check that the chain was rejected if any
920 // weak algorithms are present. This is only checked when a root cert is
921 // present because the error reported for incomplete chains with weak
922 // algorithms depends on which implementation was used to validate (NSS,
923 // OpenSSL, CryptoAPI, Security.framework) and upon which weak algorithm
924 // present (MD2, MD4, MD5).
925 if (data
.root_cert_filename
) {
926 if (data
.expected_has_md4
|| data
.expected_has_md2
) {
927 EXPECT_EQ(ERR_CERT_INVALID
, rv
);
928 } else if (data
.expected_has_md5
) {
929 EXPECT_EQ(ERR_CERT_WEAK_SIGNATURE_ALGORITHM
, rv
);
936 // Unlike TEST/TEST_F, which are macros that expand to further macros,
937 // INSTANTIATE_TEST_CASE_P is a macro that expands directly to code that
938 // stringizes the arguments. As a result, macros passed as parameters (such as
939 // prefix or test_case_name) will not be expanded by the preprocessor. To work
940 // around this, indirect the macro for INSTANTIATE_TEST_CASE_P, so that the
941 // pre-processor will expand macros such as MAYBE_test_name before
942 // instantiating the test.
943 #define WRAPPED_INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
944 INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator)
946 // The signature algorithm of the root CA should not matter.
947 const WeakDigestTestData kVerifyRootCATestData
[] = {
948 { "weak_digest_md5_root.pem", "weak_digest_sha1_intermediate.pem",
949 "weak_digest_sha1_ee.pem", false, false, false, false, false },
950 #if defined(USE_OPENSSL) || defined(OS_WIN)
951 // MD4 is not supported by OS X / NSS
952 { "weak_digest_md4_root.pem", "weak_digest_sha1_intermediate.pem",
953 "weak_digest_sha1_ee.pem", false, false, false, false, false },
955 { "weak_digest_md2_root.pem", "weak_digest_sha1_intermediate.pem",
956 "weak_digest_sha1_ee.pem", false, false, false, false, false },
958 INSTANTIATE_TEST_CASE_P(VerifyRoot
, CertVerifyProcWeakDigestTest
,
959 testing::ValuesIn(kVerifyRootCATestData
));
961 // The signature algorithm of intermediates should be properly detected.
962 const WeakDigestTestData kVerifyIntermediateCATestData
[] = {
963 { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
964 "weak_digest_sha1_ee.pem", true, false, false, true, false },
965 #if defined(USE_OPENSSL) || defined(OS_WIN)
966 // MD4 is not supported by OS X / NSS
967 { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
968 "weak_digest_sha1_ee.pem", false, true, false, false, false },
970 { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
971 "weak_digest_sha1_ee.pem", false, false, true, false, true },
973 // Disabled on NSS - MD4 is not supported, and MD2 and MD5 are disabled.
974 #if defined(USE_NSS) || defined(OS_IOS)
975 #define MAYBE_VerifyIntermediate DISABLED_VerifyIntermediate
977 #define MAYBE_VerifyIntermediate VerifyIntermediate
979 WRAPPED_INSTANTIATE_TEST_CASE_P(
980 MAYBE_VerifyIntermediate
,
981 CertVerifyProcWeakDigestTest
,
982 testing::ValuesIn(kVerifyIntermediateCATestData
));
984 // The signature algorithm of end-entity should be properly detected.
985 const WeakDigestTestData kVerifyEndEntityTestData
[] = {
986 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
987 "weak_digest_md5_ee.pem", true, false, false, false, false },
988 #if defined(USE_OPENSSL) || defined(OS_WIN)
989 // MD4 is not supported by OS X / NSS
990 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
991 "weak_digest_md4_ee.pem", false, true, false, false, false },
993 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
994 "weak_digest_md2_ee.pem", false, false, true, false, false },
996 // Disabled on NSS - NSS caches chains/signatures in such a way that cannot
997 // be cleared until NSS is cleanly shutdown, which is not presently supported
999 #if defined(USE_NSS) || defined(OS_IOS)
1000 #define MAYBE_VerifyEndEntity DISABLED_VerifyEndEntity
1002 #define MAYBE_VerifyEndEntity VerifyEndEntity
1004 WRAPPED_INSTANTIATE_TEST_CASE_P(MAYBE_VerifyEndEntity
,
1005 CertVerifyProcWeakDigestTest
,
1006 testing::ValuesIn(kVerifyEndEntityTestData
));
1008 // Incomplete chains should still report the status of the intermediate.
1009 const WeakDigestTestData kVerifyIncompleteIntermediateTestData
[] = {
1010 { NULL
, "weak_digest_md5_intermediate.pem", "weak_digest_sha1_ee.pem",
1011 true, false, false, true, false },
1012 #if defined(USE_OPENSSL) || defined(OS_WIN)
1013 // MD4 is not supported by OS X / NSS
1014 { NULL
, "weak_digest_md4_intermediate.pem", "weak_digest_sha1_ee.pem",
1015 false, true, false, false, false },
1017 { NULL
, "weak_digest_md2_intermediate.pem", "weak_digest_sha1_ee.pem",
1018 false, false, true, false, true },
1020 // Disabled on NSS - libpkix does not return constructed chains on error,
1021 // preventing us from detecting/inspecting the verified chain.
1022 #if defined(USE_NSS) || defined(OS_IOS)
1023 #define MAYBE_VerifyIncompleteIntermediate \
1024 DISABLED_VerifyIncompleteIntermediate
1026 #define MAYBE_VerifyIncompleteIntermediate VerifyIncompleteIntermediate
1028 WRAPPED_INSTANTIATE_TEST_CASE_P(
1029 MAYBE_VerifyIncompleteIntermediate
,
1030 CertVerifyProcWeakDigestTest
,
1031 testing::ValuesIn(kVerifyIncompleteIntermediateTestData
));
1033 // Incomplete chains should still report the status of the end-entity.
1034 const WeakDigestTestData kVerifyIncompleteEETestData
[] = {
1035 { NULL
, "weak_digest_sha1_intermediate.pem", "weak_digest_md5_ee.pem",
1036 true, false, false, false, false },
1037 #if defined(USE_OPENSSL) || defined(OS_WIN)
1038 // MD4 is not supported by OS X / NSS
1039 { NULL
, "weak_digest_sha1_intermediate.pem", "weak_digest_md4_ee.pem",
1040 false, true, false, false, false },
1042 { NULL
, "weak_digest_sha1_intermediate.pem", "weak_digest_md2_ee.pem",
1043 false, false, true, false, false },
1045 // Disabled on NSS - libpkix does not return constructed chains on error,
1046 // preventing us from detecting/inspecting the verified chain.
1047 #if defined(USE_NSS) || defined(OS_IOS)
1048 #define MAYBE_VerifyIncompleteEndEntity DISABLED_VerifyIncompleteEndEntity
1050 #define MAYBE_VerifyIncompleteEndEntity VerifyIncompleteEndEntity
1052 WRAPPED_INSTANTIATE_TEST_CASE_P(
1053 MAYBE_VerifyIncompleteEndEntity
,
1054 CertVerifyProcWeakDigestTest
,
1055 testing::ValuesIn(kVerifyIncompleteEETestData
));
1057 // Differing algorithms between the intermediate and the EE should still be
1059 const WeakDigestTestData kVerifyMixedTestData
[] = {
1060 { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
1061 "weak_digest_md2_ee.pem", true, false, true, true, false },
1062 { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
1063 "weak_digest_md5_ee.pem", true, false, true, false, true },
1064 #if defined(USE_OPENSSL) || defined(OS_WIN)
1065 // MD4 is not supported by OS X / NSS
1066 { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
1067 "weak_digest_md2_ee.pem", false, true, true, false, false },
1070 // NSS does not support MD4 and does not enable MD2 by default, making all
1071 // permutations invalid.
1072 #if defined(USE_NSS) || defined(OS_IOS)
1073 #define MAYBE_VerifyMixed DISABLED_VerifyMixed
1075 #define MAYBE_VerifyMixed VerifyMixed
1077 WRAPPED_INSTANTIATE_TEST_CASE_P(
1079 CertVerifyProcWeakDigestTest
,
1080 testing::ValuesIn(kVerifyMixedTestData
));