Blame nss/cmd/lib/derprint.c

Packit 40b132
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit 40b132
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit 40b132
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit 40b132
#include "secutil.h"
Packit 40b132
#include "secoid.h"
Packit 40b132
Packit 40b132
#ifdef __sun
Packit 40b132
extern int fprintf(FILE *strm, const char *format, .../* args */);
Packit 40b132
extern int fflush(FILE *stream);
Packit 40b132
#endif
Packit 40b132
Packit 40b132
#define RIGHT_MARGIN	24
Packit 40b132
/*#define RAW_BYTES 1 */
Packit 40b132
Packit 40b132
static int prettyColumn = 0;
Packit 40b132
Packit 40b132
static int
Packit 40b132
getInteger256(const unsigned char *data, unsigned int nb)
Packit 40b132
{
Packit 40b132
    int val;
Packit 40b132
Packit 40b132
    switch (nb) {
Packit 40b132
      case 1:
Packit 40b132
	val = data[0];
Packit 40b132
	break;
Packit 40b132
      case 2:
Packit 40b132
	val = (data[0] << 8) | data[1];
Packit 40b132
	break;
Packit 40b132
      case 3:
Packit 40b132
	val = (data[0] << 16) | (data[1] << 8) | data[2];
Packit 40b132
	break;
Packit 40b132
      case 4:
Packit 40b132
	val = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
Packit 40b132
	break;
Packit 40b132
      default:
Packit 40b132
	PORT_SetError(SEC_ERROR_BAD_DER);
Packit 40b132
	return -1;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    return val;
Packit 40b132
}
Packit 40b132
Packit 40b132
static int
Packit 40b132
prettyNewline(FILE *out)
Packit 40b132
{
Packit 40b132
    int rv;
Packit 40b132
Packit 40b132
    if (prettyColumn != -1) {
Packit 40b132
	rv = fprintf(out, "\n");
Packit 40b132
	prettyColumn = -1;
Packit 40b132
	if (rv < 0) {
Packit 40b132
	    PORT_SetError(SEC_ERROR_IO);
Packit 40b132
	    return rv;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
    return 0;
Packit 40b132
}
Packit 40b132
Packit 40b132
static int
Packit 40b132
prettyIndent(FILE *out, unsigned level)
Packit 40b132
{
Packit 40b132
    unsigned int i;
Packit 40b132
    int rv;
Packit 40b132
Packit 40b132
    if (prettyColumn == -1) {
Packit 40b132
	prettyColumn = level;
Packit 40b132
	for (i = 0; i < level; i++) {
Packit 40b132
	    rv = fprintf(out, "   ");
Packit 40b132
	    if (rv < 0) {
Packit 40b132
		PORT_SetError(SEC_ERROR_IO);
Packit 40b132
		return rv;
Packit 40b132
	    }
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
Packit 40b132
    return 0;
Packit 40b132
}
Packit 40b132
Packit 40b132
static int
Packit 40b132
prettyPrintByte(FILE *out, unsigned char item, unsigned int level)
Packit 40b132
{
Packit 40b132
    int rv;
Packit 40b132
Packit 40b132
    rv = prettyIndent(out, level);
Packit 40b132
    if (rv < 0)
Packit 40b132
	return rv;
Packit 40b132
Packit 40b132
    rv = fprintf(out, "%02x ", item);
Packit 40b132
    if (rv < 0) {
Packit 40b132
	PORT_SetError(SEC_ERROR_IO);
Packit 40b132
	return rv;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    prettyColumn++;
Packit 40b132
    if (prettyColumn >= RIGHT_MARGIN) {
Packit 40b132
	return prettyNewline(out);
Packit 40b132
    }
Packit 40b132
Packit 40b132
    return 0;
Packit 40b132
}
Packit 40b132
Packit 40b132
static int
Packit 40b132
prettyPrintLeaf(FILE *out, const unsigned char *data,
Packit 40b132
		unsigned int len, unsigned int lv)
Packit 40b132
{
Packit 40b132
    unsigned int i;
Packit 40b132
    int rv;
Packit 40b132
Packit 40b132
    for (i = 0; i < len; i++) {
Packit 40b132
	rv = prettyPrintByte(out, *data++, lv);
Packit 40b132
	if (rv < 0)
Packit 40b132
	    return rv;
Packit 40b132
    }
Packit 40b132
    return prettyNewline(out);
Packit 40b132
}
Packit 40b132
Packit 40b132
static int
Packit 40b132
prettyPrintStringStart(FILE *out, const unsigned char *str,
Packit 40b132
		       unsigned int len, unsigned int level)
Packit 40b132
{
Packit 40b132
#define BUF_SIZE 100
Packit 40b132
    unsigned char buf[BUF_SIZE];
Packit 40b132
    int rv;
Packit 40b132
Packit 40b132
    if (len >= BUF_SIZE)
Packit 40b132
	len = BUF_SIZE - 1;
Packit 40b132
Packit 40b132
    rv = prettyNewline(out);
Packit 40b132
    if (rv < 0)
Packit 40b132
	return rv;
Packit 40b132
Packit 40b132
    rv = prettyIndent(out, level);
Packit 40b132
    if (rv < 0)
Packit 40b132
	return rv;
Packit 40b132
Packit 40b132
    memcpy(buf, str, len);
Packit 40b132
    buf[len] = '\000';
Packit 40b132
Packit 40b132
    rv = fprintf(out, "\"%s\"", buf);
Packit 40b132
    if (rv < 0) {
Packit 40b132
	PORT_SetError(SEC_ERROR_IO);
Packit 40b132
	return rv;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    return 0;
Packit 40b132
#undef BUF_SIZE
Packit 40b132
}
Packit 40b132
Packit 40b132
static int
Packit 40b132
prettyPrintString(FILE *out, const unsigned char *str,
Packit 40b132
		  unsigned int len, unsigned int level, PRBool raw)
Packit 40b132
{
Packit 40b132
    int rv;
Packit 40b132
Packit 40b132
    rv = prettyPrintStringStart(out, str, len, level);
Packit 40b132
    if (rv < 0)
Packit 40b132
	return rv;
Packit 40b132
Packit 40b132
    rv = prettyNewline(out);
Packit 40b132
    if (rv < 0)
Packit 40b132
	return rv;
Packit 40b132
Packit 40b132
    if (raw) {
Packit 40b132
	rv = prettyPrintLeaf(out, str, len, level);
Packit 40b132
	if (rv < 0)
Packit 40b132
	    return rv;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    return 0;
Packit 40b132
}
Packit 40b132
Packit 40b132
static int
Packit 40b132
prettyPrintTime(FILE *out, const unsigned char *str,
Packit 40b132
		unsigned int len, unsigned int level, PRBool raw, PRBool utc)
Packit 40b132
{
Packit 40b132
    SECItem time_item;
Packit 40b132
    int rv;
Packit 40b132
Packit 40b132
    rv = prettyPrintStringStart(out, str, len, level);
Packit 40b132
    if (rv < 0)
Packit 40b132
	return rv;
Packit 40b132
Packit 40b132
    time_item.data = (unsigned char *)str;
Packit 40b132
    time_item.len = len;
Packit 40b132
Packit 40b132
    rv = fprintf(out, " (");
Packit 40b132
    if (rv < 0) {
Packit 40b132
	PORT_SetError(SEC_ERROR_IO);
Packit 40b132
	return rv;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if (utc)
Packit 40b132
	SECU_PrintUTCTime(out, &time_item, NULL, 0);
Packit 40b132
    else
Packit 40b132
	SECU_PrintGeneralizedTime(out, &time_item, NULL, 0);
Packit 40b132
Packit 40b132
    rv = fprintf(out, ")");
Packit 40b132
    if (rv < 0) {
Packit 40b132
	PORT_SetError(SEC_ERROR_IO);
Packit 40b132
	return rv;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    rv = prettyNewline(out);
Packit 40b132
    if (rv < 0)
Packit 40b132
	return rv;
Packit 40b132
Packit 40b132
    if (raw) {
Packit 40b132
	rv = prettyPrintLeaf(out, str, len, level);
Packit 40b132
	if (rv < 0)
Packit 40b132
	    return rv;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    return 0;
Packit 40b132
}
Packit 40b132
Packit 40b132
static int
Packit 40b132
prettyPrintObjectID(FILE *out, const unsigned char *data,
Packit 40b132
		    unsigned int len, unsigned int level, PRBool raw)
Packit 40b132
{
Packit 40b132
    SECOidData *oiddata;
Packit 40b132
    SECItem oiditem;
Packit 40b132
    unsigned int i;
Packit 40b132
    unsigned long val;
Packit 40b132
    int rv;
Packit 40b132
Packit 40b132
Packit 40b132
    /*
Packit 40b132
     * First print the Object Id in numeric format
Packit 40b132
     */
Packit 40b132
Packit 40b132
    rv = prettyIndent(out, level);
Packit 40b132
    if (rv < 0)
Packit 40b132
	return rv;
Packit 40b132
Packit 40b132
    val = data[0];
Packit 40b132
    i   = val % 40;
Packit 40b132
    val = val / 40;
Packit 40b132
    rv = fprintf(out, "%lu %u ", val, i);
Packit 40b132
    if (rv < 0) {
Packit 40b132
	PORT_SetError(SEC_ERROR_IO);
Packit 40b132
	return rv;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    val = 0;
Packit 40b132
    for (i = 1; i < len; ++i) {
Packit 40b132
        unsigned long j;
Packit 40b132
Packit 40b132
	j = data[i];
Packit 40b132
	val = (val << 7) | (j & 0x7f);
Packit 40b132
	if (j & 0x80) 
Packit 40b132
	    continue;
Packit 40b132
	rv = fprintf(out, "%lu ", val);
Packit 40b132
	if (rv < 0) {
Packit 40b132
	    PORT_SetError(SEC_ERROR_IO);
Packit 40b132
	    return rv;
Packit 40b132
	}
Packit 40b132
	val = 0;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /*
Packit 40b132
     * Now try to look it up and print a symbolic version.
Packit 40b132
     */
Packit 40b132
    oiditem.data = (unsigned char *)data;
Packit 40b132
    oiditem.len = len;
Packit 40b132
    oiddata = SECOID_FindOID(&oiditem);
Packit 40b132
    if (oiddata != NULL) {
Packit 40b132
	i = PORT_Strlen(oiddata->desc);
Packit 40b132
	if ((prettyColumn + 1 + (i / 3)) > RIGHT_MARGIN) {
Packit 40b132
	    rv = prettyNewline(out);
Packit 40b132
	    if (rv < 0)
Packit 40b132
		return rv;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	rv = prettyIndent(out, level);
Packit 40b132
	if (rv < 0)
Packit 40b132
	    return rv;
Packit 40b132
Packit 40b132
	rv = fprintf(out, "(%s)", oiddata->desc);
Packit 40b132
	if (rv < 0) {
Packit 40b132
	    PORT_SetError(SEC_ERROR_IO);
Packit 40b132
	    return rv;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /*
Packit 40b132
     * Finally, on a new line, print the raw bytes (if requested).
Packit 40b132
     */
Packit 40b132
    if (raw) {
Packit 40b132
	rv = prettyNewline(out);
Packit 40b132
	if (rv < 0) {
Packit 40b132
	    PORT_SetError(SEC_ERROR_IO);
Packit 40b132
	    return rv;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	for (i = 0; i < len; i++) {
Packit 40b132
	    rv = prettyPrintByte(out, *data++, level);
Packit 40b132
	    if (rv < 0)
Packit 40b132
		return rv;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
Packit 40b132
    return prettyNewline(out);
Packit 40b132
}
Packit 40b132
Packit 40b132
static char *prettyTagType [32] = {
Packit 40b132
  "End of Contents",
Packit 40b132
  "Boolean",
Packit 40b132
  "Integer",
Packit 40b132
  "Bit String",
Packit 40b132
  "Octet String",
Packit 40b132
  "NULL",
Packit 40b132
  "Object Identifier",
Packit 40b132
  "0x07",
Packit 40b132
  "0x08",
Packit 40b132
  "0x09",
Packit 40b132
  "Enumerated",
Packit 40b132
  "0x0B",
Packit 40b132
  "UTF8 String",
Packit 40b132
  "0x0D",
Packit 40b132
  "0x0E",
Packit 40b132
  "0x0F",
Packit 40b132
  "Sequence",
Packit 40b132
  "Set",
Packit 40b132
  "0x12",
Packit 40b132
  "Printable String",
Packit 40b132
  "T61 String",
Packit 40b132
  "0x15",
Packit 40b132
  "IA5 String",
Packit 40b132
  "UTC Time",
Packit 40b132
  "Generalized Time",
Packit 40b132
  "0x19",
Packit 40b132
  "Visible String",
Packit 40b132
  "0x1B",
Packit 40b132
  "Universal String",
Packit 40b132
  "0x1D",
Packit 40b132
  "BMP String",
Packit 40b132
  "High-Tag-Number"
Packit 40b132
};
Packit 40b132
Packit 40b132
static int
Packit 40b132
prettyPrintTag(FILE *out, const unsigned char *src, const unsigned char *end,
Packit 40b132
	       unsigned char *codep, unsigned int level, PRBool raw)
Packit 40b132
{
Packit 40b132
    int rv;
Packit 40b132
    unsigned char code, tagnum;
Packit 40b132
Packit 40b132
    if (src >= end) {
Packit 40b132
	PORT_SetError(SEC_ERROR_BAD_DER);
Packit 40b132
	return -1;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    code = *src;
Packit 40b132
    tagnum = code & SEC_ASN1_TAGNUM_MASK;
Packit 40b132
Packit 40b132
    /*
Packit 40b132
     * NOTE: This code does not (yet) handle the high-tag-number form!
Packit 40b132
     */
Packit 40b132
    if (tagnum == SEC_ASN1_HIGH_TAG_NUMBER) {
Packit 40b132
        PORT_SetError(SEC_ERROR_BAD_DER);
Packit 40b132
	return -1;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if (raw)
Packit 40b132
	rv = prettyPrintByte(out, code, level);
Packit 40b132
    else
Packit 40b132
	rv = prettyIndent(out, level);
Packit 40b132
Packit 40b132
    if (rv < 0)
Packit 40b132
	return rv;
Packit 40b132
Packit 40b132
    if (code & SEC_ASN1_CONSTRUCTED) {
Packit 40b132
        rv = fprintf(out, "C-");
Packit 40b132
	if (rv < 0) {
Packit 40b132
	    PORT_SetError(SEC_ERROR_IO);
Packit 40b132
	    return rv;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
Packit 40b132
    switch (code & SEC_ASN1_CLASS_MASK) {
Packit 40b132
    case SEC_ASN1_UNIVERSAL:
Packit 40b132
        rv = fprintf(out, "%s ", prettyTagType[tagnum]);
Packit 40b132
	break;
Packit 40b132
    case SEC_ASN1_APPLICATION:
Packit 40b132
        rv = fprintf(out, "Application: %d ", tagnum);
Packit 40b132
	break;
Packit 40b132
    case SEC_ASN1_CONTEXT_SPECIFIC:
Packit 40b132
        rv = fprintf(out, "[%d] ", tagnum);
Packit 40b132
	break;
Packit 40b132
    case SEC_ASN1_PRIVATE:
Packit 40b132
        rv = fprintf(out, "Private: %d ", tagnum);
Packit 40b132
	break;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if (rv < 0) {
Packit 40b132
        PORT_SetError(SEC_ERROR_IO);
Packit 40b132
	return rv;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    *codep = code;
Packit 40b132
Packit 40b132
    return 1;
Packit 40b132
}
Packit 40b132
Packit 40b132
static int
Packit 40b132
prettyPrintLength(FILE *out, const unsigned char *data, const unsigned char *end,
Packit 40b132
		  int *lenp, PRBool *indefinitep, unsigned int lv, PRBool raw)
Packit 40b132
{
Packit 40b132
    unsigned char lbyte;
Packit 40b132
    int lenLen;
Packit 40b132
    int rv;
Packit 40b132
Packit 40b132
    if (data >= end) {
Packit 40b132
	PORT_SetError(SEC_ERROR_BAD_DER);
Packit 40b132
	return -1;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    rv = fprintf(out, " ");
Packit 40b132
    if (rv < 0) {
Packit 40b132
        PORT_SetError(SEC_ERROR_IO);
Packit 40b132
	return rv;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    *indefinitep = PR_FALSE;
Packit 40b132
Packit 40b132
    lbyte = *data++;
Packit 40b132
    if (lbyte >= 0x80) {
Packit 40b132
	/* Multibyte length */
Packit 40b132
	unsigned nb = (unsigned) (lbyte & 0x7f);
Packit 40b132
	if (nb > 4) {
Packit 40b132
	    PORT_SetError(SEC_ERROR_BAD_DER);
Packit 40b132
	    return -1;
Packit 40b132
	}
Packit 40b132
	if (nb > 0) {
Packit 40b132
	    int il;
Packit 40b132
Packit 40b132
	    if ((data + nb) > end) {
Packit 40b132
		PORT_SetError(SEC_ERROR_BAD_DER);
Packit 40b132
		return -1;
Packit 40b132
	    }
Packit 40b132
	    il = getInteger256(data, nb);
Packit 40b132
	    if (il < 0) return -1;
Packit 40b132
	    *lenp = (unsigned) il;
Packit 40b132
	} else {
Packit 40b132
	    *lenp = 0;
Packit 40b132
	    *indefinitep = PR_TRUE;
Packit 40b132
	}
Packit 40b132
	lenLen = nb + 1;
Packit 40b132
	if (raw) {
Packit 40b132
	    int i;
Packit 40b132
Packit 40b132
	    rv = prettyPrintByte(out, lbyte, lv);
Packit 40b132
	    if (rv < 0)
Packit 40b132
		return rv;
Packit 40b132
	    for (i = 0; i < nb; i++) {
Packit 40b132
		rv = prettyPrintByte(out, data[i], lv);
Packit 40b132
		if (rv < 0)
Packit 40b132
		    return rv;
Packit 40b132
	    }
Packit 40b132
	}
Packit 40b132
    } else {
Packit 40b132
	*lenp = lbyte;
Packit 40b132
	lenLen = 1;
Packit 40b132
	if (raw) {
Packit 40b132
	    rv = prettyPrintByte(out, lbyte, lv);
Packit 40b132
	    if (rv < 0)
Packit 40b132
		return rv;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
    if (*indefinitep)
Packit 40b132
	rv = fprintf(out, "(indefinite)\n");
Packit 40b132
    else
Packit 40b132
	rv = fprintf(out, "(%d)\n", *lenp);
Packit 40b132
    if (rv < 0) {
Packit 40b132
        PORT_SetError(SEC_ERROR_IO);
Packit 40b132
	return rv;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    prettyColumn = -1;
Packit 40b132
    return lenLen;
Packit 40b132
}
Packit 40b132
Packit 40b132
static int
Packit 40b132
prettyPrintItem(FILE *out, const unsigned char *data, const unsigned char *end,
Packit 40b132
		unsigned int lv, PRBool raw)
Packit 40b132
{
Packit 40b132
    int slen;
Packit 40b132
    int lenLen;
Packit 40b132
    const unsigned char *orig = data;
Packit 40b132
    int rv;
Packit 40b132
Packit 40b132
    while (data < end) {
Packit 40b132
        unsigned char code;
Packit 40b132
	PRBool indefinite;
Packit 40b132
Packit 40b132
	slen = prettyPrintTag(out, data, end, &code, lv, raw);
Packit 40b132
	if (slen < 0)
Packit 40b132
	    return slen;
Packit 40b132
	data += slen;
Packit 40b132
Packit 40b132
	lenLen = prettyPrintLength(out, data, end, &slen, &indefinite, lv, raw);
Packit 40b132
	if (lenLen < 0)
Packit 40b132
	    return lenLen;
Packit 40b132
	data += lenLen;
Packit 40b132
Packit 40b132
	/*
Packit 40b132
	 * Just quit now if slen more bytes puts us off the end.
Packit 40b132
	 */
Packit 40b132
	if ((data + slen) > end) {
Packit 40b132
	    PORT_SetError(SEC_ERROR_BAD_DER);
Packit 40b132
	    return -1;
Packit 40b132
	}
Packit 40b132
Packit 40b132
        if (code & SEC_ASN1_CONSTRUCTED) {
Packit 40b132
	    if (slen > 0 || indefinite) {
Packit 40b132
		slen = prettyPrintItem(out, data,
Packit 40b132
				       slen == 0 ? end : data + slen,
Packit 40b132
				       lv+1, raw);
Packit 40b132
		if (slen < 0)
Packit 40b132
		    return slen;
Packit 40b132
		data += slen;
Packit 40b132
	    }
Packit 40b132
	} else if (code == 0) {
Packit 40b132
	    if (slen != 0 || lenLen != 1) {
Packit 40b132
		PORT_SetError(SEC_ERROR_BAD_DER);
Packit 40b132
		return -1;
Packit 40b132
	    }
Packit 40b132
	    break;
Packit 40b132
	} else {
Packit 40b132
	    switch (code) {
Packit 40b132
	      case SEC_ASN1_PRINTABLE_STRING:
Packit 40b132
	      case SEC_ASN1_IA5_STRING:
Packit 40b132
	      case SEC_ASN1_VISIBLE_STRING:
Packit 40b132
	        rv = prettyPrintString(out, data, slen, lv+1, raw);
Packit 40b132
		if (rv < 0)
Packit 40b132
		    return rv;
Packit 40b132
		break;
Packit 40b132
	      case SEC_ASN1_UTC_TIME:
Packit 40b132
	        rv = prettyPrintTime(out, data, slen, lv+1, raw, PR_TRUE);
Packit 40b132
		if (rv < 0)
Packit 40b132
		    return rv;
Packit 40b132
		break;
Packit 40b132
	      case SEC_ASN1_GENERALIZED_TIME:
Packit 40b132
	        rv = prettyPrintTime(out, data, slen, lv+1, raw, PR_FALSE);
Packit 40b132
		if (rv < 0)
Packit 40b132
		    return rv;
Packit 40b132
		break;
Packit 40b132
	      case SEC_ASN1_OBJECT_ID:
Packit 40b132
	        rv = prettyPrintObjectID(out, data, slen, lv+1, raw);
Packit 40b132
		if (rv < 0)
Packit 40b132
		    return rv;
Packit 40b132
		break;
Packit 40b132
	      case SEC_ASN1_BOOLEAN:	/* could do nicer job */
Packit 40b132
	      case SEC_ASN1_INTEGER:	/* could do nicer job */
Packit 40b132
	      case SEC_ASN1_BIT_STRING:	/* could do nicer job */
Packit 40b132
	      case SEC_ASN1_OCTET_STRING:
Packit 40b132
	      case SEC_ASN1_NULL:
Packit 40b132
	      case SEC_ASN1_ENUMERATED:	/* could do nicer job, as INTEGER */
Packit 40b132
	      case SEC_ASN1_UTF8_STRING:
Packit 40b132
	      case SEC_ASN1_T61_STRING:	/* print as printable string? */
Packit 40b132
	      case SEC_ASN1_UNIVERSAL_STRING:
Packit 40b132
	      case SEC_ASN1_BMP_STRING:
Packit 40b132
	      default:
Packit 40b132
	        rv = prettyPrintLeaf(out, data, slen, lv+1);
Packit 40b132
		if (rv < 0)
Packit 40b132
		    return rv;
Packit 40b132
		break;
Packit 40b132
	    }
Packit 40b132
	    data += slen;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
Packit 40b132
    rv = prettyNewline(out);
Packit 40b132
    if (rv < 0)
Packit 40b132
	return rv;
Packit 40b132
Packit 40b132
    return data - orig;
Packit 40b132
}
Packit 40b132
Packit 40b132
SECStatus
Packit 40b132
DER_PrettyPrint(FILE *out, const SECItem *it, PRBool raw)
Packit 40b132
{
Packit 40b132
    int rv;
Packit 40b132
Packit 40b132
    prettyColumn = -1;
Packit 40b132
Packit 40b132
    rv = prettyPrintItem(out, it->data, it->data + it->len, 0, raw);
Packit 40b132
    if (rv < 0)
Packit 40b132
	return SECFailure;
Packit 40b132
    return SECSuccess;
Packit 40b132
}