blob: 6567d1656fccc9e47c5f7435712dc39b27b26ae4 [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
[email protected]6e7845ae2013-03-29 21:48:115#include "net/cert/cert_verify_proc.h"
[email protected]66d9b6e32012-03-22 03:04:326
7#include <vector>
8
[email protected]1c232c22013-08-30 02:04:049#include "base/callback_helpers.h"
[email protected]57999812013-02-24 05:40:5210#include "base/files/file_path.h"
[email protected]ef155122013-03-23 19:11:2411#include "base/logging.h"
[email protected]66d9b6e32012-03-22 03:04:3212#include "base/sha1.h"
[email protected]4b355212013-06-11 10:35:1913#include "base/strings/string_number_conversions.h"
[email protected]bfea55d2013-04-04 11:06:0414#include "crypto/sha2.h"
[email protected]66d9b6e32012-03-22 03:04:3215#include "net/base/net_errors.h"
[email protected]42fdb452012-11-01 12:44:4016#include "net/base/test_data_directory.h"
[email protected]6e7845ae2013-03-29 21:48:1117#include "net/cert/asn1_util.h"
18#include "net/cert/cert_status_flags.h"
19#include "net/cert/cert_verifier.h"
20#include "net/cert/cert_verify_result.h"
21#include "net/cert/crl_set.h"
22#include "net/cert/test_root_certs.h"
23#include "net/cert/x509_certificate.h"
24#include "net/test/cert_test_util.h"
25#include "net/test/test_certificate_data.h"
[email protected]66d9b6e32012-03-22 03:04:3226#include "testing/gtest/include/gtest/gtest.h"
27
28#if defined(OS_WIN)
29#include "base/win/windows_version.h"
[email protected]12b3c8822012-09-26 11:51:1830#elif defined(OS_MACOSX) && !defined(OS_IOS)
[email protected]66d9b6e32012-03-22 03:04:3231#include "base/mac/mac_util.h"
[email protected]23073f92014-01-17 22:52:1732#elif defined(OS_ANDROID)
33#include "base/android/build_info.h"
[email protected]66d9b6e32012-03-22 03:04:3234#endif
35
36using base::HexEncode;
37
38namespace net {
39
40namespace {
41
42// A certificate for www.paypal.com with a NULL byte in the common name.
43// From http://www.gossamer-threads.com/lists/fulldisc/full-disclosure/70363
44unsigned char paypal_null_fingerprint[] = {
45 0x4c, 0x88, 0x9e, 0x28, 0xd7, 0x7a, 0x44, 0x1e, 0x13, 0xf2, 0x6a, 0xba,
46 0x1f, 0xe8, 0x1b, 0xd6, 0xab, 0x7b, 0xe8, 0xd7
47};
48
[email protected]ff353212013-05-17 02:09:0849// Mock CertVerifyProc that will set |verify_result->is_issued_by_known_root|
50// for all certificates that are Verified.
51class WellKnownCaCertVerifyProc : public CertVerifyProc {
52 public:
53 // Initialize a CertVerifyProc that will set
54 // |verify_result->is_issued_by_known_root| to |is_well_known|.
55 explicit WellKnownCaCertVerifyProc(bool is_well_known)
56 : is_well_known_(is_well_known) {}
57
58 // CertVerifyProc implementation:
59 virtual bool SupportsAdditionalTrustAnchors() const OVERRIDE { return false; }
60
61 protected:
62 virtual ~WellKnownCaCertVerifyProc() {}
63
64 private:
65 virtual int VerifyInternal(X509Certificate* cert,
66 const std::string& hostname,
67 int flags,
68 CRLSet* crl_set,
69 const CertificateList& additional_trust_anchors,
70 CertVerifyResult* verify_result) OVERRIDE;
71
72 const bool is_well_known_;
73
74 DISALLOW_COPY_AND_ASSIGN(WellKnownCaCertVerifyProc);
75};
76
77int WellKnownCaCertVerifyProc::VerifyInternal(
78 X509Certificate* cert,
79 const std::string& hostname,
80 int flags,
81 CRLSet* crl_set,
82 const CertificateList& additional_trust_anchors,
83 CertVerifyResult* verify_result) {
84 verify_result->is_issued_by_known_root = is_well_known_;
85 return OK;
86}
87
[email protected]23073f92014-01-17 22:52:1788bool SupportsReturningVerifiedChain() {
89#if defined(OS_ANDROID)
90 // Before API level 17, Android does not expose the APIs necessary to get at
91 // the verified certificate chain.
92 if (base::android::BuildInfo::GetInstance()->sdk_int() < 17)
93 return false;
94#endif
95 return true;
96}
97
98bool SupportsDetectingKnownRoots() {
99#if defined(OS_ANDROID)
[email protected]981f6c4e2014-05-14 00:51:09100 // Before API level 17, Android does not expose the APIs necessary to get at
101 // the verified certificate chain and detect known roots.
102 if (base::android::BuildInfo::GetInstance()->sdk_int() < 17)
103 return false;
[email protected]23073f92014-01-17 22:52:17104#endif
105 return true;
106}
107
[email protected]66d9b6e32012-03-22 03:04:32108} // namespace
109
110class CertVerifyProcTest : public testing::Test {
111 public:
112 CertVerifyProcTest()
113 : verify_proc_(CertVerifyProc::CreateDefault()) {
114 }
115 virtual ~CertVerifyProcTest() {}
116
117 protected:
[email protected]ef155122013-03-23 19:11:24118 bool SupportsAdditionalTrustAnchors() {
119 return verify_proc_->SupportsAdditionalTrustAnchors();
120 }
121
[email protected]66d9b6e32012-03-22 03:04:32122 int Verify(X509Certificate* cert,
123 const std::string& hostname,
124 int flags,
125 CRLSet* crl_set,
[email protected]ef155122013-03-23 19:11:24126 const CertificateList& additional_trust_anchors,
[email protected]66d9b6e32012-03-22 03:04:32127 CertVerifyResult* verify_result) {
128 return verify_proc_->Verify(cert, hostname, flags, crl_set,
[email protected]ef155122013-03-23 19:11:24129 additional_trust_anchors, verify_result);
[email protected]66d9b6e32012-03-22 03:04:32130 }
131
[email protected]ef155122013-03-23 19:11:24132 const CertificateList empty_cert_list_;
[email protected]66d9b6e32012-03-22 03:04:32133 scoped_refptr<CertVerifyProc> verify_proc_;
134};
135
[email protected]f0a09a262013-10-01 00:31:25136TEST_F(CertVerifyProcTest, DISABLED_WithoutRevocationChecking) {
[email protected]66d9b6e32012-03-22 03:04:32137 // Check that verification without revocation checking works.
138 CertificateList certs = CreateCertificateListFromFile(
139 GetTestCertsDirectory(),
140 "googlenew.chain.pem",
141 X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
142
143 X509Certificate::OSCertHandles intermediates;
144 intermediates.push_back(certs[1]->os_cert_handle());
145
146 scoped_refptr<X509Certificate> google_full_chain =
147 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
148 intermediates);
149
150 CertVerifyResult verify_result;
[email protected]90499482013-06-01 00:39:50151 EXPECT_EQ(OK,
152 Verify(google_full_chain.get(),
153 "www.google.com",
154 0 /* flags */,
155 NULL,
156 empty_cert_list_,
157 &verify_result));
[email protected]66d9b6e32012-03-22 03:04:32158}
159
[email protected]e1b2d732014-03-28 16:20:32160#if defined(OS_ANDROID) || defined(USE_OPENSSL_CERTS)
[email protected]66d9b6e32012-03-22 03:04:32161// TODO(jnd): http://crbug.com/117478 - EV verification is not yet supported.
162#define MAYBE_EVVerification DISABLED_EVVerification
163#else
164#define MAYBE_EVVerification EVVerification
165#endif
[email protected]77f1f9d2013-06-29 14:16:51166TEST_F(CertVerifyProcTest, MAYBE_EVVerification) {
[email protected]66d9b6e32012-03-22 03:04:32167 CertificateList certs = CreateCertificateListFromFile(
168 GetTestCertsDirectory(),
169 "comodo.chain.pem",
170 X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
171 ASSERT_EQ(3U, certs.size());
172
173 X509Certificate::OSCertHandles intermediates;
174 intermediates.push_back(certs[1]->os_cert_handle());
175 intermediates.push_back(certs[2]->os_cert_handle());
176
177 scoped_refptr<X509Certificate> comodo_chain =
178 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
179 intermediates);
180
[email protected]51523f52013-07-31 21:57:28181 scoped_refptr<CRLSet> crl_set(CRLSet::ForTesting(false, NULL, ""));
[email protected]66d9b6e32012-03-22 03:04:32182 CertVerifyResult verify_result;
[email protected]8738e0d72012-08-23 02:00:47183 int flags = CertVerifier::VERIFY_EV_CERT;
[email protected]90499482013-06-01 00:39:50184 int error = Verify(comodo_chain.get(),
185 "comodo.com",
186 flags,
187 crl_set.get(),
188 empty_cert_list_,
189 &verify_result);
[email protected]66d9b6e32012-03-22 03:04:32190 EXPECT_EQ(OK, error);
191 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV);
192}
193
194TEST_F(CertVerifyProcTest, PaypalNullCertParsing) {
195 scoped_refptr<X509Certificate> paypal_null_cert(
196 X509Certificate::CreateFromBytes(
197 reinterpret_cast<const char*>(paypal_null_der),
198 sizeof(paypal_null_der)));
199
200 ASSERT_NE(static_cast<X509Certificate*>(NULL), paypal_null_cert);
201
[email protected]ede03212012-09-07 12:52:26202 const SHA1HashValue& fingerprint =
[email protected]66d9b6e32012-03-22 03:04:32203 paypal_null_cert->fingerprint();
204 for (size_t i = 0; i < 20; ++i)
205 EXPECT_EQ(paypal_null_fingerprint[i], fingerprint.data[i]);
206
207 int flags = 0;
208 CertVerifyResult verify_result;
[email protected]90499482013-06-01 00:39:50209 int error = Verify(paypal_null_cert.get(),
210 "www.paypal.com",
211 flags,
212 NULL,
213 empty_cert_list_,
214 &verify_result);
[email protected]71f4b272013-02-13 19:13:49215#if defined(USE_NSS) || defined(OS_IOS) || defined(OS_ANDROID)
[email protected]317dbc72012-04-03 18:45:14216 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error);
217#else
[email protected]66d9b6e32012-03-22 03:04:32218 // TOOD(bulach): investigate why macosx and win aren't returning
219 // ERR_CERT_INVALID or ERR_CERT_COMMON_NAME_INVALID.
220 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
[email protected]66d9b6e32012-03-22 03:04:32221#endif
222 // Either the system crypto library should correctly report a certificate
223 // name mismatch, or our certificate blacklist should cause us to report an
224 // invalid certificate.
[email protected]12b3c8822012-09-26 11:51:18225#if defined(USE_NSS) || defined(OS_WIN) || defined(OS_IOS)
[email protected]66d9b6e32012-03-22 03:04:32226 EXPECT_TRUE(verify_result.cert_status &
227 (CERT_STATUS_COMMON_NAME_INVALID | CERT_STATUS_INVALID));
228#endif
229}
230
231// A regression test for http://crbug.com/31497.
[email protected]25bf1962013-07-26 07:39:37232#if defined(OS_ANDROID)
233// Disabled on Android, as the Android verification libraries require an
234// explicit policy to be specified, even when anyPolicy is permitted.
235#define MAYBE_IntermediateCARequireExplicitPolicy \
236 DISABLED_IntermediateCARequireExplicitPolicy
237#else
238#define MAYBE_IntermediateCARequireExplicitPolicy \
239 IntermediateCARequireExplicitPolicy
240#endif
241TEST_F(CertVerifyProcTest, MAYBE_IntermediateCARequireExplicitPolicy) {
[email protected]6cdfd7f2013-02-08 20:40:15242 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]66d9b6e32012-03-22 03:04:32243
[email protected]25bf1962013-07-26 07:39:37244 CertificateList certs = CreateCertificateListFromFile(
245 certs_dir, "explicit-policy-chain.pem",
246 X509Certificate::FORMAT_AUTO);
247 ASSERT_EQ(3U, certs.size());
[email protected]66d9b6e32012-03-22 03:04:32248
249 X509Certificate::OSCertHandles intermediates;
[email protected]25bf1962013-07-26 07:39:37250 intermediates.push_back(certs[1]->os_cert_handle());
251
252 scoped_refptr<X509Certificate> cert =
253 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
[email protected]66d9b6e32012-03-22 03:04:32254 intermediates);
[email protected]25bf1962013-07-26 07:39:37255 ASSERT_TRUE(cert.get());
256
257 ScopedTestRoot scoped_root(certs[2].get());
[email protected]66d9b6e32012-03-22 03:04:32258
259 int flags = 0;
260 CertVerifyResult verify_result;
[email protected]25bf1962013-07-26 07:39:37261 int error = Verify(cert.get(),
262 "policy_test.example",
[email protected]90499482013-06-01 00:39:50263 flags,
264 NULL,
265 empty_cert_list_,
266 &verify_result);
[email protected]25bf1962013-07-26 07:39:37267 EXPECT_EQ(OK, error);
268 EXPECT_EQ(0u, verify_result.cert_status);
[email protected]66d9b6e32012-03-22 03:04:32269}
270
[email protected]66d9b6e32012-03-22 03:04:32271// Test for bug 58437.
272// This certificate will expire on 2011-12-21. The test will still
273// pass if error == ERR_CERT_DATE_INVALID.
274// This test is DISABLED because it appears that we cannot do
275// certificate revocation checking when running all of the net unit tests.
276// This test passes when run individually, but when run with all of the net
277// unit tests, the call to PKIXVerifyCert returns the NSS error -8180, which is
278// SEC_ERROR_REVOKED_CERTIFICATE. This indicates a lack of revocation
279// status, i.e. that the revocation check is failing for some reason.
280TEST_F(CertVerifyProcTest, DISABLED_GlobalSignR3EVTest) {
[email protected]6cdfd7f2013-02-08 20:40:15281 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]66d9b6e32012-03-22 03:04:32282
283 scoped_refptr<X509Certificate> server_cert =
284 ImportCertFromFile(certs_dir, "2029_globalsign_com_cert.pem");
285 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
286
287 scoped_refptr<X509Certificate> intermediate_cert =
288 ImportCertFromFile(certs_dir, "globalsign_ev_sha256_ca_cert.pem");
289 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert);
290
291 X509Certificate::OSCertHandles intermediates;
292 intermediates.push_back(intermediate_cert->os_cert_handle());
293 scoped_refptr<X509Certificate> cert_chain =
294 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
295 intermediates);
296
297 CertVerifyResult verify_result;
[email protected]8738e0d72012-08-23 02:00:47298 int flags = CertVerifier::VERIFY_REV_CHECKING_ENABLED |
299 CertVerifier::VERIFY_EV_CERT;
[email protected]90499482013-06-01 00:39:50300 int error = Verify(cert_chain.get(),
301 "2029.globalsign.com",
302 flags,
303 NULL,
304 empty_cert_list_,
305 &verify_result);
[email protected]66d9b6e32012-03-22 03:04:32306 if (error == OK)
307 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV);
308 else
309 EXPECT_EQ(ERR_CERT_DATE_INVALID, error);
310}
311
[email protected]fe845ab62012-08-24 16:03:29312// Test that verifying an ECDSA certificate doesn't crash on XP. (See
313// crbug.com/144466).
314TEST_F(CertVerifyProcTest, ECDSA_RSA) {
[email protected]6cdfd7f2013-02-08 20:40:15315 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]fe845ab62012-08-24 16:03:29316
317 scoped_refptr<X509Certificate> cert =
318 ImportCertFromFile(certs_dir,
319 "prime256v1-ecdsa-ee-by-1024-rsa-intermediate.pem");
320
321 CertVerifyResult verify_result;
[email protected]90499482013-06-01 00:39:50322 Verify(cert.get(), "127.0.0.1", 0, NULL, empty_cert_list_, &verify_result);
[email protected]fe845ab62012-08-24 16:03:29323
324 // We don't check verify_result because the certificate is signed by an
325 // unknown CA and will be considered invalid on XP because of the ECDSA
326 // public key.
327}
328
[email protected]66d9b6e32012-03-22 03:04:32329// Currently, only RSA and DSA keys are checked for weakness, and our example
330// weak size is 768. These could change in the future.
331//
332// Note that this means there may be false negatives: keys for other
333// algorithms and which are weak will pass this test.
334static bool IsWeakKeyType(const std::string& key_type) {
335 size_t pos = key_type.find("-");
336 std::string size = key_type.substr(0, pos);
337 std::string type = key_type.substr(pos + 1);
338
339 if (type == "rsa" || type == "dsa")
340 return size == "768";
341
342 return false;
343}
344
345TEST_F(CertVerifyProcTest, RejectWeakKeys) {
[email protected]6cdfd7f2013-02-08 20:40:15346 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]66d9b6e32012-03-22 03:04:32347 typedef std::vector<std::string> Strings;
348 Strings key_types;
349
350 // generate-weak-test-chains.sh currently has:
351 // key_types="768-rsa 1024-rsa 2048-rsa prime256v1-ecdsa"
352 // We must use the same key types here. The filenames generated look like:
353 // 2048-rsa-ee-by-768-rsa-intermediate.pem
354 key_types.push_back("768-rsa");
355 key_types.push_back("1024-rsa");
356 key_types.push_back("2048-rsa");
357
358 bool use_ecdsa = true;
359#if defined(OS_WIN)
360 use_ecdsa = base::win::GetVersion() > base::win::VERSION_XP;
[email protected]66d9b6e32012-03-22 03:04:32361#endif
362
363 if (use_ecdsa)
364 key_types.push_back("prime256v1-ecdsa");
365
366 // Add the root that signed the intermediates for this test.
367 scoped_refptr<X509Certificate> root_cert =
368 ImportCertFromFile(certs_dir, "2048-rsa-root.pem");
369 ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert);
[email protected]90499482013-06-01 00:39:50370 ScopedTestRoot scoped_root(root_cert.get());
[email protected]66d9b6e32012-03-22 03:04:32371
372 // Now test each chain.
373 for (Strings::const_iterator ee_type = key_types.begin();
374 ee_type != key_types.end(); ++ee_type) {
375 for (Strings::const_iterator signer_type = key_types.begin();
376 signer_type != key_types.end(); ++signer_type) {
377 std::string basename = *ee_type + "-ee-by-" + *signer_type +
378 "-intermediate.pem";
379 SCOPED_TRACE(basename);
380 scoped_refptr<X509Certificate> ee_cert =
381 ImportCertFromFile(certs_dir, basename);
382 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert);
383
384 basename = *signer_type + "-intermediate.pem";
385 scoped_refptr<X509Certificate> intermediate =
386 ImportCertFromFile(certs_dir, basename);
387 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate);
388
389 X509Certificate::OSCertHandles intermediates;
390 intermediates.push_back(intermediate->os_cert_handle());
391 scoped_refptr<X509Certificate> cert_chain =
392 X509Certificate::CreateFromHandle(ee_cert->os_cert_handle(),
393 intermediates);
394
395 CertVerifyResult verify_result;
[email protected]90499482013-06-01 00:39:50396 int error = Verify(cert_chain.get(),
397 "127.0.0.1",
398 0,
399 NULL,
400 empty_cert_list_,
401 &verify_result);
[email protected]66d9b6e32012-03-22 03:04:32402
403 if (IsWeakKeyType(*ee_type) || IsWeakKeyType(*signer_type)) {
404 EXPECT_NE(OK, error);
405 EXPECT_EQ(CERT_STATUS_WEAK_KEY,
406 verify_result.cert_status & CERT_STATUS_WEAK_KEY);
[email protected]58484ca2012-05-29 21:56:34407 EXPECT_NE(CERT_STATUS_INVALID,
408 verify_result.cert_status & CERT_STATUS_INVALID);
[email protected]66d9b6e32012-03-22 03:04:32409 } else {
410 EXPECT_EQ(OK, error);
411 EXPECT_EQ(0U, verify_result.cert_status & CERT_STATUS_WEAK_KEY);
412 }
413 }
414 }
415}
416
[email protected]77f1f9d2013-06-29 14:16:51417// Regression test for http://crbug.com/108514.
418#if defined(OS_MACOSX) && !defined(OS_IOS)
419// Disabled on OS X - Security.framework doesn't ignore superflous certificates
420// provided by servers. See CertVerifyProcTest.CybertrustGTERoot for further
421// details.
422#define MAYBE_ExtraneousMD5RootCert DISABLED_ExtraneousMD5RootCert
[email protected]77f1f9d2013-06-29 14:16:51423#else
424#define MAYBE_ExtraneousMD5RootCert ExtraneousMD5RootCert
425#endif
426TEST_F(CertVerifyProcTest, MAYBE_ExtraneousMD5RootCert) {
[email protected]23073f92014-01-17 22:52:17427 if (!SupportsReturningVerifiedChain()) {
428 LOG(INFO) << "Skipping this test in this platform.";
429 return;
430 }
431
[email protected]6cdfd7f2013-02-08 20:40:15432 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]66d9b6e32012-03-22 03:04:32433
434 scoped_refptr<X509Certificate> server_cert =
[email protected]77f1f9d2013-06-29 14:16:51435 ImportCertFromFile(certs_dir, "cross-signed-leaf.pem");
436 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get());
[email protected]66d9b6e32012-03-22 03:04:32437
[email protected]77f1f9d2013-06-29 14:16:51438 scoped_refptr<X509Certificate> extra_cert =
439 ImportCertFromFile(certs_dir, "cross-signed-root-md5.pem");
440 ASSERT_NE(static_cast<X509Certificate*>(NULL), extra_cert.get());
[email protected]66d9b6e32012-03-22 03:04:32441
[email protected]77f1f9d2013-06-29 14:16:51442 scoped_refptr<X509Certificate> root_cert =
443 ImportCertFromFile(certs_dir, "cross-signed-root-sha1.pem");
444 ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert.get());
445
446 ScopedTestRoot scoped_root(root_cert.get());
[email protected]66d9b6e32012-03-22 03:04:32447
448 X509Certificate::OSCertHandles intermediates;
[email protected]77f1f9d2013-06-29 14:16:51449 intermediates.push_back(extra_cert->os_cert_handle());
[email protected]66d9b6e32012-03-22 03:04:32450 scoped_refptr<X509Certificate> cert_chain =
451 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
452 intermediates);
453
454 CertVerifyResult verify_result;
455 int flags = 0;
[email protected]90499482013-06-01 00:39:50456 int error = Verify(cert_chain.get(),
[email protected]77f1f9d2013-06-29 14:16:51457 "127.0.0.1",
[email protected]90499482013-06-01 00:39:50458 flags,
459 NULL,
460 empty_cert_list_,
461 &verify_result);
[email protected]77f1f9d2013-06-29 14:16:51462 EXPECT_EQ(OK, error);
463
464 // The extra MD5 root should be discarded
465 ASSERT_TRUE(verify_result.verified_cert.get());
466 ASSERT_EQ(1u,
467 verify_result.verified_cert->GetIntermediateCertificates().size());
468 EXPECT_TRUE(X509Certificate::IsSameOSCert(
469 verify_result.verified_cert->GetIntermediateCertificates().front(),
470 root_cert->os_cert_handle()));
[email protected]66d9b6e32012-03-22 03:04:32471
472 EXPECT_FALSE(verify_result.has_md5);
[email protected]66d9b6e32012-03-22 03:04:32473}
474
475// Test for bug 94673.
476TEST_F(CertVerifyProcTest, GoogleDigiNotarTest) {
[email protected]6cdfd7f2013-02-08 20:40:15477 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]66d9b6e32012-03-22 03:04:32478
479 scoped_refptr<X509Certificate> server_cert =
480 ImportCertFromFile(certs_dir, "google_diginotar.pem");
481 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
482
483 scoped_refptr<X509Certificate> intermediate_cert =
484 ImportCertFromFile(certs_dir, "diginotar_public_ca_2025.pem");
485 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert);
486
487 X509Certificate::OSCertHandles intermediates;
488 intermediates.push_back(intermediate_cert->os_cert_handle());
489 scoped_refptr<X509Certificate> cert_chain =
490 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
491 intermediates);
492
493 CertVerifyResult verify_result;
[email protected]8738e0d72012-08-23 02:00:47494 int flags = CertVerifier::VERIFY_REV_CHECKING_ENABLED;
[email protected]90499482013-06-01 00:39:50495 int error = Verify(cert_chain.get(),
496 "mail.google.com",
497 flags,
498 NULL,
499 empty_cert_list_,
500 &verify_result);
[email protected]66d9b6e32012-03-22 03:04:32501 EXPECT_NE(OK, error);
502
503 // Now turn off revocation checking. Certificate verification should still
504 // fail.
505 flags = 0;
[email protected]90499482013-06-01 00:39:50506 error = Verify(cert_chain.get(),
507 "mail.google.com",
508 flags,
509 NULL,
510 empty_cert_list_,
511 &verify_result);
[email protected]66d9b6e32012-03-22 03:04:32512 EXPECT_NE(OK, error);
513}
514
[email protected]62b23c22012-03-22 04:50:24515TEST_F(CertVerifyProcTest, DigiNotarCerts) {
516 static const char* const kDigiNotarFilenames[] = {
517 "diginotar_root_ca.pem",
518 "diginotar_cyber_ca.pem",
519 "diginotar_services_1024_ca.pem",
520 "diginotar_pkioverheid.pem",
521 "diginotar_pkioverheid_g2.pem",
522 NULL,
523 };
524
[email protected]6cdfd7f2013-02-08 20:40:15525 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]62b23c22012-03-22 04:50:24526
527 for (size_t i = 0; kDigiNotarFilenames[i]; i++) {
528 scoped_refptr<X509Certificate> diginotar_cert =
529 ImportCertFromFile(certs_dir, kDigiNotarFilenames[i]);
530 std::string der_bytes;
531 ASSERT_TRUE(X509Certificate::GetDEREncoded(
532 diginotar_cert->os_cert_handle(), &der_bytes));
533
534 base::StringPiece spki;
535 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_bytes, &spki));
536
537 std::string spki_sha1 = base::SHA1HashString(spki.as_string());
538
[email protected]ede03212012-09-07 12:52:26539 HashValueVector public_keys;
540 HashValue hash(HASH_VALUE_SHA1);
541 ASSERT_EQ(hash.size(), spki_sha1.size());
542 memcpy(hash.data(), spki_sha1.data(), spki_sha1.size());
543 public_keys.push_back(hash);
[email protected]62b23c22012-03-22 04:50:24544
545 EXPECT_TRUE(CertVerifyProc::IsPublicKeyBlacklisted(public_keys)) <<
546 "Public key not blocked for " << kDigiNotarFilenames[i];
547 }
548}
549
[email protected]f5a393db2013-12-16 18:41:01550TEST_F(CertVerifyProcTest, NameConstraintsOk) {
551 CertificateList ca_cert_list =
552 CreateCertificateListFromFile(GetTestCertsDirectory(),
553 "root_ca_cert.pem",
554 X509Certificate::FORMAT_AUTO);
555 ASSERT_EQ(1U, ca_cert_list.size());
556 ScopedTestRoot test_root(ca_cert_list[0]);
557
558 CertificateList cert_list = CreateCertificateListFromFile(
559 GetTestCertsDirectory(), "name_constraint_ok.crt",
560 X509Certificate::FORMAT_AUTO);
561 ASSERT_EQ(1U, cert_list.size());
562
563 X509Certificate::OSCertHandles intermediates;
564 scoped_refptr<X509Certificate> leaf =
565 X509Certificate::CreateFromHandle(cert_list[0]->os_cert_handle(),
566 intermediates);
567
568 int flags = 0;
569 CertVerifyResult verify_result;
570 int error = Verify(leaf.get(),
571 "test.example.com",
572 flags,
573 NULL,
574 empty_cert_list_,
575 &verify_result);
576 EXPECT_EQ(OK, error);
577 EXPECT_EQ(0U, verify_result.cert_status);
578}
579
[email protected]23073f92014-01-17 22:52:17580TEST_F(CertVerifyProcTest, NameConstraintsFailure) {
581 if (!SupportsReturningVerifiedChain()) {
582 LOG(INFO) << "Skipping this test in this platform.";
583 return;
584 }
585
[email protected]f5a393db2013-12-16 18:41:01586 CertificateList ca_cert_list =
587 CreateCertificateListFromFile(GetTestCertsDirectory(),
588 "root_ca_cert.pem",
589 X509Certificate::FORMAT_AUTO);
590 ASSERT_EQ(1U, ca_cert_list.size());
591 ScopedTestRoot test_root(ca_cert_list[0]);
592
593 CertificateList cert_list = CreateCertificateListFromFile(
594 GetTestCertsDirectory(), "name_constraint_bad.crt",
595 X509Certificate::FORMAT_AUTO);
596 ASSERT_EQ(1U, cert_list.size());
597
598 X509Certificate::OSCertHandles intermediates;
599 scoped_refptr<X509Certificate> leaf =
600 X509Certificate::CreateFromHandle(cert_list[0]->os_cert_handle(),
601 intermediates);
602
603 int flags = 0;
604 CertVerifyResult verify_result;
605 int error = Verify(leaf.get(),
606 "test.example.com",
607 flags,
608 NULL,
609 empty_cert_list_,
610 &verify_result);
611 EXPECT_EQ(ERR_CERT_NAME_CONSTRAINT_VIOLATION, error);
612 EXPECT_EQ(CERT_STATUS_NAME_CONSTRAINT_VIOLATION,
613 verify_result.cert_status & CERT_STATUS_NAME_CONSTRAINT_VIOLATION);
614}
615
[email protected]5b9a1882013-07-17 16:34:35616TEST_F(CertVerifyProcTest, TestKnownRoot) {
[email protected]23073f92014-01-17 22:52:17617 if (!SupportsDetectingKnownRoots()) {
618 LOG(INFO) << "Skipping this test in this platform.";
619 return;
620 }
621
[email protected]6cdfd7f2013-02-08 20:40:15622 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]a6b4ee042012-07-24 20:52:46623 CertificateList certs = CreateCertificateListFromFile(
[email protected]5b9a1882013-07-17 16:34:35624 certs_dir, "satveda.pem", X509Certificate::FORMAT_AUTO);
625 ASSERT_EQ(2U, certs.size());
[email protected]66d9b6e32012-03-22 03:04:32626
627 X509Certificate::OSCertHandles intermediates;
[email protected]a6b4ee042012-07-24 20:52:46628 intermediates.push_back(certs[1]->os_cert_handle());
[email protected]a6b4ee042012-07-24 20:52:46629
[email protected]66d9b6e32012-03-22 03:04:32630 scoped_refptr<X509Certificate> cert_chain =
[email protected]a6b4ee042012-07-24 20:52:46631 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
[email protected]66d9b6e32012-03-22 03:04:32632 intermediates);
633
634 int flags = 0;
635 CertVerifyResult verify_result;
[email protected]5b9a1882013-07-17 16:34:35636 // This will blow up, May 24th, 2019. Sorry! Please disable and file a bug
[email protected]a6b4ee042012-07-24 20:52:46637 // against agl. See also PublicKeyHashes.
[email protected]90499482013-06-01 00:39:50638 int error = Verify(cert_chain.get(),
[email protected]5b9a1882013-07-17 16:34:35639 "satveda.com",
[email protected]90499482013-06-01 00:39:50640 flags,
641 NULL,
642 empty_cert_list_,
643 &verify_result);
[email protected]66d9b6e32012-03-22 03:04:32644 EXPECT_EQ(OK, error);
645 EXPECT_EQ(0U, verify_result.cert_status);
646 EXPECT_TRUE(verify_result.is_issued_by_known_root);
647}
648
[email protected]e1920ea2013-07-12 14:32:02649// The certse.pem certificate has been revoked. crbug.com/259723.
[email protected]5b9a1882013-07-17 16:34:35650TEST_F(CertVerifyProcTest, PublicKeyHashes) {
[email protected]23073f92014-01-17 22:52:17651 if (!SupportsReturningVerifiedChain()) {
652 LOG(INFO) << "Skipping this test in this platform.";
653 return;
654 }
655
[email protected]6cdfd7f2013-02-08 20:40:15656 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]a6b4ee042012-07-24 20:52:46657 CertificateList certs = CreateCertificateListFromFile(
[email protected]5b9a1882013-07-17 16:34:35658 certs_dir, "satveda.pem", X509Certificate::FORMAT_AUTO);
659 ASSERT_EQ(2U, certs.size());
[email protected]66d9b6e32012-03-22 03:04:32660
661 X509Certificate::OSCertHandles intermediates;
[email protected]a6b4ee042012-07-24 20:52:46662 intermediates.push_back(certs[1]->os_cert_handle());
[email protected]66d9b6e32012-03-22 03:04:32663
[email protected]a6b4ee042012-07-24 20:52:46664 scoped_refptr<X509Certificate> cert_chain =
665 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
666 intermediates);
[email protected]66d9b6e32012-03-22 03:04:32667 int flags = 0;
668 CertVerifyResult verify_result;
669
[email protected]5b9a1882013-07-17 16:34:35670 // This will blow up, May 24th, 2019. Sorry! Please disable and file a bug
[email protected]a6b4ee042012-07-24 20:52:46671 // against agl. See also TestKnownRoot.
[email protected]90499482013-06-01 00:39:50672 int error = Verify(cert_chain.get(),
[email protected]5b9a1882013-07-17 16:34:35673 "satveda.com",
[email protected]90499482013-06-01 00:39:50674 flags,
675 NULL,
676 empty_cert_list_,
677 &verify_result);
[email protected]66d9b6e32012-03-22 03:04:32678 EXPECT_EQ(OK, error);
679 EXPECT_EQ(0U, verify_result.cert_status);
[email protected]5b9a1882013-07-17 16:34:35680 ASSERT_LE(2U, verify_result.public_key_hashes.size());
[email protected]ede03212012-09-07 12:52:26681
682 HashValueVector sha1_hashes;
[email protected]bfea55d2013-04-04 11:06:04683 for (size_t i = 0; i < verify_result.public_key_hashes.size(); ++i) {
[email protected]ede03212012-09-07 12:52:26684 if (verify_result.public_key_hashes[i].tag != HASH_VALUE_SHA1)
685 continue;
686 sha1_hashes.push_back(verify_result.public_key_hashes[i]);
687 }
[email protected]5b9a1882013-07-17 16:34:35688 ASSERT_LE(2u, sha1_hashes.size());
[email protected]ede03212012-09-07 12:52:26689
[email protected]5b9a1882013-07-17 16:34:35690 for (size_t i = 0; i < 2; ++i) {
691 EXPECT_EQ(HexEncode(kSatvedaSPKIs[i], base::kSHA1Length),
[email protected]ede03212012-09-07 12:52:26692 HexEncode(sha1_hashes[i].data(), base::kSHA1Length));
[email protected]a6b4ee042012-07-24 20:52:46693 }
[email protected]bfea55d2013-04-04 11:06:04694
695 HashValueVector sha256_hashes;
696 for (size_t i = 0; i < verify_result.public_key_hashes.size(); ++i) {
697 if (verify_result.public_key_hashes[i].tag != HASH_VALUE_SHA256)
698 continue;
699 sha256_hashes.push_back(verify_result.public_key_hashes[i]);
700 }
[email protected]5b9a1882013-07-17 16:34:35701 ASSERT_LE(2u, sha256_hashes.size());
[email protected]bfea55d2013-04-04 11:06:04702
[email protected]5b9a1882013-07-17 16:34:35703 for (size_t i = 0; i < 2; ++i) {
704 EXPECT_EQ(HexEncode(kSatvedaSPKIsSHA256[i], crypto::kSHA256Length),
[email protected]bfea55d2013-04-04 11:06:04705 HexEncode(sha256_hashes[i].data(), crypto::kSHA256Length));
706 }
[email protected]66d9b6e32012-03-22 03:04:32707}
708
709// A regression test for http://crbug.com/70293.
710// The Key Usage extension in this RSA SSL server certificate does not have
711// the keyEncipherment bit.
712TEST_F(CertVerifyProcTest, InvalidKeyUsage) {
[email protected]6cdfd7f2013-02-08 20:40:15713 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]66d9b6e32012-03-22 03:04:32714
715 scoped_refptr<X509Certificate> server_cert =
716 ImportCertFromFile(certs_dir, "invalid_key_usage_cert.der");
717 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
718
719 int flags = 0;
720 CertVerifyResult verify_result;
[email protected]90499482013-06-01 00:39:50721 int error = Verify(server_cert.get(),
722 "jira.aquameta.com",
723 flags,
724 NULL,
725 empty_cert_list_,
726 &verify_result);
[email protected]e1b2d732014-03-28 16:20:32727#if defined(USE_OPENSSL_CERTS) && !defined(OS_ANDROID)
[email protected]66d9b6e32012-03-22 03:04:32728 // This certificate has two errors: "invalid key usage" and "untrusted CA".
729 // However, OpenSSL returns only one (the latter), and we can't detect
730 // the other errors.
731 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
732#else
733 EXPECT_EQ(ERR_CERT_INVALID, error);
734 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID);
735#endif
736 // TODO(wtc): fix http://crbug.com/75520 to get all the certificate errors
737 // from NSS.
[email protected]c97dc552013-04-25 21:29:56738#if !defined(USE_NSS) && !defined(OS_IOS) && !defined(OS_ANDROID)
[email protected]66d9b6e32012-03-22 03:04:32739 // The certificate is issued by an unknown CA.
740 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID);
741#endif
742}
743
744// Basic test for returning the chain in CertVerifyResult. Note that the
745// returned chain may just be a reflection of the originally supplied chain;
746// that is, if any errors occur, the default chain returned is an exact copy
747// of the certificate to be verified. The remaining VerifyReturn* tests are
748// used to ensure that the actual, verified chain is being returned by
749// Verify().
750TEST_F(CertVerifyProcTest, VerifyReturnChainBasic) {
[email protected]23073f92014-01-17 22:52:17751 if (!SupportsReturningVerifiedChain()) {
752 LOG(INFO) << "Skipping this test in this platform.";
753 return;
754 }
755
[email protected]6cdfd7f2013-02-08 20:40:15756 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]66d9b6e32012-03-22 03:04:32757 CertificateList certs = CreateCertificateListFromFile(
758 certs_dir, "x509_verify_results.chain.pem",
759 X509Certificate::FORMAT_AUTO);
760 ASSERT_EQ(3U, certs.size());
761
762 X509Certificate::OSCertHandles intermediates;
763 intermediates.push_back(certs[1]->os_cert_handle());
764 intermediates.push_back(certs[2]->os_cert_handle());
765
[email protected]90499482013-06-01 00:39:50766 ScopedTestRoot scoped_root(certs[2].get());
[email protected]66d9b6e32012-03-22 03:04:32767
768 scoped_refptr<X509Certificate> google_full_chain =
769 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
770 intermediates);
771 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain);
772 ASSERT_EQ(2U, google_full_chain->GetIntermediateCertificates().size());
773
774 CertVerifyResult verify_result;
775 EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
[email protected]90499482013-06-01 00:39:50776 int error = Verify(google_full_chain.get(),
777 "127.0.0.1",
778 0,
779 NULL,
780 empty_cert_list_,
781 &verify_result);
[email protected]66d9b6e32012-03-22 03:04:32782 EXPECT_EQ(OK, error);
783 ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
784
785 EXPECT_NE(google_full_chain, verify_result.verified_cert);
786 EXPECT_TRUE(X509Certificate::IsSameOSCert(
787 google_full_chain->os_cert_handle(),
788 verify_result.verified_cert->os_cert_handle()));
789 const X509Certificate::OSCertHandles& return_intermediates =
790 verify_result.verified_cert->GetIntermediateCertificates();
791 ASSERT_EQ(2U, return_intermediates.size());
792 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0],
793 certs[1]->os_cert_handle()));
794 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1],
795 certs[2]->os_cert_handle()));
796}
797
[email protected]ff353212013-05-17 02:09:08798// Test that certificates issued for 'intranet' names (that is, containing no
799// known public registry controlled domain information) issued by well-known
800// CAs are flagged appropriately, while certificates that are issued by
801// internal CAs are not flagged.
[email protected]23073f92014-01-17 22:52:17802TEST_F(CertVerifyProcTest, IntranetHostsRejected) {
803 if (!SupportsDetectingKnownRoots()) {
804 LOG(INFO) << "Skipping this test in this platform.";
805 return;
806 }
807
[email protected]ff353212013-05-17 02:09:08808 CertificateList cert_list = CreateCertificateListFromFile(
809 GetTestCertsDirectory(), "ok_cert.pem",
810 X509Certificate::FORMAT_AUTO);
811 ASSERT_EQ(1U, cert_list.size());
812 scoped_refptr<X509Certificate> cert(cert_list[0]);
813
814 CertVerifyResult verify_result;
815 int error = 0;
816
817 // Intranet names for public CAs should be flagged:
818 verify_proc_ = new WellKnownCaCertVerifyProc(true);
[email protected]90499482013-06-01 00:39:50819 error =
820 Verify(cert.get(), "intranet", 0, NULL, empty_cert_list_, &verify_result);
[email protected]ff353212013-05-17 02:09:08821 EXPECT_EQ(OK, error);
822 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME);
823
824 // However, if the CA is not well known, these should not be flagged:
825 verify_proc_ = new WellKnownCaCertVerifyProc(false);
[email protected]90499482013-06-01 00:39:50826 error =
827 Verify(cert.get(), "intranet", 0, NULL, empty_cert_list_, &verify_result);
[email protected]ff353212013-05-17 02:09:08828 EXPECT_EQ(OK, error);
829 EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME);
830}
831
[email protected]66d9b6e32012-03-22 03:04:32832// Test that the certificate returned in CertVerifyResult is able to reorder
833// certificates that are not ordered from end-entity to root. While this is
834// a protocol violation if sent during a TLS handshake, if multiple sources
835// of intermediate certificates are combined, it's possible that order may
836// not be maintained.
837TEST_F(CertVerifyProcTest, VerifyReturnChainProperlyOrdered) {
[email protected]23073f92014-01-17 22:52:17838 if (!SupportsReturningVerifiedChain()) {
839 LOG(INFO) << "Skipping this test in this platform.";
840 return;
841 }
842
[email protected]6cdfd7f2013-02-08 20:40:15843 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]66d9b6e32012-03-22 03:04:32844 CertificateList certs = CreateCertificateListFromFile(
845 certs_dir, "x509_verify_results.chain.pem",
846 X509Certificate::FORMAT_AUTO);
847 ASSERT_EQ(3U, certs.size());
848
849 // Construct the chain out of order.
850 X509Certificate::OSCertHandles intermediates;
851 intermediates.push_back(certs[2]->os_cert_handle());
852 intermediates.push_back(certs[1]->os_cert_handle());
853
[email protected]90499482013-06-01 00:39:50854 ScopedTestRoot scoped_root(certs[2].get());
[email protected]66d9b6e32012-03-22 03:04:32855
856 scoped_refptr<X509Certificate> google_full_chain =
857 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
858 intermediates);
859 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain);
860 ASSERT_EQ(2U, google_full_chain->GetIntermediateCertificates().size());
861
862 CertVerifyResult verify_result;
863 EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
[email protected]90499482013-06-01 00:39:50864 int error = Verify(google_full_chain.get(),
865 "127.0.0.1",
866 0,
867 NULL,
868 empty_cert_list_,
869 &verify_result);
[email protected]66d9b6e32012-03-22 03:04:32870 EXPECT_EQ(OK, error);
871 ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
872
873 EXPECT_NE(google_full_chain, verify_result.verified_cert);
874 EXPECT_TRUE(X509Certificate::IsSameOSCert(
875 google_full_chain->os_cert_handle(),
876 verify_result.verified_cert->os_cert_handle()));
877 const X509Certificate::OSCertHandles& return_intermediates =
878 verify_result.verified_cert->GetIntermediateCertificates();
879 ASSERT_EQ(2U, return_intermediates.size());
880 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0],
881 certs[1]->os_cert_handle()));
882 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1],
883 certs[2]->os_cert_handle()));
884}
885
886// Test that Verify() filters out certificates which are not related to
887// or part of the certificate chain being verified.
888TEST_F(CertVerifyProcTest, VerifyReturnChainFiltersUnrelatedCerts) {
[email protected]23073f92014-01-17 22:52:17889 if (!SupportsReturningVerifiedChain()) {
890 LOG(INFO) << "Skipping this test in this platform.";
891 return;
892 }
893
[email protected]6cdfd7f2013-02-08 20:40:15894 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]66d9b6e32012-03-22 03:04:32895 CertificateList certs = CreateCertificateListFromFile(
896 certs_dir, "x509_verify_results.chain.pem",
897 X509Certificate::FORMAT_AUTO);
898 ASSERT_EQ(3U, certs.size());
[email protected]90499482013-06-01 00:39:50899 ScopedTestRoot scoped_root(certs[2].get());
[email protected]66d9b6e32012-03-22 03:04:32900
[email protected]25bf1962013-07-26 07:39:37901 scoped_refptr<X509Certificate> unrelated_certificate =
902 ImportCertFromFile(certs_dir, "duplicate_cn_1.pem");
903 scoped_refptr<X509Certificate> unrelated_certificate2 =
904 ImportCertFromFile(certs_dir, "aia-cert.pem");
905 ASSERT_NE(static_cast<X509Certificate*>(NULL), unrelated_certificate);
906 ASSERT_NE(static_cast<X509Certificate*>(NULL), unrelated_certificate2);
[email protected]66d9b6e32012-03-22 03:04:32907
908 // Interject unrelated certificates into the list of intermediates.
909 X509Certificate::OSCertHandles intermediates;
[email protected]25bf1962013-07-26 07:39:37910 intermediates.push_back(unrelated_certificate->os_cert_handle());
[email protected]66d9b6e32012-03-22 03:04:32911 intermediates.push_back(certs[1]->os_cert_handle());
[email protected]25bf1962013-07-26 07:39:37912 intermediates.push_back(unrelated_certificate2->os_cert_handle());
[email protected]66d9b6e32012-03-22 03:04:32913 intermediates.push_back(certs[2]->os_cert_handle());
914
915 scoped_refptr<X509Certificate> google_full_chain =
916 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
917 intermediates);
918 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain);
919 ASSERT_EQ(4U, google_full_chain->GetIntermediateCertificates().size());
920
921 CertVerifyResult verify_result;
922 EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
[email protected]90499482013-06-01 00:39:50923 int error = Verify(google_full_chain.get(),
924 "127.0.0.1",
925 0,
926 NULL,
927 empty_cert_list_,
928 &verify_result);
[email protected]66d9b6e32012-03-22 03:04:32929 EXPECT_EQ(OK, error);
930 ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
931
932 EXPECT_NE(google_full_chain, verify_result.verified_cert);
933 EXPECT_TRUE(X509Certificate::IsSameOSCert(
934 google_full_chain->os_cert_handle(),
935 verify_result.verified_cert->os_cert_handle()));
936 const X509Certificate::OSCertHandles& return_intermediates =
937 verify_result.verified_cert->GetIntermediateCertificates();
938 ASSERT_EQ(2U, return_intermediates.size());
939 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0],
940 certs[1]->os_cert_handle()));
941 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1],
942 certs[2]->os_cert_handle()));
943}
944
[email protected]ef155122013-03-23 19:11:24945TEST_F(CertVerifyProcTest, AdditionalTrustAnchors) {
946 if (!SupportsAdditionalTrustAnchors()) {
947 LOG(INFO) << "Skipping this test in this platform.";
948 return;
949 }
950
951 // |ca_cert| is the issuer of |cert|.
952 CertificateList ca_cert_list = CreateCertificateListFromFile(
[email protected]d321e742013-06-20 16:28:44953 GetTestCertsDirectory(), "root_ca_cert.pem",
[email protected]ef155122013-03-23 19:11:24954 X509Certificate::FORMAT_AUTO);
955 ASSERT_EQ(1U, ca_cert_list.size());
956 scoped_refptr<X509Certificate> ca_cert(ca_cert_list[0]);
957
958 CertificateList cert_list = CreateCertificateListFromFile(
959 GetTestCertsDirectory(), "ok_cert.pem",
960 X509Certificate::FORMAT_AUTO);
961 ASSERT_EQ(1U, cert_list.size());
962 scoped_refptr<X509Certificate> cert(cert_list[0]);
963
964 // Verification of |cert| fails when |ca_cert| is not in the trust anchors
965 // list.
966 int flags = 0;
967 CertVerifyResult verify_result;
[email protected]90499482013-06-01 00:39:50968 int error = Verify(
969 cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_, &verify_result);
[email protected]ef155122013-03-23 19:11:24970 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
971 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status);
[email protected]0d20bad2013-03-24 04:56:48972 EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor);
[email protected]ef155122013-03-23 19:11:24973
974 // Now add the |ca_cert| to the |trust_anchors|, and verification should pass.
975 CertificateList trust_anchors;
976 trust_anchors.push_back(ca_cert);
[email protected]90499482013-06-01 00:39:50977 error = Verify(
978 cert.get(), "127.0.0.1", flags, NULL, trust_anchors, &verify_result);
[email protected]ef155122013-03-23 19:11:24979 EXPECT_EQ(OK, error);
980 EXPECT_EQ(0U, verify_result.cert_status);
[email protected]0d20bad2013-03-24 04:56:48981 EXPECT_TRUE(verify_result.is_issued_by_additional_trust_anchor);
[email protected]ef155122013-03-23 19:11:24982
983 // Clearing the |trust_anchors| makes verification fail again (the cache
984 // should be skipped).
[email protected]90499482013-06-01 00:39:50985 error = Verify(
986 cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_, &verify_result);
[email protected]ef155122013-03-23 19:11:24987 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
988 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status);
[email protected]0d20bad2013-03-24 04:56:48989 EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor);
[email protected]ef155122013-03-23 19:11:24990}
991
[email protected]23073f92014-01-17 22:52:17992// Tests that certificates issued by user-supplied roots are not flagged as
993// issued by a known root. This should pass whether or not the platform supports
994// detecting known roots.
995TEST_F(CertVerifyProcTest, IsIssuedByKnownRootIgnoresTestRoots) {
996 // Load root_ca_cert.pem into the test root store.
997 TestRootCerts* root_certs = TestRootCerts::GetInstance();
998 root_certs->AddFromFile(
999 GetTestCertsDirectory().AppendASCII("root_ca_cert.pem"));
1000
1001 CertificateList cert_list = CreateCertificateListFromFile(
1002 GetTestCertsDirectory(), "ok_cert.pem",
1003 X509Certificate::FORMAT_AUTO);
1004 ASSERT_EQ(1U, cert_list.size());
1005 scoped_refptr<X509Certificate> cert(cert_list[0]);
1006
1007 // Verification should pass.
1008 int flags = 0;
1009 CertVerifyResult verify_result;
1010 int error = Verify(
1011 cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_, &verify_result);
1012 EXPECT_EQ(OK, error);
1013 EXPECT_EQ(0U, verify_result.cert_status);
1014 // But should not be marked as a known root.
1015 EXPECT_FALSE(verify_result.is_issued_by_known_root);
[email protected]87015652014-03-26 12:33:161016
1017 root_certs->Clear();
1018 EXPECT_TRUE(root_certs->IsEmpty());
[email protected]23073f92014-01-17 22:52:171019}
1020
[email protected]339e17e2013-06-14 02:48:291021#if defined(OS_MACOSX) && !defined(OS_IOS)
1022// Tests that, on OS X, issues with a cross-certified Baltimore CyberTrust
1023// Root can be successfully worked around once Apple completes removing the
1024// older GTE CyberTrust Root from its trusted root store.
1025//
1026// The issue is caused by servers supplying the cross-certified intermediate
1027// (necessary for certain mobile platforms), which OS X does not recognize
1028// as already existing within its trust store.
1029TEST_F(CertVerifyProcTest, CybertrustGTERoot) {
1030 CertificateList certs = CreateCertificateListFromFile(
1031 GetTestCertsDirectory(),
1032 "cybertrust_omniroot_chain.pem",
1033 X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
1034 ASSERT_EQ(2U, certs.size());
1035
1036 X509Certificate::OSCertHandles intermediates;
1037 intermediates.push_back(certs[1]->os_cert_handle());
1038
1039 scoped_refptr<X509Certificate> cybertrust_basic =
1040 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
1041 intermediates);
1042 ASSERT_TRUE(cybertrust_basic.get());
1043
1044 scoped_refptr<X509Certificate> baltimore_root =
1045 ImportCertFromFile(GetTestCertsDirectory(),
1046 "cybertrust_baltimore_root.pem");
1047 ASSERT_TRUE(baltimore_root.get());
1048
[email protected]f15d9ebc2013-07-02 00:14:501049 ScopedTestRoot scoped_root(baltimore_root.get());
[email protected]339e17e2013-06-14 02:48:291050
1051 // Ensure that ONLY the Baltimore CyberTrust Root is trusted. This
1052 // simulates Keychain removing support for the GTE CyberTrust Root.
1053 TestRootCerts::GetInstance()->SetAllowSystemTrust(false);
1054 base::ScopedClosureRunner reset_system_trust(
1055 base::Bind(&TestRootCerts::SetAllowSystemTrust,
1056 base::Unretained(TestRootCerts::GetInstance()),
1057 true));
1058
1059 // First, make sure a simple certificate chain from
1060 // EE -> Public SureServer SV -> Baltimore CyberTrust
1061 // works. Only the first two certificates are included in the chain.
1062 int flags = 0;
1063 CertVerifyResult verify_result;
[email protected]f15d9ebc2013-07-02 00:14:501064 int error = Verify(cybertrust_basic.get(),
1065 "cacert.omniroot.com",
1066 flags,
1067 NULL,
1068 empty_cert_list_,
1069 &verify_result);
[email protected]339e17e2013-06-14 02:48:291070 EXPECT_EQ(OK, error);
1071 EXPECT_EQ(0U, verify_result.cert_status);
1072
1073 // Attempt to verify with the first known cross-certified intermediate
1074 // provided.
1075 scoped_refptr<X509Certificate> baltimore_intermediate_1 =
1076 ImportCertFromFile(GetTestCertsDirectory(),
1077 "cybertrust_baltimore_cross_certified_1.pem");
1078 ASSERT_TRUE(baltimore_intermediate_1.get());
1079
1080 X509Certificate::OSCertHandles intermediate_chain_1 =
1081 cybertrust_basic->GetIntermediateCertificates();
1082 intermediate_chain_1.push_back(baltimore_intermediate_1->os_cert_handle());
1083
1084 scoped_refptr<X509Certificate> baltimore_chain_1 =
1085 X509Certificate::CreateFromHandle(cybertrust_basic->os_cert_handle(),
1086 intermediate_chain_1);
[email protected]f15d9ebc2013-07-02 00:14:501087 error = Verify(baltimore_chain_1.get(),
1088 "cacert.omniroot.com",
1089 flags,
1090 NULL,
1091 empty_cert_list_,
1092 &verify_result);
[email protected]339e17e2013-06-14 02:48:291093 EXPECT_EQ(OK, error);
1094 EXPECT_EQ(0U, verify_result.cert_status);
1095
1096 // Attempt to verify with the second known cross-certified intermediate
1097 // provided.
1098 scoped_refptr<X509Certificate> baltimore_intermediate_2 =
1099 ImportCertFromFile(GetTestCertsDirectory(),
1100 "cybertrust_baltimore_cross_certified_2.pem");
1101 ASSERT_TRUE(baltimore_intermediate_2.get());
1102
1103 X509Certificate::OSCertHandles intermediate_chain_2 =
1104 cybertrust_basic->GetIntermediateCertificates();
1105 intermediate_chain_2.push_back(baltimore_intermediate_2->os_cert_handle());
1106
1107 scoped_refptr<X509Certificate> baltimore_chain_2 =
1108 X509Certificate::CreateFromHandle(cybertrust_basic->os_cert_handle(),
1109 intermediate_chain_2);
[email protected]f15d9ebc2013-07-02 00:14:501110 error = Verify(baltimore_chain_2.get(),
1111 "cacert.omniroot.com",
1112 flags,
1113 NULL,
1114 empty_cert_list_,
1115 &verify_result);
[email protected]339e17e2013-06-14 02:48:291116 EXPECT_EQ(OK, error);
1117 EXPECT_EQ(0U, verify_result.cert_status);
1118
1119 // Attempt to verify when both a cross-certified intermediate AND
1120 // the legacy GTE root are provided.
1121 scoped_refptr<X509Certificate> cybertrust_root =
1122 ImportCertFromFile(GetTestCertsDirectory(),
1123 "cybertrust_gte_root.pem");
1124 ASSERT_TRUE(cybertrust_root.get());
1125
1126 intermediate_chain_2.push_back(cybertrust_root->os_cert_handle());
1127 scoped_refptr<X509Certificate> baltimore_chain_with_root =
1128 X509Certificate::CreateFromHandle(cybertrust_basic->os_cert_handle(),
1129 intermediate_chain_2);
[email protected]f15d9ebc2013-07-02 00:14:501130 error = Verify(baltimore_chain_with_root.get(),
1131 "cacert.omniroot.com",
1132 flags,
1133 NULL,
1134 empty_cert_list_,
1135 &verify_result);
[email protected]339e17e2013-06-14 02:48:291136 EXPECT_EQ(OK, error);
1137 EXPECT_EQ(0U, verify_result.cert_status);
1138
[email protected]87015652014-03-26 12:33:161139 TestRootCerts::GetInstance()->Clear();
1140 EXPECT_TRUE(TestRootCerts::GetInstance()->IsEmpty());
[email protected]339e17e2013-06-14 02:48:291141}
1142#endif
1143
[email protected]12b3c8822012-09-26 11:51:181144#if defined(USE_NSS) || defined(OS_IOS) || defined(OS_WIN) || defined(OS_MACOSX)
[email protected]d0ead382013-11-25 22:42:061145static const uint8 kCRLSetLeafSPKIBlocked[] = {
[email protected]66d9b6e32012-03-22 03:04:321146 0x8e, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a,
1147 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
1148 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22,
1149 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22,
1150 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c,
1151 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a,
1152 0x30, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b,
[email protected]d0ead382013-11-25 22:42:061153 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x43, 0x38, 0x4d, 0x4a, 0x46, 0x55, 0x55,
1154 0x5a, 0x38, 0x43, 0x79, 0x54, 0x2b, 0x4e, 0x57, 0x64, 0x68, 0x69, 0x7a, 0x51,
1155 0x68, 0x54, 0x49, 0x65, 0x46, 0x49, 0x37, 0x76, 0x41, 0x77, 0x7a, 0x64, 0x54,
1156 0x79, 0x52, 0x59, 0x45, 0x6e, 0x78, 0x6c, 0x33, 0x62, 0x67, 0x3d, 0x22, 0x5d,
[email protected]66d9b6e32012-03-22 03:04:321157 0x7d,
1158};
1159
[email protected]d0ead382013-11-25 22:42:061160static const uint8 kCRLSetLeafSerialBlocked[] = {
[email protected]66d9b6e32012-03-22 03:04:321161 0x60, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a,
1162 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
1163 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22,
1164 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22,
1165 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c,
1166 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a,
1167 0x31, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b,
[email protected]d0ead382013-11-25 22:42:061168 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x0f, 0x87, 0xe4, 0xc7, 0x75, 0xea,
1169 0x46, 0x7e, 0xf3, 0xfd, 0x82, 0xb7, 0x46, 0x7b, 0x10, 0xda, 0xc5, 0xbf, 0xd8,
1170 0xd1, 0x29, 0xb2, 0xc6, 0xac, 0x7f, 0x51, 0x42, 0x15, 0x28, 0x51, 0x06, 0x7f,
1171 0x01, 0x00, 0x00, 0x00, // number of serials
1172 0x01, 0xed, // serial 0xed
[email protected]66d9b6e32012-03-22 03:04:321173};
1174
[email protected]d0ead382013-11-25 22:42:061175static const uint8 kCRLSetQUICSerialBlocked[] = {
[email protected]66d9b6e32012-03-22 03:04:321176 0x60, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a,
1177 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
1178 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22,
1179 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22,
1180 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c,
1181 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a,
1182 0x31, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b,
[email protected]d0ead382013-11-25 22:42:061183 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d,
[email protected]9d5ce432013-11-27 04:48:331184 // Issuer SPKI SHA-256 hash:
1185 0xe4, 0x3a, 0xa3, 0xdb, 0x98, 0x31, 0x61, 0x05, 0xdd, 0x57, 0x6d, 0xc6, 0x2f,
1186 0x71, 0x26, 0xba, 0xdd, 0xf4, 0x98, 0x3e, 0x62, 0x22, 0xf8, 0xf9, 0xe4, 0x18,
1187 0x62, 0x77, 0x79, 0xdb, 0x9b, 0x31,
[email protected]d0ead382013-11-25 22:42:061188 0x01, 0x00, 0x00, 0x00, // number of serials
1189 0x01, 0x03, // serial 3
[email protected]66d9b6e32012-03-22 03:04:321190};
1191
1192// Test that CRLSets are effective in making a certificate appear to be
1193// revoked.
[email protected]d0ead382013-11-25 22:42:061194TEST_F(CertVerifyProcTest, CRLSet) {
1195 CertificateList ca_cert_list =
1196 CreateCertificateListFromFile(GetTestCertsDirectory(),
1197 "root_ca_cert.pem",
1198 X509Certificate::FORMAT_AUTO);
1199 ASSERT_EQ(1U, ca_cert_list.size());
1200 ScopedTestRoot test_root(ca_cert_list[0]);
[email protected]66d9b6e32012-03-22 03:04:321201
[email protected]d0ead382013-11-25 22:42:061202 CertificateList cert_list = CreateCertificateListFromFile(
1203 GetTestCertsDirectory(), "ok_cert.pem", X509Certificate::FORMAT_AUTO);
1204 ASSERT_EQ(1U, cert_list.size());
1205 scoped_refptr<X509Certificate> cert(cert_list[0]);
[email protected]66d9b6e32012-03-22 03:04:321206
[email protected]d0ead382013-11-25 22:42:061207 int flags = 0;
[email protected]66d9b6e32012-03-22 03:04:321208 CertVerifyResult verify_result;
[email protected]d0ead382013-11-25 22:42:061209 int error = Verify(
1210 cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_, &verify_result);
[email protected]66d9b6e32012-03-22 03:04:321211 EXPECT_EQ(OK, error);
[email protected]d0ead382013-11-25 22:42:061212 EXPECT_EQ(0U, verify_result.cert_status);
[email protected]66d9b6e32012-03-22 03:04:321213
1214 // First test blocking by SPKI.
1215 base::StringPiece crl_set_bytes(
[email protected]d0ead382013-11-25 22:42:061216 reinterpret_cast<const char*>(kCRLSetLeafSPKIBlocked),
1217 sizeof(kCRLSetLeafSPKIBlocked));
[email protected]66d9b6e32012-03-22 03:04:321218 scoped_refptr<CRLSet> crl_set;
1219 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
1220
[email protected]d0ead382013-11-25 22:42:061221 error = Verify(cert.get(),
1222 "127.0.0.1",
1223 flags,
[email protected]90499482013-06-01 00:39:501224 crl_set.get(),
1225 empty_cert_list_,
1226 &verify_result);
[email protected]66d9b6e32012-03-22 03:04:321227 EXPECT_EQ(ERR_CERT_REVOKED, error);
1228
1229 // Second, test revocation by serial number of a cert directly under the
1230 // root.
[email protected]d0ead382013-11-25 22:42:061231 crl_set_bytes =
1232 base::StringPiece(reinterpret_cast<const char*>(kCRLSetLeafSerialBlocked),
1233 sizeof(kCRLSetLeafSerialBlocked));
[email protected]66d9b6e32012-03-22 03:04:321234 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
1235
[email protected]d0ead382013-11-25 22:42:061236 error = Verify(cert.get(),
1237 "127.0.0.1",
1238 flags,
[email protected]90499482013-06-01 00:39:501239 crl_set.get(),
1240 empty_cert_list_,
1241 &verify_result);
[email protected]66d9b6e32012-03-22 03:04:321242 EXPECT_EQ(ERR_CERT_REVOKED, error);
[email protected]d0ead382013-11-25 22:42:061243}
[email protected]66d9b6e32012-03-22 03:04:321244
[email protected]d0ead382013-11-25 22:42:061245TEST_F(CertVerifyProcTest, CRLSetLeafSerial) {
1246 CertificateList ca_cert_list =
1247 CreateCertificateListFromFile(GetTestCertsDirectory(),
1248 "quic_root.crt",
1249 X509Certificate::FORMAT_AUTO);
1250 ASSERT_EQ(1U, ca_cert_list.size());
1251 ScopedTestRoot test_root(ca_cert_list[0]);
1252
1253 CertificateList intermediate_cert_list =
1254 CreateCertificateListFromFile(GetTestCertsDirectory(),
1255 "quic_intermediate.crt",
1256 X509Certificate::FORMAT_AUTO);
1257 ASSERT_EQ(1U, intermediate_cert_list.size());
1258 X509Certificate::OSCertHandles intermediates;
1259 intermediates.push_back(intermediate_cert_list[0]->os_cert_handle());
1260
1261 CertificateList cert_list = CreateCertificateListFromFile(
1262 GetTestCertsDirectory(), "quic_test.example.com.crt",
1263 X509Certificate::FORMAT_AUTO);
1264 ASSERT_EQ(1U, cert_list.size());
1265
1266 scoped_refptr<X509Certificate> leaf =
1267 X509Certificate::CreateFromHandle(cert_list[0]->os_cert_handle(),
1268 intermediates);
1269
1270 int flags = 0;
1271 CertVerifyResult verify_result;
1272 int error = Verify(leaf.get(),
1273 "test.example.com",
1274 flags,
1275 NULL,
1276 empty_cert_list_,
1277 &verify_result);
1278 EXPECT_EQ(OK, error);
1279 EXPECT_EQ(0U, verify_result.cert_status);
1280
1281 // Test revocation by serial number of a certificate not under the root.
1282 scoped_refptr<CRLSet> crl_set;
1283 base::StringPiece crl_set_bytes =
1284 base::StringPiece(reinterpret_cast<const char*>(kCRLSetQUICSerialBlocked),
1285 sizeof(kCRLSetQUICSerialBlocked));
[email protected]66d9b6e32012-03-22 03:04:321286 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
1287
[email protected]d0ead382013-11-25 22:42:061288 error = Verify(leaf.get(),
1289 "test.example.com",
1290 flags,
[email protected]90499482013-06-01 00:39:501291 crl_set.get(),
1292 empty_cert_list_,
1293 &verify_result);
[email protected]66d9b6e32012-03-22 03:04:321294 EXPECT_EQ(ERR_CERT_REVOKED, error);
1295}
1296#endif
1297
1298struct WeakDigestTestData {
1299 const char* root_cert_filename;
1300 const char* intermediate_cert_filename;
1301 const char* ee_cert_filename;
1302 bool expected_has_md5;
1303 bool expected_has_md4;
1304 bool expected_has_md2;
[email protected]66d9b6e32012-03-22 03:04:321305};
1306
1307// GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
1308// to output the parameter that was passed. Without this, it will simply
1309// attempt to print out the first twenty bytes of the object, which depending
1310// on platform and alignment, may result in an invalid read.
1311void PrintTo(const WeakDigestTestData& data, std::ostream* os) {
1312 *os << "root: "
1313 << (data.root_cert_filename ? data.root_cert_filename : "none")
1314 << "; intermediate: " << data.intermediate_cert_filename
1315 << "; end-entity: " << data.ee_cert_filename;
1316}
1317
1318class CertVerifyProcWeakDigestTest
1319 : public CertVerifyProcTest,
1320 public testing::WithParamInterface<WeakDigestTestData> {
1321 public:
1322 CertVerifyProcWeakDigestTest() {}
1323 virtual ~CertVerifyProcWeakDigestTest() {}
1324};
1325
1326TEST_P(CertVerifyProcWeakDigestTest, Verify) {
1327 WeakDigestTestData data = GetParam();
[email protected]6cdfd7f2013-02-08 20:40:151328 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]66d9b6e32012-03-22 03:04:321329
1330 ScopedTestRoot test_root;
1331 if (data.root_cert_filename) {
1332 scoped_refptr<X509Certificate> root_cert =
1333 ImportCertFromFile(certs_dir, data.root_cert_filename);
1334 ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert);
[email protected]90499482013-06-01 00:39:501335 test_root.Reset(root_cert.get());
[email protected]66d9b6e32012-03-22 03:04:321336 }
1337
1338 scoped_refptr<X509Certificate> intermediate_cert =
1339 ImportCertFromFile(certs_dir, data.intermediate_cert_filename);
1340 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert);
1341 scoped_refptr<X509Certificate> ee_cert =
1342 ImportCertFromFile(certs_dir, data.ee_cert_filename);
1343 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert);
1344
1345 X509Certificate::OSCertHandles intermediates;
1346 intermediates.push_back(intermediate_cert->os_cert_handle());
1347
1348 scoped_refptr<X509Certificate> ee_chain =
1349 X509Certificate::CreateFromHandle(ee_cert->os_cert_handle(),
1350 intermediates);
1351 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_chain);
1352
1353 int flags = 0;
1354 CertVerifyResult verify_result;
[email protected]90499482013-06-01 00:39:501355 int rv = Verify(ee_chain.get(),
1356 "127.0.0.1",
1357 flags,
1358 NULL,
1359 empty_cert_list_,
1360 &verify_result);
[email protected]66d9b6e32012-03-22 03:04:321361 EXPECT_EQ(data.expected_has_md5, verify_result.has_md5);
1362 EXPECT_EQ(data.expected_has_md4, verify_result.has_md4);
1363 EXPECT_EQ(data.expected_has_md2, verify_result.has_md2);
[email protected]0d20bad2013-03-24 04:56:481364 EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor);
[email protected]66d9b6e32012-03-22 03:04:321365
1366 // Ensure that MD4 and MD2 are tagged as invalid.
1367 if (data.expected_has_md4 || data.expected_has_md2) {
1368 EXPECT_EQ(CERT_STATUS_INVALID,
1369 verify_result.cert_status & CERT_STATUS_INVALID);
1370 }
1371
1372 // Ensure that MD5 is flagged as weak.
1373 if (data.expected_has_md5) {
1374 EXPECT_EQ(
1375 CERT_STATUS_WEAK_SIGNATURE_ALGORITHM,
1376 verify_result.cert_status & CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
1377 }
1378
1379 // If a root cert is present, then check that the chain was rejected if any
1380 // weak algorithms are present. This is only checked when a root cert is
1381 // present because the error reported for incomplete chains with weak
1382 // algorithms depends on which implementation was used to validate (NSS,
1383 // OpenSSL, CryptoAPI, Security.framework) and upon which weak algorithm
1384 // present (MD2, MD4, MD5).
1385 if (data.root_cert_filename) {
1386 if (data.expected_has_md4 || data.expected_has_md2) {
1387 EXPECT_EQ(ERR_CERT_INVALID, rv);
1388 } else if (data.expected_has_md5) {
1389 EXPECT_EQ(ERR_CERT_WEAK_SIGNATURE_ALGORITHM, rv);
1390 } else {
1391 EXPECT_EQ(OK, rv);
1392 }
1393 }
1394}
1395
1396// Unlike TEST/TEST_F, which are macros that expand to further macros,
1397// INSTANTIATE_TEST_CASE_P is a macro that expands directly to code that
1398// stringizes the arguments. As a result, macros passed as parameters (such as
1399// prefix or test_case_name) will not be expanded by the preprocessor. To work
1400// around this, indirect the macro for INSTANTIATE_TEST_CASE_P, so that the
1401// pre-processor will expand macros such as MAYBE_test_name before
1402// instantiating the test.
1403#define WRAPPED_INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
1404 INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator)
1405
1406// The signature algorithm of the root CA should not matter.
1407const WeakDigestTestData kVerifyRootCATestData[] = {
1408 { "weak_digest_md5_root.pem", "weak_digest_sha1_intermediate.pem",
[email protected]4aba74c2013-06-28 01:35:501409 "weak_digest_sha1_ee.pem", false, false, false },
[email protected]e1b2d732014-03-28 16:20:321410#if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
[email protected]317dbc72012-04-03 18:45:141411 // MD4 is not supported by OS X / NSS
[email protected]66d9b6e32012-03-22 03:04:321412 { "weak_digest_md4_root.pem", "weak_digest_sha1_intermediate.pem",
[email protected]4aba74c2013-06-28 01:35:501413 "weak_digest_sha1_ee.pem", false, false, false },
[email protected]66d9b6e32012-03-22 03:04:321414#endif
1415 { "weak_digest_md2_root.pem", "weak_digest_sha1_intermediate.pem",
[email protected]4aba74c2013-06-28 01:35:501416 "weak_digest_sha1_ee.pem", false, false, false },
[email protected]66d9b6e32012-03-22 03:04:321417};
1418INSTANTIATE_TEST_CASE_P(VerifyRoot, CertVerifyProcWeakDigestTest,
1419 testing::ValuesIn(kVerifyRootCATestData));
1420
1421// The signature algorithm of intermediates should be properly detected.
1422const WeakDigestTestData kVerifyIntermediateCATestData[] = {
1423 { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
[email protected]4aba74c2013-06-28 01:35:501424 "weak_digest_sha1_ee.pem", true, false, false },
[email protected]e1b2d732014-03-28 16:20:321425#if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
[email protected]317dbc72012-04-03 18:45:141426 // MD4 is not supported by OS X / NSS
[email protected]66d9b6e32012-03-22 03:04:321427 { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
[email protected]4aba74c2013-06-28 01:35:501428 "weak_digest_sha1_ee.pem", false, true, false },
[email protected]66d9b6e32012-03-22 03:04:321429#endif
[email protected]66d9b6e32012-03-22 03:04:321430 { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
[email protected]4aba74c2013-06-28 01:35:501431 "weak_digest_sha1_ee.pem", false, false, true },
[email protected]66d9b6e32012-03-22 03:04:321432};
[email protected]fa2d3dc2012-11-20 07:58:441433// Disabled on NSS - MD4 is not supported, and MD2 and MD5 are disabled.
1434#if defined(USE_NSS) || defined(OS_IOS)
1435#define MAYBE_VerifyIntermediate DISABLED_VerifyIntermediate
1436#else
1437#define MAYBE_VerifyIntermediate VerifyIntermediate
1438#endif
1439WRAPPED_INSTANTIATE_TEST_CASE_P(
1440 MAYBE_VerifyIntermediate,
1441 CertVerifyProcWeakDigestTest,
1442 testing::ValuesIn(kVerifyIntermediateCATestData));
[email protected]66d9b6e32012-03-22 03:04:321443
1444// The signature algorithm of end-entity should be properly detected.
1445const WeakDigestTestData kVerifyEndEntityTestData[] = {
1446 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
[email protected]4aba74c2013-06-28 01:35:501447 "weak_digest_md5_ee.pem", true, false, false },
[email protected]e1b2d732014-03-28 16:20:321448#if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
[email protected]317dbc72012-04-03 18:45:141449 // MD4 is not supported by OS X / NSS
[email protected]66d9b6e32012-03-22 03:04:321450 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
[email protected]4aba74c2013-06-28 01:35:501451 "weak_digest_md4_ee.pem", false, true, false },
[email protected]66d9b6e32012-03-22 03:04:321452#endif
[email protected]66d9b6e32012-03-22 03:04:321453 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
[email protected]4aba74c2013-06-28 01:35:501454 "weak_digest_md2_ee.pem", false, false, true },
[email protected]66d9b6e32012-03-22 03:04:321455};
1456// Disabled on NSS - NSS caches chains/signatures in such a way that cannot
1457// be cleared until NSS is cleanly shutdown, which is not presently supported
1458// in Chromium.
[email protected]12b3c8822012-09-26 11:51:181459#if defined(USE_NSS) || defined(OS_IOS)
[email protected]66d9b6e32012-03-22 03:04:321460#define MAYBE_VerifyEndEntity DISABLED_VerifyEndEntity
1461#else
1462#define MAYBE_VerifyEndEntity VerifyEndEntity
1463#endif
1464WRAPPED_INSTANTIATE_TEST_CASE_P(MAYBE_VerifyEndEntity,
1465 CertVerifyProcWeakDigestTest,
1466 testing::ValuesIn(kVerifyEndEntityTestData));
1467
1468// Incomplete chains should still report the status of the intermediate.
1469const WeakDigestTestData kVerifyIncompleteIntermediateTestData[] = {
1470 { NULL, "weak_digest_md5_intermediate.pem", "weak_digest_sha1_ee.pem",
[email protected]4aba74c2013-06-28 01:35:501471 true, false, false },
[email protected]e1b2d732014-03-28 16:20:321472#if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
[email protected]317dbc72012-04-03 18:45:141473 // MD4 is not supported by OS X / NSS
[email protected]66d9b6e32012-03-22 03:04:321474 { NULL, "weak_digest_md4_intermediate.pem", "weak_digest_sha1_ee.pem",
[email protected]4aba74c2013-06-28 01:35:501475 false, true, false },
[email protected]66d9b6e32012-03-22 03:04:321476#endif
1477 { NULL, "weak_digest_md2_intermediate.pem", "weak_digest_sha1_ee.pem",
[email protected]4aba74c2013-06-28 01:35:501478 false, false, true },
[email protected]66d9b6e32012-03-22 03:04:321479};
1480// Disabled on NSS - libpkix does not return constructed chains on error,
1481// preventing us from detecting/inspecting the verified chain.
[email protected]12b3c8822012-09-26 11:51:181482#if defined(USE_NSS) || defined(OS_IOS)
[email protected]66d9b6e32012-03-22 03:04:321483#define MAYBE_VerifyIncompleteIntermediate \
1484 DISABLED_VerifyIncompleteIntermediate
1485#else
1486#define MAYBE_VerifyIncompleteIntermediate VerifyIncompleteIntermediate
1487#endif
1488WRAPPED_INSTANTIATE_TEST_CASE_P(
1489 MAYBE_VerifyIncompleteIntermediate,
1490 CertVerifyProcWeakDigestTest,
1491 testing::ValuesIn(kVerifyIncompleteIntermediateTestData));
1492
1493// Incomplete chains should still report the status of the end-entity.
1494const WeakDigestTestData kVerifyIncompleteEETestData[] = {
1495 { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md5_ee.pem",
[email protected]4aba74c2013-06-28 01:35:501496 true, false, false },
[email protected]e1b2d732014-03-28 16:20:321497#if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
[email protected]317dbc72012-04-03 18:45:141498 // MD4 is not supported by OS X / NSS
[email protected]66d9b6e32012-03-22 03:04:321499 { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md4_ee.pem",
[email protected]4aba74c2013-06-28 01:35:501500 false, true, false },
[email protected]66d9b6e32012-03-22 03:04:321501#endif
1502 { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md2_ee.pem",
[email protected]4aba74c2013-06-28 01:35:501503 false, false, true },
[email protected]66d9b6e32012-03-22 03:04:321504};
1505// Disabled on NSS - libpkix does not return constructed chains on error,
1506// preventing us from detecting/inspecting the verified chain.
[email protected]12b3c8822012-09-26 11:51:181507#if defined(USE_NSS) || defined(OS_IOS)
[email protected]66d9b6e32012-03-22 03:04:321508#define MAYBE_VerifyIncompleteEndEntity DISABLED_VerifyIncompleteEndEntity
1509#else
1510#define MAYBE_VerifyIncompleteEndEntity VerifyIncompleteEndEntity
1511#endif
1512WRAPPED_INSTANTIATE_TEST_CASE_P(
1513 MAYBE_VerifyIncompleteEndEntity,
1514 CertVerifyProcWeakDigestTest,
1515 testing::ValuesIn(kVerifyIncompleteEETestData));
1516
1517// Differing algorithms between the intermediate and the EE should still be
1518// reported.
1519const WeakDigestTestData kVerifyMixedTestData[] = {
1520 { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
[email protected]4aba74c2013-06-28 01:35:501521 "weak_digest_md2_ee.pem", true, false, true },
[email protected]66d9b6e32012-03-22 03:04:321522 { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
[email protected]4aba74c2013-06-28 01:35:501523 "weak_digest_md5_ee.pem", true, false, true },
[email protected]e1b2d732014-03-28 16:20:321524#if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
[email protected]317dbc72012-04-03 18:45:141525 // MD4 is not supported by OS X / NSS
[email protected]66d9b6e32012-03-22 03:04:321526 { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
[email protected]4aba74c2013-06-28 01:35:501527 "weak_digest_md2_ee.pem", false, true, true },
[email protected]66d9b6e32012-03-22 03:04:321528#endif
1529};
1530// NSS does not support MD4 and does not enable MD2 by default, making all
1531// permutations invalid.
[email protected]12b3c8822012-09-26 11:51:181532#if defined(USE_NSS) || defined(OS_IOS)
[email protected]66d9b6e32012-03-22 03:04:321533#define MAYBE_VerifyMixed DISABLED_VerifyMixed
1534#else
1535#define MAYBE_VerifyMixed VerifyMixed
1536#endif
1537WRAPPED_INSTANTIATE_TEST_CASE_P(
1538 MAYBE_VerifyMixed,
1539 CertVerifyProcWeakDigestTest,
1540 testing::ValuesIn(kVerifyMixedTestData));
1541
[email protected]6454e352013-08-16 23:56:531542// For the list of valid hostnames, see
1543// net/cert/data/ssl/certificates/subjectAltName_sanity_check.pem
1544static const struct CertVerifyProcNameData {
1545 const char* hostname;
1546 bool valid; // Whether or not |hostname| matches a subjectAltName.
1547} kVerifyNameData[] = {
1548 { "127.0.0.1", false }, // Don't match the common name
1549 { "127.0.0.2", true }, // Matches the iPAddress SAN (IPv4)
1550 { "FE80:0:0:0:0:0:0:1", true }, // Matches the iPAddress SAN (IPv6)
1551 { "[FE80:0:0:0:0:0:0:1]", false }, // Should not match the iPAddress SAN
1552 { "FE80::1", true }, // Compressed form matches the iPAddress SAN (IPv6)
1553 { "::127.0.0.2", false }, // IPv6 mapped form should NOT match iPAddress SAN
1554 { "test.example", true }, // Matches the dNSName SAN
1555 { "test.example.", true }, // Matches the dNSName SAN (trailing . ignored)
1556 { "www.test.example", false }, // Should not match the dNSName SAN
1557 { "test..example", false }, // Should not match the dNSName SAN
1558 { "test.example..", false }, // Should not match the dNSName SAN
1559 { ".test.example.", false }, // Should not match the dNSName SAN
1560 { ".test.example", false }, // Should not match the dNSName SAN
1561};
1562
1563// GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
1564// to output the parameter that was passed. Without this, it will simply
1565// attempt to print out the first twenty bytes of the object, which depending
1566// on platform and alignment, may result in an invalid read.
1567void PrintTo(const CertVerifyProcNameData& data, std::ostream* os) {
1568 *os << "Hostname: " << data.hostname << "; valid=" << data.valid;
1569}
1570
1571class CertVerifyProcNameTest
1572 : public CertVerifyProcTest,
1573 public testing::WithParamInterface<CertVerifyProcNameData> {
1574 public:
1575 CertVerifyProcNameTest() {}
1576 virtual ~CertVerifyProcNameTest() {}
1577};
1578
1579TEST_P(CertVerifyProcNameTest, VerifyCertName) {
1580 CertVerifyProcNameData data = GetParam();
1581
1582 CertificateList cert_list = CreateCertificateListFromFile(
1583 GetTestCertsDirectory(), "subjectAltName_sanity_check.pem",
1584 X509Certificate::FORMAT_AUTO);
1585 ASSERT_EQ(1U, cert_list.size());
1586 scoped_refptr<X509Certificate> cert(cert_list[0]);
1587
1588 ScopedTestRoot scoped_root(cert.get());
1589
1590 CertVerifyResult verify_result;
1591 int error = Verify(cert.get(), data.hostname, 0, NULL, empty_cert_list_,
1592 &verify_result);
1593 if (data.valid) {
1594 EXPECT_EQ(OK, error);
1595 EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_COMMON_NAME_INVALID);
1596 } else {
1597 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error);
1598 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_COMMON_NAME_INVALID);
1599 }
1600}
1601
1602WRAPPED_INSTANTIATE_TEST_CASE_P(
1603 VerifyName,
1604 CertVerifyProcNameTest,
1605 testing::ValuesIn(kVerifyNameData));
1606
[email protected]66d9b6e32012-03-22 03:04:321607} // namespace net