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