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