blob: 9dae0b25c5b8ab1c3f595f9cc31266ebce140def [file] [log] [blame]
[email protected]66d9b6e32012-03-22 03:04:321// 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.
4
5#include "net/base/cert_verify_proc.h"
6
7#include <vector>
8
9#include "base/file_path.h"
10#include "base/string_number_conversions.h"
11#include "base/sha1.h"
[email protected]62b23c22012-03-22 04:50:2412#include "net/base/asn1_util.h"
[email protected]66d9b6e32012-03-22 03:04:3213#include "net/base/cert_status_flags.h"
14#include "net/base/cert_test_util.h"
[email protected]8738e0d72012-08-23 02:00:4715#include "net/base/cert_verifier.h"
[email protected]66d9b6e32012-03-22 03:04:3216#include "net/base/cert_verify_result.h"
17#include "net/base/crl_set.h"
18#include "net/base/net_errors.h"
19#include "net/base/test_certificate_data.h"
[email protected]42fdb452012-11-01 12:44:4020#include "net/base/test_data_directory.h"
[email protected]66d9b6e32012-03-22 03:04:3221#include "net/base/test_root_certs.h"
22#include "net/base/x509_certificate.h"
23#include "testing/gtest/include/gtest/gtest.h"
24
25#if defined(OS_WIN)
26#include "base/win/windows_version.h"
[email protected]12b3c8822012-09-26 11:51:1827#elif defined(OS_MACOSX) && !defined(OS_IOS)
[email protected]66d9b6e32012-03-22 03:04:3228#include "base/mac/mac_util.h"
29#endif
30
31using base::HexEncode;
32
33namespace net {
34
35namespace {
36
37// A certificate for www.paypal.com with a NULL byte in the common name.
38// From http://www.gossamer-threads.com/lists/fulldisc/full-disclosure/70363
39unsigned char paypal_null_fingerprint[] = {
40 0x4c, 0x88, 0x9e, 0x28, 0xd7, 0x7a, 0x44, 0x1e, 0x13, 0xf2, 0x6a, 0xba,
41 0x1f, 0xe8, 0x1b, 0xd6, 0xab, 0x7b, 0xe8, 0xd7
42};
43
44} // namespace
45
46class CertVerifyProcTest : public testing::Test {
47 public:
48 CertVerifyProcTest()
49 : verify_proc_(CertVerifyProc::CreateDefault()) {
50 }
51 virtual ~CertVerifyProcTest() {}
52
53 protected:
54 int Verify(X509Certificate* cert,
55 const std::string& hostname,
56 int flags,
57 CRLSet* crl_set,
58 CertVerifyResult* verify_result) {
59 return verify_proc_->Verify(cert, hostname, flags, crl_set,
60 verify_result);
61 }
62
63 private:
64 scoped_refptr<CertVerifyProc> verify_proc_;
65};
66
67TEST_F(CertVerifyProcTest, WithoutRevocationChecking) {
68 // Check that verification without revocation checking works.
69 CertificateList certs = CreateCertificateListFromFile(
70 GetTestCertsDirectory(),
71 "googlenew.chain.pem",
72 X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
73
74 X509Certificate::OSCertHandles intermediates;
75 intermediates.push_back(certs[1]->os_cert_handle());
76
77 scoped_refptr<X509Certificate> google_full_chain =
78 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
79 intermediates);
80
81 CertVerifyResult verify_result;
82 EXPECT_EQ(OK, Verify(google_full_chain, "www.google.com", 0 /* flags */,
83 NULL, &verify_result));
84}
85
86#if defined(OS_ANDROID) || defined(USE_OPENSSL)
87// TODO(jnd): http://crbug.com/117478 - EV verification is not yet supported.
88#define MAYBE_EVVerification DISABLED_EVVerification
89#else
90#define MAYBE_EVVerification EVVerification
91#endif
92TEST_F(CertVerifyProcTest, MAYBE_EVVerification) {
93 // This certificate will expire Jun 21, 2013.
94 CertificateList certs = CreateCertificateListFromFile(
95 GetTestCertsDirectory(),
96 "comodo.chain.pem",
97 X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
98 ASSERT_EQ(3U, certs.size());
99
100 X509Certificate::OSCertHandles intermediates;
101 intermediates.push_back(certs[1]->os_cert_handle());
102 intermediates.push_back(certs[2]->os_cert_handle());
103
104 scoped_refptr<X509Certificate> comodo_chain =
105 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
106 intermediates);
107
108 scoped_refptr<CRLSet> crl_set(CRLSet::EmptyCRLSetForTesting());
109 CertVerifyResult verify_result;
[email protected]8738e0d72012-08-23 02:00:47110 int flags = CertVerifier::VERIFY_EV_CERT;
[email protected]66d9b6e32012-03-22 03:04:32111 int error = Verify(comodo_chain, "comodo.com", flags, crl_set.get(),
112 &verify_result);
113 EXPECT_EQ(OK, error);
114 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV);
115}
116
117TEST_F(CertVerifyProcTest, PaypalNullCertParsing) {
118 scoped_refptr<X509Certificate> paypal_null_cert(
119 X509Certificate::CreateFromBytes(
120 reinterpret_cast<const char*>(paypal_null_der),
121 sizeof(paypal_null_der)));
122
123 ASSERT_NE(static_cast<X509Certificate*>(NULL), paypal_null_cert);
124
[email protected]ede03212012-09-07 12:52:26125 const SHA1HashValue& fingerprint =
[email protected]66d9b6e32012-03-22 03:04:32126 paypal_null_cert->fingerprint();
127 for (size_t i = 0; i < 20; ++i)
128 EXPECT_EQ(paypal_null_fingerprint[i], fingerprint.data[i]);
129
130 int flags = 0;
131 CertVerifyResult verify_result;
132 int error = Verify(paypal_null_cert, "www.paypal.com", flags, NULL,
133 &verify_result);
[email protected]12b3c8822012-09-26 11:51:18134#if defined(USE_NSS) || defined(OS_IOS)
[email protected]317dbc72012-04-03 18:45:14135 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error);
136#else
[email protected]66d9b6e32012-03-22 03:04:32137 // TOOD(bulach): investigate why macosx and win aren't returning
138 // ERR_CERT_INVALID or ERR_CERT_COMMON_NAME_INVALID.
139 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
[email protected]66d9b6e32012-03-22 03:04:32140#endif
141 // Either the system crypto library should correctly report a certificate
142 // name mismatch, or our certificate blacklist should cause us to report an
143 // invalid certificate.
[email protected]12b3c8822012-09-26 11:51:18144#if defined(USE_NSS) || defined(OS_WIN) || defined(OS_IOS)
[email protected]66d9b6e32012-03-22 03:04:32145 EXPECT_TRUE(verify_result.cert_status &
146 (CERT_STATUS_COMMON_NAME_INVALID | CERT_STATUS_INVALID));
147#endif
148}
149
150// A regression test for http://crbug.com/31497.
151// This certificate will expire on 2012-04-08. The test will still
152// pass if error == ERR_CERT_DATE_INVALID. TODO(wtc): generate test
153// certificates for this unit test. http://crbug.com/111742
154TEST_F(CertVerifyProcTest, IntermediateCARequireExplicitPolicy) {
[email protected]6cdfd7f2013-02-08 20:40:15155 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]66d9b6e32012-03-22 03:04:32156
157 scoped_refptr<X509Certificate> server_cert =
158 ImportCertFromFile(certs_dir, "www_us_army_mil_cert.der");
159 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
160
161 // The intermediate CA certificate's policyConstraints extension has a
162 // requireExplicitPolicy field with SkipCerts=0.
163 scoped_refptr<X509Certificate> intermediate_cert =
164 ImportCertFromFile(certs_dir, "dod_ca_17_cert.der");
165 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert);
166
167 scoped_refptr<X509Certificate> root_cert =
168 ImportCertFromFile(certs_dir, "dod_root_ca_2_cert.der");
169 ScopedTestRoot scoped_root(root_cert);
170
171 X509Certificate::OSCertHandles intermediates;
172 intermediates.push_back(intermediate_cert->os_cert_handle());
173 scoped_refptr<X509Certificate> cert_chain =
174 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
175 intermediates);
176
177 int flags = 0;
178 CertVerifyResult verify_result;
179 int error = Verify(cert_chain, "www.us.army.mil", flags, NULL,
180 &verify_result);
181 if (error == OK) {
182 EXPECT_EQ(0U, verify_result.cert_status);
183 } else {
184 EXPECT_EQ(ERR_CERT_DATE_INVALID, error);
185 EXPECT_EQ(CERT_STATUS_DATE_INVALID, verify_result.cert_status);
186 }
187}
188
189
190// Test for bug 58437.
191// This certificate will expire on 2011-12-21. The test will still
192// pass if error == ERR_CERT_DATE_INVALID.
193// This test is DISABLED because it appears that we cannot do
194// certificate revocation checking when running all of the net unit tests.
195// This test passes when run individually, but when run with all of the net
196// unit tests, the call to PKIXVerifyCert returns the NSS error -8180, which is
197// SEC_ERROR_REVOKED_CERTIFICATE. This indicates a lack of revocation
198// status, i.e. that the revocation check is failing for some reason.
199TEST_F(CertVerifyProcTest, DISABLED_GlobalSignR3EVTest) {
[email protected]6cdfd7f2013-02-08 20:40:15200 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]66d9b6e32012-03-22 03:04:32201
202 scoped_refptr<X509Certificate> server_cert =
203 ImportCertFromFile(certs_dir, "2029_globalsign_com_cert.pem");
204 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
205
206 scoped_refptr<X509Certificate> intermediate_cert =
207 ImportCertFromFile(certs_dir, "globalsign_ev_sha256_ca_cert.pem");
208 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert);
209
210 X509Certificate::OSCertHandles intermediates;
211 intermediates.push_back(intermediate_cert->os_cert_handle());
212 scoped_refptr<X509Certificate> cert_chain =
213 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
214 intermediates);
215
216 CertVerifyResult verify_result;
[email protected]8738e0d72012-08-23 02:00:47217 int flags = CertVerifier::VERIFY_REV_CHECKING_ENABLED |
218 CertVerifier::VERIFY_EV_CERT;
[email protected]66d9b6e32012-03-22 03:04:32219 int error = Verify(cert_chain, "2029.globalsign.com", flags, NULL,
220 &verify_result);
221 if (error == OK)
222 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV);
223 else
224 EXPECT_EQ(ERR_CERT_DATE_INVALID, error);
225}
226
[email protected]fe845ab62012-08-24 16:03:29227// Test that verifying an ECDSA certificate doesn't crash on XP. (See
228// crbug.com/144466).
229TEST_F(CertVerifyProcTest, ECDSA_RSA) {
[email protected]6cdfd7f2013-02-08 20:40:15230 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]fe845ab62012-08-24 16:03:29231
232 scoped_refptr<X509Certificate> cert =
233 ImportCertFromFile(certs_dir,
234 "prime256v1-ecdsa-ee-by-1024-rsa-intermediate.pem");
235
236 CertVerifyResult verify_result;
237 Verify(cert, "127.0.0.1", 0, NULL, &verify_result);
238
239 // We don't check verify_result because the certificate is signed by an
240 // unknown CA and will be considered invalid on XP because of the ECDSA
241 // public key.
242}
243
[email protected]66d9b6e32012-03-22 03:04:32244// Currently, only RSA and DSA keys are checked for weakness, and our example
245// weak size is 768. These could change in the future.
246//
247// Note that this means there may be false negatives: keys for other
248// algorithms and which are weak will pass this test.
249static bool IsWeakKeyType(const std::string& key_type) {
250 size_t pos = key_type.find("-");
251 std::string size = key_type.substr(0, pos);
252 std::string type = key_type.substr(pos + 1);
253
254 if (type == "rsa" || type == "dsa")
255 return size == "768";
256
257 return false;
258}
259
260TEST_F(CertVerifyProcTest, RejectWeakKeys) {
[email protected]6cdfd7f2013-02-08 20:40:15261 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]66d9b6e32012-03-22 03:04:32262 typedef std::vector<std::string> Strings;
263 Strings key_types;
264
265 // generate-weak-test-chains.sh currently has:
266 // key_types="768-rsa 1024-rsa 2048-rsa prime256v1-ecdsa"
267 // We must use the same key types here. The filenames generated look like:
268 // 2048-rsa-ee-by-768-rsa-intermediate.pem
269 key_types.push_back("768-rsa");
270 key_types.push_back("1024-rsa");
271 key_types.push_back("2048-rsa");
272
273 bool use_ecdsa = true;
274#if defined(OS_WIN)
275 use_ecdsa = base::win::GetVersion() > base::win::VERSION_XP;
[email protected]66d9b6e32012-03-22 03:04:32276#endif
277
278 if (use_ecdsa)
279 key_types.push_back("prime256v1-ecdsa");
280
281 // Add the root that signed the intermediates for this test.
282 scoped_refptr<X509Certificate> root_cert =
283 ImportCertFromFile(certs_dir, "2048-rsa-root.pem");
284 ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert);
285 ScopedTestRoot scoped_root(root_cert);
286
287 // Now test each chain.
288 for (Strings::const_iterator ee_type = key_types.begin();
289 ee_type != key_types.end(); ++ee_type) {
290 for (Strings::const_iterator signer_type = key_types.begin();
291 signer_type != key_types.end(); ++signer_type) {
292 std::string basename = *ee_type + "-ee-by-" + *signer_type +
293 "-intermediate.pem";
294 SCOPED_TRACE(basename);
295 scoped_refptr<X509Certificate> ee_cert =
296 ImportCertFromFile(certs_dir, basename);
297 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert);
298
299 basename = *signer_type + "-intermediate.pem";
300 scoped_refptr<X509Certificate> intermediate =
301 ImportCertFromFile(certs_dir, basename);
302 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate);
303
304 X509Certificate::OSCertHandles intermediates;
305 intermediates.push_back(intermediate->os_cert_handle());
306 scoped_refptr<X509Certificate> cert_chain =
307 X509Certificate::CreateFromHandle(ee_cert->os_cert_handle(),
308 intermediates);
309
310 CertVerifyResult verify_result;
311 int error = Verify(cert_chain, "127.0.0.1", 0, NULL, &verify_result);
312
313 if (IsWeakKeyType(*ee_type) || IsWeakKeyType(*signer_type)) {
314 EXPECT_NE(OK, error);
315 EXPECT_EQ(CERT_STATUS_WEAK_KEY,
316 verify_result.cert_status & CERT_STATUS_WEAK_KEY);
[email protected]58484ca2012-05-29 21:56:34317 EXPECT_NE(CERT_STATUS_INVALID,
318 verify_result.cert_status & CERT_STATUS_INVALID);
[email protected]66d9b6e32012-03-22 03:04:32319 } else {
320 EXPECT_EQ(OK, error);
321 EXPECT_EQ(0U, verify_result.cert_status & CERT_STATUS_WEAK_KEY);
322 }
323 }
324 }
325}
326
327// Test for bug 108514.
328// The certificate will expire on 2012-07-20. The test will still
329// pass if error == ERR_CERT_DATE_INVALID. TODO(rsleevi): generate test
330// certificates for this unit test. http://crbug.com/111730
331TEST_F(CertVerifyProcTest, ExtraneousMD5RootCert) {
[email protected]6cdfd7f2013-02-08 20:40:15332 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]66d9b6e32012-03-22 03:04:32333
334 scoped_refptr<X509Certificate> server_cert =
335 ImportCertFromFile(certs_dir, "images_etrade_wallst_com.pem");
336 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
337
338 scoped_refptr<X509Certificate> intermediate_cert =
339 ImportCertFromFile(certs_dir, "globalsign_orgv1_ca.pem");
340 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert);
341
342 scoped_refptr<X509Certificate> md5_root_cert =
343 ImportCertFromFile(certs_dir, "globalsign_root_ca_md5.pem");
344 ASSERT_NE(static_cast<X509Certificate*>(NULL), md5_root_cert);
345
346 X509Certificate::OSCertHandles intermediates;
347 intermediates.push_back(intermediate_cert->os_cert_handle());
348 intermediates.push_back(md5_root_cert->os_cert_handle());
349 scoped_refptr<X509Certificate> cert_chain =
350 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
351 intermediates);
352
353 CertVerifyResult verify_result;
354 int flags = 0;
355 int error = Verify(cert_chain, "images.etrade.wallst.com", flags, NULL,
356 &verify_result);
357 if (error != OK)
358 EXPECT_EQ(ERR_CERT_DATE_INVALID, error);
359
360 EXPECT_FALSE(verify_result.has_md5);
361 EXPECT_FALSE(verify_result.has_md5_ca);
362}
363
364// Test for bug 94673.
365TEST_F(CertVerifyProcTest, GoogleDigiNotarTest) {
[email protected]6cdfd7f2013-02-08 20:40:15366 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]66d9b6e32012-03-22 03:04:32367
368 scoped_refptr<X509Certificate> server_cert =
369 ImportCertFromFile(certs_dir, "google_diginotar.pem");
370 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
371
372 scoped_refptr<X509Certificate> intermediate_cert =
373 ImportCertFromFile(certs_dir, "diginotar_public_ca_2025.pem");
374 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert);
375
376 X509Certificate::OSCertHandles intermediates;
377 intermediates.push_back(intermediate_cert->os_cert_handle());
378 scoped_refptr<X509Certificate> cert_chain =
379 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
380 intermediates);
381
382 CertVerifyResult verify_result;
[email protected]8738e0d72012-08-23 02:00:47383 int flags = CertVerifier::VERIFY_REV_CHECKING_ENABLED;
[email protected]66d9b6e32012-03-22 03:04:32384 int error = Verify(cert_chain, "mail.google.com", flags, NULL,
385 &verify_result);
386 EXPECT_NE(OK, error);
387
388 // Now turn off revocation checking. Certificate verification should still
389 // fail.
390 flags = 0;
391 error = Verify(cert_chain, "mail.google.com", flags, NULL, &verify_result);
392 EXPECT_NE(OK, error);
393}
394
[email protected]62b23c22012-03-22 04:50:24395TEST_F(CertVerifyProcTest, DigiNotarCerts) {
396 static const char* const kDigiNotarFilenames[] = {
397 "diginotar_root_ca.pem",
398 "diginotar_cyber_ca.pem",
399 "diginotar_services_1024_ca.pem",
400 "diginotar_pkioverheid.pem",
401 "diginotar_pkioverheid_g2.pem",
402 NULL,
403 };
404
[email protected]6cdfd7f2013-02-08 20:40:15405 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]62b23c22012-03-22 04:50:24406
407 for (size_t i = 0; kDigiNotarFilenames[i]; i++) {
408 scoped_refptr<X509Certificate> diginotar_cert =
409 ImportCertFromFile(certs_dir, kDigiNotarFilenames[i]);
410 std::string der_bytes;
411 ASSERT_TRUE(X509Certificate::GetDEREncoded(
412 diginotar_cert->os_cert_handle(), &der_bytes));
413
414 base::StringPiece spki;
415 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_bytes, &spki));
416
417 std::string spki_sha1 = base::SHA1HashString(spki.as_string());
418
[email protected]ede03212012-09-07 12:52:26419 HashValueVector public_keys;
420 HashValue hash(HASH_VALUE_SHA1);
421 ASSERT_EQ(hash.size(), spki_sha1.size());
422 memcpy(hash.data(), spki_sha1.data(), spki_sha1.size());
423 public_keys.push_back(hash);
[email protected]62b23c22012-03-22 04:50:24424
425 EXPECT_TRUE(CertVerifyProc::IsPublicKeyBlacklisted(public_keys)) <<
426 "Public key not blocked for " << kDigiNotarFilenames[i];
427 }
428}
429
[email protected]a6b4ee042012-07-24 20:52:46430TEST_F(CertVerifyProcTest, TestKnownRoot) {
[email protected]6cdfd7f2013-02-08 20:40:15431 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]a6b4ee042012-07-24 20:52:46432 CertificateList certs = CreateCertificateListFromFile(
433 certs_dir, "certse.pem", X509Certificate::FORMAT_AUTO);
434 ASSERT_EQ(3U, certs.size());
[email protected]66d9b6e32012-03-22 03:04:32435
436 X509Certificate::OSCertHandles intermediates;
[email protected]a6b4ee042012-07-24 20:52:46437 intermediates.push_back(certs[1]->os_cert_handle());
438 intermediates.push_back(certs[2]->os_cert_handle());
439
[email protected]66d9b6e32012-03-22 03:04:32440 scoped_refptr<X509Certificate> cert_chain =
[email protected]a6b4ee042012-07-24 20:52:46441 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
[email protected]66d9b6e32012-03-22 03:04:32442 intermediates);
443
444 int flags = 0;
445 CertVerifyResult verify_result;
[email protected]a6b4ee042012-07-24 20:52:46446 // This will blow up, June 8th, 2014. Sorry! Please disable and file a bug
447 // against agl. See also PublicKeyHashes.
448 int error = Verify(cert_chain, "cert.se", flags, NULL, &verify_result);
[email protected]66d9b6e32012-03-22 03:04:32449 EXPECT_EQ(OK, error);
450 EXPECT_EQ(0U, verify_result.cert_status);
451 EXPECT_TRUE(verify_result.is_issued_by_known_root);
452}
453
[email protected]a6b4ee042012-07-24 20:52:46454TEST_F(CertVerifyProcTest, PublicKeyHashes) {
[email protected]6cdfd7f2013-02-08 20:40:15455 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]a6b4ee042012-07-24 20:52:46456 CertificateList certs = CreateCertificateListFromFile(
457 certs_dir, "certse.pem", X509Certificate::FORMAT_AUTO);
458 ASSERT_EQ(3U, certs.size());
[email protected]66d9b6e32012-03-22 03:04:32459
460 X509Certificate::OSCertHandles intermediates;
[email protected]a6b4ee042012-07-24 20:52:46461 intermediates.push_back(certs[1]->os_cert_handle());
462 intermediates.push_back(certs[2]->os_cert_handle());
[email protected]66d9b6e32012-03-22 03:04:32463
[email protected]a6b4ee042012-07-24 20:52:46464 scoped_refptr<X509Certificate> cert_chain =
465 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
466 intermediates);
[email protected]66d9b6e32012-03-22 03:04:32467 int flags = 0;
468 CertVerifyResult verify_result;
469
[email protected]a6b4ee042012-07-24 20:52:46470 // This will blow up, June 8th, 2014. Sorry! Please disable and file a bug
471 // against agl. See also TestKnownRoot.
472 int error = Verify(cert_chain, "cert.se", flags, NULL, &verify_result);
[email protected]66d9b6e32012-03-22 03:04:32473 EXPECT_EQ(OK, error);
474 EXPECT_EQ(0U, verify_result.cert_status);
[email protected]bc0d7b82012-08-08 06:32:23475 ASSERT_LE(3u, verify_result.public_key_hashes.size());
[email protected]ede03212012-09-07 12:52:26476
477 HashValueVector sha1_hashes;
478 for (unsigned i = 0; i < verify_result.public_key_hashes.size(); ++i) {
479 if (verify_result.public_key_hashes[i].tag != HASH_VALUE_SHA1)
480 continue;
481 sha1_hashes.push_back(verify_result.public_key_hashes[i]);
482 }
483 ASSERT_LE(3u, sha1_hashes.size());
484
485 for (unsigned i = 0; i < 3; ++i) {
[email protected]a6b4ee042012-07-24 20:52:46486 EXPECT_EQ(HexEncode(kCertSESPKIs[i], base::kSHA1Length),
[email protected]ede03212012-09-07 12:52:26487 HexEncode(sha1_hashes[i].data(), base::kSHA1Length));
[email protected]a6b4ee042012-07-24 20:52:46488 }
[email protected]66d9b6e32012-03-22 03:04:32489}
490
491// A regression test for http://crbug.com/70293.
492// The Key Usage extension in this RSA SSL server certificate does not have
493// the keyEncipherment bit.
494TEST_F(CertVerifyProcTest, InvalidKeyUsage) {
[email protected]6cdfd7f2013-02-08 20:40:15495 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]66d9b6e32012-03-22 03:04:32496
497 scoped_refptr<X509Certificate> server_cert =
498 ImportCertFromFile(certs_dir, "invalid_key_usage_cert.der");
499 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
500
501 int flags = 0;
502 CertVerifyResult verify_result;
503 int error = Verify(server_cert, "jira.aquameta.com", flags, NULL,
504 &verify_result);
505#if defined(USE_OPENSSL)
506 // This certificate has two errors: "invalid key usage" and "untrusted CA".
507 // However, OpenSSL returns only one (the latter), and we can't detect
508 // the other errors.
509 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
510#else
511 EXPECT_EQ(ERR_CERT_INVALID, error);
512 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID);
513#endif
514 // TODO(wtc): fix http://crbug.com/75520 to get all the certificate errors
515 // from NSS.
[email protected]12b3c8822012-09-26 11:51:18516#if !defined(USE_NSS) && !defined(OS_IOS)
[email protected]66d9b6e32012-03-22 03:04:32517 // The certificate is issued by an unknown CA.
518 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID);
519#endif
520}
521
522// Basic test for returning the chain in CertVerifyResult. Note that the
523// returned chain may just be a reflection of the originally supplied chain;
524// that is, if any errors occur, the default chain returned is an exact copy
525// of the certificate to be verified. The remaining VerifyReturn* tests are
526// used to ensure that the actual, verified chain is being returned by
527// Verify().
528TEST_F(CertVerifyProcTest, VerifyReturnChainBasic) {
[email protected]6cdfd7f2013-02-08 20:40:15529 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]66d9b6e32012-03-22 03:04:32530 CertificateList certs = CreateCertificateListFromFile(
531 certs_dir, "x509_verify_results.chain.pem",
532 X509Certificate::FORMAT_AUTO);
533 ASSERT_EQ(3U, certs.size());
534
535 X509Certificate::OSCertHandles intermediates;
536 intermediates.push_back(certs[1]->os_cert_handle());
537 intermediates.push_back(certs[2]->os_cert_handle());
538
539 ScopedTestRoot scoped_root(certs[2]);
540
541 scoped_refptr<X509Certificate> google_full_chain =
542 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
543 intermediates);
544 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain);
545 ASSERT_EQ(2U, google_full_chain->GetIntermediateCertificates().size());
546
547 CertVerifyResult verify_result;
548 EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
549 int error = Verify(google_full_chain, "127.0.0.1", 0, NULL, &verify_result);
550 EXPECT_EQ(OK, error);
551 ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
552
553 EXPECT_NE(google_full_chain, verify_result.verified_cert);
554 EXPECT_TRUE(X509Certificate::IsSameOSCert(
555 google_full_chain->os_cert_handle(),
556 verify_result.verified_cert->os_cert_handle()));
557 const X509Certificate::OSCertHandles& return_intermediates =
558 verify_result.verified_cert->GetIntermediateCertificates();
559 ASSERT_EQ(2U, return_intermediates.size());
560 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0],
561 certs[1]->os_cert_handle()));
562 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1],
563 certs[2]->os_cert_handle()));
564}
565
566// Test that the certificate returned in CertVerifyResult is able to reorder
567// certificates that are not ordered from end-entity to root. While this is
568// a protocol violation if sent during a TLS handshake, if multiple sources
569// of intermediate certificates are combined, it's possible that order may
570// not be maintained.
571TEST_F(CertVerifyProcTest, VerifyReturnChainProperlyOrdered) {
[email protected]6cdfd7f2013-02-08 20:40:15572 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]66d9b6e32012-03-22 03:04:32573 CertificateList certs = CreateCertificateListFromFile(
574 certs_dir, "x509_verify_results.chain.pem",
575 X509Certificate::FORMAT_AUTO);
576 ASSERT_EQ(3U, certs.size());
577
578 // Construct the chain out of order.
579 X509Certificate::OSCertHandles intermediates;
580 intermediates.push_back(certs[2]->os_cert_handle());
581 intermediates.push_back(certs[1]->os_cert_handle());
582
583 ScopedTestRoot scoped_root(certs[2]);
584
585 scoped_refptr<X509Certificate> google_full_chain =
586 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
587 intermediates);
588 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain);
589 ASSERT_EQ(2U, google_full_chain->GetIntermediateCertificates().size());
590
591 CertVerifyResult verify_result;
592 EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
593 int error = Verify(google_full_chain, "127.0.0.1", 0, NULL, &verify_result);
594 EXPECT_EQ(OK, error);
595 ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
596
597 EXPECT_NE(google_full_chain, verify_result.verified_cert);
598 EXPECT_TRUE(X509Certificate::IsSameOSCert(
599 google_full_chain->os_cert_handle(),
600 verify_result.verified_cert->os_cert_handle()));
601 const X509Certificate::OSCertHandles& return_intermediates =
602 verify_result.verified_cert->GetIntermediateCertificates();
603 ASSERT_EQ(2U, return_intermediates.size());
604 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0],
605 certs[1]->os_cert_handle()));
606 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1],
607 certs[2]->os_cert_handle()));
608}
609
610// Test that Verify() filters out certificates which are not related to
611// or part of the certificate chain being verified.
612TEST_F(CertVerifyProcTest, VerifyReturnChainFiltersUnrelatedCerts) {
[email protected]6cdfd7f2013-02-08 20:40:15613 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]66d9b6e32012-03-22 03:04:32614 CertificateList certs = CreateCertificateListFromFile(
615 certs_dir, "x509_verify_results.chain.pem",
616 X509Certificate::FORMAT_AUTO);
617 ASSERT_EQ(3U, certs.size());
618 ScopedTestRoot scoped_root(certs[2]);
619
620 scoped_refptr<X509Certificate> unrelated_dod_certificate =
621 ImportCertFromFile(certs_dir, "dod_ca_17_cert.der");
622 scoped_refptr<X509Certificate> unrelated_dod_certificate2 =
623 ImportCertFromFile(certs_dir, "dod_root_ca_2_cert.der");
624 ASSERT_NE(static_cast<X509Certificate*>(NULL), unrelated_dod_certificate);
625 ASSERT_NE(static_cast<X509Certificate*>(NULL), unrelated_dod_certificate2);
626
627 // Interject unrelated certificates into the list of intermediates.
628 X509Certificate::OSCertHandles intermediates;
629 intermediates.push_back(unrelated_dod_certificate->os_cert_handle());
630 intermediates.push_back(certs[1]->os_cert_handle());
631 intermediates.push_back(unrelated_dod_certificate2->os_cert_handle());
632 intermediates.push_back(certs[2]->os_cert_handle());
633
634 scoped_refptr<X509Certificate> google_full_chain =
635 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
636 intermediates);
637 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain);
638 ASSERT_EQ(4U, google_full_chain->GetIntermediateCertificates().size());
639
640 CertVerifyResult verify_result;
641 EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
642 int error = Verify(google_full_chain, "127.0.0.1", 0, NULL, &verify_result);
643 EXPECT_EQ(OK, error);
644 ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
645
646 EXPECT_NE(google_full_chain, verify_result.verified_cert);
647 EXPECT_TRUE(X509Certificate::IsSameOSCert(
648 google_full_chain->os_cert_handle(),
649 verify_result.verified_cert->os_cert_handle()));
650 const X509Certificate::OSCertHandles& return_intermediates =
651 verify_result.verified_cert->GetIntermediateCertificates();
652 ASSERT_EQ(2U, return_intermediates.size());
653 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0],
654 certs[1]->os_cert_handle()));
655 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1],
656 certs[2]->os_cert_handle()));
657}
658
[email protected]12b3c8822012-09-26 11:51:18659#if defined(USE_NSS) || defined(OS_IOS) || defined(OS_WIN) || defined(OS_MACOSX)
[email protected]66d9b6e32012-03-22 03:04:32660static const uint8 kCRLSetThawteSPKIBlocked[] = {
661 0x8e, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a,
662 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
663 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22,
664 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22,
665 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c,
666 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a,
667 0x30, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b,
668 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x36, 0x58, 0x36, 0x4d, 0x78, 0x52, 0x37,
669 0x58, 0x70, 0x4d, 0x51, 0x4b, 0x78, 0x49, 0x41, 0x39, 0x50, 0x6a, 0x36, 0x37,
670 0x36, 0x38, 0x76, 0x74, 0x55, 0x6b, 0x6b, 0x7a, 0x48, 0x79, 0x7a, 0x41, 0x6f,
671 0x6d, 0x6f, 0x4f, 0x68, 0x4b, 0x55, 0x6e, 0x7a, 0x73, 0x55, 0x3d, 0x22, 0x5d,
672 0x7d,
673};
674
675static const uint8 kCRLSetThawteSerialBlocked[] = {
676 0x60, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a,
677 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
678 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22,
679 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22,
680 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c,
681 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a,
682 0x31, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b,
683 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0xb1, 0x12, 0x41, 0x42, 0xa5, 0xa1,
684 0xa5, 0xa2, 0x88, 0x19, 0xc7, 0x35, 0x34, 0x0e, 0xff, 0x8c, 0x9e, 0x2f, 0x81,
685 0x68, 0xfe, 0xe3, 0xba, 0x18, 0x7f, 0x25, 0x3b, 0xc1, 0xa3, 0x92, 0xd7, 0xe2,
686 // Note that this is actually blocking two serial numbers because on XP and
687 // Vista, CryptoAPI finds a different Thawte certificate.
688 0x02, 0x00, 0x00, 0x00,
689 0x04, 0x30, 0x00, 0x00, 0x02,
690 0x04, 0x30, 0x00, 0x00, 0x06,
691};
692
693static const uint8 kCRLSetGoogleSerialBlocked[] = {
694 0x60, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a,
695 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
696 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22,
697 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22,
698 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c,
699 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a,
700 0x31, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b,
701 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0xe9, 0x7e, 0x8c, 0xc5, 0x1e, 0xd7,
702 0xa4, 0xc4, 0x0a, 0xc4, 0x80, 0x3d, 0x3e, 0x3e, 0xbb, 0xeb, 0xcb, 0xed, 0x52,
703 0x49, 0x33, 0x1f, 0x2c, 0xc0, 0xa2, 0x6a, 0x0e, 0x84, 0xa5, 0x27, 0xce, 0xc5,
704 0x01, 0x00, 0x00, 0x00, 0x10, 0x4f, 0x9d, 0x96, 0xd9, 0x66, 0xb0, 0x99, 0x2b,
705 0x54, 0xc2, 0x95, 0x7c, 0xb4, 0x15, 0x7d, 0x4d,
706};
707
708// Test that CRLSets are effective in making a certificate appear to be
709// revoked.
710TEST_F(CertVerifyProcTest, CRLSet) {
711 CertificateList certs = CreateCertificateListFromFile(
712 GetTestCertsDirectory(),
713 "googlenew.chain.pem",
714 X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
715
716 X509Certificate::OSCertHandles intermediates;
717 intermediates.push_back(certs[1]->os_cert_handle());
718
719 scoped_refptr<X509Certificate> google_full_chain =
720 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
721 intermediates);
722
723 CertVerifyResult verify_result;
724 int error = Verify(google_full_chain, "www.google.com", 0, NULL,
725 &verify_result);
726 EXPECT_EQ(OK, error);
727
728 // First test blocking by SPKI.
729 base::StringPiece crl_set_bytes(
730 reinterpret_cast<const char*>(kCRLSetThawteSPKIBlocked),
731 sizeof(kCRLSetThawteSPKIBlocked));
732 scoped_refptr<CRLSet> crl_set;
733 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
734
735 error = Verify(google_full_chain, "www.google.com", 0, crl_set.get(),
736 &verify_result);
737 EXPECT_EQ(ERR_CERT_REVOKED, error);
738
739 // Second, test revocation by serial number of a cert directly under the
740 // root.
741 crl_set_bytes = base::StringPiece(
742 reinterpret_cast<const char*>(kCRLSetThawteSerialBlocked),
743 sizeof(kCRLSetThawteSerialBlocked));
744 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
745
746 error = Verify(google_full_chain, "www.google.com", 0, crl_set.get(),
747 &verify_result);
748 EXPECT_EQ(ERR_CERT_REVOKED, error);
749
750 // Lastly, test revocation by serial number of a certificate not under the
751 // root.
752 crl_set_bytes = base::StringPiece(
753 reinterpret_cast<const char*>(kCRLSetGoogleSerialBlocked),
754 sizeof(kCRLSetGoogleSerialBlocked));
755 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
756
757 error = Verify(google_full_chain, "www.google.com", 0, crl_set.get(),
758 &verify_result);
759 EXPECT_EQ(ERR_CERT_REVOKED, error);
760}
761#endif
762
763struct WeakDigestTestData {
764 const char* root_cert_filename;
765 const char* intermediate_cert_filename;
766 const char* ee_cert_filename;
767 bool expected_has_md5;
768 bool expected_has_md4;
769 bool expected_has_md2;
770 bool expected_has_md5_ca;
771 bool expected_has_md2_ca;
772};
773
774// GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
775// to output the parameter that was passed. Without this, it will simply
776// attempt to print out the first twenty bytes of the object, which depending
777// on platform and alignment, may result in an invalid read.
778void PrintTo(const WeakDigestTestData& data, std::ostream* os) {
779 *os << "root: "
780 << (data.root_cert_filename ? data.root_cert_filename : "none")
781 << "; intermediate: " << data.intermediate_cert_filename
782 << "; end-entity: " << data.ee_cert_filename;
783}
784
785class CertVerifyProcWeakDigestTest
786 : public CertVerifyProcTest,
787 public testing::WithParamInterface<WeakDigestTestData> {
788 public:
789 CertVerifyProcWeakDigestTest() {}
790 virtual ~CertVerifyProcWeakDigestTest() {}
791};
792
793TEST_P(CertVerifyProcWeakDigestTest, Verify) {
794 WeakDigestTestData data = GetParam();
[email protected]6cdfd7f2013-02-08 20:40:15795 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]66d9b6e32012-03-22 03:04:32796
797 ScopedTestRoot test_root;
798 if (data.root_cert_filename) {
799 scoped_refptr<X509Certificate> root_cert =
800 ImportCertFromFile(certs_dir, data.root_cert_filename);
801 ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert);
802 test_root.Reset(root_cert);
803 }
804
805 scoped_refptr<X509Certificate> intermediate_cert =
806 ImportCertFromFile(certs_dir, data.intermediate_cert_filename);
807 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert);
808 scoped_refptr<X509Certificate> ee_cert =
809 ImportCertFromFile(certs_dir, data.ee_cert_filename);
810 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert);
811
812 X509Certificate::OSCertHandles intermediates;
813 intermediates.push_back(intermediate_cert->os_cert_handle());
814
815 scoped_refptr<X509Certificate> ee_chain =
816 X509Certificate::CreateFromHandle(ee_cert->os_cert_handle(),
817 intermediates);
818 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_chain);
819
820 int flags = 0;
821 CertVerifyResult verify_result;
822 int rv = Verify(ee_chain, "127.0.0.1", flags, NULL, &verify_result);
823 EXPECT_EQ(data.expected_has_md5, verify_result.has_md5);
824 EXPECT_EQ(data.expected_has_md4, verify_result.has_md4);
825 EXPECT_EQ(data.expected_has_md2, verify_result.has_md2);
826 EXPECT_EQ(data.expected_has_md5_ca, verify_result.has_md5_ca);
827 EXPECT_EQ(data.expected_has_md2_ca, verify_result.has_md2_ca);
828
829 // Ensure that MD4 and MD2 are tagged as invalid.
830 if (data.expected_has_md4 || data.expected_has_md2) {
831 EXPECT_EQ(CERT_STATUS_INVALID,
832 verify_result.cert_status & CERT_STATUS_INVALID);
833 }
834
835 // Ensure that MD5 is flagged as weak.
836 if (data.expected_has_md5) {
837 EXPECT_EQ(
838 CERT_STATUS_WEAK_SIGNATURE_ALGORITHM,
839 verify_result.cert_status & CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
840 }
841
842 // If a root cert is present, then check that the chain was rejected if any
843 // weak algorithms are present. This is only checked when a root cert is
844 // present because the error reported for incomplete chains with weak
845 // algorithms depends on which implementation was used to validate (NSS,
846 // OpenSSL, CryptoAPI, Security.framework) and upon which weak algorithm
847 // present (MD2, MD4, MD5).
848 if (data.root_cert_filename) {
849 if (data.expected_has_md4 || data.expected_has_md2) {
850 EXPECT_EQ(ERR_CERT_INVALID, rv);
851 } else if (data.expected_has_md5) {
852 EXPECT_EQ(ERR_CERT_WEAK_SIGNATURE_ALGORITHM, rv);
853 } else {
854 EXPECT_EQ(OK, rv);
855 }
856 }
857}
858
859// Unlike TEST/TEST_F, which are macros that expand to further macros,
860// INSTANTIATE_TEST_CASE_P is a macro that expands directly to code that
861// stringizes the arguments. As a result, macros passed as parameters (such as
862// prefix or test_case_name) will not be expanded by the preprocessor. To work
863// around this, indirect the macro for INSTANTIATE_TEST_CASE_P, so that the
864// pre-processor will expand macros such as MAYBE_test_name before
865// instantiating the test.
866#define WRAPPED_INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
867 INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator)
868
869// The signature algorithm of the root CA should not matter.
870const WeakDigestTestData kVerifyRootCATestData[] = {
871 { "weak_digest_md5_root.pem", "weak_digest_sha1_intermediate.pem",
872 "weak_digest_sha1_ee.pem", false, false, false, false, false },
[email protected]317dbc72012-04-03 18:45:14873#if defined(USE_OPENSSL) || defined(OS_WIN)
874 // MD4 is not supported by OS X / NSS
[email protected]66d9b6e32012-03-22 03:04:32875 { "weak_digest_md4_root.pem", "weak_digest_sha1_intermediate.pem",
876 "weak_digest_sha1_ee.pem", false, false, false, false, false },
877#endif
878 { "weak_digest_md2_root.pem", "weak_digest_sha1_intermediate.pem",
879 "weak_digest_sha1_ee.pem", false, false, false, false, false },
880};
881INSTANTIATE_TEST_CASE_P(VerifyRoot, CertVerifyProcWeakDigestTest,
882 testing::ValuesIn(kVerifyRootCATestData));
883
884// The signature algorithm of intermediates should be properly detected.
885const WeakDigestTestData kVerifyIntermediateCATestData[] = {
886 { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
887 "weak_digest_sha1_ee.pem", true, false, false, true, false },
[email protected]317dbc72012-04-03 18:45:14888#if defined(USE_OPENSSL) || defined(OS_WIN)
889 // MD4 is not supported by OS X / NSS
[email protected]66d9b6e32012-03-22 03:04:32890 { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
891 "weak_digest_sha1_ee.pem", false, true, false, false, false },
892#endif
[email protected]66d9b6e32012-03-22 03:04:32893 { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
894 "weak_digest_sha1_ee.pem", false, false, true, false, true },
[email protected]66d9b6e32012-03-22 03:04:32895};
[email protected]fa2d3dc2012-11-20 07:58:44896// Disabled on NSS - MD4 is not supported, and MD2 and MD5 are disabled.
897#if defined(USE_NSS) || defined(OS_IOS)
898#define MAYBE_VerifyIntermediate DISABLED_VerifyIntermediate
899#else
900#define MAYBE_VerifyIntermediate VerifyIntermediate
901#endif
902WRAPPED_INSTANTIATE_TEST_CASE_P(
903 MAYBE_VerifyIntermediate,
904 CertVerifyProcWeakDigestTest,
905 testing::ValuesIn(kVerifyIntermediateCATestData));
[email protected]66d9b6e32012-03-22 03:04:32906
907// The signature algorithm of end-entity should be properly detected.
908const WeakDigestTestData kVerifyEndEntityTestData[] = {
909 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
910 "weak_digest_md5_ee.pem", true, false, false, false, false },
[email protected]317dbc72012-04-03 18:45:14911#if defined(USE_OPENSSL) || defined(OS_WIN)
912 // MD4 is not supported by OS X / NSS
[email protected]66d9b6e32012-03-22 03:04:32913 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
914 "weak_digest_md4_ee.pem", false, true, false, false, false },
915#endif
[email protected]66d9b6e32012-03-22 03:04:32916 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
917 "weak_digest_md2_ee.pem", false, false, true, false, false },
[email protected]66d9b6e32012-03-22 03:04:32918};
919// Disabled on NSS - NSS caches chains/signatures in such a way that cannot
920// be cleared until NSS is cleanly shutdown, which is not presently supported
921// in Chromium.
[email protected]12b3c8822012-09-26 11:51:18922#if defined(USE_NSS) || defined(OS_IOS)
[email protected]66d9b6e32012-03-22 03:04:32923#define MAYBE_VerifyEndEntity DISABLED_VerifyEndEntity
924#else
925#define MAYBE_VerifyEndEntity VerifyEndEntity
926#endif
927WRAPPED_INSTANTIATE_TEST_CASE_P(MAYBE_VerifyEndEntity,
928 CertVerifyProcWeakDigestTest,
929 testing::ValuesIn(kVerifyEndEntityTestData));
930
931// Incomplete chains should still report the status of the intermediate.
932const WeakDigestTestData kVerifyIncompleteIntermediateTestData[] = {
933 { NULL, "weak_digest_md5_intermediate.pem", "weak_digest_sha1_ee.pem",
934 true, false, false, true, false },
[email protected]317dbc72012-04-03 18:45:14935#if defined(USE_OPENSSL) || defined(OS_WIN)
936 // MD4 is not supported by OS X / NSS
[email protected]66d9b6e32012-03-22 03:04:32937 { NULL, "weak_digest_md4_intermediate.pem", "weak_digest_sha1_ee.pem",
938 false, true, false, false, false },
939#endif
940 { NULL, "weak_digest_md2_intermediate.pem", "weak_digest_sha1_ee.pem",
941 false, false, true, false, true },
942};
943// Disabled on NSS - libpkix does not return constructed chains on error,
944// preventing us from detecting/inspecting the verified chain.
[email protected]12b3c8822012-09-26 11:51:18945#if defined(USE_NSS) || defined(OS_IOS)
[email protected]66d9b6e32012-03-22 03:04:32946#define MAYBE_VerifyIncompleteIntermediate \
947 DISABLED_VerifyIncompleteIntermediate
948#else
949#define MAYBE_VerifyIncompleteIntermediate VerifyIncompleteIntermediate
950#endif
951WRAPPED_INSTANTIATE_TEST_CASE_P(
952 MAYBE_VerifyIncompleteIntermediate,
953 CertVerifyProcWeakDigestTest,
954 testing::ValuesIn(kVerifyIncompleteIntermediateTestData));
955
956// Incomplete chains should still report the status of the end-entity.
957const WeakDigestTestData kVerifyIncompleteEETestData[] = {
958 { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md5_ee.pem",
959 true, false, false, false, false },
[email protected]317dbc72012-04-03 18:45:14960#if defined(USE_OPENSSL) || defined(OS_WIN)
961 // MD4 is not supported by OS X / NSS
[email protected]66d9b6e32012-03-22 03:04:32962 { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md4_ee.pem",
963 false, true, false, false, false },
964#endif
965 { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md2_ee.pem",
966 false, false, true, false, false },
967};
968// Disabled on NSS - libpkix does not return constructed chains on error,
969// preventing us from detecting/inspecting the verified chain.
[email protected]12b3c8822012-09-26 11:51:18970#if defined(USE_NSS) || defined(OS_IOS)
[email protected]66d9b6e32012-03-22 03:04:32971#define MAYBE_VerifyIncompleteEndEntity DISABLED_VerifyIncompleteEndEntity
972#else
973#define MAYBE_VerifyIncompleteEndEntity VerifyIncompleteEndEntity
974#endif
975WRAPPED_INSTANTIATE_TEST_CASE_P(
976 MAYBE_VerifyIncompleteEndEntity,
977 CertVerifyProcWeakDigestTest,
978 testing::ValuesIn(kVerifyIncompleteEETestData));
979
980// Differing algorithms between the intermediate and the EE should still be
981// reported.
982const WeakDigestTestData kVerifyMixedTestData[] = {
983 { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
984 "weak_digest_md2_ee.pem", true, false, true, true, false },
985 { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
986 "weak_digest_md5_ee.pem", true, false, true, false, true },
[email protected]317dbc72012-04-03 18:45:14987#if defined(USE_OPENSSL) || defined(OS_WIN)
988 // MD4 is not supported by OS X / NSS
[email protected]66d9b6e32012-03-22 03:04:32989 { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
990 "weak_digest_md2_ee.pem", false, true, true, false, false },
991#endif
992};
993// NSS does not support MD4 and does not enable MD2 by default, making all
994// permutations invalid.
[email protected]12b3c8822012-09-26 11:51:18995#if defined(USE_NSS) || defined(OS_IOS)
[email protected]66d9b6e32012-03-22 03:04:32996#define MAYBE_VerifyMixed DISABLED_VerifyMixed
997#else
998#define MAYBE_VerifyMixed VerifyMixed
999#endif
1000WRAPPED_INSTANTIATE_TEST_CASE_P(
1001 MAYBE_VerifyMixed,
1002 CertVerifyProcWeakDigestTest,
1003 testing::ValuesIn(kVerifyMixedTestData));
1004
1005} // namespace net