зеркало из https://github.com/mozilla/gecko-dev.git
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).
This commit is contained in:
Родитель
0fc82ad629
Коммит
0feb5dfd5f
|
@ -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 (!val || !isprint(val)) {
|
||||
isString = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isString)
|
||||
for (i = 0; i < data->len; i++) {
|
||||
unsigned char val = data->data[i];
|
||||
|
||||
if (isString && val && !isprint(val)) {
|
||||
isString = PR_FALSE;
|
||||
}
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
SECU_Indent(out, level); column = level*INDENT_MULT;
|
||||
fprintf(out, "\""); column++;
|
||||
|
||||
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 ( val ) {
|
||||
SECU_Indent(out, level); fprintf(out, "%s\n", "True");
|
||||
} else {
|
||||
SECU_Indent(out, level); fprintf(out, "%s\n", "False");
|
||||
if (!m) {
|
||||
m = "Boolean";
|
||||
}
|
||||
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;
|
||||
|
||||
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;
|
||||
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);
|
||||
return;
|
||||
}
|
||||
name = oiddata->desc;
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -1342,22 +1433,9 @@ PrintExtKeyUsageExten (FILE *out, SECItem *value, char *msg, int level)
|
|||
}
|
||||
|
||||
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;
|
||||
SECU_PrintObjectID(out, *op, msg, level + 1);
|
||||
}
|
||||
|
||||
SECU_Indent(out, level+1);
|
||||
if( od->desc ) fprintf(out, "%s", od->desc);
|
||||
else SECU_PrintAsHex(out, &od->oid, "", level+2);
|
||||
|
||||
secu_Newline(out);
|
||||
}
|
||||
|
||||
CERT_DestroyOidSequence(os);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
@ -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,37 +1557,39 @@ 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)) {
|
||||
if ((my.data[0] != SEC_ASN1_BIT_STRING) ||
|
||||
SECSuccess != SECU_StripTagAndLength(&my)) {
|
||||
secu_PrintAny(out, value, "Data", level);
|
||||
return SECSuccess;
|
||||
}
|
||||
NS_Type=value->data[3];
|
||||
|
||||
unused = (my.len == 2) ? (my.data[0] & 0x0f) : 0;
|
||||
NS_Type = my.data[1] & (0xff << unused);
|
||||
|
||||
|
||||
if (msg) {
|
||||
SECU_Indent(out, level);
|
||||
if (msg) {
|
||||
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]);
|
||||
fprintf(out, "%c%s", (found ? ',' : '<'), nsTypeBits[i]);
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
if (found) { fprintf(out,">\n"); } else { fprintf(out,"none\n"); }
|
||||
fprintf(out, (found ? ">\n" : "none\n"));
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче