Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
derprint.c File Reference
#include "secutil.h"
#include "secoid.h"

Go to the source code of this file.

Defines

#define RIGHT_MARGIN   24
#define BUF_SIZE   100

Functions

static int getInteger256 (unsigned char *data, unsigned int nb)
static int prettyNewline (FILE *out)
static int prettyIndent (FILE *out, unsigned level)
static int prettyPrintByte (FILE *out, unsigned char item, unsigned int level)
static int prettyPrintLeaf (FILE *out, unsigned char *data, unsigned int len, unsigned int lv)
static int prettyPrintStringStart (FILE *out, unsigned char *str, unsigned int len, unsigned int level)
static int prettyPrintString (FILE *out, unsigned char *str, unsigned int len, unsigned int level, PRBool raw)
static int prettyPrintTime (FILE *out, unsigned char *str, unsigned int len, unsigned int level, PRBool raw, PRBool utc)
static int prettyPrintObjectID (FILE *out, unsigned char *data, unsigned int len, unsigned int level, PRBool raw)
static int prettyPrintTag (FILE *out, unsigned char *src, unsigned char *end, unsigned char *codep, unsigned int level, PRBool raw)
static int prettyPrintLength (FILE *out, unsigned char *data, unsigned char *end, int *lenp, PRBool *indefinitep, unsigned int lv, PRBool raw)
static int prettyPrintItem (FILE *out, unsigned char *data, unsigned char *end, unsigned int lv, PRBool raw)
SECStatus DER_PrettyPrint (FILE *out, SECItem *it, PRBool raw)

Variables

static int prettyColumn = 0
static char * prettyTagType [32]

Define Documentation

#define BUF_SIZE   100
#define RIGHT_MARGIN   24

Definition at line 44 of file derprint.c.


Function Documentation

SECStatus DER_PrettyPrint ( FILE out,
SECItem *  it,
PRBool  raw 
)

Definition at line 612 of file derprint.c.

{
    int rv;

    prettyColumn = -1;

    rv = prettyPrintItem(out, it->data, it->data + it->len, 0, raw);
    if (rv < 0)
       return SECFailure;
    return SECSuccess;
}

Here is the call graph for this function:

static int getInteger256 ( unsigned char *  data,
unsigned int  nb 
) [static]

Definition at line 50 of file derprint.c.

{
    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;
    }

    return val;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int prettyIndent ( FILE out,
unsigned  level 
) [static]

Definition at line 92 of file derprint.c.

{
    unsigned int i;
    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;
           }
       }
    }

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int prettyNewline ( FILE out) [static]

Definition at line 76 of file derprint.c.

{
    int rv;

    if (prettyColumn != -1) {
       rv = fprintf(out, "\n");
       prettyColumn = -1;
       if (rv < 0) {
           PORT_SetError(SEC_ERROR_IO);
           return rv;
       }
    }
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int prettyPrintByte ( FILE out,
unsigned char  item,
unsigned int  level 
) [static]

Definition at line 112 of file derprint.c.

{
    int rv;

    rv = prettyIndent(out, level);
    if (rv < 0)
       return rv;

    rv = fprintf(out, "%02x ", item);
    if (rv < 0) {
       PORT_SetError(SEC_ERROR_IO);
       return rv;
    }

    prettyColumn++;
    if (prettyColumn >= RIGHT_MARGIN) {
       return prettyNewline(out);
    }

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int prettyPrintItem ( FILE out,
unsigned char *  data,
unsigned char *  end,
unsigned int  lv,
PRBool  raw 
) [static]

Definition at line 515 of file derprint.c.

{
    int slen;
    int lenLen;
    unsigned char *orig = data;
    int rv;

    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;
       }

        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;
       }
    }

    rv = prettyNewline(out);
    if (rv < 0)
       return rv;

    return data - orig;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int prettyPrintLeaf ( FILE out,
unsigned char *  data,
unsigned int  len,
unsigned int  lv 
) [static]

Definition at line 135 of file derprint.c.

{
    unsigned int i;
    int rv;

    for (i = 0; i < len; i++) {
       rv = prettyPrintByte(out, *data++, lv);
       if (rv < 0)
           return rv;
    }
    return prettyNewline(out);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int prettyPrintLength ( FILE out,
unsigned char *  data,
unsigned char *  end,
int lenp,
PRBool indefinitep,
unsigned int  lv,
PRBool  raw 
) [static]

Definition at line 437 of file derprint.c.

{
    unsigned char lbyte;
    int lenLen;
    int rv;

    if (data >= end) {
       PORT_SetError(SEC_ERROR_BAD_DER);
       return -1;
    }

    rv = fprintf(out, " ");
    if (rv < 0) {
        PORT_SetError(SEC_ERROR_IO);
       return rv;
    }

    *indefinitep = PR_FALSE;

    lbyte = *data++;
    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) {
           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;
       }
    }
    if (*indefinitep)
       rv = fprintf(out, "(indefinite)\n");
    else
       rv = fprintf(out, "(%d)\n", *lenp);
    if (rv < 0) {
        PORT_SetError(SEC_ERROR_IO);
       return rv;
    }

    prettyColumn = -1;
    return lenLen;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int prettyPrintObjectID ( FILE out,
unsigned char *  data,
unsigned int  len,
unsigned int  level,
PRBool  raw 
) [static]

