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