diff options
Diffstat (limited to 'nss/cmd/lib/derprint.c')
-rw-r--r-- | nss/cmd/lib/derprint.c | 588 |
1 files changed, 296 insertions, 292 deletions
diff --git a/nss/cmd/lib/derprint.c b/nss/cmd/lib/derprint.c index 75811df..08ef66d 100644 --- a/nss/cmd/lib/derprint.c +++ b/nss/cmd/lib/derprint.c @@ -5,11 +5,11 @@ #include "secoid.h" #ifdef __sun -extern int fprintf(FILE *strm, const char *format, .../* args */); +extern int fprintf(FILE *strm, const char *format, ... /* args */); extern int fflush(FILE *stream); #endif -#define RIGHT_MARGIN 24 +#define RIGHT_MARGIN 24 /*#define RAW_BYTES 1 */ static int prettyColumn = 0; @@ -20,21 +20,28 @@ getInteger256(const unsigned char *data, unsigned int nb) int val; switch (nb) { - case 1: - val = data[0]; - break; - case 2: - val = (data[0] << 8) | data[1]; - break; - case 3: - val = (data[0] << 16) | (data[1] << 8) | data[2]; - break; - case 4: - val = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; - break; - default: - PORT_SetError(SEC_ERROR_BAD_DER); - return -1; + case 1: + val = data[0]; + break; + case 2: + val = (data[0] << 8) | data[1]; + break; + case 3: + val = (data[0] << 16) | (data[1] << 8) | data[2]; + break; + case 4: + /* If the most significant bit of data[0] is 1, val would be negative. + * Treat it as an error. + */ + if (data[0] & 0x80) { + PORT_SetError(SEC_ERROR_BAD_DER); + return -1; + } + val = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; + break; + default: + PORT_SetError(SEC_ERROR_BAD_DER); + return -1; } return val; @@ -46,12 +53,12 @@ prettyNewline(FILE *out) int rv; if (prettyColumn != -1) { - rv = fprintf(out, "\n"); - prettyColumn = -1; - if (rv < 0) { - PORT_SetError(SEC_ERROR_IO); - return rv; - } + rv = fprintf(out, "\n"); + prettyColumn = -1; + if (rv < 0) { + PORT_SetError(SEC_ERROR_IO); + return rv; + } } return 0; } @@ -63,14 +70,14 @@ prettyIndent(FILE *out, unsigned level) int rv; if (prettyColumn == -1) { - prettyColumn = level; - for (i = 0; i < level; i++) { - rv = fprintf(out, " "); - if (rv < 0) { - PORT_SetError(SEC_ERROR_IO); - return rv; - } - } + prettyColumn = level; + for (i = 0; i < level; i++) { + rv = fprintf(out, " "); + if (rv < 0) { + PORT_SetError(SEC_ERROR_IO); + return rv; + } + } } return 0; @@ -83,17 +90,17 @@ prettyPrintByte(FILE *out, unsigned char item, unsigned int level) rv = prettyIndent(out, level); if (rv < 0) - return rv; + return rv; rv = fprintf(out, "%02x ", item); if (rv < 0) { - PORT_SetError(SEC_ERROR_IO); - return rv; + PORT_SetError(SEC_ERROR_IO); + return rv; } prettyColumn++; if (prettyColumn >= RIGHT_MARGIN) { - return prettyNewline(out); + return prettyNewline(out); } return 0; @@ -101,45 +108,45 @@ prettyPrintByte(FILE *out, unsigned char item, unsigned int level) static int prettyPrintLeaf(FILE *out, const unsigned char *data, - unsigned int len, unsigned int lv) + unsigned int len, unsigned int lv) { unsigned int i; int rv; for (i = 0; i < len; i++) { - rv = prettyPrintByte(out, *data++, lv); - if (rv < 0) - return rv; + rv = prettyPrintByte(out, *data++, lv); + if (rv < 0) + return rv; } return prettyNewline(out); } static int prettyPrintStringStart(FILE *out, const unsigned char *str, - unsigned int len, unsigned int level) + unsigned int len, unsigned int level) { #define BUF_SIZE 100 unsigned char buf[BUF_SIZE]; int rv; if (len >= BUF_SIZE) - len = BUF_SIZE - 1; + len = BUF_SIZE - 1; rv = prettyNewline(out); if (rv < 0) - return rv; + return rv; rv = prettyIndent(out, level); if (rv < 0) - return rv; + return rv; memcpy(buf, str, len); buf[len] = '\000'; rv = fprintf(out, "\"%s\"", buf); if (rv < 0) { - PORT_SetError(SEC_ERROR_IO); - return rv; + PORT_SetError(SEC_ERROR_IO); + return rv; } return 0; @@ -148,22 +155,22 @@ prettyPrintStringStart(FILE *out, const unsigned char *str, static int prettyPrintString(FILE *out, const unsigned char *str, - unsigned int len, unsigned int level, PRBool raw) + unsigned int len, unsigned int level, PRBool raw) { int rv; rv = prettyPrintStringStart(out, str, len, level); if (rv < 0) - return rv; + return rv; rv = prettyNewline(out); if (rv < 0) - return rv; + return rv; if (raw) { - rv = prettyPrintLeaf(out, str, len, level); - if (rv < 0) - return rv; + rv = prettyPrintLeaf(out, str, len, level); + if (rv < 0) + return rv; } return 0; @@ -171,43 +178,43 @@ prettyPrintString(FILE *out, const unsigned char *str, static int prettyPrintTime(FILE *out, const unsigned char *str, - unsigned int len, unsigned int level, PRBool raw, PRBool utc) + unsigned int len, unsigned int level, PRBool raw, PRBool utc) { SECItem time_item; int rv; rv = prettyPrintStringStart(out, str, len, level); if (rv < 0) - return rv; + return rv; time_item.data = (unsigned char *)str; time_item.len = len; rv = fprintf(out, " ("); if (rv < 0) { - PORT_SetError(SEC_ERROR_IO); - return rv; + PORT_SetError(SEC_ERROR_IO); + return rv; } if (utc) - SECU_PrintUTCTime(out, &time_item, NULL, 0); + SECU_PrintUTCTime(out, &time_item, NULL, 0); else - SECU_PrintGeneralizedTime(out, &time_item, NULL, 0); + SECU_PrintGeneralizedTime(out, &time_item, NULL, 0); rv = fprintf(out, ")"); if (rv < 0) { - PORT_SetError(SEC_ERROR_IO); - return rv; + PORT_SetError(SEC_ERROR_IO); + return rv; } rv = prettyNewline(out); if (rv < 0) - return rv; + return rv; if (raw) { - rv = prettyPrintLeaf(out, str, len, level); - if (rv < 0) - return rv; + rv = prettyPrintLeaf(out, str, len, level); + if (rv < 0) + return rv; } return 0; @@ -215,7 +222,7 @@ prettyPrintTime(FILE *out, const unsigned char *str, static int prettyPrintObjectID(FILE *out, const unsigned char *data, - unsigned int len, unsigned int level, PRBool raw) + unsigned int len, unsigned int level, PRBool raw) { SECOidData *oiddata; SECItem oiditem; @@ -223,38 +230,41 @@ prettyPrintObjectID(FILE *out, const unsigned char *data, unsigned long val; int rv; - /* * First print the Object Id in numeric format */ rv = prettyIndent(out, level); if (rv < 0) - return rv; + return rv; + if (len == 0) { + PORT_SetError(SEC_ERROR_BAD_DER); + return -1; + } val = data[0]; - i = val % 40; + i = val % 40; val = val / 40; rv = fprintf(out, "%lu %u ", val, i); if (rv < 0) { - PORT_SetError(SEC_ERROR_IO); - return rv; + PORT_SetError(SEC_ERROR_IO); + return rv; } val = 0; for (i = 1; i < len; ++i) { unsigned long j; - j = data[i]; - val = (val << 7) | (j & 0x7f); - if (j & 0x80) - continue; - rv = fprintf(out, "%lu ", val); - if (rv < 0) { - PORT_SetError(SEC_ERROR_IO); - return rv; - } - val = 0; + j = data[i]; + val = (val << 7) | (j & 0x7f); + if (j & 0x80) + continue; + rv = fprintf(out, "%lu ", val); + if (rv < 0) { + PORT_SetError(SEC_ERROR_IO); + return rv; + } + val = 0; } /* @@ -264,89 +274,82 @@ prettyPrintObjectID(FILE *out, const unsigned char *data, oiditem.len = len; oiddata = SECOID_FindOID(&oiditem); if (oiddata != NULL) { - i = PORT_Strlen(oiddata->desc); - if ((prettyColumn + 1 + (i / 3)) > RIGHT_MARGIN) { - rv = prettyNewline(out); - if (rv < 0) - return rv; - } - - rv = prettyIndent(out, level); - if (rv < 0) - return rv; - - rv = fprintf(out, "(%s)", oiddata->desc); - if (rv < 0) { - PORT_SetError(SEC_ERROR_IO); - return rv; - } + i = PORT_Strlen(oiddata->desc); + if ((prettyColumn + 1 + (i / 3)) > RIGHT_MARGIN) { + rv = prettyNewline(out); + if (rv < 0) + return rv; + } + + rv = prettyIndent(out, level); + if (rv < 0) + return rv; + + rv = fprintf(out, "(%s)", oiddata->desc); + if (rv < 0) { + PORT_SetError(SEC_ERROR_IO); + return rv; + } } - /* - * Finally, on a new line, print the raw bytes (if requested). - */ + rv = prettyNewline(out); + if (rv < 0) + return rv; + if (raw) { - rv = prettyNewline(out); - if (rv < 0) { - PORT_SetError(SEC_ERROR_IO); - return rv; - } - - for (i = 0; i < len; i++) { - rv = prettyPrintByte(out, *data++, level); - if (rv < 0) - return rv; - } + rv = prettyPrintLeaf(out, data, len, level); + if (rv < 0) + return rv; } - return prettyNewline(out); + return 0; } -static char *prettyTagType [32] = { - "End of Contents", - "Boolean", - "Integer", - "Bit String", - "Octet String", - "NULL", - "Object Identifier", - "0x07", - "0x08", - "0x09", - "Enumerated", - "0x0B", - "UTF8 String", - "0x0D", - "0x0E", - "0x0F", - "Sequence", - "Set", - "0x12", - "Printable String", - "T61 String", - "0x15", - "IA5 String", - "UTC Time", - "Generalized Time", - "0x19", - "Visible String", - "0x1B", - "Universal String", - "0x1D", - "BMP String", - "High-Tag-Number" +static char *prettyTagType[32] = { + "End of Contents", + "Boolean", + "Integer", + "Bit String", + "Octet String", + "NULL", + "Object Identifier", + "0x07", + "0x08", + "0x09", + "Enumerated", + "0x0B", + "UTF8 String", + "0x0D", + "0x0E", + "0x0F", + "Sequence", + "Set", + "0x12", + "Printable String", + "T61 String", + "0x15", + "IA5 String", + "UTC Time", + "Generalized Time", + "0x19", + "Visible String", + "0x1B", + "Universal String", + "0x1D", + "BMP String", + "High-Tag-Number" }; static int prettyPrintTag(FILE *out, const unsigned char *src, const unsigned char *end, - unsigned char *codep, unsigned int level, PRBool raw) + unsigned char *codep, unsigned int level, PRBool raw) { int rv; unsigned char code, tagnum; if (src >= end) { - PORT_SetError(SEC_ERROR_BAD_DER); - return -1; + PORT_SetError(SEC_ERROR_BAD_DER); + return -1; } code = *src; @@ -357,43 +360,43 @@ prettyPrintTag(FILE *out, const unsigned char *src, const unsigned char *end, */ if (tagnum == SEC_ASN1_HIGH_TAG_NUMBER) { PORT_SetError(SEC_ERROR_BAD_DER); - return -1; + return -1; } if (raw) - rv = prettyPrintByte(out, code, level); + rv = prettyPrintByte(out, code, level); else - rv = prettyIndent(out, level); + rv = prettyIndent(out, level); if (rv < 0) - return rv; + return rv; if (code & SEC_ASN1_CONSTRUCTED) { rv = fprintf(out, "C-"); - if (rv < 0) { - PORT_SetError(SEC_ERROR_IO); - return rv; - } + if (rv < 0) { + PORT_SetError(SEC_ERROR_IO); + return rv; + } } switch (code & SEC_ASN1_CLASS_MASK) { - case SEC_ASN1_UNIVERSAL: - rv = fprintf(out, "%s ", prettyTagType[tagnum]); - break; - case SEC_ASN1_APPLICATION: - rv = fprintf(out, "Application: %d ", tagnum); - break; - case SEC_ASN1_CONTEXT_SPECIFIC: - rv = fprintf(out, "[%d] ", tagnum); - break; - case SEC_ASN1_PRIVATE: - rv = fprintf(out, "Private: %d ", tagnum); - break; + case SEC_ASN1_UNIVERSAL: + rv = fprintf(out, "%s ", prettyTagType[tagnum]); + break; + case SEC_ASN1_APPLICATION: + rv = fprintf(out, "Application: %d ", tagnum); + break; + case SEC_ASN1_CONTEXT_SPECIFIC: + rv = fprintf(out, "[%d] ", tagnum); + break; + case SEC_ASN1_PRIVATE: + rv = fprintf(out, "Private: %d ", tagnum); + break; } if (rv < 0) { PORT_SetError(SEC_ERROR_IO); - return rv; + return rv; } *codep = code; @@ -403,76 +406,77 @@ prettyPrintTag(FILE *out, const unsigned char *src, const unsigned char *end, static int prettyPrintLength(FILE *out, const unsigned char *data, const unsigned char *end, - int *lenp, PRBool *indefinitep, unsigned int lv, PRBool raw) + int *lenp, PRBool *indefinitep, unsigned int lv, PRBool raw) { unsigned char lbyte; int lenLen; int rv; if (data >= end) { - PORT_SetError(SEC_ERROR_BAD_DER); - return -1; + PORT_SetError(SEC_ERROR_BAD_DER); + return -1; } rv = fprintf(out, " "); if (rv < 0) { PORT_SetError(SEC_ERROR_IO); - return rv; + return rv; } *indefinitep = PR_FALSE; lbyte = *data++; + lenLen = 1; if (lbyte >= 0x80) { - /* Multibyte length */ - unsigned nb = (unsigned) (lbyte & 0x7f); - if (nb > 4) { - PORT_SetError(SEC_ERROR_BAD_DER); - return -1; - } - if (nb > 0) { - int il; - - if ((data + nb) > end) { - PORT_SetError(SEC_ERROR_BAD_DER); - return -1; - } - il = getInteger256(data, nb); - if (il < 0) return -1; - *lenp = (unsigned) il; - } else { - *lenp = 0; - *indefinitep = PR_TRUE; - } - lenLen = nb + 1; - if (raw) { - unsigned int i; - - rv = prettyPrintByte(out, lbyte, lv); - if (rv < 0) - return rv; - for (i = 0; i < nb; i++) { - rv = prettyPrintByte(out, data[i], lv); - if (rv < 0) - return rv; - } - } + /* Multibyte length */ + unsigned nb = (unsigned)(lbyte & 0x7f); + if (nb > 4) { + PORT_SetError(SEC_ERROR_BAD_DER); + return -1; + } + if (nb > 0) { + int il; + + if ((data + nb) > end) { + PORT_SetError(SEC_ERROR_BAD_DER); + return -1; + } + il = getInteger256(data, nb); + if (il < 0) + return -1; + *lenp = (unsigned)il; + } else { + *lenp = 0; + *indefinitep = PR_TRUE; + } + lenLen += nb; + if (raw) { + unsigned int i; + + rv = prettyPrintByte(out, lbyte, lv); + if (rv < 0) + return rv; + for (i = 0; i < nb; i++) { + rv = prettyPrintByte(out, data[i], lv); + if (rv < 0) + return rv; + } + } } else { - *lenp = lbyte; - lenLen = 1; - if (raw) { - rv = prettyPrintByte(out, lbyte, lv); - if (rv < 0) - return rv; - } + *lenp = lbyte; + if (raw) { + rv = prettyPrintByte(out, lbyte, lv); + if (rv < 0) + return rv; + } } if (*indefinitep) - rv = fprintf(out, "(indefinite)\n"); + rv = fprintf(out, "(indefinite)\n"); else - rv = fprintf(out, "(%d)\n", *lenp); + rv = fprintf(out, "(%d)\n", *lenp); if (rv < 0) { PORT_SetError(SEC_ERROR_IO); - return rv; + return rv; } prettyColumn = -1; @@ -481,7 +485,7 @@ prettyPrintLength(FILE *out, const unsigned char *data, const unsigned char *end static int prettyPrintItem(FILE *out, const unsigned char *data, const unsigned char *end, - unsigned int lv, PRBool raw) + unsigned int lv, PRBool raw) { int slen; int lenLen; @@ -490,88 +494,88 @@ prettyPrintItem(FILE *out, const unsigned char *data, const unsigned char *end, while (data < end) { unsigned char code; - PRBool indefinite; - - slen = prettyPrintTag(out, data, end, &code, lv, raw); - if (slen < 0) - return slen; - data += slen; - - lenLen = prettyPrintLength(out, data, end, &slen, &indefinite, lv, raw); - if (lenLen < 0) - return lenLen; - data += lenLen; - - /* - * Just quit now if slen more bytes puts us off the end. - */ - if ((data + slen) > end) { - PORT_SetError(SEC_ERROR_BAD_DER); - return -1; - } + PRBool indefinite; + + slen = prettyPrintTag(out, data, end, &code, lv, raw); + if (slen < 0) + return slen; + data += slen; + + lenLen = prettyPrintLength(out, data, end, &slen, &indefinite, lv, raw); + if (lenLen < 0) + return lenLen; + data += lenLen; + + /* + * Just quit now if slen more bytes puts us off the end. + */ + if ((data + slen) > end) { + PORT_SetError(SEC_ERROR_BAD_DER); + return -1; + } if (code & SEC_ASN1_CONSTRUCTED) { - if (slen > 0 || indefinite) { - slen = prettyPrintItem(out, data, - slen == 0 ? end : data + slen, - lv+1, raw); - if (slen < 0) - return slen; - data += slen; - } - } else if (code == 0) { - if (slen != 0 || lenLen != 1) { - PORT_SetError(SEC_ERROR_BAD_DER); - return -1; - } - break; - } else { - switch (code) { - case SEC_ASN1_PRINTABLE_STRING: - case SEC_ASN1_IA5_STRING: - case SEC_ASN1_VISIBLE_STRING: - rv = prettyPrintString(out, data, slen, lv+1, raw); - if (rv < 0) - return rv; - break; - case SEC_ASN1_UTC_TIME: - rv = prettyPrintTime(out, data, slen, lv+1, raw, PR_TRUE); - if (rv < 0) - return rv; - break; - case SEC_ASN1_GENERALIZED_TIME: - rv = prettyPrintTime(out, data, slen, lv+1, raw, PR_FALSE); - if (rv < 0) - return rv; - break; - case SEC_ASN1_OBJECT_ID: - rv = prettyPrintObjectID(out, data, slen, lv+1, raw); - if (rv < 0) - return rv; - break; - case SEC_ASN1_BOOLEAN: /* could do nicer job */ - case SEC_ASN1_INTEGER: /* could do nicer job */ - case SEC_ASN1_BIT_STRING: /* could do nicer job */ - case SEC_ASN1_OCTET_STRING: - case SEC_ASN1_NULL: - case SEC_ASN1_ENUMERATED: /* could do nicer job, as INTEGER */ - case SEC_ASN1_UTF8_STRING: - case SEC_ASN1_T61_STRING: /* print as printable string? */ - case SEC_ASN1_UNIVERSAL_STRING: - case SEC_ASN1_BMP_STRING: - default: - rv = prettyPrintLeaf(out, data, slen, lv+1); - if (rv < 0) - return rv; - break; - } - data += slen; - } + if (slen > 0 || indefinite) { + slen = prettyPrintItem(out, data, + slen == 0 ? end : data + slen, + lv + 1, raw); + if (slen < 0) + return slen; + data += slen; + } + } else if (code == 0) { + if (slen != 0 || lenLen != 1) { + PORT_SetError(SEC_ERROR_BAD_DER); + return -1; + } + break; + } else { + switch (code) { + case SEC_ASN1_PRINTABLE_STRING: + case SEC_ASN1_IA5_STRING: + case SEC_ASN1_VISIBLE_STRING: + rv = prettyPrintString(out, data, slen, lv + 1, raw); + if (rv < 0) + return rv; + break; + case SEC_ASN1_UTC_TIME: + rv = prettyPrintTime(out, data, slen, lv + 1, raw, PR_TRUE); + if (rv < 0) + return rv; + break; + case SEC_ASN1_GENERALIZED_TIME: + rv = prettyPrintTime(out, data, slen, lv + 1, raw, PR_FALSE); + if (rv < 0) + return rv; + break; + case SEC_ASN1_OBJECT_ID: + rv = prettyPrintObjectID(out, data, slen, lv + 1, raw); + if (rv < 0) + return rv; + break; + case SEC_ASN1_BOOLEAN: /* could do nicer job */ + case SEC_ASN1_INTEGER: /* could do nicer job */ + case SEC_ASN1_BIT_STRING: /* could do nicer job */ + case SEC_ASN1_OCTET_STRING: + case SEC_ASN1_NULL: + case SEC_ASN1_ENUMERATED: /* could do nicer job, as INTEGER */ + case SEC_ASN1_UTF8_STRING: + case SEC_ASN1_T61_STRING: /* print as printable string? */ + case SEC_ASN1_UNIVERSAL_STRING: + case SEC_ASN1_BMP_STRING: + default: + rv = prettyPrintLeaf(out, data, slen, lv + 1); + if (rv < 0) + return rv; + break; + } + data += slen; + } } rv = prettyNewline(out); if (rv < 0) - return rv; + return rv; return data - orig; } @@ -585,6 +589,6 @@ DER_PrettyPrint(FILE *out, const SECItem *it, PRBool raw) rv = prettyPrintItem(out, it->data, it->data + it->len, 0, raw); if (rv < 0) - return SECFailure; + return SECFailure; return SECSuccess; } |