1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/common/net/x509_certificate_model.h"
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"
14 #include "crypto/scoped_test_nss_db.h"
15 #include "net/cert/nss_cert_database.h"
18 TEST(X509CertificateModelTest
, GetCertNameOrNicknameAndGetTitle
) {
19 scoped_refptr
<net::X509Certificate
> cert(
20 net::ImportCertFromFile(net::GetTestCertsDirectory(),
22 ASSERT_TRUE(cert
.get());
25 x509_certificate_model::GetCertNameOrNickname(cert
->os_cert_handle()));
27 scoped_refptr
<net::X509Certificate
> punycode_cert(
28 net::ImportCertFromFile(net::GetTestCertsDirectory(),
30 ASSERT_TRUE(punycode_cert
.get());
31 EXPECT_EQ("xn--wgv71a119e.com (日本語.com)",
32 x509_certificate_model::GetCertNameOrNickname(
33 punycode_cert
->os_cert_handle()));
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@google.com",
41 x509_certificate_model::GetCertNameOrNickname(
42 no_cn_cert
->os_cert_handle()));
44 // Temp cert has no nickname.
46 x509_certificate_model::GetCertNameOrNickname(
47 no_cn_cert
->os_cert_handle()));
50 EXPECT_EQ("xn--wgv71a119e.com",
51 x509_certificate_model::GetTitle(
52 punycode_cert
->os_cert_handle()));
54 #if defined(USE_OPENSSL)
55 EXPECT_EQ("emailAddress=wtc@google.com",
56 x509_certificate_model::GetTitle(
57 no_cn_cert
->os_cert_handle()));
59 EXPECT_EQ("E=wtc@google.com",
60 x509_certificate_model::GetTitle(
61 no_cn_cert
->os_cert_handle()));
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()));
71 TEST(X509CertificateModelTest
, GetExtensions
) {
73 scoped_refptr
<net::X509Certificate
> cert(net::ImportCertFromFile(
74 net::GetTestCertsDirectory(), "root_ca_cert.pem"));
75 ASSERT_TRUE(cert
.get());
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());
82 EXPECT_EQ("Certificate Basic Constraints", extensions
[0].name
);
84 "critical\nIs a Certification Authority\n"
85 "Maximum number of intermediate CAs: unlimited",
88 EXPECT_EQ("Certificate Subject Key ID", extensions
[1].name
);
90 "notcrit\nKey ID: BC F7 30 D1 3C C0 F2 79 FA EF 9F C9 6C 5C 93 F3\n8A "
94 EXPECT_EQ("Certificate Key Usage", extensions
[2].name
);
95 EXPECT_EQ("critical\nCertificate Signer\nCRL Signer", extensions
[2].value
);
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
);
107 "notcrit\nIP Address: 127.0.0.2\nIP Address: fe80::1\nDNS Name: "
108 "test.example\nEmail Address: test@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
);
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
);
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());
132 EXPECT_EQ("Certificate Subject Key ID", extensions
[0].name
);
134 "notcrit\nKey ID: 59 BC D9 69 F7 B0 65 BB C8 34 C5 D2 C2 EF 17 78\nA6 "
136 extensions
[0].value
);
138 EXPECT_EQ("Certification Authority Key ID", extensions
[1].name
);
140 "notcrit\nKey ID: 8A FC 14 1B 3D A3 59 67 A5 3B E1 73 92 A6 62 91\n7F "
142 extensions
[1].value
);
144 EXPECT_EQ("Authority Information Access", extensions
[2].name
);
146 "notcrit\nCA Issuers: "
147 "URI: http://secure.globalsign.net/cacert/SHA256extendval1.crt\n",
148 extensions
[2].value
);
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
);
154 EXPECT_EQ("Certificate Basic Constraints", extensions
[4].name
);
155 EXPECT_EQ("notcrit\nIs not a Certification Authority\n",
156 extensions
[4].value
);
158 EXPECT_EQ("Certificate Key Usage", extensions
[5].name
);
160 "critical\nSigning\nNon-repudiation\nKey Encipherment\n"
162 extensions
[5].value
);
164 EXPECT_EQ("Extended Key Usage", extensions
[6].name
);
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
);
170 EXPECT_EQ("Certificate Policies", extensions
[7].name
);
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
);
177 EXPECT_EQ("Netscape Certificate Type", extensions
[8].name
);
178 EXPECT_EQ("notcrit\nSSL Client Certificate\nSSL Server Certificate",
179 extensions
[8].value
);
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());
190 EXPECT_EQ("Authority Information Access", extensions
[0].name
);
192 "notcrit\nOCSP Responder: "
193 "URI: http://validation.diginotar.nl\n",
194 extensions
[0].value
);
196 EXPECT_EQ("Certificate Basic Constraints", extensions
[2].name
);
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
);
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"
207 " Conditions, as mentioned on our website (www.diginotar.nl), are "
208 "applicable to all our products and services.\n",
209 extensions
[3].value
);
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());
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()));
224 EXPECT_EQ(net::CA_CERT
,
225 x509_certificate_model::GetType(cert
->os_cert_handle()));
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 */);
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
));
238 EXPECT_EQ(net::CA_CERT
,
239 x509_certificate_model::GetType(cert
->os_cert_handle()));
243 TEST(X509CertificateModelTest
, GetTypeServer
) {
244 scoped_refptr
<net::X509Certificate
> cert(
245 net::ImportCertFromFile(net::GetTestCertsDirectory(),
246 "google.single.der"));
247 ASSERT_TRUE(cert
.get());
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()));
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()));
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 */);
267 // Test GetCertType with server certs and explicit trust.
268 EXPECT_TRUE(db
.SetCertTrust(
269 cert
.get(), net::SERVER_CERT
, net::NSSCertDatabase::TRUSTED_SSL
));
271 EXPECT_EQ(net::SERVER_CERT
,
272 x509_certificate_model::GetType(cert
->os_cert_handle()));
274 // Test GetCertType with server certs and explicit distrust.
275 EXPECT_TRUE(db
.SetCertTrust(
276 cert
.get(), net::SERVER_CERT
, net::NSSCertDatabase::DISTRUSTED_SSL
));
278 EXPECT_EQ(net::SERVER_CERT
,
279 x509_certificate_model::GetType(cert
->os_cert_handle()));
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(),
289 ASSERT_TRUE(cert
.get());
291 EXPECT_EQ("1", x509_certificate_model::GetVersion(cert
->os_cert_handle()));
294 TEST(X509CertificateModelTest
, GetCMSString
) {
295 net::CertificateList certs
=
296 CreateCertificateListFromFile(net::GetTestCertsDirectory(),
297 "multi-root-chain1.pem",
298 net::X509Certificate::FORMAT_AUTO
);
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());
306 // Write the full chain.
307 std::string pkcs7_string
= x509_certificate_model::GetCMSString(
308 cert_handles
, 0, cert_handles
.size());
310 ASSERT_FALSE(pkcs7_string
.empty());
312 net::CertificateList decoded_certs
=
313 net::X509Certificate::CreateCertificateListFromBytes(
316 net::X509Certificate::FORMAT_PKCS7
);
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
]));
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()));
331 // Write only the first cert.
332 std::string pkcs7_string
=
333 x509_certificate_model::GetCMSString(cert_handles
, 0, 1);
335 net::CertificateList decoded_certs
=
336 net::X509Certificate::CreateCertificateListFromBytes(
339 net::X509Certificate::FORMAT_PKCS7
);
341 ASSERT_EQ(1U, decoded_certs
.size());
342 EXPECT_TRUE(certs
[0]->Equals(decoded_certs
[0].get()));
346 TEST(X509CertificateModelTest
, ProcessSecAlgorithms
) {
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()));
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()));
377 TEST(X509CertificateModelTest
, ProcessSubjectPublicKeyInfo
) {
379 scoped_refptr
<net::X509Certificate
> cert(net::ImportCertFromFile(
380 net::GetTestCertsDirectory(), "root_ca_cert.pem"));
381 ASSERT_TRUE(cert
.get());
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"
401 #if defined(USE_OPENSSL)
402 " Public Exponent (17 bits):\n"
404 " Public Exponent (24 bits):\n"
407 x509_certificate_model::ProcessSubjectPublicKeyInfo(
408 cert
->os_cert_handle()));
411 scoped_refptr
<net::X509Certificate
> cert(net::ImportCertFromFile(
412 net::GetTestCertsDirectory(), "prime256v1-ecdsa-intermediate.pem"));
413 ASSERT_TRUE(cert
.get());
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"
420 x509_certificate_model::ProcessSubjectPublicKeyInfo(
421 cert
->os_cert_handle()));
425 TEST(X509CertificateModelTest
, ProcessRawBitsSignatureWrap
) {
426 scoped_refptr
<net::X509Certificate
> cert(net::ImportCertFromFile(
427 net::GetTestCertsDirectory(), "root_ca_cert.pem"));
428 ASSERT_TRUE(cert
.get());
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()));