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