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_3_4-5-g8cba109


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU libtasn1 branch, master, updated. libtasn1_3_4-5-g8cba109
Date: Fri, 14 Mar 2014 14:10:06 +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=8cba109feac0872bdd938e36283063926948ce4c

The branch, master has been updated
       via  8cba109feac0872bdd938e36283063926948ce4c (commit)
       via  d84d6567ecdeeb00b2536f3c16bc4f599df23e49 (commit)
       via  05b093a2ef966fd02a2e93248194778b1caa2d55 (commit)
       via  27251752116bd04dcf5369ae93b03769847ce879 (commit)
      from  601448517af3c99f5bc8ce763b4003b0aa4eae70 (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 8cba109feac0872bdd938e36283063926948ce4c
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Mar 14 15:09:56 2014 +0100

    doc update

commit d84d6567ecdeeb00b2536f3c16bc4f599df23e49
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Mar 14 15:09:11 2014 +0100

    Added self-check for recursive choices.

commit 05b093a2ef966fd02a2e93248194778b1caa2d55
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Mar 14 15:02:15 2014 +0100

    Handle recursive CHOICEs.

commit 27251752116bd04dcf5369ae93b03769847ce879
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Mar 14 14:07:42 2014 +0100

    Use special function for common usage of _asn1_extract_tag_der().

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

Summary of changes:
 NEWS                |    3 +
 lib/decoding.c      |  108 +++++++++++++++++++++++----------------------------
 tests/Makefile.am   |    6 +-
 tests/Test_choice.c |   93 +++++++++++++++++++++++++++++++++++++++++++
 tests/choice.asn    |   23 +++++++++++
 5 files changed, 171 insertions(+), 62 deletions(-)
 create mode 100644 tests/Test_choice.c
 create mode 100644 tests/choice.asn

diff --git a/NEWS b/NEWS
index e9c1d03..022e75d 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,8 @@
 GNU Libtasn1 NEWS                                     -*- outline -*-
 
+* Noteworthy changes in release 3.5 (unreleased)
+- Handle recursive CHOICE options.
+
 * Noteworthy changes in release 3.4 (released 2013-11-25) [stable]
 - Added asn1_delete_structure2() which allows zeroizing the contents
   of all values in the structure prior to deinitialization.
diff --git a/lib/decoding.c b/lib/decoding.c
index eb83d89..82f1c24 100644
--- a/lib/decoding.c
+++ b/lib/decoding.c
@@ -376,6 +376,7 @@ asn1_get_bit_der (const unsigned char *der, int der_len,
   return ASN1_SUCCESS;
 }
 
+
 static int
 _asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len,
                       int *ret_len)
