summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2016-04-09 08:17:22 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2016-04-09 08:17:22 +0200
commit3e01143ad960a2693bee91b26a91d3b23d04bb3c (patch)
treed3118dcfd23c789f75a3e7c323ef69f7a7a1f367
parent259278197b6bfcadf333cda9e98ac330f88057f0 (diff)
downloadgnutls-3e01143ad960a2693bee91b26a91d3b23d04bb3c.tar.gz
minitasn1: updated to latest git version
-rw-r--r--lib/minitasn1/coding.c15
-rw-r--r--lib/minitasn1/decoding.c581
-rw-r--r--lib/minitasn1/element.c26
-rw-r--r--lib/minitasn1/element.h8
-rw-r--r--lib/minitasn1/int.h30
-rw-r--r--lib/minitasn1/libtasn1.h7
-rw-r--r--lib/minitasn1/parser_aux.c51
-rw-r--r--lib/minitasn1/parser_aux.h13
-rw-r--r--lib/minitasn1/structure.c34
9 files changed, 409 insertions, 356 deletions
diff --git a/lib/minitasn1/coding.c b/lib/minitasn1/coding.c
index 2dd80ba419..0c0f69c5ce 100644
--- a/lib/minitasn1/coding.c
+++ b/lib/minitasn1/coding.c
@@ -443,7 +443,9 @@ asn1_bit_der (const unsigned char *str, int bit_len,
len_byte++;
asn1_length_der (len_byte + 1, der, &len_len);
der[len_len] = len_pad;
- memcpy (der + len_len + 1, str, len_byte);
+
+ if (str)
+ memcpy (der + len_len + 1, str, len_byte);
der[len_len + len_byte] &= bit_mask[len_pad];
*der_len = len_byte + len_len + 1;
}
@@ -628,7 +630,7 @@ _asn1_insert_tag_der (asn1_node node, unsigned char *der, int *counter,
tag_der, &tag_len);
*max_len -= tag_len;
- if (*max_len >= 0)
+ if (der && *max_len >= 0)
memcpy (der + *counter, tag_der, tag_len);
*counter += tag_len;
@@ -680,7 +682,7 @@ _asn1_insert_tag_der (asn1_node node, unsigned char *der, int *counter,
}
*max_len -= tag_len;
- if (*max_len >= 0)
+ if (der && *max_len >= 0)
memcpy (der + *counter, tag_der, tag_len);
*counter += tag_len;
@@ -1018,6 +1020,9 @@ asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
int err;
unsigned char *der = ider;
+ if (ErrorDescription)
+ ErrorDescription[0] = 0;
+
node = asn1_find_node (element, name);
if (node == NULL)
return ASN1_ELEMENT_NOT_FOUND;
@@ -1248,7 +1253,7 @@ asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
continue;
}
else
- p = _asn1_get_up (p);
+ p = _asn1_find_up (p);
move = UP;
}
if (move == UP)
@@ -1323,7 +1328,7 @@ asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
move = UP;
}
if (move == UP)
- p = _asn1_get_up (p);
+ p = _asn1_find_up (p);
}
*len = counter;
diff --git a/lib/minitasn1/decoding.c b/lib/minitasn1/decoding.c
index 42ddc6be03..e5513a38b0 100644
--- a/lib/minitasn1/decoding.c
+++ b/lib/minitasn1/decoding.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002-2014 Free Software Foundation, Inc.
+ * Copyright (C) 2002-2016 Free Software Foundation, Inc.
*
* This file is part of LIBTASN1.
*
@@ -43,6 +43,9 @@
#define HAVE_TWO(x) (x>=2?1:0)
+#define DECODE_FLAG_HAVE_TAG 1
+#define DECODE_FLAG_INDEFINITE (1<<1)
+
#define DECR_LEN(l, s) do { \
l -= s; \
if (l < 0) { \
@@ -55,6 +58,17 @@
static int
_asn1_get_indefinite_length_string (const unsigned char *der, int der_len, int *len);
+static int
+_asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
+ unsigned int _der_len, unsigned char **str,
+ unsigned int *str_len, unsigned int *ber_len,
+ unsigned dflags);
+
+static int
+_asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
+ unsigned int _der_len, const unsigned char **str,
+ unsigned int *str_len, unsigned dflags);
+
static void
_asn1_error_description_tag_error (asn1_node node, char *ErrorDescription)
{
@@ -236,13 +250,15 @@ asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len)
/**
* asn1_get_octet_der:
* @der: DER data to decode containing the OCTET SEQUENCE.
- * @der_len: Length of DER data to decode.
- * @ret_len: Output variable containing the length of the DER data.
+ * @der_len: The length of the @der data to decode.
+ * @ret_len: Output variable containing the encoded length of the DER data.
* @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in.
* @str_size: Length of pre-allocated output buffer.
- * @str_len: Output variable containing the length of the OCTET SEQUENCE.
+ * @str_len: Output variable containing the length of the contents of the OCTET SEQUENCE.
*
- * Extract an OCTET SEQUENCE from DER data.
+ * Extract an OCTET SEQUENCE from DER data. Note that this function
+ * expects the DER data past the tag field, i.e., the length and
+ * content octets.
*
* Returns: Returns %ASN1_SUCCESS on success, or an error.
**/
@@ -275,9 +291,23 @@ asn1_get_octet_der (const unsigned char *der, int der_len,
return ASN1_SUCCESS;
}
-/* Returns ASN1_SUCCESS on success or an error code on error.
- * type should be one of ASN1_ETYPE_GENERALIZED_TIME or ASN1_ETYPE_UTC_TIME.
- */
+
+/*-
+ * _asn1_get_time_der:
+ * @type: %ASN1_ETYPE_GENERALIZED_TIME or %ASN1_ETYPE_UTC_TIME
+ * @der: DER data to decode containing the time
+ * @der_len: Length of DER data to decode.
+ * @ret_len: Output variable containing the length of the DER data.
+ * @str: Pre-allocated output buffer to put the textual time in.
+ * @str_size: Length of pre-allocated output buffer.
+ * @flags: Zero or %ASN1_DECODE_FLAG_STRICT_DER
+ *
+ * Performs basic checks in the DER encoded time object and returns its textual form.
+ * The textual form will be in the YYYYMMDD000000Z format for GeneralizedTime
+ * and YYMMDD000000Z for UTCTime.
+ *
+ * Returns: %ASN1_SUCCESS on success, or an error.
+ -*/
static int
_asn1_get_time_der (unsigned type, const unsigned char *der, int der_len, int *ret_len,
char *str, int str_size, unsigned flags)
@@ -329,7 +359,7 @@ _asn1_get_time_der (unsigned type, const unsigned char *der, int der_len, int *r
}
warn();
- return ASN1_DER_ERROR;
+ return ASN1_DER_ERROR;
}
}
@@ -346,8 +376,20 @@ _asn1_get_time_der (unsigned type, const unsigned char *der, int der_len, int *r
return ASN1_SUCCESS;
}
-static int
-_asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len,
+/**
+ * asn1_get_objectid_der:
+ * @der: DER data to decode containing the OBJECT IDENTIFIER
+ * @der_len: Length of DER data to decode.
+ * @ret_len: Output variable containing the length of the DER data.
+ * @str: Pre-allocated output buffer to put the textual object id in.
+ * @str_size: Length of pre-allocated output buffer.
+ *
+ * Converts a DER encoded object identifier to its textual form.
+ *
+ * Returns: %ASN1_SUCCESS on success, or an error.
+ **/
+int
+asn1_get_object_id_der (const unsigned char *der, int der_len, int *ret_len,
char *str, int str_size)
{
int len_len, len, k;
@@ -419,7 +461,7 @@ _asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len,
*
* Extract a BIT SEQUENCE from DER data.
*
- * Returns: Return %ASN1_SUCCESS on success, or an error.
+ * Returns: %ASN1_SUCCESS on success, or an error.
**/
int
asn1_get_bit_der (const unsigned char *der, int der_len,
@@ -454,10 +496,12 @@ asn1_get_bit_der (const unsigned char *der, int der_len,
return ASN1_SUCCESS;
}
-
+/* tag_len: the total tag length (explicit+inner)
+ * inner_tag_len: the inner_tag length
+ */
static int
_asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len,
- int *ret_len, unsigned flags)
+ int *tag_len, int *inner_tag_len, unsigned flags)
{
asn1_node p;
int counter, len2, len3, is_tag_implicit;
@@ -568,7 +612,9 @@ _asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len,
unsigned type = type_field (node->type);
if (type == ASN1_ETYPE_TAG)
{
- *ret_len = 0;
+ *tag_len = 0;
+ if (inner_tag_len)
+ *inner_tag_len = 0;
return ASN1_SUCCESS;
}
@@ -628,7 +674,9 @@ _asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len,
}
counter += len2;
- *ret_len = counter;
+ *tag_len = counter;
+ if (inner_tag_len)
+ *inner_tag_len = len2;
return ASN1_SUCCESS;
cleanup:
@@ -637,7 +685,7 @@ cleanup:
static int
extract_tag_der_recursive(asn1_node node, const unsigned char *der, int der_len,
- int *ret_len, unsigned flags)
+ int *ret_len, int *inner_len, unsigned flags)
{
asn1_node p;
int ris = ASN1_DER_ERROR;
@@ -647,7 +695,7 @@ int ris = ASN1_DER_ERROR;
p = node->down;
while (p)
{
- ris = _asn1_extract_tag_der (p, der, der_len, ret_len, flags);
+ ris = _asn1_extract_tag_der (p, der, der_len, ret_len, inner_len, flags);
if (ris == ASN1_SUCCESS)
break;
p = p->right;
@@ -657,7 +705,7 @@ int ris = ASN1_DER_ERROR;
return ris;
}
else
- return _asn1_extract_tag_der (node, der, der_len, ret_len, flags);
+ return _asn1_extract_tag_der (node, der, der_len, ret_len, inner_len, flags);
}
static int
@@ -678,7 +726,7 @@ _asn1_delete_not_used (asn1_node node)
{
p2 = _asn1_find_left (p);
if (!p2)
- p2 = _asn1_get_up (p);
+ p2 = _asn1_find_up (p);
}
asn1_delete_structure (&p);
p = p2;
@@ -701,7 +749,7 @@ _asn1_delete_not_used (asn1_node node)
{
while (1)
{
- p = _asn1_get_up (p);
+ p = _asn1_find_up (p);
if (p == node)
{
p = NULL;
@@ -720,167 +768,6 @@ _asn1_delete_not_used (asn1_node node)
}
static int
-_asn1_extract_der_octet (asn1_node node, const unsigned char *der,
- int der_len, unsigned flags)
-{
- int len2, len3;
- int counter, counter_end;
- int result;
-
- len2 = asn1_get_length_der (der, der_len, &len3);
- if (len2 < -1)
- return ASN1_DER_ERROR;
-
- counter = len3 + 1;
- DECR_LEN(der_len, len3);
-
- if (len2 == -1)
- counter_end = der_len - 2;
- else
- counter_end = der_len;
-
- while (counter < counter_end)
- {
- DECR_LEN(der_len, 1);
- len2 = asn1_get_length_der (der + counter, der_len, &len3);
-
- if (IS_ERR(len2, flags))
- {
- warn();
- return ASN1_DER_ERROR;
- }
-
- if (len2 >= 0)
- {
- DECR_LEN(der_len, len2+len3);
- _asn1_append_value (node, der + counter + len3, len2);
- }
- else
- { /* indefinite */
- DECR_LEN(der_len, len3);
- result =
- _asn1_extract_der_octet (node, der + counter + len3,
- der_len, flags);
- if (result != ASN1_SUCCESS)
- return result;
- len2 = 0;
- }
-
- counter += len2 + len3 + 1;
- }
-
- return ASN1_SUCCESS;
-
-cleanup:
- return result;
-}
-
-static int
-_asn1_get_octet_string (asn1_node node, const unsigned char *der, int der_len,
- int *len, unsigned flags)
-{
- int len2, len3, counter, tot_len, indefinite;
- int result;
- int orig_der_len = der_len;
-
- counter = 0;
-
- if (*(der - 1) & ASN1_CLASS_STRUCTURED)
- {
- tot_len = 0;
-
- indefinite = asn1_get_length_der (der, der_len, &len3);
- if (IS_ERR(indefinite, flags))
- {
- warn();
- return ASN1_DER_ERROR;
- }
-
- counter += len3;
- DECR_LEN(der_len, len3);
-
- if (indefinite >= 0)
- indefinite += len3;
-
- while (1)
- {
- if (indefinite == -1)
- {
- if (HAVE_TWO(der_len) && (der[counter] == 0) && (der[counter + 1] == 0))
- {
- counter += 2;
- DECR_LEN(der_len, 2);
- break;
- }
- }
- else if (counter >= indefinite)
- break;
-
- DECR_LEN(der_len, 1);
- if (der[counter] != ASN1_TAG_OCTET_STRING)
- {
- warn();
- return ASN1_DER_ERROR;
- }
-
- counter++;
-
- len2 = asn1_get_length_der (der + counter, der_len, &len3);
- if (len2 <= 0)
- {
- warn();
- return ASN1_DER_ERROR;
- }
-
- DECR_LEN(der_len, len3 + len2);
- counter += len3 + len2;
-
- tot_len += len2;
- }
-
- /* copy */
- if (node)
- {
- unsigned char temp[ASN1_MAX_LENGTH_SIZE];
- 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, orig_der_len, flags);
- if (ret != ASN1_SUCCESS)
- {
- warn();
- return ret;
- }
-
- }
- }
- else
- { /* NOT STRUCTURED */
- len2 = asn1_get_length_der (der, der_len, &len3);
- if (len2 < 0)
- {
- warn();
- return ASN1_DER_ERROR;
- }
-
- DECR_LEN(der_len, len3+len2);
- counter = len3 + len2;
- if (node)
- _asn1_set_value (node, der, counter);
- }
-
- *len = counter;
- return ASN1_SUCCESS;
-
-cleanup:
- return result;
-}
-
-static int
_asn1_get_indefinite_length_string (const unsigned char *der,
int der_len, int *len)
{
@@ -982,11 +869,14 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
asn1_node node, p, p2, p3;
char temp[128];
int counter, len2, len3, len4, move, ris, tlen;
- asn1_node ptail = NULL;
+ struct node_tail_cache_st tcache = {NULL, NULL};
unsigned char class;
unsigned long tag;
int tag_len;
int indefinite, result, total_len = *max_ider_len, ider_len = *max_ider_len;
+ int inner_tag_len;
+ unsigned char *ptmp;
+ const unsigned char *ptag;
const unsigned char *der = ider;
node = *element;
@@ -1010,12 +900,13 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
while (1)
{
tag_len = 0;
+ inner_tag_len = 0;
ris = ASN1_SUCCESS;
if (move != UP)
{
if (p->type & CONST_SET)
{
- p2 = _asn1_get_up (p);
+ p2 = _asn1_find_up (p);
len2 = p2->tmp_ival;
if (len2 == -1)
{
@@ -1047,7 +938,7 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
{
ris =
extract_tag_der_recursive (p2, der + counter,
- ider_len, &len2, flags);
+ ider_len, &len2, NULL, flags);
if (ris == ASN1_SUCCESS)
{
p2->type &= ~CONST_NOT_USED;
@@ -1071,7 +962,7 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
{
- p2 = _asn1_get_up (p);
+ p2 = _asn1_find_up (p);
len2 = p2->tmp_ival;
if (counter == len2)
{
@@ -1097,7 +988,7 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
{
ris =
extract_tag_der_recursive (p->down, der + counter,
- ider_len, &len2, flags);
+ ider_len, &len2, NULL, flags);
if (ris == ASN1_SUCCESS)
{
@@ -1134,7 +1025,7 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
{
- p2 = _asn1_get_up (p);
+ p2 = _asn1_find_up (p);
len2 = p2->tmp_ival;
if ((len2 != -1) && (counter > len2))
@@ -1144,7 +1035,7 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
if (ris == ASN1_SUCCESS)
ris =
extract_tag_der_recursive (p, der + counter, ider_len,
- &tag_len, flags);
+ &tag_len, &inner_tag_len, flags);
if (ris != ASN1_SUCCESS)
{
@@ -1224,7 +1115,7 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
break;
case ASN1_ETYPE_OBJECT_ID:
result =
- _asn1_get_objectid_der (der + counter, ider_len, &len2,
+ asn1_get_object_id_der (der + counter, ider_len, &len2,
temp, sizeof (temp));
if (result != ASN1_SUCCESS)
{
@@ -1262,15 +1153,51 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
move = RIGHT;
break;
case ASN1_ETYPE_OCTET_STRING:
- result = _asn1_get_octet_string (p, der + counter, ider_len, &len3, flags);
- if (result != ASN1_SUCCESS)
+ if (counter < inner_tag_len)
{
+ result = ASN1_DER_ERROR;
warn();
goto cleanup;
- }
+ }
+
+ ptag = der + counter - inner_tag_len;
+ if (flags & ASN1_DECODE_FLAG_STRICT_DER || !(ptag[0] & ASN1_CLASS_STRUCTURED))
+ {
+ len2 =
+ asn1_get_length_der (der + counter, ider_len, &len3);
+ if (len2 < 0)
+ {
+ result = ASN1_DER_ERROR;
+ warn();
+ goto cleanup;
+ }
+
+ DECR_LEN(ider_len, len3+len2);
+
+ _asn1_set_value (p, der + counter, len3 + len2);
+ counter += len3 + len2;
+ }
+ else
+ {
+ unsigned dflags = 0, vlen, ber_len;
+
+ if (ptag[0] & ASN1_CLASS_STRUCTURED)
+ dflags |= DECODE_FLAG_INDEFINITE;
- DECR_LEN(ider_len, len3);
- counter += len3;
+ result = _asn1_decode_simple_ber(type_field (p->type), der+counter, ider_len, &ptmp, &vlen, &ber_len, dflags);
+ if (result != ASN1_SUCCESS)
+ {
+ warn();
+ goto cleanup;
+ }
+
+ DECR_LEN(ider_len, ber_len);
+
+ _asn1_set_value_lv (p, ptmp, vlen);
+
+ counter += ber_len;
+ free(ptmp);
+ }
move = RIGHT;
break;
case ASN1_ETYPE_GENERALSTRING:
@@ -1377,14 +1304,15 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
{ /* indefinite length method */
if (!HAVE_TWO(ider_len) || ((der[counter]) || der[counter + 1]))
{
- _asn1_append_sequence_set (p, &ptail);
- p = ptail;
+ _asn1_append_sequence_set (p, &tcache);
+ p = tcache.tail;
move = RIGHT;
continue;
}
p->tmp_ival = 0;
- ptail = NULL; /* finished decoding this structure */
+ tcache.tail = NULL; /* finished decoding this structure */
+ tcache.head = NULL;
DECR_LEN(ider_len, 2);
counter += 2;
}
@@ -1392,14 +1320,15 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
{ /* definite length method */
if (len2 > counter)
{
- _asn1_append_sequence_set (p, &ptail);
- p = ptail;
+ _asn1_append_sequence_set (p, &tcache);
+ p = tcache.tail;
move = RIGHT;
continue;
}
p->tmp_ival = 0;
- ptail = NULL; /* finished decoding this structure */
+ tcache.tail = NULL; /* finished decoding this structure */
+ tcache.head = NULL;
if (len2 != counter)
{
@@ -1437,7 +1366,7 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
|| (type_field (p2->type) == ASN1_ETYPE_SIZE))
p2 = p2->right;
if (p2->right == NULL)
- _asn1_append_sequence_set (p, &ptail);
+ _asn1_append_sequence_set (p, &tcache);
p = p2;
}
}
@@ -1553,7 +1482,7 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
move = UP;
}
if (move == UP)
- p = _asn1_get_up (p);
+ p = _asn1_find_up (p);
}
_asn1_delete_not_used (*element);
@@ -1766,7 +1695,7 @@ asn1_expand_any_defined_by (asn1_node definitions, asn1_node * element)
break;
}
- p3 = _asn1_get_up (p);
+ p3 = _asn1_find_up (p);
if (!p3)
{
@@ -1786,8 +1715,8 @@ asn1_expand_any_defined_by (asn1_node definitions, asn1_node * element)
(p3->value == NULL))
{
- p3 = _asn1_get_up (p);
- p3 = _asn1_get_up (p3);
+ p3 = _asn1_find_up (p);
+ p3 = _asn1_find_up (p3);
if (!p3)
{
@@ -1922,7 +1851,7 @@ asn1_expand_any_defined_by (asn1_node definitions, asn1_node * element)
{
while (1)
{
- p = _asn1_get_up (p);
+ p = _asn1_find_up (p);
if (p == *element)
{
p = NULL;
@@ -2082,23 +2011,24 @@ asn1_expand_octet_string (asn1_node definitions, asn1_node * element,
return retCode;
}
-/**
- * asn1_decode_simple_der:
+/*-
+ * _asn1_decode_simple_der:
* @etype: The type of the string to be encoded (ASN1_ETYPE_)
* @der: the encoded string
* @_der_len: the bytes of the encoded string
* @str: a pointer to the data
* @str_len: the length of the data
+ * @dflags: DECODE_FLAG_*
*
* 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.
- **/
-int
-asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
+ -*/
+static int
+_asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
unsigned int _der_len, const unsigned char **str,
- unsigned int *str_len)
+ unsigned int *str_len, unsigned dflags)
{
int tag_len, len_len;
const unsigned char *p;
@@ -2110,25 +2040,33 @@ asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
if (der == NULL || der_len == 0)
return ASN1_VALUE_NOT_VALID;
- if (ETYPE_OK (etype) == 0)
+ if (ETYPE_OK (etype) == 0 || ETYPE_IS_STRING(etype) == 0)
return ASN1_VALUE_NOT_VALID;
/* doesn't handle constructed classes */
- if (ETYPE_CLASS (etype) != ASN1_CLASS_UNIVERSAL)
+ class = ETYPE_CLASS(etype);
+ if (class != 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;
- if (class != ETYPE_CLASS (etype) || tag != ETYPE_TAG (etype))
- return ASN1_DER_ERROR;
+ if (dflags & DECODE_FLAG_HAVE_TAG)
+ {
+ ret = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag);
+ if (ret != ASN1_SUCCESS)
+ return ret;
- p += tag_len;
- der_len -= tag_len;
- if (der_len <= 0)
- return ASN1_DER_ERROR;
+ if (class != ETYPE_CLASS (etype) || tag != ETYPE_TAG (etype))
+ {
+ warn();
+ return ASN1_DER_ERROR;
+ }
+
+ p += tag_len;
+ der_len -= tag_len;
+ if (der_len <= 0)
+ return ASN1_DER_ERROR;
+ }
ret = asn1_get_length_der (p, der_len, &len_len);
if (ret < 0)
@@ -2145,9 +2083,30 @@ asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
return ASN1_SUCCESS;
}
+/**
+ * asn1_decode_simple_der:
+ * @etype: The type of the string to be encoded (ASN1_ETYPE_)
+ * @der: the encoded string
+ * @_der_len: the bytes of the encoded string
+ * @str: a pointer to the data
+ * @str_len: the length of the data
+ *
+ * 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.
+ **/
+int
+asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
+ unsigned int _der_len, const unsigned char **str,
+ unsigned int *str_len)
+{
+ return _asn1_decode_simple_der(etype, der, _der_len, str, str_len, DECODE_FLAG_HAVE_TAG);
+}
+
static int append(uint8_t **dst, unsigned *dst_size, const unsigned char *src, unsigned src_size)
{
- *dst = realloc(*dst, *dst_size+src_size);
+ *dst = _asn1_realloc(*dst, *dst_size+src_size);
if (*dst == NULL)
return ASN1_MEM_ERROR;
memcpy(*dst + *dst_size, src, src_size);
@@ -2155,25 +2114,27 @@ static int append(uint8_t **dst, unsigned *dst_size, const unsigned char *src, u
return ASN1_SUCCESS;
}
-/**
- * asn1_decode_simple_ber:
+/*-
+ * _asn1_decode_simple_ber:
* @etype: The type of the string to be encoded (ASN1_ETYPE_)
* @der: the encoded string
* @_der_len: the bytes of the encoded string
* @str: a pointer to the data
* @str_len: the length of the data
* @ber_len: the total length occupied by BER (may be %NULL)
+ * @have_tag: whether a DER tag is included
*
* Decodes a BER encoded type. The output is an allocated value
* of the data. This decodes BER STRINGS only. Other types are
* decoded as DER.
*
* Returns: %ASN1_SUCCESS if successful or an error value.
- **/
-int
-asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
+ -*/
+static int
+_asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
unsigned int _der_len, unsigned char **str,
- unsigned int *str_len, unsigned int *ber_len)
+ unsigned int *str_len, unsigned int *ber_len,
+ unsigned dflags)
{
int tag_len, len_len;
const unsigned char *p;
@@ -2183,8 +2144,9 @@ asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
unsigned char class;
unsigned long tag;
unsigned char *out = NULL;
+ const unsigned char *cout = NULL;
unsigned out_len;
- long ret;
+ long result;
if (ber_len) *ber_len = 0;
@@ -2200,53 +2162,52 @@ asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
return ASN1_VALUE_NOT_VALID;
}
- /* doesn't handle constructed classes */
- if (ETYPE_CLASS (etype) != ASN1_CLASS_UNIVERSAL)
+ /* doesn't handle constructed + definite classes */
+ class = ETYPE_CLASS (etype);
+ if (class != ASN1_CLASS_UNIVERSAL)
{
warn();
return ASN1_VALUE_NOT_VALID;
}
p = der;
- ret = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag);
- if (ret != ASN1_SUCCESS)
+
+ if (dflags & DECODE_FLAG_HAVE_TAG)
{
- warn();
- return ret;
- }
+ result = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag);
+ if (result != ASN1_SUCCESS)
+ {
+ warn();
+ return result;
+ }
- if (ber_len) *ber_len += tag_len;
+ if (tag != ETYPE_TAG (etype))
+ {
+ warn();
+ return ASN1_DER_ERROR;
+ }
- if (tag != ETYPE_TAG (etype))
- {
- warn();
- return ASN1_DER_ERROR;
- }
+ p += tag_len;
- p += tag_len;
- der_len -= tag_len;
- if (der_len <= 0)
- return ASN1_DER_ERROR;
+ DECR_LEN(der_len, tag_len);
- if (class == ASN1_CLASS_STRUCTURED && (etype == ASN1_ETYPE_GENERALSTRING ||
- etype == ASN1_ETYPE_NUMERIC_STRING || etype == ASN1_ETYPE_IA5_STRING ||
- etype == ASN1_ETYPE_TELETEX_STRING || etype == ASN1_ETYPE_PRINTABLE_STRING ||
- etype == ASN1_ETYPE_UNIVERSAL_STRING || etype == ASN1_ETYPE_BMP_STRING ||
- etype == ASN1_ETYPE_UTF8_STRING || etype == ASN1_ETYPE_VISIBLE_STRING ||
- etype == ASN1_ETYPE_OCTET_STRING))
- {
+ if (ber_len) *ber_len += tag_len;
+ }
+ /* indefinite constructed */
+ if (((dflags & DECODE_FLAG_INDEFINITE) || class == ASN1_CLASS_STRUCTURED) && ETYPE_IS_STRING(etype))
+ {
len_len = 1;
+
+ DECR_LEN(der_len, len_len);
if (p[0] != 0x80)
{
warn();
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
p += len_len;
- der_len -= len_len;
- if (der_len <= 0)
- return ASN1_DER_ERROR;
if (ber_len) *ber_len += len_len;
@@ -2255,38 +2216,48 @@ asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
{
unsigned tmp_len;
- ret = asn1_decode_simple_ber(etype, p, der_len, &out, &out_len, &tmp_len);
- if (ret != ASN1_SUCCESS)
+ result = asn1_decode_simple_ber(etype, p, der_len, &out, &out_len, &tmp_len);
+ if (result != ASN1_SUCCESS)
{
- free(total);
- return ret;
+ warn();
+ goto cleanup;
}
+
p += tmp_len;
- der_len -= tmp_len;
+ DECR_LEN(der_len, tmp_len);
+
if (ber_len) *ber_len += tmp_len;
- if (der_len < 2) /* we need the EOC */
- {
- free(total);
- return ASN1_DER_ERROR;
- }
+ DECR_LEN(der_len, 2); /* we need the EOC */
if (out_len > 0)
{
- ret = append(&total, &total_size, out, out_len);
- free(out);
- if (ret != ASN1_SUCCESS)
+ result = append(&total, &total_size, out, out_len);
+ if (result != ASN1_SUCCESS)
{
- free(total);
- return ret;
+ warn();
+ goto cleanup;
}
}
+ free(out);
+ out = NULL;
+
if (p[0] == 0 && p[1] == 0) /* EOC */
{
if (ber_len) *ber_len += 2;
break;
}
+
+ /* no EOC */
+ der_len += 2;
+
+ if (der_len == 2)
+ {
+ warn();
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
}
while(1);
}
@@ -2294,29 +2265,67 @@ asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
{
if (ber_len)
{
- ret = asn1_get_length_der (p, der_len, &len_len);
- if (ret < 0)
+ result = asn1_get_length_der (p, der_len, &len_len);
+ if (result < 0)
{
warn();
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
- *ber_len += ret + len_len;
+ *ber_len += result + len_len;
}
/* non-string values are decoded as DER */
- ret = asn1_decode_simple_der(etype, der, _der_len, (const unsigned char**)&out, &out_len);
- if (ret != ASN1_SUCCESS)
- return ret;
+ result = _asn1_decode_simple_der(etype, der, _der_len, &cout, &out_len, dflags);
+ if (result != ASN1_SUCCESS)
+ {
+ warn();
+ goto cleanup;
+ }
- ret = append(&total, &total_size, out, out_len);
- if (ret != ASN1_SUCCESS)
- return ret;
+ result = append(&total, &total_size, cout, out_len);
+ if (result != ASN1_SUCCESS)
+ {
+ warn();
+ goto cleanup;
+ }
}
else
- return ASN1_DER_ERROR;
+ {
+ warn();
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
*str = total;
*str_len = total_size;
return ASN1_SUCCESS;
+cleanup:
+ free(out);
+ free(total);
+ return result;
+}
+
+/**
+ * asn1_decode_simple_ber:
+ * @etype: The type of the string to be encoded (ASN1_ETYPE_)
+ * @der: the encoded string
+ * @_der_len: the bytes of the encoded string
+ * @str: a pointer to the data
+ * @str_len: the length of the data
+ * @ber_len: the total length occupied by BER (may be %NULL)
+ *
+ * Decodes a BER encoded type. The output is an allocated value
+ * of the data. This decodes BER STRINGS only. Other types are
+ * decoded as DER.
+ *
+ * Returns: %ASN1_SUCCESS if successful or an error value.
+ **/
+int
+asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
+ unsigned int _der_len, unsigned char **str,
+ unsigned int *str_len, unsigned int *ber_len)
+{
+ return _asn1_decode_simple_ber(etype, der, _der_len, str, str_len, ber_len, DECODE_FLAG_HAVE_TAG);
}
diff --git a/lib/minitasn1/element.c b/lib/minitasn1/element.c
index 321302af06..dceb8ba83e 100644
--- a/lib/minitasn1/element.c
+++ b/lib/minitasn1/element.c
@@ -52,7 +52,7 @@ _asn1_hierarchical_name (asn1_node node, char *name, int name_size)
_asn1_str_cat (name, name_size, ".");
_asn1_str_cat (name, name_size, tmp_name);
}
- p = _asn1_get_up (p);
+ p = _asn1_find_up (p);
}
if (name[0] == 0)
@@ -132,14 +132,14 @@ _asn1_convert_integer (const unsigned char *value, unsigned char *value_out,
* node. The new element will have a name of '?number', where number
* is a monotonically increased serial number.
*
- * The last element in the list may be provided in @ptail, to avoid
+ * The last element in the list may be provided in @pcache, to avoid
* traversing the list, an expensive operation in long lists.
*
- * On success it returns in @ptail the added element (which is the
+ * On success it returns in @pcache the added element (which is the
* tail in the list of added elements).
*/
int
-_asn1_append_sequence_set (asn1_node node, asn1_node *ptail)
+_asn1_append_sequence_set (asn1_node node, struct node_tail_cache_st *pcache)
{
asn1_node p, p2;
char temp[LTOSTR_MAX_SIZE];
@@ -154,18 +154,24 @@ _asn1_append_sequence_set (asn1_node node, asn1_node *ptail)
p = p->right;
p2 = _asn1_copy_structure3 (p);
- if (ptail == NULL || *ptail == NULL || (*ptail)->up != p->up)
- while (p->right) {
- p = p->right;
+ if (pcache == NULL || pcache->tail == NULL || pcache->head != node)
+ {
+ while (p->right)
+ {
+ p = p->right;
+ }
}
else
{
- p = *ptail;
+ p = pcache->tail;
}
_asn1_set_right (p, p2);
- if (ptail)
- *ptail = p2;
+ if (pcache)
+ {
+ pcache->head = node;
+ pcache->tail = p2;
+ }
if (p->name[0] == 0)
_asn1_str_cpy (temp, sizeof (temp), "?1");
diff --git a/lib/minitasn1/element.h b/lib/minitasn1/element.h
index 65a4845699..4e45367415 100644
--- a/lib/minitasn1/element.h
+++ b/lib/minitasn1/element.h
@@ -23,7 +23,13 @@
#define _ELEMENT_H
-int _asn1_append_sequence_set (asn1_node node, asn1_node *pcached);
+struct node_tail_cache_st
+{
+ asn1_node head; /* the first element of the sequence */
+ asn1_node tail;
+};
+
+int _asn1_append_sequence_set (asn1_node node, struct node_tail_cache_st *pcached);
int _asn1_convert_integer (const unsigned char *value,
unsigned char *value_out,
diff --git a/lib/minitasn1/int.h b/lib/minitasn1/int.h
index 8cc79cca2e..f1f13024e4 100644
--- a/lib/minitasn1/int.h
+++ b/lib/minitasn1/int.h
@@ -51,7 +51,6 @@ struct asn1_node_st
unsigned int type; /* Node type */
unsigned char *value; /* Node value */
int value_len;
- asn1_node up; /* Pointer to the parent node */
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 */
@@ -98,9 +97,16 @@ typedef struct tag_and_class_st
#define ETYPE_TAG(etype) (_asn1_tags[etype].tag)
#define ETYPE_CLASS(etype) (_asn1_tags[etype].class)
-#define ETYPE_OK(etype) ((etype != ASN1_ETYPE_INVALID && \
- etype <= _asn1_tags_size && \
- _asn1_tags[etype].desc != NULL)?1:0)
+#define ETYPE_OK(etype) (((etype) != ASN1_ETYPE_INVALID && \
+ (etype) <= _asn1_tags_size && \
+ _asn1_tags[(etype)].desc != NULL)?1:0)
+
+#define ETYPE_IS_STRING(etype) ((etype == ASN1_ETYPE_GENERALSTRING || \
+ etype == ASN1_ETYPE_NUMERIC_STRING || etype == ASN1_ETYPE_IA5_STRING || \
+ etype == ASN1_ETYPE_TELETEX_STRING || etype == ASN1_ETYPE_PRINTABLE_STRING || \
+ etype == ASN1_ETYPE_UNIVERSAL_STRING || etype == ASN1_ETYPE_BMP_STRING || \
+ etype == ASN1_ETYPE_UTF8_STRING || etype == ASN1_ETYPE_VISIBLE_STRING || \
+ etype == ASN1_ETYPE_OCTET_STRING)?1:0)
extern unsigned int _asn1_tags_size;
extern const tag_and_class_st _asn1_tags[];
@@ -191,4 +197,20 @@ convert_old_type (unsigned int ntype)
return ntype;
}
+static inline
+void *_asn1_realloc(void *ptr, size_t size)
+{
+ void *ret;
+
+ if (size == 0)
+ return ptr;
+
+ ret = realloc(ptr, size);
+ if (ret == NULL)
+ {
+ free(ptr);
+ }
+ return ret;
+}
+
#endif /* INT_H */
diff --git a/lib/minitasn1/libtasn1.h b/lib/minitasn1/libtasn1.h
index 53cec5e6a1..aa9e8a480c 100644
--- a/lib/minitasn1/libtasn1.h
+++ b/lib/minitasn1/libtasn1.h
@@ -44,7 +44,7 @@ extern "C"
{
#endif
-#define ASN1_VERSION "4.4"
+#define ASN1_VERSION "4.8"
#if defined(__GNUC__) && !defined(ASN1_INTERNAL_BUILD)
# define _ASN1_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
@@ -374,6 +374,11 @@ extern "C"
int *ret_len, unsigned char *str,
int str_size, int *bit_len);
+ extern ASN1_API int
+ asn1_get_object_id_der (const unsigned char *der,
+ int der_len, int *ret_len,
+ char *str, int str_size);
+
/* Compatibility types */
typedef int asn1_retCode; /* type returned by libtasn1 functions */
diff --git a/lib/minitasn1/parser_aux.c b/lib/minitasn1/parser_aux.c
index da9a388fe3..52700c6d0a 100644
--- a/lib/minitasn1/parser_aux.c
+++ b/lib/minitasn1/parser_aux.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ * Copyright (C) 2000-2016 Free Software Foundation, Inc.
*
* This file is part of LIBTASN1.
*
@@ -316,39 +316,49 @@ _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)
+
+ if (node->value == NULL)
+ return _asn1_set_value (node, value, len);
+
+ if (len == 0)
+ return node;
+
+ if (node->value == node->small_value)
{
- /* value is allocated */
+ /* value is in node */
int prev_len = node->value_len;
node->value_len += len;
- node->value = realloc (node->value, node->value_len);
+ node->value = malloc (node->value_len);
if (node->value == NULL)
{
node->value_len = 0;
return NULL;
}
+
+ if (prev_len > 0)
+ memcpy (node->value, node->small_value, prev_len);
+
memcpy (&node->value[prev_len], value, len);
return node;
}
- else if (node->value == node->small_value)
+ else /* if (node->value != NULL && node->value != node->small_value) */
{
- /* value is in node */
+ /* value is allocated */
int prev_len = node->value_len;
node->value_len += len;
- node->value = malloc (node->value_len);
+
+ node->value = _asn1_realloc (node->value, 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);
}
/******************************************************************/
@@ -425,11 +435,7 @@ _asn1_set_right (asn1_node node, asn1_node right)
return node;
node->right = right;
if (right)
- {
- right->left = node;
- if (right->up == NULL)
- right->up = node->up;
- }
+ right->left = node;
return node;
}
@@ -625,7 +631,7 @@ _asn1_change_integer_value (asn1_node node)
{
while (1)
{
- p = _asn1_get_up (p);
+ p = _asn1_find_up (p);
if (p == node)
{
p = NULL;
@@ -753,7 +759,7 @@ _asn1_expand_object_id (asn1_node node)
move = UP;
}
if (move == UP)
- p = _asn1_get_up (p);
+ p = _asn1_find_up (p);
}
@@ -786,6 +792,9 @@ _asn1_expand_object_id (asn1_node node)
{
if (type_field (p4->type) == ASN1_ETYPE_CONSTANT)
{
+ if (p4->value == NULL)
+ return ASN1_VALUE_NOT_FOUND;
+
if (name2[0])
_asn1_str_cat (name2, sizeof (name2), ".");
_asn1_str_cat (name2, sizeof (name2),
@@ -825,7 +834,7 @@ _asn1_expand_object_id (asn1_node node)
move = UP;
}
if (move == UP)
- p = _asn1_get_up (p);
+ p = _asn1_find_up (p);
}
return ASN1_SUCCESS;
@@ -895,7 +904,7 @@ _asn1_type_set_config (asn1_node node)
move = UP;
}
if (move == UP)
- p = _asn1_get_up (p);
+ p = _asn1_find_up (p);
}
return ASN1_SUCCESS;
@@ -992,7 +1001,7 @@ _asn1_check_identifier (asn1_node node)
{
while (1)
{
- p = _asn1_get_up (p);
+ p = _asn1_find_up (p);
if (p == node)
{
p = NULL;
@@ -1052,7 +1061,7 @@ _asn1_set_default_tag (asn1_node node)
{
while (1)
{
- p = _asn1_get_up (p);
+ p = _asn1_find_up (p);
if (p == node)
{
p = NULL;
diff --git a/lib/minitasn1/parser_aux.h b/lib/minitasn1/parser_aux.h
index 437f1c863f..10b864b0f5 100644
--- a/lib/minitasn1/parser_aux.h
+++ b/lib/minitasn1/parser_aux.h
@@ -58,14 +58,6 @@ char *_asn1_ltostr (long v, char str[LTOSTR_MAX_SIZE]);
asn1_node _asn1_find_up (asn1_node node);
-inline static asn1_node _asn1_get_up(asn1_node node)
-{
- if (node && node->up)
- return node->up;
- else
- return _asn1_find_up(node);
-}
-
int _asn1_change_integer_value (asn1_node node);
int _asn1_expand_object_id (asn1_node node);
@@ -108,10 +100,7 @@ _asn1_set_down (asn1_node node, asn1_node down)
return node;
node->down = down;
if (down)
- {
- down->left = node;
- down->up = node;
- }
+ down->left = node;
return node;
}
diff --git a/lib/minitasn1/structure.c b/lib/minitasn1/structure.c
index ffb6aa5092..01715b138b 100644
--- a/lib/minitasn1/structure.c
+++ b/lib/minitasn1/structure.c
@@ -134,7 +134,7 @@ _asn1_create_static_structure (asn1_node pointer, char *output_file_name,
{
while (1)
{
- p = _asn1_get_up (p);
+ p = _asn1_find_up (p);
if (p == pointer)
{
p = NULL;
@@ -183,6 +183,8 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions,
int result;
unsigned int type;
+ if (errorDescription)
+ errorDescription[0] = 0;
if (*definitions != NULL)
return ASN1_ELEMENT_NOT_EMPTY;
@@ -221,7 +223,7 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions,
if (p_last == *definitions)
break;
- p_last = _asn1_get_up (p_last);
+ p_last = _asn1_find_up (p_last);
if (p_last == NULL)
break;
@@ -321,7 +323,7 @@ asn1_delete_structure2 (asn1_node * structure, unsigned int flags)
p2 = p->right;
if (p != *structure)
{
- p3 = _asn1_get_up (p);
+ p3 = _asn1_find_up (p);
_asn1_set_down (p3, p2);
_asn1_remove_node (p, flags);
p = p3;
@@ -331,7 +333,7 @@ asn1_delete_structure2 (asn1_node * structure, unsigned int flags)
p3 = _asn1_find_left (p);
if (!p3)
{
- p3 = _asn1_get_up (p);
+ p3 = _asn1_find_up (p);
if (p3)
_asn1_set_down (p3, p2);
else
@@ -379,7 +381,7 @@ asn1_delete_element (asn1_node structure, const char *element_name)
p3 = _asn1_find_left (source_node);
if (!p3)
{
- p3 = _asn1_get_up (source_node);
+ p3 = _asn1_find_up (source_node);
if (p3)
_asn1_set_down (p3, p2);
else if (source_node->right)
@@ -441,8 +443,8 @@ _asn1_copy_structure3 (asn1_node source_node)
else
{
move = UP;
- p_s = _asn1_get_up (p_s);
- p_d = _asn1_get_up (p_d);
+ p_s = _asn1_find_up (p_s);
+ p_d = _asn1_find_up (p_d);
}
}
while (p_s != source_node);
@@ -542,7 +544,7 @@ _asn1_type_choice_config (asn1_node node)
move = UP;
}
if (move == UP)
- p = _asn1_get_up (p);
+ p = _asn1_find_up (p);
}
return ASN1_SUCCESS;
@@ -593,7 +595,7 @@ _asn1_expand_identifier (asn1_node * node, asn1_node root)
_asn1_set_right (p3, p2);
else
{
- p3 = _asn1_get_up (p);
+ p3 = _asn1_find_up (p);
if (p3)
_asn1_set_down (p3, p2);
else
@@ -649,7 +651,7 @@ _asn1_expand_identifier (asn1_node * node, asn1_node root)
move = UP;
}
if (move == UP)
- p = _asn1_get_up (p);
+ p = _asn1_find_up (p);
}
return ASN1_SUCCESS;
@@ -832,7 +834,7 @@ asn1_print_structure (FILE * out, asn1_node structure, const char *name,
fprintf (out, " value:0x");
if (len > 0)
for (k = 0; k < len; k++)
- fprintf (out, "%02x", (p->value)[k + len2]);
+ fprintf (out, "%02x", (unsigned) (p->value)[k + len2]);
}
break;
case ASN1_ETYPE_ENUMERATED:
@@ -843,7 +845,7 @@ asn1_print_structure (FILE * out, asn1_node structure, const char *name,
fprintf (out, " value:0x");
if (len > 0)
for (k = 0; k < len; k++)
- fprintf (out, "%02x", (p->value)[k + len2]);
+ fprintf (out, "%02x", (unsigned) (p->value)[k + len2]);
}
break;
case ASN1_ETYPE_BOOLEAN:
@@ -865,7 +867,7 @@ asn1_print_structure (FILE * out, asn1_node structure, const char *name,
fprintf (out, " value(%i):",
(len - 1) * 8 - (p->value[len2]));
for (k = 1; k < len; k++)
- fprintf (out, "%02x", (p->value)[k + len2]);
+ fprintf (out, "%02x", (unsigned) (p->value)[k + len2]);
}
}
break;
@@ -905,7 +907,7 @@ asn1_print_structure (FILE * out, asn1_node structure, const char *name,
fprintf (out, " value:");
if (len > 0)
for (k = 0; k < len; k++)
- fprintf (out, "%02x", (p->value)[k + len2]);
+ fprintf (out, "%02x", (unsigned) (p->value)[k + len2]);
}
break;
case ASN1_ETYPE_OBJECT_ID:
@@ -920,7 +922,7 @@ asn1_print_structure (FILE * out, asn1_node structure, const char *name,
fprintf (out, " value:");
if (len2 > 0)
for (k = 0; k < len2; k++)
- fprintf (out, "%02x", (p->value)[k + len3]);
+ fprintf (out, "%02x", (unsigned) (p->value)[k + len3]);
}
break;
case ASN1_ETYPE_SET:
@@ -1017,7 +1019,7 @@ asn1_print_structure (FILE * out, asn1_node structure, const char *name,
{
while (1)
{
- p = _asn1_get_up (p);
+ p = _asn1_find_up (p);
if (p == root)
{
p = NULL;