1 : /* ***** BEGIN LICENSE BLOCK *****
2 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 : *
4 : * The contents of this file are subject to the Mozilla Public License Version
5 : * 1.1 (the "License"); you may not use this file except in compliance with
6 : * the License. You may obtain a copy of the License at
7 : * http://www.mozilla.org/MPL/
8 : *
9 : * Software distributed under the License is distributed on an "AS IS" basis,
10 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 : * for the specific language governing rights and limitations under the
12 : * License.
13 : *
14 : * The Original Code is the Netscape security libraries.
15 : *
16 : * The Initial Developer of the Original Code is
17 : * Netscape Communications Corporation.
18 : * Portions created by the Initial Developer are Copyright (C) 2000
19 : * the Initial Developer. All Rights Reserved.
20 : *
21 : * Contributor(s):
22 : * Ian McGreer <mcgreer@netscape.com>
23 : * Javier Delgadillo <javi@netscape.com>
24 : * John Gardiner Myers <jgmyers@speakeasy.net>
25 : * Martin v. Loewis <martin@v.loewis.de>
26 : *
27 : * Alternatively, the contents of this file may be used under the terms of
28 : * either the GNU General Public License Version 2 or later (the "GPL"), or
29 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 : * in which case the provisions of the GPL or the LGPL are applicable instead
31 : * of those above. If you wish to allow use of your version of this file only
32 : * under the terms of either the GPL or the LGPL, and not to allow others to
33 : * use your version of this file under the terms of the MPL, indicate your
34 : * decision by deleting the provisions above and replace them with the notice
35 : * and other provisions required by the GPL or the LGPL. If you do not delete
36 : * the provisions above, a recipient may use your version of this file under
37 : * the terms of any one of the MPL, the GPL or the LGPL.
38 : *
39 : * ***** END LICENSE BLOCK ***** */
40 :
41 : #include "prmem.h"
42 : #include "prerror.h"
43 : #include "prprf.h"
44 :
45 : #include "nsNSSCertHelper.h"
46 : #include "nsCOMPtr.h"
47 : #include "nsNSSCertificate.h"
48 : #include "cert.h"
49 : #include "keyhi.h"
50 : #include "secder.h"
51 : #include "nsNSSCertValidity.h"
52 : #include "nsNSSASN1Object.h"
53 : #include "nsNSSComponent.h"
54 : #include "nsNSSCertTrust.h"
55 : #include "nsIDateTimeFormat.h"
56 : #include "nsDateTimeFormatCID.h"
57 :
58 : static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
59 :
60 : /* Object Identifier constants */
61 : #define CONST_OID static const unsigned char
62 : #define MICROSOFT_OID 0x2b, 0x6, 0x1, 0x4, 0x1, 0x82, 0x37
63 : #define PKIX_OID 0x2b, 0x6, 0x01, 0x05, 0x05, 0x07
64 : CONST_OID msCertExtCerttype[] = { MICROSOFT_OID, 20, 2};
65 : CONST_OID msNTPrincipalName[] = { MICROSOFT_OID, 20, 2, 3 };
66 : CONST_OID msCertsrvCAVersion[] = { MICROSOFT_OID, 21, 1 };
67 : CONST_OID msNTDSReplication[] = { MICROSOFT_OID, 25, 1 };
68 : CONST_OID pkixLogotype[] = { PKIX_OID, 1, 12 };
69 :
70 : #define OI(x) { siDEROID, (unsigned char *)x, sizeof x }
71 : #define OD(oid,desc,mech,ext) {OI(oid), SEC_OID_UNKNOWN, desc, mech, ext}
72 : #define SEC_OID(tag) more_oids[tag].offset
73 :
74 : static SECOidData more_oids[] = {
75 : /* Microsoft OIDs */
76 : #define MS_CERT_EXT_CERTTYPE 0
77 : OD( msCertExtCerttype,
78 : "Microsoft Certificate Template Name",
79 : CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
80 :
81 : #define MS_NT_PRINCIPAL_NAME 1
82 : OD( msNTPrincipalName,
83 : "Microsoft Principal Name",
84 : CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
85 :
86 : #define MS_CERTSERV_CA_VERSION 2
87 : OD( msCertsrvCAVersion,
88 : "Microsoft CA Version",
89 : CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
90 :
91 : #define MS_NTDS_REPLICATION 3
92 : OD( msNTDSReplication,
93 : "Microsoft Domain GUID",
94 : CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
95 :
96 : #define PKIX_LOGOTYPE 4
97 : OD( pkixLogotype,
98 : "Logotype",
99 : CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
100 : };
101 :
102 : static const unsigned int numOids = (sizeof more_oids) / (sizeof more_oids[0]);
103 :
104 : static nsresult
105 0 : GetIntValue(SECItem *versionItem,
106 : unsigned long *version)
107 : {
108 : SECStatus srv;
109 :
110 0 : srv = SEC_ASN1DecodeInteger(versionItem,version);
111 0 : if (srv != SECSuccess) {
112 0 : NS_ERROR("Could not decode version of cert");
113 0 : return NS_ERROR_FAILURE;
114 : }
115 0 : return NS_OK;
116 : }
117 :
118 : static nsresult
119 0 : ProcessVersion(SECItem *versionItem,
120 : nsINSSComponent *nssComponent,
121 : nsIASN1PrintableItem **retItem)
122 : {
123 : nsresult rv;
124 0 : nsAutoString text;
125 0 : nsCOMPtr<nsIASN1PrintableItem> printableItem = new nsNSSASN1PrintableItem();
126 0 : if (printableItem == nsnull)
127 0 : return NS_ERROR_OUT_OF_MEMORY;
128 :
129 0 : nssComponent->GetPIPNSSBundleString("CertDumpVersion", text);
130 0 : rv = printableItem->SetDisplayName(text);
131 0 : if (NS_FAILED(rv))
132 0 : return rv;
133 :
134 : // Now to figure out what version this certificate is.
135 : unsigned long version;
136 :
137 0 : if (versionItem->data) {
138 0 : rv = GetIntValue(versionItem, &version);
139 0 : if (NS_FAILED(rv))
140 0 : return rv;
141 : } else {
142 : // If there is no version present in the cert, then rfc2459
143 : // says we default to v1 (0)
144 0 : version = 0;
145 : }
146 :
147 0 : switch (version){
148 : case 0:
149 0 : rv = nssComponent->GetPIPNSSBundleString("CertDumpVersion1", text);
150 0 : break;
151 : case 1:
152 0 : rv = nssComponent->GetPIPNSSBundleString("CertDumpVersion2", text);
153 0 : break;
154 : case 2:
155 0 : rv = nssComponent->GetPIPNSSBundleString("CertDumpVersion3", text);
156 0 : break;
157 : default:
158 0 : NS_ERROR("Bad value for cert version");
159 0 : rv = NS_ERROR_FAILURE;
160 : }
161 :
162 0 : if (NS_FAILED(rv))
163 0 : return rv;
164 :
165 0 : rv = printableItem->SetDisplayValue(text);
166 0 : if (NS_FAILED(rv))
167 0 : return rv;
168 :
169 0 : *retItem = printableItem;
170 0 : NS_ADDREF(*retItem);
171 0 : return NS_OK;
172 : }
173 :
174 : static nsresult
175 0 : ProcessSerialNumberDER(SECItem *serialItem,
176 : nsINSSComponent *nssComponent,
177 : nsIASN1PrintableItem **retItem)
178 : {
179 : nsresult rv;
180 0 : nsAutoString text;
181 0 : nsCOMPtr<nsIASN1PrintableItem> printableItem = new nsNSSASN1PrintableItem();
182 :
183 0 : if (printableItem == nsnull)
184 0 : return NS_ERROR_OUT_OF_MEMORY;
185 :
186 0 : rv = nssComponent->GetPIPNSSBundleString("CertDumpSerialNo", text);
187 0 : if (NS_FAILED(rv))
188 0 : return rv;
189 :
190 0 : rv = printableItem->SetDisplayName(text);
191 0 : if (NS_FAILED(rv))
192 0 : return rv;
193 :
194 0 : nsXPIDLCString serialNumber;
195 0 : serialNumber.Adopt(CERT_Hexify(serialItem, 1));
196 0 : if (serialNumber == nsnull)
197 0 : return NS_ERROR_OUT_OF_MEMORY;
198 :
199 0 : rv = printableItem->SetDisplayValue(NS_ConvertASCIItoUTF16(serialNumber));
200 0 : *retItem = printableItem;
201 0 : NS_ADDREF(*retItem);
202 0 : return rv;
203 : }
204 :
205 : static nsresult
206 0 : GetDefaultOIDFormat(SECItem *oid,
207 : nsINSSComponent *nssComponent,
208 : nsAString &outString,
209 : char separator)
210 : {
211 : char buf[300];
212 0 : unsigned int len = 0;
213 0 : int written, invalidCount = 0;
214 :
215 : unsigned int i;
216 0 : unsigned long val = 0;
217 0 : bool invalid = false;
218 0 : bool first = true;
219 :
220 0 : val = 0;
221 0 : for (i = 0; i < oid->len; ++i) {
222 : // In this loop, we have to parse a DER formatted
223 : // If the first bit is a 1, then the integer is
224 : // represented by more than one byte. If the
225 : // first bit is set then we continue on and add
226 : // the values of the later bytes until we get
227 : // a byte without the first bit set.
228 : unsigned long j;
229 :
230 0 : j = oid->data[i];
231 0 : val = (val << 7) | (j & 0x7f);
232 0 : if (j & 0x80) {
233 : // - If val is 0 in this block, the OID number particle starts with 0x80
234 : // what is specified as an invalid formating.
235 : // - If val is larger then 2^32-7, on next left shift by 7 we will loose
236 : // the most significant bits, this OID number particle cannot be read
237 : // by our implementation.
238 : // - If the first bit is set while this is the last component of the OID
239 : // we are also in an invalid state.
240 0 : if (val == 0 || (val >= (1 << (32-7))) || (i == oid->len-1)) {
241 0 : invalid = true;
242 : }
243 :
244 0 : if (i < oid->len-1)
245 0 : continue;
246 : }
247 :
248 0 : if (!invalid) {
249 0 : if (first) {
250 0 : unsigned long one = NS_MIN(val/40, 2UL); // never > 2
251 0 : unsigned long two = val - (one * 40);
252 :
253 : written = PR_snprintf(&buf[len], sizeof(buf)-len, "%lu%c%lu",
254 0 : one, separator, two);
255 : }
256 : else {
257 : written = PR_snprintf(&buf[len], sizeof(buf)-len, "%c%lu",
258 0 : separator, val);
259 : }
260 : }
261 : else {
262 0 : nsAutoString unknownText;
263 : nssComponent->GetPIPNSSBundleString("CertUnknown",
264 0 : unknownText);
265 0 : if (first) {
266 : written = PR_snprintf(&buf[len], sizeof(buf)-len, "%s",
267 0 : NS_ConvertUTF16toUTF8(unknownText).get());
268 : }
269 : else {
270 : written = PR_snprintf(&buf[len], sizeof(buf)-len, "%c%s",
271 : separator,
272 0 : NS_ConvertUTF16toUTF8(unknownText).get());
273 : }
274 :
275 0 : if (++invalidCount > 3) {
276 : // Allow only 3 occurences of Unknown in OID display string to
277 : // prevent bloat.
278 : break;
279 : }
280 : }
281 :
282 0 : if (written < 0)
283 0 : return NS_ERROR_FAILURE;
284 :
285 0 : len += written;
286 0 : NS_ASSERTION(len < sizeof(buf), "OID data to big to display in 300 chars.");
287 0 : val = 0;
288 0 : invalid = false;
289 0 : first = false;
290 : }
291 :
292 0 : CopyASCIItoUTF16(buf, outString);
293 0 : return NS_OK;
294 : }
295 :
296 : static nsresult
297 0 : GetOIDText(SECItem *oid, nsINSSComponent *nssComponent, nsAString &text)
298 : {
299 : nsresult rv;
300 0 : SECOidTag oidTag = SECOID_FindOIDTag(oid);
301 0 : const char *bundlekey = 0;
302 :
303 0 : switch (oidTag) {
304 : case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
305 0 : bundlekey = "CertDumpMD2WithRSA";
306 0 : break;
307 : case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
308 0 : bundlekey = "CertDumpMD5WithRSA";
309 0 : break;
310 : case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
311 0 : bundlekey = "CertDumpSHA1WithRSA";
312 0 : break;
313 : case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
314 0 : bundlekey = "CertDumpSHA256WithRSA";
315 0 : break;
316 : case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
317 0 : bundlekey = "CertDumpSHA384WithRSA";
318 0 : break;
319 : case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
320 0 : bundlekey = "CertDumpSHA512WithRSA";
321 0 : break;
322 : case SEC_OID_PKCS1_RSA_ENCRYPTION:
323 0 : bundlekey = "CertDumpRSAEncr";
324 0 : break;
325 : case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
326 0 : bundlekey = "CertDumpRSAPSSSignature";
327 0 : break;
328 : case SEC_OID_NS_CERT_EXT_CERT_TYPE:
329 0 : bundlekey = "CertDumpCertType";
330 0 : break;
331 : case SEC_OID_NS_CERT_EXT_BASE_URL:
332 0 : bundlekey = "CertDumpNSCertExtBaseUrl";
333 0 : break;
334 : case SEC_OID_NS_CERT_EXT_REVOCATION_URL:
335 0 : bundlekey = "CertDumpNSCertExtRevocationUrl";
336 0 : break;
337 : case SEC_OID_NS_CERT_EXT_CA_REVOCATION_URL:
338 0 : bundlekey = "CertDumpNSCertExtCARevocationUrl";
339 0 : break;
340 : case SEC_OID_NS_CERT_EXT_CERT_RENEWAL_URL:
341 0 : bundlekey = "CertDumpNSCertExtCertRenewalUrl";
342 0 : break;
343 : case SEC_OID_NS_CERT_EXT_CA_POLICY_URL:
344 0 : bundlekey = "CertDumpNSCertExtCAPolicyUrl";
345 0 : break;
346 : case SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME:
347 0 : bundlekey = "CertDumpNSCertExtSslServerName";
348 0 : break;
349 : case SEC_OID_NS_CERT_EXT_COMMENT:
350 0 : bundlekey = "CertDumpNSCertExtComment";
351 0 : break;
352 : case SEC_OID_NS_CERT_EXT_LOST_PASSWORD_URL:
353 0 : bundlekey = "CertDumpNSCertExtLostPasswordUrl";
354 0 : break;
355 : case SEC_OID_NS_CERT_EXT_CERT_RENEWAL_TIME:
356 0 : bundlekey = "CertDumpNSCertExtCertRenewalTime";
357 0 : break;
358 : case SEC_OID_NETSCAPE_AOLSCREENNAME:
359 0 : bundlekey = "CertDumpNetscapeAolScreenname";
360 0 : break;
361 : case SEC_OID_AVA_COUNTRY_NAME:
362 0 : bundlekey = "CertDumpAVACountry";
363 0 : break;
364 : case SEC_OID_AVA_COMMON_NAME:
365 0 : bundlekey = "CertDumpAVACN";
366 0 : break;
367 : case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME:
368 0 : bundlekey = "CertDumpAVAOU";
369 0 : break;
370 : case SEC_OID_AVA_ORGANIZATION_NAME:
371 0 : bundlekey = "CertDumpAVAOrg";
372 0 : break;
373 : case SEC_OID_AVA_LOCALITY:
374 0 : bundlekey = "CertDumpAVALocality";
375 0 : break;
376 : case SEC_OID_AVA_DN_QUALIFIER:
377 0 : bundlekey = "CertDumpAVADN";
378 0 : break;
379 : case SEC_OID_AVA_DC:
380 0 : bundlekey = "CertDumpAVADC";
381 0 : break;
382 : case SEC_OID_AVA_STATE_OR_PROVINCE:
383 0 : bundlekey = "CertDumpAVAState";
384 0 : break;
385 : case SEC_OID_AVA_SURNAME:
386 0 : bundlekey = "CertDumpSurname";
387 0 : break;
388 : case SEC_OID_AVA_GIVEN_NAME:
389 0 : bundlekey = "CertDumpGivenName";
390 0 : break;
391 : case SEC_OID_X509_SUBJECT_DIRECTORY_ATTR:
392 0 : bundlekey = "CertDumpSubjectDirectoryAttr";
393 0 : break;
394 : case SEC_OID_X509_SUBJECT_KEY_ID:
395 0 : bundlekey = "CertDumpSubjectKeyID";
396 0 : break;
397 : case SEC_OID_X509_KEY_USAGE:
398 0 : bundlekey = "CertDumpKeyUsage";
399 0 : break;
400 : case SEC_OID_X509_SUBJECT_ALT_NAME:
401 0 : bundlekey = "CertDumpSubjectAltName";
402 0 : break;
403 : case SEC_OID_X509_ISSUER_ALT_NAME:
404 0 : bundlekey = "CertDumpIssuerAltName";
405 0 : break;
406 : case SEC_OID_X509_BASIC_CONSTRAINTS:
407 0 : bundlekey = "CertDumpBasicConstraints";
408 0 : break;
409 : case SEC_OID_X509_NAME_CONSTRAINTS:
410 0 : bundlekey = "CertDumpNameConstraints";
411 0 : break;
412 : case SEC_OID_X509_CRL_DIST_POINTS:
413 0 : bundlekey = "CertDumpCrlDistPoints";
414 0 : break;
415 : case SEC_OID_X509_CERTIFICATE_POLICIES:
416 0 : bundlekey = "CertDumpCertPolicies";
417 0 : break;
418 : case SEC_OID_X509_POLICY_MAPPINGS:
419 0 : bundlekey = "CertDumpPolicyMappings";
420 0 : break;
421 : case SEC_OID_X509_POLICY_CONSTRAINTS:
422 0 : bundlekey = "CertDumpPolicyConstraints";
423 0 : break;
424 : case SEC_OID_X509_AUTH_KEY_ID:
425 0 : bundlekey = "CertDumpAuthKeyID";
426 0 : break;
427 : case SEC_OID_X509_EXT_KEY_USAGE:
428 0 : bundlekey = "CertDumpExtKeyUsage";
429 0 : break;
430 : case SEC_OID_X509_AUTH_INFO_ACCESS:
431 0 : bundlekey = "CertDumpAuthInfoAccess";
432 0 : break;
433 : case SEC_OID_ANSIX9_DSA_SIGNATURE:
434 0 : bundlekey = "CertDumpAnsiX9DsaSignature";
435 0 : break;
436 : case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
437 0 : bundlekey = "CertDumpAnsiX9DsaSignatureWithSha1";
438 0 : break;
439 : case SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST:
440 0 : bundlekey = "CertDumpAnsiX962ECDsaSignatureWithSha1";
441 0 : break;
442 : case SEC_OID_RFC1274_UID:
443 0 : bundlekey = "CertDumpUserID";
444 0 : break;
445 : case SEC_OID_PKCS9_EMAIL_ADDRESS:
446 0 : bundlekey = "CertDumpPK9Email";
447 0 : break;
448 : case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
449 0 : bundlekey = "CertDumpECPublicKey";
450 0 : break;
451 : /* ANSI X9.62 named elliptic curves (prime field) */
452 : case SEC_OID_ANSIX962_EC_PRIME192V1:
453 : /* same as SEC_OID_SECG_EC_SECP192r1 */
454 0 : bundlekey = "CertDumpECprime192v1";
455 0 : break;
456 : case SEC_OID_ANSIX962_EC_PRIME192V2:
457 0 : bundlekey = "CertDumpECprime192v2";
458 0 : break;
459 : case SEC_OID_ANSIX962_EC_PRIME192V3:
460 0 : bundlekey = "CertDumpECprime192v3";
461 0 : break;
462 : case SEC_OID_ANSIX962_EC_PRIME239V1:
463 0 : bundlekey = "CertDumpECprime239v1";
464 0 : break;
465 : case SEC_OID_ANSIX962_EC_PRIME239V2:
466 0 : bundlekey = "CertDumpECprime239v2";
467 0 : break;
468 : case SEC_OID_ANSIX962_EC_PRIME239V3:
469 0 : bundlekey = "CertDumpECprime239v3";
470 0 : break;
471 : case SEC_OID_ANSIX962_EC_PRIME256V1:
472 : /* same as SEC_OID_SECG_EC_SECP256r1 */
473 0 : bundlekey = "CertDumpECprime256v1";
474 0 : break;
475 : /* SECG named elliptic curves (prime field) */
476 : case SEC_OID_SECG_EC_SECP112R1:
477 0 : bundlekey = "CertDumpECsecp112r1";
478 0 : break;
479 : case SEC_OID_SECG_EC_SECP112R2:
480 0 : bundlekey = "CertDumpECsecp112r2";
481 0 : break;
482 : case SEC_OID_SECG_EC_SECP128R1:
483 0 : bundlekey = "CertDumpECsecp128r1";
484 0 : break;
485 : case SEC_OID_SECG_EC_SECP128R2:
486 0 : bundlekey = "CertDumpECsecp128r2";
487 0 : break;
488 : case SEC_OID_SECG_EC_SECP160K1:
489 0 : bundlekey = "CertDumpECsecp160k1";
490 0 : break;
491 : case SEC_OID_SECG_EC_SECP160R1:
492 0 : bundlekey = "CertDumpECsecp160r1";
493 0 : break;
494 : case SEC_OID_SECG_EC_SECP160R2:
495 0 : bundlekey = "CertDumpECsecp160r2";
496 0 : break;
497 : case SEC_OID_SECG_EC_SECP192K1:
498 0 : bundlekey = "CertDumpECsecp192k1";
499 0 : break;
500 : case SEC_OID_SECG_EC_SECP224K1:
501 0 : bundlekey = "CertDumpECsecp224k1";
502 0 : break;
503 : case SEC_OID_SECG_EC_SECP224R1:
504 0 : bundlekey = "CertDumpECsecp224r1";
505 0 : break;
506 : case SEC_OID_SECG_EC_SECP256K1:
507 0 : bundlekey = "CertDumpECsecp256k1";
508 0 : break;
509 : case SEC_OID_SECG_EC_SECP384R1:
510 0 : bundlekey = "CertDumpECsecp384r1";
511 0 : break;
512 :
513 : case SEC_OID_SECG_EC_SECP521R1:
514 0 : bundlekey = "CertDumpECsecp521r1";
515 0 : break;
516 : /* ANSI X9.62 named elliptic curves (characteristic two field) */
517 : case SEC_OID_ANSIX962_EC_C2PNB163V1:
518 0 : bundlekey = "CertDumpECc2pnb163v1";
519 0 : break;
520 : case SEC_OID_ANSIX962_EC_C2PNB163V2:
521 0 : bundlekey = "CertDumpECc2pnb163v2";
522 0 : break;
523 : case SEC_OID_ANSIX962_EC_C2PNB163V3:
524 0 : bundlekey = "CertDumpECc2pnb163v3";
525 0 : break;
526 : case SEC_OID_ANSIX962_EC_C2PNB176V1:
527 0 : bundlekey = "CertDumpECc2pnb176v1";
528 0 : break;
529 : case SEC_OID_ANSIX962_EC_C2TNB191V1:
530 0 : bundlekey = "CertDumpECc2tnb191v1";
531 0 : break;
532 : case SEC_OID_ANSIX962_EC_C2TNB191V2:
533 0 : bundlekey = "CertDumpECc2tnb191v2";
534 0 : break;
535 : case SEC_OID_ANSIX962_EC_C2TNB191V3:
536 0 : bundlekey = "CertDumpECc2tnb191v3";
537 0 : break;
538 : case SEC_OID_ANSIX962_EC_C2ONB191V4:
539 0 : bundlekey = "CertDumpECc2onb191v4";
540 0 : break;
541 : case SEC_OID_ANSIX962_EC_C2ONB191V5:
542 0 : bundlekey = "CertDumpECc2onb191v5";
543 0 : break;
544 : case SEC_OID_ANSIX962_EC_C2PNB208W1:
545 0 : bundlekey = "CertDumpECc2pnb208w1";
546 0 : break;
547 : case SEC_OID_ANSIX962_EC_C2TNB239V1:
548 0 : bundlekey = "CertDumpECc2tnb239v1";
549 0 : break;
550 : case SEC_OID_ANSIX962_EC_C2TNB239V2:
551 0 : bundlekey = "CertDumpECc2tnb239v2";
552 0 : break;
553 : case SEC_OID_ANSIX962_EC_C2TNB239V3:
554 0 : bundlekey = "CertDumpECc2tnb239v3";
555 0 : break;
556 : case SEC_OID_ANSIX962_EC_C2ONB239V4:
557 0 : bundlekey = "CertDumpECc2onb239v4";
558 0 : break;
559 : case SEC_OID_ANSIX962_EC_C2ONB239V5:
560 0 : bundlekey = "CertDumpECc2onb239v5";
561 0 : break;
562 : case SEC_OID_ANSIX962_EC_C2PNB272W1:
563 0 : bundlekey = "CertDumpECc2pnb272w1";
564 0 : break;
565 : case SEC_OID_ANSIX962_EC_C2PNB304W1:
566 0 : bundlekey = "CertDumpECc2pnb304w1";
567 0 : break;
568 : case SEC_OID_ANSIX962_EC_C2TNB359V1:
569 0 : bundlekey = "CertDumpECc2tnb359v1";
570 0 : break;
571 : case SEC_OID_ANSIX962_EC_C2PNB368W1:
572 0 : bundlekey = "CertDumpECc2pnb368w1";
573 0 : break;
574 : case SEC_OID_ANSIX962_EC_C2TNB431R1:
575 0 : bundlekey = "CertDumpECc2tnb431r1";
576 0 : break;
577 : /* SECG named elliptic curves (characteristic two field) */
578 : case SEC_OID_SECG_EC_SECT113R1:
579 0 : bundlekey = "CertDumpECsect113r1";
580 0 : break;
581 : case SEC_OID_SECG_EC_SECT113R2:
582 0 : bundlekey = "CertDumpECsect113r2";
583 0 : break;
584 : case SEC_OID_SECG_EC_SECT131R1:
585 0 : bundlekey = "CertDumpECsect131r1";
586 0 : break;
587 : case SEC_OID_SECG_EC_SECT131R2:
588 0 : bundlekey = "CertDumpECsect131r2";
589 0 : break;
590 : case SEC_OID_SECG_EC_SECT163K1:
591 0 : bundlekey = "CertDumpECsect163k1";
592 0 : break;
593 : case SEC_OID_SECG_EC_SECT163R1:
594 0 : bundlekey = "CertDumpECsect163r1";
595 0 : break;
596 : case SEC_OID_SECG_EC_SECT163R2:
597 0 : bundlekey = "CertDumpECsect163r2";
598 0 : break;
599 : case SEC_OID_SECG_EC_SECT193R1:
600 0 : bundlekey = "CertDumpECsect193r1";
601 0 : break;
602 : case SEC_OID_SECG_EC_SECT193R2:
603 0 : bundlekey = "CertDumpECsect193r2";
604 0 : break;
605 : case SEC_OID_SECG_EC_SECT233K1:
606 0 : bundlekey = "CertDumpECsect233k1";
607 0 : break;
608 : case SEC_OID_SECG_EC_SECT233R1:
609 0 : bundlekey = "CertDumpECsect233r1";
610 0 : break;
611 : case SEC_OID_SECG_EC_SECT239K1:
612 0 : bundlekey = "CertDumpECsect239k1";
613 0 : break;
614 : case SEC_OID_SECG_EC_SECT283K1:
615 0 : bundlekey = "CertDumpECsect283k1";
616 0 : break;
617 : case SEC_OID_SECG_EC_SECT283R1:
618 0 : bundlekey = "CertDumpECsect283r1";
619 0 : break;
620 : case SEC_OID_SECG_EC_SECT409K1:
621 0 : bundlekey = "CertDumpECsect409k1";
622 0 : break;
623 : case SEC_OID_SECG_EC_SECT409R1:
624 0 : bundlekey = "CertDumpECsect409r1";
625 0 : break;
626 : case SEC_OID_SECG_EC_SECT571K1:
627 0 : bundlekey = "CertDumpECsect571k1";
628 0 : break;
629 : case SEC_OID_SECG_EC_SECT571R1:
630 0 : bundlekey = "CertDumpECsect571r1";
631 0 : break;
632 : default:
633 0 : if (oidTag == SEC_OID(MS_CERT_EXT_CERTTYPE)) {
634 0 : bundlekey = "CertDumpMSCerttype";
635 0 : break;
636 : }
637 0 : if (oidTag == SEC_OID(MS_CERTSERV_CA_VERSION)) {
638 0 : bundlekey = "CertDumpMSCAVersion";
639 0 : break;
640 : }
641 0 : if (oidTag == SEC_OID(PKIX_LOGOTYPE)) {
642 0 : bundlekey = "CertDumpLogotype";
643 0 : break;
644 : }
645 : /* fallthrough */
646 : }
647 :
648 0 : if (bundlekey) {
649 0 : rv = nssComponent->GetPIPNSSBundleString(bundlekey, text);
650 : } else {
651 0 : nsAutoString text2;
652 0 : rv = GetDefaultOIDFormat(oid, nssComponent, text2, ' ');
653 0 : if (NS_FAILED(rv))
654 0 : return rv;
655 :
656 0 : const PRUnichar *params[1] = {text2.get()};
657 : rv = nssComponent->PIPBundleFormatStringFromName("CertDumpDefOID",
658 0 : params, 1, text);
659 : }
660 0 : return rv;
661 : }
662 :
663 : #define SEPARATOR "\n"
664 :
665 : static nsresult
666 0 : ProcessRawBytes(nsINSSComponent *nssComponent, SECItem *data,
667 : nsAString &text, bool wantHeader = true)
668 : {
669 : // This function is used to display some DER bytes
670 : // that we have not added support for decoding.
671 : // If it's short, let's display as an integer, no size header.
672 :
673 0 : if (data->len <= 4) {
674 0 : int i_pv = DER_GetInteger(data);
675 0 : nsAutoString value;
676 0 : value.AppendInt(i_pv);
677 0 : text.Append(value);
678 0 : text.Append(NS_LITERAL_STRING(SEPARATOR).get());
679 0 : return NS_OK;
680 : }
681 :
682 : // Else produce a hex dump.
683 :
684 0 : if (wantHeader) {
685 0 : nsAutoString bytelen, bitlen;
686 0 : bytelen.AppendInt(data->len);
687 0 : bitlen.AppendInt(data->len*8);
688 :
689 0 : const PRUnichar *params[2] = {bytelen.get(), bitlen.get()};
690 : nsresult rv = nssComponent->PIPBundleFormatStringFromName("CertDumpRawBytesHeader",
691 0 : params, 2, text);
692 0 : if (NS_FAILED(rv))
693 0 : return rv;
694 :
695 0 : text.Append(NS_LITERAL_STRING(SEPARATOR).get());
696 : }
697 :
698 : // This prints the value of the byte out into a
699 : // string that can later be displayed as a byte
700 : // string. We place a new line after 24 bytes
701 : // to break up extermaly long sequence of bytes.
702 :
703 : PRUint32 i;
704 : char buffer[5];
705 0 : for (i=0; i<data->len; i++) {
706 0 : PR_snprintf(buffer, 5, "%02x ", data->data[i]);
707 0 : AppendASCIItoUTF16(buffer, text);
708 0 : if ((i+1)%16 == 0) {
709 0 : text.Append(NS_LITERAL_STRING(SEPARATOR).get());
710 : }
711 : }
712 0 : return NS_OK;
713 : }
714 :
715 : static nsresult
716 0 : ProcessNSCertTypeExtensions(SECItem *extData,
717 : nsAString &text,
718 : nsINSSComponent *nssComponent)
719 : {
720 0 : nsAutoString local;
721 : SECItem decoded;
722 0 : decoded.data = nsnull;
723 0 : decoded.len = 0;
724 0 : if (SECSuccess != SEC_ASN1DecodeItem(nsnull, &decoded,
725 0 : SEC_ASN1_GET(SEC_BitStringTemplate), extData)) {
726 0 : nssComponent->GetPIPNSSBundleString("CertDumpExtensionFailure", local);
727 0 : text.Append(local.get());
728 0 : return NS_OK;
729 : }
730 0 : unsigned char nsCertType = decoded.data[0];
731 0 : nsMemory::Free(decoded.data);
732 0 : if (nsCertType & NS_CERT_TYPE_SSL_CLIENT) {
733 0 : nssComponent->GetPIPNSSBundleString("VerifySSLClient", local);
734 0 : text.Append(local.get());
735 0 : text.Append(NS_LITERAL_STRING(SEPARATOR).get());
736 : }
737 0 : if (nsCertType & NS_CERT_TYPE_SSL_SERVER) {
738 0 : nssComponent->GetPIPNSSBundleString("VerifySSLServer", local);
739 0 : text.Append(local.get());
740 0 : text.Append(NS_LITERAL_STRING(SEPARATOR).get());
741 : }
742 0 : if (nsCertType & NS_CERT_TYPE_EMAIL) {
743 0 : nssComponent->GetPIPNSSBundleString("CertDumpCertTypeEmail", local);
744 0 : text.Append(local.get());
745 0 : text.Append(NS_LITERAL_STRING(SEPARATOR).get());
746 : }
747 0 : if (nsCertType & NS_CERT_TYPE_OBJECT_SIGNING) {
748 0 : nssComponent->GetPIPNSSBundleString("VerifyObjSign", local);
749 0 : text.Append(local.get());
750 0 : text.Append(NS_LITERAL_STRING(SEPARATOR).get());
751 : }
752 0 : if (nsCertType & NS_CERT_TYPE_SSL_CA) {
753 0 : nssComponent->GetPIPNSSBundleString("VerifySSLCA", local);
754 0 : text.Append(local.get());
755 0 : text.Append(NS_LITERAL_STRING(SEPARATOR).get());
756 : }
757 0 : if (nsCertType & NS_CERT_TYPE_EMAIL_CA) {
758 0 : nssComponent->GetPIPNSSBundleString("CertDumpEmailCA", local);
759 0 : text.Append(local.get());
760 0 : text.Append(NS_LITERAL_STRING(SEPARATOR).get());
761 : }
762 0 : if (nsCertType & NS_CERT_TYPE_OBJECT_SIGNING_CA) {
763 0 : nssComponent->GetPIPNSSBundleString("VerifyObjSign", local);
764 0 : text.Append(local.get());
765 0 : text.Append(NS_LITERAL_STRING(SEPARATOR).get());
766 : }
767 0 : return NS_OK;
768 : }
769 :
770 : static nsresult
771 0 : ProcessKeyUsageExtension(SECItem *extData, nsAString &text,
772 : nsINSSComponent *nssComponent)
773 : {
774 0 : nsAutoString local;
775 : SECItem decoded;
776 0 : decoded.data = nsnull;
777 0 : decoded.len = 0;
778 0 : if (SECSuccess != SEC_ASN1DecodeItem(nsnull, &decoded,
779 0 : SEC_ASN1_GET(SEC_BitStringTemplate), extData)) {
780 0 : nssComponent->GetPIPNSSBundleString("CertDumpExtensionFailure", local);
781 0 : text.Append(local.get());
782 0 : return NS_OK;
783 : }
784 0 : unsigned char keyUsage = decoded.data[0];
785 0 : nsMemory::Free(decoded.data);
786 0 : if (keyUsage & KU_DIGITAL_SIGNATURE) {
787 0 : nssComponent->GetPIPNSSBundleString("CertDumpKUSign", local);
788 0 : text.Append(local.get());
789 0 : text.Append(NS_LITERAL_STRING(SEPARATOR).get());
790 : }
791 0 : if (keyUsage & KU_NON_REPUDIATION) {
792 0 : nssComponent->GetPIPNSSBundleString("CertDumpKUNonRep", local);
793 0 : text.Append(local.get());
794 0 : text.Append(NS_LITERAL_STRING(SEPARATOR).get());
795 : }
796 0 : if (keyUsage & KU_KEY_ENCIPHERMENT) {
797 0 : nssComponent->GetPIPNSSBundleString("CertDumpKUEnc", local);
798 0 : text.Append(local.get());
799 0 : text.Append(NS_LITERAL_STRING(SEPARATOR).get());
800 : }
801 0 : if (keyUsage & KU_DATA_ENCIPHERMENT) {
802 0 : nssComponent->GetPIPNSSBundleString("CertDumpKUDEnc", local);
803 0 : text.Append(local.get());
804 0 : text.Append(NS_LITERAL_STRING(SEPARATOR).get());
805 : }
806 0 : if (keyUsage & KU_KEY_AGREEMENT) {
807 0 : nssComponent->GetPIPNSSBundleString("CertDumpKUKA", local);
808 0 : text.Append(local.get());
809 0 : text.Append(NS_LITERAL_STRING(SEPARATOR).get());
810 : }
811 0 : if (keyUsage & KU_KEY_CERT_SIGN) {
812 0 : nssComponent->GetPIPNSSBundleString("CertDumpKUCertSign", local);
813 0 : text.Append(local.get());
814 0 : text.Append(NS_LITERAL_STRING(SEPARATOR).get());
815 : }
816 0 : if (keyUsage & KU_CRL_SIGN) {
817 0 : nssComponent->GetPIPNSSBundleString("CertDumpKUCRLSigner", local);
818 0 : text.Append(local.get());
819 0 : text.Append(NS_LITERAL_STRING(SEPARATOR).get());
820 : }
821 :
822 0 : return NS_OK;
823 : }
824 :
825 : static nsresult
826 0 : ProcessBasicConstraints(SECItem *extData,
827 : nsAString &text,
828 : nsINSSComponent *nssComponent)
829 : {
830 0 : nsAutoString local;
831 : CERTBasicConstraints value;
832 : SECStatus rv;
833 : nsresult rv2;
834 :
835 0 : value.pathLenConstraint = -1;
836 0 : rv = CERT_DecodeBasicConstraintValue (&value, extData);
837 0 : if (rv != SECSuccess) {
838 0 : ProcessRawBytes(nssComponent, extData, text);
839 0 : return NS_OK;
840 : }
841 0 : if (value.isCA)
842 0 : rv2 = nssComponent->GetPIPNSSBundleString("CertDumpIsCA", local);
843 : else
844 0 : rv2 = nssComponent->GetPIPNSSBundleString("CertDumpIsNotCA", local);
845 0 : if (NS_FAILED(rv2))
846 0 : return rv2;
847 0 : text.Append(local.get());
848 0 : if (value.pathLenConstraint != -1) {
849 0 : nsAutoString depth;
850 0 : if (value.pathLenConstraint == CERT_UNLIMITED_PATH_CONSTRAINT)
851 0 : nssComponent->GetPIPNSSBundleString("CertDumpPathLenUnlimited", depth);
852 : else
853 0 : depth.AppendInt(value.pathLenConstraint);
854 0 : const PRUnichar *params[1] = {depth.get()};
855 : rv2 = nssComponent->PIPBundleFormatStringFromName("CertDumpPathLen",
856 0 : params, 1, local);
857 0 : if (NS_FAILED(rv2))
858 0 : return rv2;
859 0 : text.Append(NS_LITERAL_STRING(SEPARATOR).get());
860 0 : text.Append(local.get());
861 : }
862 0 : return NS_OK;
863 : }
864 :
865 : static nsresult
866 0 : ProcessExtKeyUsage(SECItem *extData,
867 : nsAString &text,
868 : nsINSSComponent *nssComponent)
869 : {
870 0 : nsAutoString local;
871 0 : CERTOidSequence *extKeyUsage = NULL;
872 : SECItem **oids;
873 : SECItem *oid;
874 : nsresult rv;
875 :
876 0 : extKeyUsage = CERT_DecodeOidSequence(extData);
877 0 : if (extKeyUsage == NULL)
878 0 : return NS_ERROR_FAILURE;
879 :
880 0 : oids = extKeyUsage->oids;
881 0 : while (oids != NULL && *oids != NULL) {
882 : // For each OID, try to find a bundle string
883 : // of the form CertDumpEKU_<underlined-OID>
884 0 : nsAutoString oidname;
885 0 : oid = *oids;
886 0 : rv = GetDefaultOIDFormat(oid, nssComponent, oidname, '_');
887 0 : if (NS_FAILED(rv))
888 0 : return rv;
889 0 : nsAutoString bundlekey = NS_LITERAL_STRING("CertDumpEKU_")+ oidname;
890 0 : NS_ConvertUTF16toUTF8 bk_ascii(bundlekey);
891 :
892 0 : rv = nssComponent->GetPIPNSSBundleString(bk_ascii.get(), local);
893 0 : nsresult rv2 = GetDefaultOIDFormat(oid, nssComponent, oidname, '.');
894 0 : if (NS_FAILED(rv2))
895 0 : return rv2;
896 0 : if (NS_SUCCEEDED(rv)) {
897 : // display name and OID in parentheses
898 0 : text.Append(local);
899 0 : text.Append(NS_LITERAL_STRING(" ("));
900 0 : text.Append(oidname);
901 0 : text.Append(NS_LITERAL_STRING(")"));
902 : } else
903 : // If there is no bundle string, just display the OID itself
904 0 : text.Append(oidname);
905 :
906 0 : text.Append(NS_LITERAL_STRING(SEPARATOR).get());
907 0 : oids++;
908 : }
909 :
910 0 : CERT_DestroyOidSequence(extKeyUsage);
911 0 : return NS_OK;
912 : }
913 :
914 : static nsresult
915 0 : ProcessRDN(CERTRDN* rdn, nsAString &finalString, nsINSSComponent *nssComponent)
916 : {
917 : nsresult rv;
918 : CERTAVA** avas;
919 : CERTAVA* ava;
920 0 : SECItem *decodeItem = nsnull;
921 0 : nsString avavalue;
922 0 : nsString type;
923 0 : nsAutoString temp;
924 : const PRUnichar *params[2];
925 :
926 0 : avas = rdn->avas;
927 0 : while ((ava = *avas++) != 0) {
928 0 : rv = GetOIDText(&ava->type, nssComponent, type);
929 0 : if (NS_FAILED(rv))
930 0 : return rv;
931 :
932 : //This function returns a string in UTF8 format.
933 0 : decodeItem = CERT_DecodeAVAValue(&ava->value);
934 0 : if(!decodeItem) {
935 0 : return NS_ERROR_FAILURE;
936 : }
937 :
938 : // We know we can fit buffer of this length. CERT_RFC1485_EscapeAndQuote
939 : // will fail if we provide smaller buffer then the result can fit to.
940 0 : PRIntn escapedValueCapacity = decodeItem->len * 3 + 3;
941 0 : nsAutoArrayPtr<char> escapedValue;
942 0 : escapedValue = new char[escapedValueCapacity];
943 0 : if (!escapedValue) {
944 0 : SECITEM_FreeItem(decodeItem, true);
945 0 : return NS_ERROR_OUT_OF_MEMORY;
946 : }
947 :
948 : SECStatus status = CERT_RFC1485_EscapeAndQuote(
949 : escapedValue.get(),
950 : escapedValueCapacity,
951 : (char*)decodeItem->data,
952 0 : decodeItem->len);
953 0 : if (SECSuccess != status) {
954 0 : SECITEM_FreeItem(decodeItem, true);
955 0 : return NS_ERROR_FAILURE;
956 : }
957 :
958 0 : avavalue = NS_ConvertUTF8toUTF16(escapedValue);
959 :
960 0 : SECITEM_FreeItem(decodeItem, true);
961 0 : params[0] = type.get();
962 0 : params[1] = avavalue.get();
963 : nssComponent->PIPBundleFormatStringFromName("AVATemplate",
964 0 : params, 2, temp);
965 0 : finalString += temp + NS_LITERAL_STRING("\n");
966 : }
967 0 : return NS_OK;
968 : }
969 :
970 : static nsresult
971 0 : ProcessName(CERTName *name, nsINSSComponent *nssComponent, PRUnichar **value)
972 : {
973 : CERTRDN** rdns;
974 : CERTRDN** rdn;
975 0 : nsString finalString;
976 :
977 0 : rdns = name->rdns;
978 :
979 : nsresult rv;
980 : CERTRDN **lastRdn;
981 0 : lastRdn = rdns;
982 :
983 :
984 : /* find last RDN */
985 0 : lastRdn = rdns;
986 0 : while (*lastRdn) lastRdn++;
987 : // The above whille loop will put us at the last member
988 : // of the array which is a NULL pointer. So let's back
989 : // up one spot so that we have the last non-NULL entry in
990 : // the array in preparation for traversing the
991 : // RDN's (Relative Distinguished Name) in reverse oder.
992 0 : lastRdn--;
993 :
994 : /*
995 : * Loop over name contents in _reverse_ RDN order appending to string
996 : * When building the Ascii string, NSS loops over these entries in
997 : * reverse order, so I will as well. The difference is that NSS
998 : * will always place them in a one line string separated by commas,
999 : * where I want each entry on a single line. I can't just use a comma
1000 : * as my delimitter because it is a valid character to have in the
1001 : * value portion of the AVA and could cause trouble when parsing.
1002 : */
1003 0 : for (rdn = lastRdn; rdn >= rdns; rdn--) {
1004 0 : rv = ProcessRDN(*rdn, finalString, nssComponent);
1005 0 : if (NS_FAILED(rv))
1006 0 : return rv;
1007 : }
1008 0 : *value = ToNewUnicode(finalString);
1009 0 : return NS_OK;
1010 : }
1011 :
1012 : static nsresult
1013 0 : ProcessIA5String(SECItem *extData,
1014 : nsAString &text,
1015 : nsINSSComponent *nssComponent)
1016 : {
1017 : SECItem item;
1018 0 : nsAutoString local;
1019 0 : if (SECSuccess != SEC_ASN1DecodeItem(nsnull, &item,
1020 : SEC_ASN1_GET(SEC_IA5StringTemplate),
1021 0 : extData))
1022 0 : return NS_ERROR_FAILURE;
1023 0 : local.AssignASCII((char*)item.data, item.len);
1024 0 : nsMemory::Free(item.data);
1025 0 : text.Append(local);
1026 0 : return NS_OK;
1027 : }
1028 :
1029 : static nsresult
1030 0 : AppendBMPtoUTF16(PRArenaPool *arena,
1031 : unsigned char* data, unsigned int len,
1032 : nsAString& text)
1033 : {
1034 : unsigned int utf8ValLen;
1035 : unsigned char *utf8Val;
1036 :
1037 0 : if (len % 2 != 0)
1038 0 : return NS_ERROR_FAILURE;
1039 :
1040 : /* XXX instead of converting to and from UTF-8, it would
1041 : be sufficient to just swap bytes, or do nothing */
1042 0 : utf8ValLen = len * 3 + 1;
1043 0 : utf8Val = (unsigned char*)PORT_ArenaZAlloc(arena, utf8ValLen);
1044 0 : if (!PORT_UCS2_UTF8Conversion(false, data, len,
1045 0 : utf8Val, utf8ValLen, &utf8ValLen))
1046 0 : return NS_ERROR_FAILURE;
1047 0 : AppendUTF8toUTF16((char*)utf8Val, text);
1048 0 : return NS_OK;
1049 : }
1050 :
1051 : static nsresult
1052 0 : ProcessBMPString(SECItem *extData,
1053 : nsAString &text,
1054 : nsINSSComponent *nssComponent)
1055 : {
1056 : SECItem item;
1057 : PRArenaPool *arena;
1058 0 : nsresult rv = NS_ERROR_FAILURE;
1059 :
1060 0 : arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1061 0 : if (!arena)
1062 0 : return NS_ERROR_FAILURE;
1063 :
1064 0 : if (SECSuccess == SEC_ASN1DecodeItem(arena, &item,
1065 : SEC_ASN1_GET(SEC_BMPStringTemplate),
1066 0 : extData))
1067 0 : rv = AppendBMPtoUTF16(arena, item.data, item.len, text);
1068 0 : PORT_FreeArena(arena, false);
1069 0 : return rv;
1070 : }
1071 :
1072 : static nsresult
1073 0 : ProcessGeneralName(PRArenaPool *arena,
1074 : CERTGeneralName *current,
1075 : nsAString &text,
1076 : nsINSSComponent *nssComponent)
1077 : {
1078 0 : NS_ENSURE_ARG_POINTER(current);
1079 :
1080 0 : nsAutoString key;
1081 0 : nsXPIDLString value;
1082 0 : nsresult rv = NS_OK;
1083 :
1084 0 : switch (current->type) {
1085 : case certOtherName: {
1086 0 : SECOidTag oidTag = SECOID_FindOIDTag(¤t->name.OthName.oid);
1087 0 : if (oidTag == SEC_OID(MS_NT_PRINCIPAL_NAME)) {
1088 : /* The type of this name is apparently nowhere explicitly
1089 : documented. However, in the generated templates, it is always
1090 : UTF-8. So try to decode this as UTF-8; if that fails, dump the
1091 : raw data. */
1092 : SECItem decoded;
1093 0 : nssComponent->GetPIPNSSBundleString("CertDumpMSNTPrincipal", key);
1094 0 : if (SEC_ASN1DecodeItem(arena, &decoded,
1095 : SEC_ASN1_GET(SEC_UTF8StringTemplate),
1096 0 : ¤t->name.OthName.name) == SECSuccess) {
1097 0 : AppendUTF8toUTF16(nsCAutoString((char*)decoded.data, decoded.len),
1098 0 : value);
1099 : } else {
1100 0 : ProcessRawBytes(nssComponent, ¤t->name.OthName.name, value);
1101 : }
1102 0 : break;
1103 0 : } else if (oidTag == SEC_OID(MS_NTDS_REPLICATION)) {
1104 : /* This should be a 16-byte GUID */
1105 : SECItem guid;
1106 0 : nssComponent->GetPIPNSSBundleString("CertDumpMSDomainGUID", key);
1107 0 : if (SEC_ASN1DecodeItem(arena, &guid,
1108 : SEC_ASN1_GET(SEC_OctetStringTemplate),
1109 0 : ¤t->name.OthName.name) == SECSuccess
1110 : && guid.len == 16) {
1111 : char buf[40];
1112 0 : unsigned char *d = guid.data;
1113 : PR_snprintf(buf, sizeof(buf),
1114 : "{%.2x%.2x%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x}",
1115 0 : d[3], d[2], d[1], d[0], d[5], d[4], d[7], d[6],
1116 0 : d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
1117 0 : value.AssignASCII(buf);
1118 : } else {
1119 0 : ProcessRawBytes(nssComponent, ¤t->name.OthName.name, value);
1120 : }
1121 : } else {
1122 0 : rv = GetDefaultOIDFormat(¤t->name.OthName.oid, nssComponent, key, ' ');
1123 0 : if (NS_FAILED(rv))
1124 0 : goto finish;
1125 0 : ProcessRawBytes(nssComponent, ¤t->name.OthName.name, value);
1126 : }
1127 0 : break;
1128 : }
1129 : case certRFC822Name:
1130 0 : nssComponent->GetPIPNSSBundleString("CertDumpRFC822Name", key);
1131 0 : value.AssignASCII((char*)current->name.other.data, current->name.other.len);
1132 0 : break;
1133 : case certDNSName:
1134 0 : nssComponent->GetPIPNSSBundleString("CertDumpDNSName", key);
1135 0 : value.AssignASCII((char*)current->name.other.data, current->name.other.len);
1136 0 : break;
1137 : case certX400Address:
1138 0 : nssComponent->GetPIPNSSBundleString("CertDumpX400Address", key);
1139 0 : ProcessRawBytes(nssComponent, ¤t->name.other, value);
1140 0 : break;
1141 : case certDirectoryName:
1142 0 : nssComponent->GetPIPNSSBundleString("CertDumpDirectoryName", key);
1143 : rv = ProcessName(¤t->name.directoryName, nssComponent,
1144 0 : getter_Copies(value));
1145 0 : if (NS_FAILED(rv))
1146 0 : goto finish;
1147 0 : break;
1148 : case certEDIPartyName:
1149 0 : nssComponent->GetPIPNSSBundleString("CertDumpEDIPartyName", key);
1150 0 : ProcessRawBytes(nssComponent, ¤t->name.other, value);
1151 0 : break;
1152 : case certURI:
1153 0 : nssComponent->GetPIPNSSBundleString("CertDumpURI", key);
1154 0 : value.AssignASCII((char*)current->name.other.data, current->name.other.len);
1155 0 : break;
1156 : case certIPAddress:
1157 : {
1158 : char buf[INET6_ADDRSTRLEN];
1159 0 : PRStatus status = PR_FAILURE;
1160 : PRNetAddr addr;
1161 0 : memset(&addr, 0, sizeof(addr));
1162 0 : nssComponent->GetPIPNSSBundleString("CertDumpIPAddress", key);
1163 0 : if (current->name.other.len == 4) {
1164 0 : addr.inet.family = PR_AF_INET;
1165 0 : memcpy(&addr.inet.ip, current->name.other.data, current->name.other.len);
1166 0 : status = PR_NetAddrToString(&addr, buf, sizeof(buf));
1167 0 : } else if (current->name.other.len == 16) {
1168 0 : addr.ipv6.family = PR_AF_INET6;
1169 0 : memcpy(&addr.ipv6.ip, current->name.other.data, current->name.other.len);
1170 0 : status = PR_NetAddrToString(&addr, buf, sizeof(buf));
1171 : }
1172 0 : if (status == PR_SUCCESS) {
1173 0 : value.AssignASCII(buf);
1174 : } else {
1175 : /* invalid IP address */
1176 0 : ProcessRawBytes(nssComponent, ¤t->name.other, value);
1177 : }
1178 0 : break;
1179 : }
1180 : case certRegisterID:
1181 0 : nssComponent->GetPIPNSSBundleString("CertDumpRegisterID", key);
1182 0 : rv = GetDefaultOIDFormat(¤t->name.other, nssComponent, value, '.');
1183 0 : if (NS_FAILED(rv))
1184 0 : goto finish;
1185 0 : break;
1186 : }
1187 0 : text.Append(key);
1188 0 : text.Append(NS_LITERAL_STRING(": "));
1189 0 : text.Append(value);
1190 0 : text.Append(NS_LITERAL_STRING(SEPARATOR));
1191 : finish:
1192 0 : return rv;
1193 : }
1194 :
1195 : static nsresult
1196 0 : ProcessGeneralNames(PRArenaPool *arena,
1197 : CERTGeneralName *nameList,
1198 : nsAString &text,
1199 : nsINSSComponent *nssComponent)
1200 : {
1201 0 : CERTGeneralName *current = nameList;
1202 : nsresult rv;
1203 :
1204 0 : do {
1205 0 : rv = ProcessGeneralName(arena, current, text, nssComponent);
1206 0 : if (NS_FAILED(rv))
1207 0 : break;
1208 0 : current = CERT_GetNextGeneralName(current);
1209 : } while (current != nameList);
1210 0 : return rv;
1211 : }
1212 :
1213 : static nsresult
1214 0 : ProcessAltName(SECItem *extData,
1215 : nsAString &text,
1216 : nsINSSComponent *nssComponent)
1217 : {
1218 0 : nsresult rv = NS_OK;
1219 : PRArenaPool *arena;
1220 : CERTGeneralName *nameList;
1221 :
1222 0 : arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1223 0 : if (!arena)
1224 0 : return NS_ERROR_FAILURE;
1225 :
1226 0 : nameList = CERT_DecodeAltNameExtension(arena, extData);
1227 0 : if (!nameList)
1228 0 : goto finish;
1229 :
1230 0 : rv = ProcessGeneralNames(arena, nameList, text, nssComponent);
1231 :
1232 : finish:
1233 0 : PORT_FreeArena(arena, false);
1234 0 : return rv;
1235 : }
1236 :
1237 : static nsresult
1238 0 : ProcessSubjectKeyId(SECItem *extData,
1239 : nsAString &text,
1240 : nsINSSComponent *nssComponent)
1241 : {
1242 : PRArenaPool *arena;
1243 0 : nsresult rv = NS_OK;
1244 : SECItem decoded;
1245 0 : nsAutoString local;
1246 :
1247 0 : arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1248 0 : if (!arena)
1249 0 : return NS_ERROR_FAILURE;
1250 :
1251 0 : if (SEC_QuickDERDecodeItem(arena, &decoded,
1252 : SEC_ASN1_GET(SEC_OctetStringTemplate),
1253 0 : extData) != SECSuccess) {
1254 0 : rv = NS_ERROR_FAILURE;
1255 0 : goto finish;
1256 : }
1257 :
1258 0 : nssComponent->GetPIPNSSBundleString("CertDumpKeyID", local);
1259 0 : text.Append(local);
1260 0 : text.Append(NS_LITERAL_STRING(": "));
1261 0 : ProcessRawBytes(nssComponent, &decoded, text);
1262 :
1263 : finish:
1264 0 : PORT_FreeArena(arena, false);
1265 0 : return rv;
1266 : }
1267 :
1268 : static nsresult
1269 0 : ProcessAuthKeyId(SECItem *extData,
1270 : nsAString &text,
1271 : nsINSSComponent *nssComponent)
1272 : {
1273 : CERTAuthKeyID *ret;
1274 : PRArenaPool *arena;
1275 0 : nsresult rv = NS_OK;
1276 0 : nsAutoString local;
1277 :
1278 0 : arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1279 0 : if (!arena)
1280 0 : return NS_ERROR_OUT_OF_MEMORY;
1281 :
1282 0 : ret = CERT_DecodeAuthKeyID (arena, extData);
1283 0 : if (!ret) {
1284 0 : rv = NS_ERROR_FAILURE;
1285 0 : goto finish;
1286 : }
1287 :
1288 0 : if (ret->keyID.len > 0) {
1289 0 : nssComponent->GetPIPNSSBundleString("CertDumpKeyID", local);
1290 0 : text.Append(local);
1291 0 : text.Append(NS_LITERAL_STRING(": "));
1292 0 : ProcessRawBytes(nssComponent, &ret->keyID, text);
1293 0 : text.Append(NS_LITERAL_STRING(SEPARATOR));
1294 : }
1295 :
1296 0 : if (ret->authCertIssuer) {
1297 0 : nssComponent->GetPIPNSSBundleString("CertDumpIssuer", local);
1298 0 : text.Append(local);
1299 0 : text.Append(NS_LITERAL_STRING(": "));
1300 0 : rv = ProcessGeneralNames(arena, ret->authCertIssuer, text, nssComponent);
1301 0 : if (NS_FAILED(rv))
1302 0 : goto finish;
1303 : }
1304 :
1305 0 : if (ret->authCertSerialNumber.len > 0) {
1306 0 : nssComponent->GetPIPNSSBundleString("CertDumpSerialNo", local);
1307 0 : text.Append(local);
1308 0 : text.Append(NS_LITERAL_STRING(": "));
1309 0 : ProcessRawBytes(nssComponent, &ret->authCertSerialNumber, text);
1310 : }
1311 :
1312 : finish:
1313 0 : PORT_FreeArena(arena, false);
1314 0 : return rv;
1315 : }
1316 :
1317 : static nsresult
1318 0 : ProcessUserNotice(SECItem *der_notice,
1319 : nsAString &text,
1320 : nsINSSComponent *nssComponent)
1321 : {
1322 0 : CERTUserNotice *notice = NULL;
1323 : SECItem **itemList;
1324 : PRArenaPool *arena;
1325 :
1326 0 : arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1327 0 : if (!arena)
1328 0 : return NS_ERROR_FAILURE;
1329 :
1330 0 : notice = CERT_DecodeUserNotice(der_notice);
1331 0 : if (notice == NULL) {
1332 0 : ProcessRawBytes(nssComponent, der_notice, text);
1333 0 : goto finish;
1334 : }
1335 :
1336 0 : if (notice->noticeReference.organization.len != 0) {
1337 0 : switch (notice->noticeReference.organization.type) {
1338 : case siAsciiString:
1339 : case siVisibleString:
1340 : case siUTF8String:
1341 : text.Append(NS_ConvertUTF8toUTF16(
1342 : (const char *)notice->noticeReference.organization.data,
1343 0 : notice->noticeReference.organization.len));
1344 0 : break;
1345 : case siBMPString:
1346 : AppendBMPtoUTF16(arena, notice->noticeReference.organization.data,
1347 0 : notice->noticeReference.organization.len, text);
1348 0 : break;
1349 : default:
1350 0 : break;
1351 : }
1352 0 : text.Append(NS_LITERAL_STRING(" - "));
1353 0 : itemList = notice->noticeReference.noticeNumbers;
1354 0 : while (*itemList) {
1355 : unsigned long number;
1356 : char buffer[60];
1357 0 : if (SEC_ASN1DecodeInteger(*itemList, &number) == SECSuccess) {
1358 0 : PR_snprintf(buffer, sizeof(buffer), "#%d", number);
1359 0 : if (itemList != notice->noticeReference.noticeNumbers)
1360 0 : text.Append(NS_LITERAL_STRING(", "));
1361 0 : AppendASCIItoUTF16(buffer, text);
1362 : }
1363 0 : itemList++;
1364 : }
1365 : }
1366 0 : if (notice->displayText.len != 0) {
1367 0 : text.Append(NS_LITERAL_STRING(SEPARATOR));
1368 0 : text.Append(NS_LITERAL_STRING(" "));
1369 0 : switch (notice->displayText.type) {
1370 : case siAsciiString:
1371 : case siVisibleString:
1372 : case siUTF8String:
1373 : text.Append(NS_ConvertUTF8toUTF16((const char *)notice->displayText.data,
1374 0 : notice->displayText.len));
1375 0 : break;
1376 : case siBMPString:
1377 : AppendBMPtoUTF16(arena, notice->displayText.data, notice->displayText.len,
1378 0 : text);
1379 0 : break;
1380 : default:
1381 0 : break;
1382 : }
1383 : }
1384 : finish:
1385 0 : if (notice)
1386 0 : CERT_DestroyUserNotice(notice);
1387 0 : PORT_FreeArena(arena, false);
1388 0 : return NS_OK;
1389 : }
1390 :
1391 : static nsresult
1392 0 : ProcessCertificatePolicies(SECItem *extData,
1393 : nsAString &text,
1394 : SECOidTag ev_oid_tag, // SEC_OID_UNKNOWN means: not EV
1395 : nsINSSComponent *nssComponent)
1396 : {
1397 : CERTCertificatePolicies *policies;
1398 : CERTPolicyInfo **policyInfos, *policyInfo;
1399 : CERTPolicyQualifier **policyQualifiers, *policyQualifier;
1400 0 : nsAutoString local;
1401 0 : nsresult rv = NS_OK;
1402 :
1403 0 : policies = CERT_DecodeCertificatePoliciesExtension(extData);
1404 0 : if ( policies == NULL )
1405 0 : return NS_ERROR_FAILURE;
1406 :
1407 0 : policyInfos = policies->policyInfos;
1408 0 : while (*policyInfos != NULL ) {
1409 0 : policyInfo = *policyInfos++;
1410 0 : switch (policyInfo->oid) {
1411 : case SEC_OID_VERISIGN_USER_NOTICES:
1412 0 : nssComponent->GetPIPNSSBundleString("CertDumpVerisignNotices", local);
1413 0 : text.Append(local);
1414 0 : break;
1415 : default:
1416 0 : GetDefaultOIDFormat(&policyInfo->policyID, nssComponent, local, '.');
1417 0 : text.Append(local);
1418 : }
1419 :
1420 0 : bool needColon = true;
1421 0 : if (ev_oid_tag != SEC_OID_UNKNOWN) {
1422 : // This is an EV cert. Let's see if this oid is the EV oid,
1423 : // because we want to display the EV information string
1424 : // next to the correct OID.
1425 :
1426 0 : if (policyInfo->oid == ev_oid_tag) {
1427 0 : text.Append(NS_LITERAL_STRING(":"));
1428 0 : text.Append(NS_LITERAL_STRING(SEPARATOR));
1429 0 : needColon = false;
1430 0 : nssComponent->GetPIPNSSBundleString("CertDumpPolicyOidEV", local);
1431 0 : text.Append(local);
1432 : }
1433 : }
1434 :
1435 0 : if (policyInfo->policyQualifiers) {
1436 : /* Add all qualifiers on separate lines, indented */
1437 0 : policyQualifiers = policyInfo->policyQualifiers;
1438 0 : if (needColon)
1439 0 : text.Append(NS_LITERAL_STRING(":"));
1440 0 : text.Append(NS_LITERAL_STRING(SEPARATOR));
1441 0 : while (*policyQualifiers != NULL) {
1442 0 : text.Append(NS_LITERAL_STRING(" "));
1443 0 : policyQualifier = *policyQualifiers++;
1444 0 : switch(policyQualifier->oid) {
1445 : case SEC_OID_PKIX_CPS_POINTER_QUALIFIER:
1446 0 : nssComponent->GetPIPNSSBundleString("CertDumpCPSPointer", local);
1447 0 : text.Append(local);
1448 0 : text.Append(NS_LITERAL_STRING(":"));
1449 0 : text.Append(NS_LITERAL_STRING(SEPARATOR));
1450 0 : text.Append(NS_LITERAL_STRING(" "));
1451 : /* The CPS pointer ought to be the cPSuri alternative
1452 : of the Qualifier choice. */
1453 : rv = ProcessIA5String(&policyQualifier->qualifierValue,
1454 0 : text, nssComponent);
1455 0 : if (NS_FAILED(rv))
1456 0 : goto finish;
1457 0 : break;
1458 : case SEC_OID_PKIX_USER_NOTICE_QUALIFIER:
1459 0 : nssComponent->GetPIPNSSBundleString("CertDumpUserNotice", local);
1460 0 : text.Append(local);
1461 0 : text.Append(NS_LITERAL_STRING(": "));
1462 : rv = ProcessUserNotice(&policyQualifier->qualifierValue,
1463 0 : text, nssComponent);
1464 0 : break;
1465 : default:
1466 0 : GetDefaultOIDFormat(&policyQualifier->qualifierID, nssComponent, local, '.');
1467 0 : text.Append(local);
1468 0 : text.Append(NS_LITERAL_STRING(": "));
1469 0 : ProcessRawBytes(nssComponent, &policyQualifier->qualifierValue, text);
1470 : }
1471 0 : text.Append(NS_LITERAL_STRING(SEPARATOR));
1472 : } /* while policyQualifiers */
1473 : } /* if policyQualifiers */
1474 0 : text.Append(NS_LITERAL_STRING(SEPARATOR));
1475 : }
1476 :
1477 : finish:
1478 0 : CERT_DestroyCertificatePoliciesExtension(policies);
1479 0 : return rv;
1480 : }
1481 :
1482 : static nsresult
1483 0 : ProcessCrlDistPoints(SECItem *extData,
1484 : nsAString &text,
1485 : nsINSSComponent *nssComponent)
1486 : {
1487 : CERTCrlDistributionPoints *crldp;
1488 : CRLDistributionPoint **points, *point;
1489 : PRArenaPool *arena;
1490 0 : nsresult rv = NS_OK;
1491 0 : nsAutoString local;
1492 : int reasons, comma;
1493 :
1494 0 : arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1495 0 : if (!arena)
1496 0 : return NS_ERROR_FAILURE;
1497 :
1498 0 : crldp = CERT_DecodeCRLDistributionPoints(arena, extData);
1499 0 : if (!crldp || !crldp->distPoints) {
1500 0 : rv = NS_ERROR_FAILURE;
1501 0 : goto finish;
1502 : }
1503 :
1504 0 : for(points = crldp->distPoints; *points; points++) {
1505 0 : point = *points;
1506 0 : switch (point->distPointType) {
1507 : case generalName:
1508 : rv = ProcessGeneralName(arena, point->distPoint.fullName,
1509 0 : text, nssComponent);
1510 0 : if (NS_FAILED(rv))
1511 0 : goto finish;
1512 0 : break;
1513 : case relativeDistinguishedName:
1514 : rv = ProcessRDN(&point->distPoint.relativeName,
1515 0 : text, nssComponent);
1516 0 : if (NS_FAILED(rv))
1517 0 : goto finish;
1518 0 : break;
1519 : }
1520 0 : if (point->reasons.len) {
1521 0 : reasons = point->reasons.data[0];
1522 0 : text.Append(NS_LITERAL_STRING(" "));
1523 0 : comma = 0;
1524 0 : if (reasons & RF_UNUSED) {
1525 0 : nssComponent->GetPIPNSSBundleString("CertDumpUnused", local);
1526 0 : text.Append(local); comma = 1;
1527 : }
1528 0 : if (reasons & RF_KEY_COMPROMISE) {
1529 0 : if (comma) text.Append(NS_LITERAL_STRING(", "));
1530 0 : nssComponent->GetPIPNSSBundleString("CertDumpKeyCompromise", local);
1531 0 : text.Append(local); comma = 1;
1532 : }
1533 0 : if (reasons & RF_CA_COMPROMISE) {
1534 0 : if (comma) text.Append(NS_LITERAL_STRING(", "));
1535 0 : nssComponent->GetPIPNSSBundleString("CertDumpCACompromise", local);
1536 0 : text.Append(local); comma = 1;
1537 : }
1538 0 : if (reasons & RF_AFFILIATION_CHANGED) {
1539 0 : if (comma) text.Append(NS_LITERAL_STRING(", "));
1540 0 : nssComponent->GetPIPNSSBundleString("CertDumpAffiliationChanged", local);
1541 0 : text.Append(local); comma = 1;
1542 : }
1543 0 : if (reasons & RF_SUPERSEDED) {
1544 0 : if (comma) text.Append(NS_LITERAL_STRING(", "));
1545 0 : nssComponent->GetPIPNSSBundleString("CertDumpSuperseded", local);
1546 0 : text.Append(local); comma = 1;
1547 : }
1548 0 : if (reasons & RF_CESSATION_OF_OPERATION) {
1549 0 : if (comma) text.Append(NS_LITERAL_STRING(", "));
1550 0 : nssComponent->GetPIPNSSBundleString("CertDumpCessation", local);
1551 0 : text.Append(local); comma = 1;
1552 : }
1553 0 : if (reasons & RF_CERTIFICATE_HOLD) {
1554 0 : if (comma) text.Append(NS_LITERAL_STRING(", "));
1555 0 : nssComponent->GetPIPNSSBundleString("CertDumpHold", local);
1556 0 : text.Append(local); comma = 1;
1557 : }
1558 0 : text.Append(NS_LITERAL_STRING(SEPARATOR));
1559 : }
1560 0 : if (point->crlIssuer) {
1561 0 : nssComponent->GetPIPNSSBundleString("CertDumpIssuer", local);
1562 0 : text.Append(local);
1563 0 : text.Append(NS_LITERAL_STRING(": "));
1564 : rv = ProcessGeneralNames(arena, point->crlIssuer,
1565 0 : text, nssComponent);
1566 0 : if (NS_FAILED(rv))
1567 0 : goto finish;
1568 : }
1569 : }
1570 :
1571 : finish:
1572 0 : PORT_FreeArena(arena, false);
1573 0 : return NS_OK;
1574 : }
1575 :
1576 : static nsresult
1577 0 : ProcessAuthInfoAccess(SECItem *extData,
1578 : nsAString &text,
1579 : nsINSSComponent *nssComponent)
1580 : {
1581 : CERTAuthInfoAccess **aia, *desc;
1582 : PRArenaPool *arena;
1583 0 : nsresult rv = NS_OK;
1584 0 : nsAutoString local;
1585 :
1586 0 : arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1587 0 : if (!arena)
1588 0 : return NS_ERROR_FAILURE;
1589 :
1590 0 : aia = CERT_DecodeAuthInfoAccessExtension(arena, extData);
1591 0 : if (aia == NULL)
1592 0 : goto finish;
1593 :
1594 0 : while (*aia != NULL) {
1595 0 : desc = *aia++;
1596 0 : switch (SECOID_FindOIDTag(&desc->method)) {
1597 : case SEC_OID_PKIX_OCSP:
1598 0 : nssComponent->GetPIPNSSBundleString("CertDumpOCSPResponder", local);
1599 0 : break;
1600 : case SEC_OID_PKIX_CA_ISSUERS:
1601 0 : nssComponent->GetPIPNSSBundleString("CertDumpCAIssuers", local);
1602 0 : break;
1603 : default:
1604 0 : rv = GetDefaultOIDFormat(&desc->method, nssComponent, local, '.');
1605 0 : if (NS_FAILED(rv))
1606 0 : goto finish;
1607 : }
1608 0 : text.Append(local);
1609 0 : text.Append(NS_LITERAL_STRING(": "));
1610 0 : rv = ProcessGeneralName(arena, desc->location, text, nssComponent);
1611 0 : if (NS_FAILED(rv))
1612 0 : goto finish;
1613 : }
1614 :
1615 : finish:
1616 0 : PORT_FreeArena(arena, false);
1617 0 : return rv;
1618 : }
1619 :
1620 : static nsresult
1621 0 : ProcessMSCAVersion(SECItem *extData,
1622 : nsAString &text,
1623 : nsINSSComponent *nssComponent)
1624 : {
1625 : unsigned long version;
1626 : nsresult rv;
1627 : char buf[50];
1628 : SECItem decoded;
1629 :
1630 0 : if (SECSuccess != SEC_ASN1DecodeItem(nsnull, &decoded,
1631 : SEC_ASN1_GET(SEC_IntegerTemplate),
1632 0 : extData))
1633 : /* This extension used to be an Integer when this code
1634 : was written, but apparently isn't anymore. Display
1635 : the raw bytes instead. */
1636 0 : return ProcessRawBytes(nssComponent, extData, text);
1637 :
1638 0 : rv = GetIntValue(&decoded, &version);
1639 0 : nsMemory::Free(decoded.data);
1640 0 : if (NS_FAILED(rv))
1641 : /* Value out of range, display raw bytes */
1642 0 : return ProcessRawBytes(nssComponent, extData, text);
1643 :
1644 : /* Apparently, the encoding is <minor><major>, with 16 bits each */
1645 0 : PR_snprintf(buf, sizeof(buf), "%d.%d", version & 0xFFFF, version>>16);
1646 0 : text.AppendASCII(buf);
1647 0 : return NS_OK;
1648 : }
1649 :
1650 : static nsresult
1651 0 : ProcessExtensionData(SECOidTag oidTag, SECItem *extData,
1652 : nsAString &text,
1653 : SECOidTag ev_oid_tag, // SEC_OID_UNKNOWN means: not EV
1654 : nsINSSComponent *nssComponent)
1655 : {
1656 : nsresult rv;
1657 0 : switch (oidTag) {
1658 : case SEC_OID_NS_CERT_EXT_CERT_TYPE:
1659 0 : rv = ProcessNSCertTypeExtensions(extData, text, nssComponent);
1660 0 : break;
1661 : case SEC_OID_X509_KEY_USAGE:
1662 0 : rv = ProcessKeyUsageExtension(extData, text, nssComponent);
1663 0 : break;
1664 : case SEC_OID_X509_BASIC_CONSTRAINTS:
1665 0 : rv = ProcessBasicConstraints(extData, text, nssComponent);
1666 0 : break;
1667 : case SEC_OID_X509_EXT_KEY_USAGE:
1668 0 : rv = ProcessExtKeyUsage(extData, text, nssComponent);
1669 0 : break;
1670 : case SEC_OID_X509_ISSUER_ALT_NAME:
1671 : case SEC_OID_X509_SUBJECT_ALT_NAME:
1672 0 : rv = ProcessAltName(extData, text, nssComponent);
1673 0 : break;
1674 : case SEC_OID_X509_SUBJECT_KEY_ID:
1675 0 : rv = ProcessSubjectKeyId(extData, text, nssComponent);
1676 0 : break;
1677 : case SEC_OID_X509_AUTH_KEY_ID:
1678 0 : rv = ProcessAuthKeyId(extData, text, nssComponent);
1679 0 : break;
1680 : case SEC_OID_X509_CERTIFICATE_POLICIES:
1681 0 : rv = ProcessCertificatePolicies(extData, text, ev_oid_tag, nssComponent);
1682 0 : break;
1683 : case SEC_OID_X509_CRL_DIST_POINTS:
1684 0 : rv = ProcessCrlDistPoints(extData, text, nssComponent);
1685 0 : break;
1686 : case SEC_OID_X509_AUTH_INFO_ACCESS:
1687 0 : rv = ProcessAuthInfoAccess(extData, text, nssComponent);
1688 0 : break;
1689 : case SEC_OID_NS_CERT_EXT_BASE_URL:
1690 : case SEC_OID_NS_CERT_EXT_REVOCATION_URL:
1691 : case SEC_OID_NS_CERT_EXT_CA_REVOCATION_URL:
1692 : case SEC_OID_NS_CERT_EXT_CA_CERT_URL:
1693 : case SEC_OID_NS_CERT_EXT_CERT_RENEWAL_URL:
1694 : case SEC_OID_NS_CERT_EXT_CA_POLICY_URL:
1695 : case SEC_OID_NS_CERT_EXT_HOMEPAGE_URL:
1696 : case SEC_OID_NS_CERT_EXT_COMMENT:
1697 : case SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME:
1698 : case SEC_OID_NS_CERT_EXT_LOST_PASSWORD_URL:
1699 0 : rv = ProcessIA5String(extData, text, nssComponent);
1700 0 : break;
1701 : default:
1702 0 : if (oidTag == SEC_OID(MS_CERT_EXT_CERTTYPE)) {
1703 0 : rv = ProcessBMPString(extData, text, nssComponent);
1704 0 : break;
1705 : }
1706 0 : if (oidTag == SEC_OID(MS_CERTSERV_CA_VERSION)) {
1707 0 : rv = ProcessMSCAVersion(extData, text, nssComponent);
1708 0 : break;
1709 : }
1710 0 : rv = ProcessRawBytes(nssComponent, extData, text);
1711 0 : break;
1712 : }
1713 0 : return rv;
1714 : }
1715 :
1716 : static nsresult
1717 0 : ProcessSingleExtension(CERTCertExtension *extension,
1718 : SECOidTag ev_oid_tag, // SEC_OID_UNKNOWN means: not EV
1719 : nsINSSComponent *nssComponent,
1720 : nsIASN1PrintableItem **retExtension)
1721 : {
1722 0 : nsAutoString text, extvalue;
1723 0 : GetOIDText(&extension->id, nssComponent, text);
1724 0 : nsCOMPtr<nsIASN1PrintableItem>extensionItem = new nsNSSASN1PrintableItem();
1725 0 : if (extensionItem == nsnull)
1726 0 : return NS_ERROR_OUT_OF_MEMORY;
1727 :
1728 0 : extensionItem->SetDisplayName(text);
1729 0 : SECOidTag oidTag = SECOID_FindOIDTag(&extension->id);
1730 0 : text.Truncate();
1731 0 : if (extension->critical.data != nsnull) {
1732 0 : if (extension->critical.data[0]) {
1733 0 : nssComponent->GetPIPNSSBundleString("CertDumpCritical", text);
1734 : } else {
1735 0 : nssComponent->GetPIPNSSBundleString("CertDumpNonCritical", text);
1736 : }
1737 : } else {
1738 0 : nssComponent->GetPIPNSSBundleString("CertDumpNonCritical", text);
1739 : }
1740 0 : text.Append(NS_LITERAL_STRING(SEPARATOR).get());
1741 : nsresult rv = ProcessExtensionData(oidTag, &extension->value, extvalue,
1742 0 : ev_oid_tag, nssComponent);
1743 0 : if (NS_FAILED(rv)) {
1744 0 : extvalue.Truncate();
1745 0 : rv = ProcessRawBytes(nssComponent, &extension->value, extvalue, false);
1746 : }
1747 0 : text.Append(extvalue);
1748 :
1749 0 : extensionItem->SetDisplayValue(text);
1750 0 : *retExtension = extensionItem;
1751 0 : NS_ADDREF(*retExtension);
1752 0 : return NS_OK;
1753 : }
1754 :
1755 : static nsresult
1756 0 : ProcessSECAlgorithmID(SECAlgorithmID *algID,
1757 : nsINSSComponent *nssComponent,
1758 : nsIASN1Sequence **retSequence)
1759 : {
1760 0 : SECOidTag algOIDTag = SECOID_FindOIDTag(&algID->algorithm);
1761 0 : SECItem paramsOID = { siBuffer, NULL, 0 };
1762 0 : nsCOMPtr<nsIASN1Sequence> sequence = new nsNSSASN1Sequence();
1763 0 : if (sequence == nsnull)
1764 0 : return NS_ERROR_OUT_OF_MEMORY;
1765 :
1766 0 : *retSequence = nsnull;
1767 0 : nsString text;
1768 0 : GetOIDText(&algID->algorithm, nssComponent, text);
1769 0 : if (!algID->parameters.len || algID->parameters.data[0] == nsIASN1Object::ASN1_NULL) {
1770 0 : sequence->SetDisplayValue(text);
1771 0 : sequence->SetIsValidContainer(false);
1772 : } else {
1773 0 : nsCOMPtr<nsIASN1PrintableItem> printableItem = new nsNSSASN1PrintableItem();
1774 0 : if (printableItem == nsnull)
1775 0 : return NS_ERROR_OUT_OF_MEMORY;
1776 :
1777 0 : printableItem->SetDisplayValue(text);
1778 0 : nsCOMPtr<nsIMutableArray> asn1Objects;
1779 0 : sequence->GetASN1Objects(getter_AddRefs(asn1Objects));
1780 0 : asn1Objects->AppendElement(printableItem, false);
1781 0 : nssComponent->GetPIPNSSBundleString("CertDumpAlgID", text);
1782 0 : printableItem->SetDisplayName(text);
1783 :
1784 0 : printableItem = new nsNSSASN1PrintableItem();
1785 0 : if (printableItem == nsnull)
1786 0 : return NS_ERROR_OUT_OF_MEMORY;
1787 :
1788 0 : asn1Objects->AppendElement(printableItem, false);
1789 0 : nssComponent->GetPIPNSSBundleString("CertDumpParams", text);
1790 0 : printableItem->SetDisplayName(text);
1791 0 : if ((algOIDTag == SEC_OID_ANSIX962_EC_PUBLIC_KEY) &&
1792 : (algID->parameters.len > 2) &&
1793 0 : (algID->parameters.data[0] == nsIASN1Object::ASN1_OBJECT_ID)) {
1794 0 : paramsOID.len = algID->parameters.len - 2;
1795 0 : paramsOID.data = algID->parameters.data + 2;
1796 0 : GetOIDText(¶msOID, nssComponent, text);
1797 : } else {
1798 0 : ProcessRawBytes(nssComponent, &algID->parameters,text);
1799 : }
1800 0 : printableItem->SetDisplayValue(text);
1801 : }
1802 0 : *retSequence = sequence;
1803 0 : NS_ADDREF(*retSequence);
1804 0 : return NS_OK;
1805 : }
1806 :
1807 : static nsresult
1808 0 : ProcessTime(PRTime dispTime, const PRUnichar *displayName,
1809 : nsIASN1Sequence *parentSequence)
1810 : {
1811 : nsresult rv;
1812 : nsCOMPtr<nsIDateTimeFormat> dateFormatter =
1813 0 : do_CreateInstance(NS_DATETIMEFORMAT_CONTRACTID, &rv);
1814 0 : if (NS_FAILED(rv))
1815 0 : return rv;
1816 :
1817 0 : nsString text;
1818 0 : nsString tempString;
1819 :
1820 : PRExplodedTime explodedTime;
1821 0 : PR_ExplodeTime(dispTime, PR_LocalTimeParameters, &explodedTime);
1822 :
1823 0 : dateFormatter->FormatPRExplodedTime(nsnull, kDateFormatShort, kTimeFormatSecondsForce24Hour,
1824 0 : &explodedTime, tempString);
1825 :
1826 0 : text.Append(tempString);
1827 0 : text.AppendLiteral("\n(");
1828 :
1829 : PRExplodedTime explodedTimeGMT;
1830 0 : PR_ExplodeTime(dispTime, PR_GMTParameters, &explodedTimeGMT);
1831 :
1832 0 : dateFormatter->FormatPRExplodedTime(nsnull, kDateFormatShort, kTimeFormatSecondsForce24Hour,
1833 0 : &explodedTimeGMT, tempString);
1834 :
1835 0 : text.Append(tempString);
1836 0 : text.Append(NS_LITERAL_STRING(" GMT)"));
1837 :
1838 0 : nsCOMPtr<nsIASN1PrintableItem> printableItem = new nsNSSASN1PrintableItem();
1839 0 : if (printableItem == nsnull)
1840 0 : return NS_ERROR_OUT_OF_MEMORY;
1841 :
1842 0 : printableItem->SetDisplayValue(text);
1843 0 : printableItem->SetDisplayName(nsDependentString(displayName));
1844 0 : nsCOMPtr<nsIMutableArray> asn1Objects;
1845 0 : parentSequence->GetASN1Objects(getter_AddRefs(asn1Objects));
1846 0 : asn1Objects->AppendElement(printableItem, false);
1847 0 : return NS_OK;
1848 : }
1849 :
1850 : static nsresult
1851 0 : ProcessSubjectPublicKeyInfo(CERTSubjectPublicKeyInfo *spki,
1852 : nsIASN1Sequence *parentSequence,
1853 : nsINSSComponent *nssComponent)
1854 : {
1855 0 : nsCOMPtr<nsIASN1Sequence> spkiSequence = new nsNSSASN1Sequence();
1856 :
1857 0 : if (spkiSequence == nsnull)
1858 0 : return NS_ERROR_OUT_OF_MEMORY;
1859 :
1860 0 : nsString text;
1861 0 : nssComponent->GetPIPNSSBundleString("CertDumpSPKI", text);
1862 0 : spkiSequence->SetDisplayName(text);
1863 :
1864 0 : nssComponent->GetPIPNSSBundleString("CertDumpSPKIAlg", text);
1865 0 : nsCOMPtr<nsIASN1Sequence> sequenceItem;
1866 : nsresult rv = ProcessSECAlgorithmID(&spki->algorithm, nssComponent,
1867 0 : getter_AddRefs(sequenceItem));
1868 0 : if (NS_FAILED(rv))
1869 0 : return rv;
1870 0 : sequenceItem->SetDisplayName(text);
1871 0 : nsCOMPtr<nsIMutableArray> asn1Objects;
1872 0 : spkiSequence->GetASN1Objects(getter_AddRefs(asn1Objects));
1873 0 : asn1Objects->AppendElement(sequenceItem, false);
1874 :
1875 0 : nsCOMPtr<nsIASN1PrintableItem> printableItem = new nsNSSASN1PrintableItem();
1876 0 : if (printableItem == nsnull)
1877 0 : return NS_ERROR_OUT_OF_MEMORY;
1878 :
1879 0 : text.Truncate();
1880 :
1881 0 : SECKEYPublicKey *key = SECKEY_ExtractPublicKey(spki);
1882 0 : bool displayed = false;
1883 0 : if (key != NULL) {
1884 0 : switch (key->keyType) {
1885 : case rsaKey: {
1886 0 : displayed = true;
1887 0 : nsAutoString length1, length2, data1, data2;
1888 0 : length1.AppendInt(key->u.rsa.modulus.len * 8);
1889 0 : length2.AppendInt(key->u.rsa.publicExponent.len * 8);
1890 : ProcessRawBytes(nssComponent, &key->u.rsa.modulus, data1,
1891 0 : false);
1892 : ProcessRawBytes(nssComponent, &key->u.rsa.publicExponent, data2,
1893 0 : false);
1894 0 : const PRUnichar *params[4] = {length1.get(), data1.get(),
1895 0 : length2.get(), data2.get()};
1896 : nssComponent->PIPBundleFormatStringFromName("CertDumpRSATemplate",
1897 0 : params, 4, text);
1898 : break;
1899 : }
1900 : case ecKey: {
1901 0 : displayed = true;
1902 0 : SECKEYECPublicKey &ecpk = key->u.ec;
1903 : int fieldSizeLenAsBits =
1904 0 : SECKEY_ECParamsToKeySize(&ecpk.DEREncodedParams);
1905 : int basePointOrderLenAsBits =
1906 0 : SECKEY_ECParamsToBasePointOrderLen(&ecpk.DEREncodedParams);
1907 0 : nsAutoString s_fsl, s_bpol, s_pv;
1908 0 : s_fsl.AppendInt(fieldSizeLenAsBits);
1909 0 : s_bpol.AppendInt(basePointOrderLenAsBits);
1910 :
1911 0 : if (ecpk.publicValue.len > 4) {
1912 0 : ProcessRawBytes(nssComponent, &ecpk.publicValue, s_pv, false);
1913 : } else {
1914 0 : int i_pv = DER_GetInteger(&ecpk.publicValue);
1915 0 : s_pv.AppendInt(i_pv);
1916 : }
1917 0 : const PRUnichar *params[] = {s_fsl.get(), s_bpol.get(), s_pv.get()};
1918 : nssComponent->PIPBundleFormatStringFromName("CertDumpECTemplate",
1919 0 : params, 3, text);
1920 : break;
1921 : }
1922 : default:
1923 : /* Algorithm unknown, or too rarely used to bother displaying it */
1924 0 : break;
1925 : }
1926 0 : SECKEY_DestroyPublicKey (key);
1927 : }
1928 0 : if (!displayed) {
1929 : // Algorithm unknown, display raw bytes
1930 : // The subjectPublicKey field is encoded as a bit string.
1931 : // ProcessRawBytes expects the length to be in bytes, so
1932 : // let's convert the lenght into a temporary SECItem.
1933 : SECItem data;
1934 0 : data.data = spki->subjectPublicKey.data;
1935 0 : data.len = spki->subjectPublicKey.len / 8;
1936 0 : ProcessRawBytes(nssComponent, &data, text);
1937 :
1938 : }
1939 :
1940 0 : printableItem->SetDisplayValue(text);
1941 0 : nssComponent->GetPIPNSSBundleString("CertDumpSubjPubKey", text);
1942 0 : printableItem->SetDisplayName(text);
1943 0 : asn1Objects->AppendElement(printableItem, false);
1944 :
1945 0 : parentSequence->GetASN1Objects(getter_AddRefs(asn1Objects));
1946 0 : asn1Objects->AppendElement(spkiSequence, false);
1947 0 : return NS_OK;
1948 : }
1949 :
1950 : static nsresult
1951 0 : ProcessExtensions(CERTCertExtension **extensions,
1952 : nsIASN1Sequence *parentSequence,
1953 : SECOidTag ev_oid_tag, // SEC_OID_UNKNOWN means: not EV
1954 : nsINSSComponent *nssComponent)
1955 : {
1956 0 : nsCOMPtr<nsIASN1Sequence> extensionSequence = new nsNSSASN1Sequence;
1957 0 : if (extensionSequence == nsnull)
1958 0 : return NS_ERROR_OUT_OF_MEMORY;
1959 :
1960 0 : nsString text;
1961 0 : nssComponent->GetPIPNSSBundleString("CertDumpExtensions", text);
1962 0 : extensionSequence->SetDisplayName(text);
1963 : PRInt32 i;
1964 : nsresult rv;
1965 0 : nsCOMPtr<nsIASN1PrintableItem> newExtension;
1966 0 : nsCOMPtr<nsIMutableArray> asn1Objects;
1967 0 : extensionSequence->GetASN1Objects(getter_AddRefs(asn1Objects));
1968 0 : for (i=0; extensions[i] != nsnull; i++) {
1969 0 : rv = ProcessSingleExtension(extensions[i],
1970 : ev_oid_tag,
1971 : nssComponent,
1972 0 : getter_AddRefs(newExtension));
1973 0 : if (NS_FAILED(rv))
1974 0 : return rv;
1975 :
1976 0 : asn1Objects->AppendElement(newExtension, false);
1977 : }
1978 0 : parentSequence->GetASN1Objects(getter_AddRefs(asn1Objects));
1979 0 : asn1Objects->AppendElement(extensionSequence, false);
1980 0 : return NS_OK;
1981 : }
1982 :
1983 : static bool registered;
1984 0 : static SECStatus RegisterDynamicOids()
1985 : {
1986 : unsigned int i;
1987 0 : SECStatus rv = SECSuccess;
1988 :
1989 0 : if (registered)
1990 0 : return rv;
1991 :
1992 0 : for (i = 0; i < numOids; i++) {
1993 0 : SECOidTag tag = SECOID_AddEntry(&more_oids[i]);
1994 0 : if (tag == SEC_OID_UNKNOWN) {
1995 0 : rv = SECFailure;
1996 0 : continue;
1997 : }
1998 0 : more_oids[i].offset = tag;
1999 : }
2000 0 : registered = true;
2001 0 : return rv;
2002 : }
2003 :
2004 : nsresult
2005 0 : nsNSSCertificate::CreateTBSCertificateASN1Struct(nsIASN1Sequence **retSequence,
2006 : nsINSSComponent *nssComponent)
2007 : {
2008 0 : nsNSSShutDownPreventionLock locker;
2009 0 : if (isAlreadyShutDown())
2010 0 : return NS_ERROR_NOT_AVAILABLE;
2011 :
2012 0 : if (RegisterDynamicOids() != SECSuccess)
2013 0 : return NS_ERROR_FAILURE;
2014 :
2015 : //
2016 : // TBSCertificate ::= SEQUENCE {
2017 : // version [0] EXPLICIT Version DEFAULT v1,
2018 : // serialNumber CertificateSerialNumber,
2019 : // signature AlgorithmIdentifier,
2020 : // issuer Name,
2021 : // validity Validity,
2022 : // subject Name,
2023 : // subjectPublicKeyInfo SubjectPublicKeyInfo,
2024 : // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
2025 : // -- If present, version shall be v2 or v3
2026 : // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
2027 : // -- If present, version shall be v2 or v3
2028 : // extensions [3] EXPLICIT Extensions OPTIONAL
2029 : // -- If present, version shall be v3
2030 : // }
2031 : //
2032 : // This is the ASN1 structure we should be dealing with at this point.
2033 : // The code in this method will assert this is the structure we're dealing
2034 : // and then add more user friendly text for that field.
2035 0 : nsCOMPtr<nsIASN1Sequence> sequence = new nsNSSASN1Sequence();
2036 0 : if (sequence == nsnull)
2037 0 : return NS_ERROR_OUT_OF_MEMORY;
2038 :
2039 0 : nsString text;
2040 0 : nssComponent->GetPIPNSSBundleString("CertDumpCertificate", text);
2041 0 : sequence->SetDisplayName(text);
2042 0 : nsCOMPtr<nsIASN1PrintableItem> printableItem;
2043 :
2044 0 : nsCOMPtr<nsIMutableArray> asn1Objects;
2045 0 : sequence->GetASN1Objects(getter_AddRefs(asn1Objects));
2046 :
2047 : nsresult rv = ProcessVersion(&mCert->version, nssComponent,
2048 0 : getter_AddRefs(printableItem));
2049 0 : if (NS_FAILED(rv))
2050 0 : return rv;
2051 :
2052 0 : asn1Objects->AppendElement(printableItem, false);
2053 :
2054 : rv = ProcessSerialNumberDER(&mCert->serialNumber, nssComponent,
2055 0 : getter_AddRefs(printableItem));
2056 :
2057 0 : if (NS_FAILED(rv))
2058 0 : return rv;
2059 0 : asn1Objects->AppendElement(printableItem, false);
2060 :
2061 0 : nsCOMPtr<nsIASN1Sequence> algID;
2062 : rv = ProcessSECAlgorithmID(&mCert->signature,
2063 0 : nssComponent, getter_AddRefs(algID));
2064 0 : if (NS_FAILED(rv))
2065 0 : return rv;
2066 :
2067 0 : nssComponent->GetPIPNSSBundleString("CertDumpSigAlg", text);
2068 0 : algID->SetDisplayName(text);
2069 0 : asn1Objects->AppendElement(algID, false);
2070 :
2071 0 : nsXPIDLString value;
2072 0 : ProcessName(&mCert->issuer, nssComponent, getter_Copies(value));
2073 :
2074 0 : printableItem = new nsNSSASN1PrintableItem();
2075 0 : if (printableItem == nsnull)
2076 0 : return NS_ERROR_OUT_OF_MEMORY;
2077 :
2078 0 : printableItem->SetDisplayValue(value);
2079 0 : nssComponent->GetPIPNSSBundleString("CertDumpIssuer", text);
2080 0 : printableItem->SetDisplayName(text);
2081 0 : asn1Objects->AppendElement(printableItem, false);
2082 :
2083 0 : nsCOMPtr<nsIASN1Sequence> validitySequence = new nsNSSASN1Sequence();
2084 0 : nssComponent->GetPIPNSSBundleString("CertDumpValidity", text);
2085 0 : validitySequence->SetDisplayName(text);
2086 0 : asn1Objects->AppendElement(validitySequence, false);
2087 0 : nssComponent->GetPIPNSSBundleString("CertDumpNotBefore", text);
2088 0 : nsCOMPtr<nsIX509CertValidity> validityData;
2089 0 : GetValidity(getter_AddRefs(validityData));
2090 : PRTime notBefore, notAfter;
2091 :
2092 0 : validityData->GetNotBefore(¬Before);
2093 0 : validityData->GetNotAfter(¬After);
2094 0 : validityData = 0;
2095 0 : rv = ProcessTime(notBefore, text.get(), validitySequence);
2096 0 : if (NS_FAILED(rv))
2097 0 : return rv;
2098 :
2099 0 : nssComponent->GetPIPNSSBundleString("CertDumpNotAfter", text);
2100 0 : rv = ProcessTime(notAfter, text.get(), validitySequence);
2101 0 : if (NS_FAILED(rv))
2102 0 : return rv;
2103 :
2104 0 : nssComponent->GetPIPNSSBundleString("CertDumpSubject", text);
2105 :
2106 0 : printableItem = new nsNSSASN1PrintableItem();
2107 0 : if (printableItem == nsnull)
2108 0 : return NS_ERROR_OUT_OF_MEMORY;
2109 :
2110 0 : printableItem->SetDisplayName(text);
2111 0 : ProcessName(&mCert->subject, nssComponent,getter_Copies(value));
2112 0 : printableItem->SetDisplayValue(value);
2113 0 : asn1Objects->AppendElement(printableItem, false);
2114 :
2115 : rv = ProcessSubjectPublicKeyInfo(&mCert->subjectPublicKeyInfo, sequence,
2116 0 : nssComponent);
2117 0 : if (NS_FAILED(rv))
2118 0 : return rv;
2119 :
2120 : SECItem data;
2121 : // Is there an issuerUniqueID?
2122 0 : if (mCert->issuerID.data != nsnull) {
2123 : // The issuerID is encoded as a bit string.
2124 : // The function ProcessRawBytes expects the
2125 : // length to be in bytes, so let's convert the
2126 : // length in a temporary SECItem
2127 0 : data.data = mCert->issuerID.data;
2128 0 : data.len = (mCert->issuerID.len + 7) / 8;
2129 :
2130 0 : ProcessRawBytes(nssComponent, &data, text);
2131 0 : printableItem = new nsNSSASN1PrintableItem();
2132 0 : if (printableItem == nsnull)
2133 0 : return NS_ERROR_OUT_OF_MEMORY;
2134 :
2135 0 : printableItem->SetDisplayValue(text);
2136 0 : nssComponent->GetPIPNSSBundleString("CertDumpIssuerUniqueID", text);
2137 0 : printableItem->SetDisplayName(text);
2138 0 : asn1Objects->AppendElement(printableItem, false);
2139 : }
2140 :
2141 0 : if (mCert->subjectID.data) {
2142 : // The subjectID is encoded as a bit string.
2143 : // The function ProcessRawBytes expects the
2144 : // length to be in bytes, so let's convert the
2145 : // length in a temporary SECItem
2146 0 : data.data = mCert->subjectID.data;
2147 0 : data.len = (mCert->subjectID.len + 7) / 8;
2148 :
2149 0 : ProcessRawBytes(nssComponent, &data, text);
2150 0 : printableItem = new nsNSSASN1PrintableItem();
2151 0 : if (printableItem == nsnull)
2152 0 : return NS_ERROR_OUT_OF_MEMORY;
2153 :
2154 0 : printableItem->SetDisplayValue(text);
2155 0 : nssComponent->GetPIPNSSBundleString("CertDumpSubjectUniqueID", text);
2156 0 : printableItem->SetDisplayName(text);
2157 0 : asn1Objects->AppendElement(printableItem, false);
2158 :
2159 : }
2160 0 : if (mCert->extensions) {
2161 : SECOidTag ev_oid_tag;
2162 : bool validEV;
2163 0 : rv = hasValidEVOidTag(ev_oid_tag, validEV);
2164 0 : if (NS_FAILED(rv))
2165 0 : return rv;
2166 :
2167 0 : if (!validEV)
2168 0 : ev_oid_tag = SEC_OID_UNKNOWN;
2169 :
2170 0 : rv = ProcessExtensions(mCert->extensions, sequence, ev_oid_tag, nssComponent);
2171 0 : if (NS_FAILED(rv))
2172 0 : return rv;
2173 : }
2174 0 : *retSequence = sequence;
2175 0 : NS_ADDREF(*retSequence);
2176 0 : return NS_OK;
2177 : }
2178 :
2179 : nsresult
2180 0 : nsNSSCertificate::CreateASN1Struct()
2181 : {
2182 0 : nsNSSShutDownPreventionLock locker;
2183 0 : if (isAlreadyShutDown())
2184 0 : return NS_ERROR_NOT_AVAILABLE;
2185 :
2186 0 : nsCOMPtr<nsIASN1Sequence> sequence = new nsNSSASN1Sequence();
2187 :
2188 0 : mASN1Structure = sequence;
2189 0 : if (mASN1Structure == nsnull) {
2190 0 : return NS_ERROR_OUT_OF_MEMORY;
2191 : }
2192 :
2193 0 : nsCOMPtr<nsIMutableArray> asn1Objects;
2194 0 : sequence->GetASN1Objects(getter_AddRefs(asn1Objects));
2195 0 : nsXPIDLCString title;
2196 0 : GetWindowTitle(getter_Copies(title));
2197 :
2198 0 : mASN1Structure->SetDisplayName(NS_ConvertUTF8toUTF16(title));
2199 : // This sequence will be contain the tbsCertificate, signatureAlgorithm,
2200 : // and signatureValue.
2201 : nsresult rv;
2202 0 : nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
2203 0 : if (NS_FAILED(rv))
2204 0 : return rv;
2205 :
2206 0 : rv = CreateTBSCertificateASN1Struct(getter_AddRefs(sequence),
2207 0 : nssComponent);
2208 0 : if (NS_FAILED(rv))
2209 0 : return rv;
2210 :
2211 0 : asn1Objects->AppendElement(sequence, false);
2212 0 : nsCOMPtr<nsIASN1Sequence> algID;
2213 :
2214 : rv = ProcessSECAlgorithmID(&mCert->signatureWrap.signatureAlgorithm,
2215 0 : nssComponent, getter_AddRefs(algID));
2216 0 : if (NS_FAILED(rv))
2217 0 : return rv;
2218 0 : nsString text;
2219 0 : nssComponent->GetPIPNSSBundleString("CertDumpSigAlg", text);
2220 0 : algID->SetDisplayName(text);
2221 0 : asn1Objects->AppendElement(algID, false);
2222 0 : nsCOMPtr<nsIASN1PrintableItem>printableItem = new nsNSSASN1PrintableItem();
2223 0 : nssComponent->GetPIPNSSBundleString("CertDumpCertSig", text);
2224 0 : printableItem->SetDisplayName(text);
2225 : // The signatureWrap is encoded as a bit string.
2226 : // The function ProcessRawBytes expects the
2227 : // length to be in bytes, so let's convert the
2228 : // length in a temporary SECItem
2229 : SECItem temp;
2230 0 : temp.data = mCert->signatureWrap.signature.data;
2231 0 : temp.len = mCert->signatureWrap.signature.len / 8;
2232 0 : text.Truncate();
2233 0 : ProcessRawBytes(nssComponent, &temp,text);
2234 0 : printableItem->SetDisplayValue(text);
2235 0 : asn1Objects->AppendElement(printableItem, false);
2236 0 : return NS_OK;
2237 : }
2238 :
2239 : PRUint32
2240 0 : getCertType(CERTCertificate *cert)
2241 : {
2242 0 : nsNSSCertTrust trust(cert->trust);
2243 0 : if (cert->nickname && trust.HasAnyUser())
2244 0 : return nsIX509Cert::USER_CERT;
2245 0 : if (trust.HasAnyCA())
2246 0 : return nsIX509Cert::CA_CERT;
2247 0 : if (trust.HasPeer(true, false, false))
2248 0 : return nsIX509Cert::SERVER_CERT;
2249 0 : if (trust.HasPeer(false, true, false) && cert->emailAddr)
2250 0 : return nsIX509Cert::EMAIL_CERT;
2251 0 : if (CERT_IsCACert(cert,NULL))
2252 0 : return nsIX509Cert::CA_CERT;
2253 0 : if (cert->emailAddr)
2254 0 : return nsIX509Cert::EMAIL_CERT;
2255 0 : return nsIX509Cert::UNKNOWN_CERT;
2256 : }
2257 :
2258 : CERTCertNicknames *
2259 0 : getNSSCertNicknamesFromCertList(CERTCertList *certList)
2260 : {
2261 : nsresult rv;
2262 :
2263 0 : nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
2264 0 : if (NS_FAILED(rv))
2265 0 : return nsnull;
2266 :
2267 0 : nsAutoString expiredString, notYetValidString;
2268 0 : nsAutoString expiredStringLeadingSpace, notYetValidStringLeadingSpace;
2269 :
2270 0 : nssComponent->GetPIPNSSBundleString("NicknameExpired", expiredString);
2271 0 : nssComponent->GetPIPNSSBundleString("NicknameNotYetValid", notYetValidString);
2272 :
2273 0 : expiredStringLeadingSpace.Append(NS_LITERAL_STRING(" "));
2274 0 : expiredStringLeadingSpace.Append(expiredString);
2275 :
2276 0 : notYetValidStringLeadingSpace.Append(NS_LITERAL_STRING(" "));
2277 0 : notYetValidStringLeadingSpace.Append(notYetValidString);
2278 :
2279 0 : NS_ConvertUTF16toUTF8 aUtf8ExpiredString(expiredStringLeadingSpace);
2280 0 : NS_ConvertUTF16toUTF8 aUtf8NotYetValidString(notYetValidStringLeadingSpace);
2281 :
2282 : return CERT_NicknameStringsFromCertList(certList,
2283 0 : const_cast<char*>(aUtf8ExpiredString.get()),
2284 0 : const_cast<char*>(aUtf8NotYetValidString.get()));
2285 :
2286 : }
|