forked from wolfSSL/wolfssl
Merge pull request #2622 from SparkiDev/ber_to_der_rework
Rework BER to DER to not be recursive
This commit is contained in:
@@ -174,10 +174,16 @@ WOLFSSL_LOCAL int GetLength_ex(const byte* input, word32* inOutIdx, int* len,
|
|||||||
return BUFFER_E;
|
return BUFFER_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bytes > sizeof(length)) {
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
while (bytes--) {
|
while (bytes--) {
|
||||||
b = input[idx++];
|
b = input[idx++];
|
||||||
length = (length << 8) | b;
|
length = (length << 8) | b;
|
||||||
}
|
}
|
||||||
|
if (length < 0) {
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
length = b;
|
length = b;
|
||||||
@@ -968,6 +974,150 @@ static word32 SetBitString(word32 len, byte unusedBits, byte* output)
|
|||||||
#endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 */
|
#endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 */
|
||||||
|
|
||||||
#ifdef ASN_BER_TO_DER
|
#ifdef ASN_BER_TO_DER
|
||||||
|
/* Pull informtation from the ASN.1 BER encoded item header */
|
||||||
|
static int GetBerHeader(const byte* data, word32* idx, word32 maxIdx,
|
||||||
|
byte* pTag, word32* pLen, int* indef)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
byte tag;
|
||||||
|
word32 i = *idx;
|
||||||
|
|
||||||
|
*indef = 0;
|
||||||
|
|
||||||
|
/* Check there is enough data for a minimal header */
|
||||||
|
if (i + 2 > maxIdx) {
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retrieve tag */
|
||||||
|
tag = data[i++];
|
||||||
|
|
||||||
|
/* Indefinite length handled specially */
|
||||||
|
if (data[i] == 0x80) {
|
||||||
|
/* Check valid tag for indefinite */
|
||||||
|
if (((tag & 0xc0) == 0) && ((tag & ASN_CONSTRUCTED) == 0x00)) {
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
*indef = 1;
|
||||||
|
}
|
||||||
|
else if (GetLength(data, &i, &len, maxIdx) < 0) {
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return tag, length and index after BER item header */
|
||||||
|
*pTag = tag;
|
||||||
|
*pLen = len;
|
||||||
|
*idx = i;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef INDEF_ITEMS_MAX
|
||||||
|
#define INDEF_ITEMS_MAX 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Indef length item data */
|
||||||
|
typedef struct Indef {
|
||||||
|
word32 start;
|
||||||
|
int depth;
|
||||||
|
int headerLen;
|
||||||
|
word32 len;
|
||||||
|
} Indef;
|
||||||
|
|
||||||
|
/* Indef length items */
|
||||||
|
typedef struct IndefItems
|
||||||
|
{
|
||||||
|
Indef len[INDEF_ITEMS_MAX];
|
||||||
|
int cnt;
|
||||||
|
int idx;
|
||||||
|
int depth;
|
||||||
|
} IndefItems;
|
||||||
|
|
||||||
|
|
||||||
|
/* Get header length of current item */
|
||||||
|
static int IndefItems_HeaderLen(IndefItems* items)
|
||||||
|
{
|
||||||
|
return items->len[items->idx].headerLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get data length of current item */
|
||||||
|
static word32 IndefItems_Len(IndefItems* items)
|
||||||
|
{
|
||||||
|
return items->len[items->idx].len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add a indefinite length item */
|
||||||
|
static int IndefItems_AddItem(IndefItems* items, word32 start)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (items->cnt == INDEF_ITEMS_MAX) {
|
||||||
|
ret = MEMORY_E;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
i = items->cnt++;
|
||||||
|
items->len[i].start = start;
|
||||||
|
items->len[i].depth = items->depth++;
|
||||||
|
items->len[i].headerLen = 1;
|
||||||
|
items->len[i].len = 0;
|
||||||
|
items->idx = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increase data length of current item */
|
||||||
|
static void IndefItems_AddData(IndefItems* items, word32 length)
|
||||||
|
{
|
||||||
|
items->len[items->idx].len += length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update header length of current item to reflect data length */
|
||||||
|
static void IndefItems_UpdateHeaderLen(IndefItems* items)
|
||||||
|
{
|
||||||
|
items->len[items->idx].headerLen +=
|
||||||
|
SetLength(items->len[items->idx].len, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Go to indefinite parent of current item */
|
||||||
|
static void IndefItems_Up(IndefItems* items)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int depth = items->len[items->idx].depth - 1;
|
||||||
|
|
||||||
|
for (i = items->cnt - 1; i >= 0; i--) {
|
||||||
|
if (items->len[i].depth == depth) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
items->idx = i;
|
||||||
|
items->depth = depth + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calcuate final length by adding length of indefinite child items */
|
||||||
|
static void IndefItems_CalcLength(IndefItems* items)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int idx = items->idx;
|
||||||
|
|
||||||
|
for (i = idx + 1; i < items->cnt; i++) {
|
||||||
|
if (items->len[i].depth == items->depth) {
|
||||||
|
items->len[idx].len += items->len[i].headerLen;
|
||||||
|
items->len[idx].len += items->len[i].len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
items->len[idx].headerLen += SetLength(items->len[idx].len, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add more data to indefinite length item */
|
||||||
|
static void IndefItems_MoreData(IndefItems* items, word32 length)
|
||||||
|
{
|
||||||
|
if (items->cnt > 0 && items->idx >= 0) {
|
||||||
|
items->len[items->idx].len += length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert a BER encoding with indefinite length items to DER.
|
/* Convert a BER encoding with indefinite length items to DER.
|
||||||
*
|
*
|
||||||
* ber BER encoded data.
|
* ber BER encoded data.
|
||||||
@@ -982,202 +1132,217 @@ static word32 SetBitString(word32 len, byte unusedBits, byte* output)
|
|||||||
*/
|
*/
|
||||||
int wc_BerToDer(const byte* ber, word32 berSz, byte* der, word32* derSz)
|
int wc_BerToDer(const byte* ber, word32 berSz, byte* der, word32* derSz)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
word32 i, j, k;
|
word32 i, j;
|
||||||
int len, l;
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
IndefItems* indefItems = NULL;
|
||||||
|
#else
|
||||||
|
IndefItems indefItems[1];
|
||||||
|
#endif
|
||||||
|
byte tag, basic;
|
||||||
|
word32 length;
|
||||||
int indef;
|
int indef;
|
||||||
int depth = 0;
|
|
||||||
byte type;
|
|
||||||
word32 cnt, sz;
|
|
||||||
word32 outSz = 0;
|
|
||||||
byte lenBytes[4];
|
|
||||||
|
|
||||||
if (ber == NULL || derSz == NULL)
|
if (ber == NULL || derSz == NULL)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
sz = 0;
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
outSz = *derSz;
|
indefItems = XMALLOC(sizeof(IndefItems), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (indefItems == NULL) {
|
||||||
|
ret = MEMORY_E;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
for (i = 0, j = 0; i < berSz; ) {
|
XMEMSET(indefItems, 0, sizeof(*indefItems));
|
||||||
word32 localIdx;
|
|
||||||
byte tag;
|
|
||||||
|
|
||||||
/* Check that there is data for an ASN item to parse. */
|
/* Calculate indefinite item lengths */
|
||||||
if (i + 2 > berSz)
|
for (i = 0; i < berSz; ) {
|
||||||
return ASN_PARSE_E;
|
word32 start = i;
|
||||||
|
|
||||||
/* End Of Content (EOC) mark end of indefinite length items.
|
/* Get next BER item */
|
||||||
* EOCs are not encoded in DER.
|
ret = GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
|
||||||
* Keep track of no. indefinite length items that have not been
|
if (ret != 0) {
|
||||||
* terminated in depth.
|
goto end;
|
||||||
*/
|
|
||||||
if (ber[i] == 0 && ber[i+1] == 0) {
|
|
||||||
if (depth == 0)
|
|
||||||
break;
|
|
||||||
if (--depth == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
i += 2;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Indefinite length is encoded as: 0x80 */
|
|
||||||
type = ber[i];
|
|
||||||
indef = ber[i+1] == ASN_INDEF_LENGTH;
|
|
||||||
|
|
||||||
localIdx = i;
|
|
||||||
if (GetASNTag(ber, &localIdx, &tag, berSz) != 0)
|
|
||||||
return ASN_PARSE_E;
|
|
||||||
|
|
||||||
if (indef && (type & 0xC0) == 0 &&
|
|
||||||
tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
|
|
||||||
tag != (ASN_SET | ASN_CONSTRUCTED)) {
|
|
||||||
/* Indefinite length OCTET STRING or other simple type.
|
|
||||||
* Put all the data into one entry.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Type no longer constructed. */
|
|
||||||
type &= ~ASN_CONSTRUCTED;
|
|
||||||
if (der != NULL) {
|
|
||||||
/* Ensure space for type. */
|
|
||||||
if (j + 1 >= outSz)
|
|
||||||
return BUFFER_E;
|
|
||||||
der[j] = type;
|
|
||||||
}
|
|
||||||
i++; j++;
|
|
||||||
/* Skip indefinite length. */
|
|
||||||
i++;
|
|
||||||
|
|
||||||
/* There must be further ASN1 items to combine. */
|
|
||||||
if (i + 2 > berSz)
|
|
||||||
return ASN_PARSE_E;
|
|
||||||
|
|
||||||
/* Calculate length of combined data. */
|
|
||||||
len = 0;
|
|
||||||
k = i;
|
|
||||||
while (ber[k] != 0x00) {
|
|
||||||
/* Each ASN item must be the same type as the constructed. */
|
|
||||||
if (ber[k] != type)
|
|
||||||
return ASN_PARSE_E;
|
|
||||||
k++;
|
|
||||||
|
|
||||||
ret = GetLength(ber, &k, &l, berSz);
|
|
||||||
if (ret < 0)
|
|
||||||
return ASN_PARSE_E;
|
|
||||||
k += l;
|
|
||||||
len += l;
|
|
||||||
|
|
||||||
/* Must at least have terminating EOC. */
|
|
||||||
if (k + 2 > berSz)
|
|
||||||
return ASN_PARSE_E;
|
|
||||||
}
|
|
||||||
/* Ensure a valid EOC ASN item. */
|
|
||||||
if (ber[k+1] != 0x00)
|
|
||||||
return ASN_PARSE_E;
|
|
||||||
|
|
||||||
if (der == NULL) {
|
|
||||||
/* Add length of ASN item length encoding and data. */
|
|
||||||
j += SetLength(len, lenBytes);
|
|
||||||
j += len;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* Check space for encoded length. */
|
|
||||||
if (SetLength(len, lenBytes) > outSz - j)
|
|
||||||
return BUFFER_E;
|
|
||||||
/* Encode new length. */
|
|
||||||
j += SetLength(len, der + j);
|
|
||||||
|
|
||||||
/* Encode data in single item. */
|
|
||||||
k = i;
|
|
||||||
while (ber[k] != 0x00) {
|
|
||||||
/* Skip ASN type. */
|
|
||||||
k++;
|
|
||||||
|
|
||||||
/* Find length of data in ASN item. */
|
|
||||||
ret = GetLength(ber, &k, &l, berSz);
|
|
||||||
if (ret < 0)
|
|
||||||
return ASN_PARSE_E;
|
|
||||||
|
|
||||||
/* Ensure space for data and copy in. */
|
|
||||||
if (j + l > outSz)
|
|
||||||
return BUFFER_E;
|
|
||||||
XMEMCPY(der + j, ber + k, l);
|
|
||||||
k += l; j += l;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Continue conversion after EOC. */
|
|
||||||
i = k + 2;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (der != NULL) {
|
|
||||||
/* Ensure space for type and at least one byte of length. */
|
|
||||||
if (j + 1 >= outSz)
|
|
||||||
return BUFFER_E;
|
|
||||||
/* Put in type. */
|
|
||||||
der[j] = ber[i];
|
|
||||||
}
|
|
||||||
i++; j++;
|
|
||||||
|
|
||||||
if (indef) {
|
if (indef) {
|
||||||
/* Skip indefinite length. */
|
/* Indefinite item - add to list */
|
||||||
i++;
|
ret = IndefItems_AddItem(indefItems, i);
|
||||||
/* Calculate the size of the data inside constructed. */
|
if (ret != 0) {
|
||||||
ret = wc_BerToDer(ber + i, berSz - i, NULL, &sz);
|
goto end;
|
||||||
if (ret != LENGTH_ONLY_E)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (der != NULL) {
|
|
||||||
/* Ensure space for encoded length. */
|
|
||||||
if (SetLength(sz, lenBytes) > outSz - j)
|
|
||||||
return BUFFER_E;
|
|
||||||
/* Encode real length. */
|
|
||||||
j += SetLength(sz, der + j);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* Add size of encoded length. */
|
|
||||||
j += SetLength(sz, lenBytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Another EOC to find. */
|
if ((tag & 0xC0) == 0 &&
|
||||||
depth++;
|
tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
|
||||||
|
tag != (ASN_SET | ASN_CONSTRUCTED)) {
|
||||||
|
/* Constructed basic type - get repeating tag */
|
||||||
|
basic = tag & (~ASN_CONSTRUCTED);
|
||||||
|
|
||||||
|
/* Add up lengths of each item below */
|
||||||
|
for (; i < berSz; ) {
|
||||||
|
/* Get next BER_item */
|
||||||
|
ret = GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
|
||||||
|
if (ret != 0) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End of content closes item */
|
||||||
|
if (tag == ASN_EOC) {
|
||||||
|
/* Must be zero length */
|
||||||
|
if (length != 0) {
|
||||||
|
ret = ASN_PARSE_E;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Must not be indefinite and tag must match parent */
|
||||||
|
if (indef || tag != basic) {
|
||||||
|
ret = ASN_PARSE_E;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add to length */
|
||||||
|
IndefItems_AddData(indefItems, length);
|
||||||
|
/* Skip data */
|
||||||
|
i += length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure we got an EOC and not end of data */
|
||||||
|
if (tag != ASN_EOC) {
|
||||||
|
ret = ASN_PARSE_E;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the header length to include the length field */
|
||||||
|
IndefItems_UpdateHeaderLen(indefItems);
|
||||||
|
/* Go to indefinte parent item */
|
||||||
|
IndefItems_Up(indefItems);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (tag == ASN_EOC) {
|
||||||
|
/* End-of-content must be 0 length */
|
||||||
|
if (length != 0) {
|
||||||
|
ret = ASN_PARSE_E;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
/* Check there is an item to close - missing EOC */
|
||||||
|
if (indefItems->depth == 0) {
|
||||||
|
ret = ASN_PARSE_E;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finish calculation of data length for indefinite item */
|
||||||
|
IndefItems_CalcLength(indefItems);
|
||||||
|
/* Go to indefinte parent item */
|
||||||
|
IndefItems_Up(indefItems);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Get the size of the encode length and length value. */
|
/* Known length item to add in - make sure enough data for it */
|
||||||
cnt = i;
|
if (i + length > berSz) {
|
||||||
ret = GetLength(ber, &cnt, &len, berSz);
|
ret = ASN_PARSE_E;
|
||||||
if (ret < 0)
|
goto end;
|
||||||
return ASN_PARSE_E;
|
|
||||||
cnt -= i;
|
|
||||||
|
|
||||||
/* Check there is enough data to copy out. */
|
|
||||||
if (i + cnt + len > berSz)
|
|
||||||
return ASN_PARSE_E;
|
|
||||||
|
|
||||||
if (der != NULL) {
|
|
||||||
/* Ensure space in DER buffer. */
|
|
||||||
if (j + cnt + len > outSz)
|
|
||||||
return BUFFER_E;
|
|
||||||
/* Copy length and data into DER buffer. */
|
|
||||||
XMEMCPY(der + j, ber + i, cnt + len);
|
|
||||||
}
|
}
|
||||||
/* Continue conversion after this ASN item. */
|
|
||||||
i += cnt + len;
|
/* Include all data - can't have indefinite inside definite */
|
||||||
j += cnt + len;
|
i += length;
|
||||||
|
/* Add entire item to current indefinite item */
|
||||||
|
IndefItems_MoreData(indefItems, i - start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Check we had a EOC for each indefinite item */
|
||||||
|
if (indefItems->depth != 0) {
|
||||||
|
ret = ASN_PARSE_E;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write out DER */
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
/* Reset index */
|
||||||
|
indefItems->idx = 0;
|
||||||
|
for (i = 0; i < berSz; ) {
|
||||||
|
word32 start = i;
|
||||||
|
|
||||||
|
/* Get item - checked above */
|
||||||
|
(void)GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
|
||||||
|
if (indef) {
|
||||||
|
if (der != NULL) {
|
||||||
|
/* Check enough space for header */
|
||||||
|
if (j + IndefItems_HeaderLen(indefItems) > *derSz) {
|
||||||
|
ret = BUFFER_E;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((tag & 0xC0) == 0 &&
|
||||||
|
tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
|
||||||
|
tag != (ASN_SET | ASN_CONSTRUCTED)) {
|
||||||
|
/* Remove constructed tag for basic types */
|
||||||
|
tag &= ~ASN_CONSTRUCTED;
|
||||||
|
}
|
||||||
|
/* Add tag and length */
|
||||||
|
der[j] = tag;
|
||||||
|
(void)SetLength(IndefItems_Len(indefItems), der + j + 1);
|
||||||
|
}
|
||||||
|
/* Add header length of indefinite item */
|
||||||
|
j += IndefItems_HeaderLen(indefItems);
|
||||||
|
|
||||||
|
if ((tag & 0xC0) == 0 &&
|
||||||
|
tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
|
||||||
|
tag != (ASN_SET | ASN_CONSTRUCTED)) {
|
||||||
|
/* For basic type - get each child item and add data */
|
||||||
|
for (; i < berSz; ) {
|
||||||
|
(void)GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
|
||||||
|
if (tag == ASN_EOC) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (der != NULL) {
|
||||||
|
if (j + length > *derSz) {
|
||||||
|
ret = BUFFER_E;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
XMEMCPY(der + j, ber + i, length);
|
||||||
|
}
|
||||||
|
j += length;
|
||||||
|
i += length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move to next indef item in list */
|
||||||
|
indefItems->idx++;
|
||||||
|
}
|
||||||
|
else if (tag == ASN_EOC) {
|
||||||
|
/* End-Of-Content is not written out in DER */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Write out definite length item as is. */
|
||||||
|
i += length;
|
||||||
|
if (der != NULL) {
|
||||||
|
/* Ensure space for item */
|
||||||
|
if (j + i - start > *derSz) {
|
||||||
|
ret = BUFFER_E;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
/* Copy item as is */
|
||||||
|
XMEMCPY(der + j, ber + start, i - start);
|
||||||
|
}
|
||||||
|
j += i - start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (depth >= 1)
|
/* Return the length of the DER encoded ASN.1 */
|
||||||
return ASN_PARSE_E;
|
*derSz = j;
|
||||||
|
|
||||||
/* Return length if no buffer to write to. */
|
|
||||||
if (der == NULL) {
|
if (der == NULL) {
|
||||||
*derSz = j;
|
ret = LENGTH_ONLY_E;
|
||||||
return LENGTH_ONLY_E;
|
|
||||||
}
|
}
|
||||||
|
end:
|
||||||
return 0;
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
if (indefItems != NULL) {
|
||||||
|
XFREE(indefItems, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -24791,7 +24791,7 @@ int berder_test(void)
|
|||||||
0x00, 0x00,
|
0x00, 0x00,
|
||||||
};
|
};
|
||||||
static const byte good4_out[] = {
|
static const byte good4_out[] = {
|
||||||
0x30, 0x0d,
|
0x30, 0x12,
|
||||||
0x02, 0x01, 0x01,
|
0x02, 0x01, 0x01,
|
||||||
0x30, 0x08,
|
0x30, 0x08,
|
||||||
0x04, 0x03, 0x01, 0x02, 0x03,
|
0x04, 0x03, 0x01, 0x02, 0x03,
|
||||||
@@ -24799,12 +24799,14 @@ int berder_test(void)
|
|||||||
0x31, 0x03,
|
0x31, 0x03,
|
||||||
0x06, 0x01, 0x01
|
0x06, 0x01, 0x01
|
||||||
};
|
};
|
||||||
|
static const byte good5_in[] = { 0x30, 0x03, 0x02, 0x01, 0x01 };
|
||||||
|
|
||||||
berDerTestData testData[] = {
|
berDerTestData testData[] = {
|
||||||
{ good1_in, sizeof(good1_in), good1_out, sizeof(good1_out) },
|
{ good1_in, sizeof(good1_in), good1_out, sizeof(good1_out) },
|
||||||
{ good2_in, sizeof(good2_in), good2_out, sizeof(good2_out) },
|
{ good2_in, sizeof(good2_in), good2_out, sizeof(good2_out) },
|
||||||
{ good3_in, sizeof(good3_in), good3_out, sizeof(good3_out) },
|
{ good3_in, sizeof(good3_in), good3_out, sizeof(good3_out) },
|
||||||
{ good4_in, sizeof(good4_in), good4_out, sizeof(good4_out) },
|
{ good4_in, sizeof(good4_in), good4_out, sizeof(good4_out) },
|
||||||
|
{ good5_in, sizeof(good5_in), good5_in , sizeof(good5_in ) },
|
||||||
};
|
};
|
||||||
|
|
||||||
for (i = 0; i < (int)(sizeof(testData) / sizeof(*testData)); i++) {
|
for (i = 0; i < (int)(sizeof(testData) / sizeof(*testData)); i++) {
|
||||||
@@ -24829,32 +24831,38 @@ int berder_test(void)
|
|||||||
if (ret != ASN_PARSE_E)
|
if (ret != ASN_PARSE_E)
|
||||||
return -9741;
|
return -9741;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (l = 0; l < testData[i].outSz-1; l++) {
|
||||||
|
ret = wc_BerToDer(testData[i].in, testData[i].inSz, out, &l);
|
||||||
|
if (ret != BUFFER_E)
|
||||||
|
return -9742;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = wc_BerToDer(NULL, 4, NULL, NULL);
|
ret = wc_BerToDer(NULL, 4, NULL, NULL);
|
||||||
if (ret != BAD_FUNC_ARG)
|
if (ret != BAD_FUNC_ARG)
|
||||||
return -9742;
|
return -9743;
|
||||||
ret = wc_BerToDer(out, 4, NULL, NULL);
|
ret = wc_BerToDer(out, 4, NULL, NULL);
|
||||||
if (ret != BAD_FUNC_ARG)
|
if (ret != BAD_FUNC_ARG)
|
||||||
return -9743;
|
return -9744;
|
||||||
ret = wc_BerToDer(NULL, 4, NULL, &len);
|
ret = wc_BerToDer(NULL, 4, NULL, &len);
|
||||||
if (ret != BAD_FUNC_ARG)
|
if (ret != BAD_FUNC_ARG)
|
||||||
return -9744;
|
return -9745;
|
||||||
ret = wc_BerToDer(NULL, 4, out, NULL);
|
ret = wc_BerToDer(NULL, 4, out, NULL);
|
||||||
if (ret != BAD_FUNC_ARG)
|
if (ret != BAD_FUNC_ARG)
|
||||||
return -9745;
|
return -9746;
|
||||||
ret = wc_BerToDer(out, 4, out, NULL);
|
ret = wc_BerToDer(out, 4, out, NULL);
|
||||||
if (ret != BAD_FUNC_ARG)
|
if (ret != BAD_FUNC_ARG)
|
||||||
return -9746;
|
return -9747;
|
||||||
ret = wc_BerToDer(NULL, 4, out, &len);
|
ret = wc_BerToDer(NULL, 4, out, &len);
|
||||||
if (ret != BAD_FUNC_ARG)
|
if (ret != BAD_FUNC_ARG)
|
||||||
return -9747;
|
return -9748;
|
||||||
|
|
||||||
for (l = 1; l < sizeof(good4_out); l++) {
|
for (l = 1; l < sizeof(good4_out); l++) {
|
||||||
len = l;
|
len = l;
|
||||||
ret = wc_BerToDer(good4_in, sizeof(good4_in), out, &len);
|
ret = wc_BerToDer(good4_in, sizeof(good4_in), out, &len);
|
||||||
if (ret != BUFFER_E)
|
if (ret != BUFFER_E)
|
||||||
return -9748;
|
return -9749;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -78,6 +78,7 @@ enum {
|
|||||||
|
|
||||||
/* ASN Tags */
|
/* ASN Tags */
|
||||||
enum ASN_Tags {
|
enum ASN_Tags {
|
||||||
|
ASN_EOC = 0x00,
|
||||||
ASN_BOOLEAN = 0x01,
|
ASN_BOOLEAN = 0x01,
|
||||||
ASN_INTEGER = 0x02,
|
ASN_INTEGER = 0x02,
|
||||||
ASN_BIT_STRING = 0x03,
|
ASN_BIT_STRING = 0x03,
|
||||||
|
Reference in New Issue
Block a user