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_0-12-g9b75d51


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU libtasn1 branch, master, updated. libtasn1_4_0-12-g9b75d51
Date: Wed, 20 Aug 2014 19:43:28 +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=9b75d5101ffc85730ede724d872c9a876cb0a459

The branch, master has been updated
       via  9b75d5101ffc85730ede724d872c9a876cb0a459 (commit)
       via  abbd810e61693945ebe0d10bc3441b12b8fd8a64 (commit)
       via  a01b3760350998b1ed6aab6cfb0f1e88f628ab40 (commit)
       via  2e1b0636c38153623b40944d26df23cb8b05072b (commit)
      from  0b0de9bf1a1e7f87a19d2823a8fa7d83ec41532a (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 9b75d5101ffc85730ede724d872c9a876cb0a459
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Wed Aug 20 21:43:24 2014 +0200

    doc update

commit abbd810e61693945ebe0d10bc3441b12b8fd8a64
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Wed Aug 20 21:42:26 2014 +0200

    tests: Added test for ASN1_DECODE_FLAG_STRICT_DER flag
    
    The PKCS #12 BER encoded data are tested to fail decoding
    if this flag is set.

commit a01b3760350998b1ed6aab6cfb0f1e88f628ab40
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Wed Aug 20 21:35:59 2014 +0200

    doc update

commit 2e1b0636c38153623b40944d26df23cb8b05072b
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Wed Aug 20 21:34:53 2014 +0200

    Added decoding flag ASN1_DECODE_FLAG_STRICT_DER

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

Summary of changes:
 NEWS                                    |    9 +++-
 lib/decoding.c                          |   65 +++++++++++++++--------
 lib/libtasn1.h                          |    4 ++
 tests/Makefile.am                       |    5 +-
 tests/{Test_encoding.c => strict-der.c} |   86 +++++++++++++++---------------
 5 files changed, 100 insertions(+), 69 deletions(-)
 copy tests/{Test_encoding.c => strict-der.c} (56%)

diff --git a/NEWS b/NEWS
index 4faf288..2b700da 100644
--- a/NEWS
+++ b/NEWS
@@ -1,12 +1,17 @@
 GNU Libtasn1 NEWS                                     -*- outline -*-
 
 * Noteworthy changes in release 4.1 (unreleased) [stable]
-- corrected indefinite tag check in ANY constructions. That allows
+- Corrected indefinite tag check in ANY constructions. That allows
   the decoding of BER-encoded structures that contain indefinite
   encoding within an ANY element.
+- Added DER decoding flag ASN1_DECODE_FLAG_STRICT_DER. Over the
+  years BER functionality was added to the decoder and this flag
+  provides the way to disable it.
+- API and ABI changes since last version:
+  ASN1_DECODE_FLAG_STRICT_DER: New definition
 
 * Noteworthy changes in release 4.0 (released 2014-06-26) [stable]
-- optimized asn1_der_decoding_startEnd(). It no longer requires the
+- Optimized asn1_der_decoding_startEnd(). It no longer requires the
   additional decoding step.
 - asn1_read_value() understands the ?CURRENT keyword, which can be used
   to indicate the current element of a sequence, when the provided node
diff --git a/lib/decoding.c b/lib/decoding.c
index 8b88581..fd6ef5b 100644
--- a/lib/decoding.c
+++ b/lib/decoding.c
@@ -39,6 +39,8 @@
 # define warn()
 #endif
 
+#define IS_ERR(len, flags) (len < -1 || ((flags & ASN1_DECODE_FLAG_STRICT_DER) 
&& len < 0))
+
 #define HAVE_TWO(x) (x>=2?1:0)
 
 #define DECR_LEN(l, s) do { \
