summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornelsonb%netscape.com <devnull@localhost>2003-11-04 02:16:42 +0000
committernelsonb%netscape.com <devnull@localhost>2003-11-04 02:16:42 +0000
commitfade9a586f36b702b6e719bac911d7a49df827e3 (patch)
tree9ec63d4cd9b5c793dcf1f35e232accf5fc30bcde
parentc164d6b6aa5fdff7fea15f7c1fc178427c131608 (diff)
downloadnss-hg-fade9a586f36b702b6e719bac911d7a49df827e3.tar.gz
Fix numerous errors (mostly off-by-1 errors) in the code that formats
and prints certs and CRLs. This code is common to certutil and pp. Bug 222568 r=nicholson (for this portion).
-rw-r--r--security/nss/cmd/lib/secutil.c479
1 files changed, 289 insertions, 190 deletions
diff --git a/security/nss/cmd/lib/secutil.c b/security/nss/cmd/lib/secutil.c
index a87289ae8..4fda3703b 100644
--- a/security/nss/cmd/lib/secutil.c
+++ b/security/nss/cmd/lib/secutil.c
@@ -84,6 +84,7 @@ static char consoleName[] = {
#endif
};
+
char *
SECU_GetString(int16 error_number)
{
@@ -645,6 +646,7 @@ SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii)
*trailer = '\0';
} else {
fprintf(stderr, "input has header but no trailer\n");
+ PORT_Free(filedata.data);
return SECFailure;
}
} else {
@@ -656,9 +658,11 @@ SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii)
if (rv) {
fprintf(stderr, "error converting ascii to binary (%s)\n",
SECU_Strerror(PORT_GetError()));
+ PORT_Free(filedata.data);
return SECFailure;
}
PORT_Free(asc);
+ PORT_Free(filedata.data);
} else {
/* Read in binary der */
rv = SECU_FileToItem(der, inFile);
@@ -692,6 +696,7 @@ SECU_PrintAsHex(FILE *out, SECItem *data, const char *m, int level)
unsigned i;
int column;
PRBool isString = PR_TRUE;
+ unsigned int limit = 15;
if ( m ) {
SECU_Indent(out, level); fprintf(out, "%s:\n", m);
@@ -699,12 +704,19 @@ SECU_PrintAsHex(FILE *out, SECItem *data, const char *m, int level)
}
SECU_Indent(out, level); column = level*INDENT_MULT;
+ /* take a pass to see if it's all printable. */
for (i = 0; i < data->len; i++) {
unsigned char val = data->data[i];
-
- if (isString && val && !isprint(val)) {
+ if (!val || !isprint(val)) {
isString = PR_FALSE;
+ break;
}
+ }
+
+ if (!isString)
+ for (i = 0; i < data->len; i++) {
+ unsigned char val = data->data[i];
+
if (i != data->len - 1) {
fprintf(out, "%02x:", data->data[i]);
column += 3;
@@ -713,14 +725,13 @@ SECU_PrintAsHex(FILE *out, SECItem *data, const char *m, int level)
column += 2;
break;
}
- if (column > 76 || (i % 16 == 15)) {
+ if (column > 76 || (i % 16 == limit)) {
secu_Newline(out);
- SECU_Indent(out, level); column = level*INDENT_MULT;
+ SECU_Indent(out, level);
+ column = level*INDENT_MULT;
+ limit = i % 16;
}
- }
- if (isString) {
- secu_Newline(out);
- SECU_Indent(out, level); column = level*INDENT_MULT;
+ } else {
for (i = 0; i < data->len; i++) {
unsigned char val = data->data[i];
@@ -737,7 +748,6 @@ SECU_PrintAsHex(FILE *out, SECItem *data, const char *m, int level)
}
}
- level--;
if (column != level*INDENT_MULT) {
secu_Newline(out);
}
@@ -796,6 +806,28 @@ SECU_PrintBuf(FILE *out, const char *msg, const void *vp, int len)
}
}
+SECStatus
+SECU_StripTagAndLength(SECItem *i)
+{
+ unsigned int start;
+
+ if (!i || !i->data || i->len < 2) { /* must be at least tag and length */
+ return SECFailure;
+ }
+ start = ((i->data[1] & 0x80) ? (i->data[1] & 0x7f) + 2 : 2);
+ if (i->len < start) {
+ return SECFailure;
+ }
+ i->data += start;
+ i->len -= start;
+ return SECSuccess;
+}
+
+
+/* This expents i->data[0] to be the MSB of the integer.
+** if you want to print a DER-encoded integer (with the tag and length)
+** call SECU_PrintEncodedInteger();
+*/
void
SECU_PrintInteger(FILE *out, SECItem *i, char *m, int level)
{
@@ -821,53 +853,61 @@ SECU_PrintInteger(FILE *out, SECItem *i, char *m, int level)
}
}
-void
-SECU_PrintString(FILE *out, SECItem *i, char *m, int level)
+static void
+secu_PrintRawString(FILE *out, SECItem *si, char *m, int level)
{
- char *string;
- unsigned char *data = i->data;
- int len = i->len;
- int lenlen;
- int tag;
+ int column;
+ unsigned int i;
- string = PORT_ZAlloc(i->len+1);
-
- tag = *data++; len--;
- if (data[1] & 0x80) {
- lenlen = data[1] & 0x1f;
- } else {
- lenlen = 1;
+ if ( m ) {
+ SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ level++;
}
- data += lenlen; len -= lenlen;
- if (len <= 0) return;
- PORT_Memcpy(string,data,len);
+
+ SECU_Indent(out, level); column = level*INDENT_MULT;
+ fprintf(out, "\""); column++;
- /* should check the validity of tag, and convert the string as necessary */
- SECU_Indent(out, level);
- if (m) {
- fprintf(out, "%s: \"%s\"\n", m, string);
- } else {
- fprintf(out, "\"%s\"\n", string);
+ for (i = 0; i < si->len; i++) {
+ unsigned char val = si->data[i];
+ if (column > 76) {
+ secu_Newline(out);
+ SECU_Indent(out, level); column = level*INDENT_MULT;
+ }
+
+ fprintf(out,"%c", printable[val]); column++;
}
+
+ fprintf(out, "\""); column++;
+ if (column != level*INDENT_MULT || column > 76) {
+ secu_Newline(out);
+ }
+}
+
+void
+SECU_PrintString(FILE *out, SECItem *si, char *m, int level)
+{
+ SECItem my = *si;
+
+ if (SECSuccess != SECU_StripTagAndLength(&my) || !my.len)
+ return;
+ secu_PrintRawString(out, &my, m, level);
}
+/* print an unencoded boolean */
static void
-secu_PrintBoolean(FILE *out, SECItem *i, char *m, int level)
+secu_PrintBoolean(FILE *out, SECItem *i, const char *m, int level)
{
int val = 0;
- if ( i->data ) {
+ if ( i->data && i->len ) {
val = i->data[0];
}
- if (m) {
- SECU_Indent(out, level); fprintf(out, "%s:\n", m); level++;
+ if (!m) {
+ m = "Boolean";
}
- if ( val ) {
- SECU_Indent(out, level); fprintf(out, "%s\n", "True");
- } else {
- SECU_Indent(out, level); fprintf(out, "%s\n", "False");
- }
+ SECU_Indent(out, level);
+ fprintf(out, "%s: %s\n", m, (val ? "True" : "False"));
}
/*
@@ -964,100 +1004,112 @@ SECU_PrintTimeChoice(FILE *out, SECItem *t, char *m, int level)
static void secu_PrintAny(FILE *out, SECItem *i, char *m, int level);
+/* This prints a SET or SEQUENCE */
void
SECU_PrintSet(FILE *out, SECItem *t, char *m, int level)
{
- int type= t->data[0] & SEC_ASN1_TAGNUM_MASK;
- int start;
- unsigned char *bp;
+ int type = t->data[0] & SEC_ASN1_TAGNUM_MASK;
+ int constructed = t->data[0] & SEC_ASN1_CONSTRUCTED;
+ const char * label;
+ SECItem my = *t;
+
+ if (!constructed) {
+ SECU_PrintAsHex(out, t, m, level);
+ return;
+ }
+ if (SECSuccess != SECU_StripTagAndLength(&my))
+ return;
SECU_Indent(out, level);
if (m) {
fprintf(out, "%s: ", m);
}
- fprintf(out,"%s {\n", type == SEC_ASN1_SET ? "Set" : "Sequence"); /* } */
-
- start = 2;
- if (t->data[1] & 0x80) {
- start += (t->data[1] & 0x7f);
- }
- for (bp=&t->data[start]; bp < &t->data[t->len]; ) {
- SECItem tmp;
- unsigned int i,len,lenlen;
-
- if (bp[1] & 0x80) {
- lenlen = bp[1] & 0x1f;
- len = 0;
+ if (type == SEC_ASN1_SET)
+ label = "Set ";
+ else if (type = SEC_ASN1_SEQUENCE)
+ label = "Sequence ";
+ else
+ label = "";
+ fprintf(out,"%s{\n", label); /* } */
+
+ while (my.len >= 2) {
+ SECItem tmp = my;
+
+ if (tmp.data[1] & 0x80) {
+ unsigned int i;
+ unsigned int lenlen = tmp.data[1] & 0x7f;
+ if (lenlen > sizeof tmp.len)
+ break;
+ tmp.len = 0;
for (i=0; i < lenlen; i++) {
- len = len * 255 + bp[2+i];
+ tmp.len = (tmp.len << 8) | tmp.data[2+i];
}
+ tmp.len += lenlen + 2;
} else {
- lenlen = 1;
- len = bp[1];
+ tmp.len = tmp.data[1] + 2;
}
- tmp.len = len+lenlen+1;
- if (tmp.len > &t->data[t->len] - bp) {
- tmp.len = &t->data[t->len] - bp;
+ if (tmp.len > my.len) {
+ tmp.len = my.len;
}
- tmp.data = bp;
- bp += tmp.len;
- secu_PrintAny(out,&tmp,NULL,level+1);
+ my.data += tmp.len;
+ my.len -= tmp.len;
+ secu_PrintAny(out, &tmp, NULL, level + 1);
}
- /* { */SECU_Indent(out, level); fprintf(out, "}\n");
+ SECU_Indent(out, level); fprintf(out, /* { */ "}\n");
}
static void
secu_PrintContextSpecific(FILE *out, SECItem *i, char *m, int level)
{
- int type= i->data[0] & SEC_ASN1_TAGNUM_MASK;
+ int type = i->data[0] & SEC_ASN1_TAGNUM_MASK;
+ int constructed = i->data[0] & SEC_ASN1_CONSTRUCTED;
SECItem tmp;
- int start;
+
+ if (constructed) {
+ char * m2;
+ if (!m)
+ m2 = PR_smprintf("[%d]", type);
+ else
+ m2 = PR_smprintf("%s: [%d]", m, type);
+ if (m2) {
+ SECU_PrintSet(out, i, m2, level);
+ PR_smprintf_free(m2);
+ }
+ return;
+ }
SECU_Indent(out, level);
if (m) {
fprintf(out, "%s: ", m);
}
-
fprintf(out,"[%d]\n", type);
- start = 2;
- if (i->data[1] & 0x80) {
- start = (i->data[1] & 0x7f) +1;
- }
- tmp.data = &i->data[start];
- tmp.len = i->len -start;
- SECU_PrintAsHex(out, &tmp, m, level+1);
+
+ tmp = *i;
+ if (SECSuccess == SECU_StripTagAndLength(&tmp))
+ SECU_PrintAsHex(out, &tmp, m, level+1);
}
static void
secu_PrintOctetString(FILE *out, SECItem *i, char *m, int level)
{
- SECItem tmp;
- int start;
-
- start = 2;
- if (i->data[1] & 0x80) {
- start = (i->data[1] & 0x7f) +1;
- }
- tmp.data = &i->data[start];
- tmp.len = i->len - start;
- SECU_PrintAsHex(out, &tmp, m, level);
+ SECItem tmp = *i;
+ if (SECSuccess == SECU_StripTagAndLength(&tmp))
+ SECU_PrintAsHex(out, &tmp, m, level);
}
static void
secu_PrintBitString(FILE *out, SECItem *i, char *m, int level)
{
- SECItem tmp;
- int start;
int unused_bits;
+ SECItem tmp = *i;
+
+ if (SECSuccess != SECU_StripTagAndLength(&tmp) || tmp.len < 2)
+ return;
+
+ unused_bits = *tmp.data++;
+ tmp.len--;
- start = 2;
- if (i->data[1] & 0x80) {
- start = (i->data[1] & 0x7f) + 1;
- }
- unused_bits = i->data[start++];
- tmp.data = &i->data[start];
- tmp.len = i->len - start;
SECU_PrintAsHex(out, &tmp, m, level);
if (unused_bits) {
SECU_Indent(out, level + 1);
@@ -1065,26 +1117,52 @@ secu_PrintBitString(FILE *out, SECItem *i, char *m, int level)
}
}
+/* Print a DER encoded Boolean */
+void
+SECU_PrintEncodedBoolean(FILE *out, SECItem *i, char *m, int level)
+{
+ SECItem my = *i;
+ if (SECSuccess == SECU_StripTagAndLength(&my))
+ secu_PrintBoolean(out, &my, m, level);
+}
+
+/* Print a DER encoded integer */
+void
+SECU_PrintEncodedInteger(FILE *out, SECItem *i, char *m, int level)
+{
+ SECItem my = *i;
+ if (SECSuccess == SECU_StripTagAndLength(&my))
+ SECU_PrintInteger(out, &my, m, level);
+}
+
+/* Print a DER encoded OID */
+void
+SECU_PrintEncodedObjectID(FILE *out, SECItem *i, char *m, int level)
+{
+ SECItem my = *i;
+ if (SECSuccess == SECU_StripTagAndLength(&my))
+ SECU_PrintObjectID(out, &my, m, level);
+}
+
static void
secu_PrintUniversal(FILE *out, SECItem *i, char *m, int level)
{
switch (i->data[0] & SEC_ASN1_TAGNUM_MASK) {
+ case SEC_ASN1_ENUMERATED:
case SEC_ASN1_INTEGER:
- SECU_PrintInteger(out, i, m, level);
+ SECU_PrintEncodedInteger(out, i, m, level);
break;
case SEC_ASN1_OBJECT_ID:
- SECU_PrintObjectID(out, i, m, level);
+ SECU_PrintEncodedObjectID(out, i, m, level);
break;
case SEC_ASN1_BOOLEAN:
- secu_PrintBoolean(out, i, m, level);
+ SECU_PrintEncodedBoolean(out, i, m, level);
break;
case SEC_ASN1_UTF8_STRING:
case SEC_ASN1_PRINTABLE_STRING:
case SEC_ASN1_VISIBLE_STRING:
- case SEC_ASN1_BMP_STRING:
case SEC_ASN1_IA5_STRING:
case SEC_ASN1_T61_STRING:
- case SEC_ASN1_UNIVERSAL_STRING:
SECU_PrintString(out, i, m, level);
break;
case SEC_ASN1_GENERALIZED_TIME:
@@ -1106,6 +1184,8 @@ secu_PrintUniversal(FILE *out, SECItem *i, char *m, int level)
case SEC_ASN1_BIT_STRING:
secu_PrintBitString(out, i, m, level);
break;
+ case SEC_ASN1_BMP_STRING:
+ case SEC_ASN1_UNIVERSAL_STRING:
default:
SECU_PrintAsHex(out, i, m, level);
break;
@@ -1134,30 +1214,41 @@ static int
secu_PrintValidity(FILE *out, CERTValidity *v, char *m, int level)
{
SECU_Indent(out, level); fprintf(out, "%s:\n", m);
- SECU_PrintUTCTime(out, &v->notBefore, "Not Before", level+1);
- SECU_PrintUTCTime(out, &v->notAfter, "Not After", level+1);
+ SECU_PrintTimeChoice(out, &v->notBefore, "Not Before", level+1);
+ SECU_PrintTimeChoice(out, &v->notAfter, "Not After ", level+1);
return 0;
}
+/* This function does NOT expect a DER type and length. */
void
SECU_PrintObjectID(FILE *out, SECItem *oid, char *m, int level)
{
- const char *name;
SECOidData *oiddata;
+ char * oidString = NULL;
oiddata = SECOID_FindOID(oid);
- if (oiddata == NULL) {
- SECU_PrintAsHex(out, oid, m, level);
+ if (oiddata != NULL) {
+ const char *name = oiddata->desc;
+ SECU_Indent(out, level);
+ if (m != NULL)
+ fprintf(out, "%s: ", m);
+ fprintf(out, "%s\n", name);
+ return;
+ }
+ oidString = CERT_GetOidString(oid);
+ if (oidString) {
+ SECU_Indent(out, level);
+ if (m != NULL)
+ fprintf(out, "%s: ", m);
+ fprintf(out, "%s\n", oidString);
+ PR_smprintf_free(oidString);
return;
}
- name = oiddata->desc;
-
- SECU_Indent(out, level);
- if (m != NULL)
- fprintf(out, "%s: ", m);
- fprintf(out, "%s\n", name);
+ SECU_PrintAsHex(out, oid, m, level);
}
+
+/* This function does NOT expect a DER type and length. */
void
SECU_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, char *m, int level)
{
@@ -1204,7 +1295,7 @@ secu_PrintAttribute(FILE *out, SEC_PKCS7Attribute *attr, char *m, int level)
SECU_PrintObjectID(out, value, om, level+1);
break;
case SEC_OID_PKCS9_SIGNING_TIME:
- SECU_PrintUTCTime(out, value, om, level+1);
+ SECU_PrintTimeChoice(out, value, om, level+1);
break;
}
}
@@ -1331,34 +1422,21 @@ secu_PrintX509InvalidDate(FILE *out, SECItem *value, char *msg, int level)
static SECStatus
PrintExtKeyUsageExten (FILE *out, SECItem *value, char *msg, int level)
{
- CERTOidSequence *os;
- SECItem **op;
+ CERTOidSequence *os;
+ SECItem **op;
- SECU_Indent(out, level); fprintf(out, "Extended Key Usage Extension:\n");
+ SECU_Indent(out, level); fprintf(out, "Extended Key Usage Extension:\n");
- os = CERT_DecodeOidSequence(value);
- if( (CERTOidSequence *)NULL == os ) {
- return SECFailure;
- }
-
- for( op = os->oids; *op; op++ ) {
- SECOidData *od = SECOID_FindOID(*op);
-
- if( (SECOidData *)NULL == od ) {
- SECU_Indent(out, level+1);
- SECU_PrintAsHex(out, *op, "Unknown:", level+2);
- secu_Newline(out);
- continue;
+ os = CERT_DecodeOidSequence(value);
+ if( (CERTOidSequence *)NULL == os ) {
+ return SECFailure;
}
- SECU_Indent(out, level+1);
- if( od->desc ) fprintf(out, "%s", od->desc);
- else SECU_PrintAsHex(out, &od->oid, "", level+2);
-
- secu_Newline(out);
- }
-
- return SECSuccess;
+ for( op = os->oids; *op; op++ ) {
+ SECU_PrintObjectID(out, *op, msg, level + 1);
+ }
+ CERT_DestroyOidSequence(os);
+ return SECSuccess;
}
char *
@@ -1405,7 +1483,8 @@ secu_PrintPolicyQualifier(FILE *out,CERTPolicyQualifier *policyQualifier,char *m
/* fall through on error */
case SEC_OID_PKIX_CPS_POINTER_QUALIFIER:
default:
- secu_PrintAny(out, &policyQualifier->qualifierValue, "Policy Qualifier Data", level+1);
+ secu_PrintAny(out, &policyQualifier->qualifierValue,
+ "Policy Qualifier Data", level+1);
break;
}
@@ -1478,38 +1557,40 @@ secu_PrintBasicConstraints(FILE *out, SECItem *value, char *msg, int level) {
return SECSuccess;
}
+/* NSCertType is merely a bit string whose bits are displayed symbolically */
static SECStatus
-secu_PrintNSCertType(FILE *out, SECItem *value, char *msg, int level) {
- char NS_Type=0;
- int len, i, found=0;
+secu_PrintNSCertType(FILE *out, SECItem *value, char *msg, int level)
+{
+ int unused;
+ int NS_Type;
+ int i;
+ int found = 0;
+ SECItem my = *value;
- if (value->data[1] & 0x80) {
- len = 3;
- } else {
- len = value->data[1];
- }
- if ((value->data[0] != SEC_ASN1_BIT_STRING) || (len < 2)) {
- secu_PrintAny(out, value, "Data", level);
- return SECSuccess;
- }
- NS_Type=value->data[3];
+ if ((my.data[0] != SEC_ASN1_BIT_STRING) ||
+ SECSuccess != SECU_StripTagAndLength(&my)) {
+ secu_PrintAny(out, value, "Data", level);
+ return SECSuccess;
+ }
+
+ unused = (my.len == 2) ? (my.data[0] & 0x0f) : 0;
+ NS_Type = my.data[1] & (0xff << unused);
- if (msg) {
- SECU_Indent(out, level);
- fprintf(out,"%s: ",msg);
- } else {
- SECU_Indent(out, level);
- fprintf(out,"Netscape Certificate Type: ");
- }
- for (i=0; i < 8; i++) {
- if ( (0x80 >> i) & NS_Type) {
- fprintf(out,"%c%s",found?',':'<',nsTypeBits[i]);
- found = 1;
- }
+ SECU_Indent(out, level);
+ if (msg) {
+ fprintf(out,"%s: ",msg);
+ } else {
+ fprintf(out,"Netscape Certificate Type: ");
+ }
+ for (i=0; i < 8; i++) {
+ if ( (0x80 >> i) & NS_Type) {
+ fprintf(out, "%c%s", (found ? ',' : '<'), nsTypeBits[i]);
+ found = 1;
}
- if (found) { fprintf(out,">\n"); } else { fprintf(out,"none\n"); }
- return SECSuccess;
+ }
+ fprintf(out, (found ? ">\n" : "none\n"));
+ return SECSuccess;
}
void
@@ -1523,10 +1604,9 @@ SECU_PrintExtensions(FILE *out, CERTCertExtension **extensions,
while ( *extensions ) {
SECItem *tmpitem;
- SECU_Indent(out, level+1); fprintf(out, "Name:\n");
tmpitem = &(*extensions)->id;
- SECU_PrintObjectID(out, tmpitem, NULL, level+2);
+ SECU_PrintObjectID(out, tmpitem, "Name", level+1);
tmpitem = &(*extensions)->critical;
if ( tmpitem->len ) {
@@ -1570,7 +1650,7 @@ SECU_PrintExtensions(FILE *out, CERTCertExtension **extensions,
break;
case SEC_OID_X509_EXT_KEY_USAGE:
- PrintExtKeyUsageExten(out, tmpitem, "", level+1);
+ PrintExtKeyUsageExten(out, tmpitem, NULL, level+1);
break;
case SEC_OID_X509_AUTH_INFO_ACCESS:
@@ -1625,7 +1705,7 @@ SECU_PrintExtensions(FILE *out, CERTCertExtension **extensions,
default:
- secu_PrintAny(out, tmpitem, "Data", level+1);
+ secu_PrintAny(out, tmpitem, "Data", level+1);
break;
}
@@ -1640,15 +1720,21 @@ void
SECU_PrintName(FILE *out, CERTName *name, char *msg, int level)
{
char *str;
-
- SECU_Indent(out, level); fprintf(out, "%s: ", msg);
+ SECItem my;
str = CERT_NameToAscii(name);
if (!str)
str = "!Invalid AVA!";
+ my.data = (unsigned char *)str;
+ my.len = PORT_Strlen(str);
+#if 1
+ secu_PrintRawString(out, &my, msg, level);
+#else
+ SECU_Indent(out, level); fprintf(out, "%s: ", msg);
fprintf(out, str);
-
secu_Newline(out);
+#endif
+ PORT_Free(str);
}
void
@@ -1694,13 +1780,13 @@ SECU_PrintCertNickname(CERTCertListNode *node, void *data)
out = (FILE *)data;
name = node->appData;
- if ( name == NULL) {
+ if (!name || !name[0]) {
name = cert->nickname;
}
- if ( name == NULL ) {
+ if (!name || !name[0]) {
name = cert->emailAddr;
}
- if ( name == NULL ) {
+ if (!name || !name[0]) {
name = "(NULL)";
}
@@ -1851,10 +1937,13 @@ SECU_PrintFingerprints(FILE *out, SECItem *derCert, char *m, int level)
{
unsigned char fingerprint[20];
char *fpStr = NULL;
+ int err = PORT_GetError();
+ SECStatus rv;
SECItem fpItem;
+
/* print MD5 fingerprint */
memset(fingerprint, 0, sizeof fingerprint);
- PK11_HashBuf(SEC_OID_MD5,fingerprint, derCert->data, derCert->len);
+ rv = PK11_HashBuf(SEC_OID_MD5,fingerprint, derCert->data, derCert->len);
fpItem.data = fingerprint;
fpItem.len = MD5_LENGTH;
fpStr = CERT_Hexify(&fpItem, 1);
@@ -1862,9 +1951,12 @@ SECU_PrintFingerprints(FILE *out, SECItem *derCert, char *m, int level)
SECU_Indent(out, level+1); fprintf(out, "%s\n", fpStr);
PORT_Free(fpStr);
fpStr = NULL;
+ if (rv != SECSuccess && !err)
+ err = PORT_GetError();
+
/* print SHA1 fingerprint */
memset(fingerprint, 0, sizeof fingerprint);
- PK11_HashBuf(SEC_OID_SHA1,fingerprint, derCert->data, derCert->len);
+ rv = PK11_HashBuf(SEC_OID_SHA1,fingerprint, derCert->data, derCert->len);
fpItem.data = fingerprint;
fpItem.len = SHA1_LENGTH;
fpStr = CERT_Hexify(&fpItem, 1);
@@ -1872,6 +1964,12 @@ SECU_PrintFingerprints(FILE *out, SECItem *derCert, char *m, int level)
SECU_Indent(out, level+1); fprintf(out, "%s\n", fpStr);
PORT_Free(fpStr);
fprintf(out, "\n");
+
+ if (err)
+ PORT_SetError(err);
+ if (err || rv != SECSuccess)
+ return SECFailure;
+
return 0;
}
@@ -1989,11 +2087,15 @@ SECU_PrintCRLInfo(FILE *out, CERTCrl *crl, char *m, int level)
char om[100];
SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+ /* version is optional */
+ iv = crl->version.len ? DER_GetInteger(&crl->version) : 0;
+ SECU_Indent(out, level+1);
+ fprintf(out, "%s: %d (0x%x)\n", "Version", iv + 1, iv);
SECU_PrintAlgorithmID(out, &(crl->signatureAlg), "Signature Algorithm",
level + 1);
- SECU_PrintName(out, &(crl->name), "Name", level + 1);
- SECU_PrintUTCTime(out, &(crl->lastUpdate), "Last Update", level + 1);
- SECU_PrintUTCTime(out, &(crl->nextUpdate), "Next Update", level + 1);
+ SECU_PrintName(out, &(crl->name), "Issuer", level + 1);
+ SECU_PrintTimeChoice(out, &(crl->lastUpdate), "This Update", level + 1);
+ SECU_PrintTimeChoice(out, &(crl->nextUpdate), "Next Update", level + 1);
if (crl->entries != NULL) {
iv = 0;
@@ -2002,14 +2104,13 @@ SECU_PrintCRLInfo(FILE *out, CERTCrl *crl, char *m, int level)
SECU_Indent(out, level + 1); fprintf(out, om);
SECU_PrintInteger(out, &(entry->serialNumber), "Serial Number",
level + 2);
- SECU_PrintUTCTime(out, &(entry->revocationDate), "Revocation Date",
- level + 2);
- SECU_PrintExtensions
- (out, entry->extensions, "Signed CRL Entries Extensions", level + 1);
+ SECU_PrintTimeChoice(out, &(entry->revocationDate),
+ "Revocation Date", level + 2);
+ SECU_PrintExtensions(out, entry->extensions,
+ "Entry Extensions", level + 2);
}
}
- SECU_PrintExtensions
- (out, crl->extensions, "Signed CRL Extension", level + 1);
+ SECU_PrintExtensions(out, crl->extensions, "CRL Extensions", level + 1);
}
/*
@@ -2428,16 +2529,14 @@ int SECU_PrintSignedData(FILE *out, SECItem *der, char *m,
SECU_Indent(out, level); fprintf(out, "%s:\n", m);
rv = (*inner)(out, &sd->data, "Data", level+1);
- if (rv)
- goto loser;
SECU_PrintAlgorithmID(out, &sd->signatureAlgorithm, "Signature Algorithm",
level+1);
DER_ConvertBitString(&sd->signature);
SECU_PrintAsHex(out, &sd->signature, "Signature", level+1);
+ SECU_PrintFingerprints(out, der, "Fingerprint", level+1);
loser:
PORT_FreeArena(arena, PR_FALSE);
- SECU_PrintFingerprints(out, der, "Fingerprint", level+1);
return rv;
}
@@ -2682,7 +2781,7 @@ bestCertName(CERTCertificate *cert) {
if (cert->nickname) {
return cert->nickname;
}
- if (cert->emailAddr) {
+ if (cert->emailAddr && cert->emailAddr[0]) {
return cert->emailAddr;
}
return cert->subjectName;