// This function is used to retrieve the lenght of a DER encoded // item. It looks to see if this a multibyte length and then // interprets the buffer accordingly to get the actual length value. // This funciton is used mostly while parsing the DER headers. // // A DER encoded item has the following structure: // // <tag><length<data consisting of lenght bytes> static int32_t getDERItemLength(unsigned char *data, unsigned char *end, unsigned long *bytesUsed, bool *indefinite) { unsigned char lbyte = *data++; int32_t length = -1; *indefinite = false; if (lbyte >= 0x80) { // Multibyte length unsigned nb = (unsigned) (lbyte & 0x7f); if (nb > 4) { return -1; } if (nb > 0) { if ((data+nb) > end) { return -1; } length = getInteger256(data, nb); if (length < 0) return -1; } else { *indefinite = true; length = 0; } *bytesUsed = nb+1; } else { length = lbyte; *bytesUsed = 1; } return length; }
static int prettyPrintLength(FILE *out, const unsigned char *data, const unsigned char *end, 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; } 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) { 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; } } 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; }