@@ -406,7 +408,7 @@ asn1_get_bit_der (const unsigned char *der, int der_len,
 
 static int
 _asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len,
-                      int *ret_len)
+                      int *ret_len, unsigned flags)
 {
   asn1_node p;
   int counter, len2, len3, is_tag_implicit;
@@ -445,8 +447,13 @@ _asn1_extract_tag_der (asn1_node node, const unsigned char 
*der, int der_len,
                   DECR_LEN(der_len, len2);
                  counter += len2;
 
-                 len3 =
-                   asn1_get_length_ber (der + counter, der_len,
+                 if (flags & ASN1_DECODE_FLAG_STRICT_DER)
+                   len3 =
+                     asn1_get_length_der (der + counter, der_len,
+                                        &len2);
+                 else
+                   len3 =
+                     asn1_get_length_ber (der + counter, der_len,
                                         &len2);
                  if (len3 < 0)
                    return ASN1_DER_ERROR;
@@ -581,7 +588,7 @@ cleanup:
 
 static int
 extract_tag_der_recursive(asn1_node node, const unsigned char *der, int 
der_len,
-                      int *ret_len)
+                      int *ret_len, unsigned flags)
 {
 asn1_node p;
 int ris = ASN1_DER_ERROR;
@@ -591,7 +598,7 @@ int ris = ASN1_DER_ERROR;
       p = node->down;
       while (p)
         {
-          ris = _asn1_extract_tag_der (p, der, der_len, ret_len);
+          ris = _asn1_extract_tag_der (p, der, der_len, ret_len, flags);
           if (ris == ASN1_SUCCESS)
             break;
           p = p->right;
@@ -601,7 +608,7 @@ int ris = ASN1_DER_ERROR;
       return ris;
     }
   else
-    return _asn1_extract_tag_der (node, der, der_len, ret_len);
+    return _asn1_extract_tag_der (node, der, der_len, ret_len, flags);
 }
 
 static int
@@ -665,7 +672,7 @@ _asn1_delete_not_used (asn1_node node)
 
 static int
 _asn1_extract_der_octet (asn1_node node, const unsigned char *der,
-                        int der_len)
+                        int der_len, unsigned flags)
 {
   int len2, len3;
   int counter, counter_end;
@@ -686,8 +693,11 @@ _asn1_extract_der_octet (asn1_node node, const unsigned 
char *der,
     {
       len2 = asn1_get_length_der (der + counter, der_len, &len3);
 
-      if (len2 < -1)
-       return ASN1_DER_ERROR;
+      if (IS_ERR(len2, flags))
+       {
+         warn();
+         return ASN1_DER_ERROR;
+       }
 
       if (len2 >= 0)
        {
@@ -699,7 +709,7 @@ _asn1_extract_der_octet (asn1_node node, const unsigned 
char *der,
          DECR_LEN(der_len, len3);
          result =
            _asn1_extract_der_octet (node, der + counter + len3,
-                                    der_len);
+                                    der_len, flags);
          if (result != ASN1_SUCCESS)
            return result;
          len2 = 0;
@@ -716,7 +726,8 @@ cleanup:
 }
 
 static int
-_asn1_get_octet_string (asn1_node node, const unsigned char *der, int der_len, 
int *len)
+_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;
@@ -726,9 +737,13 @@ _asn1_get_octet_string (asn1_node node, const unsigned 
char *der, int der_len, i
   if (*(der - 1) & ASN1_CLASS_STRUCTURED)
     {
       tot_len = 0;
+
       indefinite = asn1_get_length_der (der, der_len, &len3);
-      if (indefinite < -1)
-       return ASN1_DER_ERROR;
+      if (IS_ERR(indefinite, flags))
+       {
+         warn();
+         return ASN1_DER_ERROR;
+       }
 
       counter += len3;
       DECR_LEN(der_len, len3);
@@ -777,7 +792,7 @@ _asn1_get_octet_string (asn1_node node, const unsigned char 
*der, int der_len, i
          asn1_length_der (tot_len, temp, &len2);
          _asn1_set_value (node, temp, len2);
 
-         ret = _asn1_extract_der_octet (node, der, der_len);
+         ret = _asn1_extract_der_octet (node, der, der_len, flags);
          if (ret != ASN1_SUCCESS)
            return ret;
 
@@ -889,6 +904,9 @@ static void delete_unneeded_choice_fields(asn1_node p)
  * padding after the decoded DER data. Upon a successful return the value of
  * address@hidden will be set to the number of bytes decoded.
  *
+ * If %ASN1_DECODE_FLAG_STRICT_DER flag is set then the function will
+ * not decode any BER-encoded elements.
+ *
  * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
  *   if @ELEMENT is %NULL, and %ASN1_TAG_ERROR or
  *   %ASN1_DER_ERROR if the der encoding doesn't match the structure
@@ -966,7 +984,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);
+                                                    ider_len, &len2, flags);
                      if (ris == ASN1_SUCCESS)
                        {
                          p2->type &= ~CONST_NOT_USED;
@@ -1016,7 +1034,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);
+                                                ider_len, &len2, flags);
 
                  if (ris == ASN1_SUCCESS)
                    {
@@ -1062,7 +1080,8 @@ 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);
+             extract_tag_der_recursive (p, der + counter, ider_len, 
+                                        &tag_len, flags);
 
          if (ris != ASN1_SUCCESS)
            {
@@ -1180,7 +1199,7 @@ 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);
+             result = _asn1_get_octet_string (p, der + counter, ider_len, 
&len3, flags);
              if (result != ASN1_SUCCESS)
                {
                   warn();
@@ -1248,7 +1267,7 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, 
int *max_ider_len,
                {               /* move==DOWN || move==RIGHT */
                  len3 =
                    asn1_get_length_der (der + counter, ider_len, &len2);
-                 if (len3 < -1)
+                  if (IS_ERR(len3, flags))
                    {
                      result = ASN1_DER_ERROR;
                       warn();
@@ -1331,7 +1350,7 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, 
int *max_ider_len,
                {               /* move==DOWN || move==RIGHT */
                  len3 =
                    asn1_get_length_der (der + counter, ider_len, &len2);
-                 if (len3 < -1)
+                  if (IS_ERR(len3, flags))
                    {
                      result = ASN1_DER_ERROR;
                       warn();
@@ -1363,7 +1382,9 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, 
int *max_ider_len,
              break;
            case ASN1_ETYPE_ANY:
              /* Check indefinite lenth method in an EXPLICIT TAG */
-             if ((p->type & CONST_TAG) && tag_len == 2 && (der[counter - 1] == 
0x80))
+              
+             if (!(flags & ASN1_DECODE_FLAG_STRICT_DER) && (p->type & 
CONST_TAG) && 
+                 tag_len == 2 && (der[counter - 1] == 0x80))
                indefinite = 1;
              else
                indefinite = 0;
@@ -1382,7 +1403,7 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, 
int *max_ider_len,
              len4 =
                asn1_get_length_der (der + counter + len2,
                                     ider_len, &len3);
-             if (len4 < -1)
+              if (IS_ERR(len4, flags))
                {
                  result = ASN1_DER_ERROR;
                   warn();
diff --git a/lib/libtasn1.h b/lib/libtasn1.h
index 8f7ff0b..d36c99a 100644
--- a/lib/libtasn1.h
+++ b/lib/libtasn1.h
@@ -185,7 +185,11 @@ extern "C"
 #define ASN1_DELETE_FLAG_ZEROIZE 1
 
 /* Flags used by asn1_der_decoding2(). */
+
+/* This flag would allow arbitrary data past the DER data */
 #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)
 
 
   struct asn1_data_node_st
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 639d9c0..79751f4 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -36,11 +36,12 @@ MOSTLYCLEANFILES = Test_parser_ERROR.asn
 
 check_PROGRAMS = Test_parser Test_tree Test_encoding Test_indefinite \
        Test_errors Test_simple Test_overflow Test_strings Test_choice \
-       Test_encdec copynode coding-decoding2
+       Test_encdec copynode coding-decoding2 strict-der
 
 TESTS = Test_parser Test_tree Test_encoding Test_indefinite    \
        Test_errors Test_simple Test_overflow crlf threadsafety \
-       Test_strings Test_choice Test_encdec copynode coding-decoding2
+       Test_strings Test_choice Test_encdec copynode coding-decoding2 \
+       strict-der
 
 TESTS_ENVIRONMENT = \
        ASN1PARSER=$(srcdir)/Test_parser.asn \
diff --git a/tests/Test_encoding.c b/tests/strict-der.c
similarity index 56%
copy from tests/Test_encoding.c
copy to tests/strict-der.c
index 7d3266c..477e041 100644
--- a/tests/Test_encoding.c
+++ b/tests/strict-der.c
@@ -18,10 +18,6 @@
  *
  */
 
-/******************************************************/
-/* File: Test_encoding.c                              */
-/* Description: Test writing values and DER encoding. */
-/******************************************************/
 
 #include <stdio.h>
 #include <string.h>
@@ -29,39 +25,44 @@
 #include "libtasn1.h"
 
 
-unsigned char data[256];
-int data_size = sizeof (data);
-
 
 int
 main (int argc, char *argv[])
 {
-  int result, verbose = 0;
+  int result;
+  char buffer[10 * 1024];
   asn1_node definitions = NULL;
   asn1_node asn1_element = NULL;
   char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
-  const char *treefile = getenv ("ASN1ENCODING");
+  FILE *out, *fd;
+  int size;
+  const char *treefile = getenv ("ASN1PKIX");
+  const char *indeffile = getenv ("ASN1INDEF");
+  int verbose = 0;
 
   if (argc > 1)
     verbose = 1;
 
   if (!treefile)
-    treefile = "Test_encoding.asn";
+    treefile = "pkix.asn";
+
+  if (!indeffile)
+    indeffile = "TestIndef.p12";
 
-  if (verbose != 0)
+  if (verbose)
     {
       printf ("\n\n/****************************************/\n");
-      printf ("/*     Test sequence : coding-decoding  */\n");
+      printf ("/*     Test sequence : strict DER decoding  */\n");
       printf ("/****************************************/\n\n");
+      printf ("ASN1TREE: %s\n", treefile);
     }
 
   /* Check version */
-  if (asn1_check_version ("0.3.3") == NULL)
+  if (asn1_check_version ("0.2.11") == NULL)
     printf ("\nLibrary version check ERROR:\n actual version: %s\n\n",
            asn1_check_version (NULL));
 
   result = asn1_parser2tree (treefile, &definitions, errorDescription);
-
   if (result != ASN1_SUCCESS)
     {
       asn1_perror (result);
@@ -69,68 +70,67 @@ main (int argc, char *argv[])
       exit (1);
     }
 
-  result = asn1_create_element (definitions, "TEST_TREE.Koko", &asn1_element);
-  if (result != ASN1_SUCCESS)
-    {
-      fprintf (stderr, "asn1_create_element(): ");
-      asn1_perror (result);
-      exit (1);
-    }
+  out = stdout;
 
-  result = asn1_write_value (asn1_element, "seqint", "NEW", 1);
-  if (result != ASN1_SUCCESS)
+  fd = fopen (indeffile, "rb");
+  if (fd == NULL)
     {
-      fprintf (stderr, "asn1_write_value(): seqint ");
-      asn1_perror (result);
+      printf ("Cannot read file %s\n", indeffile);
       exit (1);
     }
-
-  result = asn1_write_value (asn1_element, "seqint.?LAST", "1234", 0);
-  if (result != ASN1_SUCCESS)
+  size = fread (buffer, 1, sizeof (buffer), fd);
+  if (size <= 0)
     {
-      fprintf (stderr, "asn1_write_value(): seqint.?LAST ");
-      asn1_perror (result);
+      printf ("Cannot read from file %s\n", indeffile);
       exit (1);
     }
 
-  result = asn1_write_value (asn1_element, "int", "\x0f\xff\x01", 3);
+  fclose (fd);
+
+  result =
+    asn1_create_element (definitions, "PKIX1.pkcs-12-PFX", &asn1_element);
   if (result != ASN1_SUCCESS)
     {
-      fprintf (stderr, "asn1_write_value(): int ");
       asn1_perror (result);
+      printf ("Cannot create PKCS12 element\n");
       exit (1);
     }
 
-  result = asn1_write_value (asn1_element, "str", "string", 6);
+  result = asn1_der_decoding2 (&asn1_element, buffer, &size, 0, 
errorDescription);
   if (result != ASN1_SUCCESS)
     {
-      fprintf (stderr, "asn1_write_value(): str ");
       asn1_perror (result);
+      printf ("Cannot decode BER data (size %ld) in %s: %s\n", (long) size, 
indeffile, errorDescription);
       exit (1);
     }
 
-  /* Clear the definition structures */
-  asn1_delete_structure (&definitions);
+  asn1_delete_structure (&asn1_element);
 
-  result = asn1_der_coding (asn1_element, "", data, &data_size, NULL);
+  /* Now try with strict DER */
+  result =
+    asn1_create_element (definitions, "PKIX1.pkcs-12-PFX", &asn1_element);
   if (result != ASN1_SUCCESS)
     {
-      fprintf (stderr, "Encoding error.\n");
       asn1_perror (result);
+      printf ("Cannot create PKCS12 element\n");
       exit (1);
     }
 
-  result = asn1_der_decoding (&asn1_element, data, data_size, NULL);
-  if (result != ASN1_SUCCESS)
+  result = asn1_der_decoding2 (&asn1_element, buffer, &size, 
ASN1_DECODE_FLAG_STRICT_DER, errorDescription);
+  if (result == ASN1_SUCCESS)
     {
-      fprintf (stderr, "Decoding error.\n");
       asn1_perror (result);
+      printf ("Should not have decoded DER data (size %ld) in %s: %s\n", 
(long) size, indeffile, errorDescription);
       exit (1);
     }
 
   asn1_delete_structure (&asn1_element);
 
-  if (verbose)
-    printf ("Success\n");
+  /* Clear the definition structures */
+  asn1_delete_structure (&definitions);
+
+  if (out != stdout)
+    fclose (out);
+
   exit (0);
 }


hooks/post-receive
-- 
GNU libtasn1



reply via email to

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