diff --git a/security/nss/cmd/lib/secutil.c b/security/nss/cmd/lib/secutil.c index a87289ae80b7..4fda3703b228 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"); /* } */ + if (type == SEC_ASN1_SET) + label = "Set "; + else if (type = SEC_ASN1_SEQUENCE) + label = "Sequence "; + else + label = ""; + fprintf(out,"%s{\n", label); /* } */ - 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; + while (my.len >= 2) { + SECItem tmp = my; - if (bp[1] & 0x80) { - lenlen = bp[1] & 0x1f; - len = 0; + 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: "); + 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; } - 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;