summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2014-05-01 23:15:59 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2014-05-01 23:15:59 +0200
commite46d7b0078f1c2b870960cccb16a5af54534746c (patch)
tree48df52cf6578d3a2447053aa4f070dadb4ab01de
parent2b7c4c3d9ce4d6b10559f88c705e8aebd44ad7df (diff)
downloadgnutls-e46d7b0078f1c2b870960cccb16a5af54534746c.tar.gz
updated included libtasn1.
-rw-r--r--lib/minitasn1/coding.c1895
-rw-r--r--lib/minitasn1/decoding.c4952
-rw-r--r--lib/minitasn1/element.c1264
-rw-r--r--lib/minitasn1/element.h12
-rw-r--r--lib/minitasn1/errors.c71
-rw-r--r--lib/minitasn1/gstr.c59
-rw-r--r--lib/minitasn1/gstr.h8
-rw-r--r--lib/minitasn1/int.h76
-rw-r--r--lib/minitasn1/libtasn1.h296
-rw-r--r--lib/minitasn1/parser_aux.c1399
-rw-r--r--lib/minitasn1/parser_aux.h93
-rw-r--r--lib/minitasn1/structure.c1750
-rw-r--r--lib/minitasn1/structure.h13
-rw-r--r--lib/minitasn1/version.c11
14 files changed, 6022 insertions, 5877 deletions
diff --git a/lib/minitasn1/coding.c b/lib/minitasn1/coding.c
index 8e71683d24..e4eb060bc8 100644
--- a/lib/minitasn1/coding.c
+++ b/lib/minitasn1/coding.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2002-2014 Free Software Foundation, Inc.
*
* This file is part of LIBTASN1.
*
@@ -30,6 +30,7 @@
#include "parser_aux.h"
#include <gstr.h>
#include "element.h"
+#include "minmax.h"
#include <structure.h>
#define MAX_TAG_LEN 16
@@ -44,62 +45,65 @@
/* Return: */
/******************************************************/
static void
-_asn1_error_description_value_not_found(asn1_node node,
- char *ErrorDescription)
+_asn1_error_description_value_not_found (asn1_node node,
+ char *ErrorDescription)
{
- if (ErrorDescription == NULL)
- return;
+ if (ErrorDescription == NULL)
+ return;
- Estrcpy(ErrorDescription, ":: value of element '");
- _asn1_hierarchical_name(node,
- ErrorDescription +
- strlen(ErrorDescription),
- ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40);
- Estrcat(ErrorDescription, "' not found");
+ Estrcpy (ErrorDescription, ":: value of element '");
+ _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
+ ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40);
+ Estrcat (ErrorDescription, "' not found");
}
/**
* asn1_length_der:
* @len: value to convert.
- * @der: the encoding (may be %NULL).
+ * @der: buffer to hold the returned encoding (may be %NULL).
* @der_len: number of meaningful bytes of ANS (der[0]..der[der_len-1]).
*
* Creates the DER encoding of the provided length value.
* The @der buffer must have enough room for the output. The maximum
* length this function will encode is %ASN1_MAX_LENGTH_SIZE.
- *
+ *
* To know the size of the DER encoding use a %NULL value for @der.
**/
void
-asn1_length_der(unsigned long int len, unsigned char *der, int *der_len)
+asn1_length_der (unsigned long int len, unsigned char *der, int *der_len)
{
- int k;
- unsigned char temp[ASN1_MAX_LENGTH_SIZE];
+ int k;
+ unsigned char temp[ASN1_MAX_LENGTH_SIZE];
#if SIZEOF_UNSIGNED_LONG_INT > 8
- len &= 0xFFFFFFFFFFFFFFFF;
+ len &= 0xFFFFFFFFFFFFFFFF;
#endif
- if (len < 128) {
- /* short form */
- if (der != NULL)
- der[0] = (unsigned char) len;
- *der_len = 1;
- } else {
- /* Long form */
- k = 0;
- while (len) {
- temp[k++] = len & 0xFF;
- len = len >> 8;
- }
- *der_len = k + 1;
- if (der != NULL) {
- der[0] = ((unsigned char) k & 0x7F) + 128;
- while (k--)
- der[*der_len - 1 - k] = temp[k];
- }
+ if (len < 128)
+ {
+ /* short form */
+ if (der != NULL)
+ der[0] = (unsigned char) len;
+ *der_len = 1;
+ }
+ else
+ {
+ /* Long form */
+ k = 0;
+ while (len)
+ {
+ temp[k++] = len & 0xFF;
+ len = len >> 8;
}
+ *der_len = k + 1;
+ if (der != NULL)
+ {
+ der[0] = ((unsigned char) k & 0x7F) + 128;
+ while (k--)
+ der[*der_len - 1 - k] = temp[k];
+ }
+ }
}
/******************************************************/
@@ -116,33 +120,36 @@ asn1_length_der(unsigned long int len, unsigned char *der, int *der_len)
/* Return: */
/******************************************************/
static void
-_asn1_tag_der(unsigned char class, unsigned int tag_value,
- unsigned char *ans, int *ans_len)
+_asn1_tag_der (unsigned char class, unsigned int tag_value,
+ unsigned char *ans, int *ans_len)
{
- int k;
- unsigned char temp[ASN1_MAX_TAG_SIZE];
-
- if (tag_value < 31) {
- /* short form */
- ans[0] =
- (class & 0xE0) + ((unsigned char) (tag_value & 0x1F));
- *ans_len = 1;
- } else {
- /* Long form */
- ans[0] = (class & 0xE0) + 31;
- k = 0;
- while (tag_value != 0) {
- temp[k++] = tag_value & 0x7F;
- tag_value >>= 7;
-
- if (k > ASN1_MAX_TAG_SIZE - 1)
- break; /* will not encode larger tags */
- }
- *ans_len = k + 1;
- while (k--)
- ans[*ans_len - 1 - k] = temp[k] + 128;
- ans[*ans_len - 1] -= 128;
+ int k;
+ unsigned char temp[ASN1_MAX_TAG_SIZE];
+
+ if (tag_value < 31)
+ {
+ /* short form */
+ ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F));
+ *ans_len = 1;
+ }
+ else
+ {
+ /* Long form */
+ ans[0] = (class & 0xE0) + 31;
+ k = 0;
+ while (tag_value != 0)
+ {
+ temp[k++] = tag_value & 0x7F;
+ tag_value >>= 7;
+
+ if (k > ASN1_MAX_TAG_SIZE - 1)
+ break; /* will not encode larger tags */
}
+ *ans_len = k + 1;
+ while (k--)
+ ans[*ans_len - 1 - k] = temp[k] + 128;
+ ans[*ans_len - 1] -= 128;
+ }
}
/**
@@ -163,17 +170,17 @@ _asn1_tag_der(unsigned char class, unsigned int tag_value,
* asn1_length_der().
**/
void
-asn1_octet_der(const unsigned char *str, int str_len,
- unsigned char *der, int *der_len)
+asn1_octet_der (const unsigned char *str, int str_len,
+ unsigned char *der, int *der_len)
{
- int len_len;
+ int len_len;
- if (der == NULL || str_len < 0)
- return;
+ if (der == NULL || str_len < 0)
+ return;
- asn1_length_der(str_len, der, &len_len);
- memcpy(der + len_len, str, str_len);
- *der_len = str_len + len_len;
+ asn1_length_der (str_len, der, &len_len);
+ memcpy (der + len_len, str, str_len);
+ *der_len = str_len + len_len;
}
@@ -186,56 +193,55 @@ asn1_octet_der(const unsigned char *str, int str_len,
* @tl_len: the bytes of the @tl field
*
* Creates the DER encoding for various simple ASN.1 types like strings etc.
- * It stores the tag and length in @tl, which should have space for at least
+ * It stores the tag and length in @tl, which should have space for at least
* %ASN1_MAX_TL_SIZE bytes. Initially @tl_len should contain the size of @tl.
*
* The complete DER encoding should consist of the value in @tl appended
* with the provided @str.
*
- * Returns: %ASN1_SUCCESS if successful or an error value.
+ * Returns: %ASN1_SUCCESS if successful or an error value.
**/
int
-asn1_encode_simple_der(unsigned int etype, const unsigned char *str,
- unsigned int str_len, unsigned char *tl,
- unsigned int *tl_len)
+asn1_encode_simple_der (unsigned int etype, const unsigned char *str,
+ unsigned int str_len, unsigned char *tl,
+ unsigned int *tl_len)
{
- int tag_len, len_len;
- unsigned tlen;
- unsigned char der_tag[ASN1_MAX_TAG_SIZE];
- unsigned char der_length[ASN1_MAX_LENGTH_SIZE];
- unsigned char *p;
+ int tag_len, len_len;
+ unsigned tlen;
+ unsigned char der_tag[ASN1_MAX_TAG_SIZE];
+ unsigned char der_length[ASN1_MAX_LENGTH_SIZE];
+ unsigned char *p;
- if (str == NULL)
- return ASN1_VALUE_NOT_VALID;
+ if (str == NULL)
+ return ASN1_VALUE_NOT_VALID;
- if (ETYPE_OK(etype) == 0)
- return ASN1_VALUE_NOT_VALID;
+ if (ETYPE_OK (etype) == 0)
+ return ASN1_VALUE_NOT_VALID;
- /* doesn't handle constructed classes */
- if (ETYPE_CLASS(etype) != ASN1_CLASS_UNIVERSAL)
- return ASN1_VALUE_NOT_VALID;
+ /* doesn't handle constructed classes */
+ if (ETYPE_CLASS (etype) != ASN1_CLASS_UNIVERSAL)
+ return ASN1_VALUE_NOT_VALID;
- _asn1_tag_der(ETYPE_CLASS(etype), ETYPE_TAG(etype),
- der_tag, &tag_len);
+ _asn1_tag_der (ETYPE_CLASS (etype), ETYPE_TAG (etype), der_tag, &tag_len);
- asn1_length_der(str_len, der_length, &len_len);
+ asn1_length_der (str_len, der_length, &len_len);
- if (tag_len <= 0 || len_len <= 0)
- return ASN1_VALUE_NOT_VALID;
+ if (tag_len <= 0 || len_len <= 0)
+ return ASN1_VALUE_NOT_VALID;
- tlen = tag_len + len_len;
+ tlen = tag_len + len_len;
- if (*tl_len < tlen)
- return ASN1_MEM_ERROR;
+ if (*tl_len < tlen)
+ return ASN1_MEM_ERROR;
- p = tl;
- memcpy(p, der_tag, tag_len);
- p += tag_len;
- memcpy(p, der_length, len_len);
+ p = tl;
+ memcpy (p, der_tag, tag_len);
+ p += tag_len;
+ memcpy (p, der_length, len_len);
- *tl_len = tlen;
+ *tl_len = tlen;
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
/******************************************************/
@@ -253,24 +259,24 @@ asn1_encode_simple_der(unsigned int etype, const unsigned char *str,
/* ASN1_SUCCESS otherwise */
/******************************************************/
static int
-_asn1_time_der(unsigned char *str, int str_len, unsigned char *der,
- int *der_len)
+_asn1_time_der (unsigned char *str, int str_len, unsigned char *der,
+ int *der_len)
{
- int len_len;
- int max_len;
+ int len_len;
+ int max_len;
- max_len = *der_len;
+ max_len = *der_len;
- asn1_length_der(str_len, (max_len > 0) ? der : NULL, &len_len);
+ asn1_length_der (str_len, (max_len > 0) ? der : NULL, &len_len);
- if ((len_len + str_len) <= max_len)
- memcpy(der + len_len, str, str_len);
- *der_len = len_len + str_len;
+ if ((len_len + str_len) <= max_len)
+ memcpy (der + len_len, str, str_len);
+ *der_len = len_len + str_len;
- if ((*der_len) > max_len)
- return ASN1_MEM_ERROR;
+ if ((*der_len) > max_len)
+ return ASN1_MEM_ERROR;
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
@@ -322,76 +328,84 @@ _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
/* must store the length of DER. */
/* Return: */
/* ASN1_MEM_ERROR when DER isn't big enough */
-/* ASN1_SUCCESS otherwise */
+/* ASN1_SUCCESS if succesful */
+/* or an error value. */
/******************************************************/
static int
-_asn1_objectid_der(unsigned char *str, unsigned char *der, int *der_len)
+_asn1_objectid_der (unsigned char *str, unsigned char *der, int *der_len)
{
- int len_len, counter, k, first, max_len;
- char *temp, *n_end, *n_start;
- unsigned char bit7;
- unsigned long val, val1 = 0;
- int str_len = _asn1_strlen(str);
-
- max_len = *der_len;
-
- temp = malloc(str_len + 2);
- if (temp == NULL)
- return ASN1_MEM_ALLOC_ERROR;
-
- memcpy(temp, str, str_len);
- temp[str_len] = '.';
- temp[str_len + 1] = 0;
-
- counter = 0;
- n_start = temp;
- while ((n_end = strchr(n_start, '.'))) {
- *n_end = 0;
- val = strtoul(n_start, NULL, 10);
- counter++;
-
- if (counter == 1)
- val1 = val;
- else if (counter == 2) {
- if (max_len > 0)
- der[0] = 40 * val1 + val;
- *der_len = 1;
- } else {
- first = 0;
- for (k = 4; k >= 0; k--) {
- bit7 = (val >> (k * 7)) & 0x7F;
- if (bit7 || first || !k) {
- if (k)
- bit7 |= 0x80;
- if (max_len > (*der_len))
- der[*der_len] = bit7;
- (*der_len)++;
- first = 1;
- }
- }
-
- }
- n_start = n_end + 1;
+ int len_len, counter, k, first, max_len;
+ char *temp, *n_end, *n_start;
+ unsigned char bit7;
+ unsigned long val, val1 = 0;
+ int str_len = _asn1_strlen (str);
+
+ max_len = *der_len;
+
+ temp = malloc (str_len + 2);
+ if (temp == NULL)
+ return ASN1_MEM_ALLOC_ERROR;
+
+ memcpy (temp, str, str_len);
+ temp[str_len] = '.';
+ temp[str_len + 1] = 0;
+
+ counter = 0;
+ n_start = temp;
+ while ((n_end = strchr (n_start, '.')))
+ {
+ *n_end = 0;
+ val = strtoul (n_start, NULL, 10);
+ counter++;
+
+ if (counter == 1)
+ val1 = val;
+ else if (counter == 2)
+ {
+ if (max_len > 0)
+ der[0] = 40 * val1 + val;
+ *der_len = 1;
}
+ else
+ {
+ first = 0;
+ for (k = 4; k >= 0; k--)
+ {
+ bit7 = (val >> (k * 7)) & 0x7F;
+ if (bit7 || first || !k)
+ {
+ if (k)
+ bit7 |= 0x80;
+ if (max_len > (*der_len))
+ der[*der_len] = bit7;
+ (*der_len)++;
+ first = 1;
+ }
+ }
- asn1_length_der(*der_len, NULL, &len_len);
- if (max_len >= (*der_len + len_len)) {
- memmove(der + len_len, der, *der_len);
- asn1_length_der(*der_len, der, &len_len);
}
- *der_len += len_len;
+ n_start = n_end + 1;
+ }
+
+ asn1_length_der (*der_len, NULL, &len_len);
+ if (max_len >= (*der_len + len_len))
+ {
+ memmove (der + len_len, der, *der_len);
+ asn1_length_der (*der_len, der, &len_len);
+ }
+ *der_len += len_len;
- free(temp);
+ free (temp);
- if (max_len < (*der_len))
- return ASN1_MEM_ERROR;
+ if (max_len < (*der_len))
+ return ASN1_MEM_ERROR;
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
static const unsigned char bit_mask[] =
- { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };
+ { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };
/**
* asn1_bit_der:
@@ -413,25 +427,25 @@ static const unsigned char bit_mask[] =
* asn1_length_der().
**/
void
-asn1_bit_der(const unsigned char *str, int bit_len,
- unsigned char *der, int *der_len)
+asn1_bit_der (const unsigned char *str, int bit_len,
+ unsigned char *der, int *der_len)
{
- int len_len, len_byte, len_pad;
-
- if (der == NULL)
- return;
-
- len_byte = bit_len >> 3;
- len_pad = 8 - (bit_len & 7);
- if (len_pad == 8)
- len_pad = 0;
- else
- len_byte++;
- asn1_length_der(len_byte + 1, der, &len_len);
- der[len_len] = len_pad;
- memcpy(der + len_len + 1, str, len_byte);
- der[len_len + len_byte] &= bit_mask[len_pad];
- *der_len = len_byte + len_len + 1;
+ int len_len, len_byte, len_pad;
+
+ if (der == NULL)
+ return;
+
+ len_byte = bit_len >> 3;
+ len_pad = 8 - (bit_len & 7);
+ if (len_pad == 8)
+ len_pad = 0;
+ else
+ len_byte++;
+ asn1_length_der (len_byte + 1, der, &len_len);
+ der[len_len] = len_pad;
+ memcpy (der + len_len + 1, str, len_byte);
+ der[len_len + len_byte] &= bit_mask[len_pad];
+ *der_len = len_byte + len_len + 1;
}
@@ -450,117 +464,114 @@ asn1_bit_der(const unsigned char *str, int bit_len,
/* otherwise ASN1_SUCCESS. */
/******************************************************/
static int
-_asn1_complete_explicit_tag(asn1_node node, unsigned char *der,
- int *counter, int *max_len)
+_asn1_complete_explicit_tag (asn1_node node, unsigned char *der,
+ int *counter, int *max_len)
{
- asn1_node p;
- int is_tag_implicit, len2, len3;
- unsigned char temp[SIZEOF_UNSIGNED_INT];
-
- is_tag_implicit = 0;
-
- if (node->type & CONST_TAG) {
- p = node->down;
- /* When there are nested tags we must complete them reverse to
- the order they were created. This is because completing a tag
- modifies all data within it, including the incomplete tags
- which store buffer positions -- simon@josefsson.org 2002-09-06
- */
- while (p->right)
- p = p->right;
- while (p && p != node->down->left) {
- if (type_field(p->type) == ASN1_ETYPE_TAG) {
- if (p->type & CONST_EXPLICIT) {
- len2 = strtol(p->name, NULL, 10);
- _asn1_set_name(p, NULL);
- asn1_length_der(*counter - len2,
- temp, &len3);
- if (len3 <= (*max_len)) {
- memmove(der + len2 + len3,
- der + len2,
- *counter - len2);
- memcpy(der + len2, temp,
- len3);
- }
- *max_len -= len3;
- *counter += len3;
- is_tag_implicit = 0;
- } else { /* CONST_IMPLICIT */
- if (!is_tag_implicit) {
- is_tag_implicit = 1;
- }
- }
- }
- p = p->left;
+ asn1_node p;
+ int is_tag_implicit, len2, len3;
+ unsigned char temp[SIZEOF_UNSIGNED_INT];
+
+ is_tag_implicit = 0;
+
+ if (node->type & CONST_TAG)
+ {
+ p = node->down;
+ if (p == NULL)
+ return ASN1_DER_ERROR;
+ /* When there are nested tags we must complete them reverse to
+ the order they were created. This is because completing a tag
+ modifies all data within it, including the incomplete tags
+ which store buffer positions -- simon@josefsson.org 2002-09-06
+ */
+ while (p->right)
+ p = p->right;
+ while (p && p != node->down->left)
+ {
+ if (type_field (p->type) == ASN1_ETYPE_TAG)
+ {
+ if (p->type & CONST_EXPLICIT)
+ {
+ len2 = strtol (p->name, NULL, 10);
+ _asn1_set_name (p, NULL);
+ asn1_length_der (*counter - len2, temp, &len3);
+ if (len3 <= (*max_len))
+ {
+ memmove (der + len2 + len3, der + len2,
+ *counter - len2);
+ memcpy (der + len2, temp, len3);
+ }
+ *max_len -= len3;
+ *counter += len3;
+ is_tag_implicit = 0;
}
+ else
+ { /* CONST_IMPLICIT */
+ if (!is_tag_implicit)
+ {
+ is_tag_implicit = 1;
+ }
+ }
+ }
+ p = p->left;
}
+ }
- if (*max_len < 0)
- return ASN1_MEM_ERROR;
+ if (*max_len < 0)
+ return ASN1_MEM_ERROR;
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
const tag_and_class_st _asn1_tags[] = {
- [ASN1_ETYPE_GENERALSTRING] =
- {ASN1_TAG_GENERALSTRING, ASN1_CLASS_UNIVERSAL,
- "type:GENERALSTRING"},
- [ASN1_ETYPE_NUMERIC_STRING] =
- {ASN1_TAG_NUMERIC_STRING, ASN1_CLASS_UNIVERSAL,
- "type:NUMERIC_STR"},
- [ASN1_ETYPE_IA5_STRING] =
- {ASN1_TAG_IA5_STRING, ASN1_CLASS_UNIVERSAL, "type:IA5_STR"},
- [ASN1_ETYPE_TELETEX_STRING] =
- {ASN1_TAG_TELETEX_STRING, ASN1_CLASS_UNIVERSAL,
- "type:TELETEX_STR"},
- [ASN1_ETYPE_PRINTABLE_STRING] =
- {ASN1_TAG_PRINTABLE_STRING, ASN1_CLASS_UNIVERSAL,
- "type:PRINTABLE_STR"},
- [ASN1_ETYPE_UNIVERSAL_STRING] =
- {ASN1_TAG_UNIVERSAL_STRING, ASN1_CLASS_UNIVERSAL,
- "type:UNIVERSAL_STR"},
- [ASN1_ETYPE_BMP_STRING] =
- {ASN1_TAG_BMP_STRING, ASN1_CLASS_UNIVERSAL, "type:BMP_STR"},
- [ASN1_ETYPE_UTF8_STRING] =
- {ASN1_TAG_UTF8_STRING, ASN1_CLASS_UNIVERSAL, "type:UTF8_STR"},
- [ASN1_ETYPE_VISIBLE_STRING] =
- {ASN1_TAG_VISIBLE_STRING, ASN1_CLASS_UNIVERSAL,
- "type:VISIBLE_STR"},
- [ASN1_ETYPE_OCTET_STRING] =
- {ASN1_TAG_OCTET_STRING, ASN1_CLASS_UNIVERSAL, "type:OCT_STR"},
- [ASN1_ETYPE_BIT_STRING] =
- {ASN1_TAG_BIT_STRING, ASN1_CLASS_UNIVERSAL, "type:BIT_STR"},
- [ASN1_ETYPE_OBJECT_ID] =
- {ASN1_TAG_OBJECT_ID, ASN1_CLASS_UNIVERSAL, "type:OBJ_ID"},
- [ASN1_ETYPE_NULL] =
- {ASN1_TAG_NULL, ASN1_CLASS_UNIVERSAL, "type:NULL"},
- [ASN1_ETYPE_BOOLEAN] =
- {ASN1_TAG_BOOLEAN, ASN1_CLASS_UNIVERSAL, "type:BOOLEAN"},
- [ASN1_ETYPE_INTEGER] =
- {ASN1_TAG_INTEGER, ASN1_CLASS_UNIVERSAL, "type:INTEGER"},
- [ASN1_ETYPE_ENUMERATED] =
- {ASN1_TAG_ENUMERATED, ASN1_CLASS_UNIVERSAL, "type:ENUMERATED"},
- [ASN1_ETYPE_SEQUENCE] =
- {ASN1_TAG_SEQUENCE,
- ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
- "type:SEQUENCE"},
- [ASN1_ETYPE_SEQUENCE_OF] =
- {ASN1_TAG_SEQUENCE,
- ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, "type:SEQ_OF"},
- [ASN1_ETYPE_SET] =
- {ASN1_TAG_SET, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
- "type:SET"},
- [ASN1_ETYPE_SET_OF] =
- {ASN1_TAG_SET, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
- "type:SET_OF"},
- [ASN1_ETYPE_GENERALIZED_TIME] =
- {ASN1_TAG_GENERALIZEDTime, ASN1_CLASS_UNIVERSAL,
- "type:GENERALIZED_TIME"},
- [ASN1_ETYPE_UTC_TIME] =
- {ASN1_TAG_UTCTime, ASN1_CLASS_UNIVERSAL, "type:UTC_TIME"},
+ [ASN1_ETYPE_GENERALSTRING] =
+ {ASN1_TAG_GENERALSTRING, ASN1_CLASS_UNIVERSAL, "type:GENERALSTRING"},
+ [ASN1_ETYPE_NUMERIC_STRING] =
+ {ASN1_TAG_NUMERIC_STRING, ASN1_CLASS_UNIVERSAL, "type:NUMERIC_STR"},
+ [ASN1_ETYPE_IA5_STRING] =
+ {ASN1_TAG_IA5_STRING, ASN1_CLASS_UNIVERSAL, "type:IA5_STR"},
+ [ASN1_ETYPE_TELETEX_STRING] =
+ {ASN1_TAG_TELETEX_STRING, ASN1_CLASS_UNIVERSAL, "type:TELETEX_STR"},
+ [ASN1_ETYPE_PRINTABLE_STRING] =
+ {ASN1_TAG_PRINTABLE_STRING, ASN1_CLASS_UNIVERSAL, "type:PRINTABLE_STR"},
+ [ASN1_ETYPE_UNIVERSAL_STRING] =
+ {ASN1_TAG_UNIVERSAL_STRING, ASN1_CLASS_UNIVERSAL, "type:UNIVERSAL_STR"},
+ [ASN1_ETYPE_BMP_STRING] =
+ {ASN1_TAG_BMP_STRING, ASN1_CLASS_UNIVERSAL, "type:BMP_STR"},
+ [ASN1_ETYPE_UTF8_STRING] =
+ {ASN1_TAG_UTF8_STRING, ASN1_CLASS_UNIVERSAL, "type:UTF8_STR"},
+ [ASN1_ETYPE_VISIBLE_STRING] =
+ {ASN1_TAG_VISIBLE_STRING, ASN1_CLASS_UNIVERSAL, "type:VISIBLE_STR"},
+ [ASN1_ETYPE_OCTET_STRING] =
+ {ASN1_TAG_OCTET_STRING, ASN1_CLASS_UNIVERSAL, "type:OCT_STR"},
+ [ASN1_ETYPE_BIT_STRING] =
+ {ASN1_TAG_BIT_STRING, ASN1_CLASS_UNIVERSAL, "type:BIT_STR"},
+ [ASN1_ETYPE_OBJECT_ID] =
+ {ASN1_TAG_OBJECT_ID, ASN1_CLASS_UNIVERSAL, "type:OBJ_ID"},
+ [ASN1_ETYPE_NULL] = {ASN1_TAG_NULL, ASN1_CLASS_UNIVERSAL, "type:NULL"},
+ [ASN1_ETYPE_BOOLEAN] =
+ {ASN1_TAG_BOOLEAN, ASN1_CLASS_UNIVERSAL, "type:BOOLEAN"},
+ [ASN1_ETYPE_INTEGER] =
+ {ASN1_TAG_INTEGER, ASN1_CLASS_UNIVERSAL, "type:INTEGER"},
+ [ASN1_ETYPE_ENUMERATED] =
+ {ASN1_TAG_ENUMERATED, ASN1_CLASS_UNIVERSAL, "type:ENUMERATED"},
+ [ASN1_ETYPE_SEQUENCE] =
+ {ASN1_TAG_SEQUENCE, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
+ "type:SEQUENCE"},
+ [ASN1_ETYPE_SEQUENCE_OF] =
+ {ASN1_TAG_SEQUENCE, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
+ "type:SEQ_OF"},
+ [ASN1_ETYPE_SET] =
+ {ASN1_TAG_SET, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, "type:SET"},
+ [ASN1_ETYPE_SET_OF] =
+ {ASN1_TAG_SET, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
+ "type:SET_OF"},
+ [ASN1_ETYPE_GENERALIZED_TIME] =
+ {ASN1_TAG_GENERALIZEDTime, ASN1_CLASS_UNIVERSAL, "type:GENERALIZED_TIME"},
+ [ASN1_ETYPE_UTC_TIME] =
+ {ASN1_TAG_UTCTime, ASN1_CLASS_UNIVERSAL, "type:UTC_TIME"},
};
-unsigned int _asn1_tags_size = sizeof(_asn1_tags) / sizeof(_asn1_tags[0]);
+unsigned int _asn1_tags_size = sizeof (_asn1_tags) / sizeof (_asn1_tags[0]);
/******************************************************/
/* Function : _asn1_insert_tag_der */
@@ -578,120 +589,104 @@ unsigned int _asn1_tags_size = sizeof(_asn1_tags) / sizeof(_asn1_tags[0]);
/* otherwise ASN1_SUCCESS. */
/******************************************************/
static int
-_asn1_insert_tag_der(asn1_node node, unsigned char *der, int *counter,
- int *max_len)
+_asn1_insert_tag_der (asn1_node node, unsigned char *der, int *counter,
+ int *max_len)
{
- asn1_node p;
- int tag_len, is_tag_implicit;
- unsigned char class, class_implicit =
- 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1];
- unsigned long tag_implicit = 0;
- unsigned char tag_der[MAX_TAG_LEN];
-
- is_tag_implicit = 0;
-
- if (node->type & CONST_TAG) {
- p = node->down;
- while (p) {
- if (type_field(p->type) == ASN1_ETYPE_TAG) {
- if (p->type & CONST_APPLICATION)
- class = ASN1_CLASS_APPLICATION;
- else if (p->type & CONST_UNIVERSAL)
- class = ASN1_CLASS_UNIVERSAL;
- else if (p->type & CONST_PRIVATE)
- class = ASN1_CLASS_PRIVATE;
- else
- class =
- ASN1_CLASS_CONTEXT_SPECIFIC;
-
- if (p->type & CONST_EXPLICIT) {
- if (is_tag_implicit)
- _asn1_tag_der
- (class_implicit,
- tag_implicit, tag_der,
- &tag_len);
- else
- _asn1_tag_der(class |
- ASN1_CLASS_STRUCTURED,
- _asn1_strtoul
- (p->value,
- NULL, 10),
- tag_der,
- &tag_len);
-
- *max_len -= tag_len;
- if (*max_len >= 0)
- memcpy(der + *counter,
- tag_der, tag_len);
- *counter += tag_len;
-
- _asn1_ltostr(*counter,
- (char *) temp);
- _asn1_set_name(p,
- (const char *)
- temp);
-
- is_tag_implicit = 0;
- } else { /* CONST_IMPLICIT */
- if (!is_tag_implicit) {
- if ((type_field(node->type)
- ==
- ASN1_ETYPE_SEQUENCE)
- ||
- (type_field(node->type)
- ==
- ASN1_ETYPE_SEQUENCE_OF)
- ||
- (type_field(node->type)
- == ASN1_ETYPE_SET)
- ||
- (type_field(node->type)
- == ASN1_ETYPE_SET_OF))
- class |=
- ASN1_CLASS_STRUCTURED;
- class_implicit = class;
- tag_implicit =
- _asn1_strtoul(p->value,
- NULL,
- 10);
- is_tag_implicit = 1;
- }
- }
- }
- p = p->right;
+ asn1_node p;
+ int tag_len, is_tag_implicit;
+ unsigned char class, class_implicit = 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1];
+ unsigned long tag_implicit = 0;
+ unsigned char tag_der[MAX_TAG_LEN];
+
+ is_tag_implicit = 0;
+
+ if (node->type & CONST_TAG)
+ {
+ p = node->down;
+ while (p)
+ {
+ if (type_field (p->type) == ASN1_ETYPE_TAG)
+ {
+ if (p->type & CONST_APPLICATION)
+ class = ASN1_CLASS_APPLICATION;
+ else if (p->type & CONST_UNIVERSAL)
+ class = ASN1_CLASS_UNIVERSAL;
+ else if (p->type & CONST_PRIVATE)
+ class = ASN1_CLASS_PRIVATE;
+ else
+ class = ASN1_CLASS_CONTEXT_SPECIFIC;
+
+ if (p->type & CONST_EXPLICIT)
+ {
+ if (is_tag_implicit)
+ _asn1_tag_der (class_implicit, tag_implicit, tag_der,
+ &tag_len);
+ else
+ _asn1_tag_der (class | ASN1_CLASS_STRUCTURED,
+ _asn1_strtoul (p->value, NULL, 10),
+ tag_der, &tag_len);
+
+ *max_len -= tag_len;
+ if (*max_len >= 0)
+ memcpy (der + *counter, tag_der, tag_len);
+ *counter += tag_len;
+
+ _asn1_ltostr (*counter, (char *) temp);
+ _asn1_set_name (p, (const char *) temp);
+
+ is_tag_implicit = 0;
}
- }
-
- if (is_tag_implicit) {
- _asn1_tag_der(class_implicit, tag_implicit, tag_der,
- &tag_len);
- } else {
- unsigned type = type_field(node->type);
- switch (type) {
- CASE_HANDLED_ETYPES:
- _asn1_tag_der(_asn1_tags[type].class,
- _asn1_tags[type].tag, tag_der,
- &tag_len);
- break;
- case ASN1_ETYPE_TAG:
- case ASN1_ETYPE_CHOICE:
- case ASN1_ETYPE_ANY:
- tag_len = 0;
- break;
- default:
- return ASN1_GENERIC_ERROR;
+ else
+ { /* CONST_IMPLICIT */
+ if (!is_tag_implicit)
+ {
+ if ((type_field (node->type) == ASN1_ETYPE_SEQUENCE) ||
+ (type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF)
+ || (type_field (node->type) == ASN1_ETYPE_SET)
+ || (type_field (node->type) == ASN1_ETYPE_SET_OF))
+ class |= ASN1_CLASS_STRUCTURED;
+ class_implicit = class;
+ tag_implicit = _asn1_strtoul (p->value, NULL, 10);
+ is_tag_implicit = 1;
+ }
}
+ }
+ p = p->right;
+ }
+ }
+
+ if (is_tag_implicit)
+ {
+ _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len);
+ }
+ else
+ {
+ unsigned type = type_field (node->type);
+ switch (type)
+ {
+ CASE_HANDLED_ETYPES:
+ _asn1_tag_der (_asn1_tags[type].class, _asn1_tags[type].tag,
+ tag_der, &tag_len);
+ break;
+ case ASN1_ETYPE_TAG:
+ case ASN1_ETYPE_CHOICE:
+ case ASN1_ETYPE_ANY:
+ tag_len = 0;
+ break;
+ default:
+ return ASN1_GENERIC_ERROR;
}
+ }
- *max_len -= tag_len;
- if (*max_len >= 0)
- memcpy(der + *counter, tag_der, tag_len);
- *counter += tag_len;
+ *max_len -= tag_len;
+ if (*max_len >= 0)
+ memcpy (der + *counter, tag_der, tag_len);
+ *counter += tag_len;
- if (*max_len < 0)
- return ASN1_MEM_ERROR;
+ if (*max_len < 0)
+ return ASN1_MEM_ERROR;
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
/******************************************************/
@@ -702,110 +697,134 @@ _asn1_insert_tag_der(asn1_node node, unsigned char *der, int *counter,
/* der: string with the DER coding. */
/* node: pointer to the SET element. */
/* Return: */
+/* ASN1_SUCCESS if successful */
+/* or an error value. */
/******************************************************/
-static void
-_asn1_ordering_set(unsigned char *der, int der_len, asn1_node node)
+static int
+_asn1_ordering_set (unsigned char *der, int der_len, asn1_node node)
{
- struct vet {
- int end;
- unsigned long value;
- struct vet *next, *prev;
- };
-
- int counter, len, len2;
- struct vet *first, *last, *p_vet, *p2_vet;
- asn1_node p;
- unsigned char class, *temp;
- unsigned long tag;
-
- counter = 0;
-
- if (type_field(node->type) != ASN1_ETYPE_SET)
- return;
-
- p = node->down;
- while ((type_field(p->type) == ASN1_ETYPE_TAG)
- || (type_field(p->type) == ASN1_ETYPE_SIZE))
- p = p->right;
-
- if ((p == NULL) || (p->right == NULL))
- return;
-
- first = last = NULL;
- while (p) {
- p_vet = malloc(sizeof(struct vet));
- if (p_vet == NULL)
- return;
-
- p_vet->next = NULL;
- p_vet->prev = last;
- if (first == NULL)
- first = p_vet;
- else
- last->next = p_vet;
- last = p_vet;
-
- /* tag value calculation */
- if (asn1_get_tag_der
- (der + counter, der_len - counter, &class, &len2,
- &tag) != ASN1_SUCCESS)
- return;
- p_vet->value = (class << 24) | tag;
- counter += len2;
-
- /* extraction and length */
- len2 =
- asn1_get_length_der(der + counter, der_len - counter,
- &len);
- if (len2 < 0)
- return;
- counter += len + len2;
-
- p_vet->end = counter;
- p = p->right;
+ struct vet
+ {
+ int end;
+ unsigned long value;
+ struct vet *next, *prev;
+ };
+
+ int counter, len, len2;
+ struct vet *first, *last, *p_vet, *p2_vet;
+ asn1_node p;
+ unsigned char class, *temp;
+ unsigned long tag, t;
+ int err;
+
+ counter = 0;
+
+ if (type_field (node->type) != ASN1_ETYPE_SET)
+ return ASN1_VALUE_NOT_VALID;
+
+ p = node->down;
+ while (p && ((type_field (p->type) == ASN1_ETYPE_TAG) ||
+ (type_field (p->type) == ASN1_ETYPE_SIZE)))
+ p = p->right;
+
+ if ((p == NULL) || (p->right == NULL))
+ return ASN1_SUCCESS;
+
+ first = last = NULL;
+ while (p)
+ {
+ p_vet = malloc (sizeof (struct vet));
+ if (p_vet == NULL)
+ {
+ err = ASN1_MEM_ALLOC_ERROR;
+ goto error;
}
- p_vet = first;
-
- while (p_vet) {
- p2_vet = p_vet->next;
- counter = 0;
- while (p2_vet) {
- if (p_vet->value > p2_vet->value) {
- /* change position */
- temp = malloc(p_vet->end - counter);
- if (temp == NULL)
- return;
-
- memcpy(temp, der + counter,
- p_vet->end - counter);
- memcpy(der + counter, der + p_vet->end,
- p2_vet->end - p_vet->end);
- memcpy(der + counter + p2_vet->end -
- p_vet->end, temp,
- p_vet->end - counter);
- free(temp);
-
- tag = p_vet->value;
- p_vet->value = p2_vet->value;
- p2_vet->value = tag;
-
- p_vet->end =
- counter + (p2_vet->end - p_vet->end);
- }
- counter = p_vet->end;
-
- p2_vet = p2_vet->next;
- p_vet = p_vet->next;
+ p_vet->next = NULL;
+ p_vet->prev = last;
+ if (first == NULL)
+ first = p_vet;
+ else
+ last->next = p_vet;
+ last = p_vet;
+
+ /* tag value calculation */
+ err = asn1_get_tag_der (der + counter, der_len - counter, &class, &len2,
+ &tag);
+ if (err != ASN1_SUCCESS)
+ goto error;
+
+ t = class << 24;
+ p_vet->value = t | tag;
+ counter += len2;
+
+ /* extraction and length */
+ len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
+ if (len2 < 0)
+ {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
+ counter += len + len2;
+
+ p_vet->end = counter;
+ p = p->right;
+ }
+
+ p_vet = first;
+
+ while (p_vet)
+ {
+ p2_vet = p_vet->next;
+ counter = 0;
+ while (p2_vet)
+ {
+ if (p_vet->value > p2_vet->value)
+ {
+ /* change position */
+ temp = malloc (p_vet->end - counter);
+ if (temp == NULL)
+ {
+ err = ASN1_MEM_ALLOC_ERROR;
+ goto error;
}
- if (p_vet != first)
- p_vet->prev->next = NULL;
- else
- first = NULL;
- free(p_vet);
- p_vet = first;
+ memcpy (temp, der + counter, p_vet->end - counter);
+ memcpy (der + counter, der + p_vet->end,
+ p2_vet->end - p_vet->end);
+ memcpy (der + counter + p2_vet->end - p_vet->end, temp,
+ p_vet->end - counter);
+ free (temp);
+
+ tag = p_vet->value;
+ p_vet->value = p2_vet->value;
+ p2_vet->value = tag;
+
+ p_vet->end = counter + (p2_vet->end - p_vet->end);
+ }
+ counter = p_vet->end;
+
+ p2_vet = p2_vet->next;
+ p_vet = p_vet->next;
}
+
+ if (p_vet != first)
+ p_vet->prev->next = NULL;
+ else
+ first = NULL;
+ free (p_vet);
+ p_vet = first;
+ }
+ return ASN1_SUCCESS;
+
+error:
+ while (first != NULL)
+ {
+ p_vet = first;
+ first = first->next;
+ free(p_vet);
+ }
+ return err;
}
/******************************************************/
@@ -816,129 +835,155 @@ _asn1_ordering_set(unsigned char *der, int der_len, asn1_node node)
/* der: string with the DER coding. */
/* node: pointer to the SET OF element. */
/* Return: */
+/* ASN1_SUCCESS if successful */
+/* or an error value. */
/******************************************************/
-static void
-_asn1_ordering_set_of(unsigned char *der, int der_len, asn1_node node)
+static int
+_asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node)
{
- struct vet {
- int end;
- struct vet *next, *prev;
- };
-
- int counter, len, len2, change;
- struct vet *first, *last, *p_vet, *p2_vet;
- asn1_node p;
- unsigned char *temp, class;
- unsigned long k, max;
-
- counter = 0;
-
- if (type_field(node->type) != ASN1_ETYPE_SET_OF)
- return;
+ struct vet
+ {
+ int end;
+ struct vet *next, *prev;
+ };
+
+ int counter, len, len2, change;
+ struct vet *first, *last, *p_vet, *p2_vet;
+ asn1_node p;
+ unsigned char *temp, class;
+ unsigned long k, length;
+ int err;
+
+ counter = 0;
+
+ if (type_field (node->type) != ASN1_ETYPE_SET_OF)
+ return ASN1_VALUE_NOT_VALID;
+
+ p = node->down;
+ while (p && ((type_field (p->type) == ASN1_ETYPE_TAG) ||
+ (type_field (p->type) == ASN1_ETYPE_SIZE)))
+ p = p->right;
+ if (p == NULL)
+ return ASN1_VALUE_NOT_VALID;
+ p = p->right;
+
+ if ((p == NULL) || (p->right == NULL))
+ return ASN1_SUCCESS;
+
+ first = last = NULL;
+ while (p)
+ {
+ p_vet = malloc (sizeof (struct vet));
+ if (p_vet == NULL)
+ {
+ err = ASN1_MEM_ALLOC_ERROR;
+ goto error;
+ }
- p = node->down;
- while ((type_field(p->type) == ASN1_ETYPE_TAG)
- || (type_field(p->type) == ASN1_ETYPE_SIZE))
- p = p->right;
- p = p->right;
+ p_vet->next = NULL;
+ p_vet->prev = last;
+ if (first == NULL)
+ first = p_vet;
+ else
+ last->next = p_vet;
+ last = p_vet;
+
+ /* extraction of tag and length */
+ if (der_len - counter > 0)
+ {
+
+ err = asn1_get_tag_der (der + counter, der_len - counter, &class,
+ &len, NULL);
+ if (err != ASN1_SUCCESS)
+ goto error;
+ counter += len;
+
+ len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
+ if (len2 < 0)
+ {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
+ counter += len + len2;
+ }
+ else
+ {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
- if ((p == NULL) || (p->right == NULL))
- return;
-
- first = last = NULL;
- while (p) {
- p_vet = malloc(sizeof(struct vet));
- if (p_vet == NULL)
- return;
-
- p_vet->next = NULL;
- p_vet->prev = last;
- if (first == NULL)
- first = p_vet;
- else
- last->next = p_vet;
- last = p_vet;
-
- /* extraction of tag and length */
- if (der_len - counter > 0) {
-
- if (asn1_get_tag_der
- (der + counter, der_len - counter, &class,
- &len, NULL) != ASN1_SUCCESS)
- return;
- counter += len;
-
- len2 =
- asn1_get_length_der(der + counter,
- der_len - counter, &len);
- if (len2 < 0)
- return;
- counter += len + len2;
+ p_vet->end = counter;
+ p = p->right;
+ }
+
+ p_vet = first;
+
+ while (p_vet)
+ {
+ p2_vet = p_vet->next;
+ counter = 0;
+ while (p2_vet)
+ {
+ length = MIN(p_vet->end - counter, p2_vet->end - p_vet->end);
+ change = -1;
+ for (k = 0; k < length; k++)
+ if (der[counter + k] > der[p_vet->end + k])
+ {
+ change = 1;
+ break;
+ }
+ else if (der[counter + k] < der[p_vet->end + k])
+ {
+ change = 0;
+ break;
+ }
+
+ if ((change == -1)
+ && ((p_vet->end - counter) > (p2_vet->end - p_vet->end)))
+ change = 1;
+
+ if (change == 1)
+ {
+ /* change position */
+ temp = malloc (p_vet->end - counter);
+ if (temp == NULL)
+ {
+ err = ASN1_MEM_ALLOC_ERROR;
+ goto error;
}
- p_vet->end = counter;
- p = p->right;
- }
+ memcpy (temp, der + counter, (p_vet->end) - counter);
+ memcpy (der + counter, der + (p_vet->end),
+ (p2_vet->end) - (p_vet->end));
+ memcpy (der + counter + (p2_vet->end) - (p_vet->end), temp,
+ (p_vet->end) - counter);
+ free (temp);
- p_vet = first;
-
- while (p_vet) {
- p2_vet = p_vet->next;
- counter = 0;
- while (p2_vet) {
- if ((p_vet->end - counter) >
- (p2_vet->end - p_vet->end))
- max = p_vet->end - counter;
- else
- max = p2_vet->end - p_vet->end;
-
- change = -1;
- for (k = 0; k < max; k++)
- if (der[counter + k] > der[p_vet->end + k]) {
- change = 1;
- break;
- } else if (der[counter + k] <
- der[p_vet->end + k]) {
- change = 0;
- break;
- }
-
- if ((change == -1)
- && ((p_vet->end - counter) >
- (p2_vet->end - p_vet->end)))
- change = 1;
-
- if (change == 1) {
- /* change position */
- temp = malloc(p_vet->end - counter);
- if (temp == NULL)
- return;
-
- memcpy(temp, der + counter,
- (p_vet->end) - counter);
- memcpy(der + counter, der + (p_vet->end),
- (p2_vet->end) - (p_vet->end));
- memcpy(der + counter + (p2_vet->end) -
- (p_vet->end), temp,
- (p_vet->end) - counter);
- free(temp);
-
- p_vet->end =
- counter + (p2_vet->end - p_vet->end);
- }
- counter = p_vet->end;
-
- p2_vet = p2_vet->next;
- p_vet = p_vet->next;
- }
+ p_vet->end = counter + (p2_vet->end - p_vet->end);
+ }
+ counter = p_vet->end;
- if (p_vet != first)
- p_vet->prev->next = NULL;
- else
- first = NULL;
- free(p_vet);
- p_vet = first;
+ p2_vet = p2_vet->next;
+ p_vet = p_vet->next;
}
+
+ if (p_vet != first)
+ p_vet->prev->next = NULL;
+ else
+ first = NULL;
+ free (p_vet);
+ p_vet = first;
+ }
+ return ASN1_SUCCESS;
+
+error:
+ while (first != NULL)
+ {
+ p_vet = first;
+ first = first->next;
+ free(p_vet);
+ }
+ return err;
}
/**
@@ -950,7 +995,7 @@ _asn1_ordering_set_of(unsigned char *der, int der_len, asn1_node node)
* pointer to memory cells already allocated.
* @len: number of bytes of *@ider: @ider[0]..@ider[len-1], Initialy
* holds the sizeof of der vector.
- * @errorDescription : return the error description or an empty
+ * @ErrorDescription: return the error description or an empty
* string if success.
*
* Creates the DER encoding for the NAME structure (inside *POINTER
@@ -963,334 +1008,338 @@ _asn1_ordering_set_of(unsigned char *der, int der_len, asn1_node node)
* length needed.
**/
int
-asn1_der_coding(asn1_node element, const char *name, void *ider, int *len,
- char *ErrorDescription)
+asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
+ char *ErrorDescription)
{
- asn1_node node, p, p2;
- unsigned char temp[SIZEOF_UNSIGNED_LONG_INT * 3 + 1];
- int counter, counter_old, len2, len3, tlen, move, max_len,
- max_len_old;
- int err;
- unsigned char *der = ider;
-
- node = asn1_find_node(element, name);
- if (node == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
-
- /* Node is now a locally allocated variable.
- * That is because in some point we modify the
- * structure, and I don't know why! --nmav
- */
- node = _asn1_copy_structure3(node);
- if (node == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
-
- max_len = *len;
-
- counter = 0;
- move = DOWN;
- p = node;
- while (1) {
-
- counter_old = counter;
- max_len_old = max_len;
- if (move != UP) {
- err =
- _asn1_insert_tag_der(p, der, &counter,
- &max_len);
- if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
- goto error;
+ asn1_node node, p, p2;
+ unsigned char temp[SIZEOF_UNSIGNED_LONG_INT * 3 + 1];
+ int counter, counter_old, len2, len3, tlen, move, max_len, max_len_old;
+ int err;
+ unsigned char *der = ider;
+
+ node = asn1_find_node (element, name);
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ /* Node is now a locally allocated variable.
+ * That is because in some point we modify the
+ * structure, and I don't know why! --nmav
+ */
+ node = _asn1_copy_structure3 (node);
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ max_len = *len;
+
+ counter = 0;
+ move = DOWN;
+ p = node;
+ while (1)
+ {
+
+ counter_old = counter;
+ max_len_old = max_len;
+ if (move != UP)
+ {
+ err = _asn1_insert_tag_der (p, der, &counter, &max_len);
+ if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
+ goto error;
+ }
+ switch (type_field (p->type))
+ {
+ case ASN1_ETYPE_NULL:
+ max_len--;
+ if (max_len >= 0)
+ der[counter] = 0;
+ counter++;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_BOOLEAN:
+ if ((p->type & CONST_DEFAULT) && (p->value == NULL))
+ {
+ counter = counter_old;
+ max_len = max_len_old;
+ }
+ else
+ {
+ if (p->value == NULL)
+ {
+ _asn1_error_description_value_not_found (p,
+ ErrorDescription);
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
}
- switch (type_field(p->type)) {
- case ASN1_ETYPE_NULL:
- max_len--;
- if (max_len >= 0)
- der[counter] = 0;
- counter++;
- move = RIGHT;
- break;
- case ASN1_ETYPE_BOOLEAN:
- if ((p->type & CONST_DEFAULT)
- && (p->value == NULL)) {
- counter = counter_old;
- max_len = max_len_old;
- } else {
- if (p->value == NULL) {
- _asn1_error_description_value_not_found
- (p, ErrorDescription);
- err = ASN1_VALUE_NOT_FOUND;
- goto error;
- }
- max_len -= 2;
- if (max_len >= 0) {
- der[counter++] = 1;
- if (p->value[0] == 'F')
- der[counter++] = 0;
- else
- der[counter++] = 0xFF;
- } else
- counter += 2;
- }
- move = RIGHT;
- break;
- case ASN1_ETYPE_INTEGER:
- case ASN1_ETYPE_ENUMERATED:
- if ((p->type & CONST_DEFAULT)
- && (p->value == NULL)) {
- counter = counter_old;
- max_len = max_len_old;
- } else {
- if (p->value == NULL) {
- _asn1_error_description_value_not_found
- (p, ErrorDescription);
- err = ASN1_VALUE_NOT_FOUND;
- goto error;
- }
- len2 =
- asn1_get_length_der(p->value,
- p->value_len,
- &len3);
- if (len2 < 0) {
- err = ASN1_DER_ERROR;
- goto error;
- }
- max_len -= len2 + len3;
- if (max_len >= 0)
- memcpy(der + counter, p->value,
- len3 + len2);
- counter += len3 + len2;
- }
- move = RIGHT;
- break;
- case ASN1_ETYPE_OBJECT_ID:
- if ((p->type & CONST_DEFAULT)
- && (p->value == NULL)) {
- counter = counter_old;
- max_len = max_len_old;
- } else {
- if (p->value == NULL) {
- _asn1_error_description_value_not_found
- (p, ErrorDescription);
- err = ASN1_VALUE_NOT_FOUND;
- goto error;
- }
- len2 = max_len;
- err =
- _asn1_objectid_der(p->value,
- der + counter,
- &len2);
- if (err != ASN1_SUCCESS
- && err != ASN1_MEM_ERROR)
- goto error;
-
- max_len -= len2;
- counter += len2;
- }
- move = RIGHT;
- break;
- case ASN1_ETYPE_GENERALIZED_TIME:
- case ASN1_ETYPE_UTC_TIME:
- if (p->value == NULL) {
- _asn1_error_description_value_not_found(p,
- ErrorDescription);
- err = ASN1_VALUE_NOT_FOUND;
- goto error;
- }
- len2 = max_len;
- err =
- _asn1_time_der(p->value, p->value_len,
- der + counter, &len2);
- if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
- goto error;
-
- max_len -= len2;
- counter += len2;
- move = RIGHT;
- break;
- case ASN1_ETYPE_OCTET_STRING:
- case ASN1_ETYPE_GENERALSTRING:
- case ASN1_ETYPE_NUMERIC_STRING:
- case ASN1_ETYPE_IA5_STRING:
- case ASN1_ETYPE_TELETEX_STRING:
- case ASN1_ETYPE_PRINTABLE_STRING:
- case ASN1_ETYPE_UNIVERSAL_STRING:
- case ASN1_ETYPE_BMP_STRING:
- case ASN1_ETYPE_UTF8_STRING:
- case ASN1_ETYPE_VISIBLE_STRING:
- case ASN1_ETYPE_BIT_STRING:
- if (p->value == NULL) {
- _asn1_error_description_value_not_found(p,
- ErrorDescription);
- err = ASN1_VALUE_NOT_FOUND;
- goto error;
- }
- len2 =
- asn1_get_length_der(p->value, p->value_len,
- &len3);
- if (len2 < 0) {
- err = ASN1_DER_ERROR;
- goto error;
- }
- max_len -= len2 + len3;
- if (max_len >= 0)
- memcpy(der + counter, p->value,
- len3 + len2);
- counter += len3 + len2;
- move = RIGHT;
- break;
- case ASN1_ETYPE_SEQUENCE:
- case ASN1_ETYPE_SET:
- if (move != UP) {
- _asn1_ltostr(counter, (char *) temp);
- tlen = _asn1_strlen(temp);
- if (tlen > 0)
- _asn1_set_value(p, temp, tlen + 1);
- if (p->down == NULL) {
- move = UP;
- continue;
- } else {
- p2 = p->down;
- while (p2
- && (type_field(p2->type) ==
- ASN1_ETYPE_TAG))
- p2 = p2->right;
- if (p2) {
- p = p2;
- move = RIGHT;
- continue;
- }
- move = UP;
- continue;
- }
- } else { /* move==UP */
- len2 = _asn1_strtol(p->value, NULL, 10);
- _asn1_set_value(p, NULL, 0);
- if ((type_field(p->type) == ASN1_ETYPE_SET)
- && (max_len >= 0))
- _asn1_ordering_set(der + len2,
- max_len - len2,
- p);
- asn1_length_der(counter - len2, temp,
- &len3);
- max_len -= len3;
- if (max_len >= 0) {
- memmove(der + len2 + len3,
- der + len2,
- counter - len2);
- memcpy(der + len2, temp, len3);
- }
- counter += len3;
- move = RIGHT;
- }
- break;
- case ASN1_ETYPE_SEQUENCE_OF:
- case ASN1_ETYPE_SET_OF:
- if (move != UP) {
- _asn1_ltostr(counter, (char *) temp);
- tlen = _asn1_strlen(temp);
-
- if (tlen > 0)
- _asn1_set_value(p, temp, tlen + 1);
- p = p->down;
- while ((type_field(p->type) ==
- ASN1_ETYPE_TAG)
- || (type_field(p->type) ==
- ASN1_ETYPE_SIZE))
- p = p->right;
- if (p->right) {
- p = p->right;
- move = RIGHT;
- continue;
- } else
- p = _asn1_find_up(p);
- move = UP;
- }
- if (move == UP) {
- len2 = _asn1_strtol(p->value, NULL, 10);
- _asn1_set_value(p, NULL, 0);
- if ((type_field(p->type) ==
- ASN1_ETYPE_SET_OF)
- && (max_len - len2 > 0)) {
- _asn1_ordering_set_of(der + len2,
- max_len -
- len2, p);
- }
- asn1_length_der(counter - len2, temp,
- &len3);
- max_len -= len3;
- if (max_len >= 0) {
- memmove(der + len2 + len3,
- der + len2,
- counter - len2);
- memcpy(der + len2, temp, len3);
- }
- counter += len3;
- move = RIGHT;
- }
- break;
- case ASN1_ETYPE_ANY:
- if (p->value == NULL) {
- _asn1_error_description_value_not_found(p,
- ErrorDescription);
- err = ASN1_VALUE_NOT_FOUND;
- goto error;
- }
- len2 =
- asn1_get_length_der(p->value, p->value_len,
- &len3);
- if (len2 < 0) {
- err = ASN1_DER_ERROR;
- goto error;
- }
- max_len -= len2;
- if (max_len >= 0)
- memcpy(der + counter, p->value + len3,
- len2);
- counter += len2;
- move = RIGHT;
- break;
- default:
- move = (move == UP) ? RIGHT : DOWN;
- break;
+ max_len -= 2;
+ if (max_len >= 0)
+ {
+ der[counter++] = 1;
+ if (p->value[0] == 'F')
+ der[counter++] = 0;
+ else
+ der[counter++] = 0xFF;
}
-
- if ((move != DOWN) && (counter != counter_old)) {
- err =
- _asn1_complete_explicit_tag(p, der, &counter,
- &max_len);
- if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
- goto error;
+ else
+ counter += 2;
+ }
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_INTEGER:
+ case ASN1_ETYPE_ENUMERATED:
+ if ((p->type & CONST_DEFAULT) && (p->value == NULL))
+ {
+ counter = counter_old;
+ max_len = max_len_old;
+ }
+ else
+ {
+ if (p->value == NULL)
+ {
+ _asn1_error_description_value_not_found (p,
+ ErrorDescription);
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
}
+ len2 = asn1_get_length_der (p->value, p->value_len, &len3);
+ if (len2 < 0)
+ {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
+ max_len -= len2 + len3;
+ if (max_len >= 0)
+ memcpy (der + counter, p->value, len3 + len2);
+ counter += len3 + len2;
+ }
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_OBJECT_ID:
+ if ((p->type & CONST_DEFAULT) && (p->value == NULL))
+ {
+ counter = counter_old;
+ max_len = max_len_old;
+ }
+ else
+ {
+ if (p->value == NULL)
+ {
+ _asn1_error_description_value_not_found (p,
+ ErrorDescription);
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
+ }
+ len2 = max_len;
+ err = _asn1_objectid_der (p->value, der + counter, &len2);
+ if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
+ goto error;
- if (p == node && move != DOWN)
- break;
-
- if (move == DOWN) {
- if (p->down)
- p = p->down;
- else
- move = RIGHT;
+ max_len -= len2;
+ counter += len2;
+ }
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_GENERALIZED_TIME:
+ case ASN1_ETYPE_UTC_TIME:
+ if (p->value == NULL)
+ {
+ _asn1_error_description_value_not_found (p, ErrorDescription);
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
+ }
+ len2 = max_len;
+ err = _asn1_time_der (p->value, p->value_len, der + counter, &len2);
+ if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
+ goto error;
+
+ max_len -= len2;
+ counter += len2;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_OCTET_STRING:
+ case ASN1_ETYPE_GENERALSTRING:
+ case ASN1_ETYPE_NUMERIC_STRING:
+ case ASN1_ETYPE_IA5_STRING:
+ case ASN1_ETYPE_TELETEX_STRING:
+ case ASN1_ETYPE_PRINTABLE_STRING:
+ case ASN1_ETYPE_UNIVERSAL_STRING:
+ case ASN1_ETYPE_BMP_STRING:
+ case ASN1_ETYPE_UTF8_STRING:
+ case ASN1_ETYPE_VISIBLE_STRING:
+ case ASN1_ETYPE_BIT_STRING:
+ if (p->value == NULL)
+ {
+ _asn1_error_description_value_not_found (p, ErrorDescription);
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
+ }
+ len2 = asn1_get_length_der (p->value, p->value_len, &len3);
+ if (len2 < 0)
+ {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
+ max_len -= len2 + len3;
+ if (max_len >= 0)
+ memcpy (der + counter, p->value, len3 + len2);
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_SEQUENCE:
+ case ASN1_ETYPE_SET:
+ if (move != UP)
+ {
+ _asn1_ltostr (counter, (char *) temp);
+ tlen = _asn1_strlen (temp);
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen + 1);
+ if (p->down == NULL)
+ {
+ move = UP;
+ continue;
+ }
+ else
+ {
+ p2 = p->down;
+ while (p2 && (type_field (p2->type) == ASN1_ETYPE_TAG))
+ p2 = p2->right;
+ if (p2)
+ {
+ p = p2;
+ move = RIGHT;
+ continue;
+ }
+ move = UP;
+ continue;
+ }
+ }
+ else
+ { /* move==UP */
+ len2 = _asn1_strtol (p->value, NULL, 10);
+ _asn1_set_value (p, NULL, 0);
+ if ((type_field (p->type) == ASN1_ETYPE_SET) && (max_len >= 0))
+ {
+ err = _asn1_ordering_set (der + len2, counter - len2, p);
+ if (err != ASN1_SUCCESS)
+ goto error;
+ }
+ asn1_length_der (counter - len2, temp, &len3);
+ max_len -= len3;
+ if (max_len >= 0)
+ {
+ memmove (der + len2 + len3, der + len2, counter - len2);
+ memcpy (der + len2, temp, len3);
+ }
+ counter += len3;
+ move = RIGHT;
+ }
+ break;
+ case ASN1_ETYPE_SEQUENCE_OF:
+ case ASN1_ETYPE_SET_OF:
+ if (move != UP)
+ {
+ _asn1_ltostr (counter, (char *) temp);
+ tlen = _asn1_strlen (temp);
+
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen + 1);
+ p = p->down;
+ while ((type_field (p->type) == ASN1_ETYPE_TAG)
+ || (type_field (p->type) == ASN1_ETYPE_SIZE))
+ p = p->right;
+ if (p->right)
+ {
+ p = p->right;
+ move = RIGHT;
+ continue;
}
- if (move == RIGHT) {
- if (p->right)
- p = p->right;
- else
- move = UP;
+ else
+ p = _asn1_find_up (p);
+ move = UP;
+ }
+ if (move == UP)
+ {
+ len2 = _asn1_strtol (p->value, NULL, 10);
+ _asn1_set_value (p, NULL, 0);
+ if ((type_field (p->type) == ASN1_ETYPE_SET_OF)
+ && (counter - len2 > 0) && (max_len >= 0))
+ {
+ err = _asn1_ordering_set_of (der + len2, counter - len2, p);
+ if (err != ASN1_SUCCESS)
+ goto error;
}
- if (move == UP)
- p = _asn1_find_up(p);
+ asn1_length_der (counter - len2, temp, &len3);
+ max_len -= len3;
+ if (max_len >= 0)
+ {
+ memmove (der + len2 + len3, der + len2, counter - len2);
+ memcpy (der + len2, temp, len3);
+ }
+ counter += len3;
+ move = RIGHT;
+ }
+ break;
+ case ASN1_ETYPE_ANY:
+ if (p->value == NULL)
+ {
+ _asn1_error_description_value_not_found (p, ErrorDescription);
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
+ }
+ len2 = asn1_get_length_der (p->value, p->value_len, &len3);
+ if (len2 < 0)
+ {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
+ max_len -= len2;
+ if (max_len >= 0)
+ memcpy (der + counter, p->value + len3, len2);
+ counter += len2;
+ move = RIGHT;
+ break;
+ default:
+ move = (move == UP) ? RIGHT : DOWN;
+ break;
+ }
+
+ if ((move != DOWN) && (counter != counter_old))
+ {
+ err = _asn1_complete_explicit_tag (p, der, &counter, &max_len);
+ if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
+ goto error;
}
- *len = counter;
+ if (p == node && move != DOWN)
+ break;
- if (max_len < 0) {
- err = ASN1_MEM_ERROR;
- goto error;
+ if (move == DOWN)
+ {
+ if (p->down)
+ p = p->down;
+ else
+ move = RIGHT;
}
+ if (move == RIGHT)
+ {
+ if (p->right)
+ p = p->right;
+ else
+ move = UP;
+ }
+ if (move == UP)
+ p = _asn1_find_up (p);
+ }
+
+ *len = counter;
+
+ if (max_len < 0)
+ {
+ err = ASN1_MEM_ERROR;
+ goto error;
+ }
- err = ASN1_SUCCESS;
+ err = ASN1_SUCCESS;
- error:
- asn1_delete_structure(&node);
- return err;
+error:
+ asn1_delete_structure (&node);
+ return err;
}
diff --git a/lib/minitasn1/decoding.c b/lib/minitasn1/decoding.c
index 40084d43b7..0b334fefc4 100644
--- a/lib/minitasn1/decoding.c
+++ b/lib/minitasn1/decoding.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2002-2014 Free Software Foundation, Inc.
*
* This file is part of LIBTASN1.
*
@@ -26,25 +26,24 @@
/*****************************************************/
#include <int.h>
-#include "parser_aux.h"
+#include <parser_aux.h>
#include <gstr.h>
-#include "structure.h"
-#include "element.h"
+#include <structure.h>
+#include <element.h>
#include <limits.h>
+#include <intprops.h>
static int
-_asn1_get_indefinite_length_string(const unsigned char *der, int *len);
+_asn1_get_indefinite_length_string (const unsigned char *der, int *len);
static void
-_asn1_error_description_tag_error(asn1_node node, char *ErrorDescription)
+_asn1_error_description_tag_error (asn1_node node, char *ErrorDescription)
{
- Estrcpy(ErrorDescription, ":: tag error near element '");
- _asn1_hierarchical_name(node,
- ErrorDescription +
- strlen(ErrorDescription),
- ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40);
- Estrcat(ErrorDescription, "'");
+ Estrcpy (ErrorDescription, ":: tag error near element '");
+ _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
+ ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40);
+ Estrcat (ErrorDescription, "'");
}
@@ -60,52 +59,60 @@ _asn1_error_description_tag_error(asn1_node node, char *ErrorDescription)
* length, or -2 when the value was too big to fit in a int, or -4
* when the decoded length value plus @len would exceed @der_len.
**/
-long asn1_get_length_der(const unsigned char *der, int der_len, int *len)
+long
+asn1_get_length_der (const unsigned char *der, int der_len, int *len)
{
- unsigned int ans, sum, last;
- int k, punt;
-
- *len = 0;
- if (der_len <= 0)
- return 0;
-
- if (!(der[0] & 128)) {
- /* short form */
- *len = 1;
- ans = der[0];
- } else {
- /* Long form */
- k = der[0] & 0x7F;
- punt = 1;
- if (k) { /* definite length method */
- ans = 0;
- while (punt <= k && punt < der_len) {
- last = ans;
-
- ans = (ans * 256) + der[punt++];
- if (ans < last)
- /* we wrapped around, no bignum support... */
- return -2;
- }
- } else { /* indefinite length method */
- *len = punt;
- return -1;
- }
+ unsigned int ans;
+ int k, punt, sum;
+
+ *len = 0;
+ if (der_len <= 0)
+ return 0;
+
+ if (!(der[0] & 128))
+ {
+ /* short form */
+ *len = 1;
+ ans = der[0];
+ }
+ else
+ {
+ /* Long form */
+ k = der[0] & 0x7F;
+ punt = 1;
+ if (k)
+ { /* definite length method */
+ ans = 0;
+ while (punt <= k && punt < der_len)
+ {
+ if (INT_MULTIPLY_OVERFLOW (ans, 256))
+ return -2;
+ ans *= 256;
- *len = punt;
+ if (INT_ADD_OVERFLOW (ans, ((unsigned) der[punt])))
+ return -2;
+ ans += der[punt];
+ punt++;
+ }
+ }
+ else
+ { /* indefinite length method */
+ *len = punt;
+ return -1;
}
- sum = ans + *len;
+ *len = punt;
+ }
- /* check for overflow as well INT_MAX as a maximum upper
- * limit for length */
- if (sum >= INT_MAX || sum < ans)
- return -2;
+ sum = ans;
+ if (ans >= INT_MAX || INT_ADD_OVERFLOW (sum, (*len)))
+ return -2;
+ sum += *len;
- if (((int) sum) > der_len)
- return -4;
+ if (sum > der_len)
+ return -4;
- return ans;
+ return ans;
}
/**
@@ -121,48 +128,58 @@ long asn1_get_length_der(const unsigned char *der, int der_len, int *len)
* Returns: Returns %ASN1_SUCCESS on success, or an error.
**/
int
-asn1_get_tag_der(const unsigned char *der, int der_len,
- unsigned char *cls, int *len, unsigned long *tag)
+asn1_get_tag_der (const unsigned char *der, int der_len,
+ unsigned char *cls, int *len, unsigned long *tag)
{
- unsigned int ris;
- int punt;
- unsigned int last;
+ unsigned int ris;
+ int punt;
+
+ if (der == NULL || der_len < 2 || len == NULL)
+ return ASN1_DER_ERROR;
+
+ *cls = der[0] & 0xE0;
+ if ((der[0] & 0x1F) != 0x1F)
+ {
+ /* short form */
+ *len = 1;
+ ris = der[0] & 0x1F;
+ }
+ else
+ {
+ /* Long form */
+ punt = 1;
+ ris = 0;
+ while (punt <= der_len && der[punt] & 128)
+ {
+
+ if (INT_MULTIPLY_OVERFLOW (ris, 128))
+ return ASN1_DER_ERROR;
+ ris *= 128;
+
+ if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F))))
+ return ASN1_DER_ERROR;
+ ris += (der[punt] & 0x7F);
+ punt++;
+ }
- if (der == NULL || der_len < 2 || len == NULL)
- return ASN1_DER_ERROR;
+ if (punt >= der_len)
+ return ASN1_DER_ERROR;
- *cls = der[0] & 0xE0;
- if ((der[0] & 0x1F) != 0x1F) {
- /* short form */
- *len = 1;
- ris = der[0] & 0x1F;
- } else {
- /* Long form */
- punt = 1;
- ris = 0;
- while (punt <= der_len && der[punt] & 128) {
- last = ris;
-
- ris = (ris * 128) + (der[punt++] & 0x7F);
- if (ris < last)
- /* wrapped around, and no bignums... */
- return ASN1_DER_ERROR;
- }
-
- if (punt >= der_len)
- return ASN1_DER_ERROR;
+ if (INT_MULTIPLY_OVERFLOW (ris, 128))
+ return ASN1_DER_ERROR;
+ ris *= 128;
- last = ris;
+ if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F))))
+ return ASN1_DER_ERROR;
+ ris += (der[punt] & 0x7F);
+ punt++;
- ris = (ris * 128) + (der[punt++] & 0x7F);
- if (ris < last)
- return ASN1_DER_ERROR;
+ *len = punt;
+ }
- *len = punt;
- }
- if (tag)
- *tag = ris;
- return ASN1_SUCCESS;
+ if (tag)
+ *tag = ris;
+ return ASN1_SUCCESS;
}
/**
@@ -180,20 +197,22 @@ asn1_get_tag_der(const unsigned char *der, int der_len,
*
* Since: 2.0
**/
-long asn1_get_length_ber(const unsigned char *ber, int ber_len, int *len)
+long
+asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len)
{
- int ret;
- long err;
-
- ret = asn1_get_length_der(ber, ber_len, len);
- if (ret == -1) { /* indefinite length method */
- ret = ber_len;
- err = _asn1_get_indefinite_length_string(ber + 1, &ret);
- if (err != ASN1_SUCCESS)
- return -3;
- }
-
- return ret;
+ int ret;
+ long err;
+
+ ret = asn1_get_length_der (ber, ber_len, len);
+ if (ret == -1)
+ { /* indefinite length method */
+ ret = ber_len;
+ err = _asn1_get_indefinite_length_string (ber + 1, &ret);
+ if (err != ASN1_SUCCESS)
+ return -3;
+ }
+
+ return ret;
}
/**
@@ -210,109 +229,112 @@ long asn1_get_length_ber(const unsigned char *ber, int ber_len, int *len)
* Returns: Returns %ASN1_SUCCESS on success, or an error.
**/
int
-asn1_get_octet_der(const unsigned char *der, int der_len,
- int *ret_len, unsigned char *str, int str_size,
- int *str_len)
+asn1_get_octet_der (const unsigned char *der, int der_len,
+ int *ret_len, unsigned char *str, int str_size,
+ int *str_len)
{
- int len_len;
+ int len_len;
- if (der_len <= 0)
- return ASN1_GENERIC_ERROR;
+ if (der_len <= 0)
+ return ASN1_GENERIC_ERROR;
- /* if(str==NULL) return ASN1_SUCCESS; */
- *str_len = asn1_get_length_der(der, der_len, &len_len);
+ /* if(str==NULL) return ASN1_SUCCESS; */
+ *str_len = asn1_get_length_der (der, der_len, &len_len);
- if (*str_len < 0)
- return ASN1_DER_ERROR;
+ if (*str_len < 0)
+ return ASN1_DER_ERROR;
- *ret_len = *str_len + len_len;
- if (str_size >= *str_len)
- memcpy(str, der + len_len, *str_len);
- else {
- return ASN1_MEM_ERROR;
- }
+ *ret_len = *str_len + len_len;
+ if (str_size >= *str_len)
+ memcpy (str, der + len_len, *str_len);
+ else
+ {
+ return ASN1_MEM_ERROR;
+ }
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
/* Returns ASN1_SUCCESS on success or an error code on error.
*/
static int
-_asn1_get_time_der(const unsigned char *der, int der_len, int *ret_len,
- char *str, int str_size)
+_asn1_get_time_der (const unsigned char *der, int der_len, int *ret_len,
+ char *str, int str_size)
{
- int len_len, str_len;
-
- if (der_len <= 0 || str == NULL)
- return ASN1_DER_ERROR;
- str_len = asn1_get_length_der(der, der_len, &len_len);
- if (str_len < 0 || str_size < str_len)
- return ASN1_DER_ERROR;
- memcpy(str, der + len_len, str_len);
- str[str_len] = 0;
- *ret_len = str_len + len_len;
-
- return ASN1_SUCCESS;
+ int len_len, str_len;
+
+ if (der_len <= 0 || str == NULL)
+ return ASN1_DER_ERROR;
+ str_len = asn1_get_length_der (der, der_len, &len_len);
+ if (str_len < 0 || str_size < str_len)
+ return ASN1_DER_ERROR;
+ memcpy (str, der + len_len, str_len);
+ str[str_len] = 0;
+ *ret_len = str_len + len_len;
+
+ return ASN1_SUCCESS;
}
static int
-_asn1_get_objectid_der(const unsigned char *der, int der_len, int *ret_len,
- char *str, int str_size)
+_asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len,
+ char *str, int str_size)
{
- int len_len, len, k;
- int leading;
- char temp[20];
- unsigned long val, val1, prev_val;
-
- *ret_len = 0;
- if (str && str_size > 0)
- str[0] = 0; /* no oid */
-
- if (str == NULL || der_len <= 0)
- return ASN1_GENERIC_ERROR;
- len = asn1_get_length_der(der, der_len, &len_len);
-
- if (len < 0 || len > der_len || len_len > der_len)
- return ASN1_DER_ERROR;
-
- val1 = der[len_len] / 40;
- val = der[len_len] - val1 * 40;
-
- _asn1_str_cpy(str, str_size, _asn1_ltostr(val1, temp));
- _asn1_str_cat(str, str_size, ".");
- _asn1_str_cat(str, str_size, _asn1_ltostr(val, temp));
-
- prev_val = 0;
- val = 0;
- leading = 1;
- for (k = 1; k < len; k++) {
- /* X.690 mandates that the leading byte must never be 0x80
- */
- if (leading != 0 && der[len_len + k] == 0x80)
- return ASN1_DER_ERROR;
- leading = 0;
-
- /* check for wrap around */
- val = val << 7;
- val |= der[len_len + k] & 0x7F;
-
- if (val < prev_val)
- return ASN1_DER_ERROR;
+ int len_len, len, k;
+ int leading;
+ char temp[20];
+ unsigned long val, val1;
+
+ *ret_len = 0;
+ if (str && str_size > 0)
+ str[0] = 0; /* no oid */
+
+ if (str == NULL || der_len <= 0)
+ return ASN1_GENERIC_ERROR;
+
+ len = asn1_get_length_der (der, der_len, &len_len);
+
+ if (len < 0 || len > der_len || len_len > der_len)
+ return ASN1_DER_ERROR;
+
+ val1 = der[len_len] / 40;
+ val = der[len_len] - val1 * 40;
+
+ _asn1_str_cpy (str, str_size, _asn1_ltostr (val1, temp));
+ _asn1_str_cat (str, str_size, ".");
+ _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
+
+ val = 0;
+ leading = 1;
+ for (k = 1; k < len; k++)
+ {
+ /* X.690 mandates that the leading byte must never be 0x80
+ */
+ if (leading != 0 && der[len_len + k] == 0x80)
+ return ASN1_DER_ERROR;
+ leading = 0;
+
+ /* check for wrap around */
+ if (INT_LEFT_SHIFT_OVERFLOW (val, 7))
+ return ASN1_DER_ERROR;
+
+ val = val << 7;
+ val |= der[len_len + k] & 0x7F;
+
+ if (!(der[len_len + k] & 0x80))
+ {
+ _asn1_str_cat (str, str_size, ".");
+ _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
+ val = 0;
+ leading = 1;
+ }
+ }
- prev_val = val;
+ if (INT_ADD_OVERFLOW (len, len_len))
+ return ASN1_DER_ERROR;
- if (!(der[len_len + k] & 0x80)) {
- _asn1_str_cat(str, str_size, ".");
- _asn1_str_cat(str, str_size,
- _asn1_ltostr(val, temp));
- val = 0;
- prev_val = 0;
- leading = 1;
- }
- }
- *ret_len = len + len_len;
+ *ret_len = len + len_len;
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
/**
@@ -329,430 +351,475 @@ _asn1_get_objectid_der(const unsigned char *der, int der_len, int *ret_len,
* Returns: Return %ASN1_SUCCESS on success, or an error.
**/
int
-asn1_get_bit_der(const unsigned char *der, int der_len,
- int *ret_len, unsigned char *str, int str_size,
- int *bit_len)
+asn1_get_bit_der (const unsigned char *der, int der_len,
+ int *ret_len, unsigned char *str, int str_size,
+ int *bit_len)
{
- int len_len, len_byte;
+ int len_len, len_byte;
- if (der_len <= 0)
- return ASN1_GENERIC_ERROR;
- len_byte = asn1_get_length_der(der, der_len, &len_len) - 1;
- if (len_byte < 0)
- return ASN1_DER_ERROR;
+ if (der_len <= 0)
+ return ASN1_GENERIC_ERROR;
+ len_byte = asn1_get_length_der (der, der_len, &len_len) - 1;
+ if (len_byte < 0)
+ return ASN1_DER_ERROR;
- *ret_len = len_byte + len_len + 1;
- *bit_len = len_byte * 8 - der[len_len];
+ *ret_len = len_byte + len_len + 1;
+ *bit_len = len_byte * 8 - der[len_len];
- if (str_size >= len_byte)
- memcpy(str, der + len_len + 1, len_byte);
- else {
- return ASN1_MEM_ERROR;
- }
+ if (str_size >= len_byte)
+ memcpy (str, der + len_len + 1, len_byte);
+ else
+ {
+ return ASN1_MEM_ERROR;
+ }
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
+
static int
-_asn1_extract_tag_der(asn1_node node, const unsigned char *der,
- int der_len, int *ret_len)
+_asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len,
+ int *ret_len)
{
- asn1_node p;
- int counter, len2, len3, is_tag_implicit;
- unsigned long tag, tag_implicit = 0;
- unsigned char class, class2, class_implicit = 0;
-
- if (der_len <= 0)
- return ASN1_GENERIC_ERROR;
-
- counter = is_tag_implicit = 0;
-
- if (node->type & CONST_TAG) {
- p = node->down;
- while (p) {
- if (type_field(p->type) == ASN1_ETYPE_TAG) {
- if (p->type & CONST_APPLICATION)
- class2 = ASN1_CLASS_APPLICATION;
- else if (p->type & CONST_UNIVERSAL)
- class2 = ASN1_CLASS_UNIVERSAL;
- else if (p->type & CONST_PRIVATE)
- class2 = ASN1_CLASS_PRIVATE;
- else
- class2 =
- ASN1_CLASS_CONTEXT_SPECIFIC;
-
- if (p->type & CONST_EXPLICIT) {
- if (asn1_get_tag_der
- (der + counter,
- der_len - counter, &class,
- &len2, &tag) != ASN1_SUCCESS)
- return ASN1_DER_ERROR;
-
- if (counter + len2 > der_len)
- return ASN1_DER_ERROR;
- counter += len2;
-
- len3 =
- asn1_get_length_ber(der +
- counter,
- der_len -
- counter,
- &len2);
- if (len3 < 0)
- return ASN1_DER_ERROR;
-
- counter += len2;
- if (counter > der_len)
- return ASN1_DER_ERROR;
-
- if (!is_tag_implicit) {
- if ((class !=
- (class2 |
- ASN1_CLASS_STRUCTURED))
- || (tag !=
- strtoul((char *)
- p->value,
- NULL, 10)))
- return
- ASN1_TAG_ERROR;
- } else { /* ASN1_TAG_IMPLICIT */
- if ((class !=
- class_implicit)
- || (tag !=
- tag_implicit))
- return
- ASN1_TAG_ERROR;
- }
- is_tag_implicit = 0;
- } else { /* ASN1_TAG_IMPLICIT */
- if (!is_tag_implicit) {
- if ((type_field(node->type)
- ==
- ASN1_ETYPE_SEQUENCE)
- ||
- (type_field(node->type)
- ==
- ASN1_ETYPE_SEQUENCE_OF)
- ||
- (type_field(node->type)
- == ASN1_ETYPE_SET)
- ||
- (type_field(node->type)
- == ASN1_ETYPE_SET_OF))
- class2 |=
- ASN1_CLASS_STRUCTURED;
- class_implicit = class2;
- tag_implicit =
- strtoul((char *) p->
- value, NULL,
- 10);
- is_tag_implicit = 1;
- }
- }
- }
- p = p->right;
+ asn1_node p;
+ int counter, len2, len3, is_tag_implicit;
+ unsigned long tag, tag_implicit = 0;
+ unsigned char class, class2, class_implicit = 0;
+
+ if (der_len <= 0)
+ return ASN1_GENERIC_ERROR;
+
+ counter = is_tag_implicit = 0;
+
+ if (node->type & CONST_TAG)
+ {
+ p = node->down;
+ while (p)
+ {
+ if (type_field (p->type) == ASN1_ETYPE_TAG)
+ {
+ if (p->type & CONST_APPLICATION)
+ class2 = ASN1_CLASS_APPLICATION;
+ else if (p->type & CONST_UNIVERSAL)
+ class2 = ASN1_CLASS_UNIVERSAL;
+ else if (p->type & CONST_PRIVATE)
+ class2 = ASN1_CLASS_PRIVATE;
+ else
+ class2 = ASN1_CLASS_CONTEXT_SPECIFIC;
+
+ if (p->type & CONST_EXPLICIT)
+ {
+ if (asn1_get_tag_der
+ (der + counter, der_len - counter, &class, &len2,
+ &tag) != ASN1_SUCCESS)
+ return ASN1_DER_ERROR;
+
+ if (counter + len2 > der_len)
+ return ASN1_DER_ERROR;
+ counter += len2;
+
+ len3 =
+ asn1_get_length_ber (der + counter, der_len - counter,
+ &len2);
+ if (len3 < 0)
+ return ASN1_DER_ERROR;
+
+ counter += len2;
+ if (counter > der_len)
+ return ASN1_DER_ERROR;
+
+ if (!is_tag_implicit)
+ {
+ if ((class != (class2 | ASN1_CLASS_STRUCTURED)) ||
+ (tag != strtoul ((char *) p->value, NULL, 10)))
+ return ASN1_TAG_ERROR;
+ }
+ else
+ { /* ASN1_TAG_IMPLICIT */
+ if ((class != class_implicit) || (tag != tag_implicit))
+ return ASN1_TAG_ERROR;
+ }
+ is_tag_implicit = 0;
+ }
+ else
+ { /* ASN1_TAG_IMPLICIT */
+ if (!is_tag_implicit)
+ {
+ if ((type_field (node->type) == ASN1_ETYPE_SEQUENCE) ||
+ (type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF)
+ || (type_field (node->type) == ASN1_ETYPE_SET)
+ || (type_field (node->type) == ASN1_ETYPE_SET_OF))
+ class2 |= ASN1_CLASS_STRUCTURED;
+ class_implicit = class2;
+ tag_implicit = strtoul ((char *) p->value, NULL, 10);
+ is_tag_implicit = 1;
+ }
}
+ }
+ p = p->right;
+ }
+ }
+
+ if (is_tag_implicit)
+ {
+ if (asn1_get_tag_der
+ (der + counter, der_len - counter, &class, &len2,
+ &tag) != ASN1_SUCCESS)
+ return ASN1_DER_ERROR;
+ if (counter + len2 > der_len)
+ return ASN1_DER_ERROR;
+
+ if ((class != class_implicit) || (tag != tag_implicit))
+ {
+ if (type_field (node->type) == ASN1_ETYPE_OCTET_STRING)
+ {
+ class_implicit |= ASN1_CLASS_STRUCTURED;
+ if ((class != class_implicit) || (tag != tag_implicit))
+ return ASN1_TAG_ERROR;
+ }
+ else
+ return ASN1_TAG_ERROR;
+ }
+ }
+ else
+ {
+ unsigned type = type_field (node->type);
+ if (type == ASN1_ETYPE_TAG)
+ {
+ counter = 0;
+ *ret_len = counter;
+ return ASN1_SUCCESS;
}
- if (is_tag_implicit) {
- if (asn1_get_tag_der
- (der + counter, der_len - counter, &class, &len2,
- &tag) != ASN1_SUCCESS)
- return ASN1_DER_ERROR;
- if (counter + len2 > der_len)
- return ASN1_DER_ERROR;
-
- if ((class != class_implicit) || (tag != tag_implicit)) {
- if (type_field(node->type) ==
- ASN1_ETYPE_OCTET_STRING) {
- class_implicit |= ASN1_CLASS_STRUCTURED;
- if ((class != class_implicit)
- || (tag != tag_implicit))
- return ASN1_TAG_ERROR;
- } else
- return ASN1_TAG_ERROR;
- }
- } else {
- unsigned type = type_field(node->type);
- if (type == ASN1_ETYPE_TAG) {
- counter = 0;
- *ret_len = counter;
- return ASN1_SUCCESS;
- }
-
- if (asn1_get_tag_der
- (der + counter, der_len - counter, &class, &len2,
- &tag) != ASN1_SUCCESS)
- return ASN1_DER_ERROR;
-
- if (counter + len2 > der_len)
- return ASN1_DER_ERROR;
-
- switch (type) {
- case ASN1_ETYPE_NULL:
- case ASN1_ETYPE_BOOLEAN:
- case ASN1_ETYPE_INTEGER:
- case ASN1_ETYPE_ENUMERATED:
- case ASN1_ETYPE_OBJECT_ID:
- case ASN1_ETYPE_GENERALSTRING:
- case ASN1_ETYPE_NUMERIC_STRING:
- case ASN1_ETYPE_IA5_STRING:
- case ASN1_ETYPE_TELETEX_STRING:
- case ASN1_ETYPE_PRINTABLE_STRING:
- case ASN1_ETYPE_UNIVERSAL_STRING:
- case ASN1_ETYPE_BMP_STRING:
- case ASN1_ETYPE_UTF8_STRING:
- case ASN1_ETYPE_VISIBLE_STRING:
- case ASN1_ETYPE_BIT_STRING:
- case ASN1_ETYPE_SEQUENCE:
- case ASN1_ETYPE_SEQUENCE_OF:
- case ASN1_ETYPE_SET:
- case ASN1_ETYPE_SET_OF:
- case ASN1_ETYPE_GENERALIZED_TIME:
- case ASN1_ETYPE_UTC_TIME:
- if ((class != _asn1_tags[type].class)
- || (tag != _asn1_tags[type].tag))
- return ASN1_DER_ERROR;
- break;
-
- case ASN1_ETYPE_OCTET_STRING:
- /* OCTET STRING is handled differently to allow
- * BER encodings (structured class). */
- if (((class != ASN1_CLASS_UNIVERSAL)
- && (class !=
- (ASN1_CLASS_UNIVERSAL |
- ASN1_CLASS_STRUCTURED)))
- || (tag != ASN1_TAG_OCTET_STRING))
- return ASN1_DER_ERROR;
- break;
- case ASN1_ETYPE_ANY:
- counter -= len2;
- break;
- default:
- return ASN1_DER_ERROR;
- break;
- }
+ if (asn1_get_tag_der
+ (der + counter, der_len - counter, &class, &len2,
+ &tag) != ASN1_SUCCESS)
+ return ASN1_DER_ERROR;
+
+ if (counter + len2 > der_len)
+ return ASN1_DER_ERROR;
+
+ switch (type)
+ {
+ case ASN1_ETYPE_NULL:
+ case ASN1_ETYPE_BOOLEAN:
+ case ASN1_ETYPE_INTEGER:
+ case ASN1_ETYPE_ENUMERATED:
+ case ASN1_ETYPE_OBJECT_ID:
+ case ASN1_ETYPE_GENERALSTRING:
+ case ASN1_ETYPE_NUMERIC_STRING:
+ case ASN1_ETYPE_IA5_STRING:
+ case ASN1_ETYPE_TELETEX_STRING:
+ case ASN1_ETYPE_PRINTABLE_STRING:
+ case ASN1_ETYPE_UNIVERSAL_STRING:
+ case ASN1_ETYPE_BMP_STRING:
+ case ASN1_ETYPE_UTF8_STRING:
+ case ASN1_ETYPE_VISIBLE_STRING:
+ case ASN1_ETYPE_BIT_STRING:
+ case ASN1_ETYPE_SEQUENCE:
+ case ASN1_ETYPE_SEQUENCE_OF:
+ case ASN1_ETYPE_SET:
+ case ASN1_ETYPE_SET_OF:
+ case ASN1_ETYPE_GENERALIZED_TIME:
+ case ASN1_ETYPE_UTC_TIME:
+ if ((class != _asn1_tags[type].class)
+ || (tag != _asn1_tags[type].tag))
+ return ASN1_DER_ERROR;
+ break;
+
+ case ASN1_ETYPE_OCTET_STRING:
+ /* OCTET STRING is handled differently to allow
+ * BER encodings (structured class). */
+ if (((class != ASN1_CLASS_UNIVERSAL)
+ && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
+ || (tag != ASN1_TAG_OCTET_STRING))
+ return ASN1_DER_ERROR;
+ break;
+ case ASN1_ETYPE_ANY:
+ counter -= len2;
+ break;
+ case ASN1_ETYPE_CHOICE:
+ counter -= len2;
+ break;
+ default:
+ return ASN1_DER_ERROR;
+ break;
}
+ }
- counter += len2;
- *ret_len = counter;
- return ASN1_SUCCESS;
+ counter += len2;
+ *ret_len = counter;
+ return ASN1_SUCCESS;
}
-static int _asn1_delete_not_used(asn1_node node)
+static int
+extract_tag_der_recursive(asn1_node node, const unsigned char *der, int der_len,
+ int *ret_len)
{
- asn1_node p, p2;
-
- if (node == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
-
- p = node;
- while (p) {
- if (p->type & CONST_NOT_USED) {
- p2 = NULL;
- if (p != node) {
- p2 = _asn1_find_left(p);
- if (!p2)
- p2 = _asn1_find_up(p);
- }
- asn1_delete_structure(&p);
- p = p2;
- }
-
- if (!p)
- break; /* reach node */
-
- if (p->down) {
- p = p->down;
- } else {
- if (p == node)
- p = NULL;
- else if (p->right)
- p = p->right;
- else {
- while (1) {
- p = _asn1_find_up(p);
- if (p == node) {
- p = NULL;
- break;
- }
- if (p->right) {
- p = p->right;
- break;
- }
- }
- }
- }
+asn1_node p;
+int ris = ASN1_DER_ERROR;
+
+ if (type_field (node->type) == ASN1_ETYPE_CHOICE)
+ {
+ p = node->down;
+ while (p)
+ {
+ ris = _asn1_extract_tag_der (p, der, der_len, ret_len);
+ if (ris == ASN1_SUCCESS)
+ break;
+ p = p->right;
}
- return ASN1_SUCCESS;
+
+ *ret_len = 0;
+ return ris;
+ }
+ else
+ return _asn1_extract_tag_der (node, der, der_len, ret_len);
}
static int
-_asn1_extract_der_octet(asn1_node node, const unsigned char *der,
- int der_len)
+_asn1_delete_not_used (asn1_node node)
{
- int len2, len3;
- int counter2, counter_end;
-
- len2 = asn1_get_length_der(der, der_len, &len3);
- if (len2 < -1)
- return ASN1_DER_ERROR;
-
- counter2 = len3 + 1;
-
- if (len2 == -1)
- counter_end = der_len - 2;
- else
- counter_end = der_len;
-
- while (counter2 < counter_end) {
- len2 =
- asn1_get_length_der(der + counter2, der_len - counter2,
- &len3);
-
- if (len2 < -1)
- return ASN1_DER_ERROR;
+ asn1_node p, p2;
+
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p = node;
+ while (p)
+ {
+ if (p->type & CONST_NOT_USED)
+ {
+ p2 = NULL;
+ if (p != node)
+ {
+ p2 = _asn1_find_left (p);
+ if (!p2)
+ p2 = _asn1_find_up (p);
+ }
+ asn1_delete_structure (&p);
+ p = p2;
+ }
- if (len2 > 0) {
- _asn1_append_value(node, der + counter2 + len3,
- len2);
- } else { /* indefinite */
+ if (!p)
+ break; /* reach node */
- len2 =
- _asn1_extract_der_octet(node,
- der + counter2 + len3,
- der_len - counter2 -
- len3);
- if (len2 < 0)
- return len2;
+ if (p->down)
+ {
+ p = p->down;
+ }
+ else
+ {
+ if (p == node)
+ p = NULL;
+ else if (p->right)
+ p = p->right;
+ else
+ {
+ while (1)
+ {
+ p = _asn1_find_up (p);
+ if (p == node)
+ {
+ p = NULL;
+ break;
+ }
+ if (p->right)
+ {
+ p = p->right;
+ break;
+ }
}
-
- counter2 += len2 + len3 + 1;
+ }
}
-
- return ASN1_SUCCESS;
+ }
+ return ASN1_SUCCESS;
}
static int
-_asn1_get_octet_string(const unsigned char *der, asn1_node node, int *len)
+_asn1_extract_der_octet (asn1_node node, const unsigned char *der,
+ int der_len)
{
- int len2, len3, counter, tot_len, indefinite;
+ int len2, len3;
+ int counter2, counter_end;
- counter = 0;
+ len2 = asn1_get_length_der (der, der_len, &len3);
+ if (len2 < -1)
+ return ASN1_DER_ERROR;
- if (*(der - 1) & ASN1_CLASS_STRUCTURED) {
- tot_len = 0;
- indefinite = asn1_get_length_der(der, *len, &len3);
- if (indefinite < -1)
- return ASN1_DER_ERROR;
+ counter2 = len3 + 1;
- counter += len3;
- if (indefinite >= 0)
- indefinite += len3;
+ if (len2 == -1)
+ counter_end = der_len - 2;
+ else
+ counter_end = der_len;
- while (1) {
- if (counter > (*len))
- return ASN1_DER_ERROR;
+ while (counter2 < counter_end)
+ {
+ len2 = asn1_get_length_der (der + counter2, der_len - counter2, &len3);
- if (indefinite == -1) {
- if ((der[counter] == 0)
- && (der[counter + 1] == 0)) {
- counter += 2;
- break;
- }
- } else if (counter >= indefinite)
- break;
+ if (len2 < -1)
+ return ASN1_DER_ERROR;
- if (der[counter] != ASN1_TAG_OCTET_STRING)
- return ASN1_DER_ERROR;
+ if (len2 > 0)
+ {
+ _asn1_append_value (node, der + counter2 + len3, len2);
+ }
+ else
+ { /* indefinite */
+
+ len2 =
+ _asn1_extract_der_octet (node, der + counter2 + len3,
+ der_len - counter2 - len3);
+ if (len2 < 0)
+ return len2;
+ }
- counter++;
+ counter2 += len2 + len3 + 1;
+ }
- len2 =
- asn1_get_length_der(der + counter,
- *len - counter, &len3);
- if (len2 <= 0)
- return ASN1_DER_ERROR;
+ return ASN1_SUCCESS;
+}
- counter += len3 + len2;
- tot_len += len2;
+static int
+_asn1_get_octet_string (const unsigned char *der, asn1_node node, int *len)
+{
+ int len2, len3, counter, tot_len, indefinite;
+
+ counter = 0;
+
+ if (*(der - 1) & ASN1_CLASS_STRUCTURED)
+ {
+ tot_len = 0;
+ indefinite = asn1_get_length_der (der, *len, &len3);
+ if (indefinite < -1)
+ return ASN1_DER_ERROR;
+
+ counter += len3;
+ if (indefinite >= 0)
+ indefinite += len3;
+
+ while (1)
+ {
+ if (counter > (*len))
+ return ASN1_DER_ERROR;
+
+ if (indefinite == -1)
+ {
+ if ((der[counter] == 0) && (der[counter + 1] == 0))
+ {
+ counter += 2;
+ break;
}
+ }
+ else if (counter >= indefinite)
+ break;
- /* copy */
- if (node) {
- unsigned char temp[DER_LEN];
- int ret;
+ if (der[counter] != ASN1_TAG_OCTET_STRING)
+ return ASN1_DER_ERROR;
- len2 = sizeof(temp);
+ counter++;
- asn1_length_der(tot_len, temp, &len2);
- _asn1_set_value(node, temp, len2);
+ len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
+ if (len2 <= 0)
+ return ASN1_DER_ERROR;
- ret = _asn1_extract_der_octet(node, der, *len);
- if (ret != ASN1_SUCCESS)
- return ret;
+ counter += len3 + len2;
+ tot_len += len2;
+ }
- }
- } else { /* NOT STRUCTURED */
- len2 = asn1_get_length_der(der, *len, &len3);
- if (len2 < 0)
- return ASN1_DER_ERROR;
+ /* copy */
+ if (node)
+ {
+ unsigned char temp[DER_LEN];
+ int ret;
+
+ len2 = sizeof (temp);
+
+ asn1_length_der (tot_len, temp, &len2);
+ _asn1_set_value (node, temp, len2);
+
+ ret = _asn1_extract_der_octet (node, der, *len);
+ if (ret != ASN1_SUCCESS)
+ return ret;
- counter = len3 + len2;
- if (node)
- _asn1_set_value(node, der, counter);
}
+ }
+ else
+ { /* NOT STRUCTURED */
+ len2 = asn1_get_length_der (der, *len, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
- *len = counter;
- return ASN1_SUCCESS;
+ counter = len3 + len2;
+ if (node)
+ _asn1_set_value (node, der, counter);
+ }
+
+ *len = counter;
+ return ASN1_SUCCESS;
}
static int
-_asn1_get_indefinite_length_string(const unsigned char *der, int *len)
+_asn1_get_indefinite_length_string (const unsigned char *der, int *len)
{
- int len2, len3, counter, indefinite;
- unsigned long tag;
- unsigned char class;
-
- counter = indefinite = 0;
+ int len2, len3, counter, indefinite;
+ unsigned long tag;
+ unsigned char class;
+
+ counter = indefinite = 0;
+
+ while (1)
+ {
+ if ((*len) < counter)
+ return ASN1_DER_ERROR;
+
+ if ((der[counter] == 0) && (der[counter + 1] == 0))
+ {
+ counter += 2;
+ indefinite--;
+ if (indefinite <= 0)
+ break;
+ else
+ continue;
+ }
- while (1) {
- if ((*len) < counter)
- return ASN1_DER_ERROR;
+ if (asn1_get_tag_der
+ (der + counter, *len - counter, &class, &len2,
+ &tag) != ASN1_SUCCESS)
+ return ASN1_DER_ERROR;
+ if (counter + len2 > *len)
+ return ASN1_DER_ERROR;
+ counter += len2;
+ len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
+ if (len2 < -1)
+ return ASN1_DER_ERROR;
+ if (len2 == -1)
+ {
+ indefinite++;
+ counter += 1;
+ }
+ else
+ {
+ counter += len2 + len3;
+ }
+ }
- if ((der[counter] == 0) && (der[counter + 1] == 0)) {
- counter += 2;
- indefinite--;
- if (indefinite <= 0)
- break;
- else
- continue;
- }
+ *len = counter;
+ return ASN1_SUCCESS;
- if (asn1_get_tag_der
- (der + counter, *len - counter, &class, &len2,
- &tag) != ASN1_SUCCESS)
- return ASN1_DER_ERROR;
- if (counter + len2 > *len)
- return ASN1_DER_ERROR;
- counter += len2;
- len2 =
- asn1_get_length_der(der + counter, *len - counter,
- &len3);
- if (len2 < -1)
- return ASN1_DER_ERROR;
- if (len2 == -1) {
- indefinite++;
- counter += 1;
- } else {
- counter += len2 + len3;
- }
- }
+}
- *len = counter;
- return ASN1_SUCCESS;
+static void delete_unneeded_choice_fields(asn1_node p)
+{
+ asn1_node p2;
+ while (p->right)
+ {
+ p2 = p->right;
+ asn1_delete_structure (&p2);
+ }
}
/**
@@ -775,563 +842,537 @@ _asn1_get_indefinite_length_string(const unsigned char *der, int *len)
* name (*@ELEMENT deleted).
**/
int
-asn1_der_decoding(asn1_node * element, const void *ider, int len,
- char *errorDescription)
+asn1_der_decoding (asn1_node * element, const void *ider, int len,
+ char *errorDescription)
{
- asn1_node node, p, p2, p3;
- char temp[128];
- int counter, len2, len3, len4, move, ris, tlen;
- unsigned char class;
- unsigned long tag;
- int indefinite, result;
- const unsigned char *der = ider;
+ asn1_node node, p, p2, p3;
+ char temp[128];
+ int counter, len2, len3, len4, move, ris, tlen;
+ unsigned char class;
+ unsigned long tag;
+ int indefinite, result;
+ const unsigned char *der = ider;
+
+ node = *element;
+
+ if (errorDescription != NULL)
+ errorDescription[0] = 0;
+
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ if (node->type & CONST_OPTION)
+ {
+ result = ASN1_GENERIC_ERROR;
+ goto cleanup;
+ }
+
+ counter = 0;
+ move = DOWN;
+ p = node;
+ while (1)
+ {
+ ris = ASN1_SUCCESS;
+ if (move != UP)
+ {
+ if (p->type & CONST_SET)
+ {
+ p2 = _asn1_find_up (p);
+ len2 = _asn1_strtol (p2->value, NULL, 10);
+ if (len2 == -1)
+ {
+ if (!der[counter] && !der[counter + 1])
+ {
+ p = p2;
+ move = UP;
+ counter += 2;
+ continue;
+ }
+ }
+ else if (counter == len2)
+ {
+ p = p2;
+ move = UP;
+ continue;
+ }
+ else if (counter > len2)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ p2 = p2->down;
+ while (p2)
+ {
+ if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
+ {
+ ris =
+ extract_tag_der_recursive (p2, der + counter,
+ len - counter, &len2);
+ if (ris == ASN1_SUCCESS)
+ {
+ p2->type &= ~CONST_NOT_USED;
+ p = p2;
+ break;
+ }
+ }
+ p2 = p2->right;
+ }
+ if (p2 == NULL)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ }
+
+ if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
+ {
+ p2 = _asn1_find_up (p);
+ len2 = _asn1_strtol (p2->value, NULL, 10);
+ if (counter == len2)
+ {
+ if (p->right)
+ {
+ p2 = p->right;
+ move = RIGHT;
+ }
+ else
+ move = UP;
+
+ if (p->type & CONST_OPTION)
+ asn1_delete_structure (&p);
+
+ p = p2;
+ continue;
+ }
+ }
+
+ if (type_field (p->type) == ASN1_ETYPE_CHOICE)
+ {
+ while (p->down)
+ {
+ if (counter < len)
+ ris =
+ extract_tag_der_recursive (p->down, der + counter,
+ len - counter, &len2);
+ else
+ ris = ASN1_DER_ERROR;
+ if (ris == ASN1_SUCCESS)
+ {
+ delete_unneeded_choice_fields(p->down);
+ break;
+ }
+ else if (ris == ASN1_ERROR_TYPE_ANY)
+ {
+ result = ASN1_ERROR_TYPE_ANY;
+ goto cleanup;
+ }
+ else
+ {
+ p2 = p->down;
+ asn1_delete_structure (&p2);
+ }
+ }
- node = *element;
+ if (p->down == NULL)
+ {
+ if (!(p->type & CONST_OPTION))
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ }
+ else if (type_field (p->type) != ASN1_ETYPE_CHOICE)
+ p = p->down;
+ }
+
+ if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
+ {
+ p2 = _asn1_find_up (p);
+ len2 = _asn1_strtol (p2->value, NULL, 10);
+ if ((len2 != -1) && (counter > len2))
+ ris = ASN1_TAG_ERROR;
+ }
+
+ if (ris == ASN1_SUCCESS)
+ ris =
+ extract_tag_der_recursive (p, der + counter, len - counter, &len2);
+ if (ris != ASN1_SUCCESS)
+ {
+ if (p->type & CONST_OPTION)
+ {
+ p->type |= CONST_NOT_USED;
+ move = RIGHT;
+ }
+ else if (p->type & CONST_DEFAULT)
+ {
+ _asn1_set_value (p, NULL, 0);
+ move = RIGHT;
+ }
+ else
+ {
+ if (errorDescription != NULL)
+ _asn1_error_description_tag_error (p, errorDescription);
- if (errorDescription != NULL)
- errorDescription[0] = 0;
+ result = ASN1_TAG_ERROR;
+ goto cleanup;
+ }
+ }
+ else
+ counter += len2;
+ }
- if (node == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
+ if (ris == ASN1_SUCCESS)
+ {
+ switch (type_field (p->type))
+ {
+ case ASN1_ETYPE_NULL:
+ if (der[counter])
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ counter++;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_BOOLEAN:
+ if (der[counter++] != 1)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ if (der[counter++] == 0)
+ _asn1_set_value (p, "F", 1);
+ else
+ _asn1_set_value (p, "T", 1);
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_INTEGER:
+ case ASN1_ETYPE_ENUMERATED:
+ len2 =
+ asn1_get_length_der (der + counter, len - counter, &len3);
+ if (len2 < 0)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
- if (node->type & CONST_OPTION) {
- result = ASN1_GENERIC_ERROR;
+ _asn1_set_value (p, der + counter, len3 + len2);
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_OBJECT_ID:
+ result =
+ _asn1_get_objectid_der (der + counter, len - counter, &len2,
+ temp, sizeof (temp));
+ if (result != ASN1_SUCCESS)
goto cleanup;
- }
- counter = 0;
- move = DOWN;
- p = node;
- while (1) {
- ris = ASN1_SUCCESS;
- if (move != UP) {
- if (p->type & CONST_SET) {
- p2 = _asn1_find_up(p);
- len2 = _asn1_strtol(p2->value, NULL, 10);
- if (len2 == -1) {
- if (!der[counter]
- && !der[counter + 1]) {
- p = p2;
- move = UP;
- counter += 2;
- continue;
- }
- } else if (counter == len2) {
- p = p2;
- move = UP;
- continue;
- } else if (counter > len2) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
- p2 = p2->down;
- while (p2) {
- if ((p2->type & CONST_SET)
- && (p2->
- type & CONST_NOT_USED)) {
- if (type_field(p2->type) !=
- ASN1_ETYPE_CHOICE)
- ris =
- _asn1_extract_tag_der
- (p2,
- der + counter,
- len - counter,
- &len2);
- else {
- p3 = p2->down;
- while (p3) {
- ris =
- _asn1_extract_tag_der
- (p3,
- der +
- counter,
- len -
- counter,
- &len2);
- if (ris ==
- ASN1_SUCCESS)
- break;
- p3 = p3->
- right;
- }
- }
- if (ris == ASN1_SUCCESS) {
- p2->type &=
- ~CONST_NOT_USED;
- p = p2;
- break;
- }
- }
- p2 = p2->right;
- }
- if (p2 == NULL) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
- }
+ tlen = strlen (temp);
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen + 1);
+ counter += len2;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_GENERALIZED_TIME:
+ case ASN1_ETYPE_UTC_TIME:
+ result =
+ _asn1_get_time_der (der + counter, len - counter, &len2, temp,
+ sizeof (temp) - 1);
+ if (result != ASN1_SUCCESS)
+ goto cleanup;
- if ((p->type & CONST_OPTION)
- || (p->type & CONST_DEFAULT)) {
- p2 = _asn1_find_up(p);
- len2 = _asn1_strtol(p2->value, NULL, 10);
- if (counter == len2) {
- if (p->right) {
- p2 = p->right;
- move = RIGHT;
- } else
- move = UP;
-
- if (p->type & CONST_OPTION)
- asn1_delete_structure(&p);
-
- p = p2;
- continue;
- }
- }
+ tlen = strlen (temp);
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen);
+ counter += len2;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_OCTET_STRING:
+ len3 = len - counter;
+ result = _asn1_get_octet_string (der + counter, p, &len3);
+ if (result != ASN1_SUCCESS)
+ goto cleanup;
- if (type_field(p->type) == ASN1_ETYPE_CHOICE) {
- while (p->down) {
- if (counter < len)
- ris =
- _asn1_extract_tag_der
- (p->down,
- der + counter,
- len - counter, &len2);
- else
- ris = ASN1_DER_ERROR;
- if (ris == ASN1_SUCCESS) {
- while (p->down->right) {
- p2 = p->down->
- right;
- asn1_delete_structure
- (&p2);
- }
- break;
- } else if (ris ==
- ASN1_ERROR_TYPE_ANY) {
- result =
- ASN1_ERROR_TYPE_ANY;
- goto cleanup;
- } else {
- p2 = p->down;
- asn1_delete_structure(&p2);
- }
- }
+ counter += len3;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_GENERALSTRING:
+ case ASN1_ETYPE_NUMERIC_STRING:
+ case ASN1_ETYPE_IA5_STRING:
+ case ASN1_ETYPE_TELETEX_STRING:
+ case ASN1_ETYPE_PRINTABLE_STRING:
+ case ASN1_ETYPE_UNIVERSAL_STRING:
+ case ASN1_ETYPE_BMP_STRING:
+ case ASN1_ETYPE_UTF8_STRING:
+ case ASN1_ETYPE_VISIBLE_STRING:
+ case ASN1_ETYPE_BIT_STRING:
+ len2 =
+ asn1_get_length_der (der + counter, len - counter, &len3);
+ if (len2 < 0)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
- if (p->down == NULL) {
- if (!(p->type & CONST_OPTION)) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
- } else
- p = p->down;
+ _asn1_set_value (p, der + counter, len3 + len2);
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_SEQUENCE:
+ case ASN1_ETYPE_SET:
+ if (move == UP)
+ {
+ len2 = _asn1_strtol (p->value, NULL, 10);
+ _asn1_set_value (p, NULL, 0);
+ if (len2 == -1)
+ { /* indefinite length method */
+ if (len - counter + 1 > 0)
+ {
+ if ((der[counter]) || der[counter + 1])
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
}
-
- if ((p->type & CONST_OPTION)
- || (p->type & CONST_DEFAULT)) {
- p2 = _asn1_find_up(p);
- len2 = _asn1_strtol(p2->value, NULL, 10);
- if ((len2 != -1) && (counter > len2))
- ris = ASN1_TAG_ERROR;
+ else
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
-
- if (ris == ASN1_SUCCESS)
- ris =
- _asn1_extract_tag_der(p, der + counter,
- len - counter,
- &len2);
- if (ris != ASN1_SUCCESS) {
- if (p->type & CONST_OPTION) {
- p->type |= CONST_NOT_USED;
- move = RIGHT;
- } else if (p->type & CONST_DEFAULT) {
- _asn1_set_value(p, NULL, 0);
- move = RIGHT;
- } else {
- if (errorDescription != NULL)
- _asn1_error_description_tag_error
- (p, errorDescription);
-
- result = ASN1_TAG_ERROR;
- goto cleanup;
- }
- } else
- counter += len2;
+ counter += 2;
+ }
+ else
+ { /* definite length method */
+ if (len2 != counter)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ }
+ move = RIGHT;
}
-
- if (ris == ASN1_SUCCESS) {
- switch (type_field(p->type)) {
- case ASN1_ETYPE_NULL:
- if (der[counter]) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
- counter++;
- move = RIGHT;
- break;
- case ASN1_ETYPE_BOOLEAN:
- if (der[counter++] != 1) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
- if (der[counter++] == 0)
- _asn1_set_value(p, "F", 1);
- else
- _asn1_set_value(p, "T", 1);
- move = RIGHT;
- break;
- case ASN1_ETYPE_INTEGER:
- case ASN1_ETYPE_ENUMERATED:
- len2 =
- asn1_get_length_der(der + counter,
- len - counter,
- &len3);
- if (len2 < 0) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
-
- _asn1_set_value(p, der + counter,
- len3 + len2);
- counter += len3 + len2;
- move = RIGHT;
- break;
- case ASN1_ETYPE_OBJECT_ID:
- result =
- _asn1_get_objectid_der(der + counter,
- len - counter,
- &len2, temp,
- sizeof(temp));
- if (result != ASN1_SUCCESS)
- goto cleanup;
-
- tlen = strlen(temp);
- if (tlen > 0)
- _asn1_set_value(p, temp, tlen + 1);
- counter += len2;
- move = RIGHT;
- break;
- case ASN1_ETYPE_GENERALIZED_TIME:
- case ASN1_ETYPE_UTC_TIME:
- result =
- _asn1_get_time_der(der + counter,
- len - counter,
- &len2, temp,
- sizeof(temp) - 1);
- if (result != ASN1_SUCCESS)
- goto cleanup;
-
- tlen = strlen(temp);
- if (tlen > 0)
- _asn1_set_value(p, temp, tlen);
- counter += len2;
- move = RIGHT;
- break;
- case ASN1_ETYPE_OCTET_STRING:
- len3 = len - counter;
- result =
- _asn1_get_octet_string(der + counter,
- p, &len3);
- if (result != ASN1_SUCCESS)
- goto cleanup;
-
- counter += len3;
- move = RIGHT;
- break;
- case ASN1_ETYPE_GENERALSTRING:
- case ASN1_ETYPE_NUMERIC_STRING:
- case ASN1_ETYPE_IA5_STRING:
- case ASN1_ETYPE_TELETEX_STRING:
- case ASN1_ETYPE_PRINTABLE_STRING:
- case ASN1_ETYPE_UNIVERSAL_STRING:
- case ASN1_ETYPE_BMP_STRING:
- case ASN1_ETYPE_UTF8_STRING:
- case ASN1_ETYPE_VISIBLE_STRING:
- case ASN1_ETYPE_BIT_STRING:
- len2 =
- asn1_get_length_der(der + counter,
- len - counter,
- &len3);
- if (len2 < 0) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
-
- _asn1_set_value(p, der + counter,
- len3 + len2);
- counter += len3 + len2;
- move = RIGHT;
- break;
- case ASN1_ETYPE_SEQUENCE:
- case ASN1_ETYPE_SET:
- if (move == UP) {
- len2 =
- _asn1_strtol(p->value, NULL,
- 10);
- _asn1_set_value(p, NULL, 0);
- if (len2 == -1) { /* indefinite length method */
- if (len - counter + 1 > 0) {
- if ((der[counter])
- || der[counter
- + 1]) {
- result =
- ASN1_DER_ERROR;
- goto cleanup;
- }
- } else {
- result =
- ASN1_DER_ERROR;
- goto cleanup;
- }
- counter += 2;
- } else { /* definite length method */
- if (len2 != counter) {
- result =
- ASN1_DER_ERROR;
- goto cleanup;
- }
- }
- move = RIGHT;
- } else { /* move==DOWN || move==RIGHT */
- len3 =
- asn1_get_length_der(der +
- counter,
- len -
- counter,
- &len2);
- if (len3 < -1) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
- counter += len2;
- if (len3 > 0) {
- _asn1_ltostr(counter +
- len3, temp);
- tlen = strlen(temp);
- if (tlen > 0)
- _asn1_set_value(p,
- temp,
- tlen
- +
- 1);
- move = DOWN;
- } else if (len3 == 0) {
- p2 = p->down;
- while (p2) {
- if (type_field
- (p2->type) !=
- ASN1_ETYPE_TAG)
- {
- p3 = p2->
- right;
- asn1_delete_structure
- (&p2);
- p2 = p3;
- } else
- p2 = p2->
- right;
- }
- move = RIGHT;
- } else { /* indefinite length method */
- _asn1_set_value(p, "-1",
- 3);
- move = DOWN;
- }
- }
- break;
- case ASN1_ETYPE_SEQUENCE_OF:
- case ASN1_ETYPE_SET_OF:
- if (move == UP) {
- len2 =
- _asn1_strtol(p->value, NULL,
- 10);
- if (len2 == -1) { /* indefinite length method */
- if ((counter + 2) > len) {
- result =
- ASN1_DER_ERROR;
- goto cleanup;
- }
-
- if ((der[counter])
- || der[counter + 1]) {
- _asn1_append_sequence_set
- (p);
- p = p->down;
- while (p->right)
- p = p->
- right;
- move = RIGHT;
- continue;
- }
- _asn1_set_value(p, NULL,
- 0);
- counter += 2;
- } else { /* definite length method */
- if (len2 > counter) {
- _asn1_append_sequence_set
- (p);
- p = p->down;
- while (p->right)
- p = p->
- right;
- move = RIGHT;
- continue;
- }
- _asn1_set_value(p, NULL,
- 0);
- if (len2 != counter) {
- result =
- ASN1_DER_ERROR;
- goto cleanup;
- }
- }
- } else { /* move==DOWN || move==RIGHT */
- len3 =
- asn1_get_length_der(der +
- counter,
- len -
- counter,
- &len2);
- if (len3 < -1) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
- counter += len2;
- if (len3) {
- if (len3 > 0) { /* definite length method */
- _asn1_ltostr
- (counter +
- len3, temp);
- tlen =
- strlen(temp);
-
- if (tlen > 0)
- _asn1_set_value
- (p,
- temp,
- tlen +
- 1);
- } else { /* indefinite length method */
- _asn1_set_value(p,
- "-1",
- 3);
- }
- p2 = p->down;
- while ((type_field
- (p2->type) ==
- ASN1_ETYPE_TAG)
- ||
- (type_field
- (p2->type) ==
- ASN1_ETYPE_SIZE))
- p2 = p2->right;
- if (p2->right == NULL)
- _asn1_append_sequence_set
- (p);
- p = p2;
- }
- }
- move = RIGHT;
- break;
- case ASN1_ETYPE_ANY:
- if (asn1_get_tag_der
- (der + counter, len - counter, &class,
- &len2, &tag) != ASN1_SUCCESS) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
-
- if (counter + len2 > len) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
- len4 =
- asn1_get_length_der(der + counter +
- len2,
- len - counter -
- len2, &len3);
- if (len4 < -1) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
- if (len4 != -1) {
- len2 += len4;
- _asn1_set_value_lv(p,
- der + counter,
- len2 + len3);
- counter += len2 + len3;
- } else { /* indefinite length */
- /* Check indefinite lenth method in an EXPLICIT TAG */
- if ((p->type & CONST_TAG)
- && (der[counter - 1] == 0x80))
- indefinite = 1;
- else
- indefinite = 0;
-
- len2 = len - counter;
- result =
- _asn1_get_indefinite_length_string
- (der + counter, &len2);
- if (result != ASN1_SUCCESS)
- goto cleanup;
-
- _asn1_set_value_lv(p,
- der + counter,
- len2);
- counter += len2;
-
- /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
- an indefinite length method. */
- if (indefinite) {
- if (!der[counter]
- && !der[counter + 1]) {
- counter += 2;
- } else {
- result =
- ASN1_DER_ERROR;
- goto cleanup;
- }
- }
- }
- move = RIGHT;
- break;
- default:
- move = (move == UP) ? RIGHT : DOWN;
- break;
+ else
+ { /* move==DOWN || move==RIGHT */
+ len3 =
+ asn1_get_length_der (der + counter, len - counter, &len2);
+ if (len3 < -1)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ counter += len2;
+ if (len3 > 0)
+ {
+ _asn1_ltostr (counter + len3, temp);
+ tlen = strlen (temp);
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen + 1);
+ move = DOWN;
+ }
+ else if (len3 == 0)
+ {
+ p2 = p->down;
+ while (p2)
+ {
+ if (type_field (p2->type) != ASN1_ETYPE_TAG)
+ {
+ p3 = p2->right;
+ asn1_delete_structure (&p2);
+ p2 = p3;
+ }
+ else
+ p2 = p2->right;
}
+ move = RIGHT;
+ }
+ else
+ { /* indefinite length method */
+ _asn1_set_value (p, "-1", 3);
+ move = DOWN;
+ }
}
+ break;
+ case ASN1_ETYPE_SEQUENCE_OF:
+ case ASN1_ETYPE_SET_OF:
+ if (move == UP)
+ {
+ len2 = _asn1_strtol (p->value, NULL, 10);
+ if (len2 == -1)
+ { /* indefinite length method */
+ if ((counter + 2) > len)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
- if (p == node && move != DOWN)
- break;
+ if ((der[counter]) || der[counter + 1])
+ {
+ _asn1_append_sequence_set (p);
+ p = p->down;
+ while (p->right)
+ p = p->right;
+ move = RIGHT;
+ continue;
+ }
+ _asn1_set_value (p, NULL, 0);
+ counter += 2;
+ }
+ else
+ { /* definite length method */
+ if (len2 > counter)
+ {
+ _asn1_append_sequence_set (p);
+ p = p->down;
+ while (p->right)
+ p = p->right;
+ move = RIGHT;
+ continue;
+ }
+ _asn1_set_value (p, NULL, 0);
+ if (len2 != counter)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ }
+ }
+ else
+ { /* move==DOWN || move==RIGHT */
+ len3 =
+ asn1_get_length_der (der + counter, len - counter, &len2);
+ if (len3 < -1)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ counter += len2;
+ if (len3)
+ {
+ if (len3 > 0)
+ { /* definite length method */
+ _asn1_ltostr (counter + len3, temp);
+ tlen = strlen (temp);
+
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen + 1);
+ }
+ else
+ { /* indefinite length method */
+ _asn1_set_value (p, "-1", 3);
+ }
+ p2 = p->down;
+ while ((type_field (p2->type) == ASN1_ETYPE_TAG)
+ || (type_field (p2->type) == ASN1_ETYPE_SIZE))
+ p2 = p2->right;
+ if (p2->right == NULL)
+ _asn1_append_sequence_set (p);
+ p = p2;
+ }
+ }
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_ANY:
+ if (asn1_get_tag_der
+ (der + counter, len - counter, &class, &len2,
+ &tag) != ASN1_SUCCESS)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
- if (move == DOWN) {
- if (p->down)
- p = p->down;
- else
- move = RIGHT;
+ if (counter + len2 > len)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
- if ((move == RIGHT) && !(p->type & CONST_SET)) {
- if (p->right)
- p = p->right;
- else
- move = UP;
+ len4 =
+ asn1_get_length_der (der + counter + len2,
+ len - counter - len2, &len3);
+ if (len4 < -1)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ if (len4 != -1)
+ {
+ len2 += len4;
+ _asn1_set_value_lv (p, der + counter, len2 + len3);
+ counter += len2 + len3;
+ }
+ else
+ { /* indefinite length */
+ /* Check indefinite lenth method in an EXPLICIT TAG */
+ if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
+ indefinite = 1;
+ else
+ indefinite = 0;
+
+ len2 = len - counter;
+ result =
+ _asn1_get_indefinite_length_string (der + counter, &len2);
+ if (result != ASN1_SUCCESS)
+ goto cleanup;
+
+ _asn1_set_value_lv (p, der + counter, len2);
+ counter += len2;
+
+ /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
+ an indefinite length method. */
+ if (indefinite)
+ {
+ if (!der[counter] && !der[counter + 1])
+ {
+ counter += 2;
+ }
+ else
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ }
}
- if (move == UP)
- p = _asn1_find_up(p);
+ move = RIGHT;
+ break;
+ default:
+ move = (move == UP) ? RIGHT : DOWN;
+ break;
+ }
}
- _asn1_delete_not_used(*element);
+ if (p == node && move != DOWN)
+ break;
- if (counter != len) {
- result = ASN1_DER_ERROR;
- goto cleanup;
+ if (move == DOWN)
+ {
+ if (p->down)
+ p = p->down;
+ else
+ move = RIGHT;
+ }
+ if ((move == RIGHT) && !(p->type & CONST_SET))
+ {
+ if (p->right)
+ p = p->right;
+ else
+ move = UP;
}
+ if (move == UP)
+ p = _asn1_find_up (p);
+ }
- return ASN1_SUCCESS;
+ _asn1_delete_not_used (*element);
- cleanup:
- asn1_delete_structure(element);
- return result;
+ if (counter != len)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+
+ return ASN1_SUCCESS;
+
+cleanup:
+ asn1_delete_structure (element);
+ return result;
}
#define FOUND 1
@@ -1361,796 +1402,762 @@ asn1_der_decoding(asn1_node * element, const void *ider, int len,
* match the structure @structure (*ELEMENT deleted).
**/
int
-asn1_der_decoding_element(asn1_node * structure, const char *elementName,
- const void *ider, int len,
- char *errorDescription)
+asn1_der_decoding_element (asn1_node * structure, const char *elementName,
+ const void *ider, int len, char *errorDescription)
{
- asn1_node node, p, p2, p3, nodeFound = NULL;
- char temp[128], currentName[ASN1_MAX_NAME_SIZE * 10], *dot_p,
- *char_p;
- int nameLen = ASN1_MAX_NAME_SIZE * 10 - 1, state;
- int counter, len2, len3, len4, move, ris, tlen;
- unsigned char class;
- unsigned long tag;
- int indefinite, result;
- const unsigned char *der = ider;
-
- node = *structure;
-
- if (node == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
-
- if (elementName == NULL) {
- result = ASN1_ELEMENT_NOT_FOUND;
- goto cleanup;
+ asn1_node node, p, p2, p3, nodeFound = NULL;
+ char temp[128], currentName[ASN1_MAX_NAME_SIZE * 10], *dot_p, *char_p;
+ int nameLen = ASN1_MAX_NAME_SIZE * 10 - 1, state;
+ int counter, len2, len3, len4, move, ris, tlen;
+ unsigned char class;
+ unsigned long tag;
+ int indefinite, result;
+ const unsigned char *der = ider;
+
+ node = *structure;
+
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ if (elementName == NULL)
+ {
+ result = ASN1_ELEMENT_NOT_FOUND;
+ goto cleanup;
+ }
+
+ if (node->type & CONST_OPTION)
+ {
+ result = ASN1_GENERIC_ERROR;
+ goto cleanup;
+ }
+
+ if ((*structure)->name[0] != 0)
+ { /* Has *structure got a name? */
+ nameLen -= strlen ((*structure)->name);
+ if (nameLen > 0)
+ strcpy (currentName, (*structure)->name);
+ else
+ {
+ result = ASN1_MEM_ERROR;
+ goto cleanup;
}
-
- if (node->type & CONST_OPTION) {
- result = ASN1_GENERIC_ERROR;
- goto cleanup;
+ if (!(strcmp (currentName, elementName)))
+ {
+ state = FOUND;
+ nodeFound = *structure;
}
-
- if ((*structure)->name[0] != 0) { /* Has *structure got a name? */
- nameLen -= strlen((*structure)->name);
- if (nameLen > 0)
- strcpy(currentName, (*structure)->name);
- else {
- result = ASN1_MEM_ERROR;
- goto cleanup;
- }
- if (!(strcmp(currentName, elementName))) {
- state = FOUND;
- nodeFound = *structure;
- } else
- if (!memcmp
- (currentName, elementName, strlen(currentName)))
- state = SAME_BRANCH;
- else
- state = OTHER_BRANCH;
- } else { /* *structure doesn't have a name? */
- currentName[0] = 0;
- if (elementName[0] == 0) {
- state = FOUND;
- nodeFound = *structure;
- } else {
- state = SAME_BRANCH;
- }
+ else if (!memcmp (currentName, elementName, strlen (currentName)))
+ state = SAME_BRANCH;
+ else
+ state = OTHER_BRANCH;
+ }
+ else
+ { /* *structure doesn't have a name? */
+ currentName[0] = 0;
+ if (elementName[0] == 0)
+ {
+ state = FOUND;
+ nodeFound = *structure;
}
-
- counter = 0;
- move = DOWN;
- p = node;
- while (1) {
-
- ris = ASN1_SUCCESS;
-
- if (move != UP) {
- if (p->type & CONST_SET) {
- p2 = _asn1_find_up(p);
- len2 = _asn1_strtol(p2->value, NULL, 10);
- if (counter == len2) {
- p = p2;
- move = UP;
- continue;
- } else if (counter > len2) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
- p2 = p2->down;
- while (p2) {
- if ((p2->type & CONST_SET)
- && (p2->
- type & CONST_NOT_USED)) {
- if (type_field(p2->type) !=
- ASN1_ETYPE_CHOICE)
- ris =
- _asn1_extract_tag_der
- (p2,
- der + counter,
- len - counter,
- &len2);
- else {
- p3 = p2->down;
- while (p3) {
- ris =
- _asn1_extract_tag_der
- (p3,
- der +
- counter,
- len -
- counter,
- &len2);
- if (ris ==
- ASN1_SUCCESS)
- break;
- p3 = p3->
- right;
- }
- }
- if (ris == ASN1_SUCCESS) {
- p2->type &=
- ~CONST_NOT_USED;
- p = p2;
- break;
- }
- }
- p2 = p2->right;
- }
- if (p2 == NULL) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
- }
-
- if ((p->type & CONST_OPTION)
- || (p->type & CONST_DEFAULT)) {
- p2 = _asn1_find_up(p);
- len2 = _asn1_strtol(p2->value, NULL, 10);
- if (counter == len2) {
- if (p->right) {
- p2 = p->right;
- move = RIGHT;
- } else
- move = UP;
-
- if (p->type & CONST_OPTION)
- asn1_delete_structure(&p);
-
- p = p2;
- continue;
- }
- }
-
- if (type_field(p->type) == ASN1_ETYPE_CHOICE) {
- while (p->down) {
- if (counter < len)
- ris =
- _asn1_extract_tag_der
- (p->down,
- der + counter,
- len - counter, &len2);
- else
- ris = ASN1_DER_ERROR;
- if (ris == ASN1_SUCCESS) {
- while (p->down->right) {
- p2 = p->down->
- right;
- asn1_delete_structure
- (&p2);
- }
- break;
- } else if (ris ==
- ASN1_ERROR_TYPE_ANY) {
- result =
- ASN1_ERROR_TYPE_ANY;
- goto cleanup;
- } else {
- p2 = p->down;
- asn1_delete_structure(&p2);
- }
- }
-
- if (p->down == NULL) {
- if (!(p->type & CONST_OPTION)) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
- } else
- p = p->down;
- }
-
- if ((p->type & CONST_OPTION)
- || (p->type & CONST_DEFAULT)) {
- p2 = _asn1_find_up(p);
- len2 = _asn1_strtol(p2->value, NULL, 10);
- if (counter > len2)
- ris = ASN1_TAG_ERROR;
+ else
+ {
+ state = SAME_BRANCH;
+ }
+ }
+
+ counter = 0;
+ move = DOWN;
+ p = node;
+ while (1)
+ {
+
+ ris = ASN1_SUCCESS;
+
+ if (move != UP)
+ {
+ if (p->type & CONST_SET)
+ {
+ p2 = _asn1_find_up (p);
+ len2 = _asn1_strtol (p2->value, NULL, 10);
+ if (counter == len2)
+ {
+ p = p2;
+ move = UP;
+ continue;
+ }
+ else if (counter > len2)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ p2 = p2->down;
+ while (p2)
+ {
+ if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
+ {
+ ris =
+ extract_tag_der_recursive (p2, der + counter,
+ len - counter, &len2);
+ if (ris == ASN1_SUCCESS)
+ {
+ p2->type &= ~CONST_NOT_USED;
+ p = p2;
+ break;
}
-
- if (ris == ASN1_SUCCESS)
- ris =
- _asn1_extract_tag_der(p, der + counter,
- len - counter,
- &len2);
- if (ris != ASN1_SUCCESS) {
- if (p->type & CONST_OPTION) {
- p->type |= CONST_NOT_USED;
- move = RIGHT;
- } else if (p->type & CONST_DEFAULT) {
- _asn1_set_value(p, NULL, 0);
- move = RIGHT;
- } else {
- if (errorDescription != NULL)
- _asn1_error_description_tag_error
- (p, errorDescription);
-
- result = ASN1_TAG_ERROR;
- goto cleanup;
- }
- } else
- counter += len2;
+ }
+ p2 = p2->right;
+ }
+ if (p2 == NULL)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ }
+
+ if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
+ {
+ p2 = _asn1_find_up (p);
+ len2 = _asn1_strtol (p2->value, NULL, 10);
+ if (counter == len2)
+ {
+ if (p->right)
+ {
+ p2 = p->right;
+ move = RIGHT;
+ }
+ else
+ move = UP;
+
+ if (p->type & CONST_OPTION)
+ asn1_delete_structure (&p);
+
+ p = p2;
+ continue;
+ }
+ }
+
+ if (type_field (p->type) == ASN1_ETYPE_CHOICE)
+ {
+ while (p->down)
+ {
+ if (counter < len)
+ ris =
+ _asn1_extract_tag_der (p->down, der + counter,
+ len - counter, &len2);
+ else
+ ris = ASN1_DER_ERROR;
+ if (ris == ASN1_SUCCESS)
+ {
+ delete_unneeded_choice_fields(p->down);
+ break;
+ }
+ else if (ris == ASN1_ERROR_TYPE_ANY)
+ {
+ result = ASN1_ERROR_TYPE_ANY;
+ goto cleanup;
+ }
+ else
+ {
+ p2 = p->down;
+ asn1_delete_structure (&p2);
+ }
}
- if (ris == ASN1_SUCCESS) {
- switch (type_field(p->type)) {
- case ASN1_ETYPE_NULL:
- if (der[counter]) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
+ if (p->down == NULL)
+ {
+ if (!(p->type & CONST_OPTION))
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ }
+ else if (type_field (p->type) != ASN1_ETYPE_CHOICE)
+ p = p->down;
+ }
+
+ if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
+ {
+ p2 = _asn1_find_up (p);
+ len2 = _asn1_strtol (p2->value, NULL, 10);
+ if (counter > len2)
+ ris = ASN1_TAG_ERROR;
+ }
+
+ if (ris == ASN1_SUCCESS)
+ ris =
+ _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
+ if (ris != ASN1_SUCCESS)
+ {
+ if (p->type & CONST_OPTION)
+ {
+ p->type |= CONST_NOT_USED;
+ move = RIGHT;
+ }
+ else if (p->type & CONST_DEFAULT)
+ {
+ _asn1_set_value (p, NULL, 0);
+ move = RIGHT;
+ }
+ else
+ {
+ if (errorDescription != NULL)
+ _asn1_error_description_tag_error (p, errorDescription);
- if (p == nodeFound)
- state = EXIT;
+ result = ASN1_TAG_ERROR;
+ goto cleanup;
+ }
+ }
+ else
+ counter += len2;
+ }
- counter++;
- move = RIGHT;
- break;
- case ASN1_ETYPE_BOOLEAN:
- if (der[counter++] != 1) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
+ if (ris == ASN1_SUCCESS)
+ {
+ switch (type_field (p->type))
+ {
+ case ASN1_ETYPE_NULL:
+ if (der[counter])
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
- if (state == FOUND) {
- if (der[counter++] == 0)
- _asn1_set_value(p, "F", 1);
- else
- _asn1_set_value(p, "T", 1);
-
- if (p == nodeFound)
- state = EXIT;
-
- } else
- counter++;
-
- move = RIGHT;
- break;
- case ASN1_ETYPE_INTEGER:
- case ASN1_ETYPE_ENUMERATED:
- len2 =
- asn1_get_length_der(der + counter,
- len - counter,
- &len3);
- if (len2 < 0) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
+ if (p == nodeFound)
+ state = EXIT;
+
+ counter++;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_BOOLEAN:
+ if (der[counter++] != 1)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
- if (state == FOUND) {
- if (len3 + len2 > len - counter) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
- _asn1_set_value(p, der + counter,
- len3 + len2);
+ if (state == FOUND)
+ {
+ if (der[counter++] == 0)
+ _asn1_set_value (p, "F", 1);
+ else
+ _asn1_set_value (p, "T", 1);
- if (p == nodeFound)
- state = EXIT;
- }
- counter += len3 + len2;
- move = RIGHT;
- break;
- case ASN1_ETYPE_OBJECT_ID:
- if (state == FOUND) {
- result =
- _asn1_get_objectid_der(der +
- counter,
- len -
- counter,
- &len2,
- temp,
- sizeof
- (temp));
- if (result != ASN1_SUCCESS)
- goto cleanup;
-
- tlen = strlen(temp);
-
- if (tlen > 0)
- _asn1_set_value(p, temp,
- tlen + 1);
-
- if (p == nodeFound)
- state = EXIT;
- } else {
- len2 =
- asn1_get_length_der(der +
- counter,
- len -
- counter,
- &len3);
- if (len2 < 0) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
- len2 += len3;
- }
+ if (p == nodeFound)
+ state = EXIT;
- counter += len2;
- move = RIGHT;
- break;
- case ASN1_ETYPE_GENERALIZED_TIME:
- case ASN1_ETYPE_UTC_TIME:
- if (state == FOUND) {
- result =
- _asn1_get_time_der(der +
- counter,
- len -
- counter,
- &len2, temp,
- sizeof(temp)
- - 1);
- if (result != ASN1_SUCCESS)
- goto cleanup;
-
- tlen = strlen(temp);
- if (tlen > 0)
- _asn1_set_value(p, temp,
- tlen + 1);
-
- if (p == nodeFound)
- state = EXIT;
- } else {
- len2 =
- asn1_get_length_der(der +
- counter,
- len -
- counter,
- &len3);
- if (len2 < 0) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
- len2 += len3;
- }
+ }
+ else
+ counter++;
+
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_INTEGER:
+ case ASN1_ETYPE_ENUMERATED:
+ len2 =
+ asn1_get_length_der (der + counter, len - counter, &len3);
+ if (len2 < 0)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
- counter += len2;
- move = RIGHT;
- break;
- case ASN1_ETYPE_OCTET_STRING:
- len3 = len - counter;
- if (state == FOUND) {
- result =
- _asn1_get_octet_string(der +
- counter,
- p,
- &len3);
- if (p == nodeFound)
- state = EXIT;
- } else
- result =
- _asn1_get_octet_string(der +
- counter,
- NULL,
- &len3);
-
- if (result != ASN1_SUCCESS)
- goto cleanup;
-
- counter += len3;
- move = RIGHT;
- break;
- case ASN1_ETYPE_GENERALSTRING:
- case ASN1_ETYPE_NUMERIC_STRING:
- case ASN1_ETYPE_IA5_STRING:
- case ASN1_ETYPE_TELETEX_STRING:
- case ASN1_ETYPE_PRINTABLE_STRING:
- case ASN1_ETYPE_UNIVERSAL_STRING:
- case ASN1_ETYPE_BMP_STRING:
- case ASN1_ETYPE_UTF8_STRING:
- case ASN1_ETYPE_VISIBLE_STRING:
- case ASN1_ETYPE_BIT_STRING:
- len2 =
- asn1_get_length_der(der + counter,
- len - counter,
- &len3);
- if (len2 < 0) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
+ if (state == FOUND)
+ {
+ if (len3 + len2 > len - counter)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ _asn1_set_value (p, der + counter, len3 + len2);
+
+ if (p == nodeFound)
+ state = EXIT;
+ }
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_OBJECT_ID:
+ if (state == FOUND)
+ {
+ result =
+ _asn1_get_objectid_der (der + counter, len - counter,
+ &len2, temp, sizeof (temp));
+ if (result != ASN1_SUCCESS)
+ goto cleanup;
+
+ tlen = strlen (temp);
+
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen + 1);
+
+ if (p == nodeFound)
+ state = EXIT;
+ }
+ else
+ {
+ len2 =
+ asn1_get_length_der (der + counter, len - counter, &len3);
+ if (len2 < 0)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ len2 += len3;
+ }
- if (state == FOUND) {
- if (len3 + len2 > len - counter) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
- _asn1_set_value(p, der + counter,
- len3 + len2);
+ counter += len2;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_GENERALIZED_TIME:
+ case ASN1_ETYPE_UTC_TIME:
+ if (state == FOUND)
+ {
+ result =
+ _asn1_get_time_der (der + counter, len - counter, &len2,
+ temp, sizeof (temp) - 1);
+ if (result != ASN1_SUCCESS)
+ goto cleanup;
+
+ tlen = strlen (temp);
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen + 1);
+
+ if (p == nodeFound)
+ state = EXIT;
+ }
+ else
+ {
+ len2 =
+ asn1_get_length_der (der + counter, len - counter, &len3);
+ if (len2 < 0)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ len2 += len3;
+ }
- if (p == nodeFound)
- state = EXIT;
- }
- counter += len3 + len2;
- move = RIGHT;
- break;
- case ASN1_ETYPE_SEQUENCE:
- case ASN1_ETYPE_SET:
- if (move == UP) {
- len2 =
- _asn1_strtol(p->value, NULL,
- 10);
- _asn1_set_value(p, NULL, 0);
- if (len2 == -1) { /* indefinite length method */
- if ((der[counter])
- || der[counter + 1]) {
- result =
- ASN1_DER_ERROR;
- goto cleanup;
- }
- counter += 2;
- } else { /* definite length method */
- if (len2 != counter) {
- result =
- ASN1_DER_ERROR;
- goto cleanup;
- }
- }
- if (p == nodeFound)
- state = EXIT;
- move = RIGHT;
- } else { /* move==DOWN || move==RIGHT */
- if (state == OTHER_BRANCH) {
- len3 =
- asn1_get_length_der(der
- +
- counter,
- len
- -
- counter,
- &len2);
- if (len3 < 0) {
- result =
- ASN1_DER_ERROR;
- goto cleanup;
- }
- counter += len2 + len3;
- move = RIGHT;
- } else { /* state==SAME_BRANCH or state==FOUND */
- len3 =
- asn1_get_length_der(der
- +
- counter,
- len
- -
- counter,
- &len2);
- if (len3 < 0) {
- result =
- ASN1_DER_ERROR;
- goto cleanup;
- }
- counter += len2;
- if (len3 > 0) {
- _asn1_ltostr
- (counter +
- len3, temp);
- tlen =
- strlen(temp);
-
- if (tlen > 0)
- _asn1_set_value
- (p,
- temp,
- tlen +
- 1);
- move = DOWN;
- } else if (len3 == 0) {
- p2 = p->down;
- while (p2) {
- if (type_field(p2->type) != ASN1_ETYPE_TAG) {
- p3 = p2->right;
- asn1_delete_structure
- (&p2);
- p2 = p3;
- } else
- p2 = p2->right;
- }
- move = RIGHT;
- } else { /* indefinite length method */
- _asn1_set_value(p,
- "-1",
- 3);
- move = DOWN;
- }
- }
- }
- break;
- case ASN1_ETYPE_SEQUENCE_OF:
- case ASN1_ETYPE_SET_OF:
- if (move == UP) {
- len2 =
- _asn1_strtol(p->value, NULL,
- 10);
- if (len2 > counter) {
- _asn1_append_sequence_set
- (p);
- p = p->down;
- while (p->right)
- p = p->right;
- move = RIGHT;
- continue;
- }
- _asn1_set_value(p, NULL, 0);
- if (len2 != counter) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
+ counter += len2;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_OCTET_STRING:
+ len3 = len - counter;
+ if (state == FOUND)
+ {
+ result = _asn1_get_octet_string (der + counter, p, &len3);
+ if (p == nodeFound)
+ state = EXIT;
+ }
+ else
+ result = _asn1_get_octet_string (der + counter, NULL, &len3);
- if (p == nodeFound)
- state = EXIT;
- } else { /* move==DOWN || move==RIGHT */
- if (state == OTHER_BRANCH) {
- len3 =
- asn1_get_length_der(der
- +
- counter,
- len
- -
- counter,
- &len2);
- if (len3 < 0) {
- result =
- ASN1_DER_ERROR;
- goto cleanup;
- }
- counter += len2 + len3;
- move = RIGHT;
- } else { /* state==FOUND or state==SAME_BRANCH */
- len3 =
- asn1_get_length_der(der
- +
- counter,
- len
- -
- counter,
- &len2);
- if (len3 < 0) {
- result =
- ASN1_DER_ERROR;
- goto cleanup;
- }
- counter += len2;
- if (len3) {
- _asn1_ltostr
- (counter +
- len3, temp);
- tlen =
- strlen(temp);
-
- if (tlen > 0)
- _asn1_set_value
- (p,
- temp,
- tlen +
- 1);
- p2 = p->down;
- while ((type_field
- (p2->
- type) ==
- ASN1_ETYPE_TAG)
- ||
- (type_field
- (p2->
- type) ==
- ASN1_ETYPE_SIZE))
- p2 = p2->
- right;
- if (p2->right ==
- NULL)
- _asn1_append_sequence_set
- (p);
- p = p2;
- state = FOUND;
- }
- }
- }
+ if (result != ASN1_SUCCESS)
+ goto cleanup;
- break;
- case ASN1_ETYPE_ANY:
- if (asn1_get_tag_der
- (der + counter, len - counter, &class,
- &len2, &tag) != ASN1_SUCCESS) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
+ counter += len3;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_GENERALSTRING:
+ case ASN1_ETYPE_NUMERIC_STRING:
+ case ASN1_ETYPE_IA5_STRING:
+ case ASN1_ETYPE_TELETEX_STRING:
+ case ASN1_ETYPE_PRINTABLE_STRING:
+ case ASN1_ETYPE_UNIVERSAL_STRING:
+ case ASN1_ETYPE_BMP_STRING:
+ case ASN1_ETYPE_UTF8_STRING:
+ case ASN1_ETYPE_VISIBLE_STRING:
+ case ASN1_ETYPE_BIT_STRING:
+ len2 =
+ asn1_get_length_der (der + counter, len - counter, &len3);
+ if (len2 < 0)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
- if (counter + len2 > len) {
- result = ASN1_DER_ERROR;
- goto cleanup;
+ if (state == FOUND)
+ {
+ if (len3 + len2 > len - counter)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ _asn1_set_value (p, der + counter, len3 + len2);
+
+ if (p == nodeFound)
+ state = EXIT;
+ }
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_SEQUENCE:
+ case ASN1_ETYPE_SET:
+ if (move == UP)
+ {
+ len2 = _asn1_strtol (p->value, NULL, 10);
+ _asn1_set_value (p, NULL, 0);
+ if (len2 == -1)
+ { /* indefinite length method */
+ if ((der[counter]) || der[counter + 1])
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ counter += 2;
+ }
+ else
+ { /* definite length method */
+ if (len2 != counter)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ }
+ if (p == nodeFound)
+ state = EXIT;
+ move = RIGHT;
+ }
+ else
+ { /* move==DOWN || move==RIGHT */
+ if (state == OTHER_BRANCH)
+ {
+ len3 =
+ asn1_get_length_der (der + counter, len - counter,
+ &len2);
+ if (len3 < 0)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ counter += len2 + len3;
+ move = RIGHT;
+ }
+ else
+ { /* state==SAME_BRANCH or state==FOUND */
+ len3 =
+ asn1_get_length_der (der + counter, len - counter,
+ &len2);
+ if (len3 < 0)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ counter += len2;
+ if (len3 > 0)
+ {
+ _asn1_ltostr (counter + len3, temp);
+ tlen = strlen (temp);
+
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen + 1);
+ move = DOWN;
+ }
+ else if (len3 == 0)
+ {
+ p2 = p->down;
+ while (p2)
+ {
+ if (type_field (p2->type) != ASN1_ETYPE_TAG)
+ {
+ p3 = p2->right;
+ asn1_delete_structure (&p2);
+ p2 = p3;
}
+ else
+ p2 = p2->right;
+ }
+ move = RIGHT;
+ }
+ else
+ { /* indefinite length method */
+ _asn1_set_value (p, "-1", 3);
+ move = DOWN;
+ }
+ }
+ }
+ break;
+ case ASN1_ETYPE_SEQUENCE_OF:
+ case ASN1_ETYPE_SET_OF:
+ if (move == UP)
+ {
+ len2 = _asn1_strtol (p->value, NULL, 10);
+ if (len2 > counter)
+ {
+ _asn1_append_sequence_set (p);
+ p = p->down;
+ while (p->right)
+ p = p->right;
+ move = RIGHT;
+ continue;
+ }
+ _asn1_set_value (p, NULL, 0);
+ if (len2 != counter)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+
+ if (p == nodeFound)
+ state = EXIT;
+ }
+ else
+ { /* move==DOWN || move==RIGHT */
+ if (state == OTHER_BRANCH)
+ {
+ len3 =
+ asn1_get_length_der (der + counter, len - counter,
+ &len2);
+ if (len3 < 0)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ counter += len2 + len3;
+ move = RIGHT;
+ }
+ else
+ { /* state==FOUND or state==SAME_BRANCH */
+ len3 =
+ asn1_get_length_der (der + counter, len - counter,
+ &len2);
+ if (len3 < 0)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+ counter += len2;
+ if (len3)
+ {
+ _asn1_ltostr (counter + len3, temp);
+ tlen = strlen (temp);
+
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen + 1);
+ p2 = p->down;
+ while ((type_field (p2->type) == ASN1_ETYPE_TAG)
+ || (type_field (p2->type) ==
+ ASN1_ETYPE_SIZE))
+ p2 = p2->right;
+ if (p2->right == NULL)
+ _asn1_append_sequence_set (p);
+ p = p2;
+ state = FOUND;
+ }
+ }
+ }
- len4 =
- asn1_get_length_der(der + counter +
- len2,
- len - counter -
- len2, &len3);
- if (len4 < -1) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
+ break;
+ case ASN1_ETYPE_ANY:
+ if (asn1_get_tag_der
+ (der + counter, len - counter, &class, &len2,
+ &tag) != ASN1_SUCCESS)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
- if (len4 != -1) {
- len2 += len4;
- if (state == FOUND) {
- _asn1_set_value_lv(p,
- der +
- counter,
- len2 +
- len3);
-
- if (p == nodeFound)
- state = EXIT;
- }
- counter += len2 + len3;
- } else { /* indefinite length */
- /* Check indefinite lenth method in an EXPLICIT TAG */
- if ((p->type & CONST_TAG)
- && (der[counter - 1] == 0x80))
- indefinite = 1;
- else
- indefinite = 0;
-
- len2 = len - counter;
- result =
- _asn1_get_indefinite_length_string
- (der + counter, &len2);
- if (result != ASN1_SUCCESS)
- goto cleanup;
-
- if (state == FOUND) {
- _asn1_set_value_lv(p,
- der +
- counter,
- len2);
-
- if (p == nodeFound)
- state = EXIT;
- }
+ if (counter + len2 > len)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
- counter += len2;
-
- /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
- an indefinite length method. */
- if (indefinite) {
- if (!der[counter]
- && !der[counter + 1]) {
- counter += 2;
- } else {
- result =
- ASN1_DER_ERROR;
- goto cleanup;
- }
- }
- }
- move = RIGHT;
- break;
+ len4 =
+ asn1_get_length_der (der + counter + len2,
+ len - counter - len2, &len3);
+ if (len4 < -1)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
- default:
- move = (move == UP) ? RIGHT : DOWN;
- break;
+ if (len4 != -1)
+ {
+ len2 += len4;
+ if (state == FOUND)
+ {
+ _asn1_set_value_lv (p, der + counter, len2 + len3);
+
+ if (p == nodeFound)
+ state = EXIT;
+ }
+ counter += len2 + len3;
+ }
+ else
+ { /* indefinite length */
+ /* Check indefinite lenth method in an EXPLICIT TAG */
+ if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
+ indefinite = 1;
+ else
+ indefinite = 0;
+
+ len2 = len - counter;
+ result =
+ _asn1_get_indefinite_length_string (der + counter, &len2);
+ if (result != ASN1_SUCCESS)
+ goto cleanup;
+
+ if (state == FOUND)
+ {
+ _asn1_set_value_lv (p, der + counter, len2);
+
+ if (p == nodeFound)
+ state = EXIT;
+ }
+
+ counter += len2;
+
+ /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
+ an indefinite length method. */
+ if (indefinite)
+ {
+ if (!der[counter] && !der[counter + 1])
+ {
+ counter += 2;
+ }
+ else
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
+ }
}
+ move = RIGHT;
+ break;
- if ((p == node && move != DOWN) || (state == EXIT))
- break;
+ default:
+ move = (move == UP) ? RIGHT : DOWN;
+ break;
+ }
+ }
- if (move == DOWN) {
- if (p->down) {
- p = p->down;
-
- if (state != FOUND) {
- nameLen -= strlen(p->name) + 1;
- if (nameLen > 0) {
- if (currentName[0])
- strcat(currentName,
- ".");
- strcat(currentName,
- p->name);
- } else {
- result = ASN1_MEM_ERROR;
- goto cleanup;
- }
- if (!
- (strcmp
- (currentName, elementName))) {
- state = FOUND;
- nodeFound = p;
- } else
- if (!memcmp
- (currentName, elementName,
- strlen(currentName)))
- state = SAME_BRANCH;
- else
- state = OTHER_BRANCH;
- }
- } else
- move = RIGHT;
+ if ((p == node && move != DOWN) || (state == EXIT))
+ break;
+
+ if (move == DOWN)
+ {
+ if (p->down)
+ {
+ p = p->down;
+
+ if (state != FOUND)
+ {
+ nameLen -= strlen (p->name) + 1;
+ if (nameLen > 0)
+ {
+ if (currentName[0])
+ strcat (currentName, ".");
+ strcat (currentName, p->name);
+ }
+ else
+ {
+ result = ASN1_MEM_ERROR;
+ goto cleanup;
+ }
+ if (!(strcmp (currentName, elementName)))
+ {
+ state = FOUND;
+ nodeFound = p;
+ }
+ else
+ if (!memcmp
+ (currentName, elementName, strlen (currentName)))
+ state = SAME_BRANCH;
+ else
+ state = OTHER_BRANCH;
}
+ }
+ else
+ move = RIGHT;
+ }
- if ((move == RIGHT) && !(p->type & CONST_SET)) {
- if (p->right) {
- p = p->right;
-
- if (state != FOUND) {
- dot_p = char_p = currentName;
- while ((char_p =
- strchr(char_p, '.'))) {
- dot_p = char_p++;
- dot_p++;
- }
-
- nameLen +=
- strlen(currentName) - (dot_p -
- currentName);
- *dot_p = 0;
-
- nameLen -= strlen(p->name);
- if (nameLen > 0)
- strcat(currentName,
- p->name);
- else {
- result = ASN1_MEM_ERROR;
- goto cleanup;
- }
-
- if (!
- (strcmp
- (currentName, elementName))) {
- state = FOUND;
- nodeFound = p;
- } else
- if (!memcmp
- (currentName, elementName,
- strlen(currentName)))
- state = SAME_BRANCH;
- else
- state = OTHER_BRANCH;
- }
- } else
- move = UP;
+ if ((move == RIGHT) && !(p->type & CONST_SET))
+ {
+ if (p->right)
+ {
+ p = p->right;
+
+ if (state != FOUND)
+ {
+ dot_p = char_p = currentName;
+ while ((char_p = strchr (char_p, '.')))
+ {
+ dot_p = char_p++;
+ dot_p++;
+ }
+
+ nameLen += strlen (currentName) - (dot_p - currentName);
+ *dot_p = 0;
+
+ nameLen -= strlen (p->name);
+ if (nameLen > 0)
+ strcat (currentName, p->name);
+ else
+ {
+ result = ASN1_MEM_ERROR;
+ goto cleanup;
+ }
+
+ if (!(strcmp (currentName, elementName)))
+ {
+ state = FOUND;
+ nodeFound = p;
+ }
+ else
+ if (!memcmp
+ (currentName, elementName, strlen (currentName)))
+ state = SAME_BRANCH;
+ else
+ state = OTHER_BRANCH;
}
+ }
+ else
+ move = UP;
+ }
- if (move == UP) {
- p = _asn1_find_up(p);
+ if (move == UP)
+ {
+ p = _asn1_find_up (p);
+
+ if (state != FOUND)
+ {
+ dot_p = char_p = currentName;
+ while ((char_p = strchr (char_p, '.')))
+ {
+ dot_p = char_p++;
+ dot_p++;
+ }
- if (state != FOUND) {
- dot_p = char_p = currentName;
- while ((char_p = strchr(char_p, '.'))) {
- dot_p = char_p++;
- dot_p++;
- }
+ nameLen += strlen (currentName) - (dot_p - currentName);
+ *dot_p = 0;
- nameLen +=
- strlen(currentName) - (dot_p -
- currentName);
- *dot_p = 0;
-
- if (!(strcmp(currentName, elementName))) {
- state = FOUND;
- nodeFound = p;
- } else
- if (!memcmp
- (currentName, elementName,
- strlen(currentName)))
- state = SAME_BRANCH;
- else
- state = OTHER_BRANCH;
- }
+ if (!(strcmp (currentName, elementName)))
+ {
+ state = FOUND;
+ nodeFound = p;
}
+ else
+ if (!memcmp (currentName, elementName, strlen (currentName)))
+ state = SAME_BRANCH;
+ else
+ state = OTHER_BRANCH;
+ }
}
+ }
- _asn1_delete_not_used(*structure);
+ _asn1_delete_not_used (*structure);
- if (counter > len) {
- result = ASN1_DER_ERROR;
- goto cleanup;
- }
+ if (counter > len)
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
- cleanup:
- asn1_delete_structure(structure);
- return result;
+cleanup:
+ asn1_delete_structure (structure);
+ return result;
}
/**
@@ -2179,319 +2186,308 @@ asn1_der_decoding_element(asn1_node * structure, const char *elementName,
* doesn't match the structure ELEMENT.
**/
int
-asn1_der_decoding_startEnd(asn1_node element, const void *ider, int len,
- const char *name_element, int *start, int *end)
+asn1_der_decoding_startEnd (asn1_node element, const void *ider, int len,
+ const char *name_element, int *start, int *end)
{
- asn1_node node, node_to_find, p, p2, p3;
- int counter, len2, len3, len4, move, ris;
- unsigned char class;
- unsigned long tag;
- int indefinite;
- const unsigned char *der = ider;
-
- node = element;
-
- if (node == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
-
- node_to_find = asn1_find_node(node, name_element);
-
- if (node_to_find == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
-
- if (node_to_find == node) {
- *start = 0;
- *end = len - 1;
- return ASN1_SUCCESS;
- }
-
- if (node->type & CONST_OPTION)
- return ASN1_GENERIC_ERROR;
+ asn1_node node, node_to_find, p, p2;
+ int counter, len2, len3, len4, move, ris;
+ unsigned char class;
+ unsigned long tag;
+ int indefinite;
+ const unsigned char *der = ider;
+
+ node = element;
+
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ node_to_find = asn1_find_node (node, name_element);
+
+ if (node_to_find == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ if (node_to_find == node)
+ {
+ *start = 0;
+ *end = len - 1;
+ return ASN1_SUCCESS;
+ }
+
+ if (node->type & CONST_OPTION)
+ return ASN1_GENERIC_ERROR;
+
+ counter = 0;
+ move = DOWN;
+ p = node;
+ while (1)
+ {
+ if (p == NULL)
+ return ASN1_DER_ERROR;
+
+ ris = ASN1_SUCCESS;
+
+ if (move != UP)
+ {
+ if (p->type & CONST_SET)
+ {
+ p2 = _asn1_find_up (p);
+ if (p2 == NULL)
+ return ASN1_DER_ERROR;
- counter = 0;
- move = DOWN;
- p = node;
- while (1) {
- if (p == NULL)
- return ASN1_DER_ERROR;
+ len2 = _asn1_strtol (p2->value, NULL, 10);
+ if (len2 == -1)
+ {
+ if (!der[counter] && !der[counter + 1])
+ {
+ p = p2;
+ move = UP;
+ counter += 2;
+ continue;
+ }
+ }
+ else if (counter == len2)
+ {
+ p = p2;
+ move = UP;
+ continue;
+ }
+ else if (counter > len2)
+ return ASN1_DER_ERROR;
- ris = ASN1_SUCCESS;
-
- if (move != UP) {
- if (p->type & CONST_SET) {
- p2 = _asn1_find_up(p);
- if (p2 == NULL)
- return ASN1_DER_ERROR;
-
- len2 = _asn1_strtol(p2->value, NULL, 10);
- if (len2 == -1) {
- if (!der[counter]
- && !der[counter + 1]) {
- p = p2;
- move = UP;
- counter += 2;
- continue;
- }
- } else if (counter == len2) {
- p = p2;
- move = UP;
- continue;
- } else if (counter > len2)
- return ASN1_DER_ERROR;
-
- p2 = p2->down;
-
- while (p2) {
- if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED)) { /* CONTROLLARE */
- if (type_field(p2->type) !=
- ASN1_ETYPE_CHOICE)
- ris =
- _asn1_extract_tag_der
- (p2,
- der + counter,
- len - counter,
- &len2);
- else {
- p3 = p2->down;
- if (p3 == NULL)
- return
- ASN1_DER_ERROR;
-
- ris =
- _asn1_extract_tag_der
- (p3,
- der + counter,
- len - counter,
- &len2);
- }
- if (ris == ASN1_SUCCESS) {
- p2->type &=
- ~CONST_NOT_USED;
- p = p2;
- break;
- }
- }
- p2 = p2->right;
- }
- if (p2 == NULL)
- return ASN1_DER_ERROR;
+ p2 = p2->down;
+
+ while (p2)
+ {
+ if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
+ { /* CONTROLLARE */
+ ris =
+ extract_tag_der_recursive (p2, der + counter,
+ len - counter, &len2);
+ if (ris == ASN1_SUCCESS)
+ {
+ p2->type &= ~CONST_NOT_USED;
+ p = p2;
+ break;
}
+ }
+ p2 = p2->right;
+ }
+ if (p2 == NULL)
+ return ASN1_DER_ERROR;
+ }
- if (p == node_to_find)
- *start = counter;
-
- if (type_field(p->type) == ASN1_ETYPE_CHOICE) {
- p = p->down;
- if (p == NULL)
- return ASN1_DER_ERROR;
+ if (p == node_to_find)
+ *start = counter;
- ris =
- _asn1_extract_tag_der(p, der + counter,
- len - counter,
- &len2);
- if (p == node_to_find)
- *start = counter;
- }
+ if (type_field (p->type) == ASN1_ETYPE_CHOICE)
+ {
+ p = p->down;
+ if (p == NULL)
+ return ASN1_DER_ERROR;
- if (ris == ASN1_SUCCESS)
- ris =
- _asn1_extract_tag_der(p, der + counter,
- len - counter,
- &len2);
- if (ris != ASN1_SUCCESS) {
- if (p->type & CONST_OPTION) {
- p->type |= CONST_NOT_USED;
- move = RIGHT;
- } else if (p->type & CONST_DEFAULT) {
- move = RIGHT;
- } else {
- return ASN1_TAG_ERROR;
- }
- } else
- counter += len2;
- }
-
- if (ris == ASN1_SUCCESS) {
- switch (type_field(p->type)) {
- case ASN1_ETYPE_NULL:
- if (der[counter])
- return ASN1_DER_ERROR;
- counter++;
- move = RIGHT;
- break;
- case ASN1_ETYPE_BOOLEAN:
- if (der[counter++] != 1)
- return ASN1_DER_ERROR;
- counter++;
- move = RIGHT;
- break;
- case ASN1_ETYPE_OCTET_STRING:
- len3 = len - counter;
- ris =
- _asn1_get_octet_string(der + counter,
- NULL, &len3);
- if (ris != ASN1_SUCCESS)
- return ris;
- counter += len3;
- move = RIGHT;
- break;
- case ASN1_ETYPE_UTC_TIME:
- case ASN1_ETYPE_GENERALIZED_TIME:
- case ASN1_ETYPE_OBJECT_ID:
- case ASN1_ETYPE_INTEGER:
- case ASN1_ETYPE_ENUMERATED:
- case ASN1_ETYPE_GENERALSTRING:
- case ASN1_ETYPE_NUMERIC_STRING:
- case ASN1_ETYPE_IA5_STRING:
- case ASN1_ETYPE_TELETEX_STRING:
- case ASN1_ETYPE_PRINTABLE_STRING:
- case ASN1_ETYPE_UNIVERSAL_STRING:
- case ASN1_ETYPE_BMP_STRING:
- case ASN1_ETYPE_UTF8_STRING:
- case ASN1_ETYPE_VISIBLE_STRING:
- case ASN1_ETYPE_BIT_STRING:
- len2 =
- asn1_get_length_der(der + counter,
- len - counter,
- &len3);
- if (len2 < 0)
- return ASN1_DER_ERROR;
- counter += len3 + len2;
- move = RIGHT;
- break;
- case ASN1_ETYPE_SEQUENCE:
- case ASN1_ETYPE_SET:
- if (move != UP) {
- len3 =
- asn1_get_length_der(der +
- counter,
- len -
- counter,
- &len2);
- if (len3 < -1)
- return ASN1_DER_ERROR;
- counter += len2;
- if (len3 == 0)
- move = RIGHT;
- else
- move = DOWN;
- } else {
- if (!der[counter] && !der[counter + 1]) /* indefinite length method */
- counter += 2;
- move = RIGHT;
- }
- break;
- case ASN1_ETYPE_SEQUENCE_OF:
- case ASN1_ETYPE_SET_OF:
- if (move != UP) {
- len3 =
- asn1_get_length_der(der +
- counter,
- len -
- counter,
- &len2);
- if (len3 < -1)
- return ASN1_DER_ERROR;
- counter += len2;
- if ((len3 == -1) && !der[counter]
- && !der[counter + 1])
- counter += 2;
- else if (len3) {
- p2 = p->down;
- while ((type_field
- (p2->type) ==
- ASN1_ETYPE_TAG)
- ||
- (type_field
- (p2->type) ==
- ASN1_ETYPE_SIZE))
- p2 = p2->right;
- p = p2;
- }
- } else {
- if (!der[counter] && !der[counter + 1]) /* indefinite length method */
- counter += 2;
- }
- move = RIGHT;
- break;
- case ASN1_ETYPE_ANY:
- if (asn1_get_tag_der
- (der + counter, len - counter, &class,
- &len2, &tag) != ASN1_SUCCESS)
- return ASN1_DER_ERROR;
- if (counter + len2 > len)
- return ASN1_DER_ERROR;
-
- len4 =
- asn1_get_length_der(der + counter +
- len2,
- len - counter -
- len2, &len3);
- if (len4 < -1)
- return ASN1_DER_ERROR;
-
- if (len4 != -1) {
- counter += len2 + len4 + len3;
- } else { /* indefinite length */
- /* Check indefinite lenth method in an EXPLICIT TAG */
- if ((p->type & CONST_TAG)
- && (der[counter - 1] == 0x80))
- indefinite = 1;
- else
- indefinite = 0;
-
- len2 = len - counter;
- ris =
- _asn1_get_indefinite_length_string
- (der + counter, &len2);
- if (ris != ASN1_SUCCESS)
- return ris;
- counter += len2;
-
- /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
- an indefinite length method. */
- if (indefinite) {
- if (!der[counter]
- && !der[counter + 1])
- counter += 2;
- else
- return
- ASN1_DER_ERROR;
- }
- }
- move = RIGHT;
- break;
- default:
- move = (move == UP) ? RIGHT : DOWN;
- break;
- }
+ ris =
+ _asn1_extract_tag_der (p, der + counter, len - counter,
+ &len2);
+ if (p == node_to_find)
+ *start = counter;
+ }
+
+ if (ris == ASN1_SUCCESS)
+ ris =
+ _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
+ if (ris != ASN1_SUCCESS)
+ {
+ if (p->type & CONST_OPTION)
+ {
+ p->type |= CONST_NOT_USED;
+ move = RIGHT;
}
+ else if (p->type & CONST_DEFAULT)
+ {
+ move = RIGHT;
+ }
+ else
+ {
+ return ASN1_TAG_ERROR;
+ }
+ }
+ else
+ counter += len2;
+ }
- if ((p == node_to_find) && (move == RIGHT)) {
- *end = counter - 1;
- return ASN1_SUCCESS;
+ if (ris == ASN1_SUCCESS)
+ {
+ switch (type_field (p->type))
+ {
+ case ASN1_ETYPE_NULL:
+ if (der[counter])
+ return ASN1_DER_ERROR;
+ counter++;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_BOOLEAN:
+ if (der[counter++] != 1)
+ return ASN1_DER_ERROR;
+ counter++;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_OCTET_STRING:
+ len3 = len - counter;
+ ris = _asn1_get_octet_string (der + counter, NULL, &len3);
+ if (ris != ASN1_SUCCESS)
+ return ris;
+ counter += len3;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_UTC_TIME:
+ case ASN1_ETYPE_GENERALIZED_TIME:
+ case ASN1_ETYPE_OBJECT_ID:
+ case ASN1_ETYPE_INTEGER:
+ case ASN1_ETYPE_ENUMERATED:
+ case ASN1_ETYPE_GENERALSTRING:
+ case ASN1_ETYPE_NUMERIC_STRING:
+ case ASN1_ETYPE_IA5_STRING:
+ case ASN1_ETYPE_TELETEX_STRING:
+ case ASN1_ETYPE_PRINTABLE_STRING:
+ case ASN1_ETYPE_UNIVERSAL_STRING:
+ case ASN1_ETYPE_BMP_STRING:
+ case ASN1_ETYPE_UTF8_STRING:
+ case ASN1_ETYPE_VISIBLE_STRING:
+ case ASN1_ETYPE_BIT_STRING:
+ len2 =
+ asn1_get_length_der (der + counter, len - counter, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_SEQUENCE:
+ case ASN1_ETYPE_SET:
+ if (move != UP)
+ {
+ len3 =
+ asn1_get_length_der (der + counter, len - counter, &len2);
+ if (len3 < -1)
+ return ASN1_DER_ERROR;
+ counter += len2;
+ if (len3 == 0)
+ move = RIGHT;
+ else
+ move = DOWN;
}
+ else
+ {
+ if (!der[counter] && !der[counter + 1]) /* indefinite length method */
+ counter += 2;
+ move = RIGHT;
+ }
+ break;
+ case ASN1_ETYPE_SEQUENCE_OF:
+ case ASN1_ETYPE_SET_OF:
+ if (move != UP)
+ {
+ len3 =
+ asn1_get_length_der (der + counter, len - counter, &len2);
+ if (len3 < -1)
+ return ASN1_DER_ERROR;
+ counter += len2;
+ if ((len3 == -1) && !der[counter] && !der[counter + 1])
+ counter += 2;
+ else if (len3)
+ {
+ p2 = p->down;
+ while ((type_field (p2->type) == ASN1_ETYPE_TAG) ||
+ (type_field (p2->type) == ASN1_ETYPE_SIZE))
+ p2 = p2->right;
+ p = p2;
+ }
+ }
+ else
+ {
+ if (!der[counter] && !der[counter + 1]) /* indefinite length method */
+ counter += 2;
+ }
+ move = RIGHT;
+ break;
+ case ASN1_ETYPE_ANY:
+ if (asn1_get_tag_der
+ (der + counter, len - counter, &class, &len2,
+ &tag) != ASN1_SUCCESS)
+ return ASN1_DER_ERROR;
+ if (counter + len2 > len)
+ return ASN1_DER_ERROR;
- if (p == node && move != DOWN)
- break;
+ len4 =
+ asn1_get_length_der (der + counter + len2,
+ len - counter - len2, &len3);
+ if (len4 < -1)
+ return ASN1_DER_ERROR;
- if (move == DOWN) {
- if (p->down)
- p = p->down;
- else
- move = RIGHT;
+ if (len4 != -1)
+ {
+ counter += len2 + len4 + len3;
}
- if ((move == RIGHT) && !(p->type & CONST_SET)) {
- if (p->right)
- p = p->right;
- else
- move = UP;
+ else
+ { /* indefinite length */
+ /* Check indefinite lenth method in an EXPLICIT TAG */
+ if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
+ indefinite = 1;
+ else
+ indefinite = 0;
+
+ len2 = len - counter;
+ ris =
+ _asn1_get_indefinite_length_string (der + counter, &len2);
+ if (ris != ASN1_SUCCESS)
+ return ris;
+ counter += len2;
+
+ /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
+ an indefinite length method. */
+ if (indefinite)
+ {
+ if (!der[counter] && !der[counter + 1])
+ counter += 2;
+ else
+ return ASN1_DER_ERROR;
+ }
}
- if (move == UP)
- p = _asn1_find_up(p);
+ move = RIGHT;
+ break;
+ default:
+ move = (move == UP) ? RIGHT : DOWN;
+ break;
+ }
+ }
+
+ if ((p == node_to_find) && (move == RIGHT))
+ {
+ *end = counter - 1;
+ return ASN1_SUCCESS;
+ }
+
+ if (p == node && move != DOWN)
+ break;
+
+ if (move == DOWN)
+ {
+ if (p->down)
+ p = p->down;
+ else
+ move = RIGHT;
+ }
+ if ((move == RIGHT) && !(p->type & CONST_SET))
+ {
+ if (p->right)
+ p = p->right;
+ else
+ move = UP;
}
+ if (move == UP)
+ p = _asn1_find_up (p);
+ }
- return ASN1_ELEMENT_NOT_FOUND;
+ return ASN1_ELEMENT_NOT_FOUND;
}
/**
@@ -2510,236 +2506,214 @@ asn1_der_decoding_startEnd(asn1_node element, const void *ider, int len,
* problem in OBJECT_ID -> TYPE association, or other error codes
* depending on DER decoding.
**/
-int asn1_expand_any_defined_by(asn1_node definitions, asn1_node * element)
+int
+asn1_expand_any_defined_by (asn1_node definitions, asn1_node * element)
{
- char definitionsName[ASN1_MAX_NAME_SIZE],
- name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE];
- int retCode = ASN1_SUCCESS, result;
- int len, len2, len3;
- asn1_node p, p2, p3, aux = NULL;
- char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
-
- if ((definitions == NULL) || (*element == NULL))
- return ASN1_ELEMENT_NOT_FOUND;
-
- strcpy(definitionsName, definitions->name);
- strcat(definitionsName, ".");
-
- p = *element;
- while (p) {
-
- switch (type_field(p->type)) {
- case ASN1_ETYPE_ANY:
- if ((p->type & CONST_DEFINED_BY) && (p->value)) {
- /* search the "DEF_BY" element */
- p2 = p->down;
- while ((p2)
- && (type_field(p2->type) !=
- ASN1_ETYPE_CONSTANT))
- p2 = p2->right;
-
- if (!p2) {
- retCode = ASN1_ERROR_TYPE_ANY;
- break;
- }
+ char name[2 * ASN1_MAX_NAME_SIZE + 1],
+ value[ASN1_MAX_NAME_SIZE];
+ int retCode = ASN1_SUCCESS, result;
+ int len, len2, len3;
+ asn1_node p, p2, p3, aux = NULL;
+ char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
+ const char *definitionsName;
+
+ if ((definitions == NULL) || (*element == NULL))
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ definitionsName = definitions->name;
+
+ p = *element;
+ while (p)
+ {
+
+ switch (type_field (p->type))
+ {
+ case ASN1_ETYPE_ANY:
+ if ((p->type & CONST_DEFINED_BY) && (p->value))
+ {
+ /* search the "DEF_BY" element */
+ p2 = p->down;
+ while ((p2) && (type_field (p2->type) != ASN1_ETYPE_CONSTANT))
+ p2 = p2->right;
- p3 = _asn1_find_up(p);
+ if (!p2)
+ {
+ retCode = ASN1_ERROR_TYPE_ANY;
+ break;
+ }
- if (!p3) {
- retCode = ASN1_ERROR_TYPE_ANY;
- break;
- }
+ p3 = _asn1_find_up (p);
- p3 = p3->down;
- while (p3) {
- if (!(strcmp(p3->name, p2->name)))
- break;
- p3 = p3->right;
- }
+ if (!p3)
+ {
+ retCode = ASN1_ERROR_TYPE_ANY;
+ break;
+ }
- if ((!p3)
- || (type_field(p3->type) !=
- ASN1_ETYPE_OBJECT_ID)
- || (p3->value == NULL)) {
+ p3 = p3->down;
+ while (p3)
+ {
+ if (!(strcmp (p3->name, p2->name)))
+ break;
+ p3 = p3->right;
+ }
- p3 = _asn1_find_up(p);
- p3 = _asn1_find_up(p3);
+ if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) ||
+ (p3->value == NULL))
+ {
- if (!p3) {
- retCode =
- ASN1_ERROR_TYPE_ANY;
- break;
- }
+ p3 = _asn1_find_up (p);
+ p3 = _asn1_find_up (p3);
- p3 = p3->down;
+ if (!p3)
+ {
+ retCode = ASN1_ERROR_TYPE_ANY;
+ break;
+ }
- while (p3) {
- if (!
- (strcmp
- (p3->name, p2->name)))
- break;
- p3 = p3->right;
- }
+ p3 = p3->down;
- if ((!p3)
- || (type_field(p3->type) !=
- ASN1_ETYPE_OBJECT_ID)
- || (p3->value == NULL)) {
- retCode =
- ASN1_ERROR_TYPE_ANY;
- break;
- }
- }
+ while (p3)
+ {
+ if (!(strcmp (p3->name, p2->name)))
+ break;
+ p3 = p3->right;
+ }
+
+ if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID)
+ || (p3->value == NULL))
+ {
+ retCode = ASN1_ERROR_TYPE_ANY;
+ break;
+ }
+ }
- /* search the OBJECT_ID into definitions */
- p2 = definitions->down;
- while (p2) {
- if ((type_field(p2->type) ==
- ASN1_ETYPE_OBJECT_ID)
- && (p2->type & CONST_ASSIGN)) {
- strcpy(name,
- definitionsName);
- strcat(name, p2->name);
-
- len = ASN1_MAX_NAME_SIZE;
- result =
- asn1_read_value
- (definitions, name,
- value, &len);
-
- if ((result ==
- ASN1_SUCCESS)
- &&
- (!_asn1_strcmp
- (p3->value, value))) {
- p2 = p2->right; /* pointer to the structure to
- use for expansion */
- while ((p2)
- && (p2->
- type &
- CONST_ASSIGN))
- p2 = p2->
- right;
-
- if (p2) {
- strcpy
- (name,
- definitionsName);
- strcat
- (name,
- p2->
- name);
-
- result =
- asn1_create_element
- (definitions,
- name,
- &aux);
- if (result
- ==
- ASN1_SUCCESS)
- {
- _asn1_cpy_name
- (aux,
- p);
- len2 = asn1_get_length_der(p->value, p->value_len, &len3);
- if (len2 < 0)
- return
- ASN1_DER_ERROR;
-
- result
- =
- asn1_der_decoding
- (&aux,
- p->
- value
- +
- len3,
- len2,
- errorDescription);
- if (result == ASN1_SUCCESS) {
-
- _asn1_set_right
- (aux,
- p->
- right);
- _asn1_set_right
- (p,
- aux);
-
- result
- =
- asn1_delete_structure
- (&p);
- if (result == ASN1_SUCCESS) {
- p = aux;
- aux = NULL;
- break;
- } else { /* error with asn1_delete_structure */
- asn1_delete_structure
- (&aux);
- retCode
- =
- result;
- break;
- }
- } else { /* error with asn1_der_decoding */
- retCode
- =
- result;
- break;
- }
- } else { /* error with asn1_create_element */
- retCode
- =
- result;
- break;
- }
- } else { /* error with the pointer to the structure to exapand */
- retCode =
- ASN1_ERROR_TYPE_ANY;
- break;
- }
- }
+ /* search the OBJECT_ID into definitions */
+ p2 = definitions->down;
+ while (p2)
+ {
+ if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) &&
+ (p2->type & CONST_ASSIGN))
+ {
+ snprintf(name, sizeof(name), "%s.%s", definitionsName, p2->name);
+
+ len = ASN1_MAX_NAME_SIZE;
+ result =
+ asn1_read_value (definitions, name, value, &len);
+
+ if ((result == ASN1_SUCCESS)
+ && (!_asn1_strcmp (p3->value, value)))
+ {
+ p2 = p2->right; /* pointer to the structure to
+ use for expansion */
+ while ((p2) && (p2->type & CONST_ASSIGN))
+ p2 = p2->right;
+
+ if (p2)
+ {
+ snprintf(name, sizeof(name), "%s.%s", definitionsName, p2->name);
+
+ result =
+ asn1_create_element (definitions, name, &aux);
+ if (result == ASN1_SUCCESS)
+ {
+ _asn1_cpy_name (aux, p);
+ len2 =
+ asn1_get_length_der (p->value,
+ p->value_len, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+
+ result =
+ asn1_der_decoding (&aux, p->value + len3,
+ len2,
+ errorDescription);
+ if (result == ASN1_SUCCESS)
+ {
+
+ _asn1_set_right (aux, p->right);
+ _asn1_set_right (p, aux);
+
+ result = asn1_delete_structure (&p);
+ if (result == ASN1_SUCCESS)
+ {
+ p = aux;
+ aux = NULL;
+ break;
}
- p2 = p2->right;
- } /* end while */
-
- if (!p2) {
- retCode = ASN1_ERROR_TYPE_ANY;
- break;
+ else
+ { /* error with asn1_delete_structure */
+ asn1_delete_structure (&aux);
+ retCode = result;
+ break;
+ }
+ }
+ else
+ { /* error with asn1_der_decoding */
+ retCode = result;
+ break;
+ }
}
-
+ else
+ { /* error with asn1_create_element */
+ retCode = result;
+ break;
+ }
+ }
+ else
+ { /* error with the pointer to the structure to exapand */
+ retCode = ASN1_ERROR_TYPE_ANY;
+ break;
+ }
}
- break;
- default:
- break;
+ }
+ p2 = p2->right;
+ } /* end while */
+
+ if (!p2)
+ {
+ retCode = ASN1_ERROR_TYPE_ANY;
+ break;
}
+ }
+ break;
+ default:
+ break;
+ }
- if (p->down) {
- p = p->down;
- } else if (p == *element) {
- p = NULL;
- break;
- } else if (p->right)
- p = p->right;
- else {
- while (1) {
- p = _asn1_find_up(p);
- if (p == *element) {
- p = NULL;
- break;
- }
- if (p->right) {
- p = p->right;
- break;
- }
- }
+
+ if (p->down)
+ {
+ p = p->down;
+ }
+ else if (p == *element)
+ {
+ p = NULL;
+ break;
+ }
+ else if (p->right)
+ p = p->right;
+ else
+ {
+ while (1)
+ {
+ p = _asn1_find_up (p);
+ if (p == *element)
+ {
+ p = NULL;
+ break;
}
+ if (p->right)
+ {
+ p = p->right;
+ break;
+ }
+ }
}
+ }
- return retCode;
+ return retCode;
}
/**
@@ -2761,135 +2735,127 @@ int asn1_expand_any_defined_by(asn1_node definitions, asn1_node * element)
* use for expansion, or other errors depending on DER decoding.
**/
int
-asn1_expand_octet_string(asn1_node definitions, asn1_node * element,
- const char *octetName, const char *objectName)
+asn1_expand_octet_string (asn1_node definitions, asn1_node * element,
+ const char *octetName, const char *objectName)
{
- char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE];
- int retCode = ASN1_SUCCESS, result;
- int len, len2, len3;
- asn1_node p2, aux = NULL;
- asn1_node octetNode = NULL, objectNode = NULL;
- char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
-
- if ((definitions == NULL) || (*element == NULL))
- return ASN1_ELEMENT_NOT_FOUND;
-
- octetNode = asn1_find_node(*element, octetName);
- if (octetNode == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
- if (type_field(octetNode->type) != ASN1_ETYPE_OCTET_STRING)
- return ASN1_ELEMENT_NOT_FOUND;
- if (octetNode->value == NULL)
- return ASN1_VALUE_NOT_FOUND;
-
- objectNode = asn1_find_node(*element, objectName);
- if (objectNode == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
-
- if (type_field(objectNode->type) != ASN1_ETYPE_OBJECT_ID)
- return ASN1_ELEMENT_NOT_FOUND;
-
- if (objectNode->value == NULL)
- return ASN1_VALUE_NOT_FOUND;
-
-
- /* search the OBJECT_ID into definitions */
- p2 = definitions->down;
- while (p2) {
- if ((type_field(p2->type) == ASN1_ETYPE_OBJECT_ID) &&
- (p2->type & CONST_ASSIGN)) {
- strcpy(name, definitions->name);
- strcat(name, ".");
- strcat(name, p2->name);
-
- len = sizeof(value);
- result =
- asn1_read_value(definitions, name, value,
- &len);
-
- if ((result == ASN1_SUCCESS)
- && (!_asn1_strcmp(objectNode->value, value))) {
-
- p2 = p2->right; /* pointer to the structure to
- use for expansion */
- while ((p2) && (p2->type & CONST_ASSIGN))
- p2 = p2->right;
-
- if (p2) {
- strcpy(name, definitions->name);
- strcat(name, ".");
- strcat(name, p2->name);
-
- result =
- asn1_create_element
- (definitions, name, &aux);
- if (result == ASN1_SUCCESS) {
- _asn1_cpy_name(aux,
- octetNode);
- len2 =
- asn1_get_length_der
- (octetNode->value,
- octetNode->value_len,
- &len3);
- if (len2 < 0)
- return
- ASN1_DER_ERROR;
-
- result =
- asn1_der_decoding(&aux,
- octetNode->
- value
- +
- len3,
- len2,
- errorDescription);
- if (result == ASN1_SUCCESS) {
-
- _asn1_set_right
- (aux,
- octetNode->
- right);
- _asn1_set_right
- (octetNode,
- aux);
-
- result =
- asn1_delete_structure
- (&octetNode);
- if (result ==
- ASN1_SUCCESS) {
- aux = NULL;
- break;
- } else { /* error with asn1_delete_structure */
- asn1_delete_structure
- (&aux);
- retCode =
- result;
- break;
- }
- } else { /* error with asn1_der_decoding */
- retCode = result;
- break;
- }
- } else { /* error with asn1_create_element */
- retCode = result;
- break;
- }
- } else { /* error with the pointer to the structure to exapand */
- retCode = ASN1_VALUE_NOT_VALID;
- break;
- }
+ char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE];
+ int retCode = ASN1_SUCCESS, result;
+ int len, len2, len3;
+ asn1_node p2, aux = NULL;
+ asn1_node octetNode = NULL, objectNode = NULL;
+ char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
+
+ if ((definitions == NULL) || (*element == NULL))
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ octetNode = asn1_find_node (*element, octetName);
+ if (octetNode == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+ if (type_field (octetNode->type) != ASN1_ETYPE_OCTET_STRING)
+ return ASN1_ELEMENT_NOT_FOUND;
+ if (octetNode->value == NULL)
+ return ASN1_VALUE_NOT_FOUND;
+
+ objectNode = asn1_find_node (*element, objectName);
+ if (objectNode == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ if (type_field (objectNode->type) != ASN1_ETYPE_OBJECT_ID)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ if (objectNode->value == NULL)
+ return ASN1_VALUE_NOT_FOUND;
+
+
+ /* search the OBJECT_ID into definitions */
+ p2 = definitions->down;
+ while (p2)
+ {
+ if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) &&
+ (p2->type & CONST_ASSIGN))
+ {
+ strcpy (name, definitions->name);
+ strcat (name, ".");
+ strcat (name, p2->name);
+
+ len = sizeof (value);
+ result = asn1_read_value (definitions, name, value, &len);
+
+ if ((result == ASN1_SUCCESS)
+ && (!_asn1_strcmp (objectNode->value, value)))
+ {
+
+ p2 = p2->right; /* pointer to the structure to
+ use for expansion */
+ while ((p2) && (p2->type & CONST_ASSIGN))
+ p2 = p2->right;
+
+ if (p2)
+ {
+ strcpy (name, definitions->name);
+ strcat (name, ".");
+ strcat (name, p2->name);
+
+ result = asn1_create_element (definitions, name, &aux);
+ if (result == ASN1_SUCCESS)
+ {
+ _asn1_cpy_name (aux, octetNode);
+ len2 =
+ asn1_get_length_der (octetNode->value,
+ octetNode->value_len, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+
+ result =
+ asn1_der_decoding (&aux, octetNode->value + len3,
+ len2, errorDescription);
+ if (result == ASN1_SUCCESS)
+ {
+
+ _asn1_set_right (aux, octetNode->right);
+ _asn1_set_right (octetNode, aux);
+
+ result = asn1_delete_structure (&octetNode);
+ if (result == ASN1_SUCCESS)
+ {
+ aux = NULL;
+ break;
+ }
+ else
+ { /* error with asn1_delete_structure */
+ asn1_delete_structure (&aux);
+ retCode = result;
+ break;
+ }
+ }
+ else
+ { /* error with asn1_der_decoding */
+ retCode = result;
+ break;
}
+ }
+ else
+ { /* error with asn1_create_element */
+ retCode = result;
+ break;
+ }
}
+ else
+ { /* error with the pointer to the structure to exapand */
+ retCode = ASN1_VALUE_NOT_VALID;
+ break;
+ }
+ }
+ }
- p2 = p2->right;
+ p2 = p2->right;
- }
+ }
- if (!p2)
- retCode = ASN1_VALUE_NOT_VALID;
+ if (!p2)
+ retCode = ASN1_VALUE_NOT_VALID;
- return retCode;
+ return retCode;
}
/**
@@ -2903,49 +2869,49 @@ asn1_expand_octet_string(asn1_node definitions, asn1_node * element,
* Decodes a simple DER encoded type (e.g. a string, which is not constructed).
* The output is a pointer inside the @der.
*
- * Returns: %ASN1_SUCCESS if successful or an error value.
+ * Returns: %ASN1_SUCCESS if successful or an error value.
**/
int
-asn1_decode_simple_der(unsigned int etype, const unsigned char *der,
- unsigned int der_len, const unsigned char **str,
- unsigned int *str_len)
+asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
+ unsigned int der_len, const unsigned char **str,
+ unsigned int *str_len)
{
- int tag_len, len_len;
- const unsigned char *p;
- unsigned char class;
- unsigned long tag;
- long ret;
+ int tag_len, len_len;
+ const unsigned char *p;
+ unsigned char class;
+ unsigned long tag;
+ long ret;
- if (der == NULL || der_len == 0)
- return ASN1_VALUE_NOT_VALID;
+ if (der == NULL || der_len == 0)
+ return ASN1_VALUE_NOT_VALID;
- if (ETYPE_OK(etype) == 0)
- return ASN1_VALUE_NOT_VALID;
+ if (ETYPE_OK (etype) == 0)
+ return ASN1_VALUE_NOT_VALID;
- /* doesn't handle constructed classes */
- if (ETYPE_CLASS(etype) != ASN1_CLASS_UNIVERSAL)
- return ASN1_VALUE_NOT_VALID;
+ /* doesn't handle constructed classes */
+ if (ETYPE_CLASS (etype) != ASN1_CLASS_UNIVERSAL)
+ return ASN1_VALUE_NOT_VALID;
- p = der;
- ret = asn1_get_tag_der(p, der_len, &class, &tag_len, &tag);
- if (ret != ASN1_SUCCESS)
- return ret;
+ p = der;
+ ret = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag);
+ if (ret != ASN1_SUCCESS)
+ return ret;
- if (class != ETYPE_CLASS(etype) || tag != ETYPE_TAG(etype))
- return ASN1_DER_ERROR;
+ if (class != ETYPE_CLASS (etype) || tag != ETYPE_TAG (etype))
+ return ASN1_DER_ERROR;
- p += tag_len;
- der_len -= tag_len;
+ p += tag_len;
+ der_len -= tag_len;
- ret = asn1_get_length_der(p, der_len, &len_len);
- if (ret < 0)
- return ASN1_DER_ERROR;
+ ret = asn1_get_length_der (p, der_len, &len_len);
+ if (ret < 0)
+ return ASN1_DER_ERROR;
- p += len_len;
- der_len -= len_len;
+ p += len_len;
+ der_len -= len_len;
- *str_len = ret;
- *str = p;
+ *str_len = ret;
+ *str = p;
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
diff --git a/lib/minitasn1/element.c b/lib/minitasn1/element.c
index dd561802ad..1fd988a88d 100644
--- a/lib/minitasn1/element.c
+++ b/lib/minitasn1/element.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2000-2014 Free Software Foundation, Inc.
*
* This file is part of LIBTASN1.
*
@@ -33,27 +33,30 @@
#include "element.h"
-void _asn1_hierarchical_name(asn1_node node, char *name, int name_size)
+void
+_asn1_hierarchical_name (asn1_node node, char *name, int name_size)
{
- asn1_node p;
- char tmp_name[64];
+ asn1_node p;
+ char tmp_name[64];
- p = node;
+ p = node;
- name[0] = 0;
+ name[0] = 0;
- while (p != NULL) {
- if (p->name[0] != 0) {
- _asn1_str_cpy(tmp_name, sizeof(tmp_name), name),
- _asn1_str_cpy(name, name_size, p->name);
- _asn1_str_cat(name, name_size, ".");
- _asn1_str_cat(name, name_size, tmp_name);
- }
- p = _asn1_find_up(p);
+ while (p != NULL)
+ {
+ if (p->name[0] != 0)
+ {
+ _asn1_str_cpy (tmp_name, sizeof (tmp_name), name),
+ _asn1_str_cpy (name, name_size, p->name);
+ _asn1_str_cat (name, name_size, ".");
+ _asn1_str_cat (name, name_size, tmp_name);
}
+ p = _asn1_find_up (p);
+ }
- if (name[0] == 0)
- _asn1_str_cpy(name, name_size, "ROOT");
+ if (name[0] == 0)
+ _asn1_str_cpy (name, name_size, "ROOT");
}
@@ -72,88 +75,89 @@ void _asn1_hierarchical_name(asn1_node node, char *name, int name_size)
/* Return: ASN1_MEM_ERROR or ASN1_SUCCESS */
/******************************************************************/
int
-_asn1_convert_integer(const unsigned char *value, unsigned char *value_out,
- int value_out_size, int *len)
+_asn1_convert_integer (const unsigned char *value, unsigned char *value_out,
+ int value_out_size, int *len)
{
- char negative;
- unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
- long valtmp;
- int k, k2;
+ char negative;
+ unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
+ long valtmp;
+ int k, k2;
- valtmp = _asn1_strtol(value, NULL, 10);
+ valtmp = _asn1_strtol (value, NULL, 10);
- for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++) {
- val[SIZEOF_UNSIGNED_LONG_INT - k - 1] =
- (valtmp >> (8 * k)) & 0xFF;
- }
+ for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
+ {
+ val[SIZEOF_UNSIGNED_LONG_INT - k - 1] = (valtmp >> (8 * k)) & 0xFF;
+ }
- if (val[0] & 0x80)
- negative = 1;
- else
- negative = 0;
+ if (val[0] & 0x80)
+ negative = 1;
+ else
+ negative = 0;
- for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++) {
- if (negative && (val[k] != 0xFF))
- break;
- else if (!negative && val[k])
- break;
- }
+ for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++)
+ {
+ if (negative && (val[k] != 0xFF))
+ break;
+ else if (!negative && val[k])
+ break;
+ }
- if ((negative && !(val[k] & 0x80))
- || (!negative && (val[k] & 0x80)))
- k--;
+ if ((negative && !(val[k] & 0x80)) || (!negative && (val[k] & 0x80)))
+ k--;
- *len = SIZEOF_UNSIGNED_LONG_INT - k;
+ *len = SIZEOF_UNSIGNED_LONG_INT - k;
- if (SIZEOF_UNSIGNED_LONG_INT - k > value_out_size)
- /* VALUE_OUT is too short to contain the value conversion */
- return ASN1_MEM_ERROR;
+ if (SIZEOF_UNSIGNED_LONG_INT - k > value_out_size)
+ /* VALUE_OUT is too short to contain the value conversion */
+ return ASN1_MEM_ERROR;
- for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++)
- value_out[k2 - k] = val[k2];
+ for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++)
+ value_out[k2 - k] = val[k2];
#if 0
- printf("_asn1_convert_integer: valueIn=%s, lenOut=%d", value,
- *len);
- for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
- printf(", vOut[%d]=%d", k, value_out[k]);
- printf("\n");
+ printf ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len);
+ for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
+ printf (", vOut[%d]=%d", k, value_out[k]);
+ printf ("\n");
#endif
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
-int _asn1_append_sequence_set(asn1_node node)
+int
+_asn1_append_sequence_set (asn1_node node)
{
- asn1_node p, p2;
- char temp[10];
- long n;
-
- if (!node || !(node->down))
- return ASN1_GENERIC_ERROR;
-
- p = node->down;
- while ((type_field(p->type) == ASN1_ETYPE_TAG)
- || (type_field(p->type) == ASN1_ETYPE_SIZE))
- p = p->right;
- p2 = _asn1_copy_structure3(p);
- while (p->right)
- p = p->right;
- _asn1_set_right(p, p2);
-
- if (p->name[0] == 0)
- _asn1_str_cpy(temp, sizeof(temp), "?1");
- else {
- n = strtol(p->name + 1, NULL, 0);
- n++;
- temp[0] = '?';
- _asn1_ltostr(n, temp + 1);
- }
- _asn1_set_name(p2, temp);
- /* p2->type |= CONST_OPTION; */
-
- return ASN1_SUCCESS;
+ asn1_node p, p2;
+ char temp[10];
+ long n;
+
+ if (!node || !(node->down))
+ return ASN1_GENERIC_ERROR;
+
+ p = node->down;
+ while ((type_field (p->type) == ASN1_ETYPE_TAG)
+ || (type_field (p->type) == ASN1_ETYPE_SIZE))
+ p = p->right;
+ p2 = _asn1_copy_structure3 (p);
+ while (p->right)
+ p = p->right;
+ _asn1_set_right (p, p2);
+
+ if (p->name[0] == 0)
+ _asn1_str_cpy (temp, sizeof (temp), "?1");
+ else
+ {
+ n = strtol (p->name + 1, NULL, 0);
+ n++;
+ temp[0] = '?';
+ _asn1_ltostr (n, temp + 1);
+ }
+ _asn1_set_name (p2, temp);
+ /* p2->type |= CONST_OPTION; */
+
+ return ASN1_SUCCESS;
}
@@ -264,334 +268,351 @@ int _asn1_append_sequence_set(asn1_node node)
* %ASN1_VALUE_NOT_VALID if @ivalue has a wrong format.
**/
int
-asn1_write_value(asn1_node node_root, const char *name,
- const void *ivalue, int len)
+asn1_write_value (asn1_node node_root, const char *name,
+ const void *ivalue, int len)
{
- asn1_node node, p, p2;
- unsigned char *temp, *value_temp = NULL, *default_temp = NULL;
- int len2, k, k2, negative;
- size_t i;
- const unsigned char *value = ivalue;
- unsigned int type;
-
- node = asn1_find_node(node_root, name);
- if (node == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
-
- if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0)) {
- asn1_delete_structure(&node);
- return ASN1_SUCCESS;
+ asn1_node node, p, p2;
+ unsigned char *temp, *value_temp = NULL, *default_temp = NULL;
+ int len2, k, k2, negative;
+ size_t i;
+ const unsigned char *value = ivalue;
+ unsigned int type;
+
+ node = asn1_find_node (node_root, name);
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0))
+ {
+ asn1_delete_structure (&node);
+ return ASN1_SUCCESS;
+ }
+
+ type = type_field (node->type);
+
+ if ((type == ASN1_ETYPE_SEQUENCE_OF || type == ASN1_ETYPE_SET_OF) && (value == NULL) && (len == 0))
+ {
+ p = node->down;
+ while ((type_field (p->type) == ASN1_ETYPE_TAG)
+ || (type_field (p->type) == ASN1_ETYPE_SIZE))
+ p = p->right;
+
+ while (p->right)
+ asn1_delete_structure (&p->right);
+
+ return ASN1_SUCCESS;
+ }
+
+ /* Don't allow element deletion for other types */
+ if (value == NULL)
+ {
+ return ASN1_VALUE_NOT_VALID;
+ }
+
+ switch (type)
+ {
+ case ASN1_ETYPE_BOOLEAN:
+ if (!_asn1_strcmp (value, "TRUE"))
+ {
+ if (node->type & CONST_DEFAULT)
+ {
+ p = node->down;
+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
+ p = p->right;
+ if (p->type & CONST_TRUE)
+ _asn1_set_value (node, NULL, 0);
+ else
+ _asn1_set_value (node, "T", 1);
+ }
+ else
+ _asn1_set_value (node, "T", 1);
}
-
- type = type_field(node->type);
-
- if ((type == ASN1_ETYPE_SEQUENCE_OF) && (value == NULL)
- && (len == 0)) {
- p = node->down;
- while ((type_field(p->type) == ASN1_ETYPE_TAG)
- || (type_field(p->type) == ASN1_ETYPE_SIZE))
- p = p->right;
-
- while (p->right)
- asn1_delete_structure(&p->right);
-
- return ASN1_SUCCESS;
+ else if (!_asn1_strcmp (value, "FALSE"))
+ {
+ if (node->type & CONST_DEFAULT)
+ {
+ p = node->down;
+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
+ p = p->right;
+ if (p->type & CONST_FALSE)
+ _asn1_set_value (node, NULL, 0);
+ else
+ _asn1_set_value (node, "F", 1);
+ }
+ else
+ _asn1_set_value (node, "F", 1);
}
-
- switch (type) {
- case ASN1_ETYPE_BOOLEAN:
- if (!_asn1_strcmp(value, "TRUE")) {
- if (node->type & CONST_DEFAULT) {
- p = node->down;
- while (type_field(p->type) !=
- ASN1_ETYPE_DEFAULT)
- p = p->right;
- if (p->type & CONST_TRUE)
- _asn1_set_value(node, NULL, 0);
- else
- _asn1_set_value(node, "T", 1);
- } else
- _asn1_set_value(node, "T", 1);
- } else if (!_asn1_strcmp(value, "FALSE")) {
- if (node->type & CONST_DEFAULT) {
- p = node->down;
- while (type_field(p->type) !=
- ASN1_ETYPE_DEFAULT)
- p = p->right;
- if (p->type & CONST_FALSE)
- _asn1_set_value(node, NULL, 0);
- else
- _asn1_set_value(node, "F", 1);
- } else
- _asn1_set_value(node, "F", 1);
- } else
- return ASN1_VALUE_NOT_VALID;
- break;
- case ASN1_ETYPE_INTEGER:
- case ASN1_ETYPE_ENUMERATED:
- if (len == 0) {
- if ((isdigit(value[0])) || (value[0] == '-')) {
- value_temp =
- malloc(SIZEOF_UNSIGNED_LONG_INT);
- if (value_temp == NULL)
- return ASN1_MEM_ALLOC_ERROR;
-
- _asn1_convert_integer(value, value_temp,
- SIZEOF_UNSIGNED_LONG_INT,
- &len);
- } else { /* is an identifier like v1 */
- if (!(node->type & CONST_LIST))
- return ASN1_VALUE_NOT_VALID;
- p = node->down;
- while (p) {
- if (type_field(p->type) ==
- ASN1_ETYPE_CONSTANT) {
- if (!_asn1_strcmp
- (p->name, value)) {
- value_temp =
- malloc
- (SIZEOF_UNSIGNED_LONG_INT);
- if (value_temp ==
- NULL)
- return
- ASN1_MEM_ALLOC_ERROR;
-
- _asn1_convert_integer
- (p->value,
- value_temp,
- SIZEOF_UNSIGNED_LONG_INT,
- &len);
- break;
- }
- }
- p = p->right;
- }
- if (p == NULL)
- return ASN1_VALUE_NOT_VALID;
+ else
+ return ASN1_VALUE_NOT_VALID;
+ break;
+ case ASN1_ETYPE_INTEGER:
+ case ASN1_ETYPE_ENUMERATED:
+ if (len == 0)
+ {
+ if ((isdigit (value[0])) || (value[0] == '-'))
+ {
+ value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
+ if (value_temp == NULL)
+ return ASN1_MEM_ALLOC_ERROR;
+
+ _asn1_convert_integer (value, value_temp,
+ SIZEOF_UNSIGNED_LONG_INT, &len);
+ }
+ else
+ { /* is an identifier like v1 */
+ if (!(node->type & CONST_LIST))
+ return ASN1_VALUE_NOT_VALID;
+ p = node->down;
+ while (p)
+ {
+ if (type_field (p->type) == ASN1_ETYPE_CONSTANT)
+ {
+ if (!_asn1_strcmp (p->name, value))
+ {
+ value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
+ if (value_temp == NULL)
+ return ASN1_MEM_ALLOC_ERROR;
+
+ _asn1_convert_integer (p->value,
+ value_temp,
+ SIZEOF_UNSIGNED_LONG_INT,
+ &len);
+ break;
}
- } else { /* len != 0 */
- value_temp = malloc(len);
- if (value_temp == NULL)
- return ASN1_MEM_ALLOC_ERROR;
- memcpy(value_temp, value, len);
+ }
+ p = p->right;
}
+ if (p == NULL)
+ return ASN1_VALUE_NOT_VALID;
+ }
+ }
+ else
+ { /* len != 0 */
+ value_temp = malloc (len);
+ if (value_temp == NULL)
+ return ASN1_MEM_ALLOC_ERROR;
+ memcpy (value_temp, value, len);
+ }
- if (value_temp[0] & 0x80)
- negative = 1;
- else
- negative = 0;
-
- if (negative
- && (type_field(node->type) == ASN1_ETYPE_ENUMERATED)) {
- free(value_temp);
- return ASN1_VALUE_NOT_VALID;
- }
+ if (value_temp[0] & 0x80)
+ negative = 1;
+ else
+ negative = 0;
- for (k = 0; k < len - 1; k++)
- if (negative && (value_temp[k] != 0xFF))
- break;
- else if (!negative && value_temp[k])
- break;
-
- if ((negative && !(value_temp[k] & 0x80)) ||
- (!negative && (value_temp[k] & 0x80)))
- k--;
-
- _asn1_set_value_lv(node, value_temp + k, len - k);
-
- if (node->type & CONST_DEFAULT) {
- p = node->down;
- while (type_field(p->type) != ASN1_ETYPE_DEFAULT)
- p = p->right;
- if ((isdigit(p->value[0])) || (p->value[0] == '-')) {
- default_temp =
- malloc(SIZEOF_UNSIGNED_LONG_INT);
- if (default_temp == NULL) {
- free(value_temp);
- return ASN1_MEM_ALLOC_ERROR;
- }
-
- _asn1_convert_integer(p->value,
- default_temp,
- SIZEOF_UNSIGNED_LONG_INT,
- &len2);
- } else { /* is an identifier like v1 */
- if (!(node->type & CONST_LIST)) {
- free(value_temp);
- return ASN1_VALUE_NOT_VALID;
- }
- p2 = node->down;
- while (p2) {
- if (type_field(p2->type) ==
- ASN1_ETYPE_CONSTANT) {
- if (!_asn1_strcmp
- (p2->name, p->value)) {
- default_temp =
- malloc
- (SIZEOF_UNSIGNED_LONG_INT);
- if (default_temp ==
- NULL) {
- free(value_temp);
- return
- ASN1_MEM_ALLOC_ERROR;
- }
-
- _asn1_convert_integer
- (p2->value,
- default_temp,
- SIZEOF_UNSIGNED_LONG_INT,
- &len2);
- break;
- }
- }
- p2 = p2->right;
- }
- if (p2 == NULL) {
- free(value_temp);
- return ASN1_VALUE_NOT_VALID;
- }
- }
+ if (negative && (type_field (node->type) == ASN1_ETYPE_ENUMERATED))
+ {
+ free (value_temp);
+ return ASN1_VALUE_NOT_VALID;
+ }
+ for (k = 0; k < len - 1; k++)
+ if (negative && (value_temp[k] != 0xFF))
+ break;
+ else if (!negative && value_temp[k])
+ break;
+
+ if ((negative && !(value_temp[k] & 0x80)) ||
+ (!negative && (value_temp[k] & 0x80)))
+ k--;
+
+ _asn1_set_value_lv (node, value_temp + k, len - k);
+
+ if (node->type & CONST_DEFAULT)
+ {
+ p = node->down;
+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
+ p = p->right;
+ if ((isdigit (p->value[0])) || (p->value[0] == '-'))
+ {
+ default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
+ if (default_temp == NULL)
+ {
+ free (value_temp);
+ return ASN1_MEM_ALLOC_ERROR;
+ }
- if ((len - k) == len2) {
- for (k2 = 0; k2 < len2; k2++)
- if (value_temp[k + k2] !=
- default_temp[k2]) {
- break;
- }
- if (k2 == len2)
- _asn1_set_value(node, NULL, 0);
- }
- free(default_temp);
+ _asn1_convert_integer (p->value, default_temp,
+ SIZEOF_UNSIGNED_LONG_INT, &len2);
+ }
+ else
+ { /* is an identifier like v1 */
+ if (!(node->type & CONST_LIST))
+ {
+ free (value_temp);
+ return ASN1_VALUE_NOT_VALID;
}
- free(value_temp);
- break;
- case ASN1_ETYPE_OBJECT_ID:
- for (i = 0; i < _asn1_strlen(value); i++)
- if ((!isdigit(value[i])) && (value[i] != '.')
- && (value[i] != '+'))
- return ASN1_VALUE_NOT_VALID;
- if (node->type & CONST_DEFAULT) {
- p = node->down;
- while (type_field(p->type) != ASN1_ETYPE_DEFAULT)
- p = p->right;
- if (!_asn1_strcmp(value, p->value)) {
- _asn1_set_value(node, NULL, 0);
- break;
+ p2 = node->down;
+ while (p2)
+ {
+ if (type_field (p2->type) == ASN1_ETYPE_CONSTANT)
+ {
+ if (!_asn1_strcmp (p2->name, p->value))
+ {
+ default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
+ if (default_temp == NULL)
+ {
+ free (value_temp);
+ return ASN1_MEM_ALLOC_ERROR;
+ }
+
+ _asn1_convert_integer (p2->value,
+ default_temp,
+ SIZEOF_UNSIGNED_LONG_INT,
+ &len2);
+ break;
}
+ }
+ p2 = p2->right;
}
- _asn1_set_value(node, value, _asn1_strlen(value) + 1);
- break;
- case ASN1_ETYPE_UTC_TIME:
+ if (p2 == NULL)
{
- len = _asn1_strlen(value);
- if (len < 11)
- return ASN1_VALUE_NOT_VALID;
- for (k = 0; k < 10; k++)
- if (!isdigit(value[k]))
- return ASN1_VALUE_NOT_VALID;
- switch (len) {
- case 11:
- if (value[10] != 'Z')
- return ASN1_VALUE_NOT_VALID;
- break;
- case 13:
- if ((!isdigit(value[10]))
- || (!isdigit(value[11]))
- || (value[12] != 'Z'))
- return ASN1_VALUE_NOT_VALID;
- break;
- case 15:
- if ((value[10] != '+')
- && (value[10] != '-'))
- return ASN1_VALUE_NOT_VALID;
- for (k = 11; k < 15; k++)
- if (!isdigit(value[k]))
- return
- ASN1_VALUE_NOT_VALID;
- break;
- case 17:
- if ((!isdigit(value[10]))
- || (!isdigit(value[11])))
- return ASN1_VALUE_NOT_VALID;
- if ((value[12] != '+')
- && (value[12] != '-'))
- return ASN1_VALUE_NOT_VALID;
- for (k = 13; k < 17; k++)
- if (!isdigit(value[k]))
- return
- ASN1_VALUE_NOT_VALID;
- break;
- default:
- return ASN1_VALUE_NOT_FOUND;
- }
- _asn1_set_value(node, value, len);
+ free (value_temp);
+ return ASN1_VALUE_NOT_VALID;
}
- break;
- case ASN1_ETYPE_GENERALIZED_TIME:
- len = _asn1_strlen(value);
- _asn1_set_value(node, value, len);
- break;
- case ASN1_ETYPE_OCTET_STRING:
- case ASN1_ETYPE_GENERALSTRING:
- case ASN1_ETYPE_NUMERIC_STRING:
- case ASN1_ETYPE_IA5_STRING:
- case ASN1_ETYPE_TELETEX_STRING:
- case ASN1_ETYPE_PRINTABLE_STRING:
- case ASN1_ETYPE_UNIVERSAL_STRING:
- case ASN1_ETYPE_BMP_STRING:
- case ASN1_ETYPE_UTF8_STRING:
- case ASN1_ETYPE_VISIBLE_STRING:
- if (len == 0)
- len = _asn1_strlen(value);
- _asn1_set_value_lv(node, value, len);
- break;
- case ASN1_ETYPE_BIT_STRING:
- if (len == 0)
- len = _asn1_strlen(value);
- asn1_length_der((len >> 3) + 2, NULL, &len2);
- temp = malloc((len >> 3) + 2 + len2);
- if (temp == NULL)
- return ASN1_MEM_ALLOC_ERROR;
-
- asn1_bit_der(value, len, temp, &len2);
- _asn1_set_value_m(node, temp, len2);
- temp = NULL;
- break;
- case ASN1_ETYPE_CHOICE:
- p = node->down;
- while (p) {
- if (!_asn1_strcmp(p->name, value)) {
- p2 = node->down;
- while (p2) {
- if (p2 != p) {
- asn1_delete_structure(&p2);
- p2 = node->down;
- } else
- p2 = p2->right;
- }
- break;
- }
- p = p->right;
+ }
+
+
+ if ((len - k) == len2)
+ {
+ for (k2 = 0; k2 < len2; k2++)
+ if (value_temp[k + k2] != default_temp[k2])
+ {
+ break;
+ }
+ if (k2 == len2)
+ _asn1_set_value (node, NULL, 0);
+ }
+ free (default_temp);
+ }
+ free (value_temp);
+ break;
+ case ASN1_ETYPE_OBJECT_ID:
+ for (i = 0; i < _asn1_strlen (value); i++)
+ if ((!isdigit (value[i])) && (value[i] != '.') && (value[i] != '+'))
+ return ASN1_VALUE_NOT_VALID;
+ if (node->type & CONST_DEFAULT)
+ {
+ p = node->down;
+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
+ p = p->right;
+ if (!_asn1_strcmp (value, p->value))
+ {
+ _asn1_set_value (node, NULL, 0);
+ break;
+ }
+ }
+ _asn1_set_value (node, value, _asn1_strlen (value) + 1);
+ break;
+ case ASN1_ETYPE_UTC_TIME:
+ {
+ len = _asn1_strlen (value);
+ if (len < 11)
+ return ASN1_VALUE_NOT_VALID;
+ for (k = 0; k < 10; k++)
+ if (!isdigit (value[k]))
+ return ASN1_VALUE_NOT_VALID;
+ switch (len)
+ {
+ case 11:
+ if (value[10] != 'Z')
+ return ASN1_VALUE_NOT_VALID;
+ break;
+ case 13:
+ if ((!isdigit (value[10])) || (!isdigit (value[11])) ||
+ (value[12] != 'Z'))
+ return ASN1_VALUE_NOT_VALID;
+ break;
+ case 15:
+ if ((value[10] != '+') && (value[10] != '-'))
+ return ASN1_VALUE_NOT_VALID;
+ for (k = 11; k < 15; k++)
+ if (!isdigit (value[k]))
+ return ASN1_VALUE_NOT_VALID;
+ break;
+ case 17:
+ if ((!isdigit (value[10])) || (!isdigit (value[11])))
+ return ASN1_VALUE_NOT_VALID;
+ if ((value[12] != '+') && (value[12] != '-'))
+ return ASN1_VALUE_NOT_VALID;
+ for (k = 13; k < 17; k++)
+ if (!isdigit (value[k]))
+ return ASN1_VALUE_NOT_VALID;
+ break;
+ default:
+ return ASN1_VALUE_NOT_FOUND;
+ }
+ _asn1_set_value (node, value, len);
+ }
+ break;
+ case ASN1_ETYPE_GENERALIZED_TIME:
+ len = _asn1_strlen (value);
+ _asn1_set_value (node, value, len);
+ break;
+ case ASN1_ETYPE_OCTET_STRING:
+ case ASN1_ETYPE_GENERALSTRING:
+ case ASN1_ETYPE_NUMERIC_STRING:
+ case ASN1_ETYPE_IA5_STRING:
+ case ASN1_ETYPE_TELETEX_STRING:
+ case ASN1_ETYPE_PRINTABLE_STRING:
+ case ASN1_ETYPE_UNIVERSAL_STRING:
+ case ASN1_ETYPE_BMP_STRING:
+ case ASN1_ETYPE_UTF8_STRING:
+ case ASN1_ETYPE_VISIBLE_STRING:
+ if (len == 0)
+ len = _asn1_strlen (value);
+ _asn1_set_value_lv (node, value, len);
+ break;
+ case ASN1_ETYPE_BIT_STRING:
+ if (len == 0)
+ len = _asn1_strlen (value);
+ asn1_length_der ((len >> 3) + 2, NULL, &len2);
+ temp = malloc ((len >> 3) + 2 + len2);
+ if (temp == NULL)
+ return ASN1_MEM_ALLOC_ERROR;
+
+ asn1_bit_der (value, len, temp, &len2);
+ _asn1_set_value_m (node, temp, len2);
+ temp = NULL;
+ break;
+ case ASN1_ETYPE_CHOICE:
+ p = node->down;
+ while (p)
+ {
+ if (!_asn1_strcmp (p->name, value))
+ {
+ p2 = node->down;
+ while (p2)
+ {
+ if (p2 != p)
+ {
+ asn1_delete_structure (&p2);
+ p2 = node->down;
+ }
+ else
+ p2 = p2->right;
}
- if (!p)
- return ASN1_ELEMENT_NOT_FOUND;
- break;
- case ASN1_ETYPE_ANY:
- _asn1_set_value_lv(node, value, len);
- break;
- case ASN1_ETYPE_SEQUENCE_OF:
- case ASN1_ETYPE_SET_OF:
- if (_asn1_strcmp(value, "NEW"))
- return ASN1_VALUE_NOT_VALID;
- _asn1_append_sequence_set(node);
- break;
- default:
- return ASN1_ELEMENT_NOT_FOUND;
- break;
+ break;
+ }
+ p = p->right;
}
-
- return ASN1_SUCCESS;
+ if (!p)
+ return ASN1_ELEMENT_NOT_FOUND;
+ break;
+ case ASN1_ETYPE_ANY:
+ _asn1_set_value_lv (node, value, len);
+ break;
+ case ASN1_ETYPE_SEQUENCE_OF:
+ case ASN1_ETYPE_SET_OF:
+ if (_asn1_strcmp (value, "NEW"))
+ return ASN1_VALUE_NOT_VALID;
+ _asn1_append_sequence_set (node);
+ break;
+ default:
+ return ASN1_ELEMENT_NOT_FOUND;
+ break;
+ }
+
+ return ASN1_SUCCESS;
}
@@ -600,16 +621,18 @@ asn1_write_value(asn1_node node_root, const char *name,
if (ptr_size < data_size) { \
return ASN1_MEM_ERROR; \
} else { \
- memcpy( ptr, data, data_size); \
+ if (ptr) \
+ memcpy (ptr, data, data_size); \
}
#define PUT_STR_VALUE( ptr, ptr_size, data) \
- *len = _asn1_strlen(data) + 1; \
+ *len = _asn1_strlen (data) + 1; \
if (ptr_size < *len) { \
return ASN1_MEM_ERROR; \
} else { \
/* this strcpy is checked */ \
- _asn1_strcpy(ptr, data); \
+ if (ptr) \
+ _asn1_strcpy (ptr, data); \
}
#define PUT_AS_STR_VALUE( ptr, ptr_size, data, data_size) \
@@ -618,17 +641,19 @@ asn1_write_value(asn1_node node_root, const char *name,
return ASN1_MEM_ERROR; \
} else { \
/* this strcpy is checked */ \
- memcpy(ptr, data, data_size); \
- ptr[data_size] = 0; \
+ if (ptr) { \
+ memcpy (ptr, data, data_size); \
+ ptr[data_size] = 0; \
+ } \
}
#define ADD_STR_VALUE( ptr, ptr_size, data) \
- *len = (int) _asn1_strlen(data) + 1; \
- if (ptr_size < (int) _asn1_strlen(ptr)+(*len)) { \
+ *len = (int) _asn1_strlen (data) + 1; \
+ if (ptr_size < (int) _asn1_strlen (ptr) + (*len)) { \
return ASN1_MEM_ERROR; \
} else { \
/* this strcat is checked */ \
- _asn1_strcat(ptr, data); \
+ if (ptr) _asn1_strcat (ptr, data); \
}
/**
@@ -693,9 +718,9 @@ asn1_write_value(asn1_node node_root, const char *name,
* bytes needed.
**/
int
-asn1_read_value(asn1_node root, const char *name, void *ivalue, int *len)
+asn1_read_value (asn1_node root, const char *name, void *ivalue, int *len)
{
- return asn1_read_value_type(root, name, ivalue, len, NULL);
+ return asn1_read_value_type (root, name, ivalue, len, NULL);
}
/**
@@ -761,158 +786,174 @@ asn1_read_value(asn1_node root, const char *name, void *ivalue, int *len)
* bytes needed.
**/
int
-asn1_read_value_type(asn1_node root, const char *name, void *ivalue,
- int *len, unsigned int *etype)
+asn1_read_value_type (asn1_node root, const char *name, void *ivalue,
+ int *len, unsigned int *etype)
{
- asn1_node node, p, p2;
- int len2, len3;
- int value_size = *len;
- unsigned char *value = ivalue;
- unsigned type;
-
- node = asn1_find_node(root, name);
- if (node == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
-
- type = type_field(node->type);
-
- if ((type != ASN1_ETYPE_NULL) &&
- (type != ASN1_ETYPE_CHOICE) &&
- !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN)
- && (node->value == NULL))
- return ASN1_VALUE_NOT_FOUND;
-
- if (etype)
- *etype = type;
- switch (type) {
- case ASN1_ETYPE_NULL:
- PUT_STR_VALUE(value, value_size, "NULL");
- break;
- case ASN1_ETYPE_BOOLEAN:
- if ((node->type & CONST_DEFAULT) && (node->value == NULL)) {
- p = node->down;
- while (type_field(p->type) != ASN1_ETYPE_DEFAULT)
- p = p->right;
- if (p->type & CONST_TRUE) {
- PUT_STR_VALUE(value, value_size, "TRUE");
- } else {
- PUT_STR_VALUE(value, value_size, "FALSE");
- }
- } else if (node->value[0] == 'T') {
- PUT_STR_VALUE(value, value_size, "TRUE");
- } else {
- PUT_STR_VALUE(value, value_size, "FALSE");
- }
- break;
- case ASN1_ETYPE_INTEGER:
- case ASN1_ETYPE_ENUMERATED:
- if ((node->type & CONST_DEFAULT) && (node->value == NULL)) {
- p = node->down;
- while (type_field(p->type) != ASN1_ETYPE_DEFAULT)
- p = p->right;
- if ((isdigit(p->value[0])) || (p->value[0] == '-')
- || (p->value[0] == '+')) {
- if (_asn1_convert_integer
- (p->value, value, value_size,
- len) != ASN1_SUCCESS)
- return ASN1_MEM_ERROR;
- } else { /* is an identifier like v1 */
- p2 = node->down;
- while (p2) {
- if (type_field(p2->type) ==
- ASN1_ETYPE_CONSTANT) {
- if (!_asn1_strcmp
- (p2->name, p->value)) {
- if (_asn1_convert_integer(p2->value, value, value_size, len) != ASN1_SUCCESS)
- return
- ASN1_MEM_ERROR;
- break;
- }
- }
- p2 = p2->right;
- }
+ asn1_node node, p, p2;
+ int len2, len3;
+ int value_size = *len;
+ unsigned char *value = ivalue;
+ unsigned type;
+
+ node = asn1_find_node (root, name);
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ type = type_field (node->type);
+
+ if ((type != ASN1_ETYPE_NULL) &&
+ (type != ASN1_ETYPE_CHOICE) &&
+ !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) &&
+ (node->value == NULL))
+ return ASN1_VALUE_NOT_FOUND;
+
+ if (etype)
+ *etype = type;
+ switch (type)
+ {
+ case ASN1_ETYPE_NULL:
+ PUT_STR_VALUE (value, value_size, "NULL");
+ break;
+ case ASN1_ETYPE_BOOLEAN:
+ if ((node->type & CONST_DEFAULT) && (node->value == NULL))
+ {
+ p = node->down;
+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
+ p = p->right;
+ if (p->type & CONST_TRUE)
+ {
+ PUT_STR_VALUE (value, value_size, "TRUE");
+ }
+ else
+ {
+ PUT_STR_VALUE (value, value_size, "FALSE");
+ }
+ }
+ else if (node->value[0] == 'T')
+ {
+ PUT_STR_VALUE (value, value_size, "TRUE");
+ }
+ else
+ {
+ PUT_STR_VALUE (value, value_size, "FALSE");
+ }
+ break;
+ case ASN1_ETYPE_INTEGER:
+ case ASN1_ETYPE_ENUMERATED:
+ if ((node->type & CONST_DEFAULT) && (node->value == NULL))
+ {
+ p = node->down;
+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
+ p = p->right;
+ if ((isdigit (p->value[0])) || (p->value[0] == '-')
+ || (p->value[0] == '+'))
+ {
+ if (_asn1_convert_integer
+ (p->value, value, value_size, len) != ASN1_SUCCESS)
+ return ASN1_MEM_ERROR;
+ }
+ else
+ { /* is an identifier like v1 */
+ p2 = node->down;
+ while (p2)
+ {
+ if (type_field (p2->type) == ASN1_ETYPE_CONSTANT)
+ {
+ if (!_asn1_strcmp (p2->name, p->value))
+ {
+ if (_asn1_convert_integer
+ (p2->value, value, value_size,
+ len) != ASN1_SUCCESS)
+ return ASN1_MEM_ERROR;
+ break;
}
- } else {
- len2 = -1;
- if (asn1_get_octet_der
- (node->value, node->value_len, &len2, value,
- value_size, len) != ASN1_SUCCESS)
- return ASN1_MEM_ERROR;
+ }
+ p2 = p2->right;
}
- break;
- case ASN1_ETYPE_OBJECT_ID:
- if (node->type & CONST_ASSIGN) {
- value[0] = 0;
- p = node->down;
- while (p) {
- if (type_field(p->type) ==
- ASN1_ETYPE_CONSTANT) {
- ADD_STR_VALUE(value, value_size,
- p->value);
- if (p->right) {
- ADD_STR_VALUE(value,
- value_size,
- ".");
- }
- }
- p = p->right;
- }
- *len = _asn1_strlen(value) + 1;
- } else if ((node->type & CONST_DEFAULT)
- && (node->value == NULL)) {
- p = node->down;
- while (type_field(p->type) != ASN1_ETYPE_DEFAULT)
- p = p->right;
- PUT_STR_VALUE(value, value_size, p->value);
- } else {
- PUT_STR_VALUE(value, value_size, node->value);
+ }
+ }
+ else
+ {
+ len2 = -1;
+ if (asn1_get_octet_der
+ (node->value, node->value_len, &len2, value, value_size,
+ len) != ASN1_SUCCESS)
+ return ASN1_MEM_ERROR;
+ }
+ break;
+ case ASN1_ETYPE_OBJECT_ID:
+ if (node->type & CONST_ASSIGN)
+ {
+ value[0] = 0;
+ p = node->down;
+ while (p)
+ {
+ if (type_field (p->type) == ASN1_ETYPE_CONSTANT)
+ {
+ ADD_STR_VALUE (value, value_size, p->value);
+ if (p->right)
+ {
+ ADD_STR_VALUE (value, value_size, ".");
+ }
}
- break;
- case ASN1_ETYPE_GENERALIZED_TIME:
- case ASN1_ETYPE_UTC_TIME:
- PUT_AS_STR_VALUE(value, value_size, node->value,
- node->value_len);
- break;
- case ASN1_ETYPE_OCTET_STRING:
- case ASN1_ETYPE_GENERALSTRING:
- case ASN1_ETYPE_NUMERIC_STRING:
- case ASN1_ETYPE_IA5_STRING:
- case ASN1_ETYPE_TELETEX_STRING:
- case ASN1_ETYPE_PRINTABLE_STRING:
- case ASN1_ETYPE_UNIVERSAL_STRING:
- case ASN1_ETYPE_BMP_STRING:
- case ASN1_ETYPE_UTF8_STRING:
- case ASN1_ETYPE_VISIBLE_STRING:
- len2 = -1;
- if (asn1_get_octet_der
- (node->value, node->value_len, &len2, value,
- value_size, len) != ASN1_SUCCESS)
- return ASN1_MEM_ERROR;
- break;
- case ASN1_ETYPE_BIT_STRING:
- len2 = -1;
- if (asn1_get_bit_der
- (node->value, node->value_len, &len2, value,
- value_size, len) != ASN1_SUCCESS)
- return ASN1_MEM_ERROR;
- break;
- case ASN1_ETYPE_CHOICE:
- PUT_STR_VALUE(value, value_size, node->down->name);
- break;
- case ASN1_ETYPE_ANY:
- len3 = -1;
- len2 =
- asn1_get_length_der(node->value, node->value_len,
- &len3);
- if (len2 < 0)
- return ASN1_DER_ERROR;
- PUT_VALUE(value, value_size, node->value + len3, len2);
- break;
- default:
- return ASN1_ELEMENT_NOT_FOUND;
- break;
+ p = p->right;
+ }
+ *len = _asn1_strlen (value) + 1;
+ }
+ else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
+ {
+ p = node->down;
+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
+ p = p->right;
+ PUT_STR_VALUE (value, value_size, p->value);
}
- return ASN1_SUCCESS;
+ else
+ {
+ PUT_STR_VALUE (value, value_size, node->value);
+ }
+ break;
+ case ASN1_ETYPE_GENERALIZED_TIME:
+ case ASN1_ETYPE_UTC_TIME:
+ PUT_AS_STR_VALUE (value, value_size, node->value, node->value_len);
+ break;
+ case ASN1_ETYPE_OCTET_STRING:
+ case ASN1_ETYPE_GENERALSTRING:
+ case ASN1_ETYPE_NUMERIC_STRING:
+ case ASN1_ETYPE_IA5_STRING:
+ case ASN1_ETYPE_TELETEX_STRING:
+ case ASN1_ETYPE_PRINTABLE_STRING:
+ case ASN1_ETYPE_UNIVERSAL_STRING:
+ case ASN1_ETYPE_BMP_STRING:
+ case ASN1_ETYPE_UTF8_STRING:
+ case ASN1_ETYPE_VISIBLE_STRING:
+ len2 = -1;
+ if (asn1_get_octet_der
+ (node->value, node->value_len, &len2, value, value_size,
+ len) != ASN1_SUCCESS)
+ return ASN1_MEM_ERROR;
+ break;
+ case ASN1_ETYPE_BIT_STRING:
+ len2 = -1;
+ if (asn1_get_bit_der
+ (node->value, node->value_len, &len2, value, value_size,
+ len) != ASN1_SUCCESS)
+ return ASN1_MEM_ERROR;
+ break;
+ case ASN1_ETYPE_CHOICE:
+ PUT_STR_VALUE (value, value_size, node->down->name);
+ break;
+ case ASN1_ETYPE_ANY:
+ len3 = -1;
+ len2 = asn1_get_length_der (node->value, node->value_len, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+ PUT_VALUE (value, value_size, node->value + len3, len2);
+ break;
+ default:
+ return ASN1_ELEMENT_NOT_FOUND;
+ break;
+ }
+ return ASN1_SUCCESS;
}
@@ -932,62 +973,68 @@ asn1_read_value_type(asn1_node root, const char *name, void *ivalue,
* @name is not a valid element.
**/
int
-asn1_read_tag(asn1_node root, const char *name, int *tagValue,
- int *classValue)
+asn1_read_tag (asn1_node root, const char *name, int *tagValue,
+ int *classValue)
{
- asn1_node node, p, pTag;
-
- node = asn1_find_node(root, name);
- if (node == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
-
- p = node->down;
-
- /* pTag will points to the IMPLICIT TAG */
- pTag = NULL;
- if (node->type & CONST_TAG) {
- while (p) {
- if (type_field(p->type) == ASN1_ETYPE_TAG) {
- if ((p->type & CONST_IMPLICIT)
- && (pTag == NULL))
- pTag = p;
- else if (p->type & CONST_EXPLICIT)
- pTag = NULL;
- }
- p = p->right;
- }
+ asn1_node node, p, pTag;
+
+ node = asn1_find_node (root, name);
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p = node->down;
+
+ /* pTag will points to the IMPLICIT TAG */
+ pTag = NULL;
+ if (node->type & CONST_TAG)
+ {
+ while (p)
+ {
+ if (type_field (p->type) == ASN1_ETYPE_TAG)
+ {
+ if ((p->type & CONST_IMPLICIT) && (pTag == NULL))
+ pTag = p;
+ else if (p->type & CONST_EXPLICIT)
+ pTag = NULL;
+ }
+ p = p->right;
}
-
- if (pTag) {
- *tagValue = _asn1_strtoul(pTag->value, NULL, 10);
-
- if (pTag->type & CONST_APPLICATION)
- *classValue = ASN1_CLASS_APPLICATION;
- else if (pTag->type & CONST_UNIVERSAL)
- *classValue = ASN1_CLASS_UNIVERSAL;
- else if (pTag->type & CONST_PRIVATE)
- *classValue = ASN1_CLASS_PRIVATE;
- else
- *classValue = ASN1_CLASS_CONTEXT_SPECIFIC;
- } else {
- unsigned type = type_field(node->type);
- *classValue = ASN1_CLASS_UNIVERSAL;
-
- switch (type) {
- CASE_HANDLED_ETYPES:
- *tagValue = _asn1_tags[type].tag;
- break;
- case ASN1_ETYPE_TAG:
- case ASN1_ETYPE_CHOICE:
- case ASN1_ETYPE_ANY:
- *tagValue = -1;
- break;
- default:
- break;
- }
+ }
+
+ if (pTag)
+ {
+ *tagValue = _asn1_strtoul (pTag->value, NULL, 10);
+
+ if (pTag->type & CONST_APPLICATION)
+ *classValue = ASN1_CLASS_APPLICATION;
+ else if (pTag->type & CONST_UNIVERSAL)
+ *classValue = ASN1_CLASS_UNIVERSAL;
+ else if (pTag->type & CONST_PRIVATE)
+ *classValue = ASN1_CLASS_PRIVATE;
+ else
+ *classValue = ASN1_CLASS_CONTEXT_SPECIFIC;
+ }
+ else
+ {
+ unsigned type = type_field (node->type);
+ *classValue = ASN1_CLASS_UNIVERSAL;
+
+ switch (type)
+ {
+ CASE_HANDLED_ETYPES:
+ *tagValue = _asn1_tags[type].tag;
+ break;
+ case ASN1_ETYPE_TAG:
+ case ASN1_ETYPE_CHOICE:
+ case ASN1_ETYPE_ANY:
+ *tagValue = -1;
+ break;
+ default:
+ break;
}
+ }
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
/**
@@ -1000,12 +1047,13 @@ asn1_read_tag(asn1_node root, const char *name, int *tagValue,
*
* Returns: %ASN1_SUCCESS if the node exists.
**/
-int asn1_read_node_value(asn1_node node, asn1_data_node_st * data)
+int
+asn1_read_node_value (asn1_node node, asn1_data_node_st * data)
{
- data->name = node->name;
- data->value = node->value;
- data->value_len = node->value_len;
- data->type = type_field(node->type);
+ data->name = node->name;
+ data->value = node->value;
+ data->value_len = node->value_len;
+ data->type = type_field (node->type);
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
diff --git a/lib/minitasn1/element.h b/lib/minitasn1/element.h
index aca0238b42..fdecafb611 100644
--- a/lib/minitasn1/element.h
+++ b/lib/minitasn1/element.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2000-2014 Free Software Foundation, Inc.
*
* This file is part of LIBTASN1.
*
@@ -23,12 +23,12 @@
#define _ELEMENT_H
-int _asn1_append_sequence_set(asn1_node node);
+int _asn1_append_sequence_set (asn1_node node);
-int _asn1_convert_integer(const unsigned char *value,
- unsigned char *value_out,
- int value_out_size, int *len);
+int _asn1_convert_integer (const unsigned char *value,
+ unsigned char *value_out,
+ int value_out_size, int *len);
-void _asn1_hierarchical_name(asn1_node node, char *name, int name_size);
+void _asn1_hierarchical_name (asn1_node node, char *name, int name_size);
#endif
diff --git a/lib/minitasn1/errors.c b/lib/minitasn1/errors.c
index db9f1fa051..e9fa302605 100644
--- a/lib/minitasn1/errors.c
+++ b/lib/minitasn1/errors.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2002-2014 Free Software Foundation, Inc.
*
* This file is part of LIBTASN1.
*
@@ -26,32 +26,33 @@
#define LIBTASN1_ERROR_ENTRY(name) { #name, name }
-struct libtasn1_error_entry {
- const char *name;
- int number;
+struct libtasn1_error_entry
+{
+ const char *name;
+ int number;
};
typedef struct libtasn1_error_entry libtasn1_error_entry;
static const libtasn1_error_entry error_algorithms[] = {
- LIBTASN1_ERROR_ENTRY(ASN1_SUCCESS),
- LIBTASN1_ERROR_ENTRY(ASN1_FILE_NOT_FOUND),
- LIBTASN1_ERROR_ENTRY(ASN1_ELEMENT_NOT_FOUND),
- LIBTASN1_ERROR_ENTRY(ASN1_IDENTIFIER_NOT_FOUND),
- LIBTASN1_ERROR_ENTRY(ASN1_DER_ERROR),
- LIBTASN1_ERROR_ENTRY(ASN1_VALUE_NOT_FOUND),
- LIBTASN1_ERROR_ENTRY(ASN1_GENERIC_ERROR),
- LIBTASN1_ERROR_ENTRY(ASN1_VALUE_NOT_VALID),
- LIBTASN1_ERROR_ENTRY(ASN1_TAG_ERROR),
- LIBTASN1_ERROR_ENTRY(ASN1_TAG_IMPLICIT),
- LIBTASN1_ERROR_ENTRY(ASN1_ERROR_TYPE_ANY),
- LIBTASN1_ERROR_ENTRY(ASN1_SYNTAX_ERROR),
- LIBTASN1_ERROR_ENTRY(ASN1_MEM_ERROR),
- LIBTASN1_ERROR_ENTRY(ASN1_MEM_ALLOC_ERROR),
- LIBTASN1_ERROR_ENTRY(ASN1_DER_OVERFLOW),
- LIBTASN1_ERROR_ENTRY(ASN1_NAME_TOO_LONG),
- LIBTASN1_ERROR_ENTRY(ASN1_ARRAY_ERROR),
- LIBTASN1_ERROR_ENTRY(ASN1_ELEMENT_NOT_EMPTY),
- {0, 0}
+ LIBTASN1_ERROR_ENTRY (ASN1_SUCCESS),
+ LIBTASN1_ERROR_ENTRY (ASN1_FILE_NOT_FOUND),
+ LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_FOUND),
+ LIBTASN1_ERROR_ENTRY (ASN1_IDENTIFIER_NOT_FOUND),
+ LIBTASN1_ERROR_ENTRY (ASN1_DER_ERROR),
+ LIBTASN1_ERROR_ENTRY (ASN1_VALUE_NOT_FOUND),
+ LIBTASN1_ERROR_ENTRY (ASN1_GENERIC_ERROR),
+ LIBTASN1_ERROR_ENTRY (ASN1_VALUE_NOT_VALID),
+ LIBTASN1_ERROR_ENTRY (ASN1_TAG_ERROR),
+ LIBTASN1_ERROR_ENTRY (ASN1_TAG_IMPLICIT),
+ LIBTASN1_ERROR_ENTRY (ASN1_ERROR_TYPE_ANY),
+ LIBTASN1_ERROR_ENTRY (ASN1_SYNTAX_ERROR),
+ LIBTASN1_ERROR_ENTRY (ASN1_MEM_ERROR),
+ LIBTASN1_ERROR_ENTRY (ASN1_MEM_ALLOC_ERROR),
+ LIBTASN1_ERROR_ENTRY (ASN1_DER_OVERFLOW),
+ LIBTASN1_ERROR_ENTRY (ASN1_NAME_TOO_LONG),
+ LIBTASN1_ERROR_ENTRY (ASN1_ARRAY_ERROR),
+ LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_EMPTY),
+ {0, 0}
};
/**
@@ -62,14 +63,13 @@ static const libtasn1_error_entry error_algorithms[] = {
* function is like perror(). The only difference is that it accepts
* an error returned by a libtasn1 function.
*
- * This function replaces libtasn1_perror() in older libtasn1.
- *
* Since: 1.6
**/
-void asn1_perror(int error)
+void
+asn1_perror (int error)
{
- const char *str = asn1_strerror(error);
- fprintf(stderr, "LIBTASN1 ERROR: %s\n", str ? str : "(null)");
+ const char *str = asn1_strerror (error);
+ fprintf (stderr, "LIBTASN1 ERROR: %s\n", str ? str : "(null)");
}
/**
@@ -80,20 +80,19 @@ void asn1_perror(int error)
* similar to strerror. The only difference is that it accepts an
* error (number) returned by a libtasn1 function.
*
- * This function replaces libtasn1_strerror() in older libtasn1.
- *
* Returns: Pointer to static zero-terminated string describing error
* code.
*
* Since: 1.6
**/
-const char *asn1_strerror(int error)
+const char *
+asn1_strerror (int error)
{
- const libtasn1_error_entry *p;
+ const libtasn1_error_entry *p;
- for (p = error_algorithms; p->name != NULL; p++)
- if (p->number == error)
- return p->name + sizeof("ASN1_") - 1;
+ for (p = error_algorithms; p->name != NULL; p++)
+ if (p->number == error)
+ return p->name + sizeof ("ASN1_") - 1;
- return NULL;
+ return NULL;
}
diff --git a/lib/minitasn1/gstr.c b/lib/minitasn1/gstr.c
index f10dd2ac3d..e91a3a151c 100644
--- a/lib/minitasn1/gstr.c
+++ b/lib/minitasn1/gstr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2002-2014 Free Software Foundation, Inc.
*
* This file is part of LIBTASN1.
*
@@ -28,38 +28,47 @@
*
* They should be used only with null terminated strings.
*/
-void _asn1_str_cat(char *dest, size_t dest_tot_size, const char *src)
+void
+_asn1_str_cat (char *dest, size_t dest_tot_size, const char *src)
{
- size_t str_size = strlen(src);
- size_t dest_size = strlen(dest);
+ size_t str_size = strlen (src);
+ size_t dest_size = strlen (dest);
- if (dest_tot_size - dest_size > str_size) {
- strcat(dest, src);
- } else {
- if (dest_tot_size - dest_size > 0) {
- strncat(dest, src,
- (dest_tot_size - dest_size) - 1);
- dest[dest_tot_size - 1] = 0;
- }
+ if (dest_tot_size - dest_size > str_size)
+ {
+ strcat (dest, src);
+ }
+ else
+ {
+ if (dest_tot_size - dest_size > 0)
+ {
+ strncat (dest, src, (dest_tot_size - dest_size) - 1);
+ dest[dest_tot_size - 1] = 0;
}
+ }
}
/* Returns the bytes copied (not including the null terminator) */
unsigned int
-_asn1_str_cpy(char *dest, size_t dest_tot_size, const char *src)
+_asn1_str_cpy (char *dest, size_t dest_tot_size, const char *src)
{
- size_t str_size = strlen(src);
+ size_t str_size = strlen (src);
- if (dest_tot_size > str_size) {
- strcpy(dest, src);
- return str_size;
- } else {
- if (dest_tot_size > 0) {
- str_size = dest_tot_size - 1;
- memcpy(dest, src, str_size);
- dest[str_size] = 0;
- return str_size;
- } else
- return 0;
+ if (dest_tot_size > str_size)
+ {
+ strcpy (dest, src);
+ return str_size;
+ }
+ else
+ {
+ if (dest_tot_size > 0)
+ {
+ str_size = dest_tot_size - 1;
+ memcpy (dest, src, str_size);
+ dest[str_size] = 0;
+ return str_size;
}
+ else
+ return 0;
+ }
}
diff --git a/lib/minitasn1/gstr.h b/lib/minitasn1/gstr.h
index 9b7176a4a1..51db059489 100644
--- a/lib/minitasn1/gstr.h
+++ b/lib/minitasn1/gstr.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2002-2014 Free Software Foundation, Inc.
*
* This file is part of LIBTASN1.
*
@@ -19,9 +19,9 @@
* 02110-1301, USA
*/
-unsigned int _asn1_str_cpy(char *dest, size_t dest_tot_size,
- const char *src);
-void _asn1_str_cat(char *dest, size_t dest_tot_size, const char *src);
+unsigned int _asn1_str_cpy (char *dest, size_t dest_tot_size,
+ const char *src);
+void _asn1_str_cat (char *dest, size_t dest_tot_size, const char *src);
#define Estrcpy(x,y) _asn1_str_cpy(x,ASN1_MAX_ERROR_DESCRIPTION_SIZE,y)
#define Estrcat(x,y) _asn1_str_cat(x,ASN1_MAX_ERROR_DESCRIPTION_SIZE,y)
diff --git a/lib/minitasn1/int.h b/lib/minitasn1/int.h
index d422a79c6b..3701e5f645 100644
--- a/lib/minitasn1/int.h
+++ b/lib/minitasn1/int.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2002-2014 Free Software Foundation, Inc.
*
* This file is part of LIBTASN1.
*
@@ -43,24 +43,26 @@
/* This structure is also in libtasn1.h, but then contains less
fields. You cannot make any modifications to these first fields
without breaking ABI. */
-struct asn1_node_st {
- /* public fields: */
- char name[ASN1_MAX_NAME_SIZE + 1]; /* Node name */
- unsigned int name_hash;
- unsigned int type; /* Node type */
- unsigned char *value; /* Node value */
- int value_len;
- asn1_node down; /* Pointer to the son node */
- asn1_node right; /* Pointer to the brother node */
- asn1_node left; /* Pointer to the next list element */
- /* private fields: */
- unsigned char small_value[ASN1_SMALL_VALUE_SIZE]; /* For small values */
+struct asn1_node_st
+{
+ /* public fields: */
+ char name[ASN1_MAX_NAME_SIZE + 1]; /* Node name */
+ unsigned int name_hash;
+ unsigned int type; /* Node type */
+ unsigned char *value; /* Node value */
+ int value_len;
+ asn1_node down; /* Pointer to the son node */
+ asn1_node right; /* Pointer to the brother node */
+ asn1_node left; /* Pointer to the next list element */
+ /* private fields: */
+ unsigned char small_value[ASN1_SMALL_VALUE_SIZE]; /* For small values */
};
-typedef struct tag_and_class_st {
- unsigned tag;
- unsigned class;
- const char *desc;
+typedef struct tag_and_class_st
+{
+ unsigned tag;
+ unsigned class;
+ const char *desc;
} tag_and_class_st;
/* the types that are handled in _asn1_tags */
@@ -155,28 +157,32 @@ extern const tag_and_class_st _asn1_tags[];
/* Returns the first 8 bits. */
/* Used with the field type of asn1_node_st */
/****************************************/
-inline static unsigned int type_field(unsigned int ntype)
+inline static unsigned int
+type_field (unsigned int ntype)
{
- return (ntype & 0xff);
+ return (ntype & 0xff);
}
/* To convert old types from a static structure */
-inline static unsigned int convert_old_type(unsigned int ntype)
+inline static unsigned int
+convert_old_type (unsigned int ntype)
{
- unsigned int type = ntype & 0xff;
- if (type == ASN1_ETYPE_TIME) {
- if (ntype & CONST_UTC)
- type = ASN1_ETYPE_UTC_TIME;
- else
- type = ASN1_ETYPE_GENERALIZED_TIME;
-
- ntype &= ~(CONST_UTC | CONST_GENERALIZED);
- ntype &= 0xffffff00;
- ntype |= type;
-
- return ntype;
- } else
- return ntype;
+ unsigned int type = ntype & 0xff;
+ if (type == ASN1_ETYPE_TIME)
+ {
+ if (ntype & CONST_UTC)
+ type = ASN1_ETYPE_UTC_TIME;
+ else
+ type = ASN1_ETYPE_GENERALIZED_TIME;
+
+ ntype &= ~(CONST_UTC | CONST_GENERALIZED);
+ ntype &= 0xffffff00;
+ ntype |= type;
+
+ return ntype;
+ }
+ else
+ return ntype;
}
-#endif /* INT_H */
+#endif /* INT_H */
diff --git a/lib/minitasn1/libtasn1.h b/lib/minitasn1/libtasn1.h
index 37fd376c68..92ae54eb4e 100644
--- a/lib/minitasn1/libtasn1.h
+++ b/lib/minitasn1/libtasn1.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2002-2014 Free Software Foundation, Inc.
*
* This file is part of LIBTASN1.
*
@@ -35,18 +35,19 @@
#endif
#endif
-#include <stdio.h> /* for FILE* */
#include <sys/types.h>
#include <time.h>
+#include <stdio.h> /* for FILE* */
#ifdef __cplusplus
-extern "C" {
+extern "C"
+{
#endif
-#define ASN1_VERSION "3.1"
+#define ASN1_VERSION "3.5"
/*****************************************/
- /* Errors returned by libtasn1 functions */
+ /* Errors returned by libtasn1 functions */
/*****************************************/
#define ASN1_SUCCESS 0
#define ASN1_FILE_NOT_FOUND 1
@@ -68,7 +69,7 @@ extern "C" {
#define ASN1_ELEMENT_NOT_EMPTY 17
/*************************************/
- /* Constants used in asn1_visit_tree */
+ /* Constants used in asn1_visit_tree */
/*************************************/
#define ASN1_PRINT_NAME 1
#define ASN1_PRINT_NAME_TYPE 2
@@ -76,7 +77,7 @@ extern "C" {
#define ASN1_PRINT_ALL 4
/*****************************************/
- /* Constants returned by asn1_read_tag */
+ /* Constants returned by asn1_read_tag */
/*****************************************/
#define ASN1_CLASS_UNIVERSAL 0x00 /* old: 1 */
#define ASN1_CLASS_APPLICATION 0x40 /* old: 2 */
@@ -85,7 +86,7 @@ extern "C" {
#define ASN1_CLASS_STRUCTURED 0x20
/*****************************************/
- /* Constants returned by asn1_read_tag */
+ /* Constants returned by asn1_read_tag */
/*****************************************/
#define ASN1_TAG_BOOLEAN 0x01
#define ASN1_TAG_INTEGER 0x02
@@ -109,28 +110,29 @@ extern "C" {
#define ASN1_TAG_VISIBLE_STRING 0x1A
/******************************************************/
- /* Structure definition used for the node of the tree */
- /* that represent an ASN.1 DEFINITION. */
+ /* Structure definition used for the node of the tree */
+ /* that represent an ASN.1 DEFINITION. */
/******************************************************/
- typedef struct asn1_node_st asn1_node_st;
+ typedef struct asn1_node_st asn1_node_st;
- typedef asn1_node_st *asn1_node;
+ typedef asn1_node_st *asn1_node;
- /* maximum number of characters of a name */
- /* inside a file with ASN1 definitons */
+ /* maximum number of characters of a name */
+ /* inside a file with ASN1 definitons */
#define ASN1_MAX_NAME_SIZE 64
/*****************************************/
- /* For the on-disk format of ASN.1 trees */
+ /* For the on-disk format of ASN.1 trees */
/*****************************************/
- struct asn1_static_node_st {
- const char *name; /* Node name */
- unsigned int type; /* Node type */
- const void *value; /* Node value */
- };
- typedef struct asn1_static_node_st asn1_static_node;
+ struct asn1_static_node_st
+ {
+ const char *name; /* Node name */
+ unsigned int type; /* Node type */
+ const void *value; /* Node value */
+ };
+ typedef struct asn1_static_node_st asn1_static_node;
/* List of constants for field type of node_asn */
#define ASN1_ETYPE_INVALID 0
@@ -166,185 +168,182 @@ extern "C" {
#define ASN1_ETYPE_UTC_TIME 36
#define ASN1_ETYPE_GENERALIZED_TIME 37
- struct asn1_data_node_st {
- const char *name; /* Node name */
- const void *value; /* Node value */
- unsigned int value_len; /* Node value size */
- unsigned int type; /* Node value type (ASN1_ETYPE_*) */
- };
- typedef struct asn1_data_node_st asn1_data_node_st;
+/* Flags used by asn1_delete_structure2() */
+
+/* makes sure the values are zeroized prior to deinitialization */
+#define ASN1_DELETE_FLAG_ZEROIZE 1
+
+
+ struct asn1_data_node_st
+ {
+ const char *name; /* Node name */
+ const void *value; /* Node value */
+ unsigned int value_len; /* Node value size */
+ unsigned int type; /* Node value type (ASN1_ETYPE_*) */
+ };
+ typedef struct asn1_data_node_st asn1_data_node_st;
/***********************************/
- /* Fixed constants */
+ /* Fixed constants */
/***********************************/
- /* maximum number of characters */
- /* of a description message */
- /* (null character included) */
+ /* maximum number of characters */
+ /* of a description message */
+ /* (null character included) */
#define ASN1_MAX_ERROR_DESCRIPTION_SIZE 128
/***********************************/
- /* Functions definitions */
+ /* Functions definitions */
/***********************************/
- extern ASN1_API int
- asn1_parser2tree(const char *file_name,
- asn1_node * definitions, char *errorDescription);
+ extern ASN1_API int
+ asn1_parser2tree (const char *file,
+ asn1_node * definitions, char *error_desc);
+
+ extern ASN1_API int
+ asn1_parser2array (const char *inputFileName,
+ const char *outputFileName,
+ const char *vectorName, char *error_desc);
- extern ASN1_API int
- asn1_parser2array(const char *inputFileName,
- const char *outputFileName,
- const char *vectorName, char *errorDescription);
+ extern ASN1_API int
+ asn1_array2tree (const asn1_static_node * array,
+ asn1_node * definitions, char *errorDescription);
- extern ASN1_API int
- asn1_array2tree(const asn1_static_node * array,
- asn1_node * definitions, char *errorDescription);
+ extern ASN1_API void
+ asn1_print_structure (FILE * out, asn1_node structure,
+ const char *name, int mode);
- extern ASN1_API void
- asn1_print_structure(FILE * out, asn1_node structure,
- const char *name, int mode);
+ extern ASN1_API int
+ asn1_create_element (asn1_node definitions,
+ const char *source_name, asn1_node * element);
- extern ASN1_API int
- asn1_create_element(asn1_node definitions,
- const char *source_name, asn1_node * element);
+ extern ASN1_API int asn1_delete_structure (asn1_node * structure);
- extern ASN1_API int asn1_delete_structure(asn1_node * structure);
+ extern ASN1_API int asn1_delete_structure2 (asn1_node * structure, unsigned int flags);
- extern ASN1_API int
- asn1_delete_element(asn1_node structure,
- const char *element_name);
+ extern ASN1_API int
+ asn1_delete_element (asn1_node structure, const char *element_name);
- extern ASN1_API int
- asn1_write_value(asn1_node node_root, const char *name,
- const void *ivalue, int len);
+ extern ASN1_API int
+ asn1_write_value (asn1_node node_root, const char *name,
+ const void *ivalue, int len);
- extern ASN1_API int
- asn1_read_value(asn1_node root, const char *name,
- void *ivalue, int *len);
+ extern ASN1_API int
+ asn1_read_value (asn1_node root, const char *name,
+ void *ivalue, int *len);
- extern ASN1_API int
- asn1_read_value_type(asn1_node root, const char *name,
- void *ivalue, int *len, unsigned int *etype);
+ extern ASN1_API int
+ asn1_read_value_type (asn1_node root, const char *name,
+ void *ivalue, int *len, unsigned int *etype);
- extern ASN1_API int
- asn1_read_node_value(asn1_node node, asn1_data_node_st * data);
+ extern ASN1_API int
+ asn1_read_node_value (asn1_node node, asn1_data_node_st * data);
- extern ASN1_API int
- asn1_number_of_elements(asn1_node element, const char *name,
- int *num);
+ extern ASN1_API int
+ asn1_number_of_elements (asn1_node element, const char *name, int *num);
- extern ASN1_API int
- asn1_der_coding(asn1_node element, const char *name,
- void *ider, int *len, char *ErrorDescription);
+ extern ASN1_API int
+ asn1_der_coding (asn1_node element, const char *name,
+ void *ider, int *len, char *ErrorDescription);
- extern ASN1_API int
- asn1_der_decoding(asn1_node * element, const void *ider,
- int len, char *errorDescription);
+ extern ASN1_API int
+ asn1_der_decoding (asn1_node * element, const void *ider,
+ int len, char *errorDescription);
- extern ASN1_API int
- asn1_der_decoding_element(asn1_node * structure,
- const char *elementName,
- const void *ider, int len,
- char *errorDescription);
+ extern ASN1_API int
+ asn1_der_decoding_element (asn1_node * structure,
+ const char *elementName,
+ const void *ider, int len,
+ char *errorDescription);
- extern ASN1_API int
- asn1_der_decoding_startEnd(asn1_node element,
- const void *ider, int len,
- const char *name_element,
- int *start, int *end);
+ extern ASN1_API int
+ asn1_der_decoding_startEnd (asn1_node element,
+ const void *ider, int len,
+ const char *name_element,
+ int *start, int *end);
- extern ASN1_API int
- asn1_expand_any_defined_by(asn1_node definitions,
- asn1_node * element);
+ extern ASN1_API int
+ asn1_expand_any_defined_by (asn1_node definitions, asn1_node * element);
- extern ASN1_API int
- asn1_expand_octet_string(asn1_node definitions,
- asn1_node * element,
- const char *octetName,
- const char *objectName);
+ extern ASN1_API int
+ asn1_expand_octet_string (asn1_node definitions,
+ asn1_node * element,
+ const char *octetName, const char *objectName);
- extern ASN1_API int
- asn1_read_tag(asn1_node root, const char *name,
- int *tagValue, int *classValue);
+ extern ASN1_API int
+ asn1_read_tag (asn1_node root, const char *name,
+ int *tagValue, int *classValue);
- extern ASN1_API const char *asn1_find_structure_from_oid(asn1_node
- definitions,
- const char
- *oidValue);
+ extern ASN1_API const char *asn1_find_structure_from_oid (asn1_node
+ definitions,
+ const char
+ *oidValue);
- extern ASN1_API const char *asn1_check_version(const char
- *req_version);
+ extern ASN1_API const char *asn1_check_version (const char *req_version);
- extern ASN1_API const char *asn1_strerror(int error);
+ extern ASN1_API const char *asn1_strerror (int error);
- extern ASN1_API void asn1_perror(int error);
+ extern ASN1_API void asn1_perror (int error);
#define ASN1_MAX_TAG_SIZE 4
#define ASN1_MAX_LENGTH_SIZE 9
#define ASN1_MAX_TL_SIZE (ASN1_MAX_TAG_SIZE+ASN1_MAX_LENGTH_SIZE)
- extern ASN1_API long
- asn1_get_length_der(const unsigned char *der, int der_len,
- int *len);
+ extern ASN1_API long
+ asn1_get_length_der (const unsigned char *der, int der_len, int *len);
- extern ASN1_API long
- asn1_get_length_ber(const unsigned char *ber, int ber_len,
- int *len);
+ extern ASN1_API long
+ asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len);
- extern ASN1_API void
- asn1_length_der(unsigned long int len, unsigned char *ans,
- int *ans_len);
+ extern ASN1_API void
+ asn1_length_der (unsigned long int len, unsigned char *der, int *der_len);
- /* Other utility functions. */
+ /* Other utility functions. */
- extern ASN1_API
- int asn1_decode_simple_der(unsigned int etype,
- const unsigned char *der,
- unsigned int der_len,
- const unsigned char **str,
- unsigned int *str_len);
+ extern ASN1_API
+ int asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
+ unsigned int der_len,
+ const unsigned char **str,
+ unsigned int *str_len);
- extern ASN1_API int
- asn1_encode_simple_der(unsigned int etype,
- const unsigned char *str,
- unsigned int str_len, unsigned char *tl,
- unsigned int *tl_len);
+ extern ASN1_API int
+ asn1_encode_simple_der (unsigned int etype, const unsigned char *str,
+ unsigned int str_len, unsigned char *tl,
+ unsigned int *tl_len);
- extern ASN1_API asn1_node
- asn1_find_node(asn1_node pointer, const char *name);
+ extern ASN1_API asn1_node
+ asn1_find_node (asn1_node pointer, const char *name);
- extern ASN1_API int
- asn1_copy_node(asn1_node dst, const char *dst_name,
- asn1_node src, const char *src_name);
+ extern ASN1_API int
+ asn1_copy_node (asn1_node dst, const char *dst_name,
+ asn1_node src, const char *src_name);
- /* Internal and low-level DER utility functions. */
+ /* Internal and low-level DER utility functions. */
- extern ASN1_API int
- asn1_get_tag_der(const unsigned char *der, int der_len,
- unsigned char *cls, int *len,
- unsigned long *tag);
+ extern ASN1_API int
+ asn1_get_tag_der (const unsigned char *der, int der_len,
+ unsigned char *cls, int *len, unsigned long *tag);
- extern ASN1_API void
- asn1_octet_der(const unsigned char *str, int str_len,
- unsigned char *der, int *der_len);
+ extern ASN1_API void
+ asn1_octet_der (const unsigned char *str, int str_len,
+ unsigned char *der, int *der_len);
- extern ASN1_API int
- asn1_get_octet_der(const unsigned char *der, int der_len,
- int *ret_len, unsigned char *str,
- int str_size, int *str_len);
+ extern ASN1_API int
+ asn1_get_octet_der (const unsigned char *der, int der_len,
+ int *ret_len, unsigned char *str,
+ int str_size, int *str_len);
- extern ASN1_API void asn1_bit_der(const unsigned char *str,
- int bit_len, unsigned char *der,
- int *der_len);
+ extern ASN1_API void asn1_bit_der (const unsigned char *str, int bit_len,
+ unsigned char *der, int *der_len);
- extern ASN1_API int
- asn1_get_bit_der(const unsigned char *der, int der_len,
- int *ret_len, unsigned char *str,
- int str_size, int *bit_len);
+ extern ASN1_API int
+ asn1_get_bit_der (const unsigned char *der, int der_len,
+ int *ret_len, unsigned char *str,
+ int str_size, int *bit_len);
/* Compatibility types */
- typedef int asn1_retCode; /* type returned by libtasn1 functions */
+ typedef int asn1_retCode; /* type returned by libtasn1 functions */
#define node_asn_struct asn1_node_st
#define node_asn asn1_node_st
@@ -361,4 +360,5 @@ extern "C" {
#ifdef __cplusplus
}
#endif
+
#endif /* LIBTASN1_H */
diff --git a/lib/minitasn1/parser_aux.c b/lib/minitasn1/parser_aux.c
index 3413dab6f7..b5f665db4c 100644
--- a/lib/minitasn1/parser_aux.c
+++ b/lib/minitasn1/parser_aux.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2000-2014 Free Software Foundation, Inc.
*
* This file is part of LIBTASN1.
*
@@ -33,9 +33,10 @@ char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not fou
/* Description: type used in the list during */
/* the structure creation. */
/***********************************************/
-typedef struct list_struct {
- asn1_node node;
- struct list_struct *next;
+typedef struct list_struct
+{
+ asn1_node node;
+ struct list_struct *next;
} list_type;
@@ -51,28 +52,30 @@ list_type *firstElement = NULL;
/* and CONST_ constants). */
/* Return: pointer to the new element. */
/******************************************************/
-asn1_node _asn1_add_static_node(unsigned int type)
+asn1_node
+_asn1_add_static_node (unsigned int type)
{
- list_type *listElement;
- asn1_node punt;
+ list_type *listElement;
+ asn1_node punt;
- punt = calloc(1, sizeof(struct asn1_node_st));
- if (punt == NULL)
- return NULL;
+ punt = calloc (1, sizeof (struct asn1_node_st));
+ if (punt == NULL)
+ return NULL;
- listElement = malloc(sizeof(list_type));
- if (listElement == NULL) {
- free(punt);
- return NULL;
- }
+ listElement = malloc (sizeof (list_type));
+ if (listElement == NULL)
+ {
+ free (punt);
+ return NULL;
+ }
- listElement->node = punt;
- listElement->next = firstElement;
- firstElement = listElement;
+ listElement->node = punt;
+ listElement->next = firstElement;
+ firstElement = listElement;
- punt->type = type;
+ punt->type = type;
- return punt;
+ return punt;
}
/**
@@ -87,97 +90,111 @@ asn1_node _asn1_add_static_node(unsigned int type)
*
* Returns: the search result, or %NULL if not found.
**/
-asn1_node asn1_find_node(asn1_node pointer, const char *name)
+asn1_node
+asn1_find_node (asn1_node pointer, const char *name)
{
- asn1_node p;
- char *n_end, n[ASN1_MAX_NAME_SIZE + 1];
- const char *n_start;
- unsigned int nsize;
- unsigned int nhash;
-
- if (pointer == NULL)
- return NULL;
-
- if (name == NULL)
- return NULL;
-
- p = pointer;
- n_start = name;
-
- if (p->name[0] != 0) { /* has *pointer got a name ? */
- n_end = strchr(n_start, '.'); /* search the first dot */
- if (n_end) {
- nsize = n_end - n_start;
- memcpy(n, n_start, nsize);
- n[nsize] = 0;
- n_start = n_end;
- n_start++;
-
- nhash = hash_pjw_bare(n, nsize);
- } else {
- nsize = _asn1_str_cpy(n, sizeof(n), n_start);
- nhash = hash_pjw_bare(n, nsize);
-
- n_start = NULL;
- }
-
- while (p) {
- if ((p->name) && nhash == p->name_hash
- && (!strcmp(p->name, n)))
- break;
- else
- p = p->right;
- } /* while */
-
- if (p == NULL)
- return NULL;
- } else { /* *pointer doesn't have a name */
- if (n_start[0] == 0)
- return p;
+ asn1_node p;
+ char *n_end, n[ASN1_MAX_NAME_SIZE + 1];
+ const char *n_start;
+ unsigned int nsize;
+ unsigned int nhash;
+
+ if (pointer == NULL)
+ return NULL;
+
+ if (name == NULL)
+ return NULL;
+
+ p = pointer;
+ n_start = name;
+
+ if (p->name[0] != 0)
+ { /* has *pointer got a name ? */
+ n_end = strchr (n_start, '.'); /* search the first dot */
+ if (n_end)
+ {
+ nsize = n_end - n_start;
+ memcpy (n, n_start, nsize);
+ n[nsize] = 0;
+ n_start = n_end;
+ n_start++;
+
+ nhash = hash_pjw_bare (n, nsize);
}
+ else
+ {
+ nsize = _asn1_str_cpy (n, sizeof (n), n_start);
+ nhash = hash_pjw_bare (n, nsize);
- while (n_start) { /* Has the end of NAME been reached? */
- n_end = strchr(n_start, '.'); /* search the next dot */
- if (n_end) {
- nsize = n_end - n_start;
- memcpy(n, n_start, nsize);
- n[nsize] = 0;
- n_start = n_end;
- n_start++;
-
- nhash = hash_pjw_bare(n, nsize);
- } else {
- nsize = _asn1_str_cpy(n, sizeof(n), n_start);
- nhash = hash_pjw_bare(n, nsize);
- n_start = NULL;
- }
+ n_start = NULL;
+ }
- if (p->down == NULL)
- return NULL;
-
- p = p->down;
-
- /* The identifier "?LAST" indicates the last element
- in the right chain. */
- if (!strcmp(n, "?LAST")) {
- if (p == NULL)
- return NULL;
- while (p->right)
- p = p->right;
- } else { /* no "?LAST" */
- while (p) {
- if (p->name_hash == nhash
- && !strcmp(p->name, n))
- break;
- else
- p = p->right;
- }
- if (p == NULL)
- return NULL;
- }
+ while (p)
+ {
+ if (nhash == p->name_hash && (!strcmp (p->name, n)))
+ break;
+ else
+ p = p->right;
} /* while */
+ if (p == NULL)
+ return NULL;
+ }
+ else
+ { /* *pointer doesn't have a name */
+ if (n_start[0] == 0)
return p;
+ }
+
+ while (n_start)
+ { /* Has the end of NAME been reached? */
+ n_end = strchr (n_start, '.'); /* search the next dot */
+ if (n_end)
+ {
+ nsize = n_end - n_start;
+ memcpy (n, n_start, nsize);
+ n[nsize] = 0;
+ n_start = n_end;
+ n_start++;
+
+ nhash = hash_pjw_bare (n, nsize);
+ }
+ else
+ {
+ nsize = _asn1_str_cpy (n, sizeof (n), n_start);
+ nhash = hash_pjw_bare (n, nsize);
+ n_start = NULL;
+ }
+
+ if (p->down == NULL)
+ return NULL;
+
+ p = p->down;
+
+ /* The identifier "?LAST" indicates the last element
+ in the right chain. */
+ if (!strcmp (n, "?LAST"))
+ {
+ if (p == NULL)
+ return NULL;
+ while (p->right)
+ p = p->right;
+ }
+ else
+ { /* no "?LAST" */
+ while (p)
+ {
+ if (p->name_hash == nhash && !strcmp (p->name, n))
+ break;
+ else
+ p = p->right;
+ }
+ if (p == NULL)
+ return NULL;
+ }
+ } /* while */
+
+ return p;
}
@@ -192,31 +209,35 @@ asn1_node asn1_find_node(asn1_node pointer, const char *name)
/* Return: pointer to the NODE_ASN element. */
/******************************************************************/
asn1_node
-_asn1_set_value(asn1_node node, const void *value, unsigned int len)
+_asn1_set_value (asn1_node node, const void *value, unsigned int len)
{
- if (node == NULL)
- return node;
- if (node->value) {
- if (node->value != node->small_value)
- free(node->value);
- node->value = NULL;
- node->value_len = 0;
- }
-
- if (!len)
- return node;
-
- if (len < sizeof(node->small_value)) {
- node->value = node->small_value;
- } else {
- node->value = malloc(len);
- if (node->value == NULL)
- return NULL;
- }
- node->value_len = len;
-
- memcpy(node->value, value, len);
- return node;
+ if (node == NULL)
+ return node;
+ if (node->value)
+ {
+ if (node->value != node->small_value)
+ free (node->value);
+ node->value = NULL;
+ node->value_len = 0;
+ }
+
+ if (!len)
+ return node;
+
+ if (len < sizeof (node->small_value))
+ {
+ node->value = node->small_value;
+ }
+ else
+ {
+ node->value = malloc (len);
+ if (node->value == NULL)
+ return NULL;
+ }
+ node->value_len = len;
+
+ memcpy (node->value, value, len);
+ return node;
}
/******************************************************************/
@@ -231,45 +252,47 @@ _asn1_set_value(asn1_node node, const void *value, unsigned int len)
/* Return: pointer to the NODE_ASN element. */
/******************************************************************/
asn1_node
-_asn1_set_value_lv(asn1_node node, const void *value, unsigned int len)
+_asn1_set_value_lv (asn1_node node, const void *value, unsigned int len)
{
- int len2;
- void *temp;
+ int len2;
+ void *temp;
- if (node == NULL)
- return node;
+ if (node == NULL)
+ return node;
- asn1_length_der(len, NULL, &len2);
- temp = malloc(len + len2);
- if (temp == NULL)
- return NULL;
+ asn1_length_der (len, NULL, &len2);
+ temp = malloc (len + len2);
+ if (temp == NULL)
+ return NULL;
- asn1_octet_der(value, len, temp, &len2);
- return _asn1_set_value_m(node, temp, len2);
+ asn1_octet_der (value, len, temp, &len2);
+ return _asn1_set_value_m (node, temp, len2);
}
/* the same as _asn1_set_value except that it sets an already malloc'ed
* value.
*/
-asn1_node _asn1_set_value_m(asn1_node node, void *value, unsigned int len)
+asn1_node
+_asn1_set_value_m (asn1_node node, void *value, unsigned int len)
{
- if (node == NULL)
- return node;
-
- if (node->value) {
- if (node->value != node->small_value)
- free(node->value);
- node->value = NULL;
- node->value_len = 0;
- }
+ if (node == NULL)
+ return node;
- if (!len)
- return node;
+ if (node->value)
+ {
+ if (node->value != node->small_value)
+ free (node->value);
+ node->value = NULL;
+ node->value_len = 0;
+ }
- node->value = value;
- node->value_len = len;
+ if (!len)
+ return node;
- return node;
+ node->value = value;
+ node->value_len = len;
+
+ return node;
}
/******************************************************************/
@@ -283,37 +306,43 @@ asn1_node _asn1_set_value_m(asn1_node node, void *value, unsigned int len)
/* Return: pointer to the NODE_ASN element. */
/******************************************************************/
asn1_node
-_asn1_append_value(asn1_node node, const void *value, unsigned int len)
+_asn1_append_value (asn1_node node, const void *value, unsigned int len)
{
- if (node == NULL)
- return node;
- if (node->value != NULL && node->value != node->small_value) {
- /* value is allocated */
- int prev_len = node->value_len;
- node->value_len += len;
- node->value = realloc(node->value, node->value_len);
- if (node->value == NULL) {
- node->value_len = 0;
- return NULL;
- }
- memcpy(&node->value[prev_len], value, len);
-
- return node;
- } else if (node->value == node->small_value) {
- /* value is in node */
- int prev_len = node->value_len;
- node->value_len += len;
- node->value = malloc(node->value_len);
- if (node->value == NULL) {
- node->value_len = 0;
- return NULL;
- }
- memcpy(node->value, node->small_value, prev_len);
- memcpy(&node->value[prev_len], value, len);
+ if (node == NULL)
+ return node;
+ if (node->value != NULL && node->value != node->small_value)
+ {
+ /* value is allocated */
+ int prev_len = node->value_len;
+ node->value_len += len;
+ node->value = realloc (node->value, node->value_len);
+ if (node->value == NULL)
+ {
+ node->value_len = 0;
+ return NULL;
+ }
+ memcpy (&node->value[prev_len], value, len);
+
+ return node;
+ }
+ else if (node->value == node->small_value)
+ {
+ /* value is in node */
+ int prev_len = node->value_len;
+ node->value_len += len;
+ node->value = malloc (node->value_len);
+ if (node->value == NULL)
+ {
+ node->value_len = 0;
+ return NULL;
+ }
+ memcpy (node->value, node->small_value, prev_len);
+ memcpy (&node->value[prev_len], value, len);
- return node;
- } else /* node->value == NULL */
- return _asn1_set_value(node, value, len);
+ return node;
+ }
+ else /* node->value == NULL */
+ return _asn1_set_value (node, value, len);
}
/******************************************************************/
@@ -326,23 +355,25 @@ _asn1_append_value(asn1_node node, const void *value, unsigned int len)
/* to set. */
/* Return: pointer to the NODE_ASN element. */
/******************************************************************/
-asn1_node _asn1_set_name(asn1_node node, const char *name)
+asn1_node
+_asn1_set_name (asn1_node node, const char *name)
{
- unsigned int nsize;
+ unsigned int nsize;
- if (node == NULL)
- return node;
+ if (node == NULL)
+ return node;
- if (name == NULL) {
- node->name[0] = 0;
- node->name_hash = hash_pjw_bare(node->name, 0);
- return node;
- }
+ if (name == NULL)
+ {
+ node->name[0] = 0;
+ node->name_hash = hash_pjw_bare (node->name, 0);
+ return node;
+ }
- nsize = _asn1_str_cpy(node->name, sizeof(node->name), name);
- node->name_hash = hash_pjw_bare(node->name, nsize);
+ nsize = _asn1_str_cpy (node->name, sizeof (node->name), name);
+ node->name_hash = hash_pjw_bare (node->name, nsize);
- return node;
+ return node;
}
/******************************************************************/
@@ -353,21 +384,23 @@ asn1_node _asn1_set_name(asn1_node node, const char *name)
/* src: a source element pointer. */
/* Return: pointer to the NODE_ASN element. */
/******************************************************************/
-asn1_node _asn1_cpy_name(asn1_node dst, asn1_node src)
+asn1_node
+_asn1_cpy_name (asn1_node dst, asn1_node src)
{
- if (dst == NULL)
- return dst;
+ if (dst == NULL)
+ return dst;
- if (src == NULL) {
- dst->name[0] = 0;
- dst->name_hash = hash_pjw_bare(dst->name, 0);
- return dst;
- }
+ if (src == NULL)
+ {
+ dst->name[0] = 0;
+ dst->name_hash = hash_pjw_bare (dst->name, 0);
+ return dst;
+ }
- _asn1_str_cpy(dst->name, sizeof(dst->name), src->name);
- dst->name_hash = src->name_hash;
+ _asn1_str_cpy (dst->name, sizeof (dst->name), src->name);
+ dst->name_hash = src->name_hash;
- return dst;
+ return dst;
}
/******************************************************************/
@@ -379,14 +412,15 @@ asn1_node _asn1_cpy_name(asn1_node dst, asn1_node src)
/* by NODE. */
/* Return: pointer to *NODE. */
/******************************************************************/
-asn1_node _asn1_set_right(asn1_node node, asn1_node right)
+asn1_node
+_asn1_set_right (asn1_node node, asn1_node right)
{
- if (node == NULL)
- return node;
- node->right = right;
- if (right)
- right->left = node;
- return node;
+ if (node == NULL)
+ return node;
+ node->right = right;
+ if (right)
+ right->left = node;
+ return node;
}
@@ -397,16 +431,17 @@ asn1_node _asn1_set_right(asn1_node node, asn1_node right)
/* node: starting element pointer. */
/* Return: pointer to the last element along the right chain. */
/******************************************************************/
-asn1_node _asn1_get_last_right(asn1_node node)
+asn1_node
+_asn1_get_last_right (asn1_node node)
{
- asn1_node p;
-
- if (node == NULL)
- return NULL;
- p = node;
- while (p->right)
- p = p->right;
- return p;
+ asn1_node p;
+
+ if (node == NULL)
+ return NULL;
+ p = node;
+ while (p->right)
+ p = p->right;
+ return p;
}
/******************************************************************/
@@ -415,15 +450,20 @@ asn1_node _asn1_get_last_right(asn1_node node)
/* element (not the elements pointed by it). */
/* Parameters: */
/* node: NODE_ASN element pointer. */
+/* flags: ASN1_DELETE_FLAG_* */
/******************************************************************/
-void _asn1_remove_node(asn1_node node)
+void
+_asn1_remove_node (asn1_node node, unsigned int flags)
{
- if (node == NULL)
- return;
+ if (node == NULL)
+ return;
+
+ if (flags & ASN1_DELETE_FLAG_ZEROIZE)
+ memset(node->value, 0, node->value_len);
- if (node->value != NULL && node->value != node->small_value)
- free(node->value);
- free(node);
+ if (node->value != NULL && node->value != node->small_value)
+ free (node->value);
+ free (node);
}
/******************************************************************/
@@ -433,19 +473,20 @@ void _asn1_remove_node(asn1_node node)
/* node: NODE_ASN element pointer. */
/* Return: Null if not found. */
/******************************************************************/
-asn1_node _asn1_find_up(asn1_node node)
+asn1_node
+_asn1_find_up (asn1_node node)
{
- asn1_node p;
+ asn1_node p;
- if (node == NULL)
- return NULL;
+ if (node == NULL)
+ return NULL;
- p = node;
+ p = node;
- while ((p->left != NULL) && (p->left->right == p))
- p = p->left;
+ while ((p->left != NULL) && (p->left->right == p))
+ p = p->left;
- return p->left;
+ return p->left;
}
/******************************************************************/
@@ -453,15 +494,17 @@ asn1_node _asn1_find_up(asn1_node node)
/* Description: deletes the list elements (not the elements */
/* pointed by them). */
/******************************************************************/
-void _asn1_delete_list(void)
+void
+_asn1_delete_list (void)
{
- list_type *listElement;
-
- while (firstElement) {
- listElement = firstElement;
- firstElement = firstElement->next;
- free(listElement);
- }
+ list_type *listElement;
+
+ while (firstElement)
+ {
+ listElement = firstElement;
+ firstElement = firstElement->next;
+ free (listElement);
+ }
}
/******************************************************************/
@@ -469,46 +512,52 @@ void _asn1_delete_list(void)
/* Description: deletes the list elements and the elements */
/* pointed by them. */
/******************************************************************/
-void _asn1_delete_list_and_nodes(void)
+void
+_asn1_delete_list_and_nodes (void)
{
- list_type *listElement;
-
- while (firstElement) {
- listElement = firstElement;
- firstElement = firstElement->next;
- _asn1_remove_node(listElement->node);
- free(listElement);
- }
+ list_type *listElement;
+
+ while (firstElement)
+ {
+ listElement = firstElement;
+ firstElement = firstElement->next;
+ _asn1_remove_node (listElement->node, 0);
+ free (listElement);
+ }
}
-char *_asn1_ltostr(long v, char *str)
+char *
+_asn1_ltostr (long v, char *str)
{
- long d, r;
- char temp[20];
- int count, k, start;
-
- if (v < 0) {
- str[0] = '-';
- start = 1;
- v = -v;
- } else
- start = 0;
-
- count = 0;
- do {
- d = v / 10;
- r = v - d * 10;
- temp[start + count] = '0' + (char) r;
- count++;
- v = d;
- }
- while (v);
-
- for (k = 0; k < count; k++)
- str[k + start] = temp[start + count - k - 1];
- str[count + start] = 0;
- return str;
+ long d, r;
+ char temp[20];
+ int count, k, start;
+
+ if (v < 0)
+ {
+ str[0] = '-';
+ start = 1;
+ v = -v;
+ }
+ else
+ start = 0;
+
+ count = 0;
+ do
+ {
+ d = v / 10;
+ r = v - d * 10;
+ temp[start + count] = '0' + (char) r;
+ count++;
+ v = d;
+ }
+ while (v);
+
+ for (k = 0; k < count; k++)
+ str[k + start] = temp[start + count - k - 1];
+ str[count + start] = 0;
+ return str;
}
@@ -522,52 +571,62 @@ char *_asn1_ltostr(long v, char *str)
/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
/* otherwise ASN1_SUCCESS */
/******************************************************************/
-int _asn1_change_integer_value(asn1_node node)
+int
+_asn1_change_integer_value (asn1_node node)
{
- asn1_node p;
- unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
- unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1];
- int len;
-
- if (node == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
-
- p = node;
- while (p) {
- if ((type_field(p->type) == ASN1_ETYPE_INTEGER)
- && (p->type & CONST_ASSIGN)) {
- if (p->value) {
- _asn1_convert_integer(p->value, val,
- sizeof(val), &len);
- asn1_octet_der(val, len, val2, &len);
- _asn1_set_value(p, val2, len);
- }
- }
+ asn1_node p;
+ unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
+ unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1];
+ int len;
+
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p = node;
+ while (p)
+ {
+ if ((type_field (p->type) == ASN1_ETYPE_INTEGER)
+ && (p->type & CONST_ASSIGN))
+ {
+ if (p->value)
+ {
+ _asn1_convert_integer (p->value, val, sizeof (val), &len);
+ asn1_octet_der (val, len, val2, &len);
+ _asn1_set_value (p, val2, len);
+ }
+ }
- if (p->down) {
- p = p->down;
- } else {
- if (p == node)
- p = NULL;
- else if (p->right)
- p = p->right;
- else {
- while (1) {
- p = _asn1_find_up(p);
- if (p == node) {
- p = NULL;
- break;
- }
- if (p->right) {
- p = p->right;
- break;
- }
- }
- }
+ if (p->down)
+ {
+ p = p->down;
+ }
+ else
+ {
+ if (p == node)
+ p = NULL;
+ else if (p->right)
+ p = p->right;
+ else
+ {
+ while (1)
+ {
+ p = _asn1_find_up (p);
+ if (p == node)
+ {
+ p = NULL;
+ break;
+ }
+ if (p->right)
+ {
+ p = p->right;
+ break;
+ }
}
+ }
}
+ }
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
@@ -580,217 +639,178 @@ int _asn1_change_integer_value(asn1_node node)
/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
/* otherwise ASN1_SUCCESS */
/******************************************************************/
-int _asn1_expand_object_id(asn1_node node)
+int
+_asn1_expand_object_id (asn1_node node)
{
- asn1_node p, p2, p3, p4, p5;
- char name_root[ASN1_MAX_NAME_SIZE],
- name2[2 * ASN1_MAX_NAME_SIZE + 1];
- int move, tlen;
-
- if (node == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
-
- _asn1_str_cpy(name_root, sizeof(name_root), node->name);
-
- p = node;
- move = DOWN;
-
- while (!((p == node) && (move == UP))) {
- if (move != UP) {
- if ((type_field(p->type) == ASN1_ETYPE_OBJECT_ID)
- && (p->type & CONST_ASSIGN)) {
- p2 = p->down;
- if (p2
- && (type_field(p2->type) ==
- ASN1_ETYPE_CONSTANT)) {
- if (p2->value
- && !isdigit(p2->value[0])) {
- _asn1_str_cpy(name2,
- sizeof
- (name2),
- name_root);
- _asn1_str_cat(name2,
- sizeof
- (name2),
- ".");
- _asn1_str_cat(name2,
- sizeof
- (name2),
- (char *) p2->
- value);
- p3 = asn1_find_node(node,
- name2);
- if (!p3
- ||
- (type_field(p3->type)
- !=
- ASN1_ETYPE_OBJECT_ID)
- || !(p3->
- type &
- CONST_ASSIGN))
- return
- ASN1_ELEMENT_NOT_FOUND;
- _asn1_set_down(p,
- p2->right);
- _asn1_remove_node(p2);
- p2 = p;
- p4 = p3->down;
- while (p4) {
- if (type_field
- (p4->type) ==
- ASN1_ETYPE_CONSTANT)
- {
- p5 = _asn1_add_single_node(ASN1_ETYPE_CONSTANT);
- _asn1_set_name
- (p5,
- p4->
- name);
- tlen =
- _asn1_strlen
- (p4->
- value);
- if (tlen >
- 0)
- _asn1_set_value
- (p5,
- p4->
- value,
- tlen
- +
- 1);
- if (p2 ==
- p) {
- _asn1_set_right
- (p5,
- p->
- down);
- _asn1_set_down
- (p,
- p5);
- } else {
- _asn1_set_right
- (p5,
- p2->
- right);
- _asn1_set_right
- (p2,
- p5);
- }
- p2 = p5;
- }
- p4 = p4->right;
- }
- move = DOWN;
- continue;
- }
+ asn1_node p, p2, p3, p4, p5;
+ char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1];
+ int move, tlen;
+
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ _asn1_str_cpy (name_root, sizeof (name_root), node->name);
+
+ p = node;
+ move = DOWN;
+
+ while (!((p == node) && (move == UP)))
+ {
+ if (move != UP)
+ {
+ if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID)
+ && (p->type & CONST_ASSIGN))
+ {
+ p2 = p->down;
+ if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT))
+ {
+ if (p2->value && !isdigit (p2->value[0]))
+ {
+ _asn1_str_cpy (name2, sizeof (name2), name_root);
+ _asn1_str_cat (name2, sizeof (name2), ".");
+ _asn1_str_cat (name2, sizeof (name2),
+ (char *) p2->value);
+ p3 = asn1_find_node (node, name2);
+ if (!p3
+ || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID)
+ || !(p3->type & CONST_ASSIGN))
+ return ASN1_ELEMENT_NOT_FOUND;
+ _asn1_set_down (p, p2->right);
+ _asn1_remove_node (p2, 0);
+ p2 = p;
+ p4 = p3->down;
+ while (p4)
+ {
+ if (type_field (p4->type) == ASN1_ETYPE_CONSTANT)
+ {
+ p5 =
+ _asn1_add_single_node (ASN1_ETYPE_CONSTANT);
+ _asn1_set_name (p5, p4->name);
+ tlen = _asn1_strlen (p4->value);
+ if (tlen > 0)
+ _asn1_set_value (p5, p4->value, tlen + 1);
+ if (p2 == p)
+ {
+ _asn1_set_right (p5, p->down);
+ _asn1_set_down (p, p5);
+ }
+ else
+ {
+ _asn1_set_right (p5, p2->right);
+ _asn1_set_right (p2, p5);
}
+ p2 = p5;
+ }
+ p4 = p4->right;
}
- move = DOWN;
- } else
- move = RIGHT;
-
- if (move == DOWN) {
- if (p->down)
- p = p->down;
- else
- move = RIGHT;
+ move = DOWN;
+ continue;
+ }
}
+ }
+ move = DOWN;
+ }
+ else
+ move = RIGHT;
+
+ if (move == DOWN)
+ {
+ if (p->down)
+ p = p->down;
+ else
+ move = RIGHT;
+ }
- if (p == node) {
- move = UP;
- continue;
- }
+ if (p == node)
+ {
+ move = UP;
+ continue;
+ }
- if (move == RIGHT) {
- if (p->right)
- p = p->right;
- else
- move = UP;
- }
- if (move == UP)
- p = _asn1_find_up(p);
+ if (move == RIGHT)
+ {
+ if (p->right)
+ p = p->right;
+ else
+ move = UP;
}
+ if (move == UP)
+ p = _asn1_find_up (p);
+ }
/*******************************/
- /* expand DEFAULT */
+ /* expand DEFAULT */
/*******************************/
- p = node;
- move = DOWN;
-
- while (!((p == node) && (move == UP))) {
- if (move != UP) {
- if ((type_field(p->type) == ASN1_ETYPE_OBJECT_ID)
- && (p->type & CONST_DEFAULT)) {
- p2 = p->down;
- if (p2
- && (type_field(p2->type) ==
- ASN1_ETYPE_DEFAULT)) {
- _asn1_str_cpy(name2, sizeof(name2),
- name_root);
- _asn1_str_cat(name2, sizeof(name2),
- ".");
- _asn1_str_cat(name2, sizeof(name2),
- (char *) p2->value);
- p3 = asn1_find_node(node, name2);
- if (!p3
- || (type_field(p3->type) !=
- ASN1_ETYPE_OBJECT_ID)
- || !(p3->type & CONST_ASSIGN))
- return
- ASN1_ELEMENT_NOT_FOUND;
- p4 = p3->down;
- name2[0] = 0;
- while (p4) {
- if (type_field(p4->type) ==
- ASN1_ETYPE_CONSTANT) {
- if (name2[0])
- _asn1_str_cat
- (name2,
- sizeof
- (name2),
- ".");
- _asn1_str_cat
- (name2,
- sizeof(name2),
- (char *) p4->
- value);
- }
- p4 = p4->right;
- }
- tlen = strlen(name2);
- if (tlen > 0)
- _asn1_set_value(p2, name2,
- tlen + 1);
- }
+ p = node;
+ move = DOWN;
+
+ while (!((p == node) && (move == UP)))
+ {
+ if (move != UP)
+ {
+ if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
+ (p->type & CONST_DEFAULT))
+ {
+ p2 = p->down;
+ if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT))
+ {
+ _asn1_str_cpy (name2, sizeof (name2), name_root);
+ _asn1_str_cat (name2, sizeof (name2), ".");
+ _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
+ p3 = asn1_find_node (node, name2);
+ if (!p3 || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID)
+ || !(p3->type & CONST_ASSIGN))
+ return ASN1_ELEMENT_NOT_FOUND;
+ p4 = p3->down;
+ name2[0] = 0;
+ while (p4)
+ {
+ if (type_field (p4->type) == ASN1_ETYPE_CONSTANT)
+ {
+ if (name2[0])
+ _asn1_str_cat (name2, sizeof (name2), ".");
+ _asn1_str_cat (name2, sizeof (name2),
+ (char *) p4->value);
}
- move = DOWN;
- } else
- move = RIGHT;
-
- if (move == DOWN) {
- if (p->down)
- p = p->down;
- else
- move = RIGHT;
+ p4 = p4->right;
+ }
+ tlen = strlen (name2);
+ if (tlen > 0)
+ _asn1_set_value (p2, name2, tlen + 1);
}
+ }
+ move = DOWN;
+ }
+ else
+ move = RIGHT;
+
+ if (move == DOWN)
+ {
+ if (p->down)
+ p = p->down;
+ else
+ move = RIGHT;
+ }
- if (p == node) {
- move = UP;
- continue;
- }
+ if (p == node)
+ {
+ move = UP;
+ continue;
+ }
- if (move == RIGHT) {
- if (p->right)
- p = p->right;
- else
- move = UP;
- }
- if (move == UP)
- p = _asn1_find_up(p);
+ if (move == RIGHT)
+ {
+ if (p->right)
+ p = p->right;
+ else
+ move = UP;
}
+ if (move == UP)
+ p = _asn1_find_up (p);
+ }
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
@@ -804,57 +824,63 @@ int _asn1_expand_object_id(asn1_node node)
/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
/* otherwise ASN1_SUCCESS */
/******************************************************************/
-int _asn1_type_set_config(asn1_node node)
+int
+_asn1_type_set_config (asn1_node node)
{
- asn1_node p, p2;
- int move;
-
- if (node == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
-
- p = node;
- move = DOWN;
-
- while (!((p == node) && (move == UP))) {
- if (move != UP) {
- if (type_field(p->type) == ASN1_ETYPE_SET) {
- p2 = p->down;
- while (p2) {
- if (type_field(p2->type) !=
- ASN1_ETYPE_TAG)
- p2->type |=
- CONST_SET |
- CONST_NOT_USED;
- p2 = p2->right;
- }
- }
- move = DOWN;
- } else
- move = RIGHT;
-
- if (move == DOWN) {
- if (p->down)
- p = p->down;
- else
- move = RIGHT;
+ asn1_node p, p2;
+ int move;
+
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p = node;
+ move = DOWN;
+
+ while (!((p == node) && (move == UP)))
+ {
+ if (move != UP)
+ {
+ if (type_field (p->type) == ASN1_ETYPE_SET)
+ {
+ p2 = p->down;
+ while (p2)
+ {
+ if (type_field (p2->type) != ASN1_ETYPE_TAG)
+ p2->type |= CONST_SET | CONST_NOT_USED;
+ p2 = p2->right;
}
+ }
+ move = DOWN;
+ }
+ else
+ move = RIGHT;
+
+ if (move == DOWN)
+ {
+ if (p->down)
+ p = p->down;
+ else
+ move = RIGHT;
+ }
- if (p == node) {
- move = UP;
- continue;
- }
+ if (p == node)
+ {
+ move = UP;
+ continue;
+ }
- if (move == RIGHT) {
- if (p->right)
- p = p->right;
- else
- move = UP;
- }
- if (move == UP)
- p = _asn1_find_up(p);
+ if (move == RIGHT)
+ {
+ if (p->right)
+ p = p->right;
+ else
+ move = UP;
}
+ if (move == UP)
+ p = _asn1_find_up (p);
+ }
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
@@ -871,105 +897,99 @@ int _asn1_type_set_config(asn1_node node)
/* ASN1_IDENTIFIER_NOT_FOUND if an identifier is not defined, */
/* otherwise ASN1_SUCCESS */
/******************************************************************/
-int _asn1_check_identifier(asn1_node node)
+int
+_asn1_check_identifier (asn1_node node)
{
- asn1_node p, p2;
- char name2[ASN1_MAX_NAME_SIZE * 2 + 2];
-
- if (node == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
-
- p = node;
- while (p) {
- if (type_field(p->type) == ASN1_ETYPE_IDENTIFIER) {
- _asn1_str_cpy(name2, sizeof(name2), node->name);
- _asn1_str_cat(name2, sizeof(name2), ".");
- _asn1_str_cat(name2, sizeof(name2),
- (char *) p->value);
- p2 = asn1_find_node(node, name2);
- if (p2 == NULL) {
- if (p->value)
- _asn1_strcpy
- (_asn1_identifierMissing,
- p->value);
- else
- _asn1_strcpy
- (_asn1_identifierMissing,
- "(null)");
- return ASN1_IDENTIFIER_NOT_FOUND;
- }
- } else if ((type_field(p->type) == ASN1_ETYPE_OBJECT_ID) &&
- (p->type & CONST_DEFAULT)) {
- p2 = p->down;
- if (p2
- && (type_field(p2->type) ==
- ASN1_ETYPE_DEFAULT)) {
- _asn1_str_cpy(name2, sizeof(name2),
- node->name);
- _asn1_str_cat(name2, sizeof(name2), ".");
- _asn1_str_cat(name2, sizeof(name2),
- (char *) p2->value);
- _asn1_strcpy(_asn1_identifierMissing,
- p2->value);
- p2 = asn1_find_node(node, name2);
- if (!p2
- || (type_field(p2->type) !=
- ASN1_ETYPE_OBJECT_ID)
- || !(p2->type & CONST_ASSIGN))
- return ASN1_IDENTIFIER_NOT_FOUND;
- else
- _asn1_identifierMissing[0] = 0;
- }
- } else if ((type_field(p->type) == ASN1_ETYPE_OBJECT_ID) &&
- (p->type & CONST_ASSIGN)) {
- p2 = p->down;
- if (p2
- && (type_field(p2->type) ==
- ASN1_ETYPE_CONSTANT)) {
- if (p2->value && !isdigit(p2->value[0])) {
- _asn1_str_cpy(name2, sizeof(name2),
- node->name);
- _asn1_str_cat(name2, sizeof(name2),
- ".");
- _asn1_str_cat(name2, sizeof(name2),
- (char *) p2->value);
- _asn1_strcpy
- (_asn1_identifierMissing,
- p2->value);
- p2 = asn1_find_node(node, name2);
- if (!p2
- || (type_field(p2->type) !=
- ASN1_ETYPE_OBJECT_ID)
- || !(p2->type & CONST_ASSIGN))
- return
- ASN1_IDENTIFIER_NOT_FOUND;
- else
- _asn1_identifierMissing[0]
- = 0;
- }
- }
+ asn1_node p, p2;
+ char name2[ASN1_MAX_NAME_SIZE * 2 + 2];
+
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p = node;
+ while (p)
+ {
+ if (p->value && type_field (p->type) == ASN1_ETYPE_IDENTIFIER)
+ {
+ _asn1_str_cpy (name2, sizeof (name2), node->name);
+ _asn1_str_cat (name2, sizeof (name2), ".");
+ _asn1_str_cat (name2, sizeof (name2), (char *) p->value);
+ p2 = asn1_find_node (node, name2);
+ if (p2 == NULL)
+ {
+ if (p->value)
+ _asn1_strcpy (_asn1_identifierMissing, p->value);
+ else
+ _asn1_strcpy (_asn1_identifierMissing, "(null)");
+ return ASN1_IDENTIFIER_NOT_FOUND;
+ }
+ }
+ else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
+ (p->type & CONST_DEFAULT))
+ {
+ p2 = p->down;
+ if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT))
+ {
+ _asn1_str_cpy (name2, sizeof (name2), node->name);
+ _asn1_str_cat (name2, sizeof (name2), ".");
+ _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
+ _asn1_strcpy (_asn1_identifierMissing, p2->value);
+ p2 = asn1_find_node (node, name2);
+ if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID) ||
+ !(p2->type & CONST_ASSIGN))
+ return ASN1_IDENTIFIER_NOT_FOUND;
+ else
+ _asn1_identifierMissing[0] = 0;
+ }
+ }
+ else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
+ (p->type & CONST_ASSIGN))
+ {
+ p2 = p->down;
+ if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT))
+ {
+ if (p2->value && !isdigit (p2->value[0]))
+ {
+ _asn1_str_cpy (name2, sizeof (name2), node->name);
+ _asn1_str_cat (name2, sizeof (name2), ".");
+ _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
+ _asn1_strcpy (_asn1_identifierMissing, p2->value);
+ p2 = asn1_find_node (node, name2);
+ if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID)
+ || !(p2->type & CONST_ASSIGN))
+ return ASN1_IDENTIFIER_NOT_FOUND;
+ else
+ _asn1_identifierMissing[0] = 0;
}
+ }
+ }
- if (p->down) {
- p = p->down;
- } else if (p->right)
- p = p->right;
- else {
- while (1) {
- p = _asn1_find_up(p);
- if (p == node) {
- p = NULL;
- break;
- }
- if (p->right) {
- p = p->right;
- break;
- }
- }
+ if (p->down)
+ {
+ p = p->down;
+ }
+ else if (p->right)
+ p = p->right;
+ else
+ {
+ while (1)
+ {
+ p = _asn1_find_up (p);
+ if (p == node)
+ {
+ p = NULL;
+ break;
}
+ if (p->right)
+ {
+ p = p->right;
+ break;
+ }
+ }
}
+ }
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
@@ -984,43 +1004,50 @@ int _asn1_check_identifier(asn1_node node)
/* a DEFINITIONS element, */
/* otherwise ASN1_SUCCESS */
/******************************************************************/
-int _asn1_set_default_tag(asn1_node node)
+int
+_asn1_set_default_tag (asn1_node node)
{
- asn1_node p;
-
- if ((node == NULL)
- || (type_field(node->type) != ASN1_ETYPE_DEFINITIONS))
- return ASN1_ELEMENT_NOT_FOUND;
-
- p = node;
- while (p) {
- if ((type_field(p->type) == ASN1_ETYPE_TAG) &&
- !(p->type & CONST_EXPLICIT)
- && !(p->type & CONST_IMPLICIT)) {
- if (node->type & CONST_EXPLICIT)
- p->type |= CONST_EXPLICIT;
- else
- p->type |= CONST_IMPLICIT;
- }
+ asn1_node p;
+
+ if ((node == NULL) || (type_field (node->type) != ASN1_ETYPE_DEFINITIONS))
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p = node;
+ while (p)
+ {
+ if ((type_field (p->type) == ASN1_ETYPE_TAG) &&
+ !(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT))
+ {
+ if (node->type & CONST_EXPLICIT)
+ p->type |= CONST_EXPLICIT;
+ else
+ p->type |= CONST_IMPLICIT;
+ }
- if (p->down) {
- p = p->down;
- } else if (p->right)
- p = p->right;
- else {
- while (1) {
- p = _asn1_find_up(p);
- if (p == node) {
- p = NULL;
- break;
- }
- if (p->right) {
- p = p->right;
- break;
- }
- }
+ if (p->down)
+ {
+ p = p->down;
+ }
+ else if (p->right)
+ p = p->right;
+ else
+ {
+ while (1)
+ {
+ p = _asn1_find_up (p);
+ if (p == node)
+ {
+ p = NULL;
+ break;
+ }
+ if (p->right)
+ {
+ p = p->right;
+ break;
}
+ }
}
+ }
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
diff --git a/lib/minitasn1/parser_aux.h b/lib/minitasn1/parser_aux.h
index 8b5e6c79bc..bf378527fe 100644
--- a/lib/minitasn1/parser_aux.h
+++ b/lib/minitasn1/parser_aux.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2000-2014 Free Software Foundation, Inc.
*
* This file is part of LIBTASN1.
*
@@ -27,46 +27,46 @@
/***************************************/
/* Functions used by ASN.1 parser */
/***************************************/
-asn1_node _asn1_add_static_node(unsigned int type);
+asn1_node _asn1_add_static_node (unsigned int type);
asn1_node
-_asn1_set_value(asn1_node node, const void *value, unsigned int len);
+_asn1_set_value (asn1_node node, const void *value, unsigned int len);
-asn1_node _asn1_set_value_m(asn1_node node, void *value, unsigned int len);
+asn1_node _asn1_set_value_m (asn1_node node, void *value, unsigned int len);
asn1_node
-_asn1_set_value_lv(asn1_node node, const void *value, unsigned int len);
+_asn1_set_value_lv (asn1_node node, const void *value, unsigned int len);
asn1_node
-_asn1_append_value(asn1_node node, const void *value, unsigned int len);
+_asn1_append_value (asn1_node node, const void *value, unsigned int len);
-asn1_node _asn1_set_name(asn1_node node, const char *name);
+asn1_node _asn1_set_name (asn1_node node, const char *name);
-asn1_node _asn1_cpy_name(asn1_node dst, asn1_node src);
+asn1_node _asn1_cpy_name (asn1_node dst, asn1_node src);
-asn1_node _asn1_set_right(asn1_node node, asn1_node right);
+asn1_node _asn1_set_right (asn1_node node, asn1_node right);
-asn1_node _asn1_get_last_right(asn1_node node);
+asn1_node _asn1_get_last_right (asn1_node node);
-void _asn1_remove_node(asn1_node node);
+void _asn1_remove_node (asn1_node node, unsigned int flags);
-void _asn1_delete_list(void);
+void _asn1_delete_list (void);
-void _asn1_delete_list_and_nodes(void);
+void _asn1_delete_list_and_nodes (void);
-char *_asn1_ltostr(long v, char *str);
+char *_asn1_ltostr (long v, char *str);
-asn1_node _asn1_find_up(asn1_node node);
+asn1_node _asn1_find_up (asn1_node node);
-int _asn1_change_integer_value(asn1_node node);
+int _asn1_change_integer_value (asn1_node node);
-int _asn1_expand_object_id(asn1_node node);
+int _asn1_expand_object_id (asn1_node node);
-int _asn1_type_set_config(asn1_node node);
+int _asn1_type_set_config (asn1_node node);
-int _asn1_check_identifier(asn1_node node);
+int _asn1_check_identifier (asn1_node node);
-int _asn1_set_default_tag(asn1_node node);
+int _asn1_set_default_tag (asn1_node node);
/******************************************************************/
/* Function : _asn1_get_right */
@@ -76,11 +76,12 @@ int _asn1_set_default_tag(asn1_node node);
/* node: NODE_ASN element pointer. */
/* Return: field RIGHT of NODE. */
/******************************************************************/
-inline static asn1_node _asn1_get_right(asn1_node node)
+inline static asn1_node
+_asn1_get_right (asn1_node node)
{
- if (node == NULL)
- return NULL;
- return node->right;
+ if (node == NULL)
+ return NULL;
+ return node->right;
}
/******************************************************************/
@@ -92,14 +93,15 @@ inline static asn1_node _asn1_get_right(asn1_node node)
/* by NODE. */
/* Return: pointer to *NODE. */
/******************************************************************/
-inline static asn1_node _asn1_set_down(asn1_node node, asn1_node down)
+inline static asn1_node
+_asn1_set_down (asn1_node node, asn1_node down)
{
- if (node == NULL)
- return node;
- node->down = down;
- if (down)
- down->left = node;
- return node;
+ if (node == NULL)
+ return node;
+ node->down = down;
+ if (down)
+ down->left = node;
+ return node;
}
/******************************************************************/
@@ -110,11 +112,12 @@ inline static asn1_node _asn1_set_down(asn1_node node, asn1_node down)
/* node: NODE_ASN element pointer. */
/* Return: field DOWN of NODE. */
/******************************************************************/
-inline static asn1_node _asn1_get_down(asn1_node node)
+inline static asn1_node
+_asn1_get_down (asn1_node node)
{
- if (node == NULL)
- return NULL;
- return node->down;
+ if (node == NULL)
+ return NULL;
+ return node->down;
}
/******************************************************************/
@@ -124,11 +127,12 @@ inline static asn1_node _asn1_get_down(asn1_node node)
/* node: NODE_ASN element pointer. */
/* Return: a null terminated string. */
/******************************************************************/
-inline static char *_asn1_get_name(asn1_node node)
+inline static char *
+_asn1_get_name (asn1_node node)
{
- if (node == NULL)
- return NULL;
- return node->name;
+ if (node == NULL)
+ return NULL;
+ return node->name;
}
/******************************************************************/
@@ -142,12 +146,13 @@ inline static char *_asn1_get_name(asn1_node node)
/* value of field TYPE. */
/* Return: NODE pointer. */
/******************************************************************/
-inline static asn1_node _asn1_mod_type(asn1_node node, unsigned int value)
+inline static asn1_node
+_asn1_mod_type (asn1_node node, unsigned int value)
{
- if (node == NULL)
- return node;
- node->type |= value;
- return node;
+ if (node == NULL)
+ return node;
+ node->type |= value;
+ return node;
}
#endif
diff --git a/lib/minitasn1/structure.c b/lib/minitasn1/structure.c
index 567c5cec67..27fbfe3a22 100644
--- a/lib/minitasn1/structure.c
+++ b/lib/minitasn1/structure.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2002-2014 Free Software Foundation, Inc.
*
* This file is part of LIBTASN1.
*
@@ -44,17 +44,18 @@ extern char _asn1_identifierMissing[];
/* and CONST_ constants). */
/* Return: pointer to the new element. */
/******************************************************/
-asn1_node _asn1_add_single_node(unsigned int type)
+asn1_node
+_asn1_add_single_node (unsigned int type)
{
- asn1_node punt;
+ asn1_node punt;
- punt = calloc(1, sizeof(struct asn1_node_st));
- if (punt == NULL)
- return NULL;
+ punt = calloc (1, sizeof (struct asn1_node_st));
+ if (punt == NULL)
+ return NULL;
- punt->type = type;
+ punt->type = type;
- return punt;
+ return punt;
}
@@ -66,84 +67,93 @@ asn1_node _asn1_add_single_node(unsigned int type)
/* node: NODE_ASN element pointer. */
/* Return: NULL if not found. */
/******************************************************************/
-asn1_node _asn1_find_left(asn1_node node)
+asn1_node
+_asn1_find_left (asn1_node node)
{
- if ((node == NULL) || (node->left == NULL)
- || (node->left->down == node))
- return NULL;
+ if ((node == NULL) || (node->left == NULL) || (node->left->down == node))
+ return NULL;
- return node->left;
+ return node->left;
}
int
-_asn1_create_static_structure(asn1_node pointer, char *output_file_name,
- char *vector_name)
+_asn1_create_static_structure (asn1_node pointer, char *output_file_name,
+ char *vector_name)
{
- FILE *file;
- asn1_node p;
- unsigned long t;
+ FILE *file;
+ asn1_node p;
+ unsigned long t;
- file = fopen(output_file_name, "w");
+ file = fopen (output_file_name, "w");
- if (file == NULL)
- return ASN1_FILE_NOT_FOUND;
+ if (file == NULL)
+ return ASN1_FILE_NOT_FOUND;
- fprintf(file, "#if HAVE_CONFIG_H\n");
- fprintf(file, "# include \"config.h\"\n");
- fprintf(file, "#endif\n\n");
+ fprintf (file, "#if HAVE_CONFIG_H\n");
+ fprintf (file, "# include \"config.h\"\n");
+ fprintf (file, "#endif\n\n");
- fprintf(file, "#include <libtasn1.h>\n\n");
+ fprintf (file, "#include <libtasn1.h>\n\n");
- fprintf(file, "const asn1_static_node %s[] = {\n", vector_name);
+ fprintf (file, "const asn1_static_node %s[] = {\n", vector_name);
- p = pointer;
+ p = pointer;
- while (p) {
- fprintf(file, " { ");
+ while (p)
+ {
+ fprintf (file, " { ");
- if (p->name[0] != 0)
- fprintf(file, "\"%s\", ", p->name);
- else
- fprintf(file, "NULL, ");
+ if (p->name[0] != 0)
+ fprintf (file, "\"%s\", ", p->name);
+ else
+ fprintf (file, "NULL, ");
- t = p->type;
- if (p->down)
- t |= CONST_DOWN;
- if (p->right)
- t |= CONST_RIGHT;
+ t = p->type;
+ if (p->down)
+ t |= CONST_DOWN;
+ if (p->right)
+ t |= CONST_RIGHT;
- fprintf(file, "%lu, ", t);
+ fprintf (file, "%lu, ", t);
- if (p->value)
- fprintf(file, "\"%s\"},\n", p->value);
- else
- fprintf(file, "NULL },\n");
-
- if (p->down) {
- p = p->down;
- } else if (p->right) {
- p = p->right;
- } else {
- while (1) {
- p = _asn1_find_up(p);
- if (p == pointer) {
- p = NULL;
- break;
- }
- if (p->right) {
- p = p->right;
- break;
- }
- }
+ if (p->value)
+ fprintf (file, "\"%s\"},\n", p->value);
+ else
+ fprintf (file, "NULL },\n");
+
+ if (p->down)
+ {
+ p = p->down;
+ }
+ else if (p->right)
+ {
+ p = p->right;
+ }
+ else
+ {
+ while (1)
+ {
+ p = _asn1_find_up (p);
+ if (p == pointer)
+ {
+ p = NULL;
+ break;
+ }
+ if (p->right)
+ {
+ p = p->right;
+ break;
}
+ }
}
+ }
- fprintf(file, " { NULL, 0, NULL }\n};\n");
+ fprintf (file, " { NULL, 0, NULL }\n};\n");
- fclose(file);
+ fclose (file);
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
@@ -164,92 +174,104 @@ _asn1_create_static_structure(asn1_node pointer, char *output_file_name,
* %ASN1_ARRAY_ERROR if the array pointed by @array is wrong.
**/
int
-asn1_array2tree(const asn1_static_node * array, asn1_node * definitions,
- char *errorDescription)
+asn1_array2tree (const asn1_static_node * array, asn1_node * definitions,
+ char *errorDescription)
{
- asn1_node p, p_last = NULL;
- unsigned long k;
- int move;
- int result;
- unsigned int type;
-
-
- if (*definitions != NULL)
- return ASN1_ELEMENT_NOT_EMPTY;
-
- move = UP;
-
- k = 0;
- while (array[k].value || array[k].type || array[k].name) {
- type = convert_old_type(array[k].type);
-
- p = _asn1_add_static_node(type & (~CONST_DOWN));
- if (array[k].name)
- _asn1_set_name(p, array[k].name);
- if (array[k].value)
- _asn1_set_value(p, array[k].value,
- strlen(array[k].value) + 1);
-
- if (*definitions == NULL)
- *definitions = p;
-
- if (move == DOWN)
- _asn1_set_down(p_last, p);
- else if (move == RIGHT)
- _asn1_set_right(p_last, p);
-
- p_last = p;
-
- if (type & CONST_DOWN)
- move = DOWN;
- else if (type & CONST_RIGHT)
- move = RIGHT;
- else {
- while (1) {
- if (p_last == *definitions)
- break;
-
- p_last = _asn1_find_up(p_last);
-
- if (p_last == NULL)
- break;
-
- if (p_last->type & CONST_RIGHT) {
- p_last->type &= ~CONST_RIGHT;
- move = RIGHT;
- break;
- }
- } /* while */
- }
- k++;
- } /* while */
-
- if (p_last == *definitions) {
- result = _asn1_check_identifier(*definitions);
- if (result == ASN1_SUCCESS) {
- _asn1_change_integer_value(*definitions);
- _asn1_expand_object_id(*definitions);
- }
- } else {
- result = ASN1_ARRAY_ERROR;
- }
+ asn1_node p, p_last = NULL;
+ unsigned long k;
+ int move;
+ int result;
+ unsigned int type;
- if (errorDescription != NULL) {
- if (result == ASN1_IDENTIFIER_NOT_FOUND) {
- Estrcpy(errorDescription, ":: identifier '");
- Estrcat(errorDescription, _asn1_identifierMissing);
- Estrcat(errorDescription, "' not found");
- } else
- errorDescription[0] = 0;
- }
- if (result != ASN1_SUCCESS) {
- _asn1_delete_list_and_nodes();
- *definitions = NULL;
- } else
- _asn1_delete_list();
+ if (*definitions != NULL)
+ return ASN1_ELEMENT_NOT_EMPTY;
+
+ move = UP;
+
+ k = 0;
+ while (array[k].value || array[k].type || array[k].name)
+ {
+ type = convert_old_type (array[k].type);
+
+ p = _asn1_add_static_node (type & (~CONST_DOWN));
+ if (array[k].name)
+ _asn1_set_name (p, array[k].name);
+ if (array[k].value)
+ _asn1_set_value (p, array[k].value, strlen (array[k].value) + 1);
+
+ if (*definitions == NULL)
+ *definitions = p;
+
+ if (move == DOWN)
+ _asn1_set_down (p_last, p);
+ else if (move == RIGHT)
+ _asn1_set_right (p_last, p);
+
+ p_last = p;
- return result;
+ if (type & CONST_DOWN)
+ move = DOWN;
+ else if (type & CONST_RIGHT)
+ move = RIGHT;
+ else
+ {
+ while (1)
+ {
+ if (p_last == *definitions)
+ break;
+
+ p_last = _asn1_find_up (p_last);
+
+ if (p_last == NULL)
+ break;
+
+ if (p_last->type & CONST_RIGHT)
+ {
+ p_last->type &= ~CONST_RIGHT;
+ move = RIGHT;
+ break;
+ }
+ } /* while */
+ }
+ k++;
+ } /* while */
+
+ if (p_last == *definitions)
+ {
+ result = _asn1_check_identifier (*definitions);
+ if (result == ASN1_SUCCESS)
+ {
+ _asn1_change_integer_value (*definitions);
+ _asn1_expand_object_id (*definitions);
+ }
+ }
+ else
+ {
+ result = ASN1_ARRAY_ERROR;
+ }
+
+ if (errorDescription != NULL)
+ {
+ if (result == ASN1_IDENTIFIER_NOT_FOUND)
+ {
+ Estrcpy (errorDescription, ":: identifier '");
+ Estrcat (errorDescription, _asn1_identifierMissing);
+ Estrcat (errorDescription, "' not found");
+ }
+ else
+ errorDescription[0] = 0;
+ }
+
+ if (result != ASN1_SUCCESS)
+ {
+ _asn1_delete_list_and_nodes ();
+ *definitions = NULL;
+ }
+ else
+ _asn1_delete_list ();
+
+ return result;
}
/**
@@ -262,45 +284,72 @@ asn1_array2tree(const asn1_static_node * array, asn1_node * definitions,
* Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
* *@structure was NULL.
**/
-int asn1_delete_structure(asn1_node * structure)
+int
+asn1_delete_structure (asn1_node * structure)
{
- asn1_node p, p2, p3;
-
- if (*structure == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
-
- p = *structure;
- while (p) {
- if (p->down) {
- p = p->down;
- } else { /* no down */
- p2 = p->right;
- if (p != *structure) {
- p3 = _asn1_find_up(p);
- _asn1_set_down(p3, p2);
- _asn1_remove_node(p);
- p = p3;
- } else { /* p==root */
- p3 = _asn1_find_left(p);
- if (!p3) {
- p3 = _asn1_find_up(p);
- if (p3)
- _asn1_set_down(p3, p2);
- else {
- if (p->right)
- p->right->left =
- NULL;
- }
- } else
- _asn1_set_right(p3, p2);
- _asn1_remove_node(p);
- p = NULL;
- }
+ return asn1_delete_structure2(structure, 0);
+}
+
+/**
+ * asn1_delete_structure2:
+ * @structure: pointer to the structure that you want to delete.
+ * @flags: additional flags (see %ASN1_DELETE_FLAG)
+ *
+ * Deletes the structure *@structure. At the end, *@structure is set
+ * to NULL.
+ *
+ * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
+ * *@structure was NULL.
+ **/
+int
+asn1_delete_structure2 (asn1_node * structure, unsigned int flags)
+{
+ asn1_node p, p2, p3;
+
+ if (*structure == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p = *structure;
+ while (p)
+ {
+ if (p->down)
+ {
+ p = p->down;
+ }
+ else
+ { /* no down */
+ p2 = p->right;
+ if (p != *structure)
+ {
+ p3 = _asn1_find_up (p);
+ _asn1_set_down (p3, p2);
+ _asn1_remove_node (p, flags);
+ p = p3;
+ }
+ else
+ { /* p==root */
+ p3 = _asn1_find_left (p);
+ if (!p3)
+ {
+ p3 = _asn1_find_up (p);
+ if (p3)
+ _asn1_set_down (p3, p2);
+ else
+ {
+ if (p->right)
+ p->right->left = NULL;
+ }
}
+ else
+ _asn1_set_right (p3, p2);
+ _asn1_remove_node (p, flags);
+ p = NULL;
+ }
}
+ }
- *structure = NULL;
- return ASN1_SUCCESS;
+ *structure = NULL;
+ return ASN1_SUCCESS;
}
@@ -316,279 +365,292 @@ int asn1_delete_structure(asn1_node * structure)
* Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
* the @element_name was not found.
**/
-int asn1_delete_element(asn1_node structure, const char *element_name)
+int
+asn1_delete_element (asn1_node structure, const char *element_name)
{
- asn1_node p2, p3, source_node;
-
- source_node = asn1_find_node(structure, element_name);
-
- if (source_node == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
-
- p2 = source_node->right;
- p3 = _asn1_find_left(source_node);
- if (!p3) {
- p3 = _asn1_find_up(source_node);
- if (p3)
- _asn1_set_down(p3, p2);
- else if (source_node->right)
- source_node->right->left = NULL;
- } else
- _asn1_set_right(p3, p2);
-
- return asn1_delete_structure(&source_node);
+ asn1_node p2, p3, source_node;
+
+ source_node = asn1_find_node (structure, element_name);
+
+ if (source_node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p2 = source_node->right;
+ p3 = _asn1_find_left (source_node);
+ if (!p3)
+ {
+ p3 = _asn1_find_up (source_node);
+ if (p3)
+ _asn1_set_down (p3, p2);
+ else if (source_node->right)
+ source_node->right->left = NULL;
+ }
+ else
+ _asn1_set_right (p3, p2);
+
+ return asn1_delete_structure (&source_node);
}
-asn1_node _asn1_copy_structure3(asn1_node source_node)
+asn1_node
+_asn1_copy_structure3 (asn1_node source_node)
{
- asn1_node dest_node, p_s, p_d, p_d_prev;
- int move;
-
- if (source_node == NULL)
- return NULL;
-
- dest_node = _asn1_add_single_node(source_node->type);
-
- p_s = source_node;
- p_d = dest_node;
-
- move = DOWN;
+ asn1_node dest_node, p_s, p_d, p_d_prev;
+ int move;
+
+ if (source_node == NULL)
+ return NULL;
+
+ dest_node = _asn1_add_single_node (source_node->type);
+
+ p_s = source_node;
+ p_d = dest_node;
+
+ move = DOWN;
+
+ do
+ {
+ if (move != UP)
+ {
+ if (p_s->name[0] != 0)
+ _asn1_cpy_name (p_d, p_s);
+ if (p_s->value)
+ _asn1_set_value (p_d, p_s->value, p_s->value_len);
+ if (p_s->down)
+ {
+ p_s = p_s->down;
+ p_d_prev = p_d;
+ p_d = _asn1_add_single_node (p_s->type);
+ _asn1_set_down (p_d_prev, p_d);
+ continue;
+ }
+ }
- do {
- if (move != UP) {
- if (p_s->name[0] != 0)
- _asn1_cpy_name(p_d, p_s);
- if (p_s->value)
- _asn1_set_value(p_d, p_s->value,
- p_s->value_len);
- if (p_s->down) {
- p_s = p_s->down;
- p_d_prev = p_d;
- p_d = _asn1_add_single_node(p_s->type);
- _asn1_set_down(p_d_prev, p_d);
- continue;
- }
- }
+ if (p_s == source_node)
+ break;
- if (p_s == source_node)
- break;
-
- if (p_s->right) {
- move = RIGHT;
- p_s = p_s->right;
- p_d_prev = p_d;
- p_d = _asn1_add_single_node(p_s->type);
- _asn1_set_right(p_d_prev, p_d);
- } else {
- move = UP;
- p_s = _asn1_find_up(p_s);
- p_d = _asn1_find_up(p_d);
- }
+ if (p_s->right)
+ {
+ move = RIGHT;
+ p_s = p_s->right;
+ p_d_prev = p_d;
+ p_d = _asn1_add_single_node (p_s->type);
+ _asn1_set_right (p_d_prev, p_d);
+ }
+ else
+ {
+ move = UP;
+ p_s = _asn1_find_up (p_s);
+ p_d = _asn1_find_up (p_d);
}
- while (p_s != source_node);
+ }
+ while (p_s != source_node);
- return dest_node;
+ return dest_node;
}
static asn1_node
-_asn1_copy_structure2(asn1_node root, const char *source_name)
+_asn1_copy_structure2 (asn1_node root, const char *source_name)
{
- asn1_node source_node;
+ asn1_node source_node;
- source_node = asn1_find_node(root, source_name);
+ source_node = asn1_find_node (root, source_name);
- return _asn1_copy_structure3(source_node);
+ return _asn1_copy_structure3 (source_node);
}
-static int _asn1_type_choice_config(asn1_node node)
+static int
+_asn1_type_choice_config (asn1_node node)
{
- asn1_node p, p2, p3, p4;
- int move, tlen;
-
- if (node == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
-
- p = node;
- move = DOWN;
-
- while (!((p == node) && (move == UP))) {
- if (move != UP) {
- if ((type_field(p->type) == ASN1_ETYPE_CHOICE)
- && (p->type & CONST_TAG)) {
- p2 = p->down;
- while (p2) {
- if (type_field(p2->type) !=
- ASN1_ETYPE_TAG) {
- p2->type |= CONST_TAG;
- p3 = _asn1_find_left(p2);
- while (p3) {
- if (type_field
- (p3->type) ==
- ASN1_ETYPE_TAG)
- {
- p4 = _asn1_add_single_node(p3->type);
- tlen =
- _asn1_strlen
- (p3->
- value);
- if (tlen >
- 0)
- _asn1_set_value
- (p4,
- p3->
- value,
- tlen
- +
- 1);
- _asn1_set_right
- (p4,
- p2->
- down);
- _asn1_set_down
- (p2,
- p4);
- }
- p3 = _asn1_find_left(p3);
- }
- }
- p2 = p2->right;
- }
- p->type &= ~(CONST_TAG);
- p2 = p->down;
- while (p2) {
- p3 = p2->right;
- if (type_field(p2->type) ==
- ASN1_ETYPE_TAG)
- asn1_delete_structure(&p2);
- p2 = p3;
- }
+ asn1_node p, p2, p3, p4;
+ int move, tlen;
+
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p = node;
+ move = DOWN;
+
+ while (!((p == node) && (move == UP)))
+ {
+ if (move != UP)
+ {
+ if ((type_field (p->type) == ASN1_ETYPE_CHOICE)
+ && (p->type & CONST_TAG))
+ {
+ p2 = p->down;
+ while (p2)
+ {
+ if (type_field (p2->type) != ASN1_ETYPE_TAG)
+ {
+ p2->type |= CONST_TAG;
+ p3 = _asn1_find_left (p2);
+ while (p3)
+ {
+ if (type_field (p3->type) == ASN1_ETYPE_TAG)
+ {
+ p4 = _asn1_add_single_node (p3->type);
+ tlen = _asn1_strlen (p3->value);
+ if (tlen > 0)
+ _asn1_set_value (p4, p3->value, tlen + 1);
+ _asn1_set_right (p4, p2->down);
+ _asn1_set_down (p2, p4);
+ }
+ p3 = _asn1_find_left (p3);
}
- move = DOWN;
- } else
- move = RIGHT;
-
- if (move == DOWN) {
- if (p->down)
- p = p->down;
- else
- move = RIGHT;
+ }
+ p2 = p2->right;
}
-
- if (p == node) {
- move = UP;
- continue;
+ p->type &= ~(CONST_TAG);
+ p2 = p->down;
+ while (p2)
+ {
+ p3 = p2->right;
+ if (type_field (p2->type) == ASN1_ETYPE_TAG)
+ asn1_delete_structure (&p2);
+ p2 = p3;
}
+ }
+ move = DOWN;
+ }
+ else
+ move = RIGHT;
+
+ if (move == DOWN)
+ {
+ if (p->down)
+ p = p->down;
+ else
+ move = RIGHT;
+ }
- if (move == RIGHT) {
- if (p->right)
- p = p->right;
- else
- move = UP;
- }
- if (move == UP)
- p = _asn1_find_up(p);
+ if (p == node)
+ {
+ move = UP;
+ continue;
+ }
+
+ if (move == RIGHT)
+ {
+ if (p->right)
+ p = p->right;
+ else
+ move = UP;
}
+ if (move == UP)
+ p = _asn1_find_up (p);
+ }
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
-static int _asn1_expand_identifier(asn1_node * node, asn1_node root)
+static int
+_asn1_expand_identifier (asn1_node * node, asn1_node root)
{
- asn1_node p, p2, p3;
- char name2[ASN1_MAX_NAME_SIZE + 2];
- int move;
-
- if (node == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
-
- p = *node;
- move = DOWN;
-
- while (!((p == *node) && (move == UP))) {
- if (move != UP) {
- if (type_field(p->type) == ASN1_ETYPE_IDENTIFIER) {
- snprintf(name2, sizeof(name2), "%s.%s",
- root->name, p->value);
- p2 = _asn1_copy_structure2(root, name2);
- if (p2 == NULL) {
- return ASN1_IDENTIFIER_NOT_FOUND;
- }
- _asn1_cpy_name(p2, p);
- p2->right = p->right;
- p2->left = p->left;
- if (p->right)
- p->right->left = p2;
- p3 = p->down;
- if (p3) {
- while (p3->right)
- p3 = p3->right;
- _asn1_set_right(p3, p2->down);
- _asn1_set_down(p2, p->down);
- }
-
- p3 = _asn1_find_left(p);
- if (p3)
- _asn1_set_right(p3, p2);
- else {
- p3 = _asn1_find_up(p);
- if (p3)
- _asn1_set_down(p3, p2);
- else {
- p2->left = NULL;
- }
- }
-
- if (p->type & CONST_SIZE)
- p2->type |= CONST_SIZE;
- if (p->type & CONST_TAG)
- p2->type |= CONST_TAG;
- if (p->type & CONST_OPTION)
- p2->type |= CONST_OPTION;
- if (p->type & CONST_DEFAULT)
- p2->type |= CONST_DEFAULT;
- if (p->type & CONST_SET)
- p2->type |= CONST_SET;
- if (p->type & CONST_NOT_USED)
- p2->type |= CONST_NOT_USED;
-
- if (p == *node)
- *node = p2;
- _asn1_remove_node(p);
- p = p2;
- move = DOWN;
- continue;
- }
- move = DOWN;
- } else
- move = RIGHT;
-
- if (move == DOWN) {
- if (p->down)
- p = p->down;
- else
- move = RIGHT;
+ asn1_node p, p2, p3;
+ char name2[ASN1_MAX_NAME_SIZE + 2];
+ int move;
+
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ p = *node;
+ move = DOWN;
+
+ while (!((p == *node) && (move == UP)))
+ {
+ if (move != UP)
+ {
+ if (type_field (p->type) == ASN1_ETYPE_IDENTIFIER)
+ {
+ snprintf (name2, sizeof (name2), "%s.%s", root->name, p->value);
+ p2 = _asn1_copy_structure2 (root, name2);
+ if (p2 == NULL)
+ {
+ return ASN1_IDENTIFIER_NOT_FOUND;
}
-
- if (p == *node) {
- move = UP;
- continue;
+ _asn1_cpy_name (p2, p);
+ p2->right = p->right;
+ p2->left = p->left;
+ if (p->right)
+ p->right->left = p2;
+ p3 = p->down;
+ if (p3)
+ {
+ while (p3->right)
+ p3 = p3->right;
+ _asn1_set_right (p3, p2->down);
+ _asn1_set_down (p2, p->down);
}
- if (move == RIGHT) {
- if (p->right)
- p = p->right;
- else
- move = UP;
+ p3 = _asn1_find_left (p);
+ if (p3)
+ _asn1_set_right (p3, p2);
+ else
+ {
+ p3 = _asn1_find_up (p);
+ if (p3)
+ _asn1_set_down (p3, p2);
+ else
+ {
+ p2->left = NULL;
+ }
}
- if (move == UP)
- p = _asn1_find_up(p);
+
+ if (p->type & CONST_SIZE)
+ p2->type |= CONST_SIZE;
+ if (p->type & CONST_TAG)
+ p2->type |= CONST_TAG;
+ if (p->type & CONST_OPTION)
+ p2->type |= CONST_OPTION;
+ if (p->type & CONST_DEFAULT)
+ p2->type |= CONST_DEFAULT;
+ if (p->type & CONST_SET)
+ p2->type |= CONST_SET;
+ if (p->type & CONST_NOT_USED)
+ p2->type |= CONST_NOT_USED;
+
+ if (p == *node)
+ *node = p2;
+ _asn1_remove_node (p, 0);
+ p = p2;
+ move = DOWN;
+ continue;
+ }
+ move = DOWN;
+ }
+ else
+ move = RIGHT;
+
+ if (move == DOWN)
+ {
+ if (p->down)
+ p = p->down;
+ else
+ move = RIGHT;
+ }
+
+ if (p == *node)
+ {
+ move = UP;
+ continue;
+ }
+
+ if (move == RIGHT)
+ {
+ if (p->right)
+ p = p->right;
+ else
+ move = UP;
}
+ if (move == UP)
+ p = _asn1_find_up (p);
+ }
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
@@ -608,25 +670,25 @@ static int _asn1_expand_identifier(asn1_node * node, asn1_node root)
* @source_name is not known.
**/
int
-asn1_create_element(asn1_node definitions, const char *source_name,
- asn1_node * element)
+asn1_create_element (asn1_node definitions, const char *source_name,
+ asn1_node * element)
{
- asn1_node dest_node;
- int res;
+ asn1_node dest_node;
+ int res;
- dest_node = _asn1_copy_structure2(definitions, source_name);
+ dest_node = _asn1_copy_structure2 (definitions, source_name);
- if (dest_node == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
+ if (dest_node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
- _asn1_set_name(dest_node, "");
+ _asn1_set_name (dest_node, "");
- res = _asn1_expand_identifier(&dest_node, definitions);
- _asn1_type_choice_config(dest_node);
+ res = _asn1_expand_identifier (&dest_node, definitions);
+ _asn1_type_choice_config (dest_node);
- *element = dest_node;
+ *element = dest_node;
- return res;
+ return res;
}
@@ -643,358 +705,331 @@ asn1_create_element(asn1_node definitions, const char *source_name,
* from the @name element inside the structure @structure.
**/
void
-asn1_print_structure(FILE * out, asn1_node structure, const char *name,
- int mode)
+asn1_print_structure (FILE * out, asn1_node structure, const char *name,
+ int mode)
{
- asn1_node p, root;
- int k, indent = 0, len, len2, len3;
-
- if (out == NULL)
- return;
-
- root = asn1_find_node(structure, name);
-
- if (root == NULL)
- return;
-
- p = root;
- while (p) {
- if (mode == ASN1_PRINT_ALL) {
- for (k = 0; k < indent; k++)
- fprintf(out, " ");
- fprintf(out, "name:");
- if (p->name[0] != 0)
- fprintf(out, "%s ", p->name);
- else
- fprintf(out, "NULL ");
- } else {
- switch (type_field(p->type)) {
- case ASN1_ETYPE_CONSTANT:
- case ASN1_ETYPE_TAG:
- case ASN1_ETYPE_SIZE:
- break;
- default:
- for (k = 0; k < indent; k++)
- fprintf(out, " ");
- fprintf(out, "name:");
- if (p->name[0] != 0)
- fprintf(out, "%s ", p->name);
- else
- fprintf(out, "NULL ");
- }
- }
+ asn1_node p, root;
+ int k, indent = 0, len, len2, len3;
+
+ if (out == NULL)
+ return;
+
+ root = asn1_find_node (structure, name);
+
+ if (root == NULL)
+ return;
+
+ p = root;
+ while (p)
+ {
+ if (mode == ASN1_PRINT_ALL)
+ {
+ for (k = 0; k < indent; k++)
+ fprintf (out, " ");
+ fprintf (out, "name:");
+ if (p->name[0] != 0)
+ fprintf (out, "%s ", p->name);
+ else
+ fprintf (out, "NULL ");
+ }
+ else
+ {
+ switch (type_field (p->type))
+ {
+ case ASN1_ETYPE_CONSTANT:
+ case ASN1_ETYPE_TAG:
+ case ASN1_ETYPE_SIZE:
+ break;
+ default:
+ for (k = 0; k < indent; k++)
+ fprintf (out, " ");
+ fprintf (out, "name:");
+ if (p->name[0] != 0)
+ fprintf (out, "%s ", p->name);
+ else
+ fprintf (out, "NULL ");
+ }
+ }
- if (mode != ASN1_PRINT_NAME) {
- unsigned type = type_field(p->type);
- switch (type) {
- case ASN1_ETYPE_CONSTANT:
- if (mode == ASN1_PRINT_ALL)
- fprintf(out, "type:CONST");
- break;
- case ASN1_ETYPE_TAG:
- if (mode == ASN1_PRINT_ALL)
- fprintf(out, "type:TAG");
- break;
- case ASN1_ETYPE_SIZE:
- if (mode == ASN1_PRINT_ALL)
- fprintf(out, "type:SIZE");
- break;
- case ASN1_ETYPE_DEFAULT:
- fprintf(out, "type:DEFAULT");
- break;
- case ASN1_ETYPE_IDENTIFIER:
- fprintf(out, "type:IDENTIFIER");
- break;
- case ASN1_ETYPE_ANY:
- fprintf(out, "type:ANY");
- break;
- case ASN1_ETYPE_CHOICE:
- fprintf(out, "type:CHOICE");
- break;
- case ASN1_ETYPE_DEFINITIONS:
- fprintf(out, "type:DEFINITIONS");
- break;
- CASE_HANDLED_ETYPES:
- fprintf(out, "%s", _asn1_tags[type].desc);
- break;
- default:
- break;
- }
- }
+ if (mode != ASN1_PRINT_NAME)
+ {
+ unsigned type = type_field (p->type);
+ switch (type)
+ {
+ case ASN1_ETYPE_CONSTANT:
+ if (mode == ASN1_PRINT_ALL)
+ fprintf (out, "type:CONST");
+ break;
+ case ASN1_ETYPE_TAG:
+ if (mode == ASN1_PRINT_ALL)
+ fprintf (out, "type:TAG");
+ break;
+ case ASN1_ETYPE_SIZE:
+ if (mode == ASN1_PRINT_ALL)
+ fprintf (out, "type:SIZE");
+ break;
+ case ASN1_ETYPE_DEFAULT:
+ fprintf (out, "type:DEFAULT");
+ break;
+ case ASN1_ETYPE_IDENTIFIER:
+ fprintf (out, "type:IDENTIFIER");
+ break;
+ case ASN1_ETYPE_ANY:
+ fprintf (out, "type:ANY");
+ break;
+ case ASN1_ETYPE_CHOICE:
+ fprintf (out, "type:CHOICE");
+ break;
+ case ASN1_ETYPE_DEFINITIONS:
+ fprintf (out, "type:DEFINITIONS");
+ break;
+ CASE_HANDLED_ETYPES:
+ fprintf (out, "%s", _asn1_tags[type].desc);
+ break;
+ default:
+ break;
+ }
+ }
- if ((mode == ASN1_PRINT_NAME_TYPE_VALUE)
- || (mode == ASN1_PRINT_ALL)) {
- switch (type_field(p->type)) {
- case ASN1_ETYPE_CONSTANT:
- if (mode == ASN1_PRINT_ALL)
- if (p->value)
- fprintf(out, " value:%s",
- p->value);
- break;
- case ASN1_ETYPE_TAG:
- if (mode == ASN1_PRINT_ALL)
- if (p->value)
- fprintf(out, " value:%s",
- p->value);
- break;
- case ASN1_ETYPE_SIZE:
- if (mode == ASN1_PRINT_ALL)
- if (p->value)
- fprintf(out, " value:%s",
- p->value);
- break;
- case ASN1_ETYPE_DEFAULT:
- if (p->value)
- fprintf(out, " value:%s",
- p->value);
- else if (p->type & CONST_TRUE)
- fprintf(out, " value:TRUE");
- else if (p->type & CONST_FALSE)
- fprintf(out, " value:FALSE");
- break;
- case ASN1_ETYPE_IDENTIFIER:
- if (p->value)
- fprintf(out, " value:%s",
- p->value);
- break;
- case ASN1_ETYPE_INTEGER:
- if (p->value) {
- len2 = -1;
- len =
- asn1_get_length_der(p->value,
- p->
- value_len,
- &len2);
- fprintf(out, " value:0x");
- if (len > 0)
- for (k = 0; k < len; k++)
- fprintf(out,
- "%02x",
- (p->
- value)[k +
- len2]);
- }
- break;
- case ASN1_ETYPE_ENUMERATED:
- if (p->value) {
- len2 = -1;
- len =
- asn1_get_length_der(p->value,
- p->
- value_len,
- &len2);
- fprintf(out, " value:0x");
- if (len > 0)
- for (k = 0; k < len; k++)
- fprintf(out,
- "%02x",
- (p->
- value)[k +
- len2]);
- }
- break;
- case ASN1_ETYPE_BOOLEAN:
- if (p->value) {
- if (p->value[0] == 'T')
- fprintf(out,
- " value:TRUE");
- else if (p->value[0] == 'F')
- fprintf(out,
- " value:FALSE");
- }
- break;
- case ASN1_ETYPE_BIT_STRING:
- if (p->value) {
- len2 = -1;
- len =
- asn1_get_length_der(p->value,
- p->
- value_len,
- &len2);
- if (len > 0) {
- fprintf(out,
- " value(%i):",
- (len - 1) * 8 -
- (p->value[len2]));
- for (k = 1; k < len; k++)
- fprintf(out,
- "%02x",
- (p->
- value)[k +
- len2]);
- }
- }
- break;
- case ASN1_ETYPE_GENERALIZED_TIME:
- case ASN1_ETYPE_UTC_TIME:
- if (p->value) {
- fprintf(out, " value:");
- for (k = 0; k < p->value_len; k++)
- fprintf(out, "%c",
- (p->value)[k]);
- }
- break;
- case ASN1_ETYPE_GENERALSTRING:
- case ASN1_ETYPE_NUMERIC_STRING:
- case ASN1_ETYPE_IA5_STRING:
- case ASN1_ETYPE_TELETEX_STRING:
- case ASN1_ETYPE_PRINTABLE_STRING:
- case ASN1_ETYPE_UNIVERSAL_STRING:
- case ASN1_ETYPE_UTF8_STRING:
- case ASN1_ETYPE_VISIBLE_STRING:
- if (p->value) {
- len2 = -1;
- len =
- asn1_get_length_der(p->value,
- p->
- value_len,
- &len2);
- fprintf(out, " value:");
- if (len > 0)
- for (k = 0; k < len; k++)
- fprintf(out, "%c",
- (p->
- value)[k +
- len2]);
- }
- break;
- case ASN1_ETYPE_BMP_STRING:
- case ASN1_ETYPE_OCTET_STRING:
- if (p->value) {
- len2 = -1;
- len =
- asn1_get_length_der(p->value,
- p->
- value_len,
- &len2);
- fprintf(out, " value:");
- if (len > 0)
- for (k = 0; k < len; k++)
- fprintf(out,
- "%02x",
- (p->
- value)[k +
- len2]);
- }
- break;
- case ASN1_ETYPE_OBJECT_ID:
- if (p->value)
- fprintf(out, " value:%s",
- p->value);
- break;
- case ASN1_ETYPE_ANY:
- if (p->value) {
- len3 = -1;
- len2 =
- asn1_get_length_der(p->value,
- p->
- value_len,
- &len3);
- fprintf(out, " value:");
- if (len2 > 0)
- for (k = 0; k < len2; k++)
- fprintf(out,
- "%02x",
- (p->
- value)[k +
- len3]);
- }
- break;
- case ASN1_ETYPE_SET:
- case ASN1_ETYPE_SET_OF:
- case ASN1_ETYPE_CHOICE:
- case ASN1_ETYPE_DEFINITIONS:
- case ASN1_ETYPE_SEQUENCE_OF:
- case ASN1_ETYPE_SEQUENCE:
- case ASN1_ETYPE_NULL:
- break;
- default:
- break;
- }
+ if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL))
+ {
+ switch (type_field (p->type))
+ {
+ case ASN1_ETYPE_CONSTANT:
+ if (mode == ASN1_PRINT_ALL)
+ if (p->value)
+ fprintf (out, " value:%s", p->value);
+ break;
+ case ASN1_ETYPE_TAG:
+ if (mode == ASN1_PRINT_ALL)
+ if (p->value)
+ fprintf (out, " value:%s", p->value);
+ break;
+ case ASN1_ETYPE_SIZE:
+ if (mode == ASN1_PRINT_ALL)
+ if (p->value)
+ fprintf (out, " value:%s", p->value);
+ break;
+ case ASN1_ETYPE_DEFAULT:
+ if (p->value)
+ fprintf (out, " value:%s", p->value);
+ else if (p->type & CONST_TRUE)
+ fprintf (out, " value:TRUE");
+ else if (p->type & CONST_FALSE)
+ fprintf (out, " value:FALSE");
+ break;
+ case ASN1_ETYPE_IDENTIFIER:
+ if (p->value)
+ fprintf (out, " value:%s", p->value);
+ break;
+ case ASN1_ETYPE_INTEGER:
+ if (p->value)
+ {
+ len2 = -1;
+ len = asn1_get_length_der (p->value, p->value_len, &len2);
+ fprintf (out, " value:0x");
+ if (len > 0)
+ for (k = 0; k < len; k++)
+ fprintf (out, "%02x", (p->value)[k + len2]);
}
-
- if (mode == ASN1_PRINT_ALL) {
- if (p->type & 0x1FFFFF00) {
- fprintf(out, " attr:");
- if (p->type & CONST_UNIVERSAL)
- fprintf(out, "UNIVERSAL,");
- if (p->type & CONST_PRIVATE)
- fprintf(out, "PRIVATE,");
- if (p->type & CONST_APPLICATION)
- fprintf(out, "APPLICATION,");
- if (p->type & CONST_EXPLICIT)
- fprintf(out, "EXPLICIT,");
- if (p->type & CONST_IMPLICIT)
- fprintf(out, "IMPLICIT,");
- if (p->type & CONST_TAG)
- fprintf(out, "TAG,");
- if (p->type & CONST_DEFAULT)
- fprintf(out, "DEFAULT,");
- if (p->type & CONST_TRUE)
- fprintf(out, "TRUE,");
- if (p->type & CONST_FALSE)
- fprintf(out, "FALSE,");
- if (p->type & CONST_LIST)
- fprintf(out, "LIST,");
- if (p->type & CONST_MIN_MAX)
- fprintf(out, "MIN_MAX,");
- if (p->type & CONST_OPTION)
- fprintf(out, "OPTION,");
- if (p->type & CONST_1_PARAM)
- fprintf(out, "1_PARAM,");
- if (p->type & CONST_SIZE)
- fprintf(out, "SIZE,");
- if (p->type & CONST_DEFINED_BY)
- fprintf(out, "DEF_BY,");
- if (p->type & CONST_GENERALIZED)
- fprintf(out, "GENERALIZED,");
- if (p->type & CONST_UTC)
- fprintf(out, "UTC,");
- if (p->type & CONST_SET)
- fprintf(out, "SET,");
- if (p->type & CONST_NOT_USED)
- fprintf(out, "NOT_USED,");
- if (p->type & CONST_ASSIGN)
- fprintf(out, "ASSIGNMENT,");
- }
+ break;
+ case ASN1_ETYPE_ENUMERATED:
+ if (p->value)
+ {
+ len2 = -1;
+ len = asn1_get_length_der (p->value, p->value_len, &len2);
+ fprintf (out, " value:0x");
+ if (len > 0)
+ for (k = 0; k < len; k++)
+ fprintf (out, "%02x", (p->value)[k + len2]);
}
-
- if (mode == ASN1_PRINT_ALL) {
- fprintf(out, "\n");
- } else {
- switch (type_field(p->type)) {
- case ASN1_ETYPE_CONSTANT:
- case ASN1_ETYPE_TAG:
- case ASN1_ETYPE_SIZE:
- break;
- default:
- fprintf(out, "\n");
- }
+ break;
+ case ASN1_ETYPE_BOOLEAN:
+ if (p->value)
+ {
+ if (p->value[0] == 'T')
+ fprintf (out, " value:TRUE");
+ else if (p->value[0] == 'F')
+ fprintf (out, " value:FALSE");
}
+ break;
+ case ASN1_ETYPE_BIT_STRING:
+ if (p->value)
+ {
+ len2 = -1;
+ len = asn1_get_length_der (p->value, p->value_len, &len2);
+ if (len > 0)
+ {
+ fprintf (out, " value(%i):",
+ (len - 1) * 8 - (p->value[len2]));
+ for (k = 1; k < len; k++)
+ fprintf (out, "%02x", (p->value)[k + len2]);
+ }
+ }
+ break;
+ case ASN1_ETYPE_GENERALIZED_TIME:
+ case ASN1_ETYPE_UTC_TIME:
+ if (p->value)
+ {
+ fprintf (out, " value:");
+ for (k = 0; k < p->value_len; k++)
+ fprintf (out, "%c", (p->value)[k]);
+ }
+ break;
+ case ASN1_ETYPE_GENERALSTRING:
+ case ASN1_ETYPE_NUMERIC_STRING:
+ case ASN1_ETYPE_IA5_STRING:
+ case ASN1_ETYPE_TELETEX_STRING:
+ case ASN1_ETYPE_PRINTABLE_STRING:
+ case ASN1_ETYPE_UNIVERSAL_STRING:
+ case ASN1_ETYPE_UTF8_STRING:
+ case ASN1_ETYPE_VISIBLE_STRING:
+ if (p->value)
+ {
+ len2 = -1;
+ len = asn1_get_length_der (p->value, p->value_len, &len2);
+ fprintf (out, " value:");
+ if (len > 0)
+ for (k = 0; k < len; k++)
+ fprintf (out, "%c", (p->value)[k + len2]);
+ }
+ break;
+ case ASN1_ETYPE_BMP_STRING:
+ case ASN1_ETYPE_OCTET_STRING:
+ if (p->value)
+ {
+ len2 = -1;
+ len = asn1_get_length_der (p->value, p->value_len, &len2);
+ fprintf (out, " value:");
+ if (len > 0)
+ for (k = 0; k < len; k++)
+ fprintf (out, "%02x", (p->value)[k + len2]);
+ }
+ break;
+ case ASN1_ETYPE_OBJECT_ID:
+ if (p->value)
+ fprintf (out, " value:%s", p->value);
+ break;
+ case ASN1_ETYPE_ANY:
+ if (p->value)
+ {
+ len3 = -1;
+ len2 = asn1_get_length_der (p->value, p->value_len, &len3);
+ fprintf (out, " value:");
+ if (len2 > 0)
+ for (k = 0; k < len2; k++)
+ fprintf (out, "%02x", (p->value)[k + len3]);
+ }
+ break;
+ case ASN1_ETYPE_SET:
+ case ASN1_ETYPE_SET_OF:
+ case ASN1_ETYPE_CHOICE:
+ case ASN1_ETYPE_DEFINITIONS:
+ case ASN1_ETYPE_SEQUENCE_OF:
+ case ASN1_ETYPE_SEQUENCE:
+ case ASN1_ETYPE_NULL:
+ break;
+ default:
+ break;
+ }
+ }
- if (p->down) {
- p = p->down;
- indent += 2;
- } else if (p == root) {
- p = NULL;
- break;
- } else if (p->right)
- p = p->right;
- else {
- while (1) {
- p = _asn1_find_up(p);
- if (p == root) {
- p = NULL;
- break;
- }
- indent -= 2;
- if (p->right) {
- p = p->right;
- break;
- }
- }
+ if (mode == ASN1_PRINT_ALL)
+ {
+ if (p->type & 0x1FFFFF00)
+ {
+ fprintf (out, " attr:");
+ if (p->type & CONST_UNIVERSAL)
+ fprintf (out, "UNIVERSAL,");
+ if (p->type & CONST_PRIVATE)
+ fprintf (out, "PRIVATE,");
+ if (p->type & CONST_APPLICATION)
+ fprintf (out, "APPLICATION,");
+ if (p->type & CONST_EXPLICIT)
+ fprintf (out, "EXPLICIT,");
+ if (p->type & CONST_IMPLICIT)
+ fprintf (out, "IMPLICIT,");
+ if (p->type & CONST_TAG)
+ fprintf (out, "TAG,");
+ if (p->type & CONST_DEFAULT)
+ fprintf (out, "DEFAULT,");
+ if (p->type & CONST_TRUE)
+ fprintf (out, "TRUE,");
+ if (p->type & CONST_FALSE)
+ fprintf (out, "FALSE,");
+ if (p->type & CONST_LIST)
+ fprintf (out, "LIST,");
+ if (p->type & CONST_MIN_MAX)
+ fprintf (out, "MIN_MAX,");
+ if (p->type & CONST_OPTION)
+ fprintf (out, "OPTION,");
+ if (p->type & CONST_1_PARAM)
+ fprintf (out, "1_PARAM,");
+ if (p->type & CONST_SIZE)
+ fprintf (out, "SIZE,");
+ if (p->type & CONST_DEFINED_BY)
+ fprintf (out, "DEF_BY,");
+ if (p->type & CONST_GENERALIZED)
+ fprintf (out, "GENERALIZED,");
+ if (p->type & CONST_UTC)
+ fprintf (out, "UTC,");
+ if (p->type & CONST_SET)
+ fprintf (out, "SET,");
+ if (p->type & CONST_NOT_USED)
+ fprintf (out, "NOT_USED,");
+ if (p->type & CONST_ASSIGN)
+ fprintf (out, "ASSIGNMENT,");
+ }
+ }
+
+ if (mode == ASN1_PRINT_ALL)
+ {
+ fprintf (out, "\n");
+ }
+ else
+ {
+ switch (type_field (p->type))
+ {
+ case ASN1_ETYPE_CONSTANT:
+ case ASN1_ETYPE_TAG:
+ case ASN1_ETYPE_SIZE:
+ break;
+ default:
+ fprintf (out, "\n");
+ }
+ }
+
+ if (p->down)
+ {
+ p = p->down;
+ indent += 2;
+ }
+ else if (p == root)
+ {
+ p = NULL;
+ break;
+ }
+ else if (p->right)
+ p = p->right;
+ else
+ {
+ while (1)
+ {
+ p = _asn1_find_up (p);
+ if (p == root)
+ {
+ p = NULL;
+ break;
+ }
+ indent -= 2;
+ if (p->right)
+ {
+ p = p->right;
+ break;
}
+ }
}
+ }
}
@@ -1011,28 +1046,30 @@ asn1_print_structure(FILE * out, asn1_node structure, const char *name,
* Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
* @name is not known, %ASN1_GENERIC_ERROR if pointer @num is %NULL.
**/
-int asn1_number_of_elements(asn1_node element, const char *name, int *num)
+int
+asn1_number_of_elements (asn1_node element, const char *name, int *num)
{
- asn1_node node, p;
+ asn1_node node, p;
- if (num == NULL)
- return ASN1_GENERIC_ERROR;
+ if (num == NULL)
+ return ASN1_GENERIC_ERROR;
- *num = 0;
+ *num = 0;
- node = asn1_find_node(element, name);
- if (node == NULL)
- return ASN1_ELEMENT_NOT_FOUND;
+ node = asn1_find_node (element, name);
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
- p = node->down;
+ p = node->down;
- while (p) {
- if (p->name[0] == '?')
- (*num)++;
- p = p->right;
- }
+ while (p)
+ {
+ if (p->name[0] == '?')
+ (*num)++;
+ p = p->right;
+ }
- return ASN1_SUCCESS;
+ return ASN1_SUCCESS;
}
@@ -1047,49 +1084,46 @@ int asn1_number_of_elements(asn1_node element, const char *name, int *num)
* constant string that contains the element name defined just after
* the OID.
**/
-const char *asn1_find_structure_from_oid(asn1_node definitions,
- const char *oidValue)
+const char *
+asn1_find_structure_from_oid (asn1_node definitions, const char *oidValue)
{
- char definitionsName[ASN1_MAX_NAME_SIZE],
- name[2 * ASN1_MAX_NAME_SIZE + 1];
- char value[ASN1_MAX_NAME_SIZE];
- asn1_node p;
- int len;
- int result;
-
- if ((definitions == NULL) || (oidValue == NULL))
+ char name[2 * ASN1_MAX_NAME_SIZE + 1];
+ char value[ASN1_MAX_NAME_SIZE];
+ asn1_node p;
+ int len;
+ int result;
+ const char *definitionsName;
+
+ if ((definitions == NULL) || (oidValue == NULL))
+ return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
+
+ definitionsName = definitions->name;
+
+ /* search the OBJECT_ID into definitions */
+ p = definitions->down;
+ while (p)
+ {
+ if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
+ (p->type & CONST_ASSIGN))
+ {
+ snprintf(name, sizeof(name), "%s.%s", definitionsName, p->name);
+
+ len = ASN1_MAX_NAME_SIZE;
+ result = asn1_read_value (definitions, name, value, &len);
+
+ if ((result == ASN1_SUCCESS) && (!strcmp (oidValue, value)))
+ {
+ p = p->right;
+ if (p == NULL) /* reach the end of ASN1 definitions */
return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
-
- strcpy(definitionsName, definitions->name);
- strcat(definitionsName, ".");
-
- /* search the OBJECT_ID into definitions */
- p = definitions->down;
- while (p) {
- if ((type_field(p->type) == ASN1_ETYPE_OBJECT_ID) &&
- (p->type & CONST_ASSIGN)) {
- strcpy(name, definitionsName);
- strcat(name, p->name);
-
- len = ASN1_MAX_NAME_SIZE;
- result =
- asn1_read_value(definitions, name, value,
- &len);
-
- if ((result == ASN1_SUCCESS)
- && (!strcmp(oidValue, value))) {
- p = p->right;
- if (p == NULL) /* reach the end of ASN1 definitions */
- return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
-
- return p->name;
- }
- }
- p = p->right;
+ return p->name;
+ }
}
+ p = p->right;
+ }
- return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
+ return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
}
/**
@@ -1104,40 +1138,42 @@ const char *asn1_find_structure_from_oid(asn1_node definitions,
* Returns: Return %ASN1_SUCCESS on success.
**/
int
-asn1_copy_node(asn1_node dst, const char *dst_name,
- asn1_node src, const char *src_name)
+asn1_copy_node (asn1_node dst, const char *dst_name,
+ asn1_node src, const char *src_name)
{
/* FIXME: rewrite using copy_structure().
* It seems quite hard to do.
*/
- int result;
- asn1_node dst_node;
- void *data = NULL;
- int size = 0;
-
- result = asn1_der_coding(src, src_name, NULL, &size, NULL);
- if (result != ASN1_MEM_ERROR)
- return result;
-
- data = malloc(size);
- if (data == NULL)
- return ASN1_MEM_ERROR;
-
- result = asn1_der_coding(src, src_name, data, &size, NULL);
- if (result != ASN1_SUCCESS) {
- free(data);
- return result;
- }
-
- dst_node = asn1_find_node(dst, dst_name);
- if (dst_node == NULL) {
- free(data);
- return ASN1_ELEMENT_NOT_FOUND;
- }
-
- result = asn1_der_decoding(&dst_node, data, size, NULL);
-
- free(data);
-
- return result;
+ int result;
+ asn1_node dst_node;
+ void *data = NULL;
+ int size = 0;
+
+ result = asn1_der_coding (src, src_name, NULL, &size, NULL);
+ if (result != ASN1_MEM_ERROR)
+ return result;
+
+ data = malloc (size);
+ if (data == NULL)
+ return ASN1_MEM_ERROR;
+
+ result = asn1_der_coding (src, src_name, data, &size, NULL);
+ if (result != ASN1_SUCCESS)
+ {
+ free (data);
+ return result;
+ }
+
+ dst_node = asn1_find_node (dst, dst_name);
+ if (dst_node == NULL)
+ {
+ free (data);
+ return ASN1_ELEMENT_NOT_FOUND;
+ }
+
+ result = asn1_der_decoding (&dst_node, data, size, NULL);
+
+ free (data);
+
+ return result;
}
diff --git a/lib/minitasn1/structure.h b/lib/minitasn1/structure.h
index c56beb6413..bb6e7a9b9a 100644
--- a/lib/minitasn1/structure.h
+++ b/lib/minitasn1/structure.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2002-2014 Free Software Foundation, Inc.
*
* This file is part of LIBTASN1.
*
@@ -28,14 +28,13 @@
#ifndef _STRUCTURE_H
#define _STRUCTURE_H
-int _asn1_create_static_structure(asn1_node pointer,
- char *output_file_name,
- char *vector_name);
+int _asn1_create_static_structure (asn1_node pointer,
+ char *output_file_name, char *vector_name);
-asn1_node _asn1_copy_structure3(asn1_node source_node);
+asn1_node _asn1_copy_structure3 (asn1_node source_node);
-asn1_node _asn1_add_single_node(unsigned int type);
+asn1_node _asn1_add_single_node (unsigned int type);
-asn1_node _asn1_find_left(asn1_node node);
+asn1_node _asn1_find_left (asn1_node node);
#endif
diff --git a/lib/minitasn1/version.c b/lib/minitasn1/version.c
index 2941af916a..25f8a8f28e 100644
--- a/lib/minitasn1/version.c
+++ b/lib/minitasn1/version.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2000-2014 Free Software Foundation, Inc.
*
* This file is part of LIBTASN1.
*
@@ -41,10 +41,11 @@
* Returns: Version string of run-time library, or %NULL if the
* run-time library does not meet the required version number.
*/
-const char *asn1_check_version(const char *req_version)
+const char *
+asn1_check_version (const char *req_version)
{
- if (!req_version || strverscmp(req_version, ASN1_VERSION) <= 0)
- return ASN1_VERSION;
+ if (!req_version || strverscmp (req_version, ASN1_VERSION) <= 0)
+ return ASN1_VERSION;
- return NULL;
+ return NULL;
}