@@ -537,6 +538,9 @@ _asn1_extract_tag_der (asn1_node node, const unsigned char 
*der, int der_len,
        case ASN1_ETYPE_ANY:
          counter -= len2;
          break;
+       case ASN1_ETYPE_CHOICE:
+         counter -= len2;
+         break;
        default:
          return ASN1_DER_ERROR;
          break;
@@ -549,6 +553,31 @@ _asn1_extract_tag_der (asn1_node node, const unsigned char 
*der, int der_len,
 }
 
 static int
+extract_tag_der_recursive(asn1_node node, const unsigned char *der, int 
der_len,
+                      int *ret_len)
+{
+asn1_node p;
+int ris;
+
+  if (type_field (node->type) == ASN1_ETYPE_CHOICE)
+    {
+      p = node->down;
+      while (p)
+        {
+          ris = _asn1_extract_tag_der (p, der, der_len, ret_len);
+          if (ris == ASN1_SUCCESS)
+            break;
+          p = p->right;
+       }
+
+      *ret_len = 0;
+      return ris;
+    }
+  else
+    return _asn1_extract_tag_der (node, der, der_len, ret_len);
+}
+
+static int
 _asn1_delete_not_used (asn1_node node)
 {
   asn1_node p, p2;
@@ -782,6 +811,14 @@ _asn1_get_indefinite_length_string (const unsigned char 
*der, int *len)
 
 }
 
+static void delete_unneeded_choice_fields(asn1_node p)
+{
+  if (p->right)
+    {
+      asn1_delete_structure (&p->right);
+    }
+}
+
 /**
  * asn1_der_decoding:
  * @element: pointer to an ASN1 structure.
@@ -865,23 +902,9 @@ asn1_der_decoding (asn1_node * element, const void *ider, 
int len,
                {
                  if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
                    {
-                     if (type_field (p2->type) != ASN1_ETYPE_CHOICE)
-                       ris =
-                         _asn1_extract_tag_der (p2, der + counter,
+                     ris =
+                         extract_tag_der_recursive (p2, der + counter,
                                                 len - counter, &len2);
-                     else
-                       {
-                         p3 = p2->down;
-                         while (p3)
-                           {
-                             ris =
-                               _asn1_extract_tag_der (p3, der + counter,
-                                                      len - counter, &len2);
-                             if (ris == ASN1_SUCCESS)
-                               break;
-                             p3 = p3->right;
-                           }
-                       }
                      if (ris == ASN1_SUCCESS)
                        {
                          p2->type &= ~CONST_NOT_USED;
@@ -926,17 +949,13 @@ asn1_der_decoding (asn1_node * element, const void *ider, 
int len,
                {
                  if (counter < len)
                    ris =
-                     _asn1_extract_tag_der (p->down, der + counter,
+                     extract_tag_der_recursive (p->down, der + counter,
                                             len - counter, &len2);
                  else
                    ris = ASN1_DER_ERROR;
                  if (ris == ASN1_SUCCESS)
                    {
-                     while (p->down->right)
-                       {
-                         p2 = p->down->right;
-                         asn1_delete_structure (&p2);
-                       }
+                     delete_unneeded_choice_fields(p->down);
                      break;
                    }
                  else if (ris == ASN1_ERROR_TYPE_ANY)
@@ -959,7 +978,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, 
int len,
                      goto cleanup;
                    }
                }
-             else
+             else if (type_field (p->type) != ASN1_ETYPE_CHOICE)
                p = p->down;
            }
 
@@ -973,7 +992,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, 
int len,
 
          if (ris == ASN1_SUCCESS)
            ris =
-             _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
+             extract_tag_der_recursive (p, der + counter, len - counter, 
&len2);
          if (ris != ASN1_SUCCESS)
            {
              if (p->type & CONST_OPTION)
@@ -1473,23 +1492,9 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
                {
                  if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
                    {
-                     if (type_field (p2->type) != ASN1_ETYPE_CHOICE)
-                       ris =
-                         _asn1_extract_tag_der (p2, der + counter,
+                     ris =
+                         extract_tag_der_recursive (p2, der + counter,
                                                 len - counter, &len2);
-                     else
-                       {
-                         p3 = p2->down;
-                         while (p3)
-                           {
-                             ris =
-                               _asn1_extract_tag_der (p3, der + counter,
-                                                      len - counter, &len2);
-                             if (ris == ASN1_SUCCESS)
-                               break;
-                             p3 = p3->right;
-                           }
-                       }
                      if (ris == ASN1_SUCCESS)
                        {
                          p2->type &= ~CONST_NOT_USED;
@@ -1540,11 +1545,7 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
                    ris = ASN1_DER_ERROR;
                  if (ris == ASN1_SUCCESS)
                    {
-                     while (p->down->right)
-                       {
-                         p2 = p->down->right;
-                         asn1_delete_structure (&p2);
-                       }
+                     delete_unneeded_choice_fields(p->down);
                      break;
                    }
                  else if (ris == ASN1_ERROR_TYPE_ANY)
@@ -1567,7 +1568,7 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
                      goto cleanup;
                    }
                }
-             else
+             else if (type_field (p->type) != ASN1_ETYPE_CHOICE)
                p = p->down;
            }
 
@@ -2256,20 +2257,9 @@ asn1_der_decoding_startEnd (asn1_node element, const 
void *ider, int len,
                {
                  if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
                    {           /* CONTROLLARE */
-                     if (type_field (p2->type) != ASN1_ETYPE_CHOICE)
-                       ris =
-                         _asn1_extract_tag_der (p2, der + counter,
+                     ris =
+                         extract_tag_der_recursive (p2, der + counter,
                                                 len - counter, &len2);
-                     else
-                       {
-                         p3 = p2->down;
-                         if (p3 == NULL)
-                           return ASN1_DER_ERROR;
-
-                         ris =
-                           _asn1_extract_tag_der (p3, der + counter,
-                                                  len - counter, &len2);
-                       }
                      if (ris == ASN1_SUCCESS)
                        {
                          p2->type &= ~CONST_NOT_USED;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 10bdba1..8f8beb8 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -23,7 +23,7 @@ AM_LDFLAGS = -no-install
 LDADD = ../lib/libtasn1.la ../gl/libgnu.la
 
 EXTRA_DIST = Test_parser.asn Test_tree.asn Test_tree_asn1_tab.c        \
-       Test_encoding.asn pkix.asn TestIndef.p12
+       Test_encoding.asn pkix.asn TestIndef.p12 choice.asn
 
 # For crlf.
 EXTRA_DIST += crlf.cer
@@ -34,11 +34,11 @@ dist_check_SCRIPTS += threadsafety
 MOSTLYCLEANFILES = Test_parser_ERROR.asn
 
 check_PROGRAMS = Test_parser Test_tree Test_encoding Test_indefinite \
-       Test_errors Test_simple Test_overflow Test_strings
+       Test_errors Test_simple Test_overflow Test_strings Test_choice
 
 TESTS = Test_parser Test_tree Test_encoding Test_indefinite    \
        Test_errors Test_simple Test_overflow crlf threadsafety \
-       Test_strings
+       Test_strings Test_choice
 
 TESTS_ENVIRONMENT = \
        ASN1PARSER=$(srcdir)/Test_parser.asn \
diff --git a/tests/Test_choice.c b/tests/Test_choice.c
new file mode 100644
index 0000000..0c6742e
--- /dev/null
+++ b/tests/Test_choice.c
@@ -0,0 +1,93 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <libtasn1.h>
+
+int
+main ()
+{
+  int result = 0;
+  asn1_node definitions = NULL, node1 = NULL, node2 = NULL;
+  char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
+  unsigned i;
+
+  char data[1024];
+  int data_size = sizeof (data);
+
+  /* Encode */
+  result = asn1_parser2tree ("choice.asn", &definitions, errorDescription);
+  if (result != ASN1_SUCCESS)
+    {
+      printf ("error in %d\n", __LINE__);
+      exit (1);
+    }
+
+  result = asn1_create_element (definitions, "TEST.Choice0", &node1);
+  if (result != ASN1_SUCCESS)
+    {
+      printf ("error in %d\n", __LINE__);
+      exit (1);
+    }
+
+  result = asn1_write_value (node1, "", "choice1", 1);
+  if (result != ASN1_SUCCESS)
+    {
+      printf ("error in %d\n", __LINE__);
+      exit (1);
+    }
+
+  result = asn1_write_value (node1, "choice1", "choice2", 1);
+  if (result != ASN1_SUCCESS)
+    {
+      printf ("error in %d\n", __LINE__);
+      exit (1);
+    }
+
+  result = asn1_write_value (node1, "choice1.choice2", "int1", 1);
+  if (result != ASN1_SUCCESS)
+    {
+      printf ("error in %d\n", __LINE__);
+      exit (1);
+    }
+
+  result = asn1_write_value (node1, "choice1.choice2.int1", "1234", 0);
+  if (result != ASN1_SUCCESS)
+    {
+      printf ("error in %d\n", __LINE__);
+      exit (1);
+    }
+
+  result = asn1_der_coding (node1, "", data, &data_size, errorDescription);
+  if (result != ASN1_SUCCESS)
+    {
+      printf ("error in %d\n", __LINE__);
+      exit (1);
+    }
+
+  asn1_delete_structure (&node1);
+
+  /* Decode */
+  result = asn1_create_element (definitions, "TEST.Choice0", &node2);
+  if (result != ASN1_SUCCESS)
+    {
+      printf ("error in %d\n", __LINE__);
+      exit (1);
+    }
+
+#if 0
+  printf ("der:");
+  for (i = 0; i < data_size; i++)
+    printf ("%.2x ", (unsigned char) (data[i]));
+  printf ("\n");
+#endif
+
+  result = asn1_der_decoding (&node2, data, data_size, errorDescription);
+  if (result != ASN1_SUCCESS)
+    {
+      printf ("error in %d\n", __LINE__);
+      exit (1);
+    }
+
+  asn1_delete_structure (&node2);
+
+  return 0;
+}
diff --git a/tests/choice.asn b/tests/choice.asn
new file mode 100644
index 0000000..b309204
--- /dev/null
+++ b/tests/choice.asn
@@ -0,0 +1,23 @@
+TEST {}
+DEFINITIONS IMPLICIT TAGS ::=
+BEGIN
+
+Choice2 ::= CHOICE {
+ oct1 OCTET STRING,
+ int1 [3] INTEGER,
+ oct2 OCTET STRING
+}
+
+Choice1 ::= CHOICE {
+ int4 [0] INTEGER,
+ choice2 Choice2,
+ int5 [1] INTEGER
+}
+
+Choice0 ::= CHOICE {
+ int6 [0] INTEGER,
+ choice1 Choice1,
+ int7 [1] INTEGER
+}
+
+END


hooks/post-receive
-- 
GNU libtasn1



reply via email to

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