libtasn1-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU libtasn1 branch, master, updated. libtasn1_4_2-7-g58f8a02


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU libtasn1 branch, master, updated. libtasn1_4_2-7-g58f8a02
Date: Wed, 04 Mar 2015 13:57:04 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU libtasn1".

http://git.savannah.gnu.org/cgit/libtasn1.git/commit/?id=58f8a0258d5878f84634a160728d4bec307ac3bc

The branch, master has been updated
       via  58f8a0258d5878f84634a160728d4bec307ac3bc (commit)
       via  6ac03e0f45da94db4619ad7e417be255d6ebbfec (commit)
       via  b12bfa8932f44d1d1c25b4a2e385387a62dfbcc9 (commit)
      from  edaff43f27c3e1bcf8317ecee9f733a995602b72 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 58f8a0258d5878f84634a160728d4bec307ac3bc
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Wed Mar 4 14:56:33 2015 +0100

    doc update

commit 6ac03e0f45da94db4619ad7e417be255d6ebbfec
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Wed Mar 4 14:56:00 2015 +0100

    tests: Added tests for asn1_decode_simple_ber

commit b12bfa8932f44d1d1c25b4a2e385387a62dfbcc9
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Wed Mar 4 14:02:59 2015 +0100

    Added asn1_decode_simple_ber()

-----------------------------------------------------------------------

Summary of changes:
 NEWS                 |    3 +
 lib/decoding.c       |  181 +++++++++++++++++++++++++++++++++++++++++++++++++-
 lib/libtasn1.h       |    7 ++
 lib/libtasn1.map     |    1 +
 tests/Test_strings.c |   37 ++++++++++
 5 files changed, 227 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index e2d84da..227bf77 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,8 @@
 GNU Libtasn1 NEWS                                     -*- outline -*-
 
+* Noteworthy changes in release 4.3 (unreleased) [stable]
+- Added asn1_decode_simple_ber()
+
 * Noteworthy changes in release 4.2 (released 2014-09-15) [stable]
 - Added sanity checks in the decoding of time when
   ASN1_DECODE_FLAG_STRICT_DER is used.
diff --git a/lib/decoding.c b/lib/decoding.c
index e206b93..cd9f4d2 100644
--- a/lib/decoding.c
+++ b/lib/decoding.c
@@ -33,6 +33,7 @@
 #include <limits.h>
 #include <intprops.h>
 
+#define DEBUG
 #ifdef DEBUG
 # define warn() fprintf(stderr, "%s: %d\n", __func__, __LINE__)
 #else
@@ -2085,7 +2086,7 @@ asn1_expand_octet_string (asn1_node definitions, 
asn1_node * element,
  * 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
+ * @_der_len: the bytes of the encoded string
  * @str: a pointer to the data
  * @str_len: the length of the data
  *
@@ -2096,11 +2097,12 @@ asn1_expand_octet_string (asn1_node definitions, 
asn1_node * element,
  **/
 int
 asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
-                       unsigned int der_len, const unsigned char **str,
+                       unsigned int _der_len, const unsigned char **str,
                        unsigned int *str_len)
 {
   int tag_len, len_len;
   const unsigned char *p;
+  int der_len = _der_len;
   unsigned char class;
   unsigned long tag;
   long ret;
@@ -2125,6 +2127,8 @@ asn1_decode_simple_der (unsigned int etype, const 
unsigned char *der,
 
   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)
@@ -2132,9 +2136,182 @@ asn1_decode_simple_der (unsigned int etype, const 
unsigned char *der,
 
   p += len_len;
   der_len -= len_len;
+  if (der_len <= 0)
+    return ASN1_DER_ERROR;
 
   *str_len = ret;
   *str = p;
 
   return ASN1_SUCCESS;
 }
+
+static int append(uint8_t **dst, unsigned *dst_size, const uint8_t *src, 
unsigned src_size)
+{
+  *dst = realloc(*dst, *dst_size+src_size);
+  if (*dst == NULL)
+    return ASN1_MEM_ERROR;
+  memcpy(*dst + *dst_size, src, src_size);
+  *dst_size += src_size;
+  return ASN1_SUCCESS;
+}
+
+/**
+ * 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 simple BER encoded type (e.g. a string, which is not constructed).
+ * The output is an allocated value of the data. This function works for
+ * OCTET STRINGS only.
+ *
+ * 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)
+{
+  int tag_len, len_len;
+  const unsigned char *p;
+  int der_len = _der_len;
+  uint8_t *total = NULL;
+  unsigned total_size = 0;
+  unsigned char class;
+  unsigned long tag;
+  long ret;
+
+  if (ber_len) *ber_len = 0;
+
+  if (der == NULL || der_len == 0)
+    {
+      warn();
+      return ASN1_VALUE_NOT_VALID;
+    }
+
+  if (ETYPE_OK (etype) == 0)
+    {
+      warn();
+      return ASN1_VALUE_NOT_VALID;
+    }
+
+  /* doesn't handle constructed classes */
+  if (ETYPE_CLASS (etype) != 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)
+    {
+      warn();
+      return ret;
+    }
+
+  if (ber_len) *ber_len += tag_len;
+
+  if (tag != ETYPE_TAG (etype))
+    {
+      warn();
+      return ASN1_DER_ERROR;
+    }
+
+  if (class == ASN1_CLASS_STRUCTURED)
+    {
+      p += tag_len;
+      der_len -= tag_len;
+      if (der_len <= 0)
+        return ASN1_DER_ERROR;
+
+      ret = asn1_get_length_ber (p, der_len, &len_len);
+      if (ret < 0)
+        {
+          warn();
+          return ASN1_DER_ERROR;
+        }
+
+      p += len_len;
+      der_len -= len_len;
+      if (der_len <= 0)
+        return ASN1_DER_ERROR;
+
+      if (ber_len) *ber_len += ret + len_len;
+
+      /* decode the available octet strings */
+      do
+        {
+          uint8_t *out = NULL;
+          unsigned out_len;
+          unsigned tmp_len;
+
+          ret = asn1_decode_simple_ber(etype, p, der_len, &out, &out_len, 
&tmp_len);
+          if (ret != ASN1_SUCCESS)
+            {
+              free(total);
+              return ret;
+            }
+
+          p += tmp_len;
+          der_len -= tmp_len;
+
+          if (der_len < 2)
+            {
+              free(total);
+              return ASN1_DER_ERROR;
+            }
+
+         if (out_len > 0)
+           {
+              ret = append(&total, &total_size, out, out_len);
+              free(out);
+              if (ret != ASN1_SUCCESS)
+                {
+                  free(total);
+                  return ret;
+                }
+           }
+
+         if (p[0] == 0 && p[1] == 0) /* EOC */
+           break;
+        }
+      while(1);
+    }
+  else if (class == ETYPE_CLASS(etype))
+    {
+      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)
+        {
+          warn();
+          return ASN1_DER_ERROR;
+        }
+
+      p += len_len;
+      der_len -= len_len;
+      if (der_len <= 0)
+        return ASN1_DER_ERROR;
+
+      if (ber_len)
+        *ber_len += len_len + ret;
+
+      ret = append(&total, &total_size, p, ret);
+      if (ret != ASN1_SUCCESS)
+        return ret;
+    }
+  else
+    return ASN1_DER_ERROR;
+
+  *str = total;
+  *str_len = total_size;
+
+  return ASN1_SUCCESS;
+}
diff --git a/lib/libtasn1.h b/lib/libtasn1.h
index ca21a0c..1e9a61e 100644
--- a/lib/libtasn1.h
+++ b/lib/libtasn1.h
@@ -330,6 +330,13 @@ extern "C"
                                const unsigned char **str,
                                unsigned int *str_len);
 