Definition at line 249 of file derprint.c.

{
    SECOidData *oiddata;
    SECItem oiditem;
    unsigned int i;
    unsigned long val;
    int rv;


    /*
     * First print the Object Id in numeric format
     */

    rv = prettyIndent(out, level);
    if (rv < 0)
       return rv;

    val = data[0];
    i   = val % 40;
    val = val / 40;
    rv = fprintf(out, "%lu %u ", val, i);
    if (rv < 0) {
       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;
    }

    /*
     * Now try to look it up and print a symbolic version.
     */
    oiditem.data = 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;
       }
    }

    /*
     * Finally, on a new line, print the raw bytes (if requested).
     */
    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;
       }
    }

    return prettyNewline(out);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int prettyPrintString ( FILE out,
unsigned char *  str,
unsigned int  len,
unsigned int  level,
PRBool  raw 
) [static]

Definition at line 182 of file derprint.c.

{
    int rv;

    rv = prettyPrintStringStart(out, str, len, level);
    if (rv < 0)
       return rv;

    rv = prettyNewline(out);
    if (rv < 0)
       return rv;

    if (raw) {
       rv = prettyPrintLeaf(out, str, len, level);
       if (rv < 0)
           return rv;
    }

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int prettyPrintStringStart ( FILE out,
unsigned char *  str,
unsigned int  len,
unsigned int  level 
) [static]

Definition at line 150 of file derprint.c.

{
#define BUF_SIZE 100
    unsigned char buf[BUF_SIZE];
    int rv;

    if (len >= BUF_SIZE)
       len = BUF_SIZE - 1;

    rv = prettyNewline(out);
    if (rv < 0)
       return rv;

    rv = prettyIndent(out, level);
    if (rv < 0)
       return rv;

    memcpy(buf, str, len);
    buf[len] = '\000';

    rv = fprintf(out, "\"%s\"", buf);
    if (rv < 0) {
       PORT_SetError(SEC_ERROR_IO);
       return rv;
    }

    return 0;
#undef BUF_SIZE
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int prettyPrintTag ( FILE out,
unsigned char *  src,
unsigned char *  end,
unsigned char *  codep,
unsigned int  level,
PRBool  raw 
) [static]

Definition at line 373 of file derprint.c.

{
    int rv;
    unsigned char code, tagnum;

    if (src >= end) {
       PORT_SetError(SEC_ERROR_BAD_DER);
       return -1;
    }

    code = *src;
    tagnum = code & SEC_ASN1_TAGNUM_MASK;

    /*
     * NOTE: This code does not (yet) handle the high-tag-number form!
     */
    if (tagnum == SEC_ASN1_HIGH_TAG_NUMBER) {
        PORT_SetError(SEC_ERROR_BAD_DER);
       return -1;
    }

    if (raw)
       rv = prettyPrintByte(out, code, level);
    else
       rv = prettyIndent(out, level);

    if (rv < 0)
       return rv;

    if (code & SEC_ASN1_CONSTRUCTED) {
        rv = fprintf(out, "C-");
       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;
    }

    if (rv < 0) {
        PORT_SetError(SEC_ERROR_IO);
       return rv;
    }

    *codep = code;

    return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int prettyPrintTime ( FILE out,
unsigned char *  str,
unsigned int  len,
unsigned int  level,
PRBool  raw,
PRBool  utc 
) [static]

Definition at line 205 of file derprint.c.

{
    SECItem time_item;
    int rv;

    rv = prettyPrintStringStart(out, str, len, level);
    if (rv < 0)
       return rv;

    time_item.data = str;
    time_item.len = len;

    rv = fprintf(out, " (");
    if (rv < 0) {
       PORT_SetError(SEC_ERROR_IO);
       return rv;
    }

    if (utc)
       SECU_PrintUTCTime(out, &time_item, NULL, 0);
    else
       SECU_PrintGeneralizedTime(out, &time_item, NULL, 0);

    rv = fprintf(out, ")");
    if (rv < 0) {
       PORT_SetError(SEC_ERROR_IO);
       return rv;
    }

    rv = prettyNewline(out);
    if (rv < 0)
       return rv;

    if (raw) {
       rv = prettyPrintLeaf(out, str, len, level);
       if (rv < 0)
           return rv;
    }

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

int prettyColumn = 0 [static]

Definition at line 47 of file derprint.c.

char* prettyTagType[32] [static]

Definition at line 337 of file derprint.c.