2012-05-31 09:33:35 +00:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2002-09-17 18:51:22 +00:00
|
|
|
|
2016-02-17 00:25:09 +00:00
|
|
|
#include "nsNSSCertHelper.h"
|
2014-07-11 03:37:40 +00:00
|
|
|
|
2016-02-17 00:25:09 +00:00
|
|
|
#include <algorithm>
|
2002-09-17 18:51:22 +00:00
|
|
|
|
2016-11-21 23:58:37 +00:00
|
|
|
#include "DateTimeFormat.h"
|
2016-09-21 11:34:12 +00:00
|
|
|
#include "ScopedNSSTypes.h"
|
2017-01-02 06:11:39 +00:00
|
|
|
#include "mozilla/Assertions.h"
|
2016-05-19 04:20:56 +00:00
|
|
|
#include "mozilla/Casting.h"
|
2016-06-22 22:56:11 +00:00
|
|
|
#include "mozilla/NotNull.h"
|
2016-08-15 06:43:21 +00:00
|
|
|
#include "mozilla/Sprintf.h"
|
2016-02-17 00:25:09 +00:00
|
|
|
#include "mozilla/UniquePtr.h"
|
2016-04-19 23:09:49 +00:00
|
|
|
#include "nsCOMPtr.h"
|
2017-01-31 22:08:56 +00:00
|
|
|
#include "nsIStringBundle.h"
|
2016-02-17 00:25:09 +00:00
|
|
|
#include "nsNSSASN1Object.h"
|
|
|
|
#include "nsNSSCertTrust.h"
|
2004-04-18 21:20:31 +00:00
|
|
|
#include "nsNSSCertValidity.h"
|
2016-04-18 18:07:24 +00:00
|
|
|
#include "nsNSSCertificate.h"
|
2013-06-22 22:57:15 +00:00
|
|
|
#include "nsServiceManagerUtils.h"
|
2016-02-17 00:25:09 +00:00
|
|
|
#include "prerror.h"
|
|
|
|
#include "secder.h"
|
2012-10-17 20:48:36 +00:00
|
|
|
|
|
|
|
using namespace mozilla;
|
2017-01-31 21:23:55 +00:00
|
|
|
|
2005-12-25 21:09:45 +00:00
|
|
|
/* Object Identifier constants */
|
|
|
|
#define CONST_OID static const unsigned char
|
|
|
|
#define MICROSOFT_OID 0x2b, 0x6, 0x1, 0x4, 0x1, 0x82, 0x37
|
2006-01-30 23:21:00 +00:00
|
|
|
#define PKIX_OID 0x2b, 0x6, 0x01, 0x05, 0x05, 0x07
|
2017-01-31 21:23:55 +00:00
|
|
|
CONST_OID msCertExtCerttype[] = { MICROSOFT_OID, 20, 2 };
|
|
|
|
CONST_OID msNTPrincipalName[] = { MICROSOFT_OID, 20, 2, 3 };
|
|
|
|
CONST_OID msCertsrvCAVersion[] = { MICROSOFT_OID, 21, 1 };
|
|
|
|
CONST_OID msNTDSReplication[] = { MICROSOFT_OID, 25, 1 };
|
|
|
|
CONST_OID pkixLogotype[] = { PKIX_OID, 1, 12 };
|
|
|
|
|
|
|
|
#define OI(x) \
|
|
|
|
{ \
|
|
|
|
siDEROID, (unsigned char*)x, sizeof x \
|
|
|
|
}
|
|
|
|
#define OD(oid, desc, mech, ext) \
|
|
|
|
{ \
|
|
|
|
OI(oid), SEC_OID_UNKNOWN, desc, mech, ext \
|
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
#define SEC_OID(tag) more_oids[tag].offset
|
|
|
|
|
|
|
|
static SECOidData more_oids[] = {
|
2017-01-31 21:23:55 +00:00
|
|
|
/* Microsoft OIDs */
|
|
|
|
#define MS_CERT_EXT_CERTTYPE 0
|
|
|
|
OD(msCertExtCerttype,
|
|
|
|
"Microsoft Certificate Template Name",
|
|
|
|
CKM_INVALID_MECHANISM,
|
|
|
|
INVALID_CERT_EXTENSION),
|
|
|
|
|
|
|
|
#define MS_NT_PRINCIPAL_NAME 1
|
|
|
|
OD(msNTPrincipalName,
|
|
|
|
"Microsoft Principal Name",
|
|
|
|
CKM_INVALID_MECHANISM,
|
|
|
|
INVALID_CERT_EXTENSION),
|
|
|
|
|
|
|
|
#define MS_CERTSERV_CA_VERSION 2
|
|
|
|
OD(msCertsrvCAVersion,
|
|
|
|
"Microsoft CA Version",
|
|
|
|
CKM_INVALID_MECHANISM,
|
|
|
|
INVALID_CERT_EXTENSION),
|
|
|
|
|
|
|
|
#define MS_NTDS_REPLICATION 3
|
|
|
|
OD(msNTDSReplication,
|
|
|
|
"Microsoft Domain GUID",
|
|
|
|
CKM_INVALID_MECHANISM,
|
|
|
|
INVALID_CERT_EXTENSION),
|
|
|
|
|
|
|
|
#define PKIX_LOGOTYPE 4
|
|
|
|
OD(pkixLogotype, "Logotype", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
|
2005-12-25 21:09:45 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const unsigned int numOids = (sizeof more_oids) / (sizeof more_oids[0]);
|
|
|
|
|
2004-04-18 21:20:31 +00:00
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundle(nsIStringBundle** pipnssBundle)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIStringBundleService> bundleService(
|
|
|
|
do_GetService(NS_STRINGBUNDLE_CONTRACTID));
|
|
|
|
if (!bundleService) {
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
return bundleService->CreateBundle("chrome://pipnss/locale/pipnss.properties",
|
|
|
|
pipnssBundle);
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
|
|
|
GetPIPNSSBundleString(const char* stringName, nsAString& result)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(stringName);
|
|
|
|
if (!stringName) {
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIStringBundle> pipnssBundle;
|
|
|
|
nsresult rv = GetPIPNSSBundle(getter_AddRefs(pipnssBundle));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
result.Truncate();
|
|
|
|
return pipnssBundle->GetStringFromName(
|
|
|
|
NS_ConvertASCIItoUTF16(stringName).get(), getter_Copies(result));
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
|
|
|
PIPBundleFormatStringFromName(const char* stringName, const char16_t** params,
|
|
|
|
uint32_t numParams, nsAString& result)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(stringName);
|
|
|
|
MOZ_ASSERT(params);
|
|
|
|
if (!stringName || !params) {
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIStringBundle> pipnssBundle;
|
|
|
|
nsresult rv = GetPIPNSSBundle(getter_AddRefs(pipnssBundle));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
result.Truncate();
|
|
|
|
return pipnssBundle->FormatStringFromName(
|
|
|
|
NS_ConvertASCIItoUTF16(stringName).get(), params, numParams,
|
|
|
|
getter_Copies(result));
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
|
|
|
ProcessVersion(SECItem* versionItem, nsIASN1PrintableItem** retItem)
|
2002-09-17 18:51:22 +00:00
|
|
|
{
|
2004-02-26 04:07:23 +00:00
|
|
|
nsAutoString text;
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpVersion", text);
|
2016-04-18 18:07:24 +00:00
|
|
|
nsCOMPtr<nsIASN1PrintableItem> printableItem = new nsNSSASN1PrintableItem();
|
|
|
|
nsresult rv = printableItem->SetDisplayName(text);
|
|
|
|
if (NS_FAILED(rv)) {
|
2002-09-17 18:51:22 +00:00
|
|
|
return rv;
|
2016-04-18 18:07:24 +00:00
|
|
|
}
|
2002-09-17 18:51:22 +00:00
|
|
|
|
|
|
|
// Now to figure out what version this certificate is.
|
2016-04-18 18:07:24 +00:00
|
|
|
unsigned int version;
|
2002-09-17 18:51:22 +00:00
|
|
|
if (versionItem->data) {
|
2016-04-18 18:07:24 +00:00
|
|
|
// Filter out totally bogus version values/encodings.
|
|
|
|
if (versionItem->len != 1) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2016-05-19 04:20:56 +00:00
|
|
|
version = *BitwiseCast<uint8_t*, unsigned char*>(versionItem->data);
|
2002-09-17 18:51:22 +00:00
|
|
|
} else {
|
2016-04-18 18:07:24 +00:00
|
|
|
// If there is no version present in the cert, then RFC 5280 says we
|
|
|
|
// default to v1 (0).
|
2002-09-17 18:51:22 +00:00
|
|
|
version = 0;
|
|
|
|
}
|
|
|
|
|
2016-04-18 18:07:24 +00:00
|
|
|
// A value of n actually corresponds to version n + 1
|
|
|
|
nsAutoString versionString;
|
|
|
|
versionString.AppendInt(version + 1);
|
|
|
|
const char16_t* params[1] = { versionString.get() };
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = PIPBundleFormatStringFromName(
|
2017-01-31 21:23:55 +00:00
|
|
|
"CertDumpVersionValue", params, MOZ_ARRAY_LENGTH(params), text);
|
2016-04-18 18:07:24 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
2016-04-19 23:09:49 +00:00
|
|
|
return rv;
|
2016-04-18 18:07:24 +00:00
|
|
|
}
|
2002-09-17 18:51:22 +00:00
|
|
|
|
2002-09-23 20:17:16 +00:00
|
|
|
rv = printableItem->SetDisplayValue(text);
|
2016-04-18 18:07:24 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
2002-09-17 18:51:22 +00:00
|
|
|
return rv;
|
2016-04-18 18:07:24 +00:00
|
|
|
}
|
2002-09-17 18:51:22 +00:00
|
|
|
|
2015-07-01 17:10:53 +00:00
|
|
|
printableItem.forget(retItem);
|
2002-09-17 18:51:22 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2016-06-30 01:42:37 +00:00
|
|
|
static nsresult
|
|
|
|
ProcessSerialNumberDER(const SECItem& serialItem,
|
2017-01-31 21:23:55 +00:00
|
|
|
/*out*/ nsCOMPtr<nsIASN1PrintableItem>& retItem)
|
2002-09-17 18:51:22 +00:00
|
|
|
{
|
2004-02-26 04:07:23 +00:00
|
|
|
nsAutoString text;
|
2017-01-31 22:08:56 +00:00
|
|
|
nsresult rv = GetPIPNSSBundleString("CertDumpSerialNo", text);
|
2016-06-30 01:42:37 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
2002-09-17 18:51:22 +00:00
|
|
|
return rv;
|
2016-06-30 01:42:37 +00:00
|
|
|
}
|
2002-09-17 18:51:22 +00:00
|
|
|
|
2016-06-30 01:42:37 +00:00
|
|
|
nsCOMPtr<nsIASN1PrintableItem> printableItem = new nsNSSASN1PrintableItem();
|
2002-09-23 20:17:16 +00:00
|
|
|
rv = printableItem->SetDisplayName(text);
|
2016-06-30 01:42:37 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
2002-09-17 18:51:22 +00:00
|
|
|
return rv;
|
2016-06-30 01:42:37 +00:00
|
|
|
}
|
2002-09-17 18:51:22 +00:00
|
|
|
|
2016-06-30 01:42:37 +00:00
|
|
|
UniquePORTString serialNumber(
|
|
|
|
CERT_Hexify(const_cast<SECItem*>(&serialItem), 1));
|
|
|
|
if (!serialNumber) {
|
2002-09-17 18:51:22 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2016-06-30 01:42:37 +00:00
|
|
|
}
|
2002-09-17 18:51:22 +00:00
|
|
|
|
2017-01-31 21:23:55 +00:00
|
|
|
rv =
|
|
|
|
printableItem->SetDisplayValue(NS_ConvertASCIItoUTF16(serialNumber.get()));
|
2016-06-30 01:42:37 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
retItem = printableItem.forget();
|
|
|
|
return NS_OK;
|
2002-09-17 18:51:22 +00:00
|
|
|
}
|
|
|
|
|
2004-02-26 04:07:23 +00:00
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
GetDefaultOIDFormat(SECItem* oid, nsAString& outString, char separator)
|
2002-09-17 18:51:22 +00:00
|
|
|
{
|
|
|
|
char buf[300];
|
2009-07-29 20:23:27 +00:00
|
|
|
unsigned int len = 0;
|
|
|
|
int written, invalidCount = 0;
|
2017-01-31 21:23:55 +00:00
|
|
|
|
2009-07-29 20:23:27 +00:00
|
|
|
unsigned int i;
|
2017-01-31 21:23:55 +00:00
|
|
|
unsigned long val = 0;
|
2011-09-29 06:19:26 +00:00
|
|
|
bool invalid = false;
|
|
|
|
bool first = true;
|
2002-09-17 18:51:22 +00:00
|
|
|
|
|
|
|
val = 0;
|
2009-07-29 20:23:27 +00:00
|
|
|
for (i = 0; i < oid->len; ++i) {
|
2017-01-31 21:23:55 +00:00
|
|
|
// In this loop, we have to parse a DER formatted
|
|
|
|
// If the first bit is a 1, then the integer is
|
|
|
|
// represented by more than one byte. If the
|
2002-09-17 18:51:22 +00:00
|
|
|
// first bit is set then we continue on and add
|
2017-01-31 21:23:55 +00:00
|
|
|
// the values of the later bytes until we get
|
2002-09-17 18:51:22 +00:00
|
|
|
// a byte without the first bit set.
|
|
|
|
unsigned long j;
|
|
|
|
|
|
|
|
j = oid->data[i];
|
|
|
|
val = (val << 7) | (j & 0x7f);
|
2009-07-29 20:23:27 +00:00
|
|
|
if (j & 0x80) {
|
|
|
|
// - If val is 0 in this block, the OID number particle starts with 0x80
|
|
|
|
// what is specified as an invalid formating.
|
|
|
|
// - If val is larger then 2^32-7, on next left shift by 7 we will loose
|
|
|
|
// the most significant bits, this OID number particle cannot be read
|
|
|
|
// by our implementation.
|
|
|
|
// - If the first bit is set while this is the last component of the OID
|
|
|
|
// we are also in an invalid state.
|
2017-01-31 21:23:55 +00:00
|
|
|
if (val == 0 || (val >= (1 << (32 - 7))) || (i == oid->len - 1)) {
|
2011-10-17 14:59:28 +00:00
|
|
|
invalid = true;
|
2009-07-29 20:23:27 +00:00
|
|
|
}
|
|
|
|
|
2017-01-31 21:23:55 +00:00
|
|
|
if (i < oid->len - 1)
|
2009-07-29 20:23:27 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!invalid) {
|
|
|
|
if (first) {
|
2017-01-31 21:23:55 +00:00
|
|
|
unsigned long one = std::min(val / 40, 2UL); // never > 2
|
2009-07-29 20:23:27 +00:00
|
|
|
unsigned long two = val - (one * 40);
|
|
|
|
|
2017-01-31 21:23:55 +00:00
|
|
|
written = snprintf(
|
|
|
|
&buf[len], sizeof(buf) - len, "%lu%c%lu", one, separator, two);
|
|
|
|
} else {
|
|
|
|
written =
|
|
|
|
snprintf(&buf[len], sizeof(buf) - len, "%c%lu", separator, val);
|
2009-07-29 20:23:27 +00:00
|
|
|
}
|
2017-01-31 21:23:55 +00:00
|
|
|
} else {
|
2009-07-29 20:23:27 +00:00
|
|
|
nsAutoString unknownText;
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertUnknown", unknownText);
|
2009-07-29 20:23:27 +00:00
|
|
|
if (first) {
|
2017-01-31 21:23:55 +00:00
|
|
|
written = snprintf(&buf[len],
|
|
|
|
sizeof(buf) - len,
|
|
|
|
"%s",
|
|
|
|
NS_ConvertUTF16toUTF8(unknownText).get());
|
|
|
|
} else {
|
|
|
|
written = snprintf(&buf[len],
|
|
|
|
sizeof(buf) - len,
|
|
|
|
"%c%s",
|
|
|
|
separator,
|
2016-02-26 23:31:43 +00:00
|
|
|
NS_ConvertUTF16toUTF8(unknownText).get());
|
2009-07-29 20:23:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (++invalidCount > 3) {
|
|
|
|
// Allow only 3 occurences of Unknown in OID display string to
|
|
|
|
// prevent bloat.
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-09-17 18:51:22 +00:00
|
|
|
if (written < 0)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
len += written;
|
2017-01-02 06:11:39 +00:00
|
|
|
MOZ_ASSERT(len < sizeof(buf), "OID data too big to display in 300 chars.");
|
2017-01-31 21:23:55 +00:00
|
|
|
val = 0;
|
2011-10-17 14:59:28 +00:00
|
|
|
invalid = false;
|
|
|
|
first = false;
|
2002-09-17 18:51:22 +00:00
|
|
|
}
|
|
|
|
|
2004-02-03 18:23:41 +00:00
|
|
|
CopyASCIItoUTF16(buf, outString);
|
2017-01-31 21:23:55 +00:00
|
|
|
return NS_OK;
|
2002-09-17 18:51:22 +00:00
|
|
|
}
|
|
|
|
|
2004-04-18 21:20:31 +00:00
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
GetOIDText(SECItem* oid, nsAString& text)
|
2017-01-31 21:23:55 +00:00
|
|
|
{
|
2002-09-17 18:51:22 +00:00
|
|
|
nsresult rv;
|
|
|
|
SECOidTag oidTag = SECOID_FindOIDTag(oid);
|
2017-01-31 21:23:55 +00:00
|
|
|
const char* bundlekey = 0;
|
2002-09-17 18:51:22 +00:00
|
|
|
|
|
|
|
switch (oidTag) {
|
2017-01-31 21:23:55 +00:00
|
|
|
case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
|
|
|
|
bundlekey = "CertDumpMD2WithRSA";
|
2005-12-25 21:09:45 +00:00
|
|
|
break;
|
2017-01-31 21:23:55 +00:00
|
|
|
case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
|
|
|
|
bundlekey = "CertDumpMD5WithRSA";
|
2005-12-25 21:09:45 +00:00
|
|
|
break;
|
2017-01-31 21:23:55 +00:00
|
|
|
case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
|
|
|
|
bundlekey = "CertDumpSHA1WithRSA";
|
2006-01-30 23:21:00 +00:00
|
|
|
break;
|
2017-01-31 21:23:55 +00:00
|
|
|
case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
|
|
|
|
bundlekey = "CertDumpSHA256WithRSA";
|
|
|
|
break;
|
|
|
|
case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
|
|
|
|
bundlekey = "CertDumpSHA384WithRSA";
|
|
|
|
break;
|
|
|
|
case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
|
|
|
|
bundlekey = "CertDumpSHA512WithRSA";
|
|
|
|
break;
|
|
|
|
case SEC_OID_PKCS1_RSA_ENCRYPTION:
|
|
|
|
bundlekey = "CertDumpRSAEncr";
|
|
|
|
break;
|
|
|
|
case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
|
|
|
|
bundlekey = "CertDumpRSAPSSSignature";
|
|
|
|
break;
|
|
|
|
case SEC_OID_AVA_COUNTRY_NAME:
|
|
|
|
bundlekey = "CertDumpAVACountry";
|
|
|
|
break;
|
|
|
|
case SEC_OID_AVA_COMMON_NAME:
|
|
|
|
bundlekey = "CertDumpAVACN";
|
|
|
|
break;
|
|
|
|
case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME:
|
|
|
|
bundlekey = "CertDumpAVAOU";
|
|
|
|
break;
|
|
|
|
case SEC_OID_AVA_ORGANIZATION_NAME:
|
|
|
|
bundlekey = "CertDumpAVAOrg";
|
|
|
|
break;
|
|
|
|
case SEC_OID_AVA_LOCALITY:
|
|
|
|
bundlekey = "CertDumpAVALocality";
|
|
|
|
break;
|
|
|
|
case SEC_OID_AVA_DN_QUALIFIER:
|
|
|
|
bundlekey = "CertDumpAVADN";
|
|
|
|
break;
|
|
|
|
case SEC_OID_AVA_DC:
|
|
|
|
bundlekey = "CertDumpAVADC";
|
|
|
|
break;
|
|
|
|
case SEC_OID_AVA_STATE_OR_PROVINCE:
|
|
|
|
bundlekey = "CertDumpAVAState";
|
|
|
|
break;
|
|
|
|
case SEC_OID_AVA_SURNAME:
|
|
|
|
bundlekey = "CertDumpSurname";
|
|
|
|
break;
|
|
|
|
case SEC_OID_AVA_GIVEN_NAME:
|
|
|
|
bundlekey = "CertDumpGivenName";
|
|
|
|
break;
|
|
|
|
case SEC_OID_X509_SUBJECT_DIRECTORY_ATTR:
|
|
|
|
bundlekey = "CertDumpSubjectDirectoryAttr";
|
|
|
|
break;
|
|
|
|
case SEC_OID_X509_SUBJECT_KEY_ID:
|
|
|
|
bundlekey = "CertDumpSubjectKeyID";
|
|
|
|
break;
|
|
|
|
case SEC_OID_X509_KEY_USAGE:
|
|
|
|
bundlekey = "CertDumpKeyUsage";
|
|
|
|
break;
|
|
|
|
case SEC_OID_X509_SUBJECT_ALT_NAME:
|
|
|
|
bundlekey = "CertDumpSubjectAltName";
|
|
|
|
break;
|
|
|
|
case SEC_OID_X509_ISSUER_ALT_NAME:
|
|
|
|
bundlekey = "CertDumpIssuerAltName";
|
|
|
|
break;
|
|
|
|
case SEC_OID_X509_BASIC_CONSTRAINTS:
|
|
|
|
bundlekey = "CertDumpBasicConstraints";
|
|
|
|
break;
|
|
|
|
case SEC_OID_X509_NAME_CONSTRAINTS:
|
|
|
|
bundlekey = "CertDumpNameConstraints";
|
|
|
|
break;
|
|
|
|
case SEC_OID_X509_CRL_DIST_POINTS:
|
|
|
|
bundlekey = "CertDumpCrlDistPoints";
|
|
|
|
break;
|
|
|
|
case SEC_OID_X509_CERTIFICATE_POLICIES:
|
|
|
|
bundlekey = "CertDumpCertPolicies";
|
|
|
|
break;
|
|
|
|
case SEC_OID_X509_POLICY_MAPPINGS:
|
|
|
|
bundlekey = "CertDumpPolicyMappings";
|
|
|
|
break;
|
|
|
|
case SEC_OID_X509_POLICY_CONSTRAINTS:
|
|
|
|
bundlekey = "CertDumpPolicyConstraints";
|
|
|
|
break;
|
|
|
|
case SEC_OID_X509_AUTH_KEY_ID:
|
|
|
|
bundlekey = "CertDumpAuthKeyID";
|
|
|
|
break;
|
|
|
|
case SEC_OID_X509_EXT_KEY_USAGE:
|
|
|
|
bundlekey = "CertDumpExtKeyUsage";
|
|
|
|
break;
|
|
|
|
case SEC_OID_X509_AUTH_INFO_ACCESS:
|
|
|
|
bundlekey = "CertDumpAuthInfoAccess";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX9_DSA_SIGNATURE:
|
|
|
|
bundlekey = "CertDumpAnsiX9DsaSignature";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
|
|
|
|
bundlekey = "CertDumpAnsiX9DsaSignatureWithSha1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
|
|
|
|
bundlekey = "CertDumpAnsiX962ECDsaSignatureWithSha1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
|
|
|
|
bundlekey = "CertDumpAnsiX962ECDsaSignatureWithSha224";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
|
|
|
|
bundlekey = "CertDumpAnsiX962ECDsaSignatureWithSha256";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
|
|
|
|
bundlekey = "CertDumpAnsiX962ECDsaSignatureWithSha384";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
|
|
|
|
bundlekey = "CertDumpAnsiX962ECDsaSignatureWithSha512";
|
|
|
|
break;
|
|
|
|
case SEC_OID_RFC1274_UID:
|
|
|
|
bundlekey = "CertDumpUserID";
|
|
|
|
break;
|
|
|
|
case SEC_OID_PKCS9_EMAIL_ADDRESS:
|
|
|
|
bundlekey = "CertDumpPK9Email";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
|
|
|
|
bundlekey = "CertDumpECPublicKey";
|
|
|
|
break;
|
|
|
|
/* ANSI X9.62 named elliptic curves (prime field) */
|
|
|
|
case SEC_OID_ANSIX962_EC_PRIME192V1:
|
|
|
|
/* same as SEC_OID_SECG_EC_SECP192r1 */
|
|
|
|
bundlekey = "CertDumpECprime192v1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_PRIME192V2:
|
|
|
|
bundlekey = "CertDumpECprime192v2";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_PRIME192V3:
|
|
|
|
bundlekey = "CertDumpECprime192v3";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_PRIME239V1:
|
|
|
|
bundlekey = "CertDumpECprime239v1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_PRIME239V2:
|
|
|
|
bundlekey = "CertDumpECprime239v2";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_PRIME239V3:
|
|
|
|
bundlekey = "CertDumpECprime239v3";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_PRIME256V1:
|
|
|
|
/* same as SEC_OID_SECG_EC_SECP256r1 */
|
|
|
|
bundlekey = "CertDumpECprime256v1";
|
|
|
|
break;
|
|
|
|
/* SECG named elliptic curves (prime field) */
|
|
|
|
case SEC_OID_SECG_EC_SECP112R1:
|
|
|
|
bundlekey = "CertDumpECsecp112r1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECP112R2:
|
|
|
|
bundlekey = "CertDumpECsecp112r2";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECP128R1:
|
|
|
|
bundlekey = "CertDumpECsecp128r1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECP128R2:
|
|
|
|
bundlekey = "CertDumpECsecp128r2";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECP160K1:
|
|
|
|
bundlekey = "CertDumpECsecp160k1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECP160R1:
|
|
|
|
bundlekey = "CertDumpECsecp160r1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECP160R2:
|
|
|
|
bundlekey = "CertDumpECsecp160r2";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECP192K1:
|
|
|
|
bundlekey = "CertDumpECsecp192k1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECP224K1:
|
|
|
|
bundlekey = "CertDumpECsecp224k1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECP224R1:
|
|
|
|
bundlekey = "CertDumpECsecp224r1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECP256K1:
|
|
|
|
bundlekey = "CertDumpECsecp256k1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECP384R1:
|
|
|
|
bundlekey = "CertDumpECsecp384r1";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SEC_OID_SECG_EC_SECP521R1:
|
|
|
|
bundlekey = "CertDumpECsecp521r1";
|
|
|
|
break;
|
|
|
|
/* ANSI X9.62 named elliptic curves (characteristic two field) */
|
|
|
|
case SEC_OID_ANSIX962_EC_C2PNB163V1:
|
|
|
|
bundlekey = "CertDumpECc2pnb163v1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_C2PNB163V2:
|
|
|
|
bundlekey = "CertDumpECc2pnb163v2";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_C2PNB163V3:
|
|
|
|
bundlekey = "CertDumpECc2pnb163v3";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_C2PNB176V1:
|
|
|
|
bundlekey = "CertDumpECc2pnb176v1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_C2TNB191V1:
|
|
|
|
bundlekey = "CertDumpECc2tnb191v1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_C2TNB191V2:
|
|
|
|
bundlekey = "CertDumpECc2tnb191v2";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_C2TNB191V3:
|
|
|
|
bundlekey = "CertDumpECc2tnb191v3";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_C2ONB191V4:
|
|
|
|
bundlekey = "CertDumpECc2onb191v4";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_C2ONB191V5:
|
|
|
|
bundlekey = "CertDumpECc2onb191v5";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_C2PNB208W1:
|
|
|
|
bundlekey = "CertDumpECc2pnb208w1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_C2TNB239V1:
|
|
|
|
bundlekey = "CertDumpECc2tnb239v1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_C2TNB239V2:
|
|
|
|
bundlekey = "CertDumpECc2tnb239v2";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_C2TNB239V3:
|
|
|
|
bundlekey = "CertDumpECc2tnb239v3";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_C2ONB239V4:
|
|
|
|
bundlekey = "CertDumpECc2onb239v4";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_C2ONB239V5:
|
|
|
|
bundlekey = "CertDumpECc2onb239v5";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_C2PNB272W1:
|
|
|
|
bundlekey = "CertDumpECc2pnb272w1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_C2PNB304W1:
|
|
|
|
bundlekey = "CertDumpECc2pnb304w1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_C2TNB359V1:
|
|
|
|
bundlekey = "CertDumpECc2tnb359v1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_C2PNB368W1:
|
|
|
|
bundlekey = "CertDumpECc2pnb368w1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_ANSIX962_EC_C2TNB431R1:
|
|
|
|
bundlekey = "CertDumpECc2tnb431r1";
|
|
|
|
break;
|
|
|
|
/* SECG named elliptic curves (characteristic two field) */
|
|
|
|
case SEC_OID_SECG_EC_SECT113R1:
|
|
|
|
bundlekey = "CertDumpECsect113r1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECT113R2:
|
|
|
|
bundlekey = "CertDumpECsect113r2";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECT131R1:
|
|
|
|
bundlekey = "CertDumpECsect131r1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECT131R2:
|
|
|
|
bundlekey = "CertDumpECsect131r2";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECT163K1:
|
|
|
|
bundlekey = "CertDumpECsect163k1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECT163R1:
|
|
|
|
bundlekey = "CertDumpECsect163r1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECT163R2:
|
|
|
|
bundlekey = "CertDumpECsect163r2";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECT193R1:
|
|
|
|
bundlekey = "CertDumpECsect193r1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECT193R2:
|
|
|
|
bundlekey = "CertDumpECsect193r2";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECT233K1:
|
|
|
|
bundlekey = "CertDumpECsect233k1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECT233R1:
|
|
|
|
bundlekey = "CertDumpECsect233r1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECT239K1:
|
|
|
|
bundlekey = "CertDumpECsect239k1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECT283K1:
|
|
|
|
bundlekey = "CertDumpECsect283k1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECT283R1:
|
|
|
|
bundlekey = "CertDumpECsect283r1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECT409K1:
|
|
|
|
bundlekey = "CertDumpECsect409k1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECT409R1:
|
|
|
|
bundlekey = "CertDumpECsect409r1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECT571K1:
|
|
|
|
bundlekey = "CertDumpECsect571k1";
|
|
|
|
break;
|
|
|
|
case SEC_OID_SECG_EC_SECT571R1:
|
|
|
|
bundlekey = "CertDumpECsect571r1";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (oidTag == SEC_OID(MS_CERT_EXT_CERTTYPE)) {
|
|
|
|
bundlekey = "CertDumpMSCerttype";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (oidTag == SEC_OID(MS_CERTSERV_CA_VERSION)) {
|
|
|
|
bundlekey = "CertDumpMSCAVersion";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (oidTag == SEC_OID(PKIX_LOGOTYPE)) {
|
|
|
|
bundlekey = "CertDumpLogotype";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* fallthrough */
|
2004-01-31 07:10:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (bundlekey) {
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = GetPIPNSSBundleString(bundlekey, text);
|
2004-01-31 07:10:35 +00:00
|
|
|
} else {
|
2004-02-26 04:07:23 +00:00
|
|
|
nsAutoString text2;
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = GetDefaultOIDFormat(oid, text2, ' ');
|
2002-09-17 18:51:22 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2017-01-31 21:23:55 +00:00
|
|
|
const char16_t* params[1] = { text2.get() };
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = PIPBundleFormatStringFromName("CertDumpDefOID", params, 1, text);
|
2002-09-17 18:51:22 +00:00
|
|
|
}
|
2017-01-31 21:23:55 +00:00
|
|
|
return rv;
|
2002-09-17 18:51:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#define SEPARATOR "\n"
|
|
|
|
|
2004-04-18 21:20:31 +00:00
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessRawBytes(SECItem* data, nsAString& text, bool wantHeader = true)
|
2002-09-17 18:51:22 +00:00
|
|
|
{
|
|
|
|
// This function is used to display some DER bytes
|
|
|
|
// that we have not added support for decoding.
|
2008-07-17 17:14:54 +00:00
|
|
|
// If it's short, let's display as an integer, no size header.
|
|
|
|
|
|
|
|
if (data->len <= 4) {
|
|
|
|
int i_pv = DER_GetInteger(data);
|
|
|
|
nsAutoString value;
|
|
|
|
value.AppendInt(i_pv);
|
|
|
|
text.Append(value);
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(SEPARATOR);
|
2008-07-17 17:14:54 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Else produce a hex dump.
|
2006-02-28 18:30:01 +00:00
|
|
|
|
2006-09-28 23:31:34 +00:00
|
|
|
if (wantHeader) {
|
|
|
|
nsAutoString bytelen, bitlen;
|
|
|
|
bytelen.AppendInt(data->len);
|
2017-01-31 21:23:55 +00:00
|
|
|
bitlen.AppendInt(data->len * 8);
|
|
|
|
|
|
|
|
const char16_t* params[2] = { bytelen.get(), bitlen.get() };
|
2017-01-31 22:08:56 +00:00
|
|
|
nsresult rv = PIPBundleFormatStringFromName("CertDumpRawBytesHeader",
|
|
|
|
params, 2, text);
|
2006-09-28 23:31:34 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2006-02-28 18:30:01 +00:00
|
|
|
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(SEPARATOR);
|
2006-09-28 23:31:34 +00:00
|
|
|
}
|
2006-02-28 18:30:01 +00:00
|
|
|
|
2017-01-31 21:23:55 +00:00
|
|
|
// This prints the value of the byte out into a
|
2008-07-17 17:14:54 +00:00
|
|
|
// string that can later be displayed as a byte
|
|
|
|
// string. We place a new line after 24 bytes
|
|
|
|
// to break up extermaly long sequence of bytes.
|
|
|
|
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t i;
|
2002-09-17 18:51:22 +00:00
|
|
|
char buffer[5];
|
2017-01-31 21:23:55 +00:00
|
|
|
for (i = 0; i < data->len; i++) {
|
2016-08-15 06:44:00 +00:00
|
|
|
SprintfLiteral(buffer, "%02x ", data->data[i]);
|
2003-11-01 10:57:41 +00:00
|
|
|
AppendASCIItoUTF16(buffer, text);
|
2017-01-31 21:23:55 +00:00
|
|
|
if ((i + 1) % 16 == 0) {
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(SEPARATOR);
|
2002-09-17 18:51:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
2016-06-22 22:56:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Appends a pipnss bundle string to the given string.
|
|
|
|
*
|
|
|
|
* @param bundleKey Key for the string to append.
|
|
|
|
* @param currentText The text to append to, using |SEPARATOR| as the separator.
|
|
|
|
*/
|
2017-01-31 21:23:55 +00:00
|
|
|
template <size_t N>
|
|
|
|
void
|
2017-01-31 22:08:56 +00:00
|
|
|
AppendBundleString(const char (&bundleKey)[N],
|
2017-01-31 21:23:55 +00:00
|
|
|
/*in/out*/ nsAString& currentText)
|
2016-06-22 22:56:11 +00:00
|
|
|
{
|
|
|
|
nsAutoString bundleString;
|
2017-01-31 22:08:56 +00:00
|
|
|
nsresult rv = GetPIPNSSBundleString(bundleKey, bundleString);
|
2016-06-22 22:56:11 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
currentText.Append(bundleString);
|
|
|
|
currentText.AppendLiteral(SEPARATOR);
|
|
|
|
}
|
2002-09-17 18:51:22 +00:00
|
|
|
|
2004-02-26 04:07:23 +00:00
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessKeyUsageExtension(SECItem* extData, nsAString& text)
|
2002-09-17 18:51:22 +00:00
|
|
|
{
|
2016-06-22 22:56:11 +00:00
|
|
|
MOZ_ASSERT(extData);
|
|
|
|
NS_ENSURE_ARG(extData);
|
|
|
|
|
|
|
|
ScopedAutoSECItem decoded;
|
2017-01-31 21:23:55 +00:00
|
|
|
if (SEC_ASN1DecodeItem(
|
|
|
|
nullptr, &decoded, SEC_ASN1_GET(SEC_BitStringTemplate), extData) !=
|
|
|
|
SECSuccess) {
|
2017-01-31 22:08:56 +00:00
|
|
|
AppendBundleString("CertDumpExtensionFailure", text);
|
2002-10-11 13:21:58 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2014-06-10 14:56:00 +00:00
|
|
|
unsigned char keyUsage = 0;
|
|
|
|
if (decoded.len) {
|
|
|
|
keyUsage = decoded.data[0];
|
|
|
|
}
|
2016-06-22 22:56:11 +00:00
|
|
|
|
2002-09-17 18:51:22 +00:00
|
|
|
if (keyUsage & KU_DIGITAL_SIGNATURE) {
|
2017-01-31 22:08:56 +00:00
|
|
|
AppendBundleString("CertDumpKUSign", text);
|
2002-09-17 18:51:22 +00:00
|
|
|
}
|
|
|
|
if (keyUsage & KU_NON_REPUDIATION) {
|
2017-01-31 22:08:56 +00:00
|
|
|
AppendBundleString("CertDumpKUNonRep", text);
|
2002-09-17 18:51:22 +00:00
|
|
|
}
|
|
|
|
if (keyUsage & KU_KEY_ENCIPHERMENT) {
|
2017-01-31 22:08:56 +00:00
|
|
|
AppendBundleString("CertDumpKUEnc", text);
|
2002-09-17 18:51:22 +00:00
|
|
|
}
|
|
|
|
if (keyUsage & KU_DATA_ENCIPHERMENT) {
|
2017-01-31 22:08:56 +00:00
|
|
|
AppendBundleString("CertDumpKUDEnc", text);
|
2002-09-17 18:51:22 +00:00
|
|
|
}
|
|
|
|
if (keyUsage & KU_KEY_AGREEMENT) {
|
2017-01-31 22:08:56 +00:00
|
|
|
AppendBundleString("CertDumpKUKA", text);
|
2002-09-17 18:51:22 +00:00
|
|
|
}
|
|
|
|
if (keyUsage & KU_KEY_CERT_SIGN) {
|
2017-01-31 22:08:56 +00:00
|
|
|
AppendBundleString("CertDumpKUCertSign", text);
|
2002-09-17 18:51:22 +00:00
|
|
|
}
|
|
|
|
if (keyUsage & KU_CRL_SIGN) {
|
2017-01-31 22:08:56 +00:00
|
|
|
AppendBundleString("CertDumpKUCRLSigner", text);
|
2002-09-17 18:51:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-12-02 22:29:14 +00:00
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessBasicConstraints(SECItem* extData, nsAString& text)
|
2005-12-02 22:29:14 +00:00
|
|
|
{
|
2005-12-25 21:09:45 +00:00
|
|
|
nsAutoString local;
|
|
|
|
CERTBasicConstraints value;
|
|
|
|
SECStatus rv;
|
|
|
|
nsresult rv2;
|
|
|
|
|
2006-01-30 23:21:00 +00:00
|
|
|
value.pathLenConstraint = -1;
|
2017-01-31 21:23:55 +00:00
|
|
|
rv = CERT_DecodeBasicConstraintValue(&value, extData);
|
2005-12-25 21:09:45 +00:00
|
|
|
if (rv != SECSuccess) {
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessRawBytes(extData, text);
|
2006-01-30 23:21:00 +00:00
|
|
|
return NS_OK;
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
if (value.isCA)
|
2017-01-31 22:08:56 +00:00
|
|
|
rv2 = GetPIPNSSBundleString("CertDumpIsCA", local);
|
2005-12-25 21:09:45 +00:00
|
|
|
else
|
2017-01-31 22:08:56 +00:00
|
|
|
rv2 = GetPIPNSSBundleString("CertDumpIsNotCA", local);
|
2005-12-25 21:09:45 +00:00
|
|
|
if (NS_FAILED(rv2))
|
|
|
|
return rv2;
|
|
|
|
text.Append(local.get());
|
2006-01-30 23:21:00 +00:00
|
|
|
if (value.pathLenConstraint != -1) {
|
2005-12-25 21:09:45 +00:00
|
|
|
nsAutoString depth;
|
2006-01-30 23:21:00 +00:00
|
|
|
if (value.pathLenConstraint == CERT_UNLIMITED_PATH_CONSTRAINT)
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpPathLenUnlimited", depth);
|
2006-01-30 23:21:00 +00:00
|
|
|
else
|
|
|
|
depth.AppendInt(value.pathLenConstraint);
|
2017-01-31 21:23:55 +00:00
|
|
|
const char16_t* params[1] = { depth.get() };
|
2017-01-31 22:08:56 +00:00
|
|
|
rv2 = PIPBundleFormatStringFromName("CertDumpPathLen", params, 1, local);
|
2005-12-25 21:09:45 +00:00
|
|
|
if (NS_FAILED(rv2))
|
|
|
|
return rv2;
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(SEPARATOR);
|
2005-12-25 21:09:45 +00:00
|
|
|
text.Append(local.get());
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessExtKeyUsage(SECItem* extData, nsAString& text)
|
2005-12-25 21:09:45 +00:00
|
|
|
{
|
|
|
|
nsAutoString local;
|
2017-01-31 21:23:55 +00:00
|
|
|
SECItem** oids;
|
|
|
|
SECItem* oid;
|
2005-12-25 21:09:45 +00:00
|
|
|
nsresult rv;
|
2016-02-17 00:25:09 +00:00
|
|
|
|
|
|
|
UniqueCERTOidSequence extKeyUsage(CERT_DecodeOidSequence(extData));
|
|
|
|
if (!extKeyUsage) {
|
2005-12-25 21:09:45 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2016-02-17 00:25:09 +00:00
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
|
|
|
|
oids = extKeyUsage->oids;
|
2012-10-17 20:48:36 +00:00
|
|
|
while (oids && *oids) {
|
2005-12-25 21:09:45 +00:00
|
|
|
// For each OID, try to find a bundle string
|
|
|
|
// of the form CertDumpEKU_<underlined-OID>
|
|
|
|
nsAutoString oidname;
|
|
|
|
oid = *oids;
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = GetDefaultOIDFormat(oid, oidname, '_');
|
2005-12-25 21:09:45 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2017-01-31 21:23:55 +00:00
|
|
|
nsAutoString bundlekey = NS_LITERAL_STRING("CertDumpEKU_") + oidname;
|
2005-12-25 21:09:45 +00:00
|
|
|
NS_ConvertUTF16toUTF8 bk_ascii(bundlekey);
|
2017-01-31 21:23:55 +00:00
|
|
|
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = GetPIPNSSBundleString(bk_ascii.get(), local);
|
|
|
|
nsresult rv2 = GetDefaultOIDFormat(oid, oidname, '.');
|
2006-01-30 23:21:00 +00:00
|
|
|
if (NS_FAILED(rv2))
|
|
|
|
return rv2;
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
// display name and OID in parentheses
|
|
|
|
text.Append(local);
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(" (");
|
2006-01-30 23:21:00 +00:00
|
|
|
text.Append(oidname);
|
2014-05-22 03:48:50 +00:00
|
|
|
text.Append(')');
|
2006-01-30 23:21:00 +00:00
|
|
|
} else
|
2005-12-25 21:09:45 +00:00
|
|
|
// If there is no bundle string, just display the OID itself
|
2006-01-30 23:21:00 +00:00
|
|
|
text.Append(oidname);
|
2005-12-25 21:09:45 +00:00
|
|
|
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(SEPARATOR);
|
2005-12-25 21:09:45 +00:00
|
|
|
oids++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessRDN(CERTRDN* rdn, nsAString& finalString)
|
2005-12-25 21:09:45 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
2005-12-02 23:45:53 +00:00
|
|
|
CERTAVA** avas;
|
|
|
|
CERTAVA* ava;
|
2005-12-25 21:09:45 +00:00
|
|
|
nsString avavalue;
|
|
|
|
nsString type;
|
|
|
|
nsAutoString temp;
|
2017-01-31 21:23:55 +00:00
|
|
|
const char16_t* params[2];
|
2005-12-25 21:09:45 +00:00
|
|
|
|
|
|
|
avas = rdn->avas;
|
|
|
|
while ((ava = *avas++) != 0) {
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = GetOIDText(&ava->type, type);
|
2016-02-17 00:25:09 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
2005-12-25 21:09:45 +00:00
|
|
|
return rv;
|
2016-02-17 00:25:09 +00:00
|
|
|
}
|
|
|
|
|
2017-01-31 21:23:55 +00:00
|
|
|
// This function returns a string in UTF8 format.
|
2016-02-17 00:25:09 +00:00
|
|
|
UniqueSECItem decodeItem(CERT_DecodeAVAValue(&ava->value));
|
|
|
|
if (!decodeItem) {
|
2005-12-25 21:09:45 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2009-07-29 20:23:27 +00:00
|
|
|
|
|
|
|
// We know we can fit buffer of this length. CERT_RFC1485_EscapeAndQuote
|
|
|
|
// will fail if we provide smaller buffer then the result can fit to.
|
2012-08-09 07:09:40 +00:00
|
|
|
int escapedValueCapacity = decodeItem->len * 3 + 3;
|
2014-07-11 03:37:40 +00:00
|
|
|
UniquePtr<char[]> escapedValue = MakeUnique<char[]>(escapedValueCapacity);
|
2009-07-29 20:23:27 +00:00
|
|
|
|
2017-01-31 21:23:55 +00:00
|
|
|
SECStatus status = CERT_RFC1485_EscapeAndQuote(escapedValue.get(),
|
|
|
|
escapedValueCapacity,
|
|
|
|
(char*)decodeItem->data,
|
|
|
|
decodeItem->len);
|
2010-04-07 20:46:00 +00:00
|
|
|
if (SECSuccess != status) {
|
2009-07-29 20:23:27 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2010-04-07 20:46:00 +00:00
|
|
|
}
|
2009-07-29 20:23:27 +00:00
|
|
|
|
2014-07-11 03:37:40 +00:00
|
|
|
avavalue = NS_ConvertUTF8toUTF16(escapedValue.get());
|
2016-02-17 00:25:09 +00:00
|
|
|
|
2005-12-25 21:09:45 +00:00
|
|
|
params[0] = type.get();
|
|
|
|
params[1] = avavalue.get();
|
2017-01-31 22:08:56 +00:00
|
|
|
PIPBundleFormatStringFromName("AVATemplate", params, 2, temp);
|
2005-12-25 21:09:45 +00:00
|
|
|
finalString += temp + NS_LITERAL_STRING("\n");
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessName(CERTName* name, char16_t** value)
|
2005-12-25 21:09:45 +00:00
|
|
|
{
|
|
|
|
CERTRDN** rdns;
|
|
|
|
CERTRDN** rdn;
|
2004-04-18 21:20:31 +00:00
|
|
|
nsString finalString;
|
|
|
|
|
|
|
|
rdns = name->rdns;
|
|
|
|
|
|
|
|
nsresult rv;
|
2017-01-31 21:23:55 +00:00
|
|
|
CERTRDN** lastRdn;
|
2004-04-18 21:20:31 +00:00
|
|
|
/* find last RDN */
|
|
|
|
lastRdn = rdns;
|
2017-01-31 21:23:55 +00:00
|
|
|
while (*lastRdn)
|
|
|
|
lastRdn++;
|
2004-04-18 21:20:31 +00:00
|
|
|
// The above whille loop will put us at the last member
|
2013-10-28 14:05:19 +00:00
|
|
|
// of the array which is a nullptr pointer. So let's back
|
2017-01-31 21:23:55 +00:00
|
|
|
// up one spot so that we have the last non-nullptr entry in
|
|
|
|
// the array in preparation for traversing the
|
2004-04-18 21:20:31 +00:00
|
|
|
// RDN's (Relative Distinguished Name) in reverse oder.
|
|
|
|
lastRdn--;
|
2017-01-31 21:23:55 +00:00
|
|
|
|
2004-04-18 21:20:31 +00:00
|
|
|
/*
|
|
|
|
* Loop over name contents in _reverse_ RDN order appending to string
|
2017-01-31 21:23:55 +00:00
|
|
|
* When building the Ascii string, NSS loops over these entries in
|
2004-04-18 21:20:31 +00:00
|
|
|
* reverse order, so I will as well. The difference is that NSS
|
|
|
|
* will always place them in a one line string separated by commas,
|
|
|
|
* where I want each entry on a single line. I can't just use a comma
|
2017-01-31 21:23:55 +00:00
|
|
|
* as my delimitter because it is a valid character to have in the
|
2004-04-18 21:20:31 +00:00
|
|
|
* value portion of the AVA and could cause trouble when parsing.
|
|
|
|
*/
|
|
|
|
for (rdn = lastRdn; rdn >= rdns; rdn--) {
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessRDN(*rdn, finalString);
|
2005-12-25 21:09:45 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
}
|
2017-01-31 21:23:55 +00:00
|
|
|
*value = ToNewUnicode(finalString);
|
2005-12-25 21:09:45 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
2017-01-31 21:23:55 +00:00
|
|
|
ProcessIA5String(const SECItem& extData,
|
|
|
|
/*in/out*/ nsAString& text)
|
2005-12-25 21:09:45 +00:00
|
|
|
{
|
2016-06-22 22:56:11 +00:00
|
|
|
ScopedAutoSECItem item;
|
2017-01-31 21:23:55 +00:00
|
|
|
if (SEC_ASN1DecodeItem(
|
|
|
|
nullptr, &item, SEC_ASN1_GET(SEC_IA5StringTemplate), &extData) !=
|
|
|
|
SECSuccess) {
|
2005-12-25 21:09:45 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2016-06-22 22:56:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
text.AppendASCII(BitwiseCast<char*, unsigned char*>(item.data),
|
|
|
|
AssertedCast<uint32_t>(item.len));
|
2005-12-25 21:09:45 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
2017-01-31 21:23:55 +00:00
|
|
|
AppendBMPtoUTF16(const UniquePLArenaPool& arena,
|
|
|
|
unsigned char* data,
|
|
|
|
unsigned int len,
|
|
|
|
nsAString& text)
|
2005-12-25 21:09:45 +00:00
|
|
|
{
|
2016-02-17 00:25:09 +00:00
|
|
|
if (len % 2 != 0) {
|
2005-12-25 21:09:45 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2016-02-17 00:25:09 +00:00
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
|
|
|
|
/* XXX instead of converting to and from UTF-8, it would
|
|
|
|
be sufficient to just swap bytes, or do nothing */
|
2016-02-17 00:25:09 +00:00
|
|
|
unsigned int utf8ValLen = len * 3 + 1;
|
2017-01-31 21:23:55 +00:00
|
|
|
unsigned char* utf8Val =
|
|
|
|
(unsigned char*)PORT_ArenaZAlloc(arena.get(), utf8ValLen);
|
|
|
|
if (!PORT_UCS2_UTF8Conversion(
|
|
|
|
false, data, len, utf8Val, utf8ValLen, &utf8ValLen)) {
|
2005-12-25 21:09:45 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2016-02-17 00:25:09 +00:00
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
AppendUTF8toUTF16((char*)utf8Val, text);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
2016-02-17 00:25:09 +00:00
|
|
|
ProcessBMPString(SECItem* extData, nsAString& text)
|
2005-12-25 21:09:45 +00:00
|
|
|
{
|
2016-02-17 00:25:09 +00:00
|
|
|
UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
|
|
|
if (!arena) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
|
2005-12-25 21:09:45 +00:00
|
|
|
SECItem item;
|
2017-01-31 21:23:55 +00:00
|
|
|
if (SEC_ASN1DecodeItem(
|
|
|
|
arena.get(), &item, SEC_ASN1_GET(SEC_BMPStringTemplate), extData) !=
|
|
|
|
SECSuccess) {
|
2005-12-25 21:09:45 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2016-02-17 00:25:09 +00:00
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
|
2016-02-17 00:25:09 +00:00
|
|
|
return AppendBMPtoUTF16(arena, item.data, item.len, text);
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessGeneralName(const UniquePLArenaPool& arena, CERTGeneralName* current,
|
|
|
|
nsAString& text)
|
2005-12-25 21:09:45 +00:00
|
|
|
{
|
2009-02-21 02:09:16 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(current);
|
|
|
|
|
2005-12-25 21:09:45 +00:00
|
|
|
nsAutoString key;
|
|
|
|
nsXPIDLString value;
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
switch (current->type) {
|
2017-01-31 21:23:55 +00:00
|
|
|
case certOtherName: {
|
|
|
|
SECOidTag oidTag = SECOID_FindOIDTag(¤t->name.OthName.oid);
|
|
|
|
if (oidTag == SEC_OID(MS_NT_PRINCIPAL_NAME)) {
|
|
|
|
/* The type of this name is apparently nowhere explicitly
|
|
|
|
documented. However, in the generated templates, it is always
|
|
|
|
UTF-8. So try to decode this as UTF-8; if that fails, dump the
|
|
|
|
raw data. */
|
|
|
|
SECItem decoded;
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpMSNTPrincipal", key);
|
2017-01-31 21:23:55 +00:00
|
|
|
if (SEC_ASN1DecodeItem(arena.get(),
|
|
|
|
&decoded,
|
|
|
|
SEC_ASN1_GET(SEC_UTF8StringTemplate),
|
|
|
|
¤t->name.OthName.name) == SECSuccess) {
|
|
|
|
AppendUTF8toUTF16(nsAutoCString((char*)decoded.data, decoded.len),
|
|
|
|
value);
|
|
|
|
} else {
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessRawBytes(¤t->name.OthName.name, value);
|
2017-01-31 21:23:55 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
} else if (oidTag == SEC_OID(MS_NTDS_REPLICATION)) {
|
|
|
|
/* This should be a 16-byte GUID */
|
|
|
|
SECItem guid;
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpMSDomainGUID", key);
|
2017-01-31 21:23:55 +00:00
|
|
|
if (SEC_ASN1DecodeItem(arena.get(),
|
|
|
|
&guid,
|
|
|
|
SEC_ASN1_GET(SEC_OctetStringTemplate),
|
|
|
|
¤t->name.OthName.name) == SECSuccess &&
|
|
|
|
guid.len == 16) {
|
|
|
|
char buf[40];
|
|
|
|
unsigned char* d = guid.data;
|
2016-08-15 06:44:00 +00:00
|
|
|
SprintfLiteral(buf,
|
2017-01-31 21:23:55 +00:00
|
|
|
"{%.2x%.2x%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%"
|
|
|
|
".2x%.2x%.2x%.2x%.2x}",
|
|
|
|
d[3],
|
|
|
|
d[2],
|
|
|
|
d[1],
|
|
|
|
d[0],
|
|
|
|
d[5],
|
|
|
|
d[4],
|
|
|
|
d[7],
|
|
|
|
d[6],
|
|
|
|
d[8],
|
|
|
|
d[9],
|
|
|
|
d[10],
|
|
|
|
d[11],
|
|
|
|
d[12],
|
|
|
|
d[13],
|
|
|
|
d[14],
|
|
|
|
d[15]);
|
|
|
|
value.AssignASCII(buf);
|
|
|
|
} else {
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessRawBytes(¤t->name.OthName.name, value);
|
2017-01-31 21:23:55 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
rv = GetDefaultOIDFormat(
|
2017-01-31 22:08:56 +00:00
|
|
|
¤t->name.OthName.oid, key, ' ');
|
2017-01-31 21:23:55 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessRawBytes(¤t->name.OthName.name, value);
|
2017-01-31 21:23:55 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case certRFC822Name:
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpRFC822Name", key);
|
2017-01-31 21:23:55 +00:00
|
|
|
value.AssignASCII((char*)current->name.other.data,
|
|
|
|
current->name.other.len);
|
|
|
|
break;
|
|
|
|
case certDNSName:
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpDNSName", key);
|
2017-01-31 21:23:55 +00:00
|
|
|
value.AssignASCII((char*)current->name.other.data,
|
|
|
|
current->name.other.len);
|
|
|
|
break;
|
|
|
|
case certX400Address:
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpX400Address", key);
|
|
|
|
ProcessRawBytes(¤t->name.other, value);
|
2017-01-31 21:23:55 +00:00
|
|
|
break;
|
|
|
|
case certDirectoryName:
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpDirectoryName", key);
|
2017-01-31 21:23:55 +00:00
|
|
|
rv = ProcessName(
|
2017-01-31 22:08:56 +00:00
|
|
|
¤t->name.directoryName, getter_Copies(value));
|
2016-02-17 00:25:09 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
2017-01-31 21:23:55 +00:00
|
|
|
break;
|
|
|
|
case certEDIPartyName:
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpEDIPartyName", key);
|
|
|
|
ProcessRawBytes(¤t->name.other, value);
|
2017-01-31 21:23:55 +00:00
|
|
|
break;
|
|
|
|
case certURI:
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpURI", key);
|
2017-01-31 21:23:55 +00:00
|
|
|
value.AssignASCII((char*)current->name.other.data,
|
|
|
|
current->name.other.len);
|
|
|
|
break;
|
|
|
|
case certIPAddress: {
|
2005-12-25 21:09:45 +00:00
|
|
|
char buf[INET6_ADDRSTRLEN];
|
2007-12-14 17:39:30 +00:00
|
|
|
PRStatus status = PR_FAILURE;
|
2005-12-25 21:09:45 +00:00
|
|
|
PRNetAddr addr;
|
2007-12-14 17:39:30 +00:00
|
|
|
memset(&addr, 0, sizeof(addr));
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpIPAddress", key);
|
2005-12-25 21:09:45 +00:00
|
|
|
if (current->name.other.len == 4) {
|
|
|
|
addr.inet.family = PR_AF_INET;
|
2017-01-31 21:23:55 +00:00
|
|
|
memcpy(
|
|
|
|
&addr.inet.ip, current->name.other.data, current->name.other.len);
|
2007-12-14 17:39:30 +00:00
|
|
|
status = PR_NetAddrToString(&addr, buf, sizeof(buf));
|
2005-12-25 21:09:45 +00:00
|
|
|
} else if (current->name.other.len == 16) {
|
|
|
|
addr.ipv6.family = PR_AF_INET6;
|
2017-01-31 21:23:55 +00:00
|
|
|
memcpy(
|
|
|
|
&addr.ipv6.ip, current->name.other.data, current->name.other.len);
|
2007-12-14 17:39:30 +00:00
|
|
|
status = PR_NetAddrToString(&addr, buf, sizeof(buf));
|
|
|
|
}
|
|
|
|
if (status == PR_SUCCESS) {
|
2005-12-25 21:09:45 +00:00
|
|
|
value.AssignASCII(buf);
|
|
|
|
} else {
|
|
|
|
/* invalid IP address */
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessRawBytes(¤t->name.other, value);
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2017-01-31 21:23:55 +00:00
|
|
|
case certRegisterID:
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpRegisterID", key);
|
|
|
|
rv = GetDefaultOIDFormat(¤t->name.other, value, '.');
|
2017-01-31 21:23:55 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
break;
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
text.Append(key);
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(": ");
|
2005-12-25 21:09:45 +00:00
|
|
|
text.Append(value);
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(SEPARATOR);
|
2016-02-17 00:25:09 +00:00
|
|
|
|
|
|
|
return rv;
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessGeneralNames(const UniquePLArenaPool& arena, CERTGeneralName* nameList,
|
|
|
|
nsAString& text)
|
2005-12-25 21:09:45 +00:00
|
|
|
{
|
2016-02-17 00:25:09 +00:00
|
|
|
CERTGeneralName* current = nameList;
|
2005-12-25 21:09:45 +00:00
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
do {
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessGeneralName(arena, current, text);
|
2016-02-17 00:25:09 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
2005-12-25 21:09:45 +00:00
|
|
|
break;
|
2016-02-17 00:25:09 +00:00
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
current = CERT_GetNextGeneralName(current);
|
|
|
|
} while (current != nameList);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessAltName(SECItem* extData, nsAString& text)
|
2005-12-25 21:09:45 +00:00
|
|
|
{
|
2016-02-17 00:25:09 +00:00
|
|
|
UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
|
|
|
if (!arena) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
|
2016-02-17 00:25:09 +00:00
|
|
|
CERTGeneralName* nameList = CERT_DecodeAltNameExtension(arena.get(), extData);
|
|
|
|
if (!nameList) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
|
2017-01-31 22:08:56 +00:00
|
|
|
return ProcessGeneralNames(arena, nameList, text);
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessSubjectKeyId(SECItem* extData, nsAString& text)
|
2005-12-25 21:09:45 +00:00
|
|
|
{
|
|
|
|
SECItem decoded;
|
|
|
|
nsAutoString local;
|
|
|
|
|
2016-02-17 00:25:09 +00:00
|
|
|
UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
|
|
|
if (!arena) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
2004-04-18 21:20:31 +00:00
|
|
|
|
2017-01-31 21:23:55 +00:00
|
|
|
if (SEC_QuickDERDecodeItem(arena.get(),
|
|
|
|
&decoded,
|
|
|
|
SEC_ASN1_GET(SEC_OctetStringTemplate),
|
|
|
|
extData) != SECSuccess) {
|
2016-02-17 00:25:09 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
2016-02-17 00:25:09 +00:00
|
|
|
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpKeyID", local);
|
2005-12-25 21:09:45 +00:00
|
|
|
text.Append(local);
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(": ");
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessRawBytes(&decoded, text);
|
2005-12-25 21:09:45 +00:00
|
|
|
|
2016-02-17 00:25:09 +00:00
|
|
|
return NS_OK;
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessAuthKeyId(SECItem* extData, nsAString& text)
|
2005-12-25 21:09:45 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsAutoString local;
|
|
|
|
|
2016-02-17 00:25:09 +00:00
|
|
|
UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
|
|
|
if (!arena) {
|
2011-01-13 22:33:37 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2016-02-17 00:25:09 +00:00
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
|
2016-02-17 00:25:09 +00:00
|
|
|
CERTAuthKeyID* ret = CERT_DecodeAuthKeyID(arena.get(), extData);
|
2011-01-13 22:33:37 +00:00
|
|
|
if (!ret) {
|
2016-02-17 00:25:09 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2011-01-13 22:33:37 +00:00
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
|
|
|
|
if (ret->keyID.len > 0) {
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpKeyID", local);
|
2005-12-25 21:09:45 +00:00
|
|
|
text.Append(local);
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(": ");
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessRawBytes(&ret->keyID, text);
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(SEPARATOR);
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ret->authCertIssuer) {
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpIssuer", local);
|
2005-12-25 21:09:45 +00:00
|
|
|
text.Append(local);
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(": ");
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessGeneralNames(arena, ret->authCertIssuer, text);
|
2016-02-17 00:25:09 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ret->authCertSerialNumber.len > 0) {
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpSerialNo", local);
|
2005-12-25 21:09:45 +00:00
|
|
|
text.Append(local);
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(": ");
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessRawBytes(&ret->authCertSerialNumber, text);
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessUserNotice(SECItem* derNotice, nsAString& text)
|
2005-12-25 21:09:45 +00:00
|
|
|
{
|
2016-02-17 00:25:09 +00:00
|
|
|
UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
|
|
|
if (!arena) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
|
2016-02-17 00:25:09 +00:00
|
|
|
UniqueCERTUserNotice notice(CERT_DecodeUserNotice(derNotice));
|
2012-10-17 20:48:36 +00:00
|
|
|
if (!notice) {
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessRawBytes(derNotice, text);
|
2016-02-17 00:25:09 +00:00
|
|
|
return NS_OK;
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (notice->noticeReference.organization.len != 0) {
|
2007-12-14 16:11:57 +00:00
|
|
|
switch (notice->noticeReference.organization.type) {
|
2017-01-31 21:23:55 +00:00
|
|
|
case siAsciiString:
|
|
|
|
case siVisibleString:
|
|
|
|
case siUTF8String:
|
|
|
|
text.Append(NS_ConvertUTF8toUTF16(
|
|
|
|
(const char*)notice->noticeReference.organization.data,
|
|
|
|
notice->noticeReference.organization.len));
|
|
|
|
break;
|
|
|
|
case siBMPString:
|
|
|
|
AppendBMPtoUTF16(arena,
|
|
|
|
notice->noticeReference.organization.data,
|
|
|
|
notice->noticeReference.organization.len,
|
|
|
|
text);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2007-12-14 16:11:57 +00:00
|
|
|
}
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(" - ");
|
2016-02-17 00:25:09 +00:00
|
|
|
SECItem** itemList = notice->noticeReference.noticeNumbers;
|
2005-12-25 21:09:45 +00:00
|
|
|
while (*itemList) {
|
|
|
|
unsigned long number;
|
|
|
|
char buffer[60];
|
2007-12-14 16:11:57 +00:00
|
|
|
if (SEC_ASN1DecodeInteger(*itemList, &number) == SECSuccess) {
|
2016-08-15 06:44:00 +00:00
|
|
|
SprintfLiteral(buffer, "#%lu", number);
|
2007-12-14 16:11:57 +00:00
|
|
|
if (itemList != notice->noticeReference.noticeNumbers)
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(", ");
|
2007-12-14 16:11:57 +00:00
|
|
|
AppendASCIItoUTF16(buffer, text);
|
2005-12-02 22:29:14 +00:00
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
itemList++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (notice->displayText.len != 0) {
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(SEPARATOR);
|
|
|
|
text.AppendLiteral(" ");
|
2007-12-14 16:11:57 +00:00
|
|
|
switch (notice->displayText.type) {
|
2017-01-31 21:23:55 +00:00
|
|
|
case siAsciiString:
|
|
|
|
case siVisibleString:
|
|
|
|
case siUTF8String:
|
|
|
|
text.Append(NS_ConvertUTF8toUTF16((const char*)notice->displayText.data,
|
|
|
|
notice->displayText.len));
|
|
|
|
break;
|
|
|
|
case siBMPString:
|
|
|
|
AppendBMPtoUTF16(
|
|
|
|
arena, notice->displayText.data, notice->displayText.len, text);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
}
|
2016-02-17 00:25:09 +00:00
|
|
|
|
2007-12-14 16:11:57 +00:00
|
|
|
return NS_OK;
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
2005-12-02 22:29:14 +00:00
|
|
|
|
2005-12-25 21:09:45 +00:00
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessCertificatePolicies(SECItem* extData, nsAString& text)
|
2005-12-25 21:09:45 +00:00
|
|
|
{
|
|
|
|
CERTPolicyInfo **policyInfos, *policyInfo;
|
|
|
|
CERTPolicyQualifier **policyQualifiers, *policyQualifier;
|
|
|
|
nsAutoString local;
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
2016-02-17 00:25:09 +00:00
|
|
|
UniqueCERTCertificatePolicies policies(
|
|
|
|
CERT_DecodeCertificatePoliciesExtension(extData));
|
|
|
|
if (!policies) {
|
2005-12-25 21:09:45 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2016-02-17 00:25:09 +00:00
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
|
|
|
|
policyInfos = policies->policyInfos;
|
2012-10-17 20:48:36 +00:00
|
|
|
while (*policyInfos) {
|
2005-12-25 21:09:45 +00:00
|
|
|
policyInfo = *policyInfos++;
|
|
|
|
switch (policyInfo->oid) {
|
2017-01-31 21:23:55 +00:00
|
|
|
case SEC_OID_VERISIGN_USER_NOTICES:
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpVerisignNotices", local);
|
2017-01-31 21:23:55 +00:00
|
|
|
text.Append(local);
|
|
|
|
break;
|
|
|
|
default:
|
2017-01-31 22:08:56 +00:00
|
|
|
GetDefaultOIDFormat(&policyInfo->policyID, local, '.');
|
2017-01-31 21:23:55 +00:00
|
|
|
text.Append(local);
|
2005-12-02 22:29:14 +00:00
|
|
|
}
|
2007-10-23 18:30:16 +00:00
|
|
|
|
2005-12-25 21:09:45 +00:00
|
|
|
if (policyInfo->policyQualifiers) {
|
|
|
|
/* Add all qualifiers on separate lines, indented */
|
|
|
|
policyQualifiers = policyInfo->policyQualifiers;
|
bug 1313491 - include more context when determining EV status r=Cykesiopka,jcj,mgoodwin
When doing TLS session resumption, the AuthCertificate hook is bypassed, which
means that the front-end doesn't know whether or not to show the EV indicator.
To deal with this, the platform attempts an EV verification. Before this patch,
this verification lacked much of the original context (e.g. stapled OCSP
responses, SCTs, the hostname, and in particular the first-party origin key).
Furthermore, it was unclear from a code architecture standpoint that a full
verification was even occurring. This patch brings the necessary context to the
verification and makes it much more clear that it is happening. It also takes
the opportunity to remove some unnecessary EV-related fields and information in
code and data structures that don't require it.
MozReview-Commit-ID: LTmZU4Z1YXL
--HG--
extra : rebase_source : 7db702f2037fae83c87fbb6aca75b4420544dff9
2016-11-01 00:02:57 +00:00
|
|
|
text.Append(':');
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(SEPARATOR);
|
2012-10-17 20:48:36 +00:00
|
|
|
while (*policyQualifiers) {
|
2017-01-31 21:23:55 +00:00
|
|
|
text.AppendLiteral(" ");
|
|
|
|
policyQualifier = *policyQualifiers++;
|
|
|
|
switch (policyQualifier->oid) {
|
|
|
|
case SEC_OID_PKIX_CPS_POINTER_QUALIFIER:
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpCPSPointer", local);
|
2017-01-31 21:23:55 +00:00
|
|
|
text.Append(local);
|
|
|
|
text.Append(':');
|
|
|
|
text.AppendLiteral(SEPARATOR);
|
|
|
|
text.AppendLiteral(" ");
|
|
|
|
/* The CPS pointer ought to be the cPSuri alternative
|
|
|
|
of the Qualifier choice. */
|
|
|
|
rv = ProcessIA5String(policyQualifier->qualifierValue, text);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SEC_OID_PKIX_USER_NOTICE_QUALIFIER:
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpUserNotice", local);
|
2017-01-31 21:23:55 +00:00
|
|
|
text.Append(local);
|
|
|
|
text.AppendLiteral(": ");
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessUserNotice(&policyQualifier->qualifierValue, text);
|
2017-01-31 21:23:55 +00:00
|
|
|
break;
|
|
|
|
default:
|
2017-01-31 22:08:56 +00:00
|
|
|
GetDefaultOIDFormat(&policyQualifier->qualifierID, local, '.');
|
2017-01-31 21:23:55 +00:00
|
|
|
text.Append(local);
|
|
|
|
text.AppendLiteral(": ");
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessRawBytes(&policyQualifier->qualifierValue, text);
|
2017-01-31 21:23:55 +00:00
|
|
|
}
|
|
|
|
text.AppendLiteral(SEPARATOR);
|
2005-12-25 21:09:45 +00:00
|
|
|
} /* while policyQualifiers */
|
2017-01-31 21:23:55 +00:00
|
|
|
} /* if policyQualifiers */
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(SEPARATOR);
|
2005-12-02 22:29:14 +00:00
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessCrlDistPoints(SECItem* extData, nsAString& text)
|
2005-12-25 21:09:45 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsAutoString local;
|
|
|
|
|
2016-02-17 00:25:09 +00:00
|
|
|
UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
|
|
|
if (!arena) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
|
2016-02-17 00:25:09 +00:00
|
|
|
CERTCrlDistributionPoints* crldp =
|
|
|
|
CERT_DecodeCRLDistributionPoints(arena.get(), extData);
|
2005-12-25 21:09:45 +00:00
|
|
|
if (!crldp || !crldp->distPoints) {
|
2016-02-17 00:25:09 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
|
2016-02-17 00:25:09 +00:00
|
|
|
for (CRLDistributionPoint** points = crldp->distPoints; *points; points++) {
|
|
|
|
CRLDistributionPoint* point = *points;
|
2005-12-25 21:09:45 +00:00
|
|
|
switch (point->distPointType) {
|
2017-01-31 21:23:55 +00:00
|
|
|
case generalName:
|
|
|
|
rv = ProcessGeneralName(
|
2017-01-31 22:08:56 +00:00
|
|
|
arena, point->distPoint.fullName, text);
|
2017-01-31 21:23:55 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case relativeDistinguishedName:
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessRDN(&point->distPoint.relativeName, text);
|
2017-01-31 21:23:55 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
break;
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
2017-01-31 21:23:55 +00:00
|
|
|
if (point->reasons.len) {
|
2016-02-17 00:25:09 +00:00
|
|
|
int reasons = point->reasons.data[0];
|
2014-05-22 03:48:50 +00:00
|
|
|
text.Append(' ');
|
2016-02-17 00:25:09 +00:00
|
|
|
bool comma = false;
|
2005-12-25 21:09:45 +00:00
|
|
|
if (reasons & RF_UNUSED) {
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpUnused", local);
|
2016-02-17 00:25:09 +00:00
|
|
|
text.Append(local);
|
|
|
|
comma = true;
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
if (reasons & RF_KEY_COMPROMISE) {
|
2017-01-31 21:23:55 +00:00
|
|
|
if (comma)
|
|
|
|
text.AppendLiteral(", ");
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpKeyCompromise", local);
|
2016-02-17 00:25:09 +00:00
|
|
|
text.Append(local);
|
|
|
|
comma = true;
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
if (reasons & RF_CA_COMPROMISE) {
|
2017-01-31 21:23:55 +00:00
|
|
|
if (comma)
|
|
|
|
text.AppendLiteral(", ");
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpCACompromise", local);
|
2016-02-17 00:25:09 +00:00
|
|
|
text.Append(local);
|
|
|
|
comma = true;
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
if (reasons & RF_AFFILIATION_CHANGED) {
|
2017-01-31 21:23:55 +00:00
|
|
|
if (comma)
|
|
|
|
text.AppendLiteral(", ");
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpAffiliationChanged", local);
|
2016-02-17 00:25:09 +00:00
|
|
|
text.Append(local);
|
|
|
|
comma = true;
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
if (reasons & RF_SUPERSEDED) {
|
2017-01-31 21:23:55 +00:00
|
|
|
if (comma)
|
|
|
|
text.AppendLiteral(", ");
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpSuperseded", local);
|
2016-02-17 00:25:09 +00:00
|
|
|
text.Append(local);
|
|
|
|
comma = true;
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
if (reasons & RF_CESSATION_OF_OPERATION) {
|
2017-01-31 21:23:55 +00:00
|
|
|
if (comma)
|
|
|
|
text.AppendLiteral(", ");
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpCessation", local);
|
2016-02-17 00:25:09 +00:00
|
|
|
text.Append(local);
|
|
|
|
comma = true;
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
if (reasons & RF_CERTIFICATE_HOLD) {
|
2017-01-31 21:23:55 +00:00
|
|
|
if (comma)
|
|
|
|
text.AppendLiteral(", ");
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpHold", local);
|
2016-02-17 00:25:09 +00:00
|
|
|
text.Append(local);
|
|
|
|
comma = true;
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(SEPARATOR);
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
if (point->crlIssuer) {
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpIssuer", local);
|
2005-12-25 21:09:45 +00:00
|
|
|
text.Append(local);
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(": ");
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessGeneralNames(arena, point->crlIssuer, text);
|
2016-02-17 00:25:09 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
}
|
2016-02-17 00:25:09 +00:00
|
|
|
|
2005-12-25 21:09:45 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessAuthInfoAccess(SECItem* extData, nsAString& text)
|
2005-12-25 21:09:45 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsAutoString local;
|
|
|
|
|
2016-02-17 00:25:09 +00:00
|
|
|
UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
|
|
|
if (!arena) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
|
2017-01-31 21:23:55 +00:00
|
|
|
CERTAuthInfoAccess** aia =
|
|
|
|
CERT_DecodeAuthInfoAccessExtension(arena.get(), extData);
|
2016-02-17 00:25:09 +00:00
|
|
|
if (!aia) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
|
2012-10-17 20:48:36 +00:00
|
|
|
while (*aia) {
|
2016-02-17 00:25:09 +00:00
|
|
|
CERTAuthInfoAccess* desc = *aia++;
|
2005-12-25 21:09:45 +00:00
|
|
|
switch (SECOID_FindOIDTag(&desc->method)) {
|
2017-01-31 21:23:55 +00:00
|
|
|
case SEC_OID_PKIX_OCSP:
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpOCSPResponder", local);
|
2017-01-31 21:23:55 +00:00
|
|
|
break;
|
|
|
|
case SEC_OID_PKIX_CA_ISSUERS:
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpCAIssuers", local);
|
2017-01-31 21:23:55 +00:00
|
|
|
break;
|
|
|
|
default:
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = GetDefaultOIDFormat(&desc->method, local, '.');
|
2017-01-31 21:23:55 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
text.Append(local);
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(": ");
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessGeneralName(arena, desc->location, text);
|
2016-02-17 00:25:09 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessMSCAVersion(SECItem* extData, nsAString& text)
|
2005-12-25 21:09:45 +00:00
|
|
|
{
|
2016-06-22 22:56:11 +00:00
|
|
|
MOZ_ASSERT(extData);
|
|
|
|
NS_ENSURE_ARG(extData);
|
2006-02-20 13:20:47 +00:00
|
|
|
|
2016-06-22 22:56:11 +00:00
|
|
|
ScopedAutoSECItem decoded;
|
2017-01-31 21:23:55 +00:00
|
|
|
if (SEC_ASN1DecodeItem(
|
|
|
|
nullptr, &decoded, SEC_ASN1_GET(SEC_IntegerTemplate), extData) !=
|
|
|
|
SECSuccess) {
|
2006-02-20 13:20:47 +00:00
|
|
|
/* This extension used to be an Integer when this code
|
|
|
|
was written, but apparently isn't anymore. Display
|
|
|
|
the raw bytes instead. */
|
2017-01-31 22:08:56 +00:00
|
|
|
return ProcessRawBytes(extData, text);
|
2016-06-22 22:56:11 +00:00
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
|
2016-06-22 22:56:11 +00:00
|
|
|
unsigned long version;
|
|
|
|
if (SEC_ASN1DecodeInteger(&decoded, &version) != SECSuccess) {
|
2006-02-20 13:20:47 +00:00
|
|
|
/* Value out of range, display raw bytes */
|
2017-01-31 22:08:56 +00:00
|
|
|
return ProcessRawBytes(extData, text);
|
2016-06-22 22:56:11 +00:00
|
|
|
}
|
2005-12-25 21:09:45 +00:00
|
|
|
|
2006-02-20 13:20:47 +00:00
|
|
|
/* Apparently, the encoding is <minor><major>, with 16 bits each */
|
2016-06-22 22:56:11 +00:00
|
|
|
char buf[50];
|
2016-08-15 06:44:00 +00:00
|
|
|
if (SprintfLiteral(buf, "%lu.%lu", version & 0xFFFF, version >> 16) <= 0) {
|
2016-06-22 22:56:11 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2005-12-25 21:09:45 +00:00
|
|
|
text.AppendASCII(buf);
|
2004-04-18 21:20:31 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2004-02-26 04:07:23 +00:00
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessExtensionData(SECOidTag oidTag, SECItem* extData, nsAString& text)
|
2002-09-17 18:51:22 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
switch (oidTag) {
|
2017-01-31 21:23:55 +00:00
|
|
|
case SEC_OID_X509_KEY_USAGE:
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessKeyUsageExtension(extData, text);
|
2005-12-25 21:09:45 +00:00
|
|
|
break;
|
2017-01-31 21:23:55 +00:00
|
|
|
case SEC_OID_X509_BASIC_CONSTRAINTS:
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessBasicConstraints(extData, text);
|
2017-01-31 21:23:55 +00:00
|
|
|
break;
|
|
|
|
case SEC_OID_X509_EXT_KEY_USAGE:
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessExtKeyUsage(extData, text);
|
2017-01-31 21:23:55 +00:00
|
|
|
break;
|
|
|
|
case SEC_OID_X509_ISSUER_ALT_NAME:
|
|
|
|
case SEC_OID_X509_SUBJECT_ALT_NAME:
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessAltName(extData, text);
|
2017-01-31 21:23:55 +00:00
|
|
|
break;
|
|
|
|
case SEC_OID_X509_SUBJECT_KEY_ID:
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessSubjectKeyId(extData, text);
|
2017-01-31 21:23:55 +00:00
|
|
|
break;
|
|
|
|
case SEC_OID_X509_AUTH_KEY_ID:
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessAuthKeyId(extData, text);
|
2017-01-31 21:23:55 +00:00
|
|
|
break;
|
|
|
|
case SEC_OID_X509_CERTIFICATE_POLICIES:
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessCertificatePolicies(extData, text);
|
2017-01-31 21:23:55 +00:00
|
|
|
break;
|
|
|
|
case SEC_OID_X509_CRL_DIST_POINTS:
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessCrlDistPoints(extData, text);
|
2017-01-31 21:23:55 +00:00
|
|
|
break;
|
|
|
|
case SEC_OID_X509_AUTH_INFO_ACCESS:
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessAuthInfoAccess(extData, text);
|
2017-01-31 21:23:55 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (oidTag == SEC_OID(MS_CERT_EXT_CERTTYPE)) {
|
|
|
|
rv = ProcessBMPString(extData, text);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (oidTag == SEC_OID(MS_CERTSERV_CA_VERSION)) {
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessMSCAVersion(extData, text);
|
2017-01-31 21:23:55 +00:00
|
|
|
break;
|
|
|
|
}
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessRawBytes(extData, text);
|
2005-12-25 21:09:45 +00:00
|
|
|
break;
|
2002-09-17 18:51:22 +00:00
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2004-04-18 21:20:31 +00:00
|
|
|
static nsresult
|
2017-01-31 21:23:55 +00:00
|
|
|
ProcessSingleExtension(CERTCertExtension* extension,
|
|
|
|
nsIASN1PrintableItem** retExtension)
|
2002-09-17 18:51:22 +00:00
|
|
|
{
|
2006-11-02 22:48:32 +00:00
|
|
|
nsAutoString text, extvalue;
|
2017-01-31 22:08:56 +00:00
|
|
|
GetOIDText(&extension->id, text);
|
2017-01-31 21:23:55 +00:00
|
|
|
nsCOMPtr<nsIASN1PrintableItem> extensionItem = new nsNSSASN1PrintableItem();
|
2002-09-17 18:51:22 +00:00
|
|
|
|
2002-09-23 20:17:16 +00:00
|
|
|
extensionItem->SetDisplayName(text);
|
2002-09-17 18:51:22 +00:00
|
|
|
SECOidTag oidTag = SECOID_FindOIDTag(&extension->id);
|
|
|
|
text.Truncate();
|
2012-10-17 20:48:36 +00:00
|
|
|
if (extension->critical.data) {
|
2002-09-17 18:51:22 +00:00
|
|
|
if (extension->critical.data[0]) {
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpCritical", text);
|
2002-09-17 18:51:22 +00:00
|
|
|
} else {
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpNonCritical", text);
|
2002-09-17 18:51:22 +00:00
|
|
|
}
|
|
|
|
} else {
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpNonCritical", text);
|
2002-09-17 18:51:22 +00:00
|
|
|
}
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(SEPARATOR);
|
2017-01-31 21:23:55 +00:00
|
|
|
nsresult rv =
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessExtensionData(oidTag, &extension->value, extvalue);
|
2006-11-02 22:48:32 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
extvalue.Truncate();
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessRawBytes(&extension->value, extvalue, false);
|
2006-11-02 22:48:32 +00:00
|
|
|
}
|
|
|
|
text.Append(extvalue);
|
2002-09-17 18:51:22 +00:00
|
|
|
|
2002-09-23 20:17:16 +00:00
|
|
|
extensionItem->SetDisplayValue(text);
|
2015-07-01 17:10:53 +00:00
|
|
|
extensionItem.forget(retExtension);
|
2002-09-17 18:51:22 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2004-04-18 21:20:31 +00:00
|
|
|
static nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessSECAlgorithmID(SECAlgorithmID* algID, nsIASN1Sequence** retSequence)
|
2004-04-18 21:20:31 +00:00
|
|
|
{
|
2006-05-16 00:33:44 +00:00
|
|
|
SECOidTag algOIDTag = SECOID_FindOIDTag(&algID->algorithm);
|
2012-10-17 20:48:36 +00:00
|
|
|
SECItem paramsOID = { siBuffer, nullptr, 0 };
|
2004-04-18 21:20:31 +00:00
|
|
|
nsCOMPtr<nsIASN1Sequence> sequence = new nsNSSASN1Sequence();
|
|
|
|
|
2012-07-30 14:20:58 +00:00
|
|
|
*retSequence = nullptr;
|
2004-04-18 21:20:31 +00:00
|
|
|
nsString text;
|
2017-01-31 22:08:56 +00:00
|
|
|
GetOIDText(&algID->algorithm, text);
|
2017-01-31 21:23:55 +00:00
|
|
|
if (!algID->parameters.len ||
|
|
|
|
algID->parameters.data[0] == nsIASN1Object::ASN1_NULL) {
|
2004-04-18 21:20:31 +00:00
|
|
|
sequence->SetDisplayValue(text);
|
2011-10-17 14:59:28 +00:00
|
|
|
sequence->SetIsValidContainer(false);
|
2004-04-18 21:20:31 +00:00
|
|
|
} else {
|
|
|
|
nsCOMPtr<nsIASN1PrintableItem> printableItem = new nsNSSASN1PrintableItem();
|
2006-05-16 00:33:44 +00:00
|
|
|
|
2004-04-18 21:20:31 +00:00
|
|
|
printableItem->SetDisplayValue(text);
|
|
|
|
nsCOMPtr<nsIMutableArray> asn1Objects;
|
|
|
|
sequence->GetASN1Objects(getter_AddRefs(asn1Objects));
|
2011-10-17 14:59:28 +00:00
|
|
|
asn1Objects->AppendElement(printableItem, false);
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpAlgID", text);
|
2004-04-18 21:20:31 +00:00
|
|
|
printableItem->SetDisplayName(text);
|
2006-05-16 00:33:44 +00:00
|
|
|
|
2004-04-18 21:20:31 +00:00
|
|
|
printableItem = new nsNSSASN1PrintableItem();
|
2006-05-16 00:33:44 +00:00
|
|
|
|
2011-10-17 14:59:28 +00:00
|
|
|
asn1Objects->AppendElement(printableItem, false);
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpParams", text);
|
2006-05-16 00:33:44 +00:00
|
|
|
printableItem->SetDisplayName(text);
|
|
|
|
if ((algOIDTag == SEC_OID_ANSIX962_EC_PUBLIC_KEY) &&
|
2017-01-31 21:23:55 +00:00
|
|
|
(algID->parameters.len > 2) &&
|
2006-05-16 00:33:44 +00:00
|
|
|
(algID->parameters.data[0] == nsIASN1Object::ASN1_OBJECT_ID)) {
|
2017-01-31 21:23:55 +00:00
|
|
|
paramsOID.len = algID->parameters.len - 2;
|
|
|
|
paramsOID.data = algID->parameters.data + 2;
|
2017-01-31 22:08:56 +00:00
|
|
|
GetOIDText(¶msOID, text);
|
2006-05-16 00:33:44 +00:00
|
|
|
} else {
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessRawBytes(&algID->parameters, text);
|
2006-05-16 00:33:44 +00:00
|
|
|
}
|
2004-04-18 21:20:31 +00:00
|
|
|
printableItem->SetDisplayValue(text);
|
|
|
|
}
|
2015-07-01 17:10:53 +00:00
|
|
|
sequence.forget(retSequence);
|
2004-04-18 21:20:31 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
2017-01-31 21:23:55 +00:00
|
|
|
ProcessTime(PRTime dispTime,
|
|
|
|
const char16_t* displayName,
|
2015-09-13 21:33:00 +00:00
|
|
|
nsIASN1Sequence* parentSequence)
|
2004-04-18 21:20:31 +00:00
|
|
|
{
|
|
|
|
nsString text;
|
|
|
|
nsString tempString;
|
|
|
|
|
|
|
|
PRExplodedTime explodedTime;
|
|
|
|
PR_ExplodeTime(dispTime, PR_LocalTimeParameters, &explodedTime);
|
|
|
|
|
2017-01-31 21:23:55 +00:00
|
|
|
DateTimeFormat::FormatPRExplodedTime(
|
|
|
|
kDateFormatLong, kTimeFormatSeconds, &explodedTime, tempString);
|
2004-04-18 21:20:31 +00:00
|
|
|
|
|
|
|
text.Append(tempString);
|
2004-06-17 00:13:25 +00:00
|
|
|
text.AppendLiteral("\n(");
|
2004-04-18 21:20:31 +00:00
|
|
|
|
|
|
|
PRExplodedTime explodedTimeGMT;
|
|
|
|
PR_ExplodeTime(dispTime, PR_GMTParameters, &explodedTimeGMT);
|
|
|
|
|
2017-01-31 21:23:55 +00:00
|
|
|
DateTimeFormat::FormatPRExplodedTime(
|
|
|
|
kDateFormatLong, kTimeFormatSeconds, &explodedTimeGMT, tempString);
|
2004-04-18 21:20:31 +00:00
|
|
|
|
|
|
|
text.Append(tempString);
|
2014-05-22 03:48:50 +00:00
|
|
|
text.AppendLiteral(" GMT)");
|
2004-04-18 21:20:31 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIASN1PrintableItem> printableItem = new nsNSSASN1PrintableItem();
|
|
|
|
|
|
|
|
printableItem->SetDisplayValue(text);
|
|
|
|
printableItem->SetDisplayName(nsDependentString(displayName));
|
|
|
|
nsCOMPtr<nsIMutableArray> asn1Objects;
|
|
|
|
parentSequence->GetASN1Objects(getter_AddRefs(asn1Objects));
|
2011-10-17 14:59:28 +00:00
|
|
|
asn1Objects->AppendElement(printableItem, false);
|
2004-04-18 21:20:31 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
2017-01-31 21:23:55 +00:00
|
|
|
ProcessSubjectPublicKeyInfo(CERTSubjectPublicKeyInfo* spki,
|
2017-01-31 22:08:56 +00:00
|
|
|
nsIASN1Sequence* parentSequence)
|
2004-04-18 21:20:31 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIASN1Sequence> spkiSequence = new nsNSSASN1Sequence();
|
|
|
|
|
|
|
|
nsString text;
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpSPKI", text);
|
2004-04-18 21:20:31 +00:00
|
|
|
spkiSequence->SetDisplayName(text);
|
|
|
|
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpSPKIAlg", text);
|
2004-04-18 21:20:31 +00:00
|
|
|
nsCOMPtr<nsIASN1Sequence> sequenceItem;
|
2017-01-31 21:23:55 +00:00
|
|
|
nsresult rv = ProcessSECAlgorithmID(
|
2017-01-31 22:08:56 +00:00
|
|
|
&spki->algorithm, getter_AddRefs(sequenceItem));
|
2004-04-18 21:20:31 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
sequenceItem->SetDisplayName(text);
|
|
|
|
nsCOMPtr<nsIMutableArray> asn1Objects;
|
|
|
|
spkiSequence->GetASN1Objects(getter_AddRefs(asn1Objects));
|
2011-10-17 14:59:28 +00:00
|
|
|
asn1Objects->AppendElement(sequenceItem, false);
|
2004-04-18 21:20:31 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIASN1PrintableItem> printableItem = new nsNSSASN1PrintableItem();
|
|
|
|
|
2006-09-28 23:31:34 +00:00
|
|
|
text.Truncate();
|
2016-02-17 00:25:09 +00:00
|
|
|
|
|
|
|
UniqueSECKEYPublicKey key(SECKEY_ExtractPublicKey(spki));
|
2006-09-28 23:31:34 +00:00
|
|
|
bool displayed = false;
|
2012-10-17 20:48:36 +00:00
|
|
|
if (key) {
|
2017-01-31 21:23:55 +00:00
|
|
|
switch (key->keyType) {
|
2006-09-28 23:31:34 +00:00
|
|
|
case rsaKey: {
|
2017-01-31 21:23:55 +00:00
|
|
|
displayed = true;
|
|
|
|
nsAutoString length1, length2, data1, data2;
|
|
|
|
length1.AppendInt(key->u.rsa.modulus.len * 8);
|
|
|
|
length2.AppendInt(key->u.rsa.publicExponent.len * 8);
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessRawBytes(&key->u.rsa.modulus, data1, false);
|
|
|
|
ProcessRawBytes(&key->u.rsa.publicExponent, data2, false);
|
2017-01-31 21:23:55 +00:00
|
|
|
const char16_t* params[4] = {
|
|
|
|
length1.get(), data1.get(), length2.get(), data2.get()
|
|
|
|
};
|
2017-01-31 22:08:56 +00:00
|
|
|
PIPBundleFormatStringFromName("CertDumpRSATemplate", params, 4, text);
|
2017-01-31 21:23:55 +00:00
|
|
|
break;
|
2006-09-28 23:31:34 +00:00
|
|
|
}
|
2008-07-17 17:14:54 +00:00
|
|
|
case ecKey: {
|
|
|
|
displayed = true;
|
2017-01-31 21:23:55 +00:00
|
|
|
SECKEYECPublicKey& ecpk = key->u.ec;
|
|
|
|
int fieldSizeLenAsBits =
|
|
|
|
SECKEY_ECParamsToKeySize(&ecpk.DEREncodedParams);
|
|
|
|
int basePointOrderLenAsBits =
|
|
|
|
SECKEY_ECParamsToBasePointOrderLen(&ecpk.DEREncodedParams);
|
2008-07-17 17:14:54 +00:00
|
|
|
nsAutoString s_fsl, s_bpol, s_pv;
|
|
|
|
s_fsl.AppendInt(fieldSizeLenAsBits);
|
|
|
|
s_bpol.AppendInt(basePointOrderLenAsBits);
|
|
|
|
|
|
|
|
if (ecpk.publicValue.len > 4) {
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessRawBytes(&ecpk.publicValue, s_pv, false);
|
2008-07-17 17:14:54 +00:00
|
|
|
} else {
|
|
|
|
int i_pv = DER_GetInteger(&ecpk.publicValue);
|
|
|
|
s_pv.AppendInt(i_pv);
|
|
|
|
}
|
2017-01-31 21:23:55 +00:00
|
|
|
const char16_t* params[] = { s_fsl.get(), s_bpol.get(), s_pv.get() };
|
2017-01-31 22:08:56 +00:00
|
|
|
PIPBundleFormatStringFromName("CertDumpECTemplate", params, 3, text);
|
2008-07-17 17:14:54 +00:00
|
|
|
break;
|
|
|
|
}
|
2006-09-28 23:31:34 +00:00
|
|
|
default:
|
2017-01-31 21:23:55 +00:00
|
|
|
/* Algorithm unknown, or too rarely used to bother displaying it */
|
|
|
|
break;
|
|
|
|
}
|
2006-09-28 23:31:34 +00:00
|
|
|
}
|
|
|
|
if (!displayed) {
|
2017-01-31 21:23:55 +00:00
|
|
|
// Algorithm unknown, display raw bytes
|
|
|
|
// The subjectPublicKey field is encoded as a bit string.
|
|
|
|
// ProcessRawBytes expects the length to be in bytes, so
|
|
|
|
// let's convert the lenght into a temporary SECItem.
|
|
|
|
SECItem data;
|
|
|
|
data.data = spki->subjectPublicKey.data;
|
|
|
|
data.len = spki->subjectPublicKey.len / 8;
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessRawBytes(&data, text);
|
2017-01-31 21:23:55 +00:00
|
|
|
}
|
|
|
|
|
2004-04-18 21:20:31 +00:00
|
|
|
printableItem->SetDisplayValue(text);
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpSubjPubKey", text);
|
2004-04-18 21:20:31 +00:00
|
|
|
printableItem->SetDisplayName(text);
|
2011-10-17 14:59:28 +00:00
|
|
|
asn1Objects->AppendElement(printableItem, false);
|
2017-01-31 21:23:55 +00:00
|
|
|
|
2004-04-18 21:20:31 +00:00
|
|
|
parentSequence->GetASN1Objects(getter_AddRefs(asn1Objects));
|
2011-10-17 14:59:28 +00:00
|
|
|
asn1Objects->AppendElement(spkiSequence, false);
|
2004-04-18 21:20:31 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
2017-01-31 21:23:55 +00:00
|
|
|
ProcessExtensions(CERTCertExtension** extensions,
|
2017-01-31 22:08:56 +00:00
|
|
|
nsIASN1Sequence* parentSequence)
|
2004-04-18 21:20:31 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIASN1Sequence> extensionSequence = new nsNSSASN1Sequence;
|
|
|
|
|
|
|
|
nsString text;
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpExtensions", text);
|
2004-04-18 21:20:31 +00:00
|
|
|
extensionSequence->SetDisplayName(text);
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t i;
|
2004-04-18 21:20:31 +00:00
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIASN1PrintableItem> newExtension;
|
|
|
|
nsCOMPtr<nsIMutableArray> asn1Objects;
|
|
|
|
extensionSequence->GetASN1Objects(getter_AddRefs(asn1Objects));
|
2017-01-31 21:23:55 +00:00
|
|
|
for (i = 0; extensions[i] != nullptr; i++) {
|
|
|
|
rv = ProcessSingleExtension(
|
2017-01-31 22:08:56 +00:00
|
|
|
extensions[i], getter_AddRefs(newExtension));
|
2004-04-18 21:20:31 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2011-10-17 14:59:28 +00:00
|
|
|
asn1Objects->AppendElement(newExtension, false);
|
2004-04-18 21:20:31 +00:00
|
|
|
}
|
|
|
|
parentSequence->GetASN1Objects(getter_AddRefs(asn1Objects));
|
2011-10-17 14:59:28 +00:00
|
|
|
asn1Objects->AppendElement(extensionSequence, false);
|
2004-04-18 21:20:31 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-12-25 21:09:45 +00:00
|
|
|
static bool registered;
|
2017-01-31 21:23:55 +00:00
|
|
|
static SECStatus
|
|
|
|
RegisterDynamicOids()
|
2005-12-25 21:09:45 +00:00
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
SECStatus rv = SECSuccess;
|
|
|
|
|
|
|
|
if (registered)
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
for (i = 0; i < numOids; i++) {
|
|
|
|
SECOidTag tag = SECOID_AddEntry(&more_oids[i]);
|
|
|
|
if (tag == SEC_OID_UNKNOWN) {
|
|
|
|
rv = SECFailure;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
more_oids[i].offset = tag;
|
|
|
|
}
|
|
|
|
registered = true;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2004-04-18 21:20:31 +00:00
|
|
|
nsresult
|
2017-01-31 22:08:56 +00:00
|
|
|
nsNSSCertificate::CreateTBSCertificateASN1Struct(nsIASN1Sequence** retSequence)
|
2004-04-18 21:20:31 +00:00
|
|
|
{
|
|
|
|
nsNSSShutDownPreventionLock locker;
|
|
|
|
if (isAlreadyShutDown())
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
|
2005-12-25 21:09:45 +00:00
|
|
|
if (RegisterDynamicOids() != SECSuccess)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2004-04-18 21:20:31 +00:00
|
|
|
//
|
|
|
|
// TBSCertificate ::= SEQUENCE {
|
|
|
|
// version [0] EXPLICIT Version DEFAULT v1,
|
|
|
|
// serialNumber CertificateSerialNumber,
|
|
|
|
// signature AlgorithmIdentifier,
|
|
|
|
// issuer Name,
|
|
|
|
// validity Validity,
|
|
|
|
// subject Name,
|
|
|
|
// subjectPublicKeyInfo SubjectPublicKeyInfo,
|
|
|
|
// issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
|
|
|
|
// -- If present, version shall be v2 or v3
|
|
|
|
// subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
|
|
|
|
// -- If present, version shall be v2 or v3
|
|
|
|
// extensions [3] EXPLICIT Extensions OPTIONAL
|
|
|
|
// -- If present, version shall be v3
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// This is the ASN1 structure we should be dealing with at this point.
|
|
|
|
// The code in this method will assert this is the structure we're dealing
|
|
|
|
// and then add more user friendly text for that field.
|
|
|
|
nsCOMPtr<nsIASN1Sequence> sequence = new nsNSSASN1Sequence();
|
|
|
|
|
|
|
|
nsString text;
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpCertificate", text);
|
2004-04-18 21:20:31 +00:00
|
|
|
sequence->SetDisplayName(text);
|
|
|
|
nsCOMPtr<nsIASN1PrintableItem> printableItem;
|
2017-01-31 21:23:55 +00:00
|
|
|
|
2004-04-18 21:20:31 +00:00
|
|
|
nsCOMPtr<nsIMutableArray> asn1Objects;
|
|
|
|
sequence->GetASN1Objects(getter_AddRefs(asn1Objects));
|
|
|
|
|
2017-01-31 22:08:56 +00:00
|
|
|
nsresult rv = ProcessVersion(&mCert->version, getter_AddRefs(printableItem));
|
2004-04-18 21:20:31 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2011-10-17 14:59:28 +00:00
|
|
|
asn1Objects->AppendElement(printableItem, false);
|
2004-04-18 21:20:31 +00:00
|
|
|
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessSerialNumberDER(mCert->serialNumber, printableItem);
|
2004-04-18 21:20:31 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2011-10-17 14:59:28 +00:00
|
|
|
asn1Objects->AppendElement(printableItem, false);
|
2004-04-18 21:20:31 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIASN1Sequence> algID;
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessSECAlgorithmID(&mCert->signature, getter_AddRefs(algID));
|
2004-04-18 21:20:31 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpSigAlg", text);
|
2004-04-18 21:20:31 +00:00
|
|
|
algID->SetDisplayName(text);
|
2011-10-17 14:59:28 +00:00
|
|
|
asn1Objects->AppendElement(algID, false);
|
2004-04-18 21:20:31 +00:00
|
|
|
|
|
|
|
nsXPIDLString value;
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessName(&mCert->issuer, getter_Copies(value));
|
2004-04-18 21:20:31 +00:00
|
|
|
|
|
|
|
printableItem = new nsNSSASN1PrintableItem();
|
|
|
|
|
|
|
|
printableItem->SetDisplayValue(value);
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpIssuer", text);
|
2004-04-18 21:20:31 +00:00
|
|
|
printableItem->SetDisplayName(text);
|
2011-10-17 14:59:28 +00:00
|
|
|
asn1Objects->AppendElement(printableItem, false);
|
2017-01-31 21:23:55 +00:00
|
|
|
|
2004-04-18 21:20:31 +00:00
|
|
|
nsCOMPtr<nsIASN1Sequence> validitySequence = new nsNSSASN1Sequence();
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpValidity", text);
|
2004-04-18 21:20:31 +00:00
|
|
|
validitySequence->SetDisplayName(text);
|
2011-10-17 14:59:28 +00:00
|
|
|
asn1Objects->AppendElement(validitySequence, false);
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpNotBefore", text);
|
2004-04-18 21:20:31 +00:00
|
|
|
nsCOMPtr<nsIX509CertValidity> validityData;
|
|
|
|
GetValidity(getter_AddRefs(validityData));
|
|
|
|
PRTime notBefore, notAfter;
|
|
|
|
|
|
|
|
validityData->GetNotBefore(¬Before);
|
|
|
|
validityData->GetNotAfter(¬After);
|
2016-11-10 03:11:27 +00:00
|
|
|
validityData = nullptr;
|
2004-04-18 21:20:31 +00:00
|
|
|
rv = ProcessTime(notBefore, text.get(), validitySequence);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpNotAfter", text);
|
2004-04-18 21:20:31 +00:00
|
|
|
rv = ProcessTime(notAfter, text.get(), validitySequence);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpSubject", text);
|
2004-04-18 21:20:31 +00:00
|
|
|
|
|
|
|
printableItem = new nsNSSASN1PrintableItem();
|
|
|
|
|
|
|
|
printableItem->SetDisplayName(text);
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessName(&mCert->subject, getter_Copies(value));
|
2004-04-18 21:20:31 +00:00
|
|
|
printableItem->SetDisplayValue(value);
|
2011-10-17 14:59:28 +00:00
|
|
|
asn1Objects->AppendElement(printableItem, false);
|
2004-04-18 21:20:31 +00:00
|
|
|
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessSubjectPublicKeyInfo(&mCert->subjectPublicKeyInfo, sequence);
|
2004-04-18 21:20:31 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2017-01-31 21:23:55 +00:00
|
|
|
|
|
|
|
SECItem data;
|
2004-04-18 21:20:31 +00:00
|
|
|
// Is there an issuerUniqueID?
|
2012-10-17 20:48:36 +00:00
|
|
|
if (mCert->issuerID.data) {
|
2004-04-18 21:20:31 +00:00
|
|
|
// The issuerID is encoded as a bit string.
|
|
|
|
// The function ProcessRawBytes expects the
|
|
|
|
// length to be in bytes, so let's convert the
|
|
|
|
// length in a temporary SECItem
|
|
|
|
data.data = mCert->issuerID.data;
|
2017-01-31 21:23:55 +00:00
|
|
|
data.len = (mCert->issuerID.len + 7) / 8;
|
2004-04-18 21:20:31 +00:00
|
|
|
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessRawBytes(&data, text);
|
2004-04-18 21:20:31 +00:00
|
|
|
printableItem = new nsNSSASN1PrintableItem();
|
|
|
|
|
|
|
|
printableItem->SetDisplayValue(text);
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpIssuerUniqueID", text);
|
2004-04-18 21:20:31 +00:00
|
|
|
printableItem->SetDisplayName(text);
|
2011-10-17 14:59:28 +00:00
|
|
|
asn1Objects->AppendElement(printableItem, false);
|
2004-04-18 21:20:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (mCert->subjectID.data) {
|
|
|
|
// The subjectID is encoded as a bit string.
|
|
|
|
// The function ProcessRawBytes expects the
|
|
|
|
// length to be in bytes, so let's convert the
|
|
|
|
// length in a temporary SECItem
|
2012-03-08 23:48:44 +00:00
|
|
|
data.data = mCert->subjectID.data;
|
2017-01-31 21:23:55 +00:00
|
|
|
data.len = (mCert->subjectID.len + 7) / 8;
|
2004-04-18 21:20:31 +00:00
|
|
|
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessRawBytes(&data, text);
|
2004-04-18 21:20:31 +00:00
|
|
|
printableItem = new nsNSSASN1PrintableItem();
|
|
|
|
|
|
|
|
printableItem->SetDisplayValue(text);
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpSubjectUniqueID", text);
|
2004-04-18 21:20:31 +00:00
|
|
|
printableItem->SetDisplayName(text);
|
2011-10-17 14:59:28 +00:00
|
|
|
asn1Objects->AppendElement(printableItem, false);
|
2004-04-18 21:20:31 +00:00
|
|
|
}
|
|
|
|
if (mCert->extensions) {
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = ProcessExtensions(mCert->extensions, sequence);
|
2004-04-18 21:20:31 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
}
|
2015-07-01 17:10:53 +00:00
|
|
|
sequence.forget(retSequence);
|
2004-04-18 21:20:31 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2013-07-29 16:46:52 +00:00
|
|
|
nsNSSCertificate::CreateASN1Struct(nsIASN1Object** aRetVal)
|
2004-04-18 21:20:31 +00:00
|
|
|
{
|
|
|
|
nsNSSShutDownPreventionLock locker;
|
|
|
|
if (isAlreadyShutDown())
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIASN1Sequence> sequence = new nsNSSASN1Sequence();
|
|
|
|
|
|
|
|
nsCOMPtr<nsIMutableArray> asn1Objects;
|
|
|
|
sequence->GetASN1Objects(getter_AddRefs(asn1Objects));
|
2014-06-01 11:59:00 +00:00
|
|
|
|
2016-11-18 19:18:23 +00:00
|
|
|
nsAutoString displayName;
|
|
|
|
nsresult rv = GetDisplayName(displayName);
|
2014-06-01 11:59:00 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2016-11-18 19:18:23 +00:00
|
|
|
rv = sequence->SetDisplayName(displayName);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
2014-03-15 19:00:15 +00:00
|
|
|
sequence.forget(aRetVal);
|
2013-07-29 16:46:52 +00:00
|
|
|
|
2004-04-18 21:20:31 +00:00
|
|
|
// This sequence will be contain the tbsCertificate, signatureAlgorithm,
|
|
|
|
// and signatureValue.
|
2017-01-31 22:08:56 +00:00
|
|
|
rv = CreateTBSCertificateASN1Struct(getter_AddRefs(sequence));
|
2004-04-18 21:20:31 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2011-10-17 14:59:28 +00:00
|
|
|
asn1Objects->AppendElement(sequence, false);
|
2004-04-18 21:20:31 +00:00
|
|
|
nsCOMPtr<nsIASN1Sequence> algID;
|
|
|
|
|
2017-01-31 21:23:55 +00:00
|
|
|
rv = ProcessSECAlgorithmID(&mCert->signatureWrap.signatureAlgorithm,
|
|
|
|
getter_AddRefs(algID));
|
2004-04-18 21:20:31 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
nsString text;
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpSigAlg", text);
|
2004-04-18 21:20:31 +00:00
|
|
|
algID->SetDisplayName(text);
|
2011-10-17 14:59:28 +00:00
|
|
|
asn1Objects->AppendElement(algID, false);
|
2017-01-31 21:23:55 +00:00
|
|
|
nsCOMPtr<nsIASN1PrintableItem> printableItem = new nsNSSASN1PrintableItem();
|
2017-01-31 22:08:56 +00:00
|
|
|
GetPIPNSSBundleString("CertDumpCertSig", text);
|
2004-04-18 21:20:31 +00:00
|
|
|
printableItem->SetDisplayName(text);
|
|
|
|
// The signatureWrap is encoded as a bit string.
|
|
|
|
// The function ProcessRawBytes expects the
|
|
|
|
// length to be in bytes, so let's convert the
|
|
|
|
// length in a temporary SECItem
|
|
|
|
SECItem temp;
|
|
|
|
temp.data = mCert->signatureWrap.signature.data;
|
2017-01-31 21:23:55 +00:00
|
|
|
temp.len = mCert->signatureWrap.signature.len / 8;
|
2004-04-18 21:20:31 +00:00
|
|
|
text.Truncate();
|
2017-01-31 22:08:56 +00:00
|
|
|
ProcessRawBytes(&temp, text);
|
2004-04-18 21:20:31 +00:00
|
|
|
printableItem->SetDisplayValue(text);
|
2011-10-17 14:59:28 +00:00
|
|
|
asn1Objects->AppendElement(printableItem, false);
|
2004-04-18 21:20:31 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2017-01-31 21:23:55 +00:00
|
|
|
uint32_t
|
|
|
|
getCertType(CERTCertificate* cert)
|
2002-09-17 18:51:22 +00:00
|
|
|
{
|
|
|
|
nsNSSCertTrust trust(cert->trust);
|
2004-03-10 07:36:50 +00:00
|
|
|
if (cert->nickname && trust.HasAnyUser())
|
|
|
|
return nsIX509Cert::USER_CERT;
|
2004-04-11 21:03:05 +00:00
|
|
|
if (trust.HasAnyCA())
|
2004-03-10 07:36:50 +00:00
|
|
|
return nsIX509Cert::CA_CERT;
|
2011-10-17 14:59:28 +00:00
|
|
|
if (trust.HasPeer(true, false, false))
|
2004-03-10 07:36:50 +00:00
|
|
|
return nsIX509Cert::SERVER_CERT;
|
2011-10-17 14:59:28 +00:00
|
|
|
if (trust.HasPeer(false, true, false) && cert->emailAddr)
|
2004-04-11 21:03:05 +00:00
|
|
|
return nsIX509Cert::EMAIL_CERT;
|
2012-10-17 20:48:36 +00:00
|
|
|
if (CERT_IsCACert(cert, nullptr))
|
2004-04-11 21:03:05 +00:00
|
|
|
return nsIX509Cert::CA_CERT;
|
2004-03-10 07:36:50 +00:00
|
|
|
if (cert->emailAddr)
|
2002-09-17 18:51:22 +00:00
|
|
|
return nsIX509Cert::EMAIL_CERT;
|
2007-01-06 16:36:19 +00:00
|
|
|
return nsIX509Cert::UNKNOWN_CERT;
|
2002-09-17 18:51:22 +00:00
|
|
|
}
|
2005-12-02 23:08:44 +00:00
|
|
|
|
2013-04-30 23:21:25 +00:00
|
|
|
nsresult
|
|
|
|
GetCertFingerprintByOidTag(CERTCertificate* nsscert,
|
2017-01-31 21:23:55 +00:00
|
|
|
SECOidTag aOidTag,
|
|
|
|
nsCString& fp)
|
2013-04-30 23:21:25 +00:00
|
|
|
{
|
|
|
|
Digest digest;
|
2017-01-31 21:23:55 +00:00
|
|
|
nsresult rv =
|
|
|
|
digest.DigestBuf(aOidTag, nsscert->derCert.data, nsscert->derCert.len);
|
2013-04-30 23:21:25 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2016-04-09 08:03:59 +00:00
|
|
|
UniquePORTString tmpstr(CERT_Hexify(const_cast<SECItem*>(&digest.get()), 1));
|
2013-04-30 23:21:25 +00:00
|
|
|
NS_ENSURE_TRUE(tmpstr, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
2016-04-09 08:03:59 +00:00
|
|
|
fp.Assign(tmpstr.get());
|
2013-04-30 23:21:25 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|