1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <cert.h>
6#include <certdb.h>
7#include <pk11pub.h>
8
9#include <algorithm>
10
11#include "base/bind.h"
12#include "base/files/file_path.h"
13#include "base/files/file_util.h"
14#include "base/lazy_instance.h"
15#include "base/message_loop/message_loop.h"
16#include "base/message_loop/message_loop_proxy.h"
17#include "base/path_service.h"
18#include "base/run_loop.h"
19#include "base/strings/string16.h"
20#include "base/strings/string_util.h"
21#include "base/strings/utf_string_conversions.h"
22#include "crypto/scoped_nss_types.h"
23#include "crypto/scoped_test_nss_db.h"
24#include "net/base/crypto_module.h"
25#include "net/base/net_errors.h"
26#include "net/base/test_data_directory.h"
27#include "net/cert/cert_status_flags.h"
28#include "net/cert/cert_verify_proc_nss.h"
29#include "net/cert/cert_verify_result.h"
30#include "net/cert/nss_cert_database.h"
31#include "net/cert/x509_certificate.h"
32#include "net/test/cert_test_util.h"
33#include "net/third_party/mozilla_security_manager/nsNSSCertificateDB.h"
34#include "testing/gtest/include/gtest/gtest.h"
35
36// In NSS 3.13, CERTDB_VALID_PEER was renamed CERTDB_TERMINAL_RECORD. So we use
37// the new name of the macro.
38#if !defined(CERTDB_TERMINAL_RECORD)
39#define CERTDB_TERMINAL_RECORD CERTDB_VALID_PEER
40#endif
41
42using base::ASCIIToUTF16;
43
44namespace net {
45
46namespace {
47
48void SwapCertList(CertificateList* destination,
49                  scoped_ptr<CertificateList> source) {
50  ASSERT_TRUE(destination);
51  destination->swap(*source);
52}
53
54}  // namespace
55
56class CertDatabaseNSSTest : public testing::Test {
57 public:
58  virtual void SetUp() {
59    ASSERT_TRUE(test_nssdb_.is_open());
60    cert_db_.reset(new NSSCertDatabase(
61        crypto::ScopedPK11Slot(
62            PK11_ReferenceSlot(test_nssdb_.slot())) /* public slot */,
63        crypto::ScopedPK11Slot(
64            PK11_ReferenceSlot(test_nssdb_.slot())) /* private slot */));
65    public_module_ = cert_db_->GetPublicModule();
66
67    // Test db should be empty at start of test.
68    EXPECT_EQ(0U, ListCerts().size());
69  }
70
71  virtual void TearDown() {
72    // Run the message loop to process any observer callbacks (e.g. for the
73    // ClientSocketFactory singleton) so that the scoped ref ptrs created in
74    // NSSCertDatabase::NotifyObservers* get released.
75    base::MessageLoop::current()->RunUntilIdle();
76  }
77
78 protected:
79  net::CryptoModule* GetPublicModule() {
80    return public_module_.get();
81  }
82
83  static std::string ReadTestFile(const std::string& name) {
84    std::string result;
85    base::FilePath cert_path = GetTestCertsDirectory().AppendASCII(name);
86    EXPECT_TRUE(base::ReadFileToString(cert_path, &result));
87    return result;
88  }
89
90  static bool ReadCertIntoList(const std::string& name,
91                               CertificateList* certs) {
92    scoped_refptr<X509Certificate> cert(
93        ImportCertFromFile(GetTestCertsDirectory(), name));
94    if (!cert.get())
95      return false;
96
97    certs->push_back(cert);
98    return true;
99  }
100
101  CertificateList ListCerts() {
102    CertificateList result;
103    CERTCertList* cert_list = PK11_ListCertsInSlot(test_nssdb_.slot());
104    for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
105         !CERT_LIST_END(node, cert_list);
106         node = CERT_LIST_NEXT(node)) {
107      result.push_back(X509Certificate::CreateFromHandle(
108          node->cert, X509Certificate::OSCertHandles()));
109    }
110    CERT_DestroyCertList(cert_list);
111
112    // Sort the result so that test comparisons can be deterministic.
113    std::sort(result.begin(), result.end(), X509Certificate::LessThan());
114    return result;
115  }
116
117  scoped_ptr<NSSCertDatabase> cert_db_;
118  const CertificateList empty_cert_list_;
119  crypto::ScopedTestNSSDB test_nssdb_;
120  scoped_refptr<net::CryptoModule> public_module_;
121};
122
123TEST_F(CertDatabaseNSSTest, ListCertsSync) {
124  // This test isn't terribly useful, though it will at least let valgrind test
125  // for leaks.
126  CertificateList certs;
127  cert_db_->ListCertsSync(&certs);
128  // The test DB is empty, but let's assume there will always be something in
129  // the other slots.
130  EXPECT_LT(0U, certs.size());
131}
132
133TEST_F(CertDatabaseNSSTest, ListCerts) {
134  // This test isn't terribly useful, though it will at least let valgrind test
135  // for leaks.
136  CertificateList certs;
137  cert_db_->SetSlowTaskRunnerForTest(base::MessageLoopProxy::current());
138  cert_db_->ListCerts(base::Bind(&SwapCertList, base::Unretained(&certs)));
139  EXPECT_EQ(0U, certs.size());
140
141  base::RunLoop().RunUntilIdle();
142
143  // The test DB is empty, but let's assume there will always be something in
144  // the other slots.
145  EXPECT_LT(0U, certs.size());
146}
147
148TEST_F(CertDatabaseNSSTest, ImportFromPKCS12WrongPassword) {
149  std::string pkcs12_data = ReadTestFile("client.p12");
150
151  EXPECT_EQ(ERR_PKCS12_IMPORT_BAD_PASSWORD,
152            cert_db_->ImportFromPKCS12(GetPublicModule(),
153                                       pkcs12_data,
154                                       base::string16(),
155                                       true,  // is_extractable
156                                       NULL));
157
158  // Test db should still be empty.
159  EXPECT_EQ(0U, ListCerts().size());
160}
161
162TEST_F(CertDatabaseNSSTest, ImportFromPKCS12AsExtractableAndExportAgain) {
163  std::string pkcs12_data = ReadTestFile("client.p12");
164
165  EXPECT_EQ(OK,
166            cert_db_->ImportFromPKCS12(GetPublicModule(),
167                                       pkcs12_data,
168                                       ASCIIToUTF16("12345"),
169                                       true,  // is_extractable
170                                       NULL));
171
172  CertificateList cert_list = ListCerts();
173  ASSERT_EQ(1U, cert_list.size());
174  scoped_refptr<X509Certificate> cert(cert_list[0]);
175
176  EXPECT_EQ("testusercert",
177            cert->subject().common_name);
178
179  // TODO(mattm): move export test to separate test case?
180  std::string exported_data;
181  EXPECT_EQ(1, cert_db_->ExportToPKCS12(cert_list, ASCIIToUTF16("exportpw"),
182                                        &exported_data));
183  ASSERT_LT(0U, exported_data.size());
184  // TODO(mattm): further verification of exported data?
185}
186
187TEST_F(CertDatabaseNSSTest, ImportFromPKCS12Twice) {
188  std::string pkcs12_data = ReadTestFile("client.p12");
189
190  EXPECT_EQ(OK,
191            cert_db_->ImportFromPKCS12(GetPublicModule(),
192                                       pkcs12_data,
193                                       ASCIIToUTF16("12345"),
194                                       true,  // is_extractable
195                                       NULL));
196  EXPECT_EQ(1U, ListCerts().size());
197
198  // NSS has a SEC_ERROR_PKCS12_DUPLICATE_DATA error, but it doesn't look like
199  // it's ever used.  This test verifies that.
200  EXPECT_EQ(OK,
201            cert_db_->ImportFromPKCS12(GetPublicModule(),
202                                       pkcs12_data,
203                                       ASCIIToUTF16("12345"),
204                                       true,  // is_extractable
205                                       NULL));
206  EXPECT_EQ(1U, ListCerts().size());
207}
208
209TEST_F(CertDatabaseNSSTest, ImportFromPKCS12AsUnextractableAndExportAgain) {
210  std::string pkcs12_data = ReadTestFile("client.p12");
211
212  EXPECT_EQ(OK,
213            cert_db_->ImportFromPKCS12(GetPublicModule(),
214                                       pkcs12_data,
215                                       ASCIIToUTF16("12345"),
216                                       false,  // is_extractable
217                                       NULL));
218
219  CertificateList cert_list = ListCerts();
220  ASSERT_EQ(1U, cert_list.size());
221  scoped_refptr<X509Certificate> cert(cert_list[0]);
222
223  EXPECT_EQ("testusercert",
224            cert->subject().common_name);
225
226  std::string exported_data;
227  EXPECT_EQ(0, cert_db_->ExportToPKCS12(cert_list, ASCIIToUTF16("exportpw"),
228                                        &exported_data));
229}
230
231// Importing a PKCS#12 file with a certificate but no corresponding
232// private key should not mark an existing private key as unextractable.
233TEST_F(CertDatabaseNSSTest, ImportFromPKCS12OnlyMarkIncludedKey) {
234  std::string pkcs12_data = ReadTestFile("client.p12");
235  EXPECT_EQ(OK,
236            cert_db_->ImportFromPKCS12(GetPublicModule(),
237                                       pkcs12_data,
238                                       ASCIIToUTF16("12345"),
239                                       true,  // is_extractable
240                                       NULL));
241
242  CertificateList cert_list = ListCerts();
243  ASSERT_EQ(1U, cert_list.size());
244
245  // Now import a PKCS#12 file with just a certificate but no private key.
246  pkcs12_data = ReadTestFile("client-nokey.p12");
247  EXPECT_EQ(OK,
248            cert_db_->ImportFromPKCS12(GetPublicModule(),
249                                       pkcs12_data,
250                                       ASCIIToUTF16("12345"),
251                                       false,  // is_extractable
252                                       NULL));
253
254  cert_list = ListCerts();
255  ASSERT_EQ(1U, cert_list.size());
256
257  // Make sure the imported private key is still extractable.
258  std::string exported_data;
259  EXPECT_EQ(1, cert_db_->ExportToPKCS12(cert_list, ASCIIToUTF16("exportpw"),
260                                        &exported_data));
261  ASSERT_LT(0U, exported_data.size());
262}
263
264TEST_F(CertDatabaseNSSTest, ImportFromPKCS12InvalidFile) {
265  std::string pkcs12_data = "Foobarbaz";
266
267  EXPECT_EQ(ERR_PKCS12_IMPORT_INVALID_FILE,
268            cert_db_->ImportFromPKCS12(GetPublicModule(),
269                                       pkcs12_data,
270                                       base::string16(),
271                                       true,  // is_extractable
272                                       NULL));
273
274  // Test db should still be empty.
275  EXPECT_EQ(0U, ListCerts().size());
276}
277
278TEST_F(CertDatabaseNSSTest, ImportCACert_SSLTrust) {
279  CertificateList certs = CreateCertificateListFromFile(
280      GetTestCertsDirectory(), "root_ca_cert.pem",
281      X509Certificate::FORMAT_AUTO);
282  ASSERT_EQ(1U, certs.size());
283  EXPECT_FALSE(certs[0]->os_cert_handle()->isperm);
284
285  // Import it.
286  NSSCertDatabase::ImportCertFailureList failed;
287  EXPECT_TRUE(cert_db_->ImportCACerts(certs, NSSCertDatabase::TRUSTED_SSL,
288                                      &failed));
289
290  EXPECT_EQ(0U, failed.size());
291
292  CertificateList cert_list = ListCerts();
293  ASSERT_EQ(1U, cert_list.size());
294  scoped_refptr<X509Certificate> cert(cert_list[0]);
295  EXPECT_EQ("Test Root CA", cert->subject().common_name);
296
297  EXPECT_EQ(NSSCertDatabase::TRUSTED_SSL,
298            cert_db_->GetCertTrust(cert.get(), CA_CERT));
299
300  EXPECT_EQ(unsigned(CERTDB_VALID_CA | CERTDB_TRUSTED_CA |
301                     CERTDB_TRUSTED_CLIENT_CA),
302            cert->os_cert_handle()->trust->sslFlags);
303  EXPECT_EQ(unsigned(CERTDB_VALID_CA),
304            cert->os_cert_handle()->trust->emailFlags);
305  EXPECT_EQ(unsigned(CERTDB_VALID_CA),
306            cert->os_cert_handle()->trust->objectSigningFlags);
307}
308
309TEST_F(CertDatabaseNSSTest, ImportCACert_EmailTrust) {
310  CertificateList certs = CreateCertificateListFromFile(
311      GetTestCertsDirectory(), "root_ca_cert.pem",
312      X509Certificate::FORMAT_AUTO);
313  ASSERT_EQ(1U, certs.size());
314  EXPECT_FALSE(certs[0]->os_cert_handle()->isperm);
315
316  // Import it.
317  NSSCertDatabase::ImportCertFailureList failed;
318  EXPECT_TRUE(cert_db_->ImportCACerts(certs, NSSCertDatabase::TRUSTED_EMAIL,
319                                      &failed));
320
321  EXPECT_EQ(0U, failed.size());
322
323  CertificateList cert_list = ListCerts();
324  ASSERT_EQ(1U, cert_list.size());
325  scoped_refptr<X509Certificate> cert(cert_list[0]);
326  EXPECT_EQ("Test Root CA", cert->subject().common_name);
327
328  EXPECT_EQ(NSSCertDatabase::TRUSTED_EMAIL,
329            cert_db_->GetCertTrust(cert.get(), CA_CERT));
330
331  EXPECT_EQ(unsigned(CERTDB_VALID_CA),
332            cert->os_cert_handle()->trust->sslFlags);
333  EXPECT_EQ(unsigned(CERTDB_VALID_CA | CERTDB_TRUSTED_CA |
334                     CERTDB_TRUSTED_CLIENT_CA),
335            cert->os_cert_handle()->trust->emailFlags);
336  EXPECT_EQ(unsigned(CERTDB_VALID_CA),
337            cert->os_cert_handle()->trust->objectSigningFlags);
338}
339
340TEST_F(CertDatabaseNSSTest, ImportCACert_ObjSignTrust) {
341  CertificateList certs = CreateCertificateListFromFile(
342      GetTestCertsDirectory(), "root_ca_cert.pem",
343      X509Certificate::FORMAT_AUTO);
344  ASSERT_EQ(1U, certs.size());
345  EXPECT_FALSE(certs[0]->os_cert_handle()->isperm);
346
347  // Import it.
348  NSSCertDatabase::ImportCertFailureList failed;
349  EXPECT_TRUE(cert_db_->ImportCACerts(certs, NSSCertDatabase::TRUSTED_OBJ_SIGN,
350                                      &failed));
351
352  EXPECT_EQ(0U, failed.size());
353
354  CertificateList cert_list = ListCerts();
355  ASSERT_EQ(1U, cert_list.size());
356  scoped_refptr<X509Certificate> cert(cert_list[0]);
357  EXPECT_EQ("Test Root CA", cert->subject().common_name);
358
359  EXPECT_EQ(NSSCertDatabase::TRUSTED_OBJ_SIGN,
360            cert_db_->GetCertTrust(cert.get(), CA_CERT));
361
362  EXPECT_EQ(unsigned(CERTDB_VALID_CA),
363            cert->os_cert_handle()->trust->sslFlags);
364  EXPECT_EQ(unsigned(CERTDB_VALID_CA),
365            cert->os_cert_handle()->trust->emailFlags);
366  EXPECT_EQ(unsigned(CERTDB_VALID_CA | CERTDB_TRUSTED_CA |
367                     CERTDB_TRUSTED_CLIENT_CA),
368            cert->os_cert_handle()->trust->objectSigningFlags);
369}
370
371TEST_F(CertDatabaseNSSTest, ImportCA_NotCACert) {
372  CertificateList certs = CreateCertificateListFromFile(
373      GetTestCertsDirectory(), "ok_cert.pem",
374      X509Certificate::FORMAT_AUTO);
375  ASSERT_EQ(1U, certs.size());
376  EXPECT_FALSE(certs[0]->os_cert_handle()->isperm);
377
378  // Import it.
379  NSSCertDatabase::ImportCertFailureList failed;
380  EXPECT_TRUE(cert_db_->ImportCACerts(certs, NSSCertDatabase::TRUSTED_SSL,
381                                      &failed));
382  ASSERT_EQ(1U, failed.size());
383  // Note: this compares pointers directly.  It's okay in this case because
384  // ImportCACerts returns the same pointers that were passed in.  In the
385  // general case IsSameOSCert should be used.
386  EXPECT_EQ(certs[0], failed[0].certificate);
387  EXPECT_EQ(ERR_IMPORT_CA_CERT_NOT_CA, failed[0].net_error);
388
389  EXPECT_EQ(0U, ListCerts().size());
390}
391
392TEST_F(CertDatabaseNSSTest, ImportCACertHierarchy) {
393  CertificateList certs;
394  ASSERT_TRUE(ReadCertIntoList("dod_root_ca_2_cert.der", &certs));
395  ASSERT_TRUE(ReadCertIntoList("dod_ca_17_cert.der", &certs));
396  ASSERT_TRUE(ReadCertIntoList("www_us_army_mil_cert.der", &certs));
397
398  // Import it.
399  NSSCertDatabase::ImportCertFailureList failed;
400  // Have to specify email trust for the cert verification of the child cert to
401  // work (see
402  // http://mxr.mozilla.org/mozilla/source/security/nss/lib/certhigh/certvfy.c#752
403  // "XXX This choice of trustType seems arbitrary.")
404  EXPECT_TRUE(cert_db_->ImportCACerts(
405      certs, NSSCertDatabase::TRUSTED_SSL | NSSCertDatabase::TRUSTED_EMAIL,
406      &failed));
407
408  ASSERT_EQ(2U, failed.size());
409  EXPECT_EQ("DOD CA-17", failed[0].certificate->subject().common_name);
410  EXPECT_EQ(ERR_FAILED, failed[0].net_error);  // The certificate expired.
411  EXPECT_EQ("www.us.army.mil", failed[1].certificate->subject().common_name);
412  EXPECT_EQ(ERR_IMPORT_CA_CERT_NOT_CA, failed[1].net_error);
413
414  CertificateList cert_list = ListCerts();
415  ASSERT_EQ(1U, cert_list.size());
416  EXPECT_EQ("DoD Root CA 2", cert_list[0]->subject().common_name);
417}
418
419TEST_F(CertDatabaseNSSTest, ImportCACertHierarchyDupeRoot) {
420  CertificateList certs;
421  ASSERT_TRUE(ReadCertIntoList("dod_root_ca_2_cert.der", &certs));
422
423  // First import just the root.
424  NSSCertDatabase::ImportCertFailureList failed;
425  EXPECT_TRUE(cert_db_->ImportCACerts(
426      certs, NSSCertDatabase::TRUSTED_SSL | NSSCertDatabase::TRUSTED_EMAIL,
427      &failed));
428
429  EXPECT_EQ(0U, failed.size());
430  CertificateList cert_list = ListCerts();
431  ASSERT_EQ(1U, cert_list.size());
432  EXPECT_EQ("DoD Root CA 2", cert_list[0]->subject().common_name);
433
434  ASSERT_TRUE(ReadCertIntoList("dod_ca_17_cert.der", &certs));
435  ASSERT_TRUE(ReadCertIntoList("www_us_army_mil_cert.der", &certs));
436
437  // Now import with the other certs in the list too.  Even though the root is
438  // already present, we should still import the rest.
439  failed.clear();
440  EXPECT_TRUE(cert_db_->ImportCACerts(
441      certs, NSSCertDatabase::TRUSTED_SSL | NSSCertDatabase::TRUSTED_EMAIL,
442      &failed));
443
444  ASSERT_EQ(3U, failed.size());
445  EXPECT_EQ("DoD Root CA 2", failed[0].certificate->subject().common_name);
446  EXPECT_EQ(ERR_IMPORT_CERT_ALREADY_EXISTS, failed[0].net_error);
447  EXPECT_EQ("DOD CA-17", failed[1].certificate->subject().common_name);
448  EXPECT_EQ(ERR_FAILED, failed[1].net_error);  // The certificate expired.
449  EXPECT_EQ("www.us.army.mil", failed[2].certificate->subject().common_name);
450  EXPECT_EQ(ERR_IMPORT_CA_CERT_NOT_CA, failed[2].net_error);
451
452  cert_list = ListCerts();
453  ASSERT_EQ(1U, cert_list.size());
454  EXPECT_EQ("DoD Root CA 2", cert_list[0]->subject().common_name);
455}
456
457TEST_F(CertDatabaseNSSTest, ImportCACertHierarchyUntrusted) {
458  CertificateList certs;
459  ASSERT_TRUE(ReadCertIntoList("dod_root_ca_2_cert.der", &certs));
460  ASSERT_TRUE(ReadCertIntoList("dod_ca_17_cert.der", &certs));
461
462  // Import it.
463  NSSCertDatabase::ImportCertFailureList failed;
464  EXPECT_TRUE(cert_db_->ImportCACerts(certs, NSSCertDatabase::TRUST_DEFAULT,
465                                      &failed));
466
467  ASSERT_EQ(1U, failed.size());
468  EXPECT_EQ("DOD CA-17", failed[0].certificate->subject().common_name);
469  // TODO(mattm): should check for net error equivalent of
470  // SEC_ERROR_UNTRUSTED_ISSUER
471  EXPECT_EQ(ERR_FAILED, failed[0].net_error);
472
473  CertificateList cert_list = ListCerts();
474  ASSERT_EQ(1U, cert_list.size());
475  EXPECT_EQ("DoD Root CA 2", cert_list[0]->subject().common_name);
476}
477
478TEST_F(CertDatabaseNSSTest, ImportCACertHierarchyTree) {
479  CertificateList certs;
480  ASSERT_TRUE(ReadCertIntoList("dod_root_ca_2_cert.der", &certs));
481  ASSERT_TRUE(ReadCertIntoList("dod_ca_13_cert.der", &certs));
482  ASSERT_TRUE(ReadCertIntoList("dod_ca_17_cert.der", &certs));
483
484  // Import it.
485  NSSCertDatabase::ImportCertFailureList failed;
486  EXPECT_TRUE(cert_db_->ImportCACerts(
487      certs, NSSCertDatabase::TRUSTED_SSL | NSSCertDatabase::TRUSTED_EMAIL,
488      &failed));
489
490  EXPECT_EQ(2U, failed.size());
491  EXPECT_EQ("DOD CA-13", failed[0].certificate->subject().common_name);
492  EXPECT_EQ(ERR_FAILED, failed[0].net_error);  // The certificate expired.
493  EXPECT_EQ("DOD CA-17", failed[1].certificate->subject().common_name);
494  EXPECT_EQ(ERR_FAILED, failed[1].net_error);  // The certificate expired.
495
496  CertificateList cert_list = ListCerts();
497  ASSERT_EQ(1U, cert_list.size());
498  EXPECT_EQ("DoD Root CA 2", cert_list[0]->subject().common_name);
499}
500
501TEST_F(CertDatabaseNSSTest, ImportCACertNotHierarchy) {
502  CertificateList certs = CreateCertificateListFromFile(
503      GetTestCertsDirectory(), "root_ca_cert.pem",
504      X509Certificate::FORMAT_AUTO);
505  ASSERT_EQ(1U, certs.size());
506  ASSERT_TRUE(ReadCertIntoList("dod_ca_13_cert.der", &certs));
507  ASSERT_TRUE(ReadCertIntoList("dod_ca_17_cert.der", &certs));
508
509  // Import it.
510  NSSCertDatabase::ImportCertFailureList failed;
511  EXPECT_TRUE(cert_db_->ImportCACerts(
512      certs, NSSCertDatabase::TRUSTED_SSL | NSSCertDatabase::TRUSTED_EMAIL |
513      NSSCertDatabase::TRUSTED_OBJ_SIGN, &failed));
514
515  ASSERT_EQ(2U, failed.size());
516  // TODO(mattm): should check for net error equivalent of
517  // SEC_ERROR_UNKNOWN_ISSUER
518  EXPECT_EQ("DOD CA-13", failed[0].certificate->subject().common_name);
519  EXPECT_EQ(ERR_FAILED, failed[0].net_error);
520  EXPECT_EQ("DOD CA-17", failed[1].certificate->subject().common_name);
521  EXPECT_EQ(ERR_FAILED, failed[1].net_error);
522
523  CertificateList cert_list = ListCerts();
524  ASSERT_EQ(1U, cert_list.size());
525  EXPECT_EQ("Test Root CA", cert_list[0]->subject().common_name);
526}
527
528// http://crbug.com/108009 - Disabled, as google.chain.pem is an expired
529// certificate.
530TEST_F(CertDatabaseNSSTest, DISABLED_ImportServerCert) {
531  // Need to import intermediate cert for the verify of google cert, otherwise
532  // it will try to fetch it automatically with cert_pi_useAIACertFetch, which
533  // will cause OCSPCreateSession on the main thread, which is not allowed.
534  CertificateList certs = CreateCertificateListFromFile(
535      GetTestCertsDirectory(), "google.chain.pem",
536      X509Certificate::FORMAT_AUTO);
537  ASSERT_EQ(2U, certs.size());
538
539  NSSCertDatabase::ImportCertFailureList failed;
540  EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::TRUST_DEFAULT,
541                                         &failed));
542
543  EXPECT_EQ(0U, failed.size());
544
545  CertificateList cert_list = ListCerts();
546  ASSERT_EQ(2U, cert_list.size());
547  scoped_refptr<X509Certificate> goog_cert(cert_list[0]);
548  scoped_refptr<X509Certificate> thawte_cert(cert_list[1]);
549  EXPECT_EQ("www.google.com", goog_cert->subject().common_name);
550  EXPECT_EQ("Thawte SGC CA", thawte_cert->subject().common_name);
551
552  EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT,
553            cert_db_->GetCertTrust(goog_cert.get(), SERVER_CERT));
554
555  EXPECT_EQ(0U, goog_cert->os_cert_handle()->trust->sslFlags);
556
557  scoped_refptr<CertVerifyProc> verify_proc(new CertVerifyProcNSS());
558  int flags = 0;
559  CertVerifyResult verify_result;
560  int error = verify_proc->Verify(goog_cert.get(),
561                                  "www.google.com",
562                                  flags,
563                                  NULL,
564                                  empty_cert_list_,
565                                  &verify_result);
566  EXPECT_EQ(OK, error);
567  EXPECT_EQ(0U, verify_result.cert_status);
568}
569
570TEST_F(CertDatabaseNSSTest, ImportServerCert_SelfSigned) {
571  CertificateList certs;
572  ASSERT_TRUE(ReadCertIntoList("punycodetest.pem", &certs));
573
574  NSSCertDatabase::ImportCertFailureList failed;
575  EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::TRUST_DEFAULT,
576                                         &failed));
577
578  EXPECT_EQ(0U, failed.size());
579
580  CertificateList cert_list = ListCerts();
581  ASSERT_EQ(1U, cert_list.size());
582  scoped_refptr<X509Certificate> puny_cert(cert_list[0]);
583
584  EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT,
585            cert_db_->GetCertTrust(puny_cert.get(), SERVER_CERT));
586  EXPECT_EQ(0U, puny_cert->os_cert_handle()->trust->sslFlags);
587
588  scoped_refptr<CertVerifyProc> verify_proc(new CertVerifyProcNSS());
589  int flags = 0;
590  CertVerifyResult verify_result;
591  int error = verify_proc->Verify(puny_cert.get(),
592                                  "xn--wgv71a119e.com",
593                                  flags,
594                                  NULL,
595                                  empty_cert_list_,
596                                  &verify_result);
597  EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
598  EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status);
599}
600
601TEST_F(CertDatabaseNSSTest, ImportServerCert_SelfSigned_Trusted) {
602  CertificateList certs;
603  ASSERT_TRUE(ReadCertIntoList("punycodetest.pem", &certs));
604
605  NSSCertDatabase::ImportCertFailureList failed;
606  EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::TRUSTED_SSL,
607                                         &failed));
608
609  EXPECT_EQ(0U, failed.size());
610
611  CertificateList cert_list = ListCerts();
612  ASSERT_EQ(1U, cert_list.size());
613  scoped_refptr<X509Certificate> puny_cert(cert_list[0]);
614
615  EXPECT_EQ(NSSCertDatabase::TRUSTED_SSL,
616            cert_db_->GetCertTrust(puny_cert.get(), SERVER_CERT));
617  EXPECT_EQ(unsigned(CERTDB_TRUSTED | CERTDB_TERMINAL_RECORD),
618            puny_cert->os_cert_handle()->trust->sslFlags);
619
620  scoped_refptr<CertVerifyProc> verify_proc(new CertVerifyProcNSS());
621  int flags = 0;
622  CertVerifyResult verify_result;
623  int error = verify_proc->Verify(puny_cert.get(),
624                                  "xn--wgv71a119e.com",
625                                  flags,
626                                  NULL,
627                                  empty_cert_list_,
628                                  &verify_result);
629  EXPECT_EQ(OK, error);
630  EXPECT_EQ(0U, verify_result.cert_status);
631}
632
633TEST_F(CertDatabaseNSSTest, ImportCaAndServerCert) {
634  CertificateList ca_certs = CreateCertificateListFromFile(
635      GetTestCertsDirectory(), "root_ca_cert.pem",
636      X509Certificate::FORMAT_AUTO);
637  ASSERT_EQ(1U, ca_certs.size());
638
639  // Import CA cert and trust it.
640  NSSCertDatabase::ImportCertFailureList failed;
641  EXPECT_TRUE(cert_db_->ImportCACerts(ca_certs, NSSCertDatabase::TRUSTED_SSL,
642                                      &failed));
643  EXPECT_EQ(0U, failed.size());
644
645  CertificateList certs = CreateCertificateListFromFile(
646      GetTestCertsDirectory(), "ok_cert.pem",
647      X509Certificate::FORMAT_AUTO);
648  ASSERT_EQ(1U, certs.size());
649
650  // Import server cert with default trust.
651  EXPECT_TRUE(cert_db_->ImportServerCert(certs, NSSCertDatabase::TRUST_DEFAULT,
652                                         &failed));
653  EXPECT_EQ(0U, failed.size());
654
655  // Server cert should verify.
656  scoped_refptr<CertVerifyProc> verify_proc(new CertVerifyProcNSS());
657  int flags = 0;
658  CertVerifyResult verify_result;
659  int error = verify_proc->Verify(certs[0].get(),
660                                  "127.0.0.1",
661                                  flags,
662                                  NULL,
663                                  empty_cert_list_,
664                                  &verify_result);
665  EXPECT_EQ(OK, error);
666  EXPECT_EQ(0U, verify_result.cert_status);
667}
668
669TEST_F(CertDatabaseNSSTest, ImportCaAndServerCert_DistrustServer) {
670  CertificateList ca_certs = CreateCertificateListFromFile(
671      GetTestCertsDirectory(), "root_ca_cert.pem",
672      X509Certificate::FORMAT_AUTO);
673  ASSERT_EQ(1U, ca_certs.size());
674
675  // Import CA cert and trust it.
676  NSSCertDatabase::ImportCertFailureList failed;
677  EXPECT_TRUE(cert_db_->ImportCACerts(ca_certs, NSSCertDatabase::TRUSTED_SSL,
678                                      &failed));
679  EXPECT_EQ(0U, failed.size());
680
681  CertificateList certs = CreateCertificateListFromFile(
682      GetTestCertsDirectory(), "ok_cert.pem",
683      X509Certificate::FORMAT_AUTO);
684  ASSERT_EQ(1U, certs.size());
685
686  // Import server cert without inheriting trust from issuer (explicit
687  // distrust).
688  EXPECT_TRUE(cert_db_->ImportServerCert(
689      certs, NSSCertDatabase::DISTRUSTED_SSL, &failed));
690  EXPECT_EQ(0U, failed.size());
691  EXPECT_EQ(NSSCertDatabase::DISTRUSTED_SSL,
692            cert_db_->GetCertTrust(certs[0].get(), SERVER_CERT));
693
694  EXPECT_EQ(unsigned(CERTDB_TERMINAL_RECORD),
695            certs[0]->os_cert_handle()->trust->sslFlags);
696
697  // Server cert should fail to verify.
698  scoped_refptr<CertVerifyProc> verify_proc(new CertVerifyProcNSS());
699  int flags = 0;
700  CertVerifyResult verify_result;
701  int error = verify_proc->Verify(certs[0].get(),
702                                  "127.0.0.1",
703                                  flags,
704                                  NULL,
705                                  empty_cert_list_,
706                                  &verify_result);
707  EXPECT_EQ(ERR_CERT_REVOKED, error);
708  EXPECT_EQ(CERT_STATUS_REVOKED, verify_result.cert_status);
709}
710
711TEST_F(CertDatabaseNSSTest, TrustIntermediateCa) {
712  CertificateList ca_certs = CreateCertificateListFromFile(
713      GetTestCertsDirectory(), "2048-rsa-root.pem",
714      X509Certificate::FORMAT_AUTO);
715  ASSERT_EQ(1U, ca_certs.size());
716
717  // Import Root CA cert and distrust it.
718  NSSCertDatabase::ImportCertFailureList failed;
719  EXPECT_TRUE(cert_db_->ImportCACerts(ca_certs, NSSCertDatabase::DISTRUSTED_SSL,
720                                      &failed));
721  EXPECT_EQ(0U, failed.size());
722
723  CertificateList intermediate_certs = CreateCertificateListFromFile(
724      GetTestCertsDirectory(), "2048-rsa-intermediate.pem",
725      X509Certificate::FORMAT_AUTO);
726  ASSERT_EQ(1U, intermediate_certs.size());
727
728  // Import Intermediate CA cert and trust it.
729  EXPECT_TRUE(cert_db_->ImportCACerts(intermediate_certs,
730                                      NSSCertDatabase::TRUSTED_SSL, &failed));
731  EXPECT_EQ(0U, failed.size());
732
733  CertificateList certs = CreateCertificateListFromFile(
734      GetTestCertsDirectory(), "2048-rsa-ee-by-2048-rsa-intermediate.pem",
735      X509Certificate::FORMAT_AUTO);
736  ASSERT_EQ(1U, certs.size());
737
738  // Import server cert with default trust.
739  EXPECT_TRUE(cert_db_->ImportServerCert(
740      certs, NSSCertDatabase::TRUST_DEFAULT, &failed));
741  EXPECT_EQ(0U, failed.size());
742  EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT,
743            cert_db_->GetCertTrust(certs[0].get(), SERVER_CERT));
744
745  // Server cert should verify.
746  scoped_refptr<CertVerifyProc> verify_proc(new CertVerifyProcNSS());
747  int flags = 0;
748  CertVerifyResult verify_result;
749  int error = verify_proc->Verify(certs[0].get(),
750                                  "127.0.0.1",
751                                  flags,
752                                  NULL,
753                                  empty_cert_list_,
754                                  &verify_result);
755  EXPECT_EQ(OK, error);
756  EXPECT_EQ(0U, verify_result.cert_status);
757
758  // Trust the root cert and distrust the intermediate.
759  EXPECT_TRUE(cert_db_->SetCertTrust(
760      ca_certs[0].get(), CA_CERT, NSSCertDatabase::TRUSTED_SSL));
761  EXPECT_TRUE(cert_db_->SetCertTrust(
762      intermediate_certs[0].get(), CA_CERT, NSSCertDatabase::DISTRUSTED_SSL));
763  EXPECT_EQ(
764      unsigned(CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA),
765      ca_certs[0]->os_cert_handle()->trust->sslFlags);
766  EXPECT_EQ(unsigned(CERTDB_VALID_CA),
767            ca_certs[0]->os_cert_handle()->trust->emailFlags);
768  EXPECT_EQ(unsigned(CERTDB_VALID_CA),
769            ca_certs[0]->os_cert_handle()->trust->objectSigningFlags);
770  EXPECT_EQ(unsigned(CERTDB_TERMINAL_RECORD),
771            intermediate_certs[0]->os_cert_handle()->trust->sslFlags);
772  EXPECT_EQ(unsigned(CERTDB_VALID_CA),
773            intermediate_certs[0]->os_cert_handle()->trust->emailFlags);
774  EXPECT_EQ(
775      unsigned(CERTDB_VALID_CA),
776      intermediate_certs[0]->os_cert_handle()->trust->objectSigningFlags);
777
778  // Server cert should fail to verify.
779  CertVerifyResult verify_result2;
780  error = verify_proc->Verify(certs[0].get(),
781                              "127.0.0.1",
782                              flags,
783                              NULL,
784                              empty_cert_list_,
785                              &verify_result2);
786  EXPECT_EQ(ERR_CERT_REVOKED, error);
787  EXPECT_EQ(CERT_STATUS_REVOKED, verify_result2.cert_status);
788}
789
790TEST_F(CertDatabaseNSSTest, TrustIntermediateCa2) {
791  if (NSS_VersionCheck("3.14.2") && !NSS_VersionCheck("3.15")) {
792    // See http://bugzil.la/863947 for details.
793    LOG(INFO) << "Skipping test for NSS 3.14.2 - NSS 3.15";
794    return;
795  }
796
797  NSSCertDatabase::ImportCertFailureList failed;
798
799  CertificateList intermediate_certs = CreateCertificateListFromFile(
800      GetTestCertsDirectory(), "2048-rsa-intermediate.pem",
801      X509Certificate::FORMAT_AUTO);
802  ASSERT_EQ(1U, intermediate_certs.size());
803
804  // Import Intermediate CA cert and trust it.
805  EXPECT_TRUE(cert_db_->ImportCACerts(intermediate_certs,
806                                      NSSCertDatabase::TRUSTED_SSL, &failed));
807  EXPECT_EQ(0U, failed.size());
808
809  CertificateList certs = CreateCertificateListFromFile(
810      GetTestCertsDirectory(), "2048-rsa-ee-by-2048-rsa-intermediate.pem",
811      X509Certificate::FORMAT_AUTO);
812  ASSERT_EQ(1U, certs.size());
813
814  // Import server cert with default trust.
815  EXPECT_TRUE(cert_db_->ImportServerCert(
816      certs, NSSCertDatabase::TRUST_DEFAULT, &failed));
817  EXPECT_EQ(0U, failed.size());
818  EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT,
819            cert_db_->GetCertTrust(certs[0].get(), SERVER_CERT));
820
821  // Server cert should verify.
822  scoped_refptr<CertVerifyProc> verify_proc(new CertVerifyProcNSS());
823  int flags = 0;
824  CertVerifyResult verify_result;
825  int error = verify_proc->Verify(certs[0].get(),
826                                  "127.0.0.1",
827                                  flags,
828                                  NULL,
829                                  empty_cert_list_,
830                                  &verify_result);
831  EXPECT_EQ(OK, error);
832  EXPECT_EQ(0U, verify_result.cert_status);
833
834  // Without explicit trust of the intermediate, verification should fail.
835  EXPECT_TRUE(cert_db_->SetCertTrust(
836      intermediate_certs[0].get(), CA_CERT, NSSCertDatabase::TRUST_DEFAULT));
837
838  // Server cert should fail to verify.
839  CertVerifyResult verify_result2;
840  error = verify_proc->Verify(certs[0].get(),
841                              "127.0.0.1",
842                              flags,
843                              NULL,
844                              empty_cert_list_,
845                              &verify_result2);
846  EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
847  EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result2.cert_status);
848}
849
850TEST_F(CertDatabaseNSSTest, TrustIntermediateCa3) {
851  if (NSS_VersionCheck("3.14.2") && !NSS_VersionCheck("3.15")) {
852    // See http://bugzil.la/863947 for details.
853    LOG(INFO) << "Skipping test for NSS 3.14.2 - NSS 3.15";
854    return;
855  }
856
857  NSSCertDatabase::ImportCertFailureList failed;
858
859  CertificateList ca_certs = CreateCertificateListFromFile(
860      GetTestCertsDirectory(), "2048-rsa-root.pem",
861      X509Certificate::FORMAT_AUTO);
862  ASSERT_EQ(1U, ca_certs.size());
863
864  // Import Root CA cert and default trust it.
865  EXPECT_TRUE(cert_db_->ImportCACerts(ca_certs, NSSCertDatabase::TRUST_DEFAULT,
866                                      &failed));
867  EXPECT_EQ(0U, failed.size());
868
869  CertificateList intermediate_certs = CreateCertificateListFromFile(
870      GetTestCertsDirectory(), "2048-rsa-intermediate.pem",
871      X509Certificate::FORMAT_AUTO);
872  ASSERT_EQ(1U, intermediate_certs.size());
873
874  // Import Intermediate CA cert and trust it.
875  EXPECT_TRUE(cert_db_->ImportCACerts(intermediate_certs,
876                                      NSSCertDatabase::TRUSTED_SSL, &failed));
877  EXPECT_EQ(0U, failed.size());
878
879  CertificateList certs = CreateCertificateListFromFile(
880      GetTestCertsDirectory(), "2048-rsa-ee-by-2048-rsa-intermediate.pem",
881      X509Certificate::FORMAT_AUTO);
882  ASSERT_EQ(1U, certs.size());
883
884  // Import server cert with default trust.
885  EXPECT_TRUE(cert_db_->ImportServerCert(
886      certs, NSSCertDatabase::TRUST_DEFAULT, &failed));
887  EXPECT_EQ(0U, failed.size());
888  EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT,
889            cert_db_->GetCertTrust(certs[0].get(), SERVER_CERT));
890
891  // Server cert should verify.
892  scoped_refptr<CertVerifyProc> verify_proc(new CertVerifyProcNSS());
893  int flags = 0;
894  CertVerifyResult verify_result;
895  int error = verify_proc->Verify(certs[0].get(),
896                                  "127.0.0.1",
897                                  flags,
898                                  NULL,
899                                  empty_cert_list_,
900                                  &verify_result);
901  EXPECT_EQ(OK, error);
902  EXPECT_EQ(0U, verify_result.cert_status);
903
904  // Without explicit trust of the intermediate, verification should fail.
905  EXPECT_TRUE(cert_db_->SetCertTrust(
906      intermediate_certs[0].get(), CA_CERT, NSSCertDatabase::TRUST_DEFAULT));
907
908  // Server cert should fail to verify.
909  CertVerifyResult verify_result2;
910  error = verify_proc->Verify(certs[0].get(),
911                              "127.0.0.1",
912                              flags,
913                              NULL,
914                              empty_cert_list_,
915                              &verify_result2);
916  EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
917  EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result2.cert_status);
918}
919
920TEST_F(CertDatabaseNSSTest, TrustIntermediateCa4) {
921  NSSCertDatabase::ImportCertFailureList failed;
922
923  CertificateList ca_certs = CreateCertificateListFromFile(
924      GetTestCertsDirectory(), "2048-rsa-root.pem",
925      X509Certificate::FORMAT_AUTO);
926  ASSERT_EQ(1U, ca_certs.size());
927
928  // Import Root CA cert and trust it.
929  EXPECT_TRUE(cert_db_->ImportCACerts(ca_certs, NSSCertDatabase::TRUSTED_SSL,
930                                      &failed));
931  EXPECT_EQ(0U, failed.size());
932
933  CertificateList intermediate_certs = CreateCertificateListFromFile(
934      GetTestCertsDirectory(), "2048-rsa-intermediate.pem",
935      X509Certificate::FORMAT_AUTO);
936  ASSERT_EQ(1U, intermediate_certs.size());
937
938  // Import Intermediate CA cert and distrust it.
939  EXPECT_TRUE(cert_db_->ImportCACerts(
940        intermediate_certs, NSSCertDatabase::DISTRUSTED_SSL, &failed));
941  EXPECT_EQ(0U, failed.size());
942
943  CertificateList certs = CreateCertificateListFromFile(
944      GetTestCertsDirectory(), "2048-rsa-ee-by-2048-rsa-intermediate.pem",
945      X509Certificate::FORMAT_AUTO);
946  ASSERT_EQ(1U, certs.size());
947
948  // Import server cert with default trust.
949  EXPECT_TRUE(cert_db_->ImportServerCert(
950      certs, NSSCertDatabase::TRUST_DEFAULT, &failed));
951  EXPECT_EQ(0U, failed.size());
952  EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT,
953            cert_db_->GetCertTrust(certs[0].get(), SERVER_CERT));
954
955  // Server cert should not verify.
956  scoped_refptr<CertVerifyProc> verify_proc(new CertVerifyProcNSS());
957  int flags = 0;
958  CertVerifyResult verify_result;
959  int error = verify_proc->Verify(certs[0].get(),
960                                  "127.0.0.1",
961                                  flags,
962                                  NULL,
963                                  empty_cert_list_,
964                                  &verify_result);
965  EXPECT_EQ(ERR_CERT_REVOKED, error);
966  EXPECT_EQ(CERT_STATUS_REVOKED, verify_result.cert_status);
967
968  // Without explicit distrust of the intermediate, verification should succeed.
969  EXPECT_TRUE(cert_db_->SetCertTrust(
970      intermediate_certs[0].get(), CA_CERT, NSSCertDatabase::TRUST_DEFAULT));
971
972  // Server cert should verify.
973  CertVerifyResult verify_result2;
974  error = verify_proc->Verify(certs[0].get(),
975                              "127.0.0.1",
976                              flags,
977                              NULL,
978                              empty_cert_list_,
979                              &verify_result2);
980  EXPECT_EQ(OK, error);
981  EXPECT_EQ(0U, verify_result2.cert_status);
982}
983
984// Importing two certificates with the same issuer and subject common name,
985// but overall distinct subject names, should succeed and generate a unique
986// nickname for the second certificate.
987TEST_F(CertDatabaseNSSTest, ImportDuplicateCommonName) {
988  CertificateList certs =
989      CreateCertificateListFromFile(GetTestCertsDirectory(),
990                                    "duplicate_cn_1.pem",
991                                    X509Certificate::FORMAT_AUTO);
992  ASSERT_EQ(1U, certs.size());
993
994  EXPECT_EQ(0U, ListCerts().size());
995
996  // Import server cert with default trust.
997  NSSCertDatabase::ImportCertFailureList failed;
998  EXPECT_TRUE(cert_db_->ImportServerCert(
999      certs, NSSCertDatabase::TRUST_DEFAULT, &failed));
1000  EXPECT_EQ(0U, failed.size());
1001  EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT,
1002            cert_db_->GetCertTrust(certs[0].get(), SERVER_CERT));
1003
1004  CertificateList new_certs = ListCerts();
1005  ASSERT_EQ(1U, new_certs.size());
1006
1007  // Now attempt to import a different certificate with the same common name.
1008  CertificateList certs2 =
1009      CreateCertificateListFromFile(GetTestCertsDirectory(),
1010                                    "duplicate_cn_2.pem",
1011                                    X509Certificate::FORMAT_AUTO);
1012  ASSERT_EQ(1U, certs2.size());
1013
1014  // Import server cert with default trust.
1015  EXPECT_TRUE(cert_db_->ImportServerCert(
1016      certs2, NSSCertDatabase::TRUST_DEFAULT, &failed));
1017  EXPECT_EQ(0U, failed.size());
1018  EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT,
1019            cert_db_->GetCertTrust(certs2[0].get(), SERVER_CERT));
1020
1021  new_certs = ListCerts();
1022  ASSERT_EQ(2U, new_certs.size());
1023  EXPECT_STRNE(new_certs[0]->os_cert_handle()->nickname,
1024               new_certs[1]->os_cert_handle()->nickname);
1025}
1026
1027}  // namespace net
1028