summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2017-05-27 07:31:21 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2017-05-27 07:31:21 +0200
commitfe40b44c07fd8aed9ca7c942eb16789765cecc4b (patch)
tree47b2fc1f1a8328118dda0e32ce28edd7adb35513
parent085aa25d09db57f0ccb60305439478696ba2c47d (diff)
downloadgnutls-fe40b44c07fd8aed9ca7c942eb16789765cecc4b.tar.gz
libtasn1: updated to 4.11
Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
-rw-r--r--lib/minitasn1/decoding.c39
-rw-r--r--lib/minitasn1/element.c8
-rw-r--r--lib/minitasn1/errors.c1
-rw-r--r--lib/minitasn1/libtasn1.h5
-rw-r--r--lib/minitasn1/parser_aux.c24
5 files changed, 55 insertions, 22 deletions
diff --git a/lib/minitasn1/decoding.c b/lib/minitasn1/decoding.c
index 9ac1131f5c..2240b09406 100644
--- a/lib/minitasn1/decoding.c
+++ b/lib/minitasn1/decoding.c
@@ -114,7 +114,7 @@ asn1_get_length_der (const unsigned char *der, int der_len, int *len)
k = der[0] & 0x7F;
punt = 1;
if (k)
- { /* definite length method */
+ { /* definite length method */
ans = 0;
while (punt <= k && punt < der_len)
{
@@ -154,7 +154,7 @@ asn1_get_length_der (const unsigned char *der, int der_len, int *len)
* @der_len: Length of DER data to decode.
* @cls: Output variable containing decoded class.
* @len: Output variable containing the length of the DER TAG data.
- * @tag: Output variable containing the decoded tag.
+ * @tag: Output variable containing the decoded tag (may be %NULL).
*
* Decode the class and TAG from DER code.
*
@@ -237,9 +237,9 @@ asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len)
long err;
ret = asn1_get_length_der (ber, ber_len, len);
- if (ret == -1)
+ if (ret == -1 && ber_len > 1)
{ /* indefinite length method */
- err = _asn1_get_indefinite_length_string (ber + 1, ber_len, &ret);
+ err = _asn1_get_indefinite_length_string (ber + 1, ber_len-1, &ret);
if (err != ASN1_SUCCESS)
return -3;
}
@@ -329,10 +329,10 @@ _asn1_get_time_der (unsigned type, const unsigned char *der, int der_len, int *r
if (str_len < 8)
{
warn();
- return ASN1_DER_ERROR;
+ return ASN1_TIME_ENCODING_ERROR;
}
- if (flags & ASN1_DECODE_FLAG_STRICT_DER)
+ if ((flags & ASN1_DECODE_FLAG_STRICT_DER) && !(flags & ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME))
{
p = &der[len_len];
for (i=0;i<(unsigned)(str_len-1);i++)
@@ -359,14 +359,14 @@ _asn1_get_time_der (unsigned type, const unsigned char *der, int der_len, int *r
}
warn();
- return ASN1_DER_ERROR;
+ return ASN1_TIME_ENCODING_ERROR;
}
}
if (sign_count == 0 && p[str_len-1] != 'Z')
{
warn();
- return ASN1_DER_ERROR;
+ return ASN1_TIME_ENCODING_ERROR;
}
}
memcpy (str, der + len_len, str_len);
@@ -1305,7 +1305,12 @@ 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, &tcache);
+ result = _asn1_append_sequence_set (p, &tcache);
+ if (result != 0)
+ {
+ warn();
+ goto cleanup;
+ }
p = tcache.tail;
move = RIGHT;
continue;
@@ -1321,7 +1326,12 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
{ /* definite length method */
if (len2 > counter)
{
- _asn1_append_sequence_set (p, &tcache);
+ result = _asn1_append_sequence_set (p, &tcache);
+ if (result != 0)
+ {
+ warn();
+ goto cleanup;
+ }
p = tcache.tail;
move = RIGHT;
continue;
@@ -1375,7 +1385,14 @@ 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, &tcache);
+ {
+ result = _asn1_append_sequence_set (p, &tcache);
+ if (result != 0)
+ {
+ warn();
+ goto cleanup;
+ }
+ }
p = p2;
}
}
diff --git a/lib/minitasn1/element.c b/lib/minitasn1/element.c
index 3ae7740d1a..b09f82647f 100644
--- a/lib/minitasn1/element.c
+++ b/lib/minitasn1/element.c
@@ -128,7 +128,7 @@ _asn1_convert_integer (const unsigned char *value, unsigned char *value_out,
return ASN1_SUCCESS;
}
-/* Appends a new element into the sequent (or set) defined by this
+/* Appends a new element into the sequence (or set) defined by this
* node. The new element will have a name of '?number', where number
* is a monotonically increased serial number.
*
@@ -753,7 +753,8 @@ asn1_write_value (asn1_node node_root, const char *name,
* %ASN1_VALUE_NOT_FOUND if there isn't any value for the element
* selected, and %ASN1_MEM_ERROR if The value vector isn't big enough
* to store the result, and in this case @len will contain the number of
- * bytes needed.
+ * bytes needed. On the occasion that the stored data are of zero-length
+ * this function may return %ASN1_SUCCESS even if the provided @len is zero.
**/
int
asn1_read_value (asn1_node root, const char *name, void *ivalue, int *len)
@@ -826,7 +827,8 @@ asn1_read_value (asn1_node root, const char *name, void *ivalue, int *len)
* %ASN1_VALUE_NOT_FOUND if there isn't any value for the element
* selected, and %ASN1_MEM_ERROR if The value vector isn't big enough
* to store the result, and in this case @len will contain the number of
- * bytes needed.
+ * bytes needed. On the occasion that the stored data are of zero-length
+ * this function may return %ASN1_SUCCESS even if the provided @len is zero.
**/
int
asn1_read_value_type (asn1_node root, const char *name, void *ivalue,
diff --git a/lib/minitasn1/errors.c b/lib/minitasn1/errors.c
index e9fa302605..fef45ae742 100644
--- a/lib/minitasn1/errors.c
+++ b/lib/minitasn1/errors.c
@@ -52,6 +52,7 @@ static const libtasn1_error_entry error_algorithms[] = {
LIBTASN1_ERROR_ENTRY (ASN1_NAME_TOO_LONG),
LIBTASN1_ERROR_ENTRY (ASN1_ARRAY_ERROR),
LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_EMPTY),
+ LIBTASN1_ERROR_ENTRY (ASN1_TIME_ENCODING_ERROR),
{0, 0}
};
diff --git a/lib/minitasn1/libtasn1.h b/lib/minitasn1/libtasn1.h
index 9a41780204..4ee4c54e60 100644
--- a/lib/minitasn1/libtasn1.h
+++ b/lib/minitasn1/libtasn1.h
@@ -44,7 +44,7 @@ extern "C"
{
#endif
-#define ASN1_VERSION "4.9"
+#define ASN1_VERSION "4.11"
#if defined(__GNUC__) && !defined(ASN1_INTERNAL_BUILD)
# define _ASN1_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
@@ -78,6 +78,7 @@ extern "C"
#define ASN1_NAME_TOO_LONG 15
#define ASN1_ARRAY_ERROR 16
#define ASN1_ELEMENT_NOT_EMPTY 17
+#define ASN1_TIME_ENCODING_ERROR 18
/*************************************/
/* Constants used in asn1_visit_tree */
@@ -190,6 +191,8 @@ extern "C"
#define ASN1_DECODE_FLAG_ALLOW_PADDING 1
/* This flag would ensure that no BER decoding takes place */
#define ASN1_DECODE_FLAG_STRICT_DER (1<<1)
+/* This flag will tolerate Time encoding errors when in strict DER */
+#define ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME (1<<2)
struct asn1_data_node_st
diff --git a/lib/minitasn1/parser_aux.c b/lib/minitasn1/parser_aux.c
index cfd76e0b17..976ab38f18 100644
--- a/lib/minitasn1/parser_aux.c
+++ b/lib/minitasn1/parser_aux.c
@@ -120,6 +120,9 @@ asn1_find_node (asn1_node pointer, const char *name)
if (n_end)
{
nsize = n_end - n_start;
+ if (nsize >= sizeof(n))
+ return NULL;
+
memcpy (n, n_start, nsize);
n[nsize] = 0;
n_start = n_end;
@@ -158,6 +161,9 @@ asn1_find_node (asn1_node pointer, const char *name)
if (n_end)
{
nsize = n_end - n_start;
+ if (nsize >= sizeof(n))
+ return NULL;
+
memcpy (n, n_start, nsize);
n[nsize] = 0;
n_start = n_end;
@@ -551,29 +557,33 @@ _asn1_delete_list_and_nodes (void)
char *
_asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE])
{
- int64_t d, r;
+ uint64_t d, r;
char temp[LTOSTR_MAX_SIZE];
int count, k, start;
+ uint64_t val;
if (v < 0)
{
str[0] = '-';
start = 1;
- v = -v;
+ val = -((uint64_t)v);
}
else
- start = 0;
+ {
+ val = v;
+ start = 0;
+ }
count = 0;
do
{
- d = v / 10;
- r = v - d * 10;
+ d = val / 10;
+ r = val - d * 10;
temp[start + count] = '0' + (char) r;
count++;
- v = d;
+ val = d;
}
- while (v && ((start+count) < LTOSTR_MAX_SIZE-1));
+ while (val && ((start+count) < LTOSTR_MAX_SIZE-1));
for (k = 0; k < count; k++)
str[k + start] = temp[start + count - k - 1];