summaryrefslogtreecommitdiff
path: root/nss/cmd/lib/berparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'nss/cmd/lib/berparse.c')
-rw-r--r--nss/cmd/lib/berparse.c419
1 files changed, 216 insertions, 203 deletions
diff --git a/nss/cmd/lib/berparse.c b/nss/cmd/lib/berparse.c
index 9e65361..8cd1eba 100644
--- a/nss/cmd/lib/berparse.c
+++ b/nss/cmd/lib/berparse.c
@@ -4,16 +4,20 @@
#include "secutil.h"
typedef enum {
- tagDone, lengthDone, leafDone, compositeDone,
+ tagDone,
+ lengthDone,
+ leafDone,
+ compositeDone,
notDone,
- parseError, parseComplete
+ parseError,
+ parseComplete
} ParseState;
typedef unsigned char Byte;
typedef void (*ParseProc)(BERParse *h, unsigned char **buf, int *len);
typedef struct {
SECArb arb;
- int pos; /* length from global start to item start */
+ int pos; /* length from global start to item start */
SECArb *parent;
} ParseStackElem;
@@ -24,8 +28,8 @@ struct BERParseStr {
int stackDepth;
ParseStackElem *stackPtr;
ParseStackElem *stack;
- int pending; /* bytes remaining to complete this part */
- int pos; /* running length of consumed characters */
+ int pending; /* bytes remaining to complete this part */
+ int pos; /* running length of consumed characters */
ParseState state;
PRBool keepLeaves;
PRBool derOnly;
@@ -39,46 +43,49 @@ struct BERParseStr {
#define UNKNOWN -1
-static unsigned char NextChar(BERParse *h, unsigned char **buf, int *len)
+static unsigned char
+NextChar(BERParse *h, unsigned char **buf, int *len)
{
unsigned char c = *(*buf)++;
(*len)--;
h->pos++;
if (h->filter)
- (*h->filter)(h->filterArg, &c, 1);
+ (*h->filter)(h->filterArg, &c, 1);
return c;
}
-static void ParseTag(BERParse *h, unsigned char **buf, int *len)
+static void
+ParseTag(BERParse *h, unsigned char **buf, int *len)
{
- SECArb* arb = &(h->stackPtr->arb);
+ SECArb *arb = &(h->stackPtr->arb);
arb->tag = NextChar(h, buf, len);
PORT_Assert(h->state == notDone);
- /*
- * NOTE: This does not handle the high-tag-number form
- */
+ /*
+ * NOTE: This does not handle the high-tag-number form
+ */
if ((arb->tag & DER_HIGH_TAG_NUMBER) == DER_HIGH_TAG_NUMBER) {
PORT_SetError(SEC_ERROR_BAD_DER);
- h->state = parseError;
- return;
+ h->state = parseError;
+ return;
}
h->pending = UNKNOWN;
arb->length = UNKNOWN;
if (arb->tag & DER_CONSTRUCTED) {
- arb->body.cons.numSubs = 0;
- arb->body.cons.subs = NULL;
+ arb->body.cons.numSubs = 0;
+ arb->body.cons.subs = NULL;
} else {
- arb->body.item.len = UNKNOWN;
- arb->body.item.data = NULL;
+ arb->body.item.len = UNKNOWN;
+ arb->body.item.data = NULL;
}
h->state = tagDone;
}
-static void ParseLength(BERParse *h, unsigned char **buf, int *len)
+static void
+ParseLength(BERParse *h, unsigned char **buf, int *len)
{
Byte b;
SECArb *arb = &(h->stackPtr->arb);
@@ -86,46 +93,47 @@ static void ParseLength(BERParse *h, unsigned char **buf, int *len)
PORT_Assert(h->state == notDone);
if (h->pending == UNKNOWN) {
- b = NextChar(h, buf, len);
- if ((b & 0x80) == 0) { /* short form */
- arb->length = b;
- /*
- * if the tag and the length are both zero bytes, then this
- * should be the marker showing end of list for the
- * indefinite length composite
- */
- if (arb->length == 0 && arb->tag == 0)
- h->state = compositeDone;
- else
- h->state = lengthDone;
- return;
- }
-
- h->pending = b & 0x7f;
- /* 0 implies this is an indefinite length */
- if (h->pending > 4) {
- PORT_SetError(SEC_ERROR_BAD_DER);
- h->state = parseError;
- return;
- }
- arb->length = 0;
+ b = NextChar(h, buf, len);
+ if ((b & 0x80) == 0) { /* short form */
+ arb->length = b;
+ /*
+ * if the tag and the length are both zero bytes, then this
+ * should be the marker showing end of list for the
+ * indefinite length composite
+ */
+ if (arb->length == 0 && arb->tag == 0)
+ h->state = compositeDone;
+ else
+ h->state = lengthDone;
+ return;
+ }
+
+ h->pending = b & 0x7f;
+ /* 0 implies this is an indefinite length */
+ if (h->pending > 4) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ h->state = parseError;
+ return;
+ }
+ arb->length = 0;
}
while ((*len > 0) && (h->pending > 0)) {
- b = NextChar(h, buf, len);
- arb->length = (arb->length << 8) + b;
- h->pending--;
+ b = NextChar(h, buf, len);
+ arb->length = (arb->length << 8) + b;
+ h->pending--;
}
if (h->pending == 0) {
- if (h->derOnly && (arb->length == 0))
- h->state = parseError;
- else
- h->state = lengthDone;
+ if (h->derOnly && (arb->length == 0))
+ h->state = parseError;
+ else
+ h->state = lengthDone;
}
return;
}
-static void ParseLeaf(BERParse *h, unsigned char **buf, int *len)
+static void
+ParseLeaf(BERParse *h, unsigned char **buf, int *len)
{
int count;
SECArb *arb = &(h->stackPtr->arb);
@@ -134,191 +142,196 @@ static void ParseLeaf(BERParse *h, unsigned char **buf, int *len)
PORT_Assert(h->pending >= 0);
if (*len < h->pending)
- count = *len;
+ count = *len;
else
- count = h->pending;
+ count = h->pending;
if (h->keepLeaves)
- memcpy(arb->body.item.data + arb->body.item.len, *buf, count);
+ memcpy(arb->body.item.data + arb->body.item.len, *buf, count);
if (h->filter)
- (*h->filter)(h->filterArg, *buf, count);
+ (*h->filter)(h->filterArg, *buf, count);
*buf += count;
*len -= count;
arb->body.item.len += count;
h->pending -= count;
h->pos += count;
if (h->pending == 0) {
- h->state = leafDone;
+ h->state = leafDone;
}
return;
}
-static void CreateArbNode(BERParse *h)
+static void
+CreateArbNode(BERParse *h)
{
SECArb *arb = PORT_ArenaAlloc(h->his, sizeof(SECArb));
*arb = h->stackPtr->arb;
- /*
+ /*
* Special case closing the root
- */
+ */
if (h->stackPtr == h->stack) {
- PORT_Assert(arb->tag & DER_CONSTRUCTED);
- h->state = parseComplete;
+ PORT_Assert(arb->tag & DER_CONSTRUCTED);
+ h->state = parseComplete;
} else {
- SECArb *parent = h->stackPtr->parent;
- parent->body.cons.subs = DS_ArenaGrow(
- h->his, parent->body.cons.subs,
- (parent->body.cons.numSubs) * sizeof(SECArb*),
- (parent->body.cons.numSubs + 1) * sizeof(SECArb*));
- parent->body.cons.subs[parent->body.cons.numSubs] = arb;
- parent->body.cons.numSubs++;
- h->proc = ParseTag;
- h->state = notDone;
- h->pending = UNKNOWN;
+ SECArb *parent = h->stackPtr->parent;
+ parent->body.cons.subs = DS_ArenaGrow(
+ h->his, parent->body.cons.subs,
+ (parent->body.cons.numSubs) * sizeof(SECArb *),
+ (parent->body.cons.numSubs + 1) * sizeof(SECArb *));
+ parent->body.cons.subs[parent->body.cons.numSubs] = arb;
+ parent->body.cons.numSubs++;
+ h->proc = ParseTag;
+ h->state = notDone;
+ h->pending = UNKNOWN;
}
if (h->after)
- (*h->after)(h->afterArg, arb, h->stackPtr - h->stack, PR_FALSE);
+ (*h->after)(h->afterArg, arb, h->stackPtr - h->stack, PR_FALSE);
}
-SECStatus BER_ParseSome(BERParse *h, unsigned char *buf, int len)
+SECStatus
+BER_ParseSome(BERParse *h, unsigned char *buf, int len)
{
- if (h->state == parseError) return PR_TRUE;
+ if (h->state == parseError)
+ return PR_TRUE;
while (len) {
(*h->proc)(h, &buf, &len);
- if (h->state == parseComplete) {
- PORT_SetError(SEC_ERROR_BAD_DER);
- h->state = parseError;
- return PR_TRUE;
- }
- if (h->state == parseError) return PR_TRUE;
- PORT_Assert(h->state != parseComplete);
+ if (h->state == parseComplete) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ h->state = parseError;
+ return PR_TRUE;
+ }
+ if (h->state == parseError)
+ return PR_TRUE;
+ PORT_Assert(h->state != parseComplete);
if (h->state <= compositeDone) {
- if (h->proc == ParseTag) {
- PORT_Assert(h->state == tagDone);
- h->proc = ParseLength;
- h->state = notDone;
- } else if (h->proc == ParseLength) {
- SECArb *arb = &(h->stackPtr->arb);
- PORT_Assert(h->state == lengthDone || h->state == compositeDone);
-
- if (h->before)
- (*h->before)(h->beforeArg, arb,
- h->stackPtr - h->stack, PR_TRUE);
-
- /*
- * Check to see if this is the end of an indefinite
- * length composite
- */
- if (h->state == compositeDone) {
- SECArb *parent = h->stackPtr->parent;
- PORT_Assert(parent);
- PORT_Assert(parent->tag & DER_CONSTRUCTED);
- if (parent->length != 0) {
- PORT_SetError(SEC_ERROR_BAD_DER);
- h->state = parseError;
- return PR_TRUE;
- }
- /*
- * NOTE: This does not check for an indefinite length
- * composite being contained inside a definite length
- * composite. It is not clear that is legal.
- */
- h->stackPtr--;
- CreateArbNode(h);
- } else {
- h->stackPtr->pos = h->pos;
-
-
- if (arb->tag & DER_CONSTRUCTED) {
- SECArb *parent;
- /*
- * Make sure there is room on the stack before we
- * stick anything else there.
- */
- PORT_Assert(h->stackPtr - h->stack < h->stackDepth);
- if (h->stackPtr - h->stack == h->stackDepth - 1) {
- int newDepth = h->stackDepth * 2;
- h->stack = DS_ArenaGrow(h->mine, h->stack,
- sizeof(ParseStackElem) * h->stackDepth,
- sizeof(ParseStackElem) * newDepth);
- h->stackPtr = h->stack + h->stackDepth + 1;
- h->stackDepth = newDepth;
- }
- parent = &(h->stackPtr->arb);
- h->stackPtr++;
- h->stackPtr->parent = parent;
- h->proc = ParseTag;
- h->state = notDone;
- h->pending = UNKNOWN;
- } else {
- if (arb->length < 0) {
- PORT_SetError(SEC_ERROR_BAD_DER);
- h->state = parseError;
- return PR_TRUE;
- }
- arb->body.item.len = 0;
- if (arb->length > 0 && h->keepLeaves) {
- arb->body.item.data =
- PORT_ArenaAlloc(h->his, arb->length);
- } else {
- arb->body.item.data = NULL;
- }
- h->proc = ParseLeaf;
- h->state = notDone;
- h->pending = arb->length;
- }
- }
- } else {
- ParseStackElem *parent;
- PORT_Assert(h->state = leafDone);
- PORT_Assert(h->proc == ParseLeaf);
-
- for (;;) {
- CreateArbNode(h);
- if (h->stackPtr == h->stack)
- break;
- parent = (h->stackPtr - 1);
- PORT_Assert(parent->arb.tag & DER_CONSTRUCTED);
- if (parent->arb.length == 0) /* need explicit end */
- break;
- if (parent->pos + parent->arb.length > h->pos)
- break;
- if (parent->pos + parent->arb.length < h->pos) {
- PORT_SetError(SEC_ERROR_BAD_DER);
- h->state = parseError;
- return PR_TRUE;
- }
- h->stackPtr = parent;
- }
- }
-
- }
+ if (h->proc == ParseTag) {
+ PORT_Assert(h->state == tagDone);
+ h->proc = ParseLength;
+ h->state = notDone;
+ } else if (h->proc == ParseLength) {
+ SECArb *arb = &(h->stackPtr->arb);
+ PORT_Assert(h->state == lengthDone || h->state == compositeDone);
+
+ if (h->before)
+ (*h->before)(h->beforeArg, arb,
+ h->stackPtr - h->stack, PR_TRUE);
+
+ /*
+ * Check to see if this is the end of an indefinite
+ * length composite
+ */
+ if (h->state == compositeDone) {
+ SECArb *parent = h->stackPtr->parent;
+ PORT_Assert(parent);
+ PORT_Assert(parent->tag & DER_CONSTRUCTED);
+ if (parent->length != 0) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ h->state = parseError;
+ return PR_TRUE;
+ }
+ /*
+ * NOTE: This does not check for an indefinite length
+ * composite being contained inside a definite length
+ * composite. It is not clear that is legal.
+ */
+ h->stackPtr--;
+ CreateArbNode(h);
+ } else {
+ h->stackPtr->pos = h->pos;
+
+ if (arb->tag & DER_CONSTRUCTED) {
+ SECArb *parent;
+ /*
+ * Make sure there is room on the stack before we
+ * stick anything else there.
+ */
+ PORT_Assert(h->stackPtr - h->stack < h->stackDepth);
+ if (h->stackPtr - h->stack == h->stackDepth - 1) {
+ int newDepth = h->stackDepth * 2;
+ h->stack = DS_ArenaGrow(h->mine, h->stack,
+ sizeof(ParseStackElem) *
+ h->stackDepth,
+ sizeof(ParseStackElem) *
+ newDepth);
+ h->stackPtr = h->stack + h->stackDepth + 1;
+ h->stackDepth = newDepth;
+ }
+ parent = &(h->stackPtr->arb);
+ h->stackPtr++;
+ h->stackPtr->parent = parent;
+ h->proc = ParseTag;
+ h->state = notDone;
+ h->pending = UNKNOWN;
+ } else {
+ if (arb->length < 0) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ h->state = parseError;
+ return PR_TRUE;
+ }
+ arb->body.item.len = 0;
+ if (arb->length > 0 && h->keepLeaves) {
+ arb->body.item.data =
+ PORT_ArenaAlloc(h->his, arb->length);
+ } else {
+ arb->body.item.data = NULL;
+ }
+ h->proc = ParseLeaf;
+ h->state = notDone;
+ h->pending = arb->length;
+ }
+ }
+ } else {
+ ParseStackElem *parent;
+ PORT_Assert(h->state = leafDone);
+ PORT_Assert(h->proc == ParseLeaf);
+
+ for (;;) {
+ CreateArbNode(h);
+ if (h->stackPtr == h->stack)
+ break;
+ parent = (h->stackPtr - 1);
+ PORT_Assert(parent->arb.tag & DER_CONSTRUCTED);
+ if (parent->arb.length == 0) /* need explicit end */
+ break;
+ if (parent->pos + parent->arb.length > h->pos)
+ break;
+ if (parent->pos + parent->arb.length < h->pos) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ h->state = parseError;
+ return PR_TRUE;
+ }
+ h->stackPtr = parent;
+ }
+ }
+ }
}
return PR_FALSE;
}
-BERParse *BER_ParseInit(PLArenaPool *arena, PRBool derOnly)
+BERParse *
+BER_ParseInit(PLArenaPool *arena, PRBool derOnly)
{
BERParse *h;
PLArenaPool *temp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (temp == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
}
h = PORT_ArenaAlloc(temp, sizeof(BERParse));
if (h == NULL) {
- PORT_FreeArena(temp, PR_FALSE);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
+ PORT_FreeArena(temp, PR_FALSE);
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
}
h->his = arena;
h->mine = temp;
h->proc = ParseTag;
h->stackDepth = 20;
h->stack = PORT_ArenaZAlloc(h->mine,
- sizeof(ParseStackElem) * h->stackDepth);
+ sizeof(ParseStackElem) * h->stackDepth);
h->stackPtr = h->stack;
h->state = notDone;
h->pos = 0;
@@ -330,16 +343,17 @@ BERParse *BER_ParseInit(PLArenaPool *arena, PRBool derOnly)
return h;
}
-SECArb *BER_ParseFini(BERParse *h)
+SECArb *
+BER_ParseFini(BERParse *h)
{
PLArenaPool *myArena = h->mine;
SECArb *arb;
if (h->state != parseComplete) {
- arb = NULL;
+ arb = NULL;
} else {
- arb = PORT_ArenaAlloc(h->his, sizeof(SECArb));
- *arb = h->stackPtr->arb;
+ arb = PORT_ArenaAlloc(h->his, sizeof(SECArb));
+ *arb = h->stackPtr->arb;
}
PORT_FreeArena(myArena, PR_FALSE);
@@ -347,29 +361,28 @@ SECArb *BER_ParseFini(BERParse *h)
return arb;
}
-
-void BER_SetFilter(BERParse *h, BERFilterProc proc, void *instance)
+void
+BER_SetFilter(BERParse *h, BERFilterProc proc, void *instance)
{
h->filter = proc;
h->filterArg = instance;
}
-void BER_SetLeafStorage(BERParse *h, PRBool keep)
+void
+BER_SetLeafStorage(BERParse *h, PRBool keep)
{
h->keepLeaves = keep;
}
-void BER_SetNotifyProc(BERParse *h, BERNotifyProc proc, void *instance,
- PRBool beforeData)
+void
+BER_SetNotifyProc(BERParse *h, BERNotifyProc proc, void *instance,
+ PRBool beforeData)
{
if (beforeData) {
- h->before = proc;
- h->beforeArg = instance;
+ h->before = proc;
+ h->beforeArg = instance;
} else {
- h->after = proc;
- h->afterArg = instance;
+ h->after = proc;
+ h->afterArg = instance;
}
}
-
-
-