1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/cert/ev_root_ca_metadata.h"
6 
7 #if defined(OS_WIN)
8 #include <stdlib.h>
9 #endif
10 
11 #include <algorithm>
12 
13 #include "base/lazy_instance.h"
14 #include "base/logging.h"
15 #include "base/strings/string_piece.h"
16 #include "net/der/input.h"
17 #if defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
18 #include "third_party/boringssl/src/include/openssl/bytestring.h"
19 #include "third_party/boringssl/src/include/openssl/mem.h"
20 #endif
21 
22 namespace net {
23 
24 namespace {
25 #if defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
26 // Raw metadata.
27 struct EVMetadata {
28   // kMaxOIDsPerCA is the number of OIDs that we can support per root CA. At
29   // least one CA has different EV policies for business vs government
30   // entities and, in the case of cross-signing, we might need to list another
31   // CA's policy OID under the cross-signing root.
32   static const size_t kMaxOIDsPerCA = 2;
33 
34   // The SHA-256 fingerprint of the root CA certificate, used as a unique
35   // identifier for a root CA certificate.
36   SHA256HashValue fingerprint;
37 
38   // The EV policy OIDs of the root CA.
39   const base::StringPiece policy_oids[kMaxOIDsPerCA];
40 };
41 
42 // These certificates may be found in net/data/ssl/ev_roots.
43 static const EVMetadata kEvRootCaMetadata[] = {
44     // AC Camerfirma S.A. Chambers of Commerce Root - 2008
45     // https://www.camerfirma.com
46     {
47         {{0x06, 0x3e, 0x4a, 0xfa, 0xc4, 0x91, 0xdf, 0xd3, 0x32, 0xf3, 0x08,
48           0x9b, 0x85, 0x42, 0xe9, 0x46, 0x17, 0xd8, 0x93, 0xd7, 0xfe, 0x94,
49           0x4e, 0x10, 0xa7, 0x93, 0x7e, 0xe2, 0x9d, 0x96, 0x93, 0xc0}},
50         {
51             // AC Camerfirma uses the last two arcs to track how the private key
52             // is managed - the effective verification policy is the same.
53             "1.3.6.1.4.1.17326.10.14.2.1.2",
54             "1.3.6.1.4.1.17326.10.14.2.2.2",
55         },
56     },
57     // AddTrust External CA Root
58     // https://addtrustexternalcaroot-ev.comodoca.com
59     {
60         {{0x68, 0x7f, 0xa4, 0x51, 0x38, 0x22, 0x78, 0xff, 0xf0, 0xc8, 0xb1,
61           0x1f, 0x8d, 0x43, 0xd5, 0x76, 0x67, 0x1c, 0x6e, 0xb2, 0xbc, 0xea,
62           0xb4, 0x13, 0xfb, 0x83, 0xd9, 0x65, 0xd0, 0x6d, 0x2f, 0xf2}},
63         {
64             "1.3.6.1.4.1.6449.1.2.1.5.1",
65             // This is the Network Solutions EV OID. However, this root
66             // cross-certifies NetSol and so we need it here too.
67             "1.3.6.1.4.1.782.1.2.1.8.1",
68         },
69     },
70     // Actalis Authentication Root CA
71     // https://ssltest-a.actalis.it:8443
72     {
73         {{0x55, 0x92, 0x60, 0x84, 0xec, 0x96, 0x3a, 0x64, 0xb9, 0x6e, 0x2a,
74           0xbe, 0x01, 0xce, 0x0b, 0xa8, 0x6a, 0x64, 0xfb, 0xfe, 0xbc, 0xc7,
75           0xaa, 0xb5, 0xaf, 0xc1, 0x55, 0xb3, 0x7f, 0xd7, 0x60, 0x66}},
76         {"1.3.159.1.17.1", ""},
77     },
78     // AffirmTrust Commercial
79     // https://commercial.affirmtrust.com/
80     {
81         {{0x03, 0x76, 0xab, 0x1d, 0x54, 0xc5, 0xf9, 0x80, 0x3c, 0xe4, 0xb2,
82           0xe2, 0x01, 0xa0, 0xee, 0x7e, 0xef, 0x7b, 0x57, 0xb6, 0x36, 0xe8,
83           0xa9, 0x3c, 0x9b, 0x8d, 0x48, 0x60, 0xc9, 0x6f, 0x5f, 0xa7}},
84         {"1.3.6.1.4.1.34697.2.1", ""},
85     },
86     // AffirmTrust Networking
87     // https://networking.affirmtrust.com:4431
88     {
89         {{0x0a, 0x81, 0xec, 0x5a, 0x92, 0x97, 0x77, 0xf1, 0x45, 0x90, 0x4a,
90           0xf3, 0x8d, 0x5d, 0x50, 0x9f, 0x66, 0xb5, 0xe2, 0xc5, 0x8f, 0xcd,
91           0xb5, 0x31, 0x05, 0x8b, 0x0e, 0x17, 0xf3, 0xf0, 0xb4, 0x1b}},
92         {"1.3.6.1.4.1.34697.2.2", ""},
93     },
94     // AffirmTrust Premium
95     // https://premium.affirmtrust.com:4432/
96     {
97         {{0x70, 0xa7, 0x3f, 0x7f, 0x37, 0x6b, 0x60, 0x07, 0x42, 0x48, 0x90,
98           0x45, 0x34, 0xb1, 0x14, 0x82, 0xd5, 0xbf, 0x0e, 0x69, 0x8e, 0xcc,
99           0x49, 0x8d, 0xf5, 0x25, 0x77, 0xeb, 0xf2, 0xe9, 0x3b, 0x9a}},
100         {"1.3.6.1.4.1.34697.2.3", ""},
101     },
102     // AffirmTrust Premium ECC
103     // https://premiumecc.affirmtrust.com:4433/
104     {
105         {{0xbd, 0x71, 0xfd, 0xf6, 0xda, 0x97, 0xe4, 0xcf, 0x62, 0xd1, 0x64,
106           0x7a, 0xdd, 0x25, 0x81, 0xb0, 0x7d, 0x79, 0xad, 0xf8, 0x39, 0x7e,
107           0xb4, 0xec, 0xba, 0x9c, 0x5e, 0x84, 0x88, 0x82, 0x14, 0x23}},
108         {"1.3.6.1.4.1.34697.2.4", ""},
109     },
110     // Amazon Root CA 1
111     // https://good.sca1a.amazontrust.com/
112     {
113         {{0x8e, 0xcd, 0xe6, 0x88, 0x4f, 0x3d, 0x87, 0xb1, 0x12, 0x5b, 0xa3,
114           0x1a, 0xc3, 0xfc, 0xb1, 0x3d, 0x70, 0x16, 0xde, 0x7f, 0x57, 0xcc,
115           0x90, 0x4f, 0xe1, 0xcb, 0x97, 0xc6, 0xae, 0x98, 0x19, 0x6e}},
116         {"2.23.140.1.1", ""},
117     },
118     // Amazon Root CA 2
119     // https://good.sca2a.amazontrust.com/
120     {
121         {{0x1b, 0xa5, 0xb2, 0xaa, 0x8c, 0x65, 0x40, 0x1a, 0x82, 0x96, 0x01,
122           0x18, 0xf8, 0x0b, 0xec, 0x4f, 0x62, 0x30, 0x4d, 0x83, 0xce, 0xc4,
123           0x71, 0x3a, 0x19, 0xc3, 0x9c, 0x01, 0x1e, 0xa4, 0x6d, 0xb4}},
124         {"2.23.140.1.1", ""},
125     },
126     // Amazon Root CA 3
127     // https://good.sca3a.amazontrust.com/
128     {
129         {{0x18, 0xce, 0x6c, 0xfe, 0x7b, 0xf1, 0x4e, 0x60, 0xb2, 0xe3, 0x47,
130           0xb8, 0xdf, 0xe8, 0x68, 0xcb, 0x31, 0xd0, 0x2e, 0xbb, 0x3a, 0xda,
131           0x27, 0x15, 0x69, 0xf5, 0x03, 0x43, 0xb4, 0x6d, 0xb3, 0xa4}},
132         {"2.23.140.1.1", ""},
133     },
134     // Amazon Root CA 4
135     // https://good.sca4a.amazontrust.com/
136     {
137         {{0xe3, 0x5d, 0x28, 0x41, 0x9e, 0xd0, 0x20, 0x25, 0xcf, 0xa6, 0x90,
138           0x38, 0xcd, 0x62, 0x39, 0x62, 0x45, 0x8d, 0xa5, 0xc6, 0x95, 0xfb,
139           0xde, 0xa3, 0xc2, 0x2b, 0x0b, 0xfb, 0x25, 0x89, 0x70, 0x92}},
140         {"2.23.140.1.1", ""},
141     },
142     // Autoridad de Certificacion Firmaprofesional CIF A62634068
143     // https://publifirma.firmaprofesional.com/
144     {
145         {{0x04, 0x04, 0x80, 0x28, 0xbf, 0x1f, 0x28, 0x64, 0xd4, 0x8f, 0x9a,
146           0xd4, 0xd8, 0x32, 0x94, 0x36, 0x6a, 0x82, 0x88, 0x56, 0x55, 0x3f,
147           0x3b, 0x14, 0x30, 0x3f, 0x90, 0x14, 0x7f, 0x5d, 0x40, 0xef}},
148         {"1.3.6.1.4.1.13177.10.1.3.10", ""},
149     },
150     // Baltimore CyberTrust Root
151     // https://secure.omniroot.com/repository/
152     {
153         {{0x16, 0xaf, 0x57, 0xa9, 0xf6, 0x76, 0xb0, 0xab, 0x12, 0x60, 0x95,
154           0xaa, 0x5e, 0xba, 0xde, 0xf2, 0x2a, 0xb3, 0x11, 0x19, 0xd6, 0x44,
155           0xac, 0x95, 0xcd, 0x4b, 0x93, 0xdb, 0xf3, 0xf2, 0x6a, 0xeb}},
156         {"1.3.6.1.4.1.6334.1.100.1", ""},
157     },
158     // Buypass Class 3 Root CA
159     // https://valid.evident.ca23.ssl.buypass.no/
160     {
161         {{0xed, 0xf7, 0xeb, 0xbc, 0xa2, 0x7a, 0x2a, 0x38, 0x4d, 0x38, 0x7b,
162           0x7d, 0x40, 0x10, 0xc6, 0x66, 0xe2, 0xed, 0xb4, 0x84, 0x3e, 0x4c,
163           0x29, 0xb4, 0xae, 0x1d, 0x5b, 0x93, 0x32, 0xe6, 0xb2, 0x4d}},
164         {"2.16.578.1.26.1.3.3", ""},
165     },
166     // Certum Trusted Network CA
167     // https://juice.certum.pl/
168     {
169         {{0x5c, 0x58, 0x46, 0x8d, 0x55, 0xf5, 0x8e, 0x49, 0x7e, 0x74, 0x39,
170           0x82, 0xd2, 0xb5, 0x00, 0x10, 0xb6, 0xd1, 0x65, 0x37, 0x4a, 0xcf,
171           0x83, 0xa7, 0xd4, 0xa3, 0x2d, 0xb7, 0x68, 0xc4, 0x40, 0x8e}},
172         {"1.2.616.1.113527.2.5.1.1", ""},
173     },
174     // CFCA EV ROOT
175     // https://www.erenepu.com/
176     {
177         {{0x5c, 0xc3, 0xd7, 0x8e, 0x4e, 0x1d, 0x5e, 0x45, 0x54, 0x7a, 0x04,
178           0xe6, 0x87, 0x3e, 0x64, 0xf9, 0x0c, 0xf9, 0x53, 0x6d, 0x1c, 0xcc,
179           0x2e, 0xf8, 0x00, 0xf3, 0x55, 0xc4, 0xc5, 0xfd, 0x70, 0xfd}},
180         {"2.16.156.112554.3", ""},
181     },
182     // COMODO Certification Authority
183     // https://secure.comodo.com/
184     {
185         {{0x0c, 0x2c, 0xd6, 0x3d, 0xf7, 0x80, 0x6f, 0xa3, 0x99, 0xed, 0xe8,
186           0x09, 0x11, 0x6b, 0x57, 0x5b, 0xf8, 0x79, 0x89, 0xf0, 0x65, 0x18,
187           0xf9, 0x80, 0x8c, 0x86, 0x05, 0x03, 0x17, 0x8b, 0xaf, 0x66}},
188         {"1.3.6.1.4.1.6449.1.2.1.5.1", ""},
189     },
190     // COMODO Certification Authority (reissued certificate with NotBefore of
191     // Jan 1 00:00:00 2011 GMT)
192     // https://secure.comodo.com/
193     {
194         {{0x1a, 0x0d, 0x20, 0x44, 0x5d, 0xe5, 0xba, 0x18, 0x62, 0xd1, 0x9e,
195           0xf8, 0x80, 0x85, 0x8c, 0xbc, 0xe5, 0x01, 0x02, 0xb3, 0x6e, 0x8f,
196           0x0a, 0x04, 0x0c, 0x3c, 0x69, 0xe7, 0x45, 0x22, 0xfe, 0x6e}},
197         {"1.3.6.1.4.1.6449.1.2.1.5.1", ""},
198     },
199     // COMODO ECC Certification Authority
200     // https://comodoecccertificationauthority-ev.comodoca.com/
201     {
202         {{0x17, 0x93, 0x92, 0x7a, 0x06, 0x14, 0x54, 0x97, 0x89, 0xad, 0xce,
203           0x2f, 0x8f, 0x34, 0xf7, 0xf0, 0xb6, 0x6d, 0x0f, 0x3a, 0xe3, 0xa3,
204           0xb8, 0x4d, 0x21, 0xec, 0x15, 0xdb, 0xba, 0x4f, 0xad, 0xc7}},
205         {"1.3.6.1.4.1.6449.1.2.1.5.1", ""},
206     },
207     // COMODO RSA Certification Authority
208     // https://comodorsacertificationauthority-ev.comodoca.com/
209     {
210         {{0x52, 0xf0, 0xe1, 0xc4, 0xe5, 0x8e, 0xc6, 0x29, 0x29, 0x1b, 0x60,
211           0x31, 0x7f, 0x07, 0x46, 0x71, 0xb8, 0x5d, 0x7e, 0xa8, 0x0d, 0x5b,
212           0x07, 0x27, 0x34, 0x63, 0x53, 0x4b, 0x32, 0xb4, 0x02, 0x34}},
213         {"1.3.6.1.4.1.6449.1.2.1.5.1", ""},
214     },
215     // Cybertrust Global Root
216     // https://evup.cybertrust.ne.jp/ctj-ev-upgrader/evseal.gif
217     {
218         {{0x96, 0x0a, 0xdf, 0x00, 0x63, 0xe9, 0x63, 0x56, 0x75, 0x0c, 0x29,
219           0x65, 0xdd, 0x0a, 0x08, 0x67, 0xda, 0x0b, 0x9c, 0xbd, 0x6e, 0x77,
220           0x71, 0x4a, 0xea, 0xfb, 0x23, 0x49, 0xab, 0x39, 0x3d, 0xa3}},
221         {"1.3.6.1.4.1.6334.1.100.1", ""},
222     },
223     // DigiCert Assured ID Root CA
224     // https://assured-id-root-ca.chain-demos.digicert.com/
225     {
226         {{0x3e, 0x90, 0x99, 0xb5, 0x01, 0x5e, 0x8f, 0x48, 0x6c, 0x00, 0xbc,
227           0xea, 0x9d, 0x11, 0x1e, 0xe7, 0x21, 0xfa, 0xba, 0x35, 0x5a, 0x89,
228           0xbc, 0xf1, 0xdf, 0x69, 0x56, 0x1e, 0x3d, 0xc6, 0x32, 0x5c}},
229         {"2.16.840.1.114412.2.1", ""},
230     },
231     // DigiCert Assured ID Root G2
232     // https://assured-id-root-g2.chain-demos.digicert.com/
233     {
234         {{0x7d, 0x05, 0xeb, 0xb6, 0x82, 0x33, 0x9f, 0x8c, 0x94, 0x51, 0xee,
235           0x09, 0x4e, 0xeb, 0xfe, 0xfa, 0x79, 0x53, 0xa1, 0x14, 0xed, 0xb2,
236           0xf4, 0x49, 0x49, 0x45, 0x2f, 0xab, 0x7d, 0x2f, 0xc1, 0x85}},
237         {"2.16.840.1.114412.2.1", ""},
238     },
239     // DigiCert Assured ID Root G3
240     // https://assured-id-root-g3.chain-demos.digicert.com/
241     {
242         {{0x7e, 0x37, 0xcb, 0x8b, 0x4c, 0x47, 0x09, 0x0c, 0xab, 0x36, 0x55,
243           0x1b, 0xa6, 0xf4, 0x5d, 0xb8, 0x40, 0x68, 0x0f, 0xba, 0x16, 0x6a,
244           0x95, 0x2d, 0xb1, 0x00, 0x71, 0x7f, 0x43, 0x05, 0x3f, 0xc2}},
245         {"2.16.840.1.114412.2.1", ""},
246     },
247     // DigiCert Global Root CA
248     // https://global-root-ca.chain-demos.digicert.com/
249     {
250         {{0x43, 0x48, 0xa0, 0xe9, 0x44, 0x4c, 0x78, 0xcb, 0x26, 0x5e, 0x05,
251           0x8d, 0x5e, 0x89, 0x44, 0xb4, 0xd8, 0x4f, 0x96, 0x62, 0xbd, 0x26,
252           0xdb, 0x25, 0x7f, 0x89, 0x34, 0xa4, 0x43, 0xc7, 0x01, 0x61}},
253         {"2.16.840.1.114412.2.1", ""},
254     },
255     // DigiCert Global Root G2
256     // https://global-root-g2.chain-demos.digicert.com/
257     {
258         {{0xcb, 0x3c, 0xcb, 0xb7, 0x60, 0x31, 0xe5, 0xe0, 0x13, 0x8f, 0x8d,
259           0xd3, 0x9a, 0x23, 0xf9, 0xde, 0x47, 0xff, 0xc3, 0x5e, 0x43, 0xc1,
260           0x14, 0x4c, 0xea, 0x27, 0xd4, 0x6a, 0x5a, 0xb1, 0xcb, 0x5f}},
261         {"2.16.840.1.114412.2.1", ""},
262     },
263     // DigiCert Global Root G3
264     // https://global-root-g3.chain-demos.digicert.com/
265     {
266         {{0x31, 0xad, 0x66, 0x48, 0xf8, 0x10, 0x41, 0x38, 0xc7, 0x38, 0xf3,
267           0x9e, 0xa4, 0x32, 0x01, 0x33, 0x39, 0x3e, 0x3a, 0x18, 0xcc, 0x02,
268           0x29, 0x6e, 0xf9, 0x7c, 0x2a, 0xc9, 0xef, 0x67, 0x31, 0xd0}},
269         {"2.16.840.1.114412.2.1", ""},
270     },
271     // DigiCert High Assurance EV Root CA
272     // https://www.digicert.com
273     {
274         {{0x74, 0x31, 0xe5, 0xf4, 0xc3, 0xc1, 0xce, 0x46, 0x90, 0x77, 0x4f,
275           0x0b, 0x61, 0xe0, 0x54, 0x40, 0x88, 0x3b, 0xa9, 0xa0, 0x1e, 0xd0,
276           0x0b, 0xa6, 0xab, 0xd7, 0x80, 0x6e, 0xd3, 0xb1, 0x18, 0xcf}},
277         {"2.16.840.1.114412.2.1", ""},
278     },
279     // DigiCert Trusted Root G4
280     // https://trusted-root-g4.chain-demos.digicert.com/
281     {
282         {{0x55, 0x2f, 0x7b, 0xdc, 0xf1, 0xa7, 0xaf, 0x9e, 0x6c, 0xe6, 0x72,
283           0x01, 0x7f, 0x4f, 0x12, 0xab, 0xf7, 0x72, 0x40, 0xc7, 0x8e, 0x76,
284           0x1a, 0xc2, 0x03, 0xd1, 0xd9, 0xd2, 0x0a, 0xc8, 0x99, 0x88}},
285         {"2.16.840.1.114412.2.1", ""},
286     },
287     // D-TRUST Root Class 3 CA 2 EV 2009
288     // https://certdemo-ev-valid.ssl.d-trust.net/
289     {
290         {{0xee, 0xc5, 0x49, 0x6b, 0x98, 0x8c, 0xe9, 0x86, 0x25, 0xb9, 0x34,
291           0x09, 0x2e, 0xec, 0x29, 0x08, 0xbe, 0xd0, 0xb0, 0xf3, 0x16, 0xc2,
292           0xd4, 0x73, 0x0c, 0x84, 0xea, 0xf1, 0xf3, 0xd3, 0x48, 0x81}},
293         {"1.3.6.1.4.1.4788.2.202.1", ""},
294     },
295     // emSign Root CA - G1
296     // https://testevg1.emsign.com/
297     {
298         {{0x40, 0xf6, 0xaf, 0x03, 0x46, 0xa9, 0x9a, 0xa1, 0xcd, 0x1d, 0x55,
299           0x5a, 0x4e, 0x9c, 0xce, 0x62, 0xc7, 0xf9, 0x63, 0x46, 0x03, 0xee,
300           0x40, 0x66, 0x15, 0x83, 0x3d, 0xc8, 0xc8, 0xd0, 0x03, 0x67}},
301         {"2.23.140.1.1", ""},
302     },
303     // Entrust Root Certification Authority
304     // https://www.entrust.net/
305     {
306         {{0x73, 0xc1, 0x76, 0x43, 0x4f, 0x1b, 0xc6, 0xd5, 0xad, 0xf4, 0x5b,
307           0x0e, 0x76, 0xe7, 0x27, 0x28, 0x7c, 0x8d, 0xe5, 0x76, 0x16, 0xc1,
308           0xe6, 0xe6, 0x14, 0x1a, 0x2b, 0x2c, 0xbc, 0x7d, 0x8e, 0x4c}},
309         {"2.16.840.1.114028.10.1.2", ""},
310     },
311     // Entrust Root Certification Authority – G2
312     // https://validg2.entrust.net
313     {
314         {{0x43, 0xdf, 0x57, 0x74, 0xb0, 0x3e, 0x7f, 0xef, 0x5f, 0xe4, 0x0d,
315           0x93, 0x1a, 0x7b, 0xed, 0xf1, 0xbb, 0x2e, 0x6b, 0x42, 0x73, 0x8c,
316           0x4e, 0x6d, 0x38, 0x41, 0x10, 0x3d, 0x3a, 0xa7, 0xf3, 0x39}},
317         {"2.16.840.1.114028.10.1.2", ""},
318     },
319     // Entrust Root Certification Authority – EC1
320     // https://validec.entrust.net
321     {
322         {{0x02, 0xed, 0x0e, 0xb2, 0x8c, 0x14, 0xda, 0x45, 0x16, 0x5c, 0x56,
323           0x67, 0x91, 0x70, 0x0d, 0x64, 0x51, 0xd7, 0xfb, 0x56, 0xf0, 0xb2,
324           0xab, 0x1d, 0x3b, 0x8e, 0xb0, 0x70, 0xe5, 0x6e, 0xdf, 0xf5}},
325         {"2.16.840.1.114028.10.1.2", ""},
326     },
327     // E-Tugra Certification Authority
328     // https://sslev.e-tugra.com.tr
329     {
330         {{0xb0, 0xbf, 0xd5, 0x2b, 0xb0, 0xd7, 0xd9, 0xbd, 0x92, 0xbf, 0x5d,
331           0x4d, 0xc1, 0x3d, 0xa2, 0x55, 0xc0, 0x2c, 0x54, 0x2f, 0x37, 0x83,
332           0x65, 0xea, 0x89, 0x39, 0x11, 0xf5, 0x5e, 0x55, 0xf2, 0x3c}},
333         {"2.16.792.3.0.4.1.1.4", ""},
334     },
335     // GlobalSign Root CA
336     {
337         {{0xeb, 0xd4, 0x10, 0x40, 0xe4, 0xbb, 0x3e, 0xc7, 0x42, 0xc9, 0xe3,
338           0x81, 0xd3, 0x1e, 0xf2, 0xa4, 0x1a, 0x48, 0xb6, 0x68, 0x5c, 0x96,
339           0xe7, 0xce, 0xf3, 0xc1, 0xdf, 0x6c, 0xd4, 0x33, 0x1c, 0x99}},
340         {"1.3.6.1.4.1.4146.1.1", ""},
341     },
342     // GlobalSign Root CA - R3
343     // https://2029.globalsign.com/
344     {
345         {{0xcb, 0xb5, 0x22, 0xd7, 0xb7, 0xf1, 0x27, 0xad, 0x6a, 0x01, 0x13,
346           0x86, 0x5b, 0xdf, 0x1c, 0xd4, 0x10, 0x2e, 0x7d, 0x07, 0x59, 0xaf,
347           0x63, 0x5a, 0x7c, 0xf4, 0x72, 0x0d, 0xc9, 0x63, 0xc5, 0x3b}},
348         {"1.3.6.1.4.1.4146.1.1", ""},
349     },
350     // GlobalSign ECC Root CA - R5
351     // https://2038r5.globalsign.com/
352     {
353         {{0x17, 0x9f, 0xbc, 0x14, 0x8a, 0x3d, 0xd0, 0x0f, 0xd2, 0x4e, 0xa1,
354           0x34, 0x58, 0xcc, 0x43, 0xbf, 0xa7, 0xf5, 0x9c, 0x81, 0x82, 0xd7,
355           0x83, 0xa5, 0x13, 0xf6, 0xeb, 0xec, 0x10, 0x0c, 0x89, 0x24}},
356         {"1.3.6.1.4.1.4146.1.1", ""},
357     },
358     // Go Daddy Class 2 Certification Authority
359     // https://www.godaddy.com/
360     {
361         {{0xc3, 0x84, 0x6b, 0xf2, 0x4b, 0x9e, 0x93, 0xca, 0x64, 0x27, 0x4c,
362           0x0e, 0xc6, 0x7c, 0x1e, 0xcc, 0x5e, 0x02, 0x4f, 0xfc, 0xac, 0xd2,
363           0xd7, 0x40, 0x19, 0x35, 0x0e, 0x81, 0xfe, 0x54, 0x6a, 0xe4}},
364         {"2.16.840.1.114413.1.7.23.3", ""},
365     },
366     // Go Daddy Root Certificate Authority - G2
367     // https://valid.gdig2.catest.godaddy.com/
368     {
369         {{0x45, 0x14, 0x0b, 0x32, 0x47, 0xeb, 0x9c, 0xc8, 0xc5, 0xb4, 0xf0,
370           0xd7, 0xb5, 0x30, 0x91, 0xf7, 0x32, 0x92, 0x08, 0x9e, 0x6e, 0x5a,
371           0x63, 0xe2, 0x74, 0x9d, 0xd3, 0xac, 0xa9, 0x19, 0x8e, 0xda}},
372         {"2.16.840.1.114413.1.7.23.3", ""},
373     },
374     // Hongkong Post Root CA 3
375     // https://valid-ev.ecert.gov.hk/
376     {
377         {{0x5a, 0x2f, 0xc0, 0x3f, 0x0c, 0x83, 0xb0, 0x90, 0xbb, 0xfa, 0x40,
378           0x60, 0x4b, 0x09, 0x88, 0x44, 0x6c, 0x76, 0x36, 0x18, 0x3d, 0xf9,
379           0x84, 0x6e, 0x17, 0x10, 0x1a, 0x44, 0x7f, 0xb8, 0xef, 0xd6}},
380         {"2.23.140.1.1", ""},
381     },
382     // Izenpe.com - SHA256 root
383     // The first OID is for businesses and the second for government entities.
384     // These are the test sites, respectively:
385     // https://servicios.izenpe.com
386     // https://servicios1.izenpe.com
387     {
388         {{0x25, 0x30, 0xcc, 0x8e, 0x98, 0x32, 0x15, 0x02, 0xba, 0xd9, 0x6f,
389           0x9b, 0x1f, 0xba, 0x1b, 0x09, 0x9e, 0x2d, 0x29, 0x9e, 0x0f, 0x45,
390           0x48, 0xbb, 0x91, 0x4f, 0x36, 0x3b, 0xc0, 0xd4, 0x53, 0x1f}},
391         {"1.3.6.1.4.1.14777.6.1.1", "1.3.6.1.4.1.14777.6.1.2"},
392     },
393     // Izenpe.com - SHA1 root
394     // Windows XP finds this, SHA1, root instead. The policy OIDs are the same
395     // as for the SHA256 root, above.
396     {
397         {{0x23, 0x80, 0x42, 0x03, 0xca, 0x45, 0xd8, 0xcd, 0xe7, 0x16, 0xb8,
398           0xc1, 0x3b, 0xf3, 0xb4, 0x48, 0x45, 0x7f, 0xa0, 0x6c, 0xc1, 0x02,
399           0x50, 0x99, 0x7f, 0xa0, 0x14, 0x58, 0x31, 0x7c, 0x41, 0xe5}},
400         {"1.3.6.1.4.1.14777.6.1.1", "1.3.6.1.4.1.14777.6.1.2"},
401     },
402     // LuxTrust Global Root 2
403     // https://ltsslca5.trustme.lu/
404     {
405         {{0x54, 0x45, 0x5f, 0x71, 0x29, 0xc2, 0x0b, 0x14, 0x47, 0xc4, 0x18,
406           0xf9, 0x97, 0x16, 0x8f, 0x24, 0xc5, 0x8f, 0xc5, 0x02, 0x3b, 0xf5,
407           0xda, 0x5b, 0xe2, 0xeb, 0x6e, 0x1d, 0xd8, 0x90, 0x2e, 0xd5}},
408         {"1.3.171.1.1.10.5.2", ""},
409     },
410     // Network Solutions Certificate Authority
411     // https://www.networksolutions.com/website-packages/index.jsp
412     {
413         {{0x15, 0xf0, 0xba, 0x00, 0xa3, 0xac, 0x7a, 0xf3, 0xac, 0x88, 0x4c,
414           0x07, 0x2b, 0x10, 0x11, 0xa0, 0x77, 0xbd, 0x77, 0xc0, 0x97, 0xf4,
415           0x01, 0x64, 0xb2, 0xf8, 0x59, 0x8a, 0xbd, 0x83, 0x86, 0x0c}},
416         {"1.3.6.1.4.1.782.1.2.1.8.1", ""},
417     },
418     // Network Solutions Certificate Authority (reissued certificate with
419     // NotBefore of Jan  1 00:00:00 2011 GMT).
420     // https://www.networksolutions.com/website-packages/index.jsp
421     {
422         {{0x00, 0x16, 0x86, 0xcd, 0x18, 0x1f, 0x83, 0xa1, 0xb1, 0x21, 0x7d,
423           0x30, 0x5b, 0x36, 0x5c, 0x41, 0xe3, 0x47, 0x0a, 0x78, 0xa1, 0xd3,
424           0x7b, 0x13, 0x4a, 0x98, 0xcd, 0x54, 0x7b, 0x92, 0xda, 0xb3}},
425         {"1.3.6.1.4.1.782.1.2.1.8.1", ""},
426     },
427     // OISTE WISeKey Global Root GB CA
428     // https://goodevssl.wisekey.com
429     {
430         {{0x6b, 0x9c, 0x08, 0xe8, 0x6e, 0xb0, 0xf7, 0x67, 0xcf, 0xad, 0x65,
431           0xcd, 0x98, 0xb6, 0x21, 0x49, 0xe5, 0x49, 0x4a, 0x67, 0xf5, 0x84,
432           0x5e, 0x7b, 0xd1, 0xed, 0x01, 0x9f, 0x27, 0xb8, 0x6b, 0xd6}},
433         {"2.16.756.5.14.7.4.8", ""},
434     },
435     // QuoVadis Root CA 2
436     // https://www.quovadis.bm/
437     {
438         {{0x85, 0xa0, 0xdd, 0x7d, 0xd7, 0x20, 0xad, 0xb7, 0xff, 0x05, 0xf8,
439           0x3d, 0x54, 0x2b, 0x20, 0x9d, 0xc7, 0xff, 0x45, 0x28, 0xf7, 0xd6,
440           0x77, 0xb1, 0x83, 0x89, 0xfe, 0xa5, 0xe5, 0xc4, 0x9e, 0x86}},
441         {"1.3.6.1.4.1.8024.0.2.100.1.2", ""},
442     },
443     // QuoVadis Root CA 2 G3
444     // https://evsslicag3-v.quovadisglobal.com/
445     {
446         {{0x8f, 0xe4, 0xfb, 0x0a, 0xf9, 0x3a, 0x4d, 0x0d, 0x67, 0xdb, 0x0b,
447           0xeb, 0xb2, 0x3e, 0x37, 0xc7, 0x1b, 0xf3, 0x25, 0xdc, 0xbc, 0xdd,
448           0x24, 0x0e, 0xa0, 0x4d, 0xaf, 0x58, 0xb4, 0x7e, 0x18, 0x40}},
449         {"1.3.6.1.4.1.8024.0.2.100.1.2", ""},
450     },
451     // SecureTrust CA, SecureTrust Corporation
452     // https://www.securetrust.com
453     // https://www.trustwave.com/
454     {
455         {{0xf1, 0xc1, 0xb5, 0x0a, 0xe5, 0xa2, 0x0d, 0xd8, 0x03, 0x0e, 0xc9,
456           0xf6, 0xbc, 0x24, 0x82, 0x3d, 0xd3, 0x67, 0xb5, 0x25, 0x57, 0x59,
457           0xb4, 0xe7, 0x1b, 0x61, 0xfc, 0xe9, 0xf7, 0x37, 0x5d, 0x73}},
458         {"2.16.840.1.114404.1.1.2.4.1", ""},
459     },
460     // Secure Global CA, SecureTrust Corporation
461     {
462         {{0x42, 0x00, 0xf5, 0x04, 0x3a, 0xc8, 0x59, 0x0e, 0xbb, 0x52, 0x7d,
463           0x20, 0x9e, 0xd1, 0x50, 0x30, 0x29, 0xfb, 0xcb, 0xd4, 0x1c, 0xa1,
464           0xb5, 0x06, 0xec, 0x27, 0xf1, 0x5a, 0xde, 0x7d, 0xac, 0x69}},
465         {"2.16.840.1.114404.1.1.2.4.1", ""},
466     },
467     // Security Communication RootCA1
468     // https://www.secomtrust.net/contact/form.html
469     {
470         {{0xe7, 0x5e, 0x72, 0xed, 0x9f, 0x56, 0x0e, 0xec, 0x6e, 0xb4, 0x80,
471           0x00, 0x73, 0xa4, 0x3f, 0xc3, 0xad, 0x19, 0x19, 0x5a, 0x39, 0x22,
472           0x82, 0x01, 0x78, 0x95, 0x97, 0x4a, 0x99, 0x02, 0x6b, 0x6c}},
473         {"1.2.392.200091.100.721.1", ""},
474     },
475     // Security Communication EV RootCA2
476     // https://www.secomtrust.net/contact/form.html
477     {
478         {{0x51, 0x3b, 0x2c, 0xec, 0xb8, 0x10, 0xd4, 0xcd, 0xe5, 0xdd, 0x85,
479           0x39, 0x1a, 0xdf, 0xc6, 0xc2, 0xdd, 0x60, 0xd8, 0x7b, 0xb7, 0x36,
480           0xd2, 0xb5, 0x21, 0x48, 0x4a, 0xa4, 0x7a, 0x0e, 0xbe, 0xf6}},
481         {"1.2.392.200091.100.721.1", ""},
482     },
483     // SSL.com EV Root Certification Authority ECC
484     // https://test-ev-ecc.ssl.com/
485     {
486         {{0x22, 0xa2, 0xc1, 0xf7, 0xbd, 0xed, 0x70, 0x4c, 0xc1, 0xe7, 0x01,
487           0xb5, 0xf4, 0x08, 0xc3, 0x10, 0x88, 0x0f, 0xe9, 0x56, 0xb5, 0xde,
488           0x2a, 0x4a, 0x44, 0xf9, 0x9c, 0x87, 0x3a, 0x25, 0xa7, 0xc8}},
489         {"2.23.140.1.1", ""},
490     },
491     // SSL.com EV Root Certification Authority RSA R2
492     // https://test-ev-rsa.ssl.com/
493     {
494         {{0x2e, 0x7b, 0xf1, 0x6c, 0xc2, 0x24, 0x85, 0xa7, 0xbb, 0xe2, 0xaa,
495           0x86, 0x96, 0x75, 0x07, 0x61, 0xb0, 0xae, 0x39, 0xbe, 0x3b, 0x2f,
496           0xe9, 0xd0, 0xcc, 0x6d, 0x4e, 0xf7, 0x34, 0x91, 0x42, 0x5c}},
497         {"2.23.140.1.1", ""},
498     },
499     // Staat der Nederlanden EV Root CA
500     // https://pkioevssl-v.quovadisglobal.com/
501     {
502         {{0x4d, 0x24, 0x91, 0x41, 0x4c, 0xfe, 0x95, 0x67, 0x46, 0xec, 0x4c,
503           0xef, 0xa6, 0xcf, 0x6f, 0x72, 0xe2, 0x8a, 0x13, 0x29, 0x43, 0x2f,
504           0x9d, 0x8a, 0x90, 0x7a, 0xc4, 0xcb, 0x5d, 0xad, 0xc1, 0x5a}},
505         {"2.16.528.1.1003.1.2.7", ""},
506     },
507     // Starfield Class 2 Certification Authority
508     // https://www.starfieldtech.com/
509     {
510         {{0x14, 0x65, 0xfa, 0x20, 0x53, 0x97, 0xb8, 0x76, 0xfa, 0xa6, 0xf0,
511           0xa9, 0x95, 0x8e, 0x55, 0x90, 0xe4, 0x0f, 0xcc, 0x7f, 0xaa, 0x4f,
512           0xb7, 0xc2, 0xc8, 0x67, 0x75, 0x21, 0xfb, 0x5f, 0xb6, 0x58}},
513         {"2.16.840.1.114414.1.7.23.3", ""},
514     },
515     // Starfield Root Certificate Authority - G2
516     // https://valid.sfig2.catest.starfieldtech.com/
517     {
518         {{0x2c, 0xe1, 0xcb, 0x0b, 0xf9, 0xd2, 0xf9, 0xe1, 0x02, 0x99, 0x3f,
519           0xbe, 0x21, 0x51, 0x52, 0xc3, 0xb2, 0xdd, 0x0c, 0xab, 0xde, 0x1c,
520           0x68, 0xe5, 0x31, 0x9b, 0x83, 0x91, 0x54, 0xdb, 0xb7, 0xf5}},
521         {"2.16.840.1.114414.1.7.23.3", ""},
522     },
523     // Starfield Services Root Certificate Authority - G2
524     // https://valid.sfsg2.catest.starfieldtech.com/
525     {
526         {{0x56, 0x8d, 0x69, 0x05, 0xa2, 0xc8, 0x87, 0x08, 0xa4, 0xb3, 0x02,
527           0x51, 0x90, 0xed, 0xcf, 0xed, 0xb1, 0x97, 0x4a, 0x60, 0x6a, 0x13,
528           0xc6, 0xe5, 0x29, 0x0f, 0xcb, 0x2a, 0xe6, 0x3e, 0xda, 0xb5}},
529         {"2.16.840.1.114414.1.7.24.3", "2.23.140.1.1"},
530     },
531     // SwissSign Gold CA - G2
532     // https://testevg2.swisssign.net/
533     {
534         {{0x62, 0xdd, 0x0b, 0xe9, 0xb9, 0xf5, 0x0a, 0x16, 0x3e, 0xa0, 0xf8,
535           0xe7, 0x5c, 0x05, 0x3b, 0x1e, 0xca, 0x57, 0xea, 0x55, 0xc8, 0x68,
536           0x8f, 0x64, 0x7c, 0x68, 0x81, 0xf2, 0xc8, 0x35, 0x7b, 0x95}},
537         {"2.16.756.1.89.1.2.1.1", ""},
538     },
539     // TWCA Global Root CA
540     // https://evssldemo3.twca.com.tw/index.html
541     {
542         {{0x59, 0x76, 0x90, 0x07, 0xf7, 0x68, 0x5d, 0x0f, 0xcd, 0x50, 0x87,
543           0x2f, 0x9f, 0x95, 0xd5, 0x75, 0x5a, 0x5b, 0x2b, 0x45, 0x7d, 0x81,
544           0xf3, 0x69, 0x2b, 0x61, 0x0a, 0x98, 0x67, 0x2f, 0x0e, 0x1b}},
545         {"1.3.6.1.4.1.40869.1.1.22.3", ""},
546     },
547     // TWCA Root Certification Authority
548     // https://evssldemo.twca.com.tw/index.html
549     {
550         {{0xbf, 0xd8, 0x8f, 0xe1, 0x10, 0x1c, 0x41, 0xae, 0x3e, 0x80, 0x1b,
551           0xf8, 0xbe, 0x56, 0x35, 0x0e, 0xe9, 0xba, 0xd1, 0xa6, 0xb9, 0xbd,
552           0x51, 0x5e, 0xdc, 0x5c, 0x6d, 0x5b, 0x87, 0x11, 0xac, 0x44}},
553         {"1.3.6.1.4.1.40869.1.1.22.3", ""},
554     },
555     // T-TeleSec GlobalRoot Class 3
556     // http://www.telesec.de/ / https://root-class3.test.telesec.de/
557     {
558         {{0xfd, 0x73, 0xda, 0xd3, 0x1c, 0x64, 0x4f, 0xf1, 0xb4, 0x3b, 0xef,
559           0x0c, 0xcd, 0xda, 0x96, 0x71, 0x0b, 0x9c, 0xd9, 0x87, 0x5e, 0xca,
560           0x7e, 0x31, 0x70, 0x7a, 0xf3, 0xe9, 0x6d, 0x52, 0x2b, 0xbd}},
561         {"1.3.6.1.4.1.7879.13.24.1", ""},
562     },
563     // UCA Extended Validation Root
564     // https://rsaevg1.good.sheca.com/
565     {
566         {{0xd4, 0x3a, 0xf9, 0xb3, 0x54, 0x73, 0x75, 0x5c, 0x96, 0x84, 0xfc,
567           0x06, 0xd7, 0xd8, 0xcb, 0x70, 0xee, 0x5c, 0x28, 0xe7, 0x73, 0xfb,
568           0x29, 0x4e, 0xb4, 0x1e, 0xe7, 0x17, 0x22, 0x92, 0x4d, 0x24}},
569         {"2.23.140.1.1", ""},
570     },
571     // USERTrust ECC Certification Authority
572     // https://usertrustecccertificationauthority-ev.comodoca.com/
573     {
574         {{0x4f, 0xf4, 0x60, 0xd5, 0x4b, 0x9c, 0x86, 0xda, 0xbf, 0xbc, 0xfc,
575           0x57, 0x12, 0xe0, 0x40, 0x0d, 0x2b, 0xed, 0x3f, 0xbc, 0x4d, 0x4f,
576           0xbd, 0xaa, 0x86, 0xe0, 0x6a, 0xdc, 0xd2, 0xa9, 0xad, 0x7a}},
577         {"1.3.6.1.4.1.6449.1.2.1.5.1", ""},
578     },
579     // USERTrust RSA Certification Authority
580     // https://usertrustrsacertificationauthority-ev.comodoca.com/
581     {
582         {{0xe7, 0x93, 0xc9, 0xb0, 0x2f, 0xd8, 0xaa, 0x13, 0xe2, 0x1c, 0x31,
583           0x22, 0x8a, 0xcc, 0xb0, 0x81, 0x19, 0x64, 0x3b, 0x74, 0x9c, 0x89,
584           0x89, 0x64, 0xb1, 0x74, 0x6d, 0x46, 0xc3, 0xd4, 0xcb, 0xd2}},
585         {"1.3.6.1.4.1.6449.1.2.1.5.1", ""},
586     },
587     // XRamp Global Certification Authority
588     {
589         {{0xce, 0xcd, 0xdc, 0x90, 0x50, 0x99, 0xd8, 0xda, 0xdf, 0xc5, 0xb1,
590           0xd2, 0x09, 0xb7, 0x37, 0xcb, 0xe2, 0xc1, 0x8c, 0xfb, 0x2c, 0x10,
591           0xc0, 0xff, 0x0b, 0xcf, 0x0d, 0x32, 0x86, 0xfc, 0x1a, 0xa2}},
592         {"2.16.840.1.114404.1.1.2.4.1", ""},
593     }};
594 
595 #endif  // defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
596 }  // namespace
597 
598 static base::LazyInstance<EVRootCAMetadata>::Leaky g_ev_root_ca_metadata =
599     LAZY_INSTANCE_INITIALIZER;
600 
601 // static
GetInstance()602 EVRootCAMetadata* EVRootCAMetadata::GetInstance() {
603   return g_ev_root_ca_metadata.Pointer();
604 }
605 
606 #if defined(OS_WIN)
607 
608 namespace {
609 
ConvertBytesToDottedString(const der::Input & policy_oid,std::string * dotted)610 bool ConvertBytesToDottedString(const der::Input& policy_oid,
611                                 std::string* dotted) {
612   CBS cbs;
613   CBS_init(&cbs, policy_oid.UnsafeData(), policy_oid.Length());
614   bssl::UniquePtr<char> text(CBS_asn1_oid_to_text(&cbs));
615   if (!text)
616     return false;
617   dotted->assign(text.get());
618   return true;
619 }
620 
621 }  // namespace
622 
IsEVPolicyOID(PolicyOID policy_oid) const623 bool EVRootCAMetadata::IsEVPolicyOID(PolicyOID policy_oid) const {
624   for (const auto& ev_root : kEvRootCaMetadata) {
625     if (std::find(std::begin(ev_root.policy_oids),
626                   std::end(ev_root.policy_oids),
627                   policy_oid) != std::end(ev_root.policy_oids)) {
628       return true;
629     }
630   }
631 
632   for (const auto& ca : extra_cas_) {
633     if (ca.second == policy_oid)
634       return true;
635   }
636 
637   return false;
638 }
639 
IsEVPolicyOIDGivenBytes(const der::Input & policy_oid) const640 bool EVRootCAMetadata::IsEVPolicyOIDGivenBytes(
641     const der::Input& policy_oid) const {
642   std::string dotted;
643   return ConvertBytesToDottedString(policy_oid, &dotted) &&
644          IsEVPolicyOID(dotted.c_str());
645 }
646 
HasEVPolicyOID(const SHA256HashValue & fingerprint,PolicyOID policy_oid) const647 bool EVRootCAMetadata::HasEVPolicyOID(const SHA256HashValue& fingerprint,
648                                       PolicyOID policy_oid) const {
649   for (const auto& ev_root : kEvRootCaMetadata) {
650     if (fingerprint != ev_root.fingerprint)
651       continue;
652     return std::find(std::begin(ev_root.policy_oids),
653                      std::end(ev_root.policy_oids),
654                      policy_oid) != std::end(ev_root.policy_oids);
655   }
656 
657   auto it = extra_cas_.find(fingerprint);
658   return it != extra_cas_.end() && it->second == policy_oid;
659 }
660 
HasEVPolicyOIDGivenBytes(const SHA256HashValue & fingerprint,const der::Input & policy_oid) const661 bool EVRootCAMetadata::HasEVPolicyOIDGivenBytes(
662     const SHA256HashValue& fingerprint,
663     const der::Input& policy_oid) const {
664   std::string dotted;
665   return ConvertBytesToDottedString(policy_oid, &dotted) &&
666          HasEVPolicyOID(fingerprint, dotted.c_str());
667 }
668 
669 // static
IsCaBrowserForumEvOid(PolicyOID policy_oid)670 bool EVRootCAMetadata::IsCaBrowserForumEvOid(PolicyOID policy_oid) {
671   return strcmp(policy_oid, "2.23.140.1.1") == 0;
672 }
673 
AddEVCA(const SHA256HashValue & fingerprint,const char * policy)674 bool EVRootCAMetadata::AddEVCA(const SHA256HashValue& fingerprint,
675                                const char* policy) {
676   for (const auto& ev_root : kEvRootCaMetadata) {
677     if (fingerprint == ev_root.fingerprint)
678       return false;
679   }
680   if (extra_cas_.find(fingerprint) != extra_cas_.end())
681     return false;
682 
683   extra_cas_[fingerprint] = policy;
684   return true;
685 }
686 
RemoveEVCA(const SHA256HashValue & fingerprint)687 bool EVRootCAMetadata::RemoveEVCA(const SHA256HashValue& fingerprint) {
688   auto it = extra_cas_.find(fingerprint);
689   if (it == extra_cas_.end())
690     return false;
691 
692   extra_cas_.erase(it);
693   return true;
694 }
695 
696 #elif defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
697 
698 namespace {
699 
OIDStringToDER(base::StringPiece policy)700 std::string OIDStringToDER(base::StringPiece policy) {
701   uint8_t* der;
702   size_t len;
703   bssl::ScopedCBB cbb;
704   if (!CBB_init(cbb.get(), 32) ||
705       !CBB_add_asn1_oid_from_text(cbb.get(), policy.data(), policy.size()) ||
706       !CBB_finish(cbb.get(), &der, &len)) {
707     return std::string();
708   }
709   bssl::UniquePtr<uint8_t> delete_der(der);
710   return std::string(reinterpret_cast<const char*>(der), len);
711 }
712 
713 }  // namespace
714 
IsEVPolicyOID(PolicyOID policy_oid) const715 bool EVRootCAMetadata::IsEVPolicyOID(PolicyOID policy_oid) const {
716   return policy_oids_.find(policy_oid.AsString()) != policy_oids_.end();
717 }
718 
IsEVPolicyOIDGivenBytes(const der::Input & policy_oid) const719 bool EVRootCAMetadata::IsEVPolicyOIDGivenBytes(
720     const der::Input& policy_oid) const {
721   // This implementation uses DER bytes already, so the two functions are the
722   // same.
723   return IsEVPolicyOID(policy_oid);
724 }
725 
HasEVPolicyOID(const SHA256HashValue & fingerprint,PolicyOID policy_oid) const726 bool EVRootCAMetadata::HasEVPolicyOID(const SHA256HashValue& fingerprint,
727                                       PolicyOID policy_oid) const {
728   PolicyOIDMap::const_iterator iter = ev_policy_.find(fingerprint);
729   if (iter == ev_policy_.end())
730     return false;
731   for (const std::string& ev_oid : iter->second) {
732     if (der::Input(&ev_oid) == policy_oid)
733       return true;
734   }
735   return false;
736 }
737 
HasEVPolicyOIDGivenBytes(const SHA256HashValue & fingerprint,const der::Input & policy_oid) const738 bool EVRootCAMetadata::HasEVPolicyOIDGivenBytes(
739     const SHA256HashValue& fingerprint,
740     const der::Input& policy_oid) const {
741   // The implementation uses DER bytes already, so the two functions are the
742   // same.
743   return HasEVPolicyOID(fingerprint, policy_oid);
744 }
745 
746 // static
IsCaBrowserForumEvOid(PolicyOID policy_oid)747 bool EVRootCAMetadata::IsCaBrowserForumEvOid(PolicyOID policy_oid) {
748   const uint8_t kCabEvOid[] = {0x67, 0x81, 0x0c, 0x01, 0x01};
749   return der::Input(kCabEvOid) == policy_oid;
750 }
751 
AddEVCA(const SHA256HashValue & fingerprint,const char * policy)752 bool EVRootCAMetadata::AddEVCA(const SHA256HashValue& fingerprint,
753                                const char* policy) {
754   if (ev_policy_.find(fingerprint) != ev_policy_.end())
755     return false;
756 
757   std::string der_policy = OIDStringToDER(policy);
758   if (der_policy.empty())
759     return false;
760 
761   ev_policy_[fingerprint].push_back(der_policy);
762   policy_oids_.insert(der_policy);
763   return true;
764 }
765 
RemoveEVCA(const SHA256HashValue & fingerprint)766 bool EVRootCAMetadata::RemoveEVCA(const SHA256HashValue& fingerprint) {
767   PolicyOIDMap::iterator it = ev_policy_.find(fingerprint);
768   if (it == ev_policy_.end())
769     return false;
770   std::string oid = it->second[0];
771   ev_policy_.erase(it);
772   policy_oids_.erase(oid);
773   return true;
774 }
775 
776 #else
777 
778 // These are just stub functions for platforms where we don't use this EV
779 // metadata.
780 //
781 
IsEVPolicyOID(PolicyOID policy_oid) const782 bool EVRootCAMetadata::IsEVPolicyOID(PolicyOID policy_oid) const {
783   LOG(WARNING) << "Not implemented";
784   return false;
785 }
786 
IsEVPolicyOIDGivenBytes(const der::Input & policy_oid) const787 bool EVRootCAMetadata::IsEVPolicyOIDGivenBytes(
788     const der::Input& policy_oid) const {
789   LOG(WARNING) << "Not implemented";
790   return false;
791 }
792 
HasEVPolicyOID(const SHA256HashValue & fingerprint,PolicyOID policy_oid) const793 bool EVRootCAMetadata::HasEVPolicyOID(const SHA256HashValue& fingerprint,
794                                       PolicyOID policy_oid) const {
795   LOG(WARNING) << "Not implemented";
796   return false;
797 }
798 
HasEVPolicyOIDGivenBytes(const SHA256HashValue & fingerprint,const der::Input & policy_oid) const799 bool EVRootCAMetadata::HasEVPolicyOIDGivenBytes(
800     const SHA256HashValue& fingerprint,
801     const der::Input& policy_oid) const {
802   LOG(WARNING) << "Not implemented";
803   return false;
804 }
805 
AddEVCA(const SHA256HashValue & fingerprint,const char * policy)806 bool EVRootCAMetadata::AddEVCA(const SHA256HashValue& fingerprint,
807                                const char* policy) {
808   LOG(WARNING) << "Not implemented";
809   return true;
810 }
811 
RemoveEVCA(const SHA256HashValue & fingerprint)812 bool EVRootCAMetadata::RemoveEVCA(const SHA256HashValue& fingerprint) {
813   LOG(WARNING) << "Not implemented";
814   return true;
815 }
816 
817 #endif
818 
EVRootCAMetadata()819 EVRootCAMetadata::EVRootCAMetadata() {
820 // Constructs the object from the raw metadata in kEvRootCaMetadata.
821 #if defined(PLATFORM_USES_CHROMIUM_EV_METADATA) && !defined(OS_WIN)
822   for (const auto& ev_root : kEvRootCaMetadata) {
823     for (const auto& policy : ev_root.policy_oids) {
824       if (policy.empty())
825         break;
826 
827       std::string policy_der = OIDStringToDER(policy.data());
828       if (policy_der.empty()) {
829         LOG(ERROR) << "Failed to register OID: " << policy;
830         continue;
831       }
832 
833       ev_policy_[ev_root.fingerprint].push_back(policy_der);
834       policy_oids_.insert(policy_der);
835     }
836   }
837 #endif
838 }
839 
840 EVRootCAMetadata::~EVRootCAMetadata() = default;
841 
842 }  // namespace net
843