summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2014-05-22 23:33:08 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2014-05-22 23:33:08 +0200
commit53958290ab731c8486531a3bdef54a933533579d (patch)
treead91281ee6f0ab20ef6ba7a93f1bf2838c79cc41
parent99af70b17ad87e910c528c9203f261bf4e513f54 (diff)
downloadlibtasn1-53958290ab731c8486531a3bdef54a933533579d.tar.gz
libtasn1-53958290ab731c8486531a3bdef54a933533579d.tar.bz2
libtasn1-53958290ab731c8486531a3bdef54a933533579d.zip
Allow a NULL value in asn1_read_value() for all types.
-rw-r--r--lib/decoding.c6
-rw-r--r--lib/element.c46
2 files changed, 31 insertions, 21 deletions
diff --git a/lib/decoding.c b/lib/decoding.c
index 93bc962..90a37ff 100644
--- a/lib/decoding.c
+++ b/lib/decoding.c
@@ -254,7 +254,6 @@ asn1_get_octet_der (const unsigned char *der, int der_len,
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_len < 0)
@@ -263,7 +262,7 @@ asn1_get_octet_der (const unsigned char *der, int der_len,
*ret_len = *str_len + len_len;
if (str_size >= *str_len)
{
- if (*str_len > 0)
+ if (*str_len > 0 && str != NULL)
memcpy (str, der + len_len, *str_len);
}
else
@@ -380,6 +379,7 @@ asn1_get_bit_der (const unsigned char *der, int der_len,
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;
@@ -392,7 +392,7 @@ asn1_get_bit_der (const unsigned char *der, int der_len,
if (str_size >= len_byte)
{
- if (len_byte > 0)
+ if (len_byte > 0 && str)
memcpy (str, der + len_len + 1, len_byte);
}
else
diff --git a/lib/element.c b/lib/element.c
index 359b3ab..ac30e46 100644
--- a/lib/element.c
+++ b/lib/element.c
@@ -112,8 +112,11 @@ _asn1_convert_integer (const unsigned char *value, unsigned char *value_out,
/* 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];
+ if (value_out != NULL)
+ {
+ 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);
@@ -650,31 +653,34 @@ asn1_write_value (asn1_node node_root, const char *name,
}
#define ADD_STR_VALUE( ptr, ptr_size, data) \
- *len = (int) _asn1_strlen (data) + 1; \
- if (ptr_size < (int) _asn1_strlen (ptr) + (*len)) { \
- return ASN1_MEM_ERROR; \
- } else { \
- /* this strcat is checked */ \
- if (ptr) _asn1_strcat (ptr, data); \
- }
+ *len += _asn1_strlen(data); \
+ if (ptr_size < (int) *len) { \
+ (*len)++; \
+ return ASN1_MEM_ERROR; \
+ } else { \
+ /* this strcat is checked */ \
+ if (ptr) _asn1_strcat (ptr, data); \
+ }
/**
* asn1_read_value:
* @root: pointer to a structure.
* @name: the name of the element inside a structure that you want to read.
* @ivalue: vector that will contain the element's content, must be a
- * pointer to memory cells already allocated.
+ * pointer to memory cells already allocated (may be %NULL).
* @len: number of bytes of *value: value[0]..value[len-1]. Initialy
* holds the sizeof value.
*
- * Returns the value of one element inside a structure.
- *
- * If an element is OPTIONAL and the function "read_value" returns
+ * Returns the value of one element inside a structure.
+ * If an element is OPTIONAL and this returns
* %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present
* in the der encoding that created the structure. The first element
* of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and
* so on.
*
+ * Note that there can be valid values with length zero. In these case
+ * this function will succeed and @len will be zero.
+ *
* INTEGER: VALUE will contain a two's complement form integer.
*
* integer=-1 -> value[0]=0xFF , len=1.
@@ -730,19 +736,22 @@ asn1_read_value (asn1_node root, const char *name, void *ivalue, int *len)
* @root: pointer to a structure.
* @name: the name of the element inside a structure that you want to read.
* @ivalue: vector that will contain the element's content, must be a
- * pointer to memory cells already allocated.
+ * pointer to memory cells already allocated (may be %NULL).
* @len: number of bytes of *value: value[0]..value[len-1]. Initialy
* holds the sizeof value.
* @etype: The type of the value read (ASN1_ETYPE)
*
- * Returns the value of one element inside a structure.
- *
- * If an element is OPTIONAL and the function "read_value" returns
+ * Returns the value of one element inside a structure.
+ * If an element is OPTIONAL and this returns
* %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present
* in the der encoding that created the structure. The first element
* of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and
* so on.
*
+ * Note that there can be valid values with length zero. In these case
+ * this function will succeed and @len will be zero.
+ *
+ *
* INTEGER: VALUE will contain a two's complement form integer.
*
* integer=-1 -> value[0]=0xFF , len=1.
@@ -889,6 +898,7 @@ asn1_read_value_type (asn1_node root, const char *name, void *ivalue,
case ASN1_ETYPE_OBJECT_ID:
if (node->type & CONST_ASSIGN)
{
+ *len = 0;
if (value)
value[0] = 0;
p = node->down;
@@ -904,7 +914,7 @@ asn1_read_value_type (asn1_node root, const char *name, void *ivalue,
}
p = p->right;
}
- *len = _asn1_strlen (value) + 1;
+ (*len)++;
}
else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
{