+  extern ASN1_API
+    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);
+
   extern ASN1_API int
     asn1_encode_simple_der (unsigned int etype, const unsigned char *str,
                            unsigned int str_len, unsigned char *tl,
diff --git a/lib/libtasn1.map b/lib/libtasn1.map
index 6424219..d5ffa9e 100644
--- a/lib/libtasn1.map
+++ b/lib/libtasn1.map
@@ -56,6 +56,7 @@ LIBTASN1_0_3
     asn1_read_value_type;
     asn1_delete_structure2;
     asn1_dup_node;
+    asn1_decode_simple_ber;
   local:
     *;
 };
diff --git a/tests/Test_strings.c b/tests/Test_strings.c
index f3d3dba..c68e617 100644
--- a/tests/Test_strings.c
+++ b/tests/Test_strings.c
@@ -54,6 +54,18 @@ static const struct tv tv[] = {
    
"\x04\x24\x30\x22\x80\x0F\x32\x30\x31\x31\x30\x38\x32\x31\x30\x38\x30\x30\x30\x36\x5A\x81\x0F\x32\x30\x31\x31\x30\x38\x32\x33\x32\x30\x35\x39\x35\x39\x5A"}
 };
 
+static const struct tv ber[] = {
+  {ASN1_ETYPE_OCTET_STRING, 
+   2, "\xa0\xa0",
+   10,"\x24\x80\x04\x82\x00\x02\xa0\xa0\x00\x00"},
+  {ASN1_ETYPE_OCTET_STRING,
+   5, "\xa0\xa0\xb0\xb0\xb0",
+   17, "\x24\x80\x04\x82\x00\x02\xa0\xa0\x04\x82\x00\x03\xb0\xb0\xb0\x00\x00"},
+  {ASN1_ETYPE_OCTET_STRING,
+   7, "\xa0\xa0\xb0\xb0\xb0\xa1\xa1",
+   27, 
"\x24\x80\x04\x82\x00\x02\xa0\xa0\x04\x82\x00\x03\xb0\xb0\xb0\x24\x80\x04\x82\x00\x02\xa1\xa1\x00\x00\x00\x00"},
+};
+
 int
 main (int argc, char *argv[])
 {
@@ -61,6 +73,7 @@ main (int argc, char *argv[])
   unsigned char tl[ASN1_MAX_TL_SIZE];
   unsigned int tl_len, der_len, str_len;
   const unsigned char *str;
+  unsigned char *b;
   unsigned int i;
 
   /* Dummy test */
@@ -107,6 +120,30 @@ main (int argc, char *argv[])
        }
     }
 
+  /* BER decoding */
+  for (i = 0; i < sizeof (ber) / sizeof (ber[0]); i++)
+    {
+      /* decoding */
+      ret =
+       asn1_decode_simple_ber (ber[i].etype, ber[i].der, ber[i].der_len, &b,
+                               &str_len, NULL);
+      if (ret != ASN1_SUCCESS)
+       {
+         fprintf (stderr, "BER decoding error in %u: %s\n", i,
+                  asn1_strerror (ret));
+         return 1;
+       }
+
+      if (str_len != ber[i].str_len || memcmp (b, ber[i].str, str_len) != 0)
+       {
+         fprintf (stderr,
+                  "BER decoded data differ in %u! (size: %u, expected: %u)\n",
+                  i, str_len, ber[i].str_len);
+         return 1;
+       }
+      free(b);
+    }
+
 
   return 0;
 }


hooks/post-receive
-- 
GNU libtasn1



reply via email to

[Prev in Thread] Current Thread [Next in Thread]