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