1 // Copyright 2012 The Chromium Authors
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 "net/cert/x509_certificate.h"
6
7 #include <stdint.h>
8
9 #include <memory>
10
11 #include "base/files/file_path.h"
12 #include "base/files/file_util.h"
13 #include "base/hash/sha1.h"
14 #include "base/pickle.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_split.h"
17 #include "base/strings/string_util.h"
18 #include "base/time/time.h"
19 #include "crypto/rsa_private_key.h"
20 #include "net/base/net_errors.h"
21 #include "net/cert/asn1_util.h"
22 #include "net/cert/pem.h"
23 #include "net/cert/pki/parse_certificate.h"
24 #include "net/cert/x509_util.h"
25 #include "net/test/cert_builder.h"
26 #include "net/test/cert_test_util.h"
27 #include "net/test/test_certificate_data.h"
28 #include "net/test/test_data_directory.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30
31 using base::HexEncode;
32 using base::Time;
33
34 namespace net {
35
36 // Certificates for test data. They're obtained with:
37 //
38 // $ openssl s_client -connect [host]:443 -showcerts > /tmp/host.pem < /dev/null
39 // $ openssl x509 -inform PEM -outform DER < /tmp/host.pem > /tmp/host.der
40 //
41 // For fingerprint
42 // $ openssl x509 -inform DER -fingerprint -noout < /tmp/host.der
43
44 // For valid_start, valid_expiry
45 // $ openssl x509 -inform DER -text -noout < /tmp/host.der |
46 // grep -A 2 Validity
47 // $ date +%s -d '<date str>'
48
49 // Google's cert.
50 SHA256HashValue google_fingerprint = {
51 {0x21, 0xaf, 0x58, 0x74, 0xea, 0x6b, 0xad, 0xbd, 0xe4, 0xb3, 0xb1,
52 0xaa, 0x53, 0x32, 0x80, 0x8f, 0xbf, 0x8a, 0x24, 0x7d, 0x98, 0xec,
53 0x7f, 0x77, 0x49, 0x38, 0x42, 0x81, 0x26, 0x7f, 0xed, 0x38}};
54
55 // The fingerprint of the Google certificate used in the parsing tests,
56 // which is newer than the one included in the x509_certificate_data.h
57 SHA256HashValue google_parse_fingerprint = {
58 {0xf6, 0x41, 0xc3, 0x6c, 0xfe, 0xf4, 0x9b, 0xc0, 0x71, 0x35, 0x9e,
59 0xcf, 0x88, 0xee, 0xd9, 0x31, 0x7b, 0x73, 0x8b, 0x59, 0x89, 0x41,
60 0x6a, 0xd4, 0x01, 0x72, 0x0c, 0x0a, 0x4e, 0x2e, 0x63, 0x52}};
61
62 // The fingerprint for the Thawte SGC certificate
63 SHA256HashValue thawte_parse_fingerprint = {
64 {0x10, 0x85, 0xa6, 0xf4, 0x54, 0xd0, 0xc9, 0x11, 0x98, 0xfd, 0xda,
65 0xb1, 0x1a, 0x31, 0xc7, 0x16, 0xd5, 0xdc, 0xd6, 0x8d, 0xf9, 0x1c,
66 0x03, 0x9c, 0xe1, 0x8d, 0xca, 0x9b, 0xeb, 0x3c, 0xde, 0x3d}};
67
68 // Dec 18 00:00:00 2009 GMT
69 const double kGoogleParseValidFrom = 1261094400;
70 // Dec 18 23:59:59 2011 GMT
71 const double kGoogleParseValidTo = 1324252799;
72
CheckGoogleCert(const scoped_refptr<X509Certificate> & google_cert,const SHA256HashValue & expected_fingerprint,double valid_from,double valid_to)73 void CheckGoogleCert(const scoped_refptr<X509Certificate>& google_cert,
74 const SHA256HashValue& expected_fingerprint,
75 double valid_from,
76 double valid_to) {
77 ASSERT_NE(static_cast<X509Certificate*>(nullptr), google_cert.get());
78
79 const CertPrincipal& subject = google_cert->subject();
80 EXPECT_EQ("www.google.com", subject.common_name);
81 EXPECT_EQ("Mountain View", subject.locality_name);
82 EXPECT_EQ("California", subject.state_or_province_name);
83 EXPECT_EQ("US", subject.country_name);
84 EXPECT_EQ(0U, subject.street_addresses.size());
85 ASSERT_EQ(1U, subject.organization_names.size());
86 EXPECT_EQ("Google Inc", subject.organization_names[0]);
87 EXPECT_EQ(0U, subject.organization_unit_names.size());
88 EXPECT_EQ(0U, subject.domain_components.size());
89
90 const CertPrincipal& issuer = google_cert->issuer();
91 EXPECT_EQ("Thawte SGC CA", issuer.common_name);
92 EXPECT_EQ("", issuer.locality_name);
93 EXPECT_EQ("", issuer.state_or_province_name);
94 EXPECT_EQ("ZA", issuer.country_name);
95 EXPECT_EQ(0U, issuer.street_addresses.size());
96 ASSERT_EQ(1U, issuer.organization_names.size());
97 EXPECT_EQ("Thawte Consulting (Pty) Ltd.", issuer.organization_names[0]);
98 EXPECT_EQ(0U, issuer.organization_unit_names.size());
99 EXPECT_EQ(0U, issuer.domain_components.size());
100
101 // Use DoubleT because its epoch is the same on all platforms
102 const Time& valid_start = google_cert->valid_start();
103 EXPECT_EQ(valid_from, valid_start.ToDoubleT());
104
105 const Time& valid_expiry = google_cert->valid_expiry();
106 EXPECT_EQ(valid_to, valid_expiry.ToDoubleT());
107
108 EXPECT_EQ(expected_fingerprint, X509Certificate::CalculateFingerprint256(
109 google_cert->cert_buffer()));
110
111 }
112
TEST(X509CertificateTest,GoogleCertParsing)113 TEST(X509CertificateTest, GoogleCertParsing) {
114 scoped_refptr<X509Certificate> google_cert(
115 X509Certificate::CreateFromBytes(google_der));
116
117 CheckGoogleCert(google_cert, google_fingerprint,
118 1238192407, // Mar 27 22:20:07 2009 GMT
119 1269728407); // Mar 27 22:20:07 2010 GMT
120 }
121
TEST(X509CertificateTest,WebkitCertParsing)122 TEST(X509CertificateTest, WebkitCertParsing) {
123 scoped_refptr<X509Certificate> webkit_cert(
124 X509Certificate::CreateFromBytes(webkit_der));
125
126 ASSERT_NE(static_cast<X509Certificate*>(nullptr), webkit_cert.get());
127
128 const CertPrincipal& subject = webkit_cert->subject();
129 EXPECT_EQ("Cupertino", subject.locality_name);
130 EXPECT_EQ("California", subject.state_or_province_name);
131 EXPECT_EQ("US", subject.country_name);
132 EXPECT_EQ(0U, subject.street_addresses.size());
133 ASSERT_EQ(1U, subject.organization_names.size());
134 EXPECT_EQ("Apple Inc.", subject.organization_names[0]);
135 ASSERT_EQ(1U, subject.organization_unit_names.size());
136 EXPECT_EQ("Mac OS Forge", subject.organization_unit_names[0]);
137 EXPECT_EQ(0U, subject.domain_components.size());
138
139 const CertPrincipal& issuer = webkit_cert->issuer();
140 EXPECT_EQ("Go Daddy Secure Certification Authority", issuer.common_name);
141 EXPECT_EQ("Scottsdale", issuer.locality_name);
142 EXPECT_EQ("Arizona", issuer.state_or_province_name);
143 EXPECT_EQ("US", issuer.country_name);
144 EXPECT_EQ(0U, issuer.street_addresses.size());
145 ASSERT_EQ(1U, issuer.organization_names.size());
146 EXPECT_EQ("GoDaddy.com, Inc.", issuer.organization_names[0]);
147 ASSERT_EQ(1U, issuer.organization_unit_names.size());
148 EXPECT_EQ("http://certificates.godaddy.com/repository",
149 issuer.organization_unit_names[0]);
150 EXPECT_EQ(0U, issuer.domain_components.size());
151
152 // Use DoubleT because its epoch is the same on all platforms
153 const Time& valid_start = webkit_cert->valid_start();
154 EXPECT_EQ(1205883319, valid_start.ToDoubleT()); // Mar 18 23:35:19 2008 GMT
155
156 const Time& valid_expiry = webkit_cert->valid_expiry();
157 EXPECT_EQ(1300491319, valid_expiry.ToDoubleT()); // Mar 18 23:35:19 2011 GMT
158
159 std::vector<std::string> dns_names;
160 EXPECT_TRUE(webkit_cert->GetSubjectAltName(&dns_names, nullptr));
161 ASSERT_EQ(2U, dns_names.size());
162 EXPECT_EQ("*.webkit.org", dns_names[0]);
163 EXPECT_EQ("webkit.org", dns_names[1]);
164
165 // Test that the wildcard cert matches properly.
166 EXPECT_TRUE(webkit_cert->VerifyNameMatch("www.webkit.org"));
167 EXPECT_TRUE(webkit_cert->VerifyNameMatch("foo.webkit.org"));
168 EXPECT_TRUE(webkit_cert->VerifyNameMatch("webkit.org"));
169 EXPECT_FALSE(webkit_cert->VerifyNameMatch("www.webkit.com"));
170 EXPECT_FALSE(webkit_cert->VerifyNameMatch("www.foo.webkit.com"));
171 }
172
TEST(X509CertificateTest,ThawteCertParsing)173 TEST(X509CertificateTest, ThawteCertParsing) {
174 scoped_refptr<X509Certificate> thawte_cert(
175 X509Certificate::CreateFromBytes(thawte_der));
176
177 ASSERT_NE(static_cast<X509Certificate*>(nullptr), thawte_cert.get());
178
179 const CertPrincipal& subject = thawte_cert->subject();
180 EXPECT_EQ("www.thawte.com", subject.common_name);
181 EXPECT_EQ("Mountain View", subject.locality_name);
182 EXPECT_EQ("California", subject.state_or_province_name);
183 EXPECT_EQ("US", subject.country_name);
184 EXPECT_EQ(0U, subject.street_addresses.size());
185 ASSERT_EQ(1U, subject.organization_names.size());
186 EXPECT_EQ("Thawte Inc", subject.organization_names[0]);
187 EXPECT_EQ(0U, subject.organization_unit_names.size());
188 EXPECT_EQ(0U, subject.domain_components.size());
189
190 const CertPrincipal& issuer = thawte_cert->issuer();
191 EXPECT_EQ("thawte Extended Validation SSL CA", issuer.common_name);
192 EXPECT_EQ("", issuer.locality_name);
193 EXPECT_EQ("", issuer.state_or_province_name);
194 EXPECT_EQ("US", issuer.country_name);
195 EXPECT_EQ(0U, issuer.street_addresses.size());
196 ASSERT_EQ(1U, issuer.organization_names.size());
197 EXPECT_EQ("thawte, Inc.", issuer.organization_names[0]);
198 ASSERT_EQ(1U, issuer.organization_unit_names.size());
199 EXPECT_EQ("Terms of use at https://www.thawte.com/cps (c)06",
200 issuer.organization_unit_names[0]);
201 EXPECT_EQ(0U, issuer.domain_components.size());
202
203 // Use DoubleT because its epoch is the same on all platforms
204 const Time& valid_start = thawte_cert->valid_start();
205 EXPECT_EQ(1227052800, valid_start.ToDoubleT()); // Nov 19 00:00:00 2008 GMT
206
207 const Time& valid_expiry = thawte_cert->valid_expiry();
208 EXPECT_EQ(1263772799, valid_expiry.ToDoubleT()); // Jan 17 23:59:59 2010 GMT
209 }
210
211 // Test that all desired AttributeAndValue pairs can be extracted when only
212 // a single RelativeDistinguishedName is present. "Normally" there is only
213 // one AVA per RDN, but some CAs place all AVAs within a single RDN.
214 // This is a regression test for http://crbug.com/101009
TEST(X509CertificateTest,MultivalueRDN)215 TEST(X509CertificateTest, MultivalueRDN) {
216 base::FilePath certs_dir = GetTestCertsDirectory();
217
218 scoped_refptr<X509Certificate> multivalue_rdn_cert =
219 ImportCertFromFile(certs_dir, "multivalue_rdn.pem");
220 ASSERT_NE(static_cast<X509Certificate*>(nullptr), multivalue_rdn_cert.get());
221
222 const CertPrincipal& subject = multivalue_rdn_cert->subject();
223 EXPECT_EQ("Multivalue RDN Test", subject.common_name);
224 EXPECT_EQ("", subject.locality_name);
225 EXPECT_EQ("", subject.state_or_province_name);
226 EXPECT_EQ("US", subject.country_name);
227 EXPECT_EQ(0U, subject.street_addresses.size());
228 ASSERT_EQ(1U, subject.organization_names.size());
229 EXPECT_EQ("Chromium", subject.organization_names[0]);
230 ASSERT_EQ(1U, subject.organization_unit_names.size());
231 EXPECT_EQ("Chromium net_unittests", subject.organization_unit_names[0]);
232 ASSERT_EQ(1U, subject.domain_components.size());
233 EXPECT_EQ("Chromium", subject.domain_components[0]);
234 }
235
236 // Test that characters which would normally be escaped in the string form,
237 // such as '=' or '"', are not escaped when parsed as individual components.
238 // This is a regression test for http://crbug.com/102839
TEST(X509CertificateTest,UnescapedSpecialCharacters)239 TEST(X509CertificateTest, UnescapedSpecialCharacters) {
240 base::FilePath certs_dir = GetTestCertsDirectory();
241
242 scoped_refptr<X509Certificate> unescaped_cert =
243 ImportCertFromFile(certs_dir, "unescaped.pem");
244 ASSERT_NE(static_cast<X509Certificate*>(nullptr), unescaped_cert.get());
245
246 const CertPrincipal& subject = unescaped_cert->subject();
247 EXPECT_EQ("127.0.0.1", subject.common_name);
248 EXPECT_EQ("Mountain View", subject.locality_name);
249 EXPECT_EQ("California", subject.state_or_province_name);
250 EXPECT_EQ("US", subject.country_name);
251 ASSERT_EQ(1U, subject.street_addresses.size());
252 EXPECT_EQ("1600 Amphitheatre Parkway", subject.street_addresses[0]);
253 ASSERT_EQ(1U, subject.organization_names.size());
254 EXPECT_EQ("Chromium = \"net_unittests\"", subject.organization_names[0]);
255 ASSERT_EQ(2U, subject.organization_unit_names.size());
256 EXPECT_EQ("net_unittests", subject.organization_unit_names[0]);
257 EXPECT_EQ("Chromium", subject.organization_unit_names[1]);
258 EXPECT_EQ(0U, subject.domain_components.size());
259 }
260
TEST(X509CertificateTest,InvalidPrintableStringIsUtf8)261 TEST(X509CertificateTest, InvalidPrintableStringIsUtf8) {
262 base::FilePath certs_dir =
263 GetTestNetDataDirectory().AppendASCII("parse_certificate_unittest");
264
265 std::string file_data;
266 ASSERT_TRUE(base::ReadFileToString(
267 certs_dir.AppendASCII(
268 "subject_printable_string_containing_utf8_client_cert.pem"),
269 &file_data));
270
271 net::PEMTokenizer pem_tokenizer(file_data, {"CERTIFICATE"});
272 ASSERT_TRUE(pem_tokenizer.GetNext());
273 std::string cert_der(pem_tokenizer.data());
274 ASSERT_FALSE(pem_tokenizer.GetNext());
275
276 bssl::UniquePtr<CRYPTO_BUFFER> cert_handle =
277 x509_util::CreateCryptoBuffer(cert_der);
278 ASSERT_TRUE(cert_handle);
279
280 EXPECT_FALSE(
281 X509Certificate::CreateFromBuffer(bssl::UpRef(cert_handle.get()), {}));
282
283 X509Certificate::UnsafeCreateOptions options;
284 options.printable_string_is_utf8 = true;
285 scoped_refptr<X509Certificate> cert =
286 X509Certificate::CreateFromBufferUnsafeOptions(
287 bssl::UpRef(cert_handle.get()), {}, options);
288
289 const CertPrincipal& subject = cert->subject();
290 EXPECT_EQ("Foo@#_ Clïênt Cërt", subject.common_name);
291 }
292
TEST(X509CertificateTest,TeletexStringIsLatin1)293 TEST(X509CertificateTest, TeletexStringIsLatin1) {
294 base::FilePath certs_dir =
295 GetTestNetDataDirectory().AppendASCII("parse_certificate_unittest");
296
297 scoped_refptr<X509Certificate> cert =
298 ImportCertFromFile(certs_dir, "subject_t61string.pem");
299 ASSERT_TRUE(cert);
300
301 const CertPrincipal& subject = cert->subject();
302 EXPECT_EQ(
303 " !\"#$%&'()*+,-./"
304 "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`"
305 "abcdefghijklmnopqrstuvwxyz{|}~"
306 " ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæç"
307 "èéêëìíîïðñòóôõö÷øùúûüýþÿ",
308 subject.organization_names[0]);
309 }
310
TEST(X509CertificateTest,TeletexStringControlChars)311 TEST(X509CertificateTest, TeletexStringControlChars) {
312 base::FilePath certs_dir =
313 GetTestNetDataDirectory().AppendASCII("parse_certificate_unittest");
314
315 scoped_refptr<X509Certificate> cert =
316 ImportCertFromFile(certs_dir, "subject_t61string_1-32.pem");
317 ASSERT_TRUE(cert);
318
319 const CertPrincipal& subject = cert->subject();
320 EXPECT_EQ(
321 "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12"
322 "\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20",
323 subject.organization_names[0]);
324 }
325
TEST(X509CertificateTest,TeletexStringIsLatin1NotCp1252)326 TEST(X509CertificateTest, TeletexStringIsLatin1NotCp1252) {
327 base::FilePath certs_dir =
328 GetTestNetDataDirectory().AppendASCII("parse_certificate_unittest");
329
330 scoped_refptr<X509Certificate> cert =
331 ImportCertFromFile(certs_dir, "subject_t61string_126-160.pem");
332 ASSERT_TRUE(cert);
333
334 const CertPrincipal& subject = cert->subject();
335 // TeletexString is decoded as latin1, so 127-160 get decoded to equivalent
336 // unicode control chars.
337 EXPECT_EQ(
338 "~\x7F\xC2\x80\xC2\x81\xC2\x82\xC2\x83\xC2\x84\xC2\x85\xC2\x86\xC2\x87"
339 "\xC2\x88\xC2\x89\xC2\x8A\xC2\x8B\xC2\x8C\xC2\x8D\xC2\x8E\xC2\x8F\xC2\x90"
340 "\xC2\x91\xC2\x92\xC2\x93\xC2\x94\xC2\x95\xC2\x96\xC2\x97\xC2\x98\xC2\x99"
341 "\xC2\x9A\xC2\x9B\xC2\x9C\xC2\x9D\xC2\x9E\xC2\x9F\xC2\xA0",
342 subject.organization_names[0]);
343 }
344
TEST(X509CertificateTest,TeletexStringIsNotARealT61String)345 TEST(X509CertificateTest, TeletexStringIsNotARealT61String) {
346 base::FilePath certs_dir =
347 GetTestNetDataDirectory().AppendASCII("parse_certificate_unittest");
348
349 scoped_refptr<X509Certificate> cert =
350 ImportCertFromFile(certs_dir, "subject_t61string_actual.pem");
351 ASSERT_TRUE(cert);
352
353 const CertPrincipal& subject = cert->subject();
354 // If TeletexStrings were actually parsed according to T.61, this would be
355 // "あ". (Probably. Not verified against a real implementation.)
356 EXPECT_EQ("\x1B$@$\"", subject.organization_names[0]);
357 }
358
TEST(X509CertificateTest,SerialNumbers)359 TEST(X509CertificateTest, SerialNumbers) {
360 scoped_refptr<X509Certificate> google_cert(
361 X509Certificate::CreateFromBytes(google_der));
362 ASSERT_TRUE(google_cert);
363
364 static const uint8_t google_serial[16] = {
365 0x01,0x2a,0x39,0x76,0x0d,0x3f,0x4f,0xc9,
366 0x0b,0xe7,0xbd,0x2b,0xcf,0x95,0x2e,0x7a,
367 };
368
369 ASSERT_EQ(sizeof(google_serial), google_cert->serial_number().size());
370 EXPECT_TRUE(memcmp(google_cert->serial_number().data(), google_serial,
371 sizeof(google_serial)) == 0);
372 }
373
TEST(X509CertificateTest,SerialNumberZeroPadded)374 TEST(X509CertificateTest, SerialNumberZeroPadded) {
375 base::FilePath certs_dir =
376 GetTestNetDataDirectory().AppendASCII("parse_certificate_unittest");
377 scoped_refptr<X509Certificate> cert =
378 ImportCertFromFile(certs_dir, "serial_zero_padded.pem");
379 ASSERT_TRUE(cert);
380
381 // Check a serial number where the first byte is >= 0x80, the DER returned by
382 // serial() should contain the leading 0 padding byte.
383 static const uint8_t expected_serial[3] = {0x00, 0x80, 0x01};
384 ASSERT_EQ(sizeof(expected_serial), cert->serial_number().size());
385 EXPECT_TRUE(memcmp(cert->serial_number().data(), expected_serial,
386 sizeof(expected_serial)) == 0);
387 }
388
TEST(X509CertificateTest,SerialNumberZeroPadded21BytesLong)389 TEST(X509CertificateTest, SerialNumberZeroPadded21BytesLong) {
390 base::FilePath certs_dir =
391 GetTestNetDataDirectory().AppendASCII("parse_certificate_unittest");
392 scoped_refptr<X509Certificate> cert =
393 ImportCertFromFile(certs_dir, "serial_zero_padded_21_bytes.pem");
394 ASSERT_TRUE(cert);
395
396 // Check a serial number where the first byte is >= 0x80, causing the encoded
397 // length to be 21 bytes long. This should be an error, but serial number
398 // parsing is currently permissive.
399 static const uint8_t expected_serial[21] = {
400 0x00, 0x80, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
401 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13};
402 ASSERT_EQ(sizeof(expected_serial), cert->serial_number().size());
403 EXPECT_TRUE(memcmp(cert->serial_number().data(), expected_serial,
404 sizeof(expected_serial)) == 0);
405 }
406
TEST(X509CertificateTest,SerialNumberNegative)407 TEST(X509CertificateTest, SerialNumberNegative) {
408 base::FilePath certs_dir =
409 GetTestNetDataDirectory().AppendASCII("parse_certificate_unittest");
410 scoped_refptr<X509Certificate> cert =
411 ImportCertFromFile(certs_dir, "serial_negative.pem");
412 ASSERT_TRUE(cert);
413
414 // RFC 5280 does not allow serial numbers to be negative, but serial number
415 // parsing is currently permissive, so this does not cause an error.
416 static const uint8_t expected_serial[2] = {0x80, 0x01};
417 ASSERT_EQ(sizeof(expected_serial), cert->serial_number().size());
418 EXPECT_TRUE(memcmp(cert->serial_number().data(), expected_serial,
419 sizeof(expected_serial)) == 0);
420 }
421
TEST(X509CertificateTest,SerialNumber37BytesLong)422 TEST(X509CertificateTest, SerialNumber37BytesLong) {
423 base::FilePath certs_dir =
424 GetTestNetDataDirectory().AppendASCII("parse_certificate_unittest");
425 scoped_refptr<X509Certificate> cert =
426 ImportCertFromFile(certs_dir, "serial_37_bytes.pem");
427 ASSERT_TRUE(cert);
428
429 // Check a serial number which is very long. This should be an error, but
430 // serial number parsing is currently permissive.
431 static const uint8_t expected_serial[37] = {
432 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
433 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
434 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
435 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25};
436 ASSERT_EQ(sizeof(expected_serial), cert->serial_number().size());
437 EXPECT_TRUE(memcmp(cert->serial_number().data(), expected_serial,
438 sizeof(expected_serial)) == 0);
439 }
440
TEST(X509CertificateTest,SHA256FingerprintsCorrectly)441 TEST(X509CertificateTest, SHA256FingerprintsCorrectly) {
442 scoped_refptr<X509Certificate> google_cert(
443 X509Certificate::CreateFromBytes(google_der));
444 ASSERT_TRUE(google_cert);
445
446 const SHA256HashValue google_sha256_fingerprint = {
447 {0x21, 0xaf, 0x58, 0x74, 0xea, 0x6b, 0xad, 0xbd, 0xe4, 0xb3, 0xb1,
448 0xaa, 0x53, 0x32, 0x80, 0x8f, 0xbf, 0x8a, 0x24, 0x7d, 0x98, 0xec,
449 0x7f, 0x77, 0x49, 0x38, 0x42, 0x81, 0x26, 0x7f, 0xed, 0x38}};
450
451 EXPECT_EQ(google_sha256_fingerprint, X509Certificate::CalculateFingerprint256(
452 google_cert->cert_buffer()));
453 }
454
TEST(X509CertificateTest,CAFingerprints)455 TEST(X509CertificateTest, CAFingerprints) {
456 base::FilePath certs_dir = GetTestCertsDirectory();
457
458 scoped_refptr<X509Certificate> server_cert =
459 ImportCertFromFile(certs_dir, "salesforce_com_test.pem");
460 ASSERT_NE(static_cast<X509Certificate*>(nullptr), server_cert.get());
461
462 scoped_refptr<X509Certificate> intermediate_cert1 =
463 ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2011.pem");
464 ASSERT_NE(static_cast<X509Certificate*>(nullptr), intermediate_cert1.get());
465
466 scoped_refptr<X509Certificate> intermediate_cert2 =
467 ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2016.pem");
468 ASSERT_NE(static_cast<X509Certificate*>(nullptr), intermediate_cert2.get());
469
470 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
471 intermediates.push_back(bssl::UpRef(intermediate_cert1->cert_buffer()));
472 scoped_refptr<X509Certificate> cert_chain1 =
473 X509Certificate::CreateFromBuffer(bssl::UpRef(server_cert->cert_buffer()),
474 std::move(intermediates));
475 ASSERT_TRUE(cert_chain1);
476
477 intermediates.clear();
478 intermediates.push_back(bssl::UpRef(intermediate_cert2->cert_buffer()));
479 scoped_refptr<X509Certificate> cert_chain2 =
480 X509Certificate::CreateFromBuffer(bssl::UpRef(server_cert->cert_buffer()),
481 std::move(intermediates));
482 ASSERT_TRUE(cert_chain2);
483
484 // No intermediate CA certicates.
485 intermediates.clear();
486 scoped_refptr<X509Certificate> cert_chain3 =
487 X509Certificate::CreateFromBuffer(bssl::UpRef(server_cert->cert_buffer()),
488 std::move(intermediates));
489 ASSERT_TRUE(cert_chain3);
490
491 SHA256HashValue cert_chain1_chain_fingerprint_256 = {
492 {0xac, 0xff, 0xcc, 0x63, 0x0d, 0xd0, 0xa7, 0x19, 0x78, 0xb5, 0x8a,
493 0x47, 0x8b, 0x67, 0x97, 0xcb, 0x8d, 0xe1, 0x6a, 0x8a, 0x57, 0x70,
494 0xda, 0x9a, 0x53, 0x72, 0xe2, 0xa0, 0x08, 0xab, 0xcc, 0x8f}};
495 SHA256HashValue cert_chain2_chain_fingerprint_256 = {
496 {0x67, 0x3a, 0x11, 0x20, 0xd6, 0x94, 0x14, 0xe4, 0x16, 0x9f, 0x58,
497 0xe2, 0x8b, 0xf7, 0x27, 0xed, 0xbb, 0xe8, 0xa7, 0xff, 0x1c, 0x8c,
498 0x0f, 0x21, 0x38, 0x16, 0x7c, 0xad, 0x1f, 0x22, 0x6f, 0x9b}};
499 SHA256HashValue cert_chain3_chain_fingerprint_256 = {
500 {0x16, 0x7a, 0xbd, 0xb4, 0x57, 0x04, 0x65, 0x3c, 0x3b, 0xef, 0x6e,
501 0x6a, 0xa6, 0x02, 0x73, 0x30, 0x3e, 0x34, 0x1b, 0x43, 0xc2, 0x7c,
502 0x98, 0x52, 0x9f, 0x34, 0x7f, 0x55, 0x97, 0xe9, 0x1a, 0x10}};
503 EXPECT_EQ(cert_chain1_chain_fingerprint_256,
504 cert_chain1->CalculateChainFingerprint256());
505 EXPECT_EQ(cert_chain2_chain_fingerprint_256,
506 cert_chain2->CalculateChainFingerprint256());
507 EXPECT_EQ(cert_chain3_chain_fingerprint_256,
508 cert_chain3->CalculateChainFingerprint256());
509 }
510
TEST(X509CertificateTest,ParseSubjectAltNames)511 TEST(X509CertificateTest, ParseSubjectAltNames) {
512 base::FilePath certs_dir = GetTestCertsDirectory();
513
514 scoped_refptr<X509Certificate> san_cert =
515 ImportCertFromFile(certs_dir, "subjectAltName_sanity_check.pem");
516 ASSERT_NE(static_cast<X509Certificate*>(nullptr), san_cert.get());
517
518 // Ensure that testing for SAN without using it is accepted.
519 EXPECT_TRUE(san_cert->GetSubjectAltName(nullptr, nullptr));
520
521 // Ensure that it's possible to get just dNSNames.
522 std::vector<std::string> dns_names;
523 EXPECT_TRUE(san_cert->GetSubjectAltName(&dns_names, nullptr));
524
525 // Ensure that it's possible to get just iPAddresses.
526 std::vector<std::string> ip_addresses;
527 EXPECT_TRUE(san_cert->GetSubjectAltName(nullptr, &ip_addresses));
528
529 // Ensure that DNS names are correctly parsed.
530 ASSERT_EQ(1U, dns_names.size());
531 EXPECT_EQ("test.example", dns_names[0]);
532
533 // Ensure that both IPv4 and IPv6 addresses are correctly parsed.
534 ASSERT_EQ(2U, ip_addresses.size());
535
536 static const uint8_t kIPv4Address[] = {
537 0x7F, 0x00, 0x00, 0x02
538 };
539 ASSERT_EQ(std::size(kIPv4Address), ip_addresses[0].size());
540 EXPECT_EQ(
541 0, memcmp(ip_addresses[0].data(), kIPv4Address, std::size(kIPv4Address)));
542
543 static const uint8_t kIPv6Address[] = {
544 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
545 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
546 };
547 ASSERT_EQ(std::size(kIPv6Address), ip_addresses[1].size());
548 EXPECT_EQ(
549 0, memcmp(ip_addresses[1].data(), kIPv6Address, std::size(kIPv6Address)));
550
551 // Ensure the subjectAltName dirName has not influenced the handling of
552 // the subject commonName.
553 EXPECT_EQ("127.0.0.1", san_cert->subject().common_name);
554
555 scoped_refptr<X509Certificate> no_san_cert =
556 ImportCertFromFile(certs_dir, "salesforce_com_test.pem");
557 ASSERT_NE(static_cast<X509Certificate*>(nullptr), no_san_cert.get());
558
559 EXPECT_NE(0u, dns_names.size());
560 EXPECT_NE(0u, ip_addresses.size());
561 EXPECT_FALSE(no_san_cert->GetSubjectAltName(&dns_names, &ip_addresses));
562 EXPECT_EQ(0u, dns_names.size());
563 EXPECT_EQ(0u, ip_addresses.size());
564 }
565
TEST(X509CertificateTest,ExtractSPKIFromDERCert)566 TEST(X509CertificateTest, ExtractSPKIFromDERCert) {
567 base::FilePath certs_dir = GetTestCertsDirectory();
568 scoped_refptr<X509Certificate> cert =
569 ImportCertFromFile(certs_dir, "nist.der");
570 ASSERT_NE(static_cast<X509Certificate*>(nullptr), cert.get());
571
572 base::StringPiece spkiBytes;
573 EXPECT_TRUE(asn1::ExtractSPKIFromDERCert(
574 x509_util::CryptoBufferAsStringPiece(cert->cert_buffer()), &spkiBytes));
575
576 uint8_t hash[base::kSHA1Length];
577 base::SHA1HashBytes(reinterpret_cast<const uint8_t*>(spkiBytes.data()),
578 spkiBytes.size(), hash);
579
580 EXPECT_EQ(0, memcmp(hash, kNistSPKIHash, sizeof(hash)));
581 }
582
TEST(X509CertificateTest,HasCanSignHttpExchangesDraftExtension)583 TEST(X509CertificateTest, HasCanSignHttpExchangesDraftExtension) {
584 base::FilePath certs_dir = GetTestCertsDirectory();
585 scoped_refptr<X509Certificate> cert = ImportCertFromFile(
586 certs_dir, "can_sign_http_exchanges_draft_extension.pem");
587 ASSERT_NE(static_cast<X509Certificate*>(nullptr), cert.get());
588
589 EXPECT_TRUE(asn1::HasCanSignHttpExchangesDraftExtension(
590 x509_util::CryptoBufferAsStringPiece(cert->cert_buffer())));
591 }
592
TEST(X509CertificateTest,HasCanSignHttpExchangesDraftExtensionInvalid)593 TEST(X509CertificateTest, HasCanSignHttpExchangesDraftExtensionInvalid) {
594 base::FilePath certs_dir = GetTestCertsDirectory();
595 scoped_refptr<X509Certificate> cert = ImportCertFromFile(
596 certs_dir, "can_sign_http_exchanges_draft_extension_invalid.pem");
597 ASSERT_NE(static_cast<X509Certificate*>(nullptr), cert.get());
598
599 EXPECT_FALSE(asn1::HasCanSignHttpExchangesDraftExtension(
600 x509_util::CryptoBufferAsStringPiece(cert->cert_buffer())));
601 }
602
TEST(X509CertificateTest,DoesNotHaveCanSignHttpExchangesDraftExtension)603 TEST(X509CertificateTest, DoesNotHaveCanSignHttpExchangesDraftExtension) {
604 base::FilePath certs_dir = GetTestCertsDirectory();
605 scoped_refptr<X509Certificate> cert =
606 ImportCertFromFile(certs_dir, "ok_cert.pem");
607 ASSERT_NE(static_cast<X509Certificate*>(nullptr), cert.get());
608
609 EXPECT_FALSE(asn1::HasCanSignHttpExchangesDraftExtension(
610 x509_util::CryptoBufferAsStringPiece(cert->cert_buffer())));
611 }
612
TEST(X509CertificateTest,ExtractExtension)613 TEST(X509CertificateTest, ExtractExtension) {
614 base::FilePath certs_dir = GetTestCertsDirectory();
615 scoped_refptr<X509Certificate> cert =
616 ImportCertFromFile(certs_dir, "ok_cert.pem");
617 ASSERT_TRUE(cert);
618
619 bool present, critical;
620 base::StringPiece contents;
621 ASSERT_TRUE(asn1::ExtractExtensionFromDERCert(
622 x509_util::CryptoBufferAsStringPiece(cert->cert_buffer()),
623 der::Input(kBasicConstraintsOid).AsStringView(), &present, &critical,
624 &contents));
625 EXPECT_TRUE(present);
626 EXPECT_TRUE(critical);
627 ASSERT_EQ(base::StringPiece("\x30\x00", 2), contents);
628
629 static constexpr uint8_t kNonsenseOID[] = {0x56, 0x1d, 0x13};
630 ASSERT_TRUE(asn1::ExtractExtensionFromDERCert(
631 x509_util::CryptoBufferAsStringPiece(cert->cert_buffer()),
632 base::StringPiece(reinterpret_cast<const char*>(kNonsenseOID),
633 sizeof(kNonsenseOID)),
634 &present, &critical, &contents));
635 ASSERT_FALSE(present);
636
637 scoped_refptr<X509Certificate> uid_cert =
638 ImportCertFromFile(certs_dir, "ct-test-embedded-with-uids.pem");
639 ASSERT_TRUE(uid_cert);
640 ASSERT_TRUE(asn1::ExtractExtensionFromDERCert(
641 x509_util::CryptoBufferAsStringPiece(uid_cert->cert_buffer()),
642 der::Input(kBasicConstraintsOid).AsStringView(), &present, &critical,
643 &contents));
644 EXPECT_TRUE(present);
645 EXPECT_FALSE(critical);
646 ASSERT_EQ(base::StringPiece("\x30\x00", 2), contents);
647 }
648
649 // Tests CRYPTO_BUFFER deduping via X509Certificate::CreateFromBuffer. We
650 // call X509Certificate::CreateFromBuffer several times and observe whether
651 // it returns a cached or new CRYPTO_BUFFER.
TEST(X509CertificateTest,Cache)652 TEST(X509CertificateTest, Cache) {
653 bssl::UniquePtr<CRYPTO_BUFFER> google_cert_handle;
654 bssl::UniquePtr<CRYPTO_BUFFER> thawte_cert_handle;
655
656 // Add a single certificate to the certificate cache.
657 google_cert_handle = x509_util::CreateCryptoBuffer(google_der);
658 ASSERT_TRUE(google_cert_handle);
659 scoped_refptr<X509Certificate> cert1(
660 X509Certificate::CreateFromBuffer(std::move(google_cert_handle), {}));
661 ASSERT_TRUE(cert1);
662
663 // Add the same certificate, but as a new handle.
664 google_cert_handle = x509_util::CreateCryptoBuffer(google_der);
665 ASSERT_TRUE(google_cert_handle);
666 scoped_refptr<X509Certificate> cert2(
667 X509Certificate::CreateFromBuffer(std::move(google_cert_handle), {}));
668 ASSERT_TRUE(cert2);
669
670 // A new X509Certificate should be returned.
671 EXPECT_NE(cert1.get(), cert2.get());
672 // But both instances should share the underlying OS certificate handle.
673 EXPECT_EQ(cert1->cert_buffer(), cert2->cert_buffer());
674 EXPECT_EQ(0u, cert1->intermediate_buffers().size());
675 EXPECT_EQ(0u, cert2->intermediate_buffers().size());
676
677 // Add the same certificate, but this time with an intermediate. This
678 // should result in the intermediate being cached. Note that this is not
679 // a legitimate chain, but is suitable for testing.
680 google_cert_handle = x509_util::CreateCryptoBuffer(google_der);
681 thawte_cert_handle = x509_util::CreateCryptoBuffer(thawte_der);
682 ASSERT_TRUE(google_cert_handle);
683 ASSERT_TRUE(thawte_cert_handle);
684 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
685 intermediates.push_back(std::move(thawte_cert_handle));
686 scoped_refptr<X509Certificate> cert3(X509Certificate::CreateFromBuffer(
687 std::move(google_cert_handle), std::move(intermediates)));
688 ASSERT_TRUE(cert3);
689
690 // Test that the new certificate, even with intermediates, results in the
691 // same underlying handle being used.
692 EXPECT_EQ(cert1->cert_buffer(), cert3->cert_buffer());
693 // Though they use the same OS handle, the intermediates should be different.
694 EXPECT_NE(cert1->intermediate_buffers().size(),
695 cert3->intermediate_buffers().size());
696 }
697
TEST(X509CertificateTest,Pickle)698 TEST(X509CertificateTest, Pickle) {
699 bssl::UniquePtr<CRYPTO_BUFFER> google_cert_handle =
700 x509_util::CreateCryptoBuffer(google_der);
701 ASSERT_TRUE(google_cert_handle);
702 bssl::UniquePtr<CRYPTO_BUFFER> thawte_cert_handle =
703 x509_util::CreateCryptoBuffer(thawte_der);
704 ASSERT_TRUE(thawte_cert_handle);
705
706 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
707 intermediates.push_back(std::move(thawte_cert_handle));
708 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromBuffer(
709 std::move(google_cert_handle), std::move(intermediates));
710 ASSERT_TRUE(cert);
711
712 base::Pickle pickle;
713 cert->Persist(&pickle);
714
715 base::PickleIterator iter(pickle);
716 scoped_refptr<X509Certificate> cert_from_pickle =
717 X509Certificate::CreateFromPickle(&iter);
718 ASSERT_TRUE(cert_from_pickle);
719 EXPECT_TRUE(x509_util::CryptoBufferEqual(cert->cert_buffer(),
720 cert_from_pickle->cert_buffer()));
721 const auto& cert_intermediates = cert->intermediate_buffers();
722 const auto& pickle_intermediates = cert_from_pickle->intermediate_buffers();
723 ASSERT_EQ(cert_intermediates.size(), pickle_intermediates.size());
724 for (size_t i = 0; i < cert_intermediates.size(); ++i) {
725 EXPECT_TRUE(x509_util::CryptoBufferEqual(cert_intermediates[i].get(),
726 pickle_intermediates[i].get()));
727 }
728 }
729
TEST(X509CertificateTest,IntermediateCertificates)730 TEST(X509CertificateTest, IntermediateCertificates) {
731 scoped_refptr<X509Certificate> webkit_cert(
732 X509Certificate::CreateFromBytes(webkit_der));
733 ASSERT_TRUE(webkit_cert);
734
735 scoped_refptr<X509Certificate> thawte_cert(
736 X509Certificate::CreateFromBytes(thawte_der));
737 ASSERT_TRUE(thawte_cert);
738
739 bssl::UniquePtr<CRYPTO_BUFFER> google_handle;
740 // Create object with no intermediates:
741 google_handle = x509_util::CreateCryptoBuffer(google_der);
742 scoped_refptr<X509Certificate> cert1;
743 cert1 =
744 X509Certificate::CreateFromBuffer(bssl::UpRef(google_handle.get()), {});
745 ASSERT_TRUE(cert1);
746 EXPECT_EQ(0u, cert1->intermediate_buffers().size());
747
748 // Create object with 2 intermediates:
749 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates2;
750 intermediates2.push_back(bssl::UpRef(webkit_cert->cert_buffer()));
751 intermediates2.push_back(bssl::UpRef(thawte_cert->cert_buffer()));
752 scoped_refptr<X509Certificate> cert2 = X509Certificate::CreateFromBuffer(
753 std::move(google_handle), std::move(intermediates2));
754 ASSERT_TRUE(cert2);
755
756 // Verify it has all the intermediates:
757 const auto& cert2_intermediates = cert2->intermediate_buffers();
758 ASSERT_EQ(2u, cert2_intermediates.size());
759 EXPECT_TRUE(x509_util::CryptoBufferEqual(cert2_intermediates[0].get(),
760 webkit_cert->cert_buffer()));
761 EXPECT_TRUE(x509_util::CryptoBufferEqual(cert2_intermediates[1].get(),
762 thawte_cert->cert_buffer()));
763 }
764
TEST(X509CertificateTest,Equals)765 TEST(X509CertificateTest, Equals) {
766 CertificateList certs = CreateCertificateListFromFile(
767 GetTestCertsDirectory(), "multi-root-chain1.pem",
768 X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
769 ASSERT_EQ(4u, certs.size());
770
771 // Comparing X509Certificates with no intermediates.
772 EXPECT_TRUE(certs[0]->EqualsExcludingChain(certs[0].get()));
773 EXPECT_FALSE(certs[1]->EqualsExcludingChain(certs[0].get()));
774 EXPECT_FALSE(certs[0]->EqualsExcludingChain(certs[1].get()));
775 EXPECT_TRUE(certs[0]->EqualsIncludingChain(certs[0].get()));
776 EXPECT_FALSE(certs[1]->EqualsIncludingChain(certs[0].get()));
777 EXPECT_FALSE(certs[0]->EqualsIncludingChain(certs[1].get()));
778
779 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates1;
780 intermediates1.push_back(bssl::UpRef(certs[1]->cert_buffer()));
781 scoped_refptr<X509Certificate> cert0_with_intermediate =
782 X509Certificate::CreateFromBuffer(bssl::UpRef(certs[0]->cert_buffer()),
783 std::move(intermediates1));
784 ASSERT_TRUE(cert0_with_intermediate);
785
786 // Comparing X509Certificate with one intermediate to X509Certificate with no
787 // intermediates.
788 EXPECT_TRUE(certs[0]->EqualsExcludingChain(cert0_with_intermediate.get()));
789 EXPECT_TRUE(cert0_with_intermediate->EqualsExcludingChain(certs[0].get()));
790 EXPECT_FALSE(certs[0]->EqualsIncludingChain(cert0_with_intermediate.get()));
791 EXPECT_FALSE(cert0_with_intermediate->EqualsIncludingChain(certs[0].get()));
792
793 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates2;
794 intermediates2.push_back(bssl::UpRef(certs[2]->cert_buffer()));
795 scoped_refptr<X509Certificate> cert0_with_intermediate2 =
796 X509Certificate::CreateFromBuffer(bssl::UpRef(certs[0]->cert_buffer()),
797 std::move(intermediates2));
798 ASSERT_TRUE(cert0_with_intermediate2);
799
800 // Comparing X509Certificate with one intermediate to X509Certificate with
801 // one different intermediate.
802 EXPECT_TRUE(cert0_with_intermediate2->EqualsExcludingChain(
803 cert0_with_intermediate.get()));
804 EXPECT_TRUE(cert0_with_intermediate->EqualsExcludingChain(
805 cert0_with_intermediate2.get()));
806 EXPECT_FALSE(cert0_with_intermediate2->EqualsIncludingChain(
807 cert0_with_intermediate.get()));
808 EXPECT_FALSE(cert0_with_intermediate->EqualsIncludingChain(
809 cert0_with_intermediate2.get()));
810
811 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates12;
812 intermediates12.push_back(bssl::UpRef(certs[1]->cert_buffer()));
813 intermediates12.push_back(bssl::UpRef(certs[2]->cert_buffer()));
814 scoped_refptr<X509Certificate> cert0_with_intermediates12 =
815 X509Certificate::CreateFromBuffer(bssl::UpRef(certs[0]->cert_buffer()),
816 std::move(intermediates12));
817 ASSERT_TRUE(cert0_with_intermediates12);
818
819 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates21;
820 intermediates21.push_back(bssl::UpRef(certs[2]->cert_buffer()));
821 intermediates21.push_back(bssl::UpRef(certs[1]->cert_buffer()));
822 scoped_refptr<X509Certificate> cert0_with_intermediates21 =
823 X509Certificate::CreateFromBuffer(bssl::UpRef(certs[0]->cert_buffer()),
824 std::move(intermediates21));
825 ASSERT_TRUE(cert0_with_intermediates21);
826
827 // Comparing X509Certificate with two intermediates to X509Certificate with
828 // same two intermediates but in reverse order
829 EXPECT_TRUE(cert0_with_intermediates21->EqualsExcludingChain(
830 cert0_with_intermediates12.get()));
831 EXPECT_TRUE(cert0_with_intermediates12->EqualsExcludingChain(
832 cert0_with_intermediates21.get()));
833 EXPECT_FALSE(cert0_with_intermediates21->EqualsIncludingChain(
834 cert0_with_intermediates12.get()));
835 EXPECT_FALSE(cert0_with_intermediates12->EqualsIncludingChain(
836 cert0_with_intermediates21.get()));
837
838 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates12b;
839 intermediates12b.push_back(bssl::UpRef(certs[1]->cert_buffer()));
840 intermediates12b.push_back(bssl::UpRef(certs[2]->cert_buffer()));
841 scoped_refptr<X509Certificate> cert0_with_intermediates12b =
842 X509Certificate::CreateFromBuffer(bssl::UpRef(certs[0]->cert_buffer()),
843 std::move(intermediates12b));
844 ASSERT_TRUE(cert0_with_intermediates12b);
845
846 // Comparing X509Certificate with two intermediates to X509Certificate with
847 // same two intermediates in same order.
848 EXPECT_TRUE(cert0_with_intermediates12->EqualsExcludingChain(
849 cert0_with_intermediates12b.get()));
850 EXPECT_TRUE(cert0_with_intermediates12b->EqualsExcludingChain(
851 cert0_with_intermediates12.get()));
852 EXPECT_TRUE(cert0_with_intermediates12->EqualsIncludingChain(
853 cert0_with_intermediates12b.get()));
854 EXPECT_TRUE(cert0_with_intermediates12b->EqualsIncludingChain(
855 cert0_with_intermediates12.get()));
856 }
857
TEST(X509CertificateTest,IsIssuedByEncoded)858 TEST(X509CertificateTest, IsIssuedByEncoded) {
859 base::FilePath certs_dir = GetTestCertsDirectory();
860
861 // Test a client certificate from MIT.
862 scoped_refptr<X509Certificate> mit_davidben_cert(
863 ImportCertFromFile(certs_dir, "mit.davidben.der"));
864 ASSERT_NE(static_cast<X509Certificate*>(nullptr), mit_davidben_cert.get());
865
866 std::string mit_issuer(reinterpret_cast<const char*>(MITDN),
867 sizeof(MITDN));
868
869 // Test a certificate from Google, issued by Thawte
870 scoped_refptr<X509Certificate> google_cert(
871 ImportCertFromFile(certs_dir, "google.single.der"));
872 ASSERT_NE(static_cast<X509Certificate*>(nullptr), google_cert.get());
873
874 std::string thawte_issuer(reinterpret_cast<const char*>(ThawteDN),
875 sizeof(ThawteDN));
876
877 // Check that the David Ben certificate is issued by MIT, but not
878 // by Thawte.
879 std::vector<std::string> issuers;
880 issuers.clear();
881 issuers.push_back(mit_issuer);
882 EXPECT_TRUE(mit_davidben_cert->IsIssuedByEncoded(issuers));
883 EXPECT_FALSE(google_cert->IsIssuedByEncoded(issuers));
884
885 // Check that the Google certificate is issued by Thawte and not
886 // by MIT.
887 issuers.clear();
888 issuers.push_back(thawte_issuer);
889 EXPECT_FALSE(mit_davidben_cert->IsIssuedByEncoded(issuers));
890 EXPECT_TRUE(google_cert->IsIssuedByEncoded(issuers));
891
892 // Check that they both pass when given a list of the two issuers.
893 issuers.clear();
894 issuers.push_back(mit_issuer);
895 issuers.push_back(thawte_issuer);
896 EXPECT_TRUE(mit_davidben_cert->IsIssuedByEncoded(issuers));
897 EXPECT_TRUE(google_cert->IsIssuedByEncoded(issuers));
898 }
899
TEST(X509CertificateTest,IsSelfSigned)900 TEST(X509CertificateTest, IsSelfSigned) {
901 base::FilePath certs_dir = GetTestCertsDirectory();
902
903 scoped_refptr<X509Certificate> cert(
904 ImportCertFromFile(certs_dir, "mit.davidben.der"));
905 ASSERT_NE(static_cast<X509Certificate*>(nullptr), cert.get());
906 EXPECT_FALSE(X509Certificate::IsSelfSigned(cert->cert_buffer()));
907
908 scoped_refptr<X509Certificate> self_signed(
909 ImportCertFromFile(certs_dir, "root_ca_cert.pem"));
910 ASSERT_NE(static_cast<X509Certificate*>(nullptr), self_signed.get());
911 EXPECT_TRUE(X509Certificate::IsSelfSigned(self_signed->cert_buffer()));
912
913 scoped_refptr<X509Certificate> bad_name(
914 ImportCertFromFile(certs_dir, "self-signed-invalid-name.pem"));
915 ASSERT_NE(static_cast<X509Certificate*>(nullptr), bad_name.get());
916 EXPECT_FALSE(X509Certificate::IsSelfSigned(bad_name->cert_buffer()));
917
918 scoped_refptr<X509Certificate> bad_sig(
919 ImportCertFromFile(certs_dir, "self-signed-invalid-sig.pem"));
920 ASSERT_NE(static_cast<X509Certificate*>(nullptr), bad_sig.get());
921 EXPECT_FALSE(X509Certificate::IsSelfSigned(bad_sig->cert_buffer()));
922
923 constexpr char invalid_cert_data[] = "this is not a certificate";
924 bssl::UniquePtr<CRYPTO_BUFFER> invalid_cert_handle =
925 x509_util::CreateCryptoBuffer(base::StringPiece(invalid_cert_data));
926 ASSERT_TRUE(invalid_cert_handle);
927 EXPECT_FALSE(X509Certificate::IsSelfSigned(invalid_cert_handle.get()));
928 }
929
TEST(X509CertificateTest,IsIssuedByEncodedWithIntermediates)930 TEST(X509CertificateTest, IsIssuedByEncodedWithIntermediates) {
931 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
932
933 std::string intermediate_dn = intermediate->GetSubject();
934 std::string root_dn = root->GetSubject();
935
936 // Create an X509Certificate object containing the leaf and the intermediate
937 // but not the root.
938 scoped_refptr<X509Certificate> cert_chain = leaf->GetX509CertificateChain();
939 ASSERT_TRUE(cert_chain);
940
941 // Check that the chain is issued by the intermediate.
942 EXPECT_TRUE(cert_chain->IsIssuedByEncoded({intermediate_dn}));
943
944 // Check that the chain is also issued by the root.
945 EXPECT_TRUE(cert_chain->IsIssuedByEncoded({root_dn}));
946
947 // Check that the chain is issued by either the intermediate or the root.
948 EXPECT_TRUE(cert_chain->IsIssuedByEncoded({intermediate_dn, root_dn}));
949
950 // Check that an empty issuers list returns false.
951 EXPECT_FALSE(cert_chain->IsIssuedByEncoded({}));
952
953 // Check that the chain is not issued by Verisign
954 std::string verisign_issuer(reinterpret_cast<const char*>(VerisignDN),
955 sizeof(VerisignDN));
956 EXPECT_FALSE(cert_chain->IsIssuedByEncoded({verisign_issuer}));
957
958 // Check that the chain is issued by root, though the extraneous Verisign
959 // name is also given.
960 EXPECT_TRUE(cert_chain->IsIssuedByEncoded({verisign_issuer, root_dn}));
961 }
962
963 const struct CertificateFormatTestData {
964 const char* file_name;
965 X509Certificate::Format format;
966 SHA256HashValue* chain_fingerprints[3];
967 } kFormatTestData[] = {
968 // DER Parsing - single certificate, DER encoded
969 {"google.single.der",
970 X509Certificate::FORMAT_SINGLE_CERTIFICATE,
971 {
972 &google_parse_fingerprint,
973 nullptr,
974 }},
975 // DER parsing - single certificate, PEM encoded
976 {"google.single.pem",
977 X509Certificate::FORMAT_SINGLE_CERTIFICATE,
978 {
979 &google_parse_fingerprint,
980 nullptr,
981 }},
982 // PEM parsing - single certificate, PEM encoded with a PEB of
983 // "CERTIFICATE"
984 {"google.single.pem",
985 X509Certificate::FORMAT_PEM_CERT_SEQUENCE,
986 {
987 &google_parse_fingerprint,
988 nullptr,
989 }},
990 // PEM parsing - sequence of certificates, PEM encoded with a PEB of
991 // "CERTIFICATE"
992 {"google.chain.pem",
993 X509Certificate::FORMAT_PEM_CERT_SEQUENCE,
994 {
995 &google_parse_fingerprint,
996 &thawte_parse_fingerprint,
997 nullptr,
998 }},
999 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, DER
1000 // encoding
1001 {"google.binary.p7b",
1002 X509Certificate::FORMAT_PKCS7,
1003 {
1004 &google_parse_fingerprint,
1005 &thawte_parse_fingerprint,
1006 nullptr,
1007 }},
1008 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM
1009 // encoded with a PEM PEB of "CERTIFICATE"
1010 {"google.pem_cert.p7b",
1011 X509Certificate::FORMAT_PKCS7,
1012 {
1013 &google_parse_fingerprint,
1014 &thawte_parse_fingerprint,
1015 nullptr,
1016 }},
1017 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM
1018 // encoded with a PEM PEB of "PKCS7"
1019 {"google.pem_pkcs7.p7b",
1020 X509Certificate::FORMAT_PKCS7,
1021 {
1022 &google_parse_fingerprint,
1023 &thawte_parse_fingerprint,
1024 nullptr,
1025 }},
1026 // All of the above, this time using auto-detection
1027 {"google.single.der",
1028 X509Certificate::FORMAT_AUTO,
1029 {
1030 &google_parse_fingerprint,
1031 nullptr,
1032 }},
1033 {"google.single.pem",
1034 X509Certificate::FORMAT_AUTO,
1035 {
1036 &google_parse_fingerprint,
1037 nullptr,
1038 }},
1039 {"google.chain.pem",
1040 X509Certificate::FORMAT_AUTO,
1041 {
1042 &google_parse_fingerprint,
1043 &thawte_parse_fingerprint,
1044 nullptr,
1045 }},
1046 {"google.binary.p7b",
1047 X509Certificate::FORMAT_AUTO,
1048 {
1049 &google_parse_fingerprint,
1050 &thawte_parse_fingerprint,
1051 nullptr,
1052 }},
1053 {"google.pem_cert.p7b",
1054 X509Certificate::FORMAT_AUTO,
1055 {
1056 &google_parse_fingerprint,
1057 &thawte_parse_fingerprint,
1058 nullptr,
1059 }},
1060 {"google.pem_pkcs7.p7b",
1061 X509Certificate::FORMAT_AUTO,
1062 {
1063 &google_parse_fingerprint,
1064 &thawte_parse_fingerprint,
1065 nullptr,
1066 }},
1067 };
1068
1069 class X509CertificateParseTest
1070 : public testing::TestWithParam<CertificateFormatTestData> {
1071 public:
1072 ~X509CertificateParseTest() override = default;
SetUp()1073 void SetUp() override { test_data_ = GetParam(); }
TearDown()1074 void TearDown() override {}
1075
1076 protected:
1077 CertificateFormatTestData test_data_;
1078 };
1079
TEST_P(X509CertificateParseTest,CanParseFormat)1080 TEST_P(X509CertificateParseTest, CanParseFormat) {
1081 base::FilePath certs_dir = GetTestCertsDirectory();
1082 CertificateList certs = CreateCertificateListFromFile(
1083 certs_dir, test_data_.file_name, test_data_.format);
1084 ASSERT_FALSE(certs.empty());
1085 ASSERT_LE(certs.size(), std::size(test_data_.chain_fingerprints));
1086 CheckGoogleCert(certs.front(), google_parse_fingerprint,
1087 kGoogleParseValidFrom, kGoogleParseValidTo);
1088
1089 for (size_t i = 0; i < std::size(test_data_.chain_fingerprints); ++i) {
1090 if (!test_data_.chain_fingerprints[i]) {
1091 // No more test certificates expected - make sure no more were
1092 // returned before marking this test a success.
1093 EXPECT_EQ(i, certs.size());
1094 break;
1095 }
1096
1097 // A cert is expected - make sure that one was parsed.
1098 ASSERT_LT(i, certs.size());
1099 ASSERT_TRUE(certs[i]);
1100
1101 // Compare the parsed certificate with the expected certificate, by
1102 // comparing fingerprints.
1103 EXPECT_EQ(
1104 *test_data_.chain_fingerprints[i],
1105 X509Certificate::CalculateFingerprint256(certs[i]->cert_buffer()));
1106 }
1107 }
1108
1109 INSTANTIATE_TEST_SUITE_P(All,
1110 X509CertificateParseTest,
1111 testing::ValuesIn(kFormatTestData));
1112
1113 struct CertificateNameVerifyTestData {
1114 // true iff we expect hostname to match an entry in cert_names.
1115 bool expected;
1116 // The hostname to match.
1117 const char* hostname;
1118 // Comma separated list of certificate names to match against. Any occurrence
1119 // of '#' will be replaced with a null character before processing.
1120 const char* dns_names;
1121 // Comma separated list of certificate IP Addresses to match against. Each
1122 // address is x prefixed 16 byte hex code for v6 or dotted-decimals for v4.
1123 const char* ip_addrs;
1124 };
1125
1126 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
1127 // to output the parameter that was passed. Without this, it will simply
1128 // attempt to print out the first twenty bytes of the object, which depending
1129 // on platform and alignment, may result in an invalid read.
PrintTo(const CertificateNameVerifyTestData & data,std::ostream * os)1130 void PrintTo(const CertificateNameVerifyTestData& data, std::ostream* os) {
1131 ASSERT_TRUE(data.hostname);
1132 ASSERT_TRUE(data.dns_names || data.ip_addrs);
1133 *os << " expected: " << data.expected << "; hostname: " << data.hostname
1134 << "; dns_names: " << (data.dns_names ? data.dns_names : "")
1135 << "; ip_addrs: " << (data.ip_addrs ? data.ip_addrs : "");
1136 }
1137
1138 const CertificateNameVerifyTestData kNameVerifyTestData[] = {
1139 {true, "foo.com", "foo.com"},
1140 {true, "f", "f"},
1141 {false, "h", "i"},
1142 {true, "bar.foo.com", "*.foo.com"},
1143 {true, "www.test.fr", "*.test.com,*.test.co.uk,*.test.de,*.test.fr"},
1144 {true, "wwW.tESt.fr", ",*.*,*.test.de,*.test.FR,www"},
1145 {false, "f.uk", ".uk"},
1146 {false, "w.bar.foo.com", "?.bar.foo.com"},
1147 {false, "www.foo.com", "(www|ftp).foo.com"},
1148 {false, "www.foo.com", "www.foo.com#"}, // # = null char.
1149 {false, "www.foo.com", "www.foo.com#*.foo.com,#,#"},
1150 {false, "www.house.example", "ww.house.example"},
1151 {false, "test.org", "www.test.org,*.test.org,*.org"},
1152 {false, "w.bar.foo.com", "w*.bar.foo.com"},
1153 {false, "www.bar.foo.com", "ww*ww.bar.foo.com"},
1154 {false, "wwww.bar.foo.com", "ww*ww.bar.foo.com"},
1155 {false, "wwww.bar.foo.com", "w*w.bar.foo.com"},
1156 {false, "wwww.bar.foo.com", "w*w.bar.foo.c0m"},
1157 {false, "WALLY.bar.foo.com", "wa*.bar.foo.com"},
1158 {false, "wally.bar.foo.com", "*Ly.bar.foo.com"},
1159 // Hostname escaping tests
1160 {true, "ww%57.foo.com", "www.foo.com"},
1161 {true, "www%2Efoo.com", "www.foo.com"},
1162 {false, "www%00.foo.com", "www,foo.com,www.foo.com"},
1163 {false, "www%0D.foo.com", "www.foo.com,www\r.foo.com"},
1164 {false, "www%40foo.com", "www@foo.com"},
1165 {false, "www%2E%2Efoo.com", "www.foo.com,www..foo.com"},
1166 {false, "www%252Efoo.com", "www.foo.com"},
1167 // IDN tests
1168 {true, "xn--poema-9qae5a.com.br", "xn--poema-9qae5a.com.br"},
1169 {true, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br"},
1170 {false, "xn--poema-9qae5a.com.br",
1171 "*.xn--poema-9qae5a.com.br,"
1172 "xn--poema-*.com.br,"
1173 "xn--*-9qae5a.com.br,"
1174 "*--poema-9qae5a.com.br"},
1175 // The following are adapted from the examples quoted from
1176 // http://tools.ietf.org/html/rfc6125#section-6.4.3
1177 // (e.g., *.example.com would match foo.example.com but
1178 // not bar.foo.example.com or example.com).
1179 {true, "foo.example.com", "*.example.com"},
1180 {false, "bar.foo.example.com", "*.example.com"},
1181 {false, "example.com", "*.example.com"},
1182 // Partial wildcards are disallowed, though RFC 2818 rules allow them.
1183 // That is, forms such as baz*.example.net, *baz.example.net, and
1184 // b*z.example.net should NOT match domains. Instead, the wildcard must
1185 // always be the left-most label, and only a single label.
1186 {false, "baz1.example.net", "baz*.example.net"},
1187 {false, "foobaz.example.net", "*baz.example.net"},
1188 {false, "buzz.example.net", "b*z.example.net"},
1189 {false, "www.test.example.net", "www.*.example.net"},
1190 // Wildcards should not be valid for public registry controlled domains,
1191 // and unknown/unrecognized domains, at least three domain components must
1192 // be present.
1193 {true, "www.test.example", "*.test.example"},
1194 {true, "test.example.co.uk", "*.example.co.uk"},
1195 {false, "test.example", "*.example"},
1196 {false, "example.co.uk", "*.co.uk"},
1197 {false, "foo.com", "*.com"},
1198 {false, "foo.us", "*.us"},
1199 {false, "foo", "*"},
1200 // IDN variants of wildcards and registry controlled domains.
1201 {true, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br"},
1202 {true, "test.example.xn--mgbaam7a8h", "*.example.xn--mgbaam7a8h"},
1203 {false, "xn--poema-9qae5a.com.br", "*.com.br"},
1204 {false, "example.xn--mgbaam7a8h", "*.xn--mgbaam7a8h"},
1205 // Wildcards should be permissible for 'private' registry controlled
1206 // domains.
1207 {true, "www.appspot.com", "*.appspot.com"},
1208 {true, "foo.s3.amazonaws.com", "*.s3.amazonaws.com"},
1209 // Multiple wildcards are not valid.
1210 {false, "foo.example.com", "*.*.com"},
1211 {false, "foo.bar.example.com", "*.bar.*.com"},
1212 // Absolute vs relative DNS name tests. Although not explicitly specified
1213 // in RFC 6125, absolute reference names (those ending in a .) should
1214 // match either absolute or relative presented names.
1215 {true, "foo.com", "foo.com."},
1216 {true, "foo.com.", "foo.com"},
1217 {true, "foo.com.", "foo.com."},
1218 {true, "f", "f."},
1219 {true, "f.", "f"},
1220 {true, "f.", "f."},
1221 {true, "www-3.bar.foo.com", "*.bar.foo.com."},
1222 {true, "www-3.bar.foo.com.", "*.bar.foo.com"},
1223 {true, "www-3.bar.foo.com.", "*.bar.foo.com."},
1224 {false, ".", "."},
1225 {false, "example.com", "*.com."},
1226 {false, "example.com.", "*.com"},
1227 {false, "example.com.", "*.com."},
1228 {false, "foo.", "*."},
1229 {false, "foo", "*."},
1230 {false, "foo.co.uk", "*.co.uk."},
1231 {false, "foo.co.uk.", "*.co.uk."},
1232 // IP addresses in subject alternative name
1233 {true, "10.1.2.3", "", "10.1.2.3"},
1234 {true, "14.15", "", "14.0.0.15"},
1235 {false, "10.1.2.7", "", "10.1.2.6,10.1.2.8"},
1236 {false, "10.1.2.8", "foo"},
1237 {true, "::4.5.6.7", "", "x00000000000000000000000004050607"},
1238 {false, "::6.7.8.9", "::6.7.8.9",
1239 "x00000000000000000000000006070808,x0000000000000000000000000607080a,"
1240 "xff000000000000000000000006070809,6.7.8.9"},
1241 {true, "FE80::200:f8ff:fe21:67cf", "",
1242 "x00000000000000000000000006070808,xfe800000000000000200f8fffe2167cf,"
1243 "xff0000000000000000000000060708ff,10.0.0.1"},
1244 // Invalid hostnames with final numeric component.
1245 {false, "121.2.3.512", "1*1.2.3.512,*1.2.3.512,1*.2.3.512,*.2.3.512",
1246 "121.2.3.0"},
1247 {false, "1.2.3.4.5.6", "*.2.3.4.5.6"},
1248 {false, "1.2.3.4.5", "1.2.3.4.5"},
1249 {false, "a.0.0.1", "*.0.0.1"},
1250 // IP addresses in dNSName should not match commonName
1251 {false, "127.0.0.1", "127.0.0.1"},
1252 {false, "127.0.0.1", "*.0.0.1"},
1253 // Invalid host names.
1254 {false, ".", ""},
1255 {false, ".", "."},
1256 {false, "1.2.3.4..", "", "1.2.3.4"},
1257 {false, "www..domain.example", "www.domain.example"},
1258 {false, "www^domain.example", "www^domain.example"},
1259 {false, "www%20.domain.example", "www .domain.example"},
1260 {false, "www%2520.domain.example", "www .domain.example"},
1261 {false, "www%5E.domain.example", "www^domain.example"},
1262 {false, "www,domain.example", "www,domain.example"},
1263 {false, "0x000000002200037955161..", "0x000000002200037955161"},
1264 {false, "junk)(£)$*!@~#", "junk)(£)$*!@~#"},
1265 {false, "www.*.com", "www.*.com"},
1266 {false, "w$w.f.com", "w$w.f.com"},
1267 {false, "nocolonallowed:example", "nocolonallowed:example"},
1268 {false, "www-1.[::FFFF:129.144.52.38]", "*.[::FFFF:129.144.52.38]"},
1269 {false, "[::4.5.6.9]", "", "x00000000000000000000000004050609"},
1270 };
1271
1272 class X509CertificateNameVerifyTest
1273 : public testing::TestWithParam<CertificateNameVerifyTestData> {
1274 };
1275
TEST_P(X509CertificateNameVerifyTest,VerifyHostname)1276 TEST_P(X509CertificateNameVerifyTest, VerifyHostname) {
1277 CertificateNameVerifyTestData test_data = GetParam();
1278
1279 std::vector<std::string> dns_names, ip_addressses;
1280 if (test_data.dns_names) {
1281 // Build up the certificate DNS names list.
1282 std::string dns_name_line(test_data.dns_names);
1283 std::replace(dns_name_line.begin(), dns_name_line.end(), '#', '\0');
1284 dns_names = base::SplitString(dns_name_line, ",", base::TRIM_WHITESPACE,
1285 base::SPLIT_WANT_ALL);
1286 }
1287
1288 if (test_data.ip_addrs) {
1289 // Build up the certificate IP address list.
1290 std::string ip_addrs_line(test_data.ip_addrs);
1291 std::vector<std::string> ip_addressses_ascii = base::SplitString(
1292 ip_addrs_line, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
1293 for (size_t i = 0; i < ip_addressses_ascii.size(); ++i) {
1294 std::string& addr_ascii = ip_addressses_ascii[i];
1295 ASSERT_NE(0U, addr_ascii.length());
1296 if (addr_ascii[0] == 'x') { // Hex encoded address
1297 addr_ascii.erase(0, 1);
1298 std::string bytes;
1299 EXPECT_TRUE(base::HexStringToString(addr_ascii, &bytes))
1300 << "Could not parse hex address " << addr_ascii << " i = " << i;
1301 ip_addressses.push_back(std::move(bytes));
1302 ASSERT_EQ(16U, ip_addressses.back().size()) << i;
1303 } else { // Decimal groups
1304 std::vector<std::string> decimals_ascii_list = base::SplitString(
1305 addr_ascii, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
1306 EXPECT_EQ(4U, decimals_ascii_list.size()) << i;
1307 std::string addr_bytes;
1308 for (const auto& decimals_ascii : decimals_ascii_list) {
1309 int decimal_value;
1310 EXPECT_TRUE(base::StringToInt(decimals_ascii, &decimal_value));
1311 EXPECT_GE(decimal_value, 0);
1312 EXPECT_LE(decimal_value, 255);
1313 addr_bytes.push_back(static_cast<char>(decimal_value));
1314 }
1315 ip_addressses.push_back(addr_bytes);
1316 ASSERT_EQ(4U, ip_addressses.back().size()) << i;
1317 }
1318 }
1319 }
1320
1321 EXPECT_EQ(test_data.expected,
1322 X509Certificate::VerifyHostname(test_data.hostname, dns_names,
1323 ip_addressses));
1324 }
1325
1326 INSTANTIATE_TEST_SUITE_P(All,
1327 X509CertificateNameVerifyTest,
1328 testing::ValuesIn(kNameVerifyTestData));
1329
1330 const struct PublicKeyInfoTestData {
1331 const char* cert_file;
1332 size_t expected_bits;
1333 X509Certificate::PublicKeyType expected_type;
1334 } kPublicKeyInfoTestData[] = {
1335 {"768-rsa-ee-by-768-rsa-intermediate.pem", 768,
1336 X509Certificate::kPublicKeyTypeRSA},
1337 {"1024-rsa-ee-by-768-rsa-intermediate.pem", 1024,
1338 X509Certificate::kPublicKeyTypeRSA},
1339 {"prime256v1-ecdsa-ee-by-1024-rsa-intermediate.pem", 256,
1340 X509Certificate::kPublicKeyTypeECDSA},
1341 {"large_key.pem", 8200, X509Certificate::kPublicKeyTypeRSA},
1342 };
1343
1344 class X509CertificatePublicKeyInfoTest
1345 : public testing::TestWithParam<PublicKeyInfoTestData> {
1346 };
1347
TEST_P(X509CertificatePublicKeyInfoTest,GetPublicKeyInfo)1348 TEST_P(X509CertificatePublicKeyInfoTest, GetPublicKeyInfo) {
1349 PublicKeyInfoTestData data = GetParam();
1350
1351 scoped_refptr<X509Certificate> cert(
1352 ImportCertFromFile(GetTestCertsDirectory(), data.cert_file));
1353 ASSERT_TRUE(cert.get());
1354
1355 size_t actual_bits = 0;
1356 X509Certificate::PublicKeyType actual_type =
1357 X509Certificate::kPublicKeyTypeUnknown;
1358
1359 X509Certificate::GetPublicKeyInfo(cert->cert_buffer(), &actual_bits,
1360 &actual_type);
1361
1362 EXPECT_EQ(data.expected_bits, actual_bits);
1363 EXPECT_EQ(data.expected_type, actual_type);
1364 }
1365
1366 INSTANTIATE_TEST_SUITE_P(All,
1367 X509CertificatePublicKeyInfoTest,
1368 testing::ValuesIn(kPublicKeyInfoTestData));
1369
1370 } // namespace net
1371