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