LCOV - code coverage report
Current view: top level - security/manager/ssl - nsNSSCertHelper.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 1177 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 44 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13