1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : *
3 : * ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is mozilla.org code.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Red Hat, Inc.
20 : * Portions created by the Initial Developer are Copyright (C) 2007
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Kai Engert <kengert@redhat.com>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either the GNU General Public License Version 2 or later (the "GPL"), or
28 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #include "nsAppDirectoryServiceDefs.h"
41 : #include "nsStreamUtils.h"
42 : #include "nsNetUtil.h"
43 : #include "nsILineInputStream.h"
44 : #include "nsPromiseFlatString.h"
45 : #include "nsTArray.h"
46 :
47 : #include "cert.h"
48 : #include "base64.h"
49 : #include "nsNSSComponent.h"
50 : #include "nsNSSIOLayer.h"
51 : #include "nsNSSCertificate.h"
52 : #include "nsNSSCleaner.h"
53 :
54 : #ifdef DEBUG
55 : #ifndef PSM_ENABLE_TEST_EV_ROOTS
56 : #define PSM_ENABLE_TEST_EV_ROOTS
57 : #endif
58 : #endif
59 :
60 : #ifdef PR_LOGGING
61 : extern PRLogModuleInfo* gPIPNSSLog;
62 : #endif
63 :
64 0 : NSSCleanupAutoPtrClass(CERTCertificate, CERT_DestroyCertificate)
65 0 : NSSCleanupAutoPtrClass(CERTCertList, CERT_DestroyCertList)
66 : NSSCleanupAutoPtrClass_WithParam(SECItem, SECITEM_FreeItem, TrueParam, true)
67 :
68 : #define CONST_OID static const unsigned char
69 : #define OI(x) { siDEROID, (unsigned char *)x, sizeof x }
70 :
71 : struct nsMyTrustedEVInfo
72 0 : {
73 : const char *dotted_oid;
74 : const char *oid_name; // Set this to null to signal an invalid structure,
75 : // (We can't have an empty list, so we'll use a dummy entry)
76 : SECOidTag oid_tag;
77 : const char *ev_root_sha1_fingerprint;
78 : const char *issuer_base64;
79 : const char *serial_base64;
80 : CERTCertificate *cert;
81 : };
82 :
83 : static struct nsMyTrustedEVInfo myTrustedEVInfos[] = {
84 : /*
85 : * IMPORTANT! When extending this list,
86 : * pairs of dotted_oid and oid_name should always be unique pairs.
87 : * In other words, if you add another list, that uses the same dotted_oid
88 : * as an existing entry, then please use the same oid_name.
89 : */
90 : {
91 : // CN=WellsSecure Public Root Certificate Authority,OU=Wells Fargo Bank NA,O=Wells Fargo WellsSecure,C=US
92 : "2.16.840.1.114171.500.9",
93 : "WellsSecure EV OID",
94 : SEC_OID_UNKNOWN,
95 : "E7:B4:F6:9D:61:EC:90:69:DB:7E:90:A7:40:1A:3C:F4:7D:4F:E8:EE",
96 : "MIGFMQswCQYDVQQGEwJVUzEgMB4GA1UECgwXV2VsbHMgRmFyZ28gV2VsbHNTZWN1"
97 : "cmUxHDAaBgNVBAsME1dlbGxzIEZhcmdvIEJhbmsgTkExNjA0BgNVBAMMLVdlbGxz"
98 : "U2VjdXJlIFB1YmxpYyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eQ==",
99 : "AQ==",
100 : nsnull
101 : },
102 : {
103 : // OU=Security Communication EV RootCA1,O="SECOM Trust Systems CO.,LTD.",C=JP
104 : "1.2.392.200091.100.721.1",
105 : "SECOM EV OID",
106 : SEC_OID_UNKNOWN,
107 : "FE:B8:C4:32:DC:F9:76:9A:CE:AE:3D:D8:90:8F:FD:28:86:65:64:7D",
108 : "MGAxCzAJBgNVBAYTAkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENP"
109 : "LixMVEQuMSowKAYDVQQLEyFTZWN1cml0eSBDb21tdW5pY2F0aW9uIEVWIFJvb3RD"
110 : "QTE=",
111 : "AA==",
112 : nsnull
113 : },
114 : {
115 : // CN=Cybertrust Global Root,O=Cybertrust, Inc
116 : "1.3.6.1.4.1.6334.1.100.1",
117 : "Cybertrust EV OID",
118 : SEC_OID_UNKNOWN,
119 : "5F:43:E5:B1:BF:F8:78:8C:AC:1C:C7:CA:4A:9A:C6:22:2B:CC:34:C6",
120 : "MDsxGDAWBgNVBAoTD0N5YmVydHJ1c3QsIEluYzEfMB0GA1UEAxMWQ3liZXJ0cnVz"
121 : "dCBHbG9iYWwgUm9vdA==",
122 : "BAAAAAABD4WqLUg=",
123 : nsnull
124 : },
125 : {
126 : // CN=SwissSign Gold CA - G2,O=SwissSign AG,C=CH
127 : "2.16.756.1.89.1.2.1.1",
128 : "SwissSign EV OID",
129 : SEC_OID_UNKNOWN,
130 : "D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61",
131 : "MEUxCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMT"
132 : "FlN3aXNzU2lnbiBHb2xkIENBIC0gRzI=",
133 : "ALtAHEP1Xk+w",
134 : nsnull
135 : },
136 : {
137 : // CN=StartCom Certification Authority,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL
138 : "1.3.6.1.4.1.23223.2",
139 : "StartCom EV OID",
140 : SEC_OID_UNKNOWN,
141 : "3E:2B:F7:F2:03:1B:96:F3:8C:E6:C4:D8:A8:5D:3E:2D:58:47:6A:0F",
142 : "MH0xCzAJBgNVBAYTAklMMRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMSswKQYDVQQL"
143 : "EyJTZWN1cmUgRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTaWduaW5nMSkwJwYDVQQDEyBT"
144 : "dGFydENvbSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==",
145 : "AQ==",
146 : nsnull
147 : },
148 : {
149 : // CN=VeriSign Class 3 Public Primary Certification Authority - G5,OU="(c) 2006 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US
150 : "2.16.840.1.113733.1.7.23.6",
151 : "VeriSign EV OID",
152 : SEC_OID_UNKNOWN,
153 : "4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5",
154 : "MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNV"
155 : "BAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA2IFZl"
156 : "cmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMT"
157 : "PFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBB"
158 : "dXRob3JpdHkgLSBHNQ==",
159 : "GNrRniZ96LtKIVjNzGs7Sg==",
160 : nsnull
161 : },
162 : {
163 : // CN=GeoTrust Primary Certification Authority,O=GeoTrust Inc.,C=US
164 : "1.3.6.1.4.1.14370.1.6",
165 : "GeoTrust EV OID",
166 : SEC_OID_UNKNOWN,
167 : "32:3C:11:8E:1B:F7:B8:B6:52:54:E2:E2:10:0D:D6:02:90:37:F0:96",
168 : "MFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQD"
169 : "EyhHZW9UcnVzdCBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5",
170 : "GKy1av1pthU6Y2yv2vrEoQ==",
171 : nsnull
172 : },
173 : {
174 : // CN=thawte Primary Root CA,OU="(c) 2006 thawte, Inc. - For authorized use only",OU=Certification Services Division,O="thawte, Inc.",C=US
175 : "2.16.840.1.113733.1.7.48.1",
176 : "Thawte EV OID",
177 : SEC_OID_UNKNOWN,
178 : "91:C6:D6:EE:3E:8A:C8:63:84:E5:48:C2:99:29:5C:75:6C:81:7B:81",
179 : "MIGpMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMuMSgwJgYDVQQL"
180 : "Ex9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYDVQQLEy8oYykg"
181 : "MjAwNiB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0G"
182 : "A1UEAxMWdGhhd3RlIFByaW1hcnkgUm9vdCBDQQ==",
183 : "NE7VVyDV7exJ9C/ON9srbQ==",
184 : nsnull
185 : },
186 : {
187 : // CN=XRamp Global Certification Authority,O=XRamp Security Services Inc,OU=www.xrampsecurity.com,C=US
188 : "2.16.840.1.114404.1.1.2.4.1",
189 : "Trustwave EV OID",
190 : SEC_OID_UNKNOWN,
191 : "B8:01:86:D1:EB:9C:86:A5:41:04:CF:30:54:F3:4C:52:B7:E5:58:C6",
192 : "MIGCMQswCQYDVQQGEwJVUzEeMBwGA1UECxMVd3d3LnhyYW1wc2VjdXJpdHkuY29t"
193 : "MSQwIgYDVQQKExtYUmFtcCBTZWN1cml0eSBTZXJ2aWNlcyBJbmMxLTArBgNVBAMT"
194 : "JFhSYW1wIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==",
195 : "UJRs7Bjq1ZxN1ZfvdY+grQ==",
196 : nsnull
197 : },
198 : {
199 : // CN=SecureTrust CA,O=SecureTrust Corporation,C=US
200 : "2.16.840.1.114404.1.1.2.4.1",
201 : "Trustwave EV OID",
202 : SEC_OID_UNKNOWN,
203 : "87:82:C6:C3:04:35:3B:CF:D2:96:92:D2:59:3E:7D:44:D9:34:FF:11",
204 : "MEgxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdTZWN1cmVUcnVzdCBDb3Jwb3JhdGlv"
205 : "bjEXMBUGA1UEAxMOU2VjdXJlVHJ1c3QgQ0E=",
206 : "DPCOXAgWpa1Cf/DrJxhZ0A==",
207 : nsnull
208 : },
209 : {
210 : // CN=Secure Global CA,O=SecureTrust Corporation,C=US
211 : "2.16.840.1.114404.1.1.2.4.1",
212 : "Trustwave EV OID",
213 : SEC_OID_UNKNOWN,
214 : "3A:44:73:5A:E5:81:90:1F:24:86:61:46:1E:3B:9C:C4:5F:F5:3A:1B",
215 : "MEoxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdTZWN1cmVUcnVzdCBDb3Jwb3JhdGlv"
216 : "bjEZMBcGA1UEAxMQU2VjdXJlIEdsb2JhbCBDQQ==",
217 : "B1YipOjUiolN9BPI8PjqpQ==",
218 : nsnull
219 : },
220 : {
221 : // CN=COMODO ECC Certification Authority,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB
222 : "1.3.6.1.4.1.6449.1.2.1.5.1",
223 : "Comodo EV OID",
224 : SEC_OID_UNKNOWN,
225 : "9F:74:4E:9F:2B:4D:BA:EC:0F:31:2C:50:B6:56:3B:8E:2D:93:C3:11",
226 : "MIGFMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAw"
227 : "DgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDErMCkG"
228 : "A1UEAxMiQ09NT0RPIEVDQyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==",
229 : "H0evqmIAcFBUTAGem2OZKg==",
230 : nsnull
231 : },
232 : {
233 : // CN=COMODO Certification Authority,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB
234 : "1.3.6.1.4.1.6449.1.2.1.5.1",
235 : "Comodo EV OID",
236 : SEC_OID_UNKNOWN,
237 : "66:31:BF:9E:F7:4F:9E:B6:C9:D5:A6:0C:BA:6A:BE:D1:F7:BD:EF:7B",
238 : "MIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAw"
239 : "DgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDEnMCUG"
240 : "A1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5",
241 : "ToEtioJl4AsC7j41AkblPQ==",
242 : nsnull
243 : },
244 : {
245 : // CN=AddTrust External CA Root,OU=AddTrust External TTP Network,O=AddTrust AB,C=SE
246 : "1.3.6.1.4.1.6449.1.2.1.5.1",
247 : "Comodo EV OID",
248 : SEC_OID_UNKNOWN,
249 : "02:FA:F3:E2:91:43:54:68:60:78:57:69:4D:F5:E4:5B:68:85:18:68",
250 : "MG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMd"
251 : "QWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0"
252 : "IEV4dGVybmFsIENBIFJvb3Q=",
253 : "AQ==",
254 : nsnull
255 : },
256 : {
257 : // CN=UTN - DATACorp SGC,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US
258 : "1.3.6.1.4.1.6449.1.2.1.5.1",
259 : "Comodo EV OID",
260 : SEC_OID_UNKNOWN,
261 : "58:11:9F:0E:12:82:87:EA:50:FD:D9:87:45:6F:4F:78:DC:FA:D6:D4",
262 : "MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFr"
263 : "ZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsT"
264 : "GGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNv"
265 : "cnAgU0dD",
266 : "RL4Mi1AAIbQR0ypoBqmtaQ==",
267 : nsnull
268 : },
269 : {
270 : // CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US
271 : "1.3.6.1.4.1.6449.1.2.1.5.1",
272 : "Comodo EV OID",
273 : SEC_OID_UNKNOWN,
274 : "04:83:ED:33:99:AC:36:08:05:87:22:ED:BC:5E:46:00:E3:BE:F9:D7",
275 : "MIGXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFr"
276 : "ZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsT"
277 : "GGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEfMB0GA1UEAxMWVVROLVVTRVJGaXJz"
278 : "dC1IYXJkd2FyZQ==",
279 : "RL4Mi1AAJLQR0zYq/mUK/Q==",
280 : nsnull
281 : },
282 : {
283 : // OU=Go Daddy Class 2 Certification Authority,O=\"The Go Daddy Group, Inc.\",C=US
284 : "2.16.840.1.114413.1.7.23.3",
285 : "Go Daddy EV OID a",
286 : SEC_OID_UNKNOWN,
287 : "27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4",
288 : "MGMxCzAJBgNVBAYTAlVTMSEwHwYDVQQKExhUaGUgR28gRGFkZHkgR3JvdXAsIElu"
289 : "Yy4xMTAvBgNVBAsTKEdvIERhZGR5IENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRo"
290 : "b3JpdHk=",
291 : "AA==",
292 : nsnull
293 : },
294 : {
295 : // CN=Go Daddy Root Certificate Authority - G2,O="GoDaddy.com, Inc.",L=Scottsdale,ST=Arizona,C=US
296 : "2.16.840.1.114413.1.7.23.3",
297 : "Go Daddy EV OID a",
298 : SEC_OID_UNKNOWN,
299 : "47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B",
300 : "MIGDMQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2Nv"
301 : "dHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5jb20sIEluYy4xMTAvBgNVBAMTKEdv"
302 : "IERhZGR5IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzI=",
303 : "AA==",
304 : nsnull
305 : },
306 : {
307 : // E=info@valicert.com,CN=http://www.valicert.com/,OU=ValiCert Class 2 Policy Validation Authority,O=\"ValiCert, Inc.\",L=ValiCert Validation Network
308 : "2.16.840.1.114413.1.7.23.3",
309 : "Go Daddy EV OID a",
310 : SEC_OID_UNKNOWN,
311 : "31:7A:2A:D0:7F:2B:33:5E:F5:A1:C3:4E:4B:57:E8:B7:D8:F1:FC:A6",
312 : "MIG7MSQwIgYDVQQHExtWYWxpQ2VydCBWYWxpZGF0aW9uIE5ldHdvcmsxFzAVBgNV"
313 : "BAoTDlZhbGlDZXJ0LCBJbmMuMTUwMwYDVQQLEyxWYWxpQ2VydCBDbGFzcyAyIFBv"
314 : "bGljeSBWYWxpZGF0aW9uIEF1dGhvcml0eTEhMB8GA1UEAxMYaHR0cDovL3d3dy52"
315 : "YWxpY2VydC5jb20vMSAwHgYJKoZIhvcNAQkBFhFpbmZvQHZhbGljZXJ0LmNvbQ==",
316 : "AQ==",
317 : nsnull
318 : },
319 : {
320 : // E=info@valicert.com,CN=http://www.valicert.com/,OU=ValiCert Class 2 Policy Validation Authority,O=\"ValiCert, Inc.\",L=ValiCert Validation Network
321 : "2.16.840.1.114414.1.7.23.3",
322 : "Go Daddy EV OID b",
323 : SEC_OID_UNKNOWN,
324 : "31:7A:2A:D0:7F:2B:33:5E:F5:A1:C3:4E:4B:57:E8:B7:D8:F1:FC:A6",
325 : "MIG7MSQwIgYDVQQHExtWYWxpQ2VydCBWYWxpZGF0aW9uIE5ldHdvcmsxFzAVBgNV"
326 : "BAoTDlZhbGlDZXJ0LCBJbmMuMTUwMwYDVQQLEyxWYWxpQ2VydCBDbGFzcyAyIFBv"
327 : "bGljeSBWYWxpZGF0aW9uIEF1dGhvcml0eTEhMB8GA1UEAxMYaHR0cDovL3d3dy52"
328 : "YWxpY2VydC5jb20vMSAwHgYJKoZIhvcNAQkBFhFpbmZvQHZhbGljZXJ0LmNvbQ==",
329 : "AQ==",
330 : nsnull
331 : },
332 : {
333 : // OU=Starfield Class 2 Certification Authority,O=\"Starfield Technologies, Inc.\",C=US
334 : "2.16.840.1.114414.1.7.23.3",
335 : "Go Daddy EV OID b",
336 : SEC_OID_UNKNOWN,
337 : "AD:7E:1C:28:B0:64:EF:8F:60:03:40:20:14:C3:D0:E3:37:0E:B5:8A",
338 : "MGgxCzAJBgNVBAYTAlVTMSUwIwYDVQQKExxTdGFyZmllbGQgVGVjaG5vbG9naWVz"
339 : "LCBJbmMuMTIwMAYDVQQLEylTdGFyZmllbGQgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9u"
340 : "IEF1dGhvcml0eQ==",
341 : "AA==",
342 : nsnull
343 : },
344 : {
345 : // CN=Starfield Root Certificate Authority - G2,O="Starfield Technologies, Inc.",L=Scottsdale,ST=Arizona,C=US
346 : "2.16.840.1.114414.1.7.23.3",
347 : "Go Daddy EV OID b",
348 : SEC_OID_UNKNOWN,
349 : "B5:1C:06:7C:EE:2B:0C:3D:F8:55:AB:2D:92:F4:FE:39:D4:E7:0F:0E",
350 : "MIGPMQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2Nv"
351 : "dHRzZGFsZTElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEy"
352 : "MDAGA1UEAxMpU3RhcmZpZWxkIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0g"
353 : "RzI=",
354 : "AA==",
355 : nsnull
356 : },
357 : {
358 : // CN=DigiCert High Assurance EV Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US
359 : "2.16.840.1.114412.2.1",
360 : "DigiCert EV OID",
361 : SEC_OID_UNKNOWN,
362 : "5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25",
363 : "MGwxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsT"
364 : "EHd3dy5kaWdpY2VydC5jb20xKzApBgNVBAMTIkRpZ2lDZXJ0IEhpZ2ggQXNzdXJh"
365 : "bmNlIEVWIFJvb3QgQ0E=",
366 : "AqxcJmoLQJuPC3nyrkYldw==",
367 : nsnull
368 : },
369 : {
370 : // CN=QuoVadis Root CA 2,O=QuoVadis Limited,C=BM
371 : "1.3.6.1.4.1.8024.0.2.100.1.2",
372 : "Quo Vadis EV OID",
373 : SEC_OID_UNKNOWN,
374 : "CA:3A:FB:CF:12:40:36:4B:44:B2:16:20:88:80:48:39:19:93:7C:F7",
375 : "MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYD"
376 : "VQQDExJRdW9WYWRpcyBSb290IENBIDI=",
377 : "BQk=",
378 : nsnull
379 : },
380 : {
381 : // CN=Network Solutions Certificate Authority,O=Network Solutions L.L.C.,C=US
382 : "1.3.6.1.4.1.782.1.2.1.8.1",
383 : "Network Solutions EV OID",
384 : SEC_OID_UNKNOWN,
385 : "74:F8:A3:C3:EF:E7:B3:90:06:4B:83:90:3C:21:64:60:20:E5:DF:CE",
386 : "MGIxCzAJBgNVBAYTAlVTMSEwHwYDVQQKExhOZXR3b3JrIFNvbHV0aW9ucyBMLkwu"
387 : "Qy4xMDAuBgNVBAMTJ05ldHdvcmsgU29sdXRpb25zIENlcnRpZmljYXRlIEF1dGhv"
388 : "cml0eQ==",
389 : "V8szb8JcFuZHFhfjkDFo4A==",
390 : nsnull
391 : },
392 : {
393 : // CN=Entrust Root Certification Authority,OU="(c) 2006 Entrust, Inc.",OU=www.entrust.net/CPS is incorporated by reference,O="Entrust, Inc.",C=US
394 : "2.16.840.1.114028.10.1.2",
395 : "Entrust EV OID",
396 : SEC_OID_UNKNOWN,
397 : "B3:1E:B1:B7:40:E3:6C:84:02:DA:DC:37:D4:4D:F5:D4:67:49:52:F9",
398 : "MIGwMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNRW50cnVzdCwgSW5jLjE5MDcGA1UE"
399 : "CxMwd3d3LmVudHJ1c3QubmV0L0NQUyBpcyBpbmNvcnBvcmF0ZWQgYnkgcmVmZXJl"
400 : "bmNlMR8wHQYDVQQLExYoYykgMjAwNiBFbnRydXN0LCBJbmMuMS0wKwYDVQQDEyRF"
401 : "bnRydXN0IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHk=",
402 : "RWtQVA==",
403 : nsnull
404 : },
405 : {
406 : // CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE
407 : "1.3.6.1.4.1.4146.1.1",
408 : "GlobalSign EV OID",
409 : SEC_OID_UNKNOWN,
410 : "B1:BC:96:8B:D4:F4:9D:62:2A:A8:9A:81:F2:15:01:52:A4:1D:82:9C",
411 : "MFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYD"
412 : "VQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxTaWduIFJvb3QgQ0E=",
413 : "BAAAAAABFUtaw5Q=",
414 : nsnull
415 : },
416 : {
417 : // CN=GlobalSign,O=GlobalSign,OU=GlobalSign Root CA - R2
418 : "1.3.6.1.4.1.4146.1.1",
419 : "GlobalSign EV OID",
420 : SEC_OID_UNKNOWN,
421 : "75:E0:AB:B6:13:85:12:27:1C:04:F8:5F:DD:DE:38:E4:B7:24:2E:FE",
422 : "MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpH"
423 : "bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu",
424 : "BAAAAAABD4Ym5g0=",
425 : nsnull
426 : },
427 : {
428 : // CN=GlobalSign,O=GlobalSign,OU=GlobalSign Root CA - R3
429 : "1.3.6.1.4.1.4146.1.1",
430 : "GlobalSign EV OID",
431 : SEC_OID_UNKNOWN,
432 : "D6:9B:56:11:48:F0:1C:77:C5:45:78:C1:09:26:DF:5B:85:69:76:AD",
433 : "MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIzMRMwEQYDVQQKEwpH"
434 : "bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu",
435 : "BAAAAAABIVhTCKI=",
436 : nsnull
437 : },
438 : {
439 : // CN=Buypass Class 3 CA 1,O=Buypass AS-983163327,C=NO
440 : "2.16.578.1.26.1.3.3",
441 : "Buypass Class 3 CA 1",
442 : SEC_OID_UNKNOWN,
443 : "61:57:3A:11:DF:0E:D8:7E:D5:92:65:22:EA:D0:56:D7:44:B3:23:71",
444 : "MEsxCzAJBgNVBAYTAk5PMR0wGwYDVQQKDBRCdXlwYXNzIEFTLTk4MzE2MzMyNzEd"
445 : "MBsGA1UEAwwUQnV5cGFzcyBDbGFzcyAzIENBIDE=",
446 : "Ag==",
447 : nsnull
448 : },
449 : {
450 : // CN=Class 2 Primary CA,O=Certplus,C=FR
451 : "1.3.6.1.4.1.22234.2.5.2.3.1",
452 : "Certplus EV OID",
453 : SEC_OID_UNKNOWN,
454 : "74:20:74:41:72:9C:DD:92:EC:79:31:D8:23:10:8D:C2:81:92:E2:BB",
455 : "MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xh"
456 : "c3MgMiBQcmltYXJ5IENB",
457 : "AIW9S/PY2uNp9pTXX8OlRCM=",
458 : nsnull
459 : },
460 : {
461 : // CN=Chambers of Commerce Root - 2008,O=AC Camerfirma S.A.,serialNumber=A82743287,L=Madrid (see current address at www.camerfirma.com/address),C=EU
462 : "1.3.6.1.4.1.17326.10.14.2.1.2",
463 : "Camerfirma EV OID a",
464 : SEC_OID_UNKNOWN,
465 : "78:6A:74:AC:76:AB:14:7F:9C:6A:30:50:BA:9E:A8:7E:FE:9A:CE:3C",
466 : "MIGuMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBh"
467 : "ZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ"
468 : "QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMT"
469 : "IENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4",
470 : "AKPaQn6ksa7a",
471 : nsnull
472 : },
473 : {
474 : // CN=Global Chambersign Root - 2008,O=AC Camerfirma S.A.,serialNumber=A82743287,L=Madrid (see current address at www.camerfirma.com/address),C=EU
475 : "1.3.6.1.4.1.17326.10.8.12.1.2",
476 : "Camerfirma EV OID b",
477 : SEC_OID_UNKNOWN,
478 : "4A:BD:EE:EC:95:0D:35:9C:89:AE:C7:52:A1:2C:5B:29:F6:D6:AA:0C",
479 : "MIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBh"
480 : "ZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ"
481 : "QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMT"
482 : "Hkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwOA==",
483 : "AMnN0+nVfSPO",
484 : nsnull
485 : },
486 : {
487 : // CN=TC TrustCenter Universal CA III,OU=TC TrustCenter Universal CA,O=TC TrustCenter GmbH,C=DE
488 : "1.2.276.0.44.1.1.1.4",
489 : "TC TrustCenter EV OID",
490 : SEC_OID_UNKNOWN,
491 : "96:56:CD:7B:57:96:98:95:D0:E1:41:46:68:06:FB:B8:C6:11:06:87",
492 : "MHsxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNUQyBUcnVzdENlbnRlciBHbWJIMSQw"
493 : "IgYDVQQLExtUQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0ExKDAmBgNVBAMTH1RD"
494 : "IFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJSUk=",
495 : "YyUAAQACFI0zFQLkbPQ=",
496 : nsnull
497 : },
498 : {
499 : // CN=AffirmTrust Commercial,O=AffirmTrust,C=US
500 : "1.3.6.1.4.1.34697.2.1",
501 : "AffirmTrust EV OID a",
502 : SEC_OID_UNKNOWN,
503 : "F9:B5:B6:32:45:5F:9C:BE:EC:57:5F:80:DC:E9:6E:2C:C7:B2:78:B7",
504 : "MEQxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEfMB0GA1UEAwwW"
505 : "QWZmaXJtVHJ1c3QgQ29tbWVyY2lhbA==",
506 : "d3cGJyapsXw=",
507 : nsnull
508 : },
509 : {
510 : // CN=AffirmTrust Networking,O=AffirmTrust,C=US
511 : "1.3.6.1.4.1.34697.2.2",
512 : "AffirmTrust EV OID b",
513 : SEC_OID_UNKNOWN,
514 : "29:36:21:02:8B:20:ED:02:F5:66:C5:32:D1:D6:ED:90:9F:45:00:2F",
515 : "MEQxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEfMB0GA1UEAwwW"
516 : "QWZmaXJtVHJ1c3QgTmV0d29ya2luZw==",
517 : "fE8EORzUmS0=",
518 : nsnull
519 : },
520 : {
521 : // CN=AffirmTrust Premium,O=AffirmTrust,C=US
522 : "1.3.6.1.4.1.34697.2.3",
523 : "AffirmTrust EV OID c",
524 : SEC_OID_UNKNOWN,
525 : "D8:A6:33:2C:E0:03:6F:B1:85:F6:63:4F:7D:6A:06:65:26:32:28:27",
526 : "MEExCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEcMBoGA1UEAwwT"
527 : "QWZmaXJtVHJ1c3QgUHJlbWl1bQ==",
528 : "bYwURrGmCu4=",
529 : nsnull
530 : },
531 : {
532 : // CN=AffirmTrust Premium ECC,O=AffirmTrust,C=US
533 : "1.3.6.1.4.1.34697.2.4",
534 : "AffirmTrust EV OID d",
535 : SEC_OID_UNKNOWN,
536 : "B8:23:6B:00:2F:1D:16:86:53:01:55:6C:11:A4:37:CA:EB:FF:C3:BB",
537 : "MEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwX"
538 : "QWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0M=",
539 : "dJclisc/elQ=",
540 : nsnull
541 : },
542 : {
543 : // CN=Certum Trusted Network CA,OU=Certum Certification Authority,O=Unizeto Technologies S.A.,C=PL
544 : "1.2.616.1.113527.2.5.1.1",
545 : "Certum EV OID",
546 : SEC_OID_UNKNOWN,
547 : "07:E0:32:E0:20:B7:2C:3F:19:2F:06:28:A2:59:3A:19:A7:0F:06:9E",
548 : "MH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBT"
549 : "LkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAg"
550 : "BgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0E=",
551 : "BETA",
552 : nsnull
553 : },
554 : {
555 : // CN=Izenpe.com,O=IZENPE S.A.,C=ES
556 : "1.3.6.1.4.1.14777.6.1.1",
557 : "Izenpe EV OID 1",
558 : SEC_OID_UNKNOWN,
559 : "2F:78:3D:25:52:18:A7:4A:65:39:71:B5:2C:A2:9C:45:15:6F:E9:19",
560 : "MDgxCzAJBgNVBAYTAkVTMRQwEgYDVQQKDAtJWkVOUEUgUy5BLjETMBEGA1UEAwwK"
561 : "SXplbnBlLmNvbQ==",
562 : "ALC3WhZIX7/hy/WL1xnmfQ==",
563 : nsnull
564 : },
565 : {
566 : // CN=Izenpe.com,O=IZENPE S.A.,C=ES
567 : "1.3.6.1.4.1.14777.6.1.2",
568 : "Izenpe EV OID 2",
569 : SEC_OID_UNKNOWN,
570 : "2F:78:3D:25:52:18:A7:4A:65:39:71:B5:2C:A2:9C:45:15:6F:E9:19",
571 : "MDgxCzAJBgNVBAYTAkVTMRQwEgYDVQQKDAtJWkVOUEUgUy5BLjETMBEGA1UEAwwK"
572 : "SXplbnBlLmNvbQ==",
573 : "ALC3WhZIX7/hy/WL1xnmfQ==",
574 : nsnull
575 : },
576 : {
577 : // CN=A-Trust-nQual-03,OU=A-Trust-nQual-03,O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH,C=AT
578 : "1.2.40.0.17.1.22",
579 : "A-Trust EV OID",
580 : SEC_OID_UNKNOWN,
581 : "D3:C0:63:F2:19:ED:07:3E:34:AD:5D:75:0B:32:76:29:FF:D5:9A:F2",
582 : "MIGNMQswCQYDVQQGEwJBVDFIMEYGA1UECgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hl"
583 : "cmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVya2VociBHbWJIMRkwFwYD"
584 : "VQQLDBBBLVRydXN0LW5RdWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5RdWFsLTAz",
585 : "AWwe",
586 : nsnull
587 : },
588 : {
589 : // OU=Sample Certification Authority,O=\"Sample, Inc.\",C=US
590 : "0.0.0.0",
591 : 0, // for real entries use a string like "Sample INVALID EV OID"
592 : SEC_OID_UNKNOWN,
593 : "00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33", //UPPERCASE!
594 : "Cg==",
595 : "Cg==",
596 : nsnull
597 : }
598 : };
599 :
600 : static SECOidTag
601 168 : register_oid(const SECItem *oid_item, const char *oid_name)
602 : {
603 168 : if (!oid_item)
604 0 : return SEC_OID_UNKNOWN;
605 :
606 : SECOidData od;
607 168 : od.oid.len = oid_item->len;
608 168 : od.oid.data = oid_item->data;
609 168 : od.offset = SEC_OID_UNKNOWN;
610 168 : od.desc = oid_name;
611 168 : od.mechanism = CKM_INVALID_MECHANISM;
612 168 : od.supportedExtension = INVALID_CERT_EXTENSION;
613 168 : return SECOID_AddEntry(&od);
614 : }
615 :
616 : #ifdef PSM_ENABLE_TEST_EV_ROOTS
617 : class nsMyTrustedEVInfoClass : public nsMyTrustedEVInfo
618 : {
619 : public:
620 : nsMyTrustedEVInfoClass();
621 : ~nsMyTrustedEVInfoClass();
622 : };
623 :
624 0 : nsMyTrustedEVInfoClass::nsMyTrustedEVInfoClass()
625 : {
626 0 : dotted_oid = nsnull;
627 0 : oid_name = nsnull;
628 0 : oid_tag = SEC_OID_UNKNOWN;
629 0 : ev_root_sha1_fingerprint = nsnull;
630 0 : issuer_base64 = nsnull;
631 0 : serial_base64 = nsnull;
632 0 : cert = nsnull;
633 0 : }
634 :
635 0 : nsMyTrustedEVInfoClass::~nsMyTrustedEVInfoClass()
636 : {
637 : // Cast away const-ness in order to free these strings
638 0 : free(const_cast<char*>(dotted_oid));
639 0 : free(const_cast<char*>(oid_name));
640 0 : free(const_cast<char*>(ev_root_sha1_fingerprint));
641 0 : free(const_cast<char*>(issuer_base64));
642 0 : free(const_cast<char*>(serial_base64));
643 0 : if (cert)
644 0 : CERT_DestroyCertificate(cert);
645 0 : }
646 :
647 : typedef nsTArray< nsMyTrustedEVInfoClass* > testEVArray;
648 : static testEVArray *testEVInfos;
649 : static bool testEVInfosLoaded = false;
650 : #endif
651 :
652 0 : static bool isEVMatch(SECOidTag policyOIDTag,
653 : CERTCertificate *rootCert,
654 : const nsMyTrustedEVInfo &info)
655 : {
656 0 : if (!rootCert)
657 0 : return false;
658 :
659 0 : NS_ConvertASCIItoUTF16 info_sha1(info.ev_root_sha1_fingerprint);
660 :
661 0 : nsNSSCertificate c(rootCert);
662 :
663 0 : nsAutoString fingerprint;
664 0 : if (NS_FAILED(c.GetSha1Fingerprint(fingerprint)))
665 0 : return false;
666 :
667 0 : if (fingerprint != info_sha1)
668 0 : return false;
669 :
670 0 : return (policyOIDTag == info.oid_tag);
671 : }
672 :
673 : #ifdef PSM_ENABLE_TEST_EV_ROOTS
674 : static const char kTestEVRootsFileName[] = "test_ev_roots.txt";
675 :
676 : static void
677 4 : loadTestEVInfos()
678 : {
679 4 : if (!testEVInfos)
680 0 : return;
681 :
682 4 : testEVInfos->Clear();
683 :
684 4 : char *env_val = getenv("ENABLE_TEST_EV_ROOTS_FILE");
685 4 : if (!env_val)
686 4 : return;
687 :
688 0 : int enabled_val = atoi(env_val);
689 0 : if (!enabled_val)
690 0 : return;
691 :
692 0 : nsCOMPtr<nsIFile> aFile;
693 0 : NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(aFile));
694 0 : if (!aFile)
695 : return;
696 :
697 0 : aFile->AppendNative(NS_LITERAL_CSTRING(kTestEVRootsFileName));
698 :
699 : nsresult rv;
700 0 : nsCOMPtr<nsIInputStream> fileInputStream;
701 0 : rv = NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream), aFile);
702 0 : if (NS_FAILED(rv))
703 : return;
704 :
705 0 : nsCOMPtr<nsILineInputStream> lineInputStream = do_QueryInterface(fileInputStream, &rv);
706 0 : if (NS_FAILED(rv))
707 : return;
708 :
709 0 : nsCAutoString buffer;
710 0 : bool isMore = true;
711 :
712 : /* file format
713 : *
714 : * file format must be strictly followed
715 : * strings in file must be UTF-8
716 : * each record consists of multiple lines
717 : * each line consists of a descriptor, a single space, and the data
718 : * the descriptors are:
719 : * 1_fingerprint (in format XX:XX:XX:...)
720 : * 2_readable_oid (treated as a comment)
721 : * the input file must strictly follow this order
722 : * the input file may contain 0, 1 or many records
723 : * completely empty lines are ignored
724 : * lines that start with the # char are ignored
725 : */
726 :
727 0 : int line_counter = 0;
728 0 : bool found_error = false;
729 :
730 : enum {
731 : pos_fingerprint, pos_readable_oid, pos_issuer, pos_serial
732 0 : } reader_position = pos_fingerprint;
733 :
734 0 : nsCString fingerprint, readable_oid, issuer, serial;
735 :
736 0 : while (isMore && NS_SUCCEEDED(lineInputStream->ReadLine(buffer, &isMore))) {
737 0 : ++line_counter;
738 0 : if (buffer.IsEmpty() || buffer.First() == '#') {
739 0 : continue;
740 : }
741 :
742 0 : PRInt32 seperatorIndex = buffer.FindChar(' ', 0);
743 0 : if (seperatorIndex == 0) {
744 0 : found_error = true;
745 0 : break;
746 : }
747 :
748 0 : const nsASingleFragmentCString &descriptor = Substring(buffer, 0, seperatorIndex);
749 : const nsASingleFragmentCString &data =
750 : Substring(buffer, seperatorIndex + 1,
751 0 : buffer.Length() - seperatorIndex + 1);
752 :
753 0 : if (reader_position == pos_fingerprint &&
754 0 : descriptor.EqualsLiteral(("1_fingerprint"))) {
755 0 : fingerprint = data;
756 0 : reader_position = pos_readable_oid;
757 0 : continue;
758 : }
759 0 : else if (reader_position == pos_readable_oid &&
760 0 : descriptor.EqualsLiteral(("2_readable_oid"))) {
761 0 : readable_oid = data;
762 0 : reader_position = pos_issuer;
763 0 : continue;
764 : }
765 0 : else if (reader_position == pos_issuer &&
766 0 : descriptor.EqualsLiteral(("3_issuer"))) {
767 0 : issuer = data;
768 0 : reader_position = pos_serial;
769 0 : continue;
770 : }
771 0 : else if (reader_position == pos_serial &&
772 0 : descriptor.EqualsLiteral(("4_serial"))) {
773 0 : serial = data;
774 0 : reader_position = pos_fingerprint;
775 : }
776 : else {
777 0 : found_error = true;
778 : break;
779 : }
780 :
781 0 : nsMyTrustedEVInfoClass *temp_ev = new nsMyTrustedEVInfoClass;
782 0 : if (!temp_ev)
783 : return;
784 :
785 0 : temp_ev->ev_root_sha1_fingerprint = strdup(fingerprint.get());
786 0 : temp_ev->oid_name = strdup(readable_oid.get());
787 0 : temp_ev->dotted_oid = strdup(readable_oid.get());
788 0 : temp_ev->issuer_base64 = strdup(issuer.get());
789 0 : temp_ev->serial_base64 = strdup(serial.get());
790 :
791 : SECStatus rv;
792 : CERTIssuerAndSN ias;
793 :
794 0 : rv = ATOB_ConvertAsciiToItem(&ias.derIssuer, const_cast<char*>(temp_ev->issuer_base64));
795 0 : NS_ASSERTION(rv==SECSuccess, "error converting ascii to binary.");
796 0 : rv = ATOB_ConvertAsciiToItem(&ias.serialNumber, const_cast<char*>(temp_ev->serial_base64));
797 0 : NS_ASSERTION(rv==SECSuccess, "error converting ascii to binary.");
798 :
799 0 : temp_ev->cert = CERT_FindCertByIssuerAndSN(nsnull, &ias);
800 0 : NS_ASSERTION(temp_ev->cert, "Could not find EV root in NSS storage");
801 :
802 0 : SECITEM_FreeItem(&ias.derIssuer, false);
803 0 : SECITEM_FreeItem(&ias.serialNumber, false);
804 :
805 0 : if (!temp_ev->cert)
806 : return;
807 :
808 0 : nsNSSCertificate c(temp_ev->cert);
809 0 : nsAutoString fingerprint;
810 0 : c.GetSha1Fingerprint(fingerprint);
811 :
812 0 : NS_ConvertASCIItoUTF16 sha1(temp_ev->ev_root_sha1_fingerprint);
813 :
814 0 : if (sha1 != fingerprint) {
815 0 : NS_ASSERTION(sha1 == fingerprint, "found EV root with unexpected SHA1 mismatch");
816 0 : CERT_DestroyCertificate(temp_ev->cert);
817 0 : temp_ev->cert = nsnull;
818 : return;
819 : }
820 :
821 : SECItem ev_oid_item;
822 0 : ev_oid_item.data = nsnull;
823 0 : ev_oid_item.len = 0;
824 : SECStatus srv = SEC_StringToOID(nsnull, &ev_oid_item,
825 0 : readable_oid.get(), readable_oid.Length());
826 0 : if (srv != SECSuccess) {
827 0 : delete temp_ev;
828 0 : found_error = true;
829 : break;
830 : }
831 :
832 0 : temp_ev->oid_tag = register_oid(&ev_oid_item, temp_ev->oid_name);
833 0 : SECITEM_FreeItem(&ev_oid_item, false);
834 :
835 0 : testEVInfos->AppendElement(temp_ev);
836 : }
837 :
838 0 : if (found_error) {
839 0 : fprintf(stderr, "invalid line %d in test_ev_roots file\n", line_counter);
840 : }
841 : }
842 :
843 : static bool
844 0 : isEVPolicyInExternalDebugRootsFile(SECOidTag policyOIDTag)
845 : {
846 0 : if (!testEVInfos)
847 0 : return false;
848 :
849 0 : char *env_val = getenv("ENABLE_TEST_EV_ROOTS_FILE");
850 0 : if (!env_val)
851 0 : return false;
852 :
853 0 : int enabled_val = atoi(env_val);
854 0 : if (!enabled_val)
855 0 : return false;
856 :
857 0 : for (size_t i=0; i<testEVInfos->Length(); ++i) {
858 0 : nsMyTrustedEVInfoClass *ev = testEVInfos->ElementAt(i);
859 0 : if (!ev)
860 0 : continue;
861 0 : if (policyOIDTag == ev->oid_tag)
862 0 : return true;
863 : }
864 :
865 0 : return false;
866 : }
867 :
868 : static bool
869 0 : getRootsForOidFromExternalRootsFile(CERTCertList* certList,
870 : SECOidTag policyOIDTag)
871 : {
872 0 : if (!testEVInfos)
873 0 : return false;
874 :
875 0 : char *env_val = getenv("ENABLE_TEST_EV_ROOTS_FILE");
876 0 : if (!env_val)
877 0 : return false;
878 :
879 0 : int enabled_val = atoi(env_val);
880 0 : if (!enabled_val)
881 0 : return false;
882 :
883 0 : for (size_t i=0; i<testEVInfos->Length(); ++i) {
884 0 : nsMyTrustedEVInfoClass *ev = testEVInfos->ElementAt(i);
885 0 : if (!ev)
886 0 : continue;
887 0 : if (policyOIDTag == ev->oid_tag)
888 0 : CERT_AddCertToListTail(certList, CERT_DupCertificate(ev->cert));
889 : }
890 :
891 0 : return false;
892 : }
893 :
894 : static bool
895 0 : isEVMatchInExternalDebugRootsFile(SECOidTag policyOIDTag,
896 : CERTCertificate *rootCert)
897 : {
898 0 : if (!testEVInfos)
899 0 : return false;
900 :
901 0 : if (!rootCert)
902 0 : return false;
903 :
904 0 : char *env_val = getenv("ENABLE_TEST_EV_ROOTS_FILE");
905 0 : if (!env_val)
906 0 : return false;
907 :
908 0 : int enabled_val = atoi(env_val);
909 0 : if (!enabled_val)
910 0 : return false;
911 :
912 0 : for (size_t i=0; i<testEVInfos->Length(); ++i) {
913 0 : nsMyTrustedEVInfoClass *ev = testEVInfos->ElementAt(i);
914 0 : if (!ev)
915 0 : continue;
916 0 : if (isEVMatch(policyOIDTag, rootCert, *ev))
917 0 : return true;
918 : }
919 :
920 0 : return false;
921 : }
922 : #endif
923 :
924 : static bool
925 0 : isEVPolicy(SECOidTag policyOIDTag)
926 : {
927 0 : for (size_t iEV=0; iEV < (sizeof(myTrustedEVInfos)/sizeof(nsMyTrustedEVInfo)); ++iEV) {
928 0 : nsMyTrustedEVInfo &entry = myTrustedEVInfos[iEV];
929 0 : if (!entry.oid_name) // invalid or placeholder list entry
930 0 : continue;
931 0 : if (policyOIDTag == entry.oid_tag) {
932 0 : return true;
933 : }
934 : }
935 :
936 : #ifdef PSM_ENABLE_TEST_EV_ROOTS
937 0 : if (isEVPolicyInExternalDebugRootsFile(policyOIDTag)) {
938 0 : return true;
939 : }
940 : #endif
941 :
942 0 : return false;
943 : }
944 :
945 : static CERTCertList*
946 0 : getRootsForOid(SECOidTag oid_tag)
947 : {
948 0 : CERTCertList *certList = CERT_NewCertList();
949 0 : if (!certList)
950 0 : return nsnull;
951 :
952 0 : for (size_t iEV=0; iEV < (sizeof(myTrustedEVInfos)/sizeof(nsMyTrustedEVInfo)); ++iEV) {
953 0 : nsMyTrustedEVInfo &entry = myTrustedEVInfos[iEV];
954 0 : if (!entry.oid_name) // invalid or placeholder list entry
955 0 : continue;
956 0 : if (entry.oid_tag == oid_tag)
957 0 : CERT_AddCertToListTail(certList, CERT_DupCertificate(entry.cert));
958 : }
959 :
960 : #ifdef PSM_ENABLE_TEST_EV_ROOTS
961 0 : getRootsForOidFromExternalRootsFile(certList, oid_tag);
962 : #endif
963 0 : return certList;
964 : }
965 :
966 : static bool
967 0 : isApprovedForEV(SECOidTag policyOIDTag, CERTCertificate *rootCert)
968 : {
969 0 : if (!rootCert)
970 0 : return false;
971 :
972 0 : for (size_t iEV=0; iEV < (sizeof(myTrustedEVInfos)/sizeof(nsMyTrustedEVInfo)); ++iEV) {
973 0 : nsMyTrustedEVInfo &entry = myTrustedEVInfos[iEV];
974 0 : if (!entry.oid_name) // invalid or placeholder list entry
975 0 : continue;
976 0 : if (isEVMatch(policyOIDTag, rootCert, entry)) {
977 0 : return true;
978 : }
979 : }
980 :
981 : #ifdef PSM_ENABLE_TEST_EV_ROOTS
982 0 : if (isEVMatchInExternalDebugRootsFile(policyOIDTag, rootCert)) {
983 0 : return true;
984 : }
985 : #endif
986 :
987 0 : return false;
988 : }
989 :
990 : PRStatus PR_CALLBACK
991 4 : nsNSSComponent::IdentityInfoInit()
992 : {
993 176 : for (size_t iEV=0; iEV < (sizeof(myTrustedEVInfos)/sizeof(nsMyTrustedEVInfo)); ++iEV) {
994 172 : nsMyTrustedEVInfo &entry = myTrustedEVInfos[iEV];
995 172 : if (!entry.oid_name) // invalid or placeholder list entry
996 4 : continue;
997 :
998 : SECStatus rv;
999 : CERTIssuerAndSN ias;
1000 :
1001 168 : rv = ATOB_ConvertAsciiToItem(&ias.derIssuer, const_cast<char*>(entry.issuer_base64));
1002 168 : NS_ASSERTION(rv==SECSuccess, "error converting ascii to binary.");
1003 168 : rv = ATOB_ConvertAsciiToItem(&ias.serialNumber, const_cast<char*>(entry.serial_base64));
1004 168 : NS_ASSERTION(rv==SECSuccess, "error converting ascii to binary.");
1005 168 : ias.serialNumber.type = siUnsignedInteger;
1006 :
1007 168 : entry.cert = CERT_FindCertByIssuerAndSN(nsnull, &ias);
1008 168 : NS_ASSERTION(entry.cert, "Could not find EV root in NSS storage");
1009 :
1010 168 : SECITEM_FreeItem(&ias.derIssuer, false);
1011 168 : SECITEM_FreeItem(&ias.serialNumber, false);
1012 :
1013 168 : if (!entry.cert)
1014 0 : continue;
1015 :
1016 336 : nsNSSCertificate c(entry.cert);
1017 336 : nsAutoString fingerprint;
1018 168 : c.GetSha1Fingerprint(fingerprint);
1019 :
1020 336 : NS_ConvertASCIItoUTF16 sha1(entry.ev_root_sha1_fingerprint);
1021 :
1022 168 : if (sha1 != fingerprint) {
1023 0 : NS_ASSERTION(sha1 == fingerprint, "found EV root with unexpected SHA1 mismatch");
1024 0 : CERT_DestroyCertificate(entry.cert);
1025 0 : entry.cert = nsnull;
1026 0 : continue;
1027 : }
1028 :
1029 : SECItem ev_oid_item;
1030 168 : ev_oid_item.data = nsnull;
1031 168 : ev_oid_item.len = 0;
1032 : SECStatus srv = SEC_StringToOID(nsnull, &ev_oid_item,
1033 168 : entry.dotted_oid, 0);
1034 168 : if (srv != SECSuccess)
1035 0 : continue;
1036 :
1037 168 : entry.oid_tag = register_oid(&ev_oid_item, entry.oid_name);
1038 :
1039 336 : SECITEM_FreeItem(&ev_oid_item, false);
1040 : }
1041 :
1042 : #ifdef PSM_ENABLE_TEST_EV_ROOTS
1043 4 : if (!testEVInfosLoaded) {
1044 4 : testEVInfosLoaded = true;
1045 4 : testEVInfos = new testEVArray;
1046 4 : if (testEVInfos) {
1047 4 : loadTestEVInfos();
1048 : }
1049 : }
1050 : #endif
1051 :
1052 4 : return PR_SUCCESS;
1053 : }
1054 :
1055 : // Find the first policy OID that is known to be an EV policy OID.
1056 4 : static SECStatus getFirstEVPolicy(CERTCertificate *cert, SECOidTag &outOidTag)
1057 : {
1058 4 : if (!cert)
1059 0 : return SECFailure;
1060 :
1061 4 : if (cert->extensions) {
1062 36 : for (int i=0; cert->extensions[i] != nsnull; i++) {
1063 32 : const SECItem *oid = &cert->extensions[i]->id;
1064 :
1065 32 : SECOidTag oidTag = SECOID_FindOIDTag(oid);
1066 32 : if (oidTag != SEC_OID_X509_CERTIFICATE_POLICIES)
1067 32 : continue;
1068 :
1069 0 : SECItem *value = &cert->extensions[i]->value;
1070 :
1071 : CERTCertificatePolicies *policies;
1072 : CERTPolicyInfo **policyInfos, *policyInfo;
1073 :
1074 0 : policies = CERT_DecodeCertificatePoliciesExtension(value);
1075 0 : if (!policies)
1076 0 : continue;
1077 :
1078 0 : policyInfos = policies->policyInfos;
1079 :
1080 0 : bool found = false;
1081 0 : while (*policyInfos != NULL) {
1082 0 : policyInfo = *policyInfos++;
1083 :
1084 0 : SECOidTag oid_tag = policyInfo->oid;
1085 0 : if (oid_tag != SEC_OID_UNKNOWN && isEVPolicy(oid_tag)) {
1086 : // in our list of OIDs accepted for EV
1087 0 : outOidTag = oid_tag;
1088 0 : found = true;
1089 0 : break;
1090 : }
1091 : }
1092 0 : CERT_DestroyCertificatePoliciesExtension(policies);
1093 0 : if (found)
1094 0 : return SECSuccess;
1095 : }
1096 : }
1097 :
1098 4 : return SECFailure;
1099 : }
1100 :
1101 : NS_IMETHODIMP
1102 0 : nsSSLStatus::GetIsExtendedValidation(bool* aIsEV)
1103 : {
1104 0 : NS_ENSURE_ARG_POINTER(aIsEV);
1105 0 : *aIsEV = false;
1106 :
1107 0 : nsCOMPtr<nsIX509Cert> cert = mServerCert;
1108 : nsresult rv;
1109 0 : nsCOMPtr<nsIIdentityInfo> idinfo = do_QueryInterface(cert, &rv);
1110 :
1111 : // mServerCert should never be null when this method is called because
1112 : // nsSSLStatus objects always have mServerCert set right after they are
1113 : // constructed and before they are returned. GetIsExtendedValidation should
1114 : // only be called in the chrome process (in e10s), and mServerCert will always
1115 : // implement nsIIdentityInfo in the chrome process.
1116 0 : if (!idinfo) {
1117 : NS_ERROR("nsSSLStatus has null mServerCert or was called in the content "
1118 0 : "process");
1119 0 : return NS_ERROR_UNEXPECTED;
1120 : }
1121 :
1122 : // Never allow bad certs for EV, regardless of overrides.
1123 0 : if (mHaveCertErrorBits)
1124 0 : return NS_OK;
1125 :
1126 0 : return idinfo->GetIsExtendedValidation(aIsEV);
1127 : }
1128 :
1129 : nsresult
1130 4 : nsNSSCertificate::hasValidEVOidTag(SECOidTag &resultOidTag, bool &validEV)
1131 : {
1132 8 : nsNSSShutDownPreventionLock locker;
1133 4 : if (isAlreadyShutDown())
1134 0 : return NS_ERROR_NOT_AVAILABLE;
1135 :
1136 : nsresult nrv;
1137 : nsCOMPtr<nsINSSComponent> nssComponent =
1138 8 : do_GetService(PSM_COMPONENT_CONTRACTID, &nrv);
1139 4 : if (NS_FAILED(nrv))
1140 0 : return nrv;
1141 4 : nssComponent->EnsureIdentityInfoLoaded();
1142 :
1143 4 : validEV = false;
1144 4 : resultOidTag = SEC_OID_UNKNOWN;
1145 :
1146 4 : bool isOCSPEnabled = false;
1147 8 : nsCOMPtr<nsIX509CertDB> certdb;
1148 4 : certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
1149 4 : if (certdb)
1150 4 : certdb->GetIsOcspOn(&isOCSPEnabled);
1151 : // No OCSP, no EV
1152 4 : if (!isOCSPEnabled)
1153 0 : return NS_OK;
1154 :
1155 : SECOidTag oid_tag;
1156 4 : SECStatus rv = getFirstEVPolicy(mCert, oid_tag);
1157 4 : if (rv != SECSuccess)
1158 4 : return NS_OK;
1159 :
1160 0 : if (oid_tag == SEC_OID_UNKNOWN) // not in our list of OIDs accepted for EV
1161 0 : return NS_OK;
1162 :
1163 0 : CERTCertList *rootList = getRootsForOid(oid_tag);
1164 0 : CERTCertListCleaner rootListCleaner(rootList);
1165 :
1166 : CERTRevocationMethodIndex preferedRevMethods[1] = {
1167 : cert_revocation_method_ocsp
1168 0 : };
1169 :
1170 : PRUint64 revMethodFlags =
1171 : CERT_REV_M_TEST_USING_THIS_METHOD
1172 : | CERT_REV_M_ALLOW_NETWORK_FETCHING
1173 : | CERT_REV_M_ALLOW_IMPLICIT_DEFAULT_SOURCE
1174 : | CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE
1175 : | CERT_REV_M_IGNORE_MISSING_FRESH_INFO
1176 0 : | CERT_REV_M_STOP_TESTING_ON_FRESH_INFO;
1177 :
1178 : PRUint64 revMethodIndependentFlags =
1179 : CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST
1180 0 : | CERT_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE;
1181 :
1182 : PRUint64 methodFlags[2];
1183 0 : methodFlags[cert_revocation_method_crl] = revMethodFlags;
1184 0 : methodFlags[cert_revocation_method_ocsp] = revMethodFlags;
1185 :
1186 : CERTRevocationFlags rev;
1187 :
1188 0 : rev.leafTests.number_of_defined_methods = cert_revocation_method_ocsp +1;
1189 0 : rev.leafTests.cert_rev_flags_per_method = methodFlags;
1190 0 : rev.leafTests.number_of_preferred_methods = 1;
1191 0 : rev.leafTests.preferred_methods = preferedRevMethods;
1192 : rev.leafTests.cert_rev_method_independent_flags =
1193 0 : revMethodIndependentFlags;
1194 :
1195 0 : rev.chainTests.number_of_defined_methods = cert_revocation_method_ocsp +1;
1196 0 : rev.chainTests.cert_rev_flags_per_method = methodFlags;
1197 0 : rev.chainTests.number_of_preferred_methods = 1;
1198 0 : rev.chainTests.preferred_methods = preferedRevMethods;
1199 : rev.chainTests.cert_rev_method_independent_flags =
1200 0 : revMethodIndependentFlags;
1201 :
1202 : CERTValInParam cvin[4];
1203 0 : cvin[0].type = cert_pi_policyOID;
1204 0 : cvin[0].value.arraySize = 1;
1205 0 : cvin[0].value.array.oids = &oid_tag;
1206 :
1207 0 : cvin[1].type = cert_pi_revocationFlags;
1208 0 : cvin[1].value.pointer.revocation = &rev;
1209 :
1210 0 : cvin[2].type = cert_pi_trustAnchors;
1211 0 : cvin[2].value.pointer.chain = rootList;
1212 :
1213 0 : cvin[3].type = cert_pi_end;
1214 :
1215 : CERTValOutParam cvout[2];
1216 0 : cvout[0].type = cert_po_trustAnchor;
1217 0 : cvout[0].value.pointer.cert = nsnull;
1218 0 : cvout[1].type = cert_po_end;
1219 :
1220 0 : PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("calling CERT_PKIXVerifyCert nss cert %p\n", mCert));
1221 : rv = CERT_PKIXVerifyCert(mCert, certificateUsageSSLServer,
1222 0 : cvin, cvout, nsnull);
1223 0 : if (rv != SECSuccess)
1224 0 : return NS_OK;
1225 :
1226 0 : CERTCertificate *issuerCert = cvout[0].value.pointer.cert;
1227 0 : CERTCertificateCleaner issuerCleaner(issuerCert);
1228 :
1229 : #ifdef PR_LOGGING
1230 0 : if (PR_LOG_TEST(gPIPNSSLog, PR_LOG_DEBUG)) {
1231 0 : nsNSSCertificate ic(issuerCert);
1232 0 : nsAutoString fingerprint;
1233 0 : ic.GetSha1Fingerprint(fingerprint);
1234 0 : NS_LossyConvertUTF16toASCII fpa(fingerprint);
1235 0 : PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CERT_PKIXVerifyCert returned success, issuer: %s, SHA1: %s\n",
1236 : issuerCert->subjectName, fpa.get()));
1237 : }
1238 : #endif
1239 :
1240 0 : validEV = isApprovedForEV(oid_tag, issuerCert);
1241 0 : if (validEV)
1242 0 : resultOidTag = oid_tag;
1243 :
1244 0 : return NS_OK;
1245 : }
1246 :
1247 : nsresult
1248 4 : nsNSSCertificate::getValidEVOidTag(SECOidTag &resultOidTag, bool &validEV)
1249 : {
1250 4 : if (mCachedEVStatus != ev_status_unknown) {
1251 0 : validEV = (mCachedEVStatus == ev_status_valid);
1252 0 : if (validEV)
1253 0 : resultOidTag = mCachedEVOidTag;
1254 0 : return NS_OK;
1255 : }
1256 :
1257 4 : nsresult rv = hasValidEVOidTag(resultOidTag, validEV);
1258 4 : if (NS_SUCCEEDED(rv)) {
1259 4 : if (validEV) {
1260 0 : mCachedEVOidTag = resultOidTag;
1261 : }
1262 4 : mCachedEVStatus = validEV ? ev_status_valid : ev_status_invalid;
1263 : }
1264 4 : return rv;
1265 : }
1266 :
1267 : NS_IMETHODIMP
1268 4 : nsNSSCertificate::GetIsExtendedValidation(bool* aIsEV)
1269 : {
1270 8 : nsNSSShutDownPreventionLock locker;
1271 4 : if (isAlreadyShutDown())
1272 0 : return NS_ERROR_NOT_AVAILABLE;
1273 :
1274 4 : NS_ENSURE_ARG(aIsEV);
1275 4 : *aIsEV = false;
1276 :
1277 4 : if (mCachedEVStatus != ev_status_unknown) {
1278 0 : *aIsEV = (mCachedEVStatus == ev_status_valid);
1279 0 : return NS_OK;
1280 : }
1281 :
1282 : SECOidTag oid_tag;
1283 4 : return getValidEVOidTag(oid_tag, *aIsEV);
1284 : }
1285 :
1286 : NS_IMETHODIMP
1287 0 : nsNSSCertificate::GetValidEVPolicyOid(nsACString &outDottedOid)
1288 : {
1289 0 : nsNSSShutDownPreventionLock locker;
1290 0 : if (isAlreadyShutDown())
1291 0 : return NS_ERROR_NOT_AVAILABLE;
1292 :
1293 : SECOidTag oid_tag;
1294 : bool valid;
1295 0 : nsresult rv = getValidEVOidTag(oid_tag, valid);
1296 0 : if (NS_FAILED(rv))
1297 0 : return rv;
1298 :
1299 0 : if (valid) {
1300 0 : SECOidData *oid_data = SECOID_FindOIDByTag(oid_tag);
1301 0 : if (!oid_data)
1302 0 : return NS_ERROR_FAILURE;
1303 :
1304 0 : char *oid_str = CERT_GetOidString(&oid_data->oid);
1305 0 : if (!oid_str)
1306 0 : return NS_ERROR_FAILURE;
1307 :
1308 0 : outDottedOid = oid_str;
1309 0 : PR_smprintf_free(oid_str);
1310 : }
1311 0 : return NS_OK;
1312 : }
1313 :
1314 : NS_IMETHODIMP
1315 4 : nsNSSComponent::EnsureIdentityInfoLoaded()
1316 : {
1317 4 : PRStatus rv = PR_CallOnce(&mIdentityInfoCallOnce, IdentityInfoInit);
1318 4 : return (rv == PR_SUCCESS) ? NS_OK : NS_ERROR_FAILURE;
1319 : }
1320 :
1321 : // only called during shutdown
1322 : void
1323 328 : nsNSSComponent::CleanupIdentityInfo()
1324 : {
1325 656 : nsNSSShutDownPreventionLock locker;
1326 14432 : for (size_t iEV=0; iEV < (sizeof(myTrustedEVInfos)/sizeof(nsMyTrustedEVInfo)); ++iEV) {
1327 14104 : nsMyTrustedEVInfo &entry = myTrustedEVInfos[iEV];
1328 14104 : if (entry.cert) {
1329 168 : CERT_DestroyCertificate(entry.cert);
1330 168 : entry.cert = nsnull;
1331 : }
1332 : }
1333 :
1334 : #ifdef PSM_ENABLE_TEST_EV_ROOTS
1335 328 : if (testEVInfosLoaded) {
1336 4 : testEVInfosLoaded = false;
1337 4 : if (testEVInfos) {
1338 4 : for (size_t i = 0; i<testEVInfos->Length(); ++i) {
1339 0 : delete testEVInfos->ElementAt(i);
1340 : }
1341 4 : testEVInfos->Clear();
1342 4 : delete testEVInfos;
1343 4 : testEVInfos = nsnull;
1344 : }
1345 : }
1346 : #endif
1347 328 : memset(&mIdentityInfoCallOnce, 0, sizeof(PRCallOnceType));
1348 328 : }
|