Home | History | Annotate | Download | only in net
      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 "chrome/common/net/x509_certificate_model.h"
      6 
      7 #include "base/files/file_path.h"
      8 #include "base/path_service.h"
      9 #include "net/base/test_data_directory.h"
     10 #include "net/test/cert_test_util.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 
     13 #if defined(USE_NSS)
     14 #include "crypto/scoped_test_nss_db.h"
     15 #include "net/cert/nss_cert_database.h"
     16 #endif
     17 
     18 TEST(X509CertificateModelTest, GetCertNameOrNicknameAndGetTitle) {
     19   scoped_refptr<net::X509Certificate> cert(
     20       net::ImportCertFromFile(net::GetTestCertsDirectory(),
     21                               "root_ca_cert.pem"));
     22   ASSERT_TRUE(cert.get());
     23   EXPECT_EQ(
     24       "Test Root CA",
     25       x509_certificate_model::GetCertNameOrNickname(cert->os_cert_handle()));
     26 
     27   scoped_refptr<net::X509Certificate> punycode_cert(
     28       net::ImportCertFromFile(net::GetTestCertsDirectory(),
     29                               "punycodetest.pem"));
     30   ASSERT_TRUE(punycode_cert.get());
     31   EXPECT_EQ("xn--wgv71a119e.com (.com)",
     32             x509_certificate_model::GetCertNameOrNickname(
     33                 punycode_cert->os_cert_handle()));
     34 
     35   scoped_refptr<net::X509Certificate> no_cn_cert(
     36       net::ImportCertFromFile(net::GetTestCertsDirectory(),
     37                               "no_subject_common_name_cert.pem"));
     38   ASSERT_TRUE(no_cn_cert.get());
     39 #if defined(USE_OPENSSL)
     40   EXPECT_EQ("emailAddress=wtc (at) google.com",
     41             x509_certificate_model::GetCertNameOrNickname(
     42                 no_cn_cert->os_cert_handle()));
     43 #else
     44   // Temp cert has no nickname.
     45   EXPECT_EQ("",
     46             x509_certificate_model::GetCertNameOrNickname(
     47                 no_cn_cert->os_cert_handle()));
     48 #endif
     49 
     50   EXPECT_EQ("xn--wgv71a119e.com",
     51             x509_certificate_model::GetTitle(
     52                 punycode_cert->os_cert_handle()));
     53 
     54 #if defined(USE_OPENSSL)
     55   EXPECT_EQ("emailAddress=wtc (at) google.com",
     56             x509_certificate_model::GetTitle(
     57                 no_cn_cert->os_cert_handle()));
     58 #else
     59   EXPECT_EQ("E=wtc (at) google.com",
     60             x509_certificate_model::GetTitle(
     61                 no_cn_cert->os_cert_handle()));
     62 #endif
     63 
     64   scoped_refptr<net::X509Certificate> no_cn_cert2(net::ImportCertFromFile(
     65       net::GetTestCertsDirectory(), "ct-test-embedded-cert.pem"));
     66   ASSERT_TRUE(no_cn_cert2.get());
     67   EXPECT_EQ("L=Erw Wen,ST=Wales,O=Certificate Transparency,C=GB",
     68             x509_certificate_model::GetTitle(no_cn_cert2->os_cert_handle()));
     69 }
     70 
     71 TEST(X509CertificateModelTest, GetExtensions) {
     72   {
     73     scoped_refptr<net::X509Certificate> cert(net::ImportCertFromFile(
     74         net::GetTestCertsDirectory(), "root_ca_cert.pem"));
     75     ASSERT_TRUE(cert.get());
     76 
     77     x509_certificate_model::Extensions extensions;
     78     x509_certificate_model::GetExtensions(
     79         "critical", "notcrit", cert->os_cert_handle(), &extensions);
     80     ASSERT_EQ(3U, extensions.size());
     81 
     82     EXPECT_EQ("Certificate Basic Constraints", extensions[0].name);
     83     EXPECT_EQ(
     84         "critical\nIs a Certification Authority\n"
     85         "Maximum number of intermediate CAs: unlimited",
     86         extensions[0].value);
     87 
     88     EXPECT_EQ("Certificate Subject Key ID", extensions[1].name);
     89     EXPECT_EQ(
     90         "notcrit\nKey ID: BC F7 30 D1 3C C0 F2 79 FA EF 9F C9 6C 5C 93 F3\n8A "
     91         "68 AB 83",
     92         extensions[1].value);
     93 
     94     EXPECT_EQ("Certificate Key Usage", extensions[2].name);
     95     EXPECT_EQ("critical\nCertificate Signer\nCRL Signer", extensions[2].value);
     96   }
     97 
     98   {
     99     scoped_refptr<net::X509Certificate> cert(net::ImportCertFromFile(
    100         net::GetTestCertsDirectory(), "subjectAltName_sanity_check.pem"));
    101     x509_certificate_model::Extensions extensions;
    102     x509_certificate_model::GetExtensions(
    103         "critical", "notcrit", cert->os_cert_handle(), &extensions);
    104     ASSERT_EQ(2U, extensions.size());
    105     EXPECT_EQ("Certificate Subject Alternative Name", extensions[1].name);
    106     EXPECT_EQ(
    107         "notcrit\nIP Address: 127.0.0.2\nIP Address: fe80::1\nDNS Name: "
    108         "test.example\nEmail Address: test (at) test.example\nOID.1.2.3.4: 0C 09 69 "
    109         "67 6E 6F 72 65 20 6D 65\nX.500 Name: CN = 127.0.0.3\n\n",
    110         extensions[1].value);
    111   }
    112 
    113   {
    114     scoped_refptr<net::X509Certificate> cert(net::ImportCertFromFile(
    115         net::GetTestCertsDirectory(), "foaf.me.chromium-test-cert.der"));
    116     x509_certificate_model::Extensions extensions;
    117     x509_certificate_model::GetExtensions(
    118         "critical", "notcrit", cert->os_cert_handle(), &extensions);
    119     ASSERT_EQ(5U, extensions.size());
    120     EXPECT_EQ("Netscape Certificate Comment", extensions[1].name);
    121     EXPECT_EQ("notcrit\nOpenSSL Generated Certificate", extensions[1].value);
    122   }
    123 
    124   {
    125     scoped_refptr<net::X509Certificate> cert(net::ImportCertFromFile(
    126         net::GetTestCertsDirectory(), "2029_globalsign_com_cert.pem"));
    127     x509_certificate_model::Extensions extensions;
    128     x509_certificate_model::GetExtensions(
    129         "critical", "notcrit", cert->os_cert_handle(), &extensions);
    130     ASSERT_EQ(9U, extensions.size());
    131 
    132     EXPECT_EQ("Certificate Subject Key ID", extensions[0].name);
    133     EXPECT_EQ(
    134         "notcrit\nKey ID: 59 BC D9 69 F7 B0 65 BB C8 34 C5 D2 C2 EF 17 78\nA6 "
    135         "47 1E 8B",
    136         extensions[0].value);
    137 
    138     EXPECT_EQ("Certification Authority Key ID", extensions[1].name);
    139     EXPECT_EQ(
    140         "notcrit\nKey ID: 8A FC 14 1B 3D A3 59 67 A5 3B E1 73 92 A6 62 91\n7F "
    141         "E4 78 30\n",
    142         extensions[1].value);
    143 
    144     EXPECT_EQ("Authority Information Access", extensions[2].name);
    145     EXPECT_EQ(
    146         "notcrit\nCA Issuers: "
    147         "URI: http://secure.globalsign.net/cacert/SHA256extendval1.crt\n",
    148         extensions[2].value);
    149 
    150     EXPECT_EQ("CRL Distribution Points", extensions[3].name);
    151     EXPECT_EQ("notcrit\nURI: http://crl.globalsign.net/SHA256ExtendVal1.crl\n",
    152               extensions[3].value);
    153 
    154     EXPECT_EQ("Certificate Basic Constraints", extensions[4].name);
    155     EXPECT_EQ("notcrit\nIs not a Certification Authority\n",
    156               extensions[4].value);
    157 
    158     EXPECT_EQ("Certificate Key Usage", extensions[5].name);
    159     EXPECT_EQ(
    160         "critical\nSigning\nNon-repudiation\nKey Encipherment\n"
    161         "Data Encipherment",
    162         extensions[5].value);
    163 
    164     EXPECT_EQ("Extended Key Usage", extensions[6].name);
    165     EXPECT_EQ(
    166         "notcrit\nTLS WWW Server Authentication (OID.1.3.6.1.5.5.7.3.1)\n"
    167         "TLS WWW Client Authentication (OID.1.3.6.1.5.5.7.3.2)\n",
    168         extensions[6].value);
    169 
    170     EXPECT_EQ("Certificate Policies", extensions[7].name);
    171     EXPECT_EQ(
    172         "notcrit\nOID.1.3.6.1.4.1.4146.1.1:\n"
    173         "  Certification Practice Statement Pointer:"
    174         "    http://www.globalsign.net/repository/\n",
    175         extensions[7].value);
    176 
    177     EXPECT_EQ("Netscape Certificate Type", extensions[8].name);
    178     EXPECT_EQ("notcrit\nSSL Client Certificate\nSSL Server Certificate",
    179               extensions[8].value);
    180   }
    181 
    182   {
    183     scoped_refptr<net::X509Certificate> cert(net::ImportCertFromFile(
    184         net::GetTestCertsDirectory(), "diginotar_public_ca_2025.pem"));
    185     x509_certificate_model::Extensions extensions;
    186     x509_certificate_model::GetExtensions(
    187         "critical", "notcrit", cert->os_cert_handle(), &extensions);
    188     ASSERT_EQ(7U, extensions.size());
    189 
    190     EXPECT_EQ("Authority Information Access", extensions[0].name);
    191     EXPECT_EQ(
    192         "notcrit\nOCSP Responder: "
    193         "URI: http://validation.diginotar.nl\n",
    194         extensions[0].value);
    195 
    196     EXPECT_EQ("Certificate Basic Constraints", extensions[2].name);
    197     EXPECT_EQ(
    198         "critical\nIs a Certification Authority\n"
    199         "Maximum number of intermediate CAs: 0",
    200         extensions[2].value);
    201     EXPECT_EQ("Certificate Policies", extensions[3].name);
    202     EXPECT_EQ(
    203         "notcrit\nOID.2.16.528.1.1001.1.1.1.1.5.2.6.4:\n"
    204         "  Certification Practice Statement Pointer:"
    205         "    http://www.diginotar.nl/cps\n"
    206         "  User Notice:\n"
    207         "    Conditions, as mentioned on our website (www.diginotar.nl), are "
    208         "applicable to all our products and services.\n",
    209         extensions[3].value);
    210   }
    211 }
    212 
    213 TEST(X509CertificateModelTest, GetTypeCA) {
    214   scoped_refptr<net::X509Certificate> cert(
    215       net::ImportCertFromFile(net::GetTestCertsDirectory(),
    216                               "root_ca_cert.pem"));
    217   ASSERT_TRUE(cert.get());
    218 
    219 #if defined(USE_OPENSSL)
    220   // Remove this when OpenSSL build implements the necessary functions.
    221   EXPECT_EQ(net::OTHER_CERT,
    222             x509_certificate_model::GetType(cert->os_cert_handle()));
    223 #else
    224   EXPECT_EQ(net::CA_CERT,
    225             x509_certificate_model::GetType(cert->os_cert_handle()));
    226 
    227   crypto::ScopedTestNSSDB test_nssdb;
    228   net::NSSCertDatabase db(crypto::ScopedPK11Slot(PK11_ReferenceSlot(
    229                               test_nssdb.slot())) /* public slot */,
    230                           crypto::ScopedPK11Slot(PK11_ReferenceSlot(
    231                               test_nssdb.slot())) /* private slot */);
    232 
    233   // Test that explicitly distrusted CA certs are still returned as CA_CERT
    234   // type. See http://crbug.com/96654.
    235   EXPECT_TRUE(db.SetCertTrust(
    236       cert.get(), net::CA_CERT, net::NSSCertDatabase::DISTRUSTED_SSL));
    237 
    238   EXPECT_EQ(net::CA_CERT,
    239             x509_certificate_model::GetType(cert->os_cert_handle()));
    240 #endif
    241 }
    242 
    243 TEST(X509CertificateModelTest, GetTypeServer) {
    244   scoped_refptr<net::X509Certificate> cert(
    245       net::ImportCertFromFile(net::GetTestCertsDirectory(),
    246                               "google.single.der"));
    247   ASSERT_TRUE(cert.get());
    248 
    249 #if defined(USE_OPENSSL)
    250   // Remove this when OpenSSL build implements the necessary functions.
    251   EXPECT_EQ(net::OTHER_CERT,
    252             x509_certificate_model::GetType(cert->os_cert_handle()));
    253 #else
    254   // Test mozilla_security_manager::GetCertType with server certs and default
    255   // trust.  Currently this doesn't work.
    256   // TODO(mattm): make mozilla_security_manager::GetCertType smarter so we can
    257   // tell server certs even if they have no trust bits set.
    258   EXPECT_EQ(net::OTHER_CERT,
    259             x509_certificate_model::GetType(cert->os_cert_handle()));
    260 
    261   crypto::ScopedTestNSSDB test_nssdb;
    262   net::NSSCertDatabase db(crypto::ScopedPK11Slot(PK11_ReferenceSlot(
    263                               test_nssdb.slot())) /* public slot */,
    264                           crypto::ScopedPK11Slot(PK11_ReferenceSlot(
    265                               test_nssdb.slot())) /* private slot */);
    266 
    267   // Test GetCertType with server certs and explicit trust.
    268   EXPECT_TRUE(db.SetCertTrust(
    269       cert.get(), net::SERVER_CERT, net::NSSCertDatabase::TRUSTED_SSL));
    270 
    271   EXPECT_EQ(net::SERVER_CERT,
    272             x509_certificate_model::GetType(cert->os_cert_handle()));
    273 
    274   // Test GetCertType with server certs and explicit distrust.
    275   EXPECT_TRUE(db.SetCertTrust(
    276       cert.get(), net::SERVER_CERT, net::NSSCertDatabase::DISTRUSTED_SSL));
    277 
    278   EXPECT_EQ(net::SERVER_CERT,
    279             x509_certificate_model::GetType(cert->os_cert_handle()));
    280 #endif
    281 }
    282 
    283 // An X.509 v1 certificate with the version field omitted should get
    284 // the default value v1.
    285 TEST(X509CertificateModelTest, GetVersionOmitted) {
    286   scoped_refptr<net::X509Certificate> cert(
    287       net::ImportCertFromFile(net::GetTestCertsDirectory(),
    288                               "ndn.ca.crt"));
    289   ASSERT_TRUE(cert.get());
    290 
    291   EXPECT_EQ("1", x509_certificate_model::GetVersion(cert->os_cert_handle()));
    292 }
    293 
    294 TEST(X509CertificateModelTest, GetCMSString) {
    295   net::CertificateList certs =
    296       CreateCertificateListFromFile(net::GetTestCertsDirectory(),
    297                                     "multi-root-chain1.pem",
    298                                     net::X509Certificate::FORMAT_AUTO);
    299 
    300   net::X509Certificate::OSCertHandles cert_handles;
    301   for (net::CertificateList::iterator i = certs.begin(); i != certs.end(); ++i)
    302     cert_handles.push_back((*i)->os_cert_handle());
    303   ASSERT_EQ(4U, cert_handles.size());
    304 
    305   {
    306     // Write the full chain.
    307     std::string pkcs7_string = x509_certificate_model::GetCMSString(
    308         cert_handles, 0, cert_handles.size());
    309 
    310     ASSERT_FALSE(pkcs7_string.empty());
    311 
    312     net::CertificateList decoded_certs =
    313         net::X509Certificate::CreateCertificateListFromBytes(
    314             pkcs7_string.data(),
    315             pkcs7_string.size(),
    316             net::X509Certificate::FORMAT_PKCS7);
    317 
    318     ASSERT_EQ(certs.size(), decoded_certs.size());
    319 #if defined(USE_OPENSSL)
    320     for (size_t i = 0; i < certs.size(); ++i)
    321       EXPECT_TRUE(certs[i]->Equals(decoded_certs[i]));
    322 #else
    323     // NSS sorts the certs before writing the file.
    324     EXPECT_TRUE(certs[0]->Equals(decoded_certs.back().get()));
    325     for (size_t i = 1; i < certs.size(); ++i)
    326       EXPECT_TRUE(certs[i]->Equals(decoded_certs[i - 1].get()));
    327 #endif
    328   }
    329 
    330   {
    331     // Write only the first cert.
    332     std::string pkcs7_string =
    333         x509_certificate_model::GetCMSString(cert_handles, 0, 1);
    334 
    335     net::CertificateList decoded_certs =
    336         net::X509Certificate::CreateCertificateListFromBytes(
    337             pkcs7_string.data(),
    338             pkcs7_string.size(),
    339             net::X509Certificate::FORMAT_PKCS7);
    340 
    341     ASSERT_EQ(1U, decoded_certs.size());
    342     EXPECT_TRUE(certs[0]->Equals(decoded_certs[0].get()));
    343   }
    344 }
    345 
    346 TEST(X509CertificateModelTest, ProcessSecAlgorithms) {
    347   {
    348     scoped_refptr<net::X509Certificate> cert(net::ImportCertFromFile(
    349         net::GetTestCertsDirectory(), "root_ca_cert.pem"));
    350     ASSERT_TRUE(cert.get());
    351     EXPECT_EQ("PKCS #1 SHA-1 With RSA Encryption",
    352               x509_certificate_model::ProcessSecAlgorithmSignature(
    353                   cert->os_cert_handle()));
    354     EXPECT_EQ("PKCS #1 SHA-1 With RSA Encryption",
    355               x509_certificate_model::ProcessSecAlgorithmSignatureWrap(
    356                   cert->os_cert_handle()));
    357     EXPECT_EQ("PKCS #1 RSA Encryption",
    358               x509_certificate_model::ProcessSecAlgorithmSubjectPublicKey(
    359                   cert->os_cert_handle()));
    360   }
    361   {
    362     scoped_refptr<net::X509Certificate> cert(net::ImportCertFromFile(
    363         net::GetTestCertsDirectory(), "weak_digest_md5_root.pem"));
    364     ASSERT_TRUE(cert.get());
    365     EXPECT_EQ("PKCS #1 MD5 With RSA Encryption",
    366               x509_certificate_model::ProcessSecAlgorithmSignature(
    367                   cert->os_cert_handle()));
    368     EXPECT_EQ("PKCS #1 MD5 With RSA Encryption",
    369               x509_certificate_model::ProcessSecAlgorithmSignatureWrap(
    370                   cert->os_cert_handle()));
    371     EXPECT_EQ("PKCS #1 RSA Encryption",
    372               x509_certificate_model::ProcessSecAlgorithmSubjectPublicKey(
    373                   cert->os_cert_handle()));
    374   }
    375 }
    376 
    377 TEST(X509CertificateModelTest, ProcessSubjectPublicKeyInfo) {
    378   {
    379     scoped_refptr<net::X509Certificate> cert(net::ImportCertFromFile(
    380         net::GetTestCertsDirectory(), "root_ca_cert.pem"));
    381     ASSERT_TRUE(cert.get());
    382     EXPECT_EQ(
    383         "Modulus (2048 bits):\n"
    384         "  B6 49 41 E3 42 01 51 A8 7F 3C 7A 71 D3 FB CD 91\n"
    385         "35 17 84 1A 8E F6 36 C7 D1 70 1D FA 86 F3 6E BB\n"
    386         "76 6F E8 32 2E 37 FD 38 92 3D 68 E4 8A 7D 42 33\n"
    387         "14 46 1B DC 04 F6 91 6E 54 40 C4 0A 09 FD EC 2D\n"
    388         "62 E2 5E E1 BA 2C 9C C1 B1 60 4C DA C7 F8 22 5C\n"
    389         "82 20 65 42 1E 56 77 75 4F EB 90 2C 4A EA 57 0E\n"
    390         "22 8D 6C 95 AC 11 EA CC D7 EE F6 70 0D 09 DD A6\n"
    391         "35 61 5D C9 76 6D B0 F2 1E BF 30 86 D8 77 52 36\n"
    392         "95 97 0E D1 46 C5 ED 81 3D 1B B0 F2 61 95 3C C1\n"
    393         "40 38 EF 5F 5D BA 61 9F EF 2B 9C 9F 85 89 74 70\n"
    394         "63 D5 76 E8 35 7E CE 01 E1 F3 11 11 90 1C 0D F5\n"
    395         "FD 8D CE 10 6C AD 7C 55 1A 21 6F D7 2D F4 78 15\n"
    396         "EA 2F 38 BD 91 9E 3C 1D 07 46 F5 43 C1 82 8B AF\n"
    397         "12 53 65 19 8A 69 69 66 06 B2 DA 0B FA 2A 00 A1\n"
    398         "2A 15 84 49 F1 01 BF 9B 30 06 D0 15 A0 1F 9D 51\n"
    399         "91 47 E1 53 5F EF 5E EC C2 61 79 C2 14 9F C4 E3\n"
    400         "\n"
    401 #if defined(USE_OPENSSL)
    402         "  Public Exponent (17 bits):\n"
    403 #else
    404         "  Public Exponent (24 bits):\n"
    405 #endif
    406         "  01 00 01",
    407         x509_certificate_model::ProcessSubjectPublicKeyInfo(
    408             cert->os_cert_handle()));
    409   }
    410   {
    411     scoped_refptr<net::X509Certificate> cert(net::ImportCertFromFile(
    412         net::GetTestCertsDirectory(), "prime256v1-ecdsa-intermediate.pem"));
    413     ASSERT_TRUE(cert.get());
    414     EXPECT_EQ(
    415         "04 DB 98 07 BC 61 DD 2D E6 B3 CC F7 D5 EA F7 A1\n"
    416         "0D 28 DE F2 7C 26 97 CA EB D1 DB A3 1E C1 8F E9\n"
    417         "E0 1E FE 31 BB AA 4A 5C 85 37 A6 FF 9E 2E 96 23\n"
    418         "22 B8 30 5F 8F 22 AE B9 8B 6D 4F BD 4E F3 52 12\n"
    419         "D4",
    420         x509_certificate_model::ProcessSubjectPublicKeyInfo(
    421             cert->os_cert_handle()));
    422   }
    423 }
    424 
    425 TEST(X509CertificateModelTest, ProcessRawBitsSignatureWrap) {
    426   scoped_refptr<net::X509Certificate> cert(net::ImportCertFromFile(
    427       net::GetTestCertsDirectory(), "root_ca_cert.pem"));
    428   ASSERT_TRUE(cert.get());
    429   EXPECT_EQ(
    430       "57 07 29 FB 7F E8 FF B0 E6 D8 58 6A C3 90 A1 38\n"
    431       "1C B4 F3 68 B1 EC E8 89 23 24 D7 A8 F2 21 C3 60\n"
    432       "E4 A4 49 5C 00 BF DF C7 82 78 80 2B 18 F7 AD DD\n"
    433       "D0 62 5E A7 B0 CC F0 AA B4 CE 70 12 59 65 67 76\n"
    434       "05 00 18 9A FF C4 2A 17 E3 F1 55 D8 BE 5C 5E EB\n"
    435       "CA CB 53 87 10 D5 09 32 36 A7 5E 41 F4 53 DA 7E\n"
    436       "56 60 D2 7E 4E 9A A5 08 5F 5D 75 E9 E7 30 CB 22\n"
    437       "E9 EF 19 49 83 A5 23 A1 F8 60 4C E5 36 D5 39 78\n"
    438       "18 F1 5E BF CE AA 0B 53 81 2C 78 A9 0A 6B DB 13\n"
    439       "10 21 14 7F 1B 70 3D 89 1A 40 8A 06 2C 5D 50 19\n"
    440       "62 F9 C7 45 89 F2 3D 66 05 3D 7D 75 5B 55 1E 80\n"
    441       "42 72 A1 9A 7C 6D 0A 74 F6 EE A6 21 6C 3A 98 FB\n"
    442       "77 82 5F F2 6B 56 E6 DD 9B 8E 50 F0 C6 AE FD EA\n"
    443       "A6 05 07 A9 26 06 56 B3 B2 D9 B2 37 A0 21 3E 79\n"
    444       "06 1F B9 51 BE F4 B1 49 4D 90 B5 33 E5 0E C7 5E\n"
    445       "5B 40 C5 6A 04 D1 43 7A 94 6A A4 4F 61 FC 82 E0",
    446       x509_certificate_model::ProcessRawBitsSignatureWrap(
    447           cert->os_cert_handle()));
    448 }
    449