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