Started major rewrite of the ASN.1 stuff
authorWerner Koch <wk@gnupg.org>
Fri, 12 Oct 2001 15:57:10 +0000 (15:57 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 12 Oct 2001 15:57:10 +0000 (15:57 +0000)
Compiles but does not yet work.

15 files changed:
src/CertificateExample.c
src/Makefile.am
src/asn1-der.c
src/asn1-der.h
src/asn1-func.c
src/asn1-func.h
src/asn1-gentables.c
src/asn1-parse.h
src/asn1-parse.y
src/ber-decoder.c
src/ber-decoder.h
src/ber-dump.c
src/ksba.h
src/util.c
src/util.h

index 9a611db..bb64815 100644 (file)
@@ -459,7 +459,7 @@ main(int argc,char *argv[])
   char file_name[128];
   node_asn *PKIX1Implicit88;
 
-  result=asn1_create_tree(pkix_asn1_tab,&PKIX1Implicit88);
+  result=ksba_asn_create_tree(pkix_asn1_tab,&PKIX1Implicit88);
 
   if(result==ASN_FILE_NOT_FOUND){
     printf("FILE NOT FOUND\n");
index 5597f55..ca4b176 100644 (file)
@@ -50,9 +50,15 @@ ber_dump_SOURCES = \
        ksba.h \
        ber-decoder.c ber-decoder.h \
        reader.c reader.h \
+       asn1-parse.y asn1-parse.h \
+       asn1-func.c asn1-func.h \
+       asn1-der.c asn1-der.h \
        util.c util.h   
 
 
+asn1-parse.c : asn1-func.h
+
+
 
 
 
index 1a93bea..5893351 100644 (file)
 #define TAG_ENUMERATED       0x0A
 #define TAG_NULL             0x05
 
+#define UNIVERSAL  (CLASS_UNIVERSAL << 6)
+#define STRUCTURED 0x20
+
+static AsnNode 
+find_up (AsnNode  node)
+{
+  AsnNode p;
+
+  if (node == NULL)
+    return NULL;
+
+  p = node;
+
+  while ((p->left != NULL) && (p->left->right == p))
+    p = p->left;
+
+  return p->left;
+}
+
 
 char *
 _asn1_ltostr (long v, char *str)
@@ -108,7 +127,7 @@ _asn1_length_der (unsigned long len, unsigned char *ans, int *ans_len)
 
 
 unsigned long
-_asn1_get_length_der (unsigned char *der, int *len)
+_ksba_asn_get_length_der (unsigned char *der, int *len)
 {
   unsigned long ans;
   int k, punt;
@@ -225,7 +244,7 @@ _asn1_get_octet_der (unsigned char *der, int *der_len, unsigned char *str,
 
   if (str == NULL)
     return ASN_OK;
-  *str_len = _asn1_get_length_der (der, &len_len);
+  *str_len = _ksba_asn_get_length_der (der, &len_len);
   if (str_size > *str_len)
     memcpy (str, der + len_len, *str_len);
   else
@@ -257,7 +276,7 @@ _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
   char temp[20];
 
   if(str==NULL) return;
-  str_len=_asn1_get_length_der(der,&len_len);
+  str_len=_ksba_asn_get_length_der(der,&len_len);
   memcpy(temp,der+len_len,str_len);
   *der_len=str_len+len_len;
   switch(str_len){
@@ -292,7 +311,7 @@ _asn1_get_time_der (unsigned char *der, int *der_len, unsigned char *str)
 
   if (str == NULL)
     return;
-  str_len = _asn1_get_length_der (der, &len_len);
+  str_len = _ksba_asn_get_length_der (der, &len_len);
   memcpy (str, der + len_len, str_len);
   str[str_len] = 0;
   *der_len = str_len + len_len;
@@ -363,7 +382,7 @@ _asn1_get_objectid_der (unsigned char *der, int *der_len, unsigned char *str)
 
   if (str == NULL)
     return;
-  len = _asn1_get_length_der (der, &len_len);
+  len = _ksba_asn_get_length_der (der, &len_len);
 
   val1 = der[len_len] / 40;
   val = der[len_len] - val1 * 40;
@@ -421,7 +440,7 @@ _asn1_get_bit_der (unsigned char *der, int *der_len, unsigned char *str,
 
   if (str == NULL)
     return ASN_OK;
-  len_byte = _asn1_get_length_der (der, &len_len) - 1;
+  len_byte = _ksba_asn_get_length_der (der, &len_len) - 1;
 
   if (str_size > len_byte)
     memcpy (str, der + len_len + 1, len_byte);
@@ -443,27 +462,27 @@ _asn1_get_bit_der (unsigned char *der, int *der_len, unsigned char *str,
 
 
 void
-_asn1_complete_explicit_tag (node_asn * node, unsigned char *der,
+_asn1_complete_explicit_tag (AsnNode  node, unsigned char *der,
                             int *counter)
 {
-  node_asn *p;
+  AsnNode p;
   int tag_len, is_tag_implicit, len2, len3;
   unsigned char class, class_implicit, temp[10];
   unsigned long tag_implicit;
 
   is_tag_implicit = 0;
 
-  if (node->type & CONST_TAG)
+  if (node->flags.has_tag)
     {
       p = node->down;
       while (p)
        {
-         if (type_field (p->type) == TYPE_TAG)
+         if (p->type == TYPE_TAG)
            {
-             if (p->type & CONST_EXPLICIT)
+             if (p->flags.explicit)
                {
                  len2 = strtol (p->name, NULL, 10);
-                 _asn1_set_name (p, NULL);
+                 _ksba_asn_set_name (p, NULL);
                  _asn1_length_der (*counter - len2, temp, &len3);
                  memmove (der + len2 + len3, der + len2, *counter - len2);
                  memcpy (der + len2, temp, len3);
@@ -471,7 +490,7 @@ _asn1_complete_explicit_tag (node_asn * node, unsigned char *der,
                  is_tag_implicit = 0;
                }
              else
-               {               /* CONST_IMPLICIT */
+               {       
                  if (!is_tag_implicit)
                    {
                      is_tag_implicit = 1;
@@ -485,32 +504,25 @@ _asn1_complete_explicit_tag (node_asn * node, unsigned char *der,
 
 
 int
-_asn1_insert_tag_der (node_asn * node, unsigned char *der, int *counter)
+_asn1_insert_tag_der (AsnNode  node, unsigned char *der, int *counter)
 {
-  node_asn *p;
+  AsnNode p;
   int tag_len, is_tag_implicit, len2, len3;
   unsigned char class, class_implicit, temp[10];
   unsigned long tag_implicit;
 
+
   is_tag_implicit = 0;
 
-  if (node->type & CONST_TAG)
+  if (node->flags.has_tag)
     {
       p = node->down;
       while (p)
-       {
-         if (type_field (p->type) == TYPE_TAG)
-           {
-             if (p->type & CONST_APPLICATION)
-               class = APPLICATION;
-             else if (p->type & CONST_UNIVERSAL)
-               class = UNIVERSAL;
-             else if (p->type & CONST_PRIVATE)
-               class = PRIVATE;
-             else
-               class = CONTEXT_SPECIFIC;
-
-             if (p->type & CONST_EXPLICIT)
+        {
+         if (p->type == TYPE_TAG)
+            {
+              class = p->flags.class << 6;
+             if (p->flags.explicit)
                {
                  if (is_tag_implicit)
                    _asn1_tag_der (class_implicit, tag_implicit,
@@ -521,19 +533,20 @@ _asn1_insert_tag_der (node_asn * node, unsigned char *der, int *counter)
                                   der + *counter, &tag_len);
                  *counter += tag_len;
                  _asn1_ltostr (*counter, temp);
-                 _asn1_set_name (p, temp);
+                 _ksba_asn_set_name (p, temp);
 
                  is_tag_implicit = 0;
                }
              else
-               {               /* CONST_IMPLICIT */
+               {       
                  if (!is_tag_implicit)
                    {
-                     if ((type_field (node->type) == TYPE_SEQUENCE) ||
-                         (type_field (node->type) == TYPE_SEQUENCE_OF) ||
-                         (type_field (node->type) == TYPE_SET) ||
-                         (type_field (node->type) == TYPE_SET_OF))
+                     if (node->type == TYPE_SEQUENCE 
+                          || node->type == TYPE_SEQUENCE_OF
+                          || node->type == TYPE_SET
+                          || node->type == TYPE_SET_OF)
                        class |= STRUCTURED;
+
                      class_implicit = class;
                      tag_implicit = strtoul (p->value, NULL, 10);
                      is_tag_implicit = 1;
@@ -550,7 +563,7 @@ _asn1_insert_tag_der (node_asn * node, unsigned char *der, int *counter)
     }
   else
     {
-      switch (type_field (node->type))
+      switch (node->type)
        {
        case TYPE_NULL:
          _asn1_tag_der (UNIVERSAL, TAG_NULL, der + *counter, &tag_len);
@@ -568,7 +581,7 @@ _asn1_insert_tag_der (node_asn * node, unsigned char *der, int *counter)
          _asn1_tag_der (UNIVERSAL, TAG_OBJECT_ID, der + *counter, &tag_len);
          break;
        case TYPE_TIME:
-         if (node->type & CONST_UTC)
+         if (node->flags.is_utc_time)
            {
              _asn1_tag_der (UNIVERSAL, TAG_UTCTime, der + *counter,
                             &tag_len);
@@ -615,35 +628,28 @@ _asn1_insert_tag_der (node_asn * node, unsigned char *der, int *counter)
 
 
 int
-_asn1_extract_tag_der (node_asn * node, unsigned char *der, int *der_len)
+_asn1_extract_tag_der (AsnNode  node, unsigned char *der, int *der_len)
 {
-  node_asn *p;
+  AsnNode p;
   int counter, len2, len3, is_tag_implicit;
   unsigned long tag, tag_implicit;
   unsigned char class, class2, class_implicit;
 
   counter = is_tag_implicit = 0;
-  if (node->type & CONST_TAG)
+  if (node->flags.has_tag)
     {
       p = node->down;
       while (p)
        {
-         if (type_field (p->type) == TYPE_TAG)
+         if (p->type == TYPE_TAG)
            {
-             if (p->type & CONST_APPLICATION)
-               class2 = APPLICATION;
-             else if (p->type & CONST_UNIVERSAL)
-               class2 = UNIVERSAL;
-             else if (p->type & CONST_PRIVATE)
-               class2 = PRIVATE;
-             else
-               class2 = CONTEXT_SPECIFIC;
+             class2 = p->flags.class << 6;
 
-             if (p->type & CONST_EXPLICIT)
+             if (p->flags.explicit)
                {
                  tag = _asn1_get_tag_der (der + counter, &class, &len2);
                  counter += len2;
-                 len3 = _asn1_get_length_der (der + counter, &len2);
+                 len3 = _ksba_asn_get_length_der (der + counter, &len2);
                  counter += len2;
                  if (!is_tag_implicit)
                    {
@@ -663,11 +669,12 @@ _asn1_extract_tag_der (node_asn * node, unsigned char *der, int *der_len)
                {               /* TAG_IMPLICIT */
                  if (!is_tag_implicit)
                    {
-                     if ((type_field (node->type) == TYPE_SEQUENCE) ||
-                         (type_field (node->type) == TYPE_SEQUENCE_OF) ||
-                         (type_field (node->type) == TYPE_SET) ||
-                         (type_field (node->type) == TYPE_SET_OF))
+                     if (node->type == TYPE_SEQUENCE
+                          || node->type == TYPE_SEQUENCE_OF
+                          || node->type == TYPE_SET
+                          || node->type == TYPE_SET_OF)
                        class2 |= STRUCTURED;
+
                      class_implicit = class2;
                      tag_implicit = strtoul (p->value, NULL, 10);
                      is_tag_implicit = 1;
@@ -686,7 +693,7 @@ _asn1_extract_tag_der (node_asn * node, unsigned char *der, int *der_len)
     }
   else
     {
-      if (type_field (node->type) == TYPE_TAG)
+      if (node->type == TYPE_TAG)
        {
          counter = 0;
          *der_len = counter;
@@ -694,7 +701,7 @@ _asn1_extract_tag_der (node_asn * node, unsigned char *der, int *der_len)
        }
 
       tag = _asn1_get_tag_der (der + counter, &class, &len2);
-      switch (type_field (node->type))
+      switch (node->type)
        {
        case TYPE_NULL:
          if ((class != UNIVERSAL) || (tag != TAG_NULL))
@@ -717,7 +724,7 @@ _asn1_extract_tag_der (node_asn * node, unsigned char *der, int *der_len)
            return ASN_DER_ERROR;
          break;
        case TYPE_TIME:
-         if (node->type & CONST_UTC)
+         if (node->flags.is_utc_time)
            {
              if ((class != UNIVERSAL) || (tag != TAG_UTCTime))
                return ASN_DER_ERROR;
@@ -762,7 +769,7 @@ _asn1_extract_tag_der (node_asn * node, unsigned char *der, int *der_len)
 
 
 void
-_asn1_ordering_set (unsigned char *der, node_asn * node)
+_asn1_ordering_set (unsigned char *der, AsnNode  node)
 {
   struct vet
   {
@@ -773,21 +780,20 @@ _asn1_ordering_set (unsigned char *der, node_asn * node)
 
   int counter, len, len2;
   struct vet *first, *last, *p_vet, *p2_vet;
-  node_asn *p;
+  AsnNode p;
   unsigned char class, *temp;
   unsigned long tag;
 
   counter = 0;
 
-  if (type_field (node->type) != TYPE_SET)
+  if (node->type != TYPE_SET)
     return;
 
   p = node->down;
-  while ((type_field (p->type) == TYPE_TAG)
-        || (type_field (p->type) == TYPE_SIZE))
+  while (p->type == TYPE_TAG || p->type == TYPE_SIZE)
     p = p->right;
 
-  if ((p == NULL) || (p->right == NULL))
+  if (!p || !p->right )
     return;
 
   first = last = NULL;
@@ -808,7 +814,7 @@ _asn1_ordering_set (unsigned char *der, node_asn * node)
       counter += len2;
 
       /* extraction  and length */
-      len2 = _asn1_get_length_der (der + counter, &len);
+      len2 = _ksba_asn_get_length_der (der + counter, &len);
       counter += len + len2;
 
       p_vet->end = counter;
@@ -856,7 +862,7 @@ _asn1_ordering_set (unsigned char *der, node_asn * node)
 
 
 void
-_asn1_ordering_set_of (unsigned char *der, node_asn * node)
+_asn1_ordering_set_of (unsigned char *der, AsnNode  node)
 {
   struct vet
   {
@@ -866,18 +872,17 @@ _asn1_ordering_set_of (unsigned char *der, node_asn * node)
 
   int counter, len, len2, change;
   struct vet *first, *last, *p_vet, *p2_vet;
-  node_asn *p;
+  AsnNode p;
   unsigned char *temp, class;
   unsigned long k, max;
 
   counter = 0;
 
-  if (type_field (node->type) != TYPE_SET_OF)
+  if (node->type != TYPE_SET_OF)
     return;
 
   p = node->down;
-  while ((type_field (p->type) == TYPE_TAG)
-        || (type_field (p->type) == TYPE_SIZE))
+  while (p->type == TYPE_TAG || p->type == TYPE_SIZE)
     p = p->right;
   p = p->right;
 
@@ -899,7 +904,7 @@ _asn1_ordering_set_of (unsigned char *der, node_asn * node)
       /* extraction of tag and length */
       _asn1_get_tag_der (der + counter, &class, &len);
       counter += len;
-      len2 = _asn1_get_length_der (der + counter, &len);
+      len2 = _ksba_asn_get_length_der (der + counter, &len);
       counter += len + len2;
 
       p_vet->end = counter;
@@ -965,13 +970,13 @@ _asn1_ordering_set_of (unsigned char *der, node_asn * node)
 
 
 int
-asn1_create_der (node_asn * root, char *name, unsigned char *der, int *len)
+asn1_create_der (AsnNode  root, char *name, unsigned char *der, int *len)
 {
-  node_asn *node, *p, *p2, *p3;
+  AsnNode node, p, p2, p3;
   char temp[20];
   int counter, counter_old, len2, len3, len4, move, ris;
 
-  node = _asn1_find_node (root, name);
+  node = _ksba_asn_find_node (root, name);
   if (node == NULL)
     return ASN_ELEMENT_NOT_FOUND;
 
@@ -985,7 +990,7 @@ asn1_create_der (node_asn * root, char *name, unsigned char *der, int *len)
       if (move != UP)
        ris = _asn1_insert_tag_der (p, der, &counter);
 
-      switch (type_field (p->type))
+      switch (p->type)
        {
        case TYPE_NULL:
          der[counter] = 0;
@@ -993,7 +998,7 @@ asn1_create_der (node_asn * root, char *name, unsigned char *der, int *len)
          move = RIGHT;
          break;
        case TYPE_BOOLEAN:
-         if ((p->type & CONST_DEFAULT) && (p->value == NULL))
+         if (p->flags.is_default && !p->value)
            counter = counter_old;
          else
            {
@@ -1007,11 +1012,11 @@ asn1_create_der (node_asn * root, char *name, unsigned char *der, int *len)
          break;
        case TYPE_INTEGER:
        case TYPE_ENUMERATED:
-         if ((p->type & CONST_DEFAULT) && (p->value == NULL))
+         if (p->flags.is_default && !p->value)
            counter = counter_old;
          else
            {
-             len2 = _asn1_get_length_der (p->value, &len3);
+             len2 = _ksba_asn_get_length_der (p->value, &len3);
              memcpy (der + counter, p->value, len3 + len2);
              counter += len3 + len2;
            }
@@ -1028,13 +1033,13 @@ asn1_create_der (node_asn * root, char *name, unsigned char *der, int *len)
          move = RIGHT;
          break;
        case TYPE_OCTET_STRING:
-         len2 = _asn1_get_length_der (p->value, &len3);
+         len2 = _ksba_asn_get_length_der (p->value, &len3);
          memcpy (der + counter, p->value, len3 + len2);
          counter += len3 + len2;
          move = RIGHT;
          break;
        case TYPE_BIT_STRING:
-         len2 = _asn1_get_length_der (p->value, &len3);
+         len2 = _ksba_asn_get_length_der (p->value, &len3);
          memcpy (der + counter, p->value, len3 + len2);
          counter += len3 + len2;
          move = RIGHT;
@@ -1044,14 +1049,14 @@ asn1_create_der (node_asn * root, char *name, unsigned char *der, int *len)
          if (move != UP)
            {
              _asn1_ltostr (counter, temp);
-             _asn1_set_value (p, temp, strlen (temp) + 1);
+             _ksba_asn_set_value (p, temp, strlen (temp) + 1);
              move = DOWN;
            }
          else
            {                   /* move==UP */
              len2 = strtol (p->value, NULL, 10);
-             _asn1_set_value (p, NULL, 0);
-             if (type_field (p->type) == TYPE_SET)
+             _ksba_asn_set_value (p, NULL, 0);
+             if (p->type == TYPE_SET)
                _asn1_ordering_set (der + len2, p);
              _asn1_length_der (counter - len2, temp, &len3);
              memmove (der + len2 + len3, der + len2, counter - len2);
@@ -1065,10 +1070,9 @@ asn1_create_der (node_asn * root, char *name, unsigned char *der, int *len)
          if (move != UP)
            {
              _asn1_ltostr (counter, temp);
-             _asn1_set_value (p, temp, strlen (temp) + 1);
+             _ksba_asn_set_value (p, temp, strlen (temp) + 1);
              p = p->down;
-             while ((type_field (p->type) == TYPE_TAG)
-                    || (type_field (p->type) == TYPE_SIZE))
+             while (p->type == TYPE_TAG || p->type == TYPE_SIZE)
                p = p->right;
              if (p->right)
                {
@@ -1077,14 +1081,14 @@ asn1_create_der (node_asn * root, char *name, unsigned char *der, int *len)
                  continue;
                }
              else
-               p = _asn1_find_up (p);
+               p = find_up (p);
              move = UP;
            }
          if (move == UP)
            {
              len2 = strtol (p->value, NULL, 10);
-             _asn1_set_value (p, NULL, 0);
-             if (type_field (p->type) == TYPE_SET_OF)
+             _ksba_asn_set_value (p, NULL, 0);
+             if (p->type == TYPE_SET_OF)
                _asn1_ordering_set_of (der + len2, p);
              _asn1_length_der (counter - len2, temp, &len3);
              memmove (der + len2 + len3, der + len2, counter - len2);
@@ -1094,7 +1098,7 @@ asn1_create_der (node_asn * root, char *name, unsigned char *der, int *len)
            }
          break;
        case TYPE_ANY:
-         len2 = _asn1_get_length_der (p->value, &len3);
+         len2 = _ksba_asn_get_length_der (p->value, &len3);
          memcpy (der + counter, p->value + len3, len2);
          counter += len2;
          move = RIGHT;
@@ -1125,7 +1129,7 @@ asn1_create_der (node_asn * root, char *name, unsigned char *der, int *len)
            move = UP;
        }
       if (move == UP)
-       p = _asn1_find_up (p);
+       p = find_up (p);
     }
 
   *len = counter;
@@ -1150,9 +1154,9 @@ asn1_create_der (node_asn * root, char *name, unsigned char *der, int *len)
  *   ASN_DER_ERROR:          Ditto.
  **/
 int
-asn1_get_der (node_asn * root, unsigned char *der, int len)
+asn1_get_der (AsnNode  root, unsigned char *der, int len)
 {
-  node_asn *node, *p, *p2, *p3;
+  AsnNode node, p, p2, p3;
   char temp[128];
   int counter, len2, len3, len4, move, ris;
   unsigned char class, *temp2;
@@ -1163,7 +1167,7 @@ asn1_get_der (node_asn * root, unsigned char *der, int len)
   if (node == NULL)
     return ASN_ELEMENT_NOT_FOUND;
 
-  if (node->type & CONST_OPTION)
+  if (node->flags.is_optional)
     return ASN_GENERIC_ERROR;
 
   counter = 0;
@@ -1175,9 +1179,9 @@ asn1_get_der (node_asn * root, unsigned char *der, int len)
 
       if (move != UP)
        {
-         if (p->type & CONST_SET)
+         if (p->flags.is_set)
            {
-             p2 = _asn1_find_up (p);
+             p2 = find_up (p);
              len2 = strtol (p2->value, NULL, 10);
              if (counter == len2)
                {
@@ -1190,10 +1194,10 @@ asn1_get_der (node_asn * root, unsigned char *der, int len)
              p2 = p2->down;
              while (p2)
                {
-                 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
+                 if (p2->flags.is_set && p2->flags.is_not_used)
                    {           /* CONTROLLARE */
-                     if (type_field (p2->type) != TYPE_CHOICE)
-                       ris =  _asn1_extract_tag_der (p2, der + counter, &len2);
+                     if (p2->type != TYPE_CHOICE)
+                       ris = _asn1_extract_tag_der (p2, der + counter, &len2);
                      else
                        {
                          p3 = p2->down;
@@ -1210,7 +1214,7 @@ asn1_get_der (node_asn * root, unsigned char *der, int len)
                        }
                      if (ris == ASN_OK)
                        {
-                         p2->type &= ~CONST_NOT_USED;
+                          p2->flags.is_not_used = 0;
                          p = p2;
                          break;
                        }
@@ -1222,7 +1226,7 @@ asn1_get_der (node_asn * root, unsigned char *der, int len)
                return ASN_DER_ERROR;
            }
 
-         if (type_field (p->type) == TYPE_CHOICE)
+         if (p->type == TYPE_CHOICE)
            {
              while (p->down)
                {
@@ -1230,22 +1234,22 @@ asn1_get_der (node_asn * root, unsigned char *der, int len)
                  if (ris == ASN_OK)
                    {
                      while (p->down->right)
-                       asn1_delete_structure (p->down->right);
+                       ksba_asn_delete_structure (p->down->right);
                      break;
                    }
                  else if (ris == ASN_ERROR_TYPE_ANY)
                    return ASN_ERROR_TYPE_ANY;
                  else
-                   asn1_delete_structure (p->down);
+                   ksba_asn_delete_structure (p->down);
                }
              if (p->down == NULL)
                return ASN_DER_ERROR;
              p = p->down;
            }
 
-         if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
+         if (p->flags.is_optional || p->flags.is_default)
            {
-             p2 = _asn1_find_up (p);
+             p2 = find_up (p);
              len2 = strtol (p2->value, NULL, 10);
              if (counter >= len2)
                ris = ASN_TAG_ERROR;
@@ -1256,14 +1260,14 @@ asn1_get_der (node_asn * root, unsigned char *der, int len)
          if (ris != ASN_OK)
            {
              //if(ris==ASN_ERROR_TYPE_ANY) return ASN_ERROR_TYPE_ANY;
-             if (p->type & CONST_OPTION)
+             if (p->flags.is_optional)
                {
-                 p->type |= CONST_NOT_USED;
+                  p->flags.is_not_used = 1;
                  move = RIGHT;
                }
-             else if (p->type & CONST_DEFAULT)
+             else if (p->flags.is_default)
                {
-                 _asn1_set_value (p, NULL, 0);
+                 _ksba_asn_set_value (p, NULL, 0);
                  move = RIGHT;
                }
              else
@@ -1278,7 +1282,7 @@ asn1_get_der (node_asn * root, unsigned char *der, int len)
 
       if (ris == ASN_OK)
        {
-         switch (type_field (p->type))
+         switch (p->type)
            {
            case TYPE_NULL:
              if (der[counter])
@@ -1290,39 +1294,39 @@ asn1_get_der (node_asn * root, unsigned char *der, int len)
              if (der[counter++] != 1)
                return ASN_DER_ERROR;
              if (der[counter++] == 0)
-               _asn1_set_value (p, "F", 1);
+               _ksba_asn_set_value (p, "F", 1);
              else
-               _asn1_set_value (p, "T", 1);
+               _ksba_asn_set_value (p, "T", 1);
              move = RIGHT;
              break;
            case TYPE_INTEGER:
            case TYPE_ENUMERATED:
-             len2 = _asn1_get_length_der (der + counter, &len3);
-             _asn1_set_value (p, der + counter, len3 + len2);
+             len2 = _ksba_asn_get_length_der (der + counter, &len3);
+             _ksba_asn_set_value (p, der + counter, len3 + len2);
              counter += len3 + len2;
              move = RIGHT;
              break;
            case TYPE_OBJECT_ID:
              _asn1_get_objectid_der (der + counter, &len2, temp);
-             _asn1_set_value (p, temp, strlen (temp) + 1);
+             _ksba_asn_set_value (p, temp, strlen (temp) + 1);
              counter += len2;
              move = RIGHT;
              break;
            case TYPE_TIME:
              _asn1_get_time_der (der + counter, &len2, temp);
-             _asn1_set_value (p, temp, strlen (temp) + 1);
+             _ksba_asn_set_value (p, temp, strlen (temp) + 1);
              counter += len2;
              move = RIGHT;
              break;
            case TYPE_OCTET_STRING:
-             len2 = _asn1_get_length_der (der + counter, &len3);
-             _asn1_set_value (p, der + counter, len3 + len2);
+             len2 = _ksba_asn_get_length_der (der + counter, &len3);
+             _ksba_asn_set_value (p, der + counter, len3 + len2);
              counter += len3 + len2;
              move = RIGHT;
              break;
            case TYPE_BIT_STRING:
-             len2 = _asn1_get_length_der (der + counter, &len3);
-             _asn1_set_value (p, der + counter, len3 + len2);
+             len2 = _ksba_asn_get_length_der (der + counter, &len3);
+             _ksba_asn_set_value (p, der + counter, len3 + len2);
              counter += len3 + len2;
              move = RIGHT;
              break;
@@ -1331,17 +1335,17 @@ asn1_get_der (node_asn * root, unsigned char *der, int len)
              if (move == UP)
                {
                  len2 = strtol (p->value, NULL, 10);
-                 _asn1_set_value (p, NULL, 0);
+                 _ksba_asn_set_value (p, NULL, 0);
                  if (len2 != counter)
                    return ASN_DER_ERROR;
                  move = RIGHT;
                }
              else
                {               /* move==DOWN || move==RIGHT */
-                 len3 = _asn1_get_length_der (der + counter, &len2);
+                 len3 = _ksba_asn_get_length_der (der + counter, &len2);
                  counter += len2;
                  _asn1_ltostr (counter + len3, temp);
-                 _asn1_set_value (p, temp, strlen (temp) + 1);
+                 _ksba_asn_set_value (p, temp, strlen (temp) + 1);
                  move = DOWN;
                }
              break;
@@ -1359,21 +1363,20 @@ asn1_get_der (node_asn * root, unsigned char *der, int len)
                      move = RIGHT;
                      continue;
                    }
-                 _asn1_set_value (p, NULL, 0);
+                 _ksba_asn_set_value (p, NULL, 0);
                  if (len2 != counter)
                    return ASN_DER_ERROR;
                }
              else
                {               /* move==DOWN || move==RIGHT */
-                 len3 = _asn1_get_length_der (der + counter, &len2);
+                 len3 = _ksba_asn_get_length_der (der + counter, &len2);
                  counter += len2;
                  if (len3)
                    {
                      _asn1_ltostr (counter + len3, temp);
-                     _asn1_set_value (p, temp, strlen (temp) + 1);
+                     _ksba_asn_set_value (p, temp, strlen (temp) + 1);
                      p2 = p->down;
-                     while ((type_field (p2->type) == TYPE_TAG)
-                            || (type_field (p2->type) == TYPE_SIZE))
+                     while (p2->type == TYPE_TAG || p2->type == TYPE_SIZE)
                        p2 = p2->right;
                      if (p2->right == NULL)
                        _asn1_append_sequence_set (p);
@@ -1384,11 +1387,11 @@ asn1_get_der (node_asn * root, unsigned char *der, int len)
              break;
            case TYPE_ANY:
              tag = _asn1_get_tag_der (der + counter, &class, &len2);
-             len2 += _asn1_get_length_der (der + counter + len2, &len3);
+             len2 += _ksba_asn_get_length_der (der + counter + len2, &len3);
              _asn1_length_der (len2 + len3, NULL, &len4);
              temp2 = xmalloc (len2 + len3 + len4);
              _asn1_octet_der (der + counter, len2 + len3, temp2, &len4);
-             _asn1_set_value (p, temp2, len4);
+             _ksba_asn_set_value (p, temp2, len4);
              xfree (temp2);
              counter += len2 + len3;
              move = RIGHT;
@@ -1409,7 +1412,7 @@ asn1_get_der (node_asn * root, unsigned char *der, int len)
          else
            move = RIGHT;
        }
-      if ((move == RIGHT) && !(p->type & CONST_SET))
+      if (move == RIGHT && !p->flags.is_set)
        {
          if (p->right)
            p = p->right;
@@ -1417,10 +1420,10 @@ asn1_get_der (node_asn * root, unsigned char *der, int len)
            move = UP;
        }
       if (move == UP)
-       p = _asn1_find_up (p);
+       p = find_up (p);
     }
 
-  _asn1_delete_not_used (root);
+  _ksba_asn_delete_not_used (root);
 
   return (counter == len) ? ASN_OK : ASN_DER_ERROR;
 }
@@ -1428,10 +1431,10 @@ asn1_get_der (node_asn * root, unsigned char *der, int len)
 
 
 int
-asn1_get_start_end_der (node_asn * root, unsigned char *der, int len,
+asn1_get_start_end_der (AsnNode  root, unsigned char *der, int len,
                        char *name_element, int *start, int *end)
 {
-  node_asn *node, *node_to_find, *p, *p2, *p3;
+  AsnNode node, node_to_find, p, p2, p3;
   char temp[128];
   int counter, len2, len3, move, ris;
   unsigned char class;
@@ -1439,7 +1442,7 @@ asn1_get_start_end_der (node_asn * root, unsigned char *der, int len,
   long val;
 
   node = root;
-  node_to_find = _asn1_find_node (root, name_element);
+  node_to_find = _ksba_asn_find_node (root, name_element);
 
   if (node_to_find == NULL)
     return ASN_ELEMENT_NOT_FOUND;
@@ -1454,7 +1457,7 @@ asn1_get_start_end_der (node_asn * root, unsigned char *der, int len,
   if (node == NULL)
     return ASN_ELEMENT_NOT_FOUND;
 
-  if (node->type & CONST_OPTION)
+  if (node->flags.is_optional)
     return ASN_GENERIC_ERROR;
 
   counter = 0;
@@ -1469,9 +1472,9 @@ asn1_get_start_end_der (node_asn * root, unsigned char *der, int len,
 
       if (move != UP)
        {
-         if (p->type & CONST_SET)
+         if (p->flags.is_set)
            {
-             p2 = _asn1_find_up (p);
+             p2 = find_up (p);
              len2 = strtol (p2->value, NULL, 10);
              if (counter == len2)
                {
@@ -1484,11 +1487,10 @@ asn1_get_start_end_der (node_asn * root, unsigned char *der, int len,
              p2 = p2->down;
              while (p2)
                {
-                 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
+                 if (p2->flags.is_set && p2->flags.is_not_used)
                    {           /* CONTROLLARE */
-                     if (type_field (p2->type) != TYPE_CHOICE)
-                       ris =
-                         _asn1_extract_tag_der (p2, der + counter, &len2);
+                     if (p2->type != TYPE_CHOICE)
+                       ris =  _asn1_extract_tag_der (p2, der+counter, &len2);
                      else
                        {
                          p3 = p2->down;
@@ -1497,7 +1499,7 @@ asn1_get_start_end_der (node_asn * root, unsigned char *der, int len,
                        }
                      if (ris == ASN_OK)
                        {
-                         p2->type &= ~CONST_NOT_USED;
+                          p2->flags.is_not_used = 0;
                          p = p2;
                          break;
                        }
@@ -1508,7 +1510,7 @@ asn1_get_start_end_der (node_asn * root, unsigned char *der, int len,
                return ASN_DER_ERROR;
            }
 
-         if (type_field (p->type) == TYPE_CHOICE)
+         if (p->type == TYPE_CHOICE)
            {
              p = p->down;
              ris = _asn1_extract_tag_der (p, der + counter, &len2);
@@ -1518,12 +1520,12 @@ asn1_get_start_end_der (node_asn * root, unsigned char *der, int len,
            ris = _asn1_extract_tag_der (p, der + counter, &len2);
          if (ris != ASN_OK)
            {
-             if (p->type & CONST_OPTION)
+             if (p->flags.is_optional)
                {
-                 p->type |= CONST_NOT_USED;
+                  p->flags.is_not_used = 1;
                  move = RIGHT;
                }
-             else if (p->type & CONST_DEFAULT)
+             else if (p->flags.is_default)
                {
                  move = RIGHT;
                }
@@ -1538,7 +1540,7 @@ asn1_get_start_end_der (node_asn * root, unsigned char *der, int len,
 
       if (ris == ASN_OK)
        {
-         switch (type_field (p->type))
+         switch (p->type)
            {
            case TYPE_NULL:
              if (der[counter])
@@ -1554,27 +1556,27 @@ asn1_get_start_end_der (node_asn * root, unsigned char *der, int len,
              break;
            case TYPE_INTEGER:
            case TYPE_ENUMERATED:
-             len2 = _asn1_get_length_der (der + counter, &len3);
+             len2 = _ksba_asn_get_length_der (der + counter, &len3);
              counter += len3 + len2;
              move = RIGHT;
              break;
            case TYPE_OBJECT_ID:
-             len2 = _asn1_get_length_der (der + counter, &len3);
+             len2 = _ksba_asn_get_length_der (der + counter, &len3);
              counter += len2 + len3;
              move = RIGHT;
              break;
            case TYPE_TIME:
-             len2 = _asn1_get_length_der (der + counter, &len3);
+             len2 = _ksba_asn_get_length_der (der + counter, &len3);
              counter += len2 + len3;
              move = RIGHT;
              break;
            case TYPE_OCTET_STRING:
-             len2 = _asn1_get_length_der (der + counter, &len3);
+             len2 = _ksba_asn_get_length_der (der + counter, &len3);
              counter += len3 + len2;
              move = RIGHT;
              break;
            case TYPE_BIT_STRING:
-             len2 = _asn1_get_length_der (der + counter, &len3);
+             len2 = _ksba_asn_get_length_der (der + counter, &len3);
              counter += len3 + len2;
              move = RIGHT;
              break;
@@ -1582,7 +1584,7 @@ asn1_get_start_end_der (node_asn * root, unsigned char *der, int len,
            case TYPE_SET:
              if (move != UP)
                {
-                 len3 = _asn1_get_length_der (der + counter, &len2);
+                 len3 = _ksba_asn_get_length_der (der + counter, &len2);
                  counter += len2;
                  move = DOWN;
                }
@@ -1593,13 +1595,12 @@ asn1_get_start_end_der (node_asn * root, unsigned char *der, int len,
            case TYPE_SET_OF:
              if (move != UP)
                {
-                 len3 = _asn1_get_length_der (der + counter, &len2);
+                 len3 = _ksba_asn_get_length_der (der + counter, &len2);
                  counter += len2;
                  if (len3)
                    {
                      p2 = p->down;
-                     while ((type_field (p2->type) == TYPE_TAG) ||
-                            (type_field (p2->type) == TYPE_SIZE))
+                     while (p2->type == TYPE_TAG || p2->type == TYPE_SIZE)
                        p2 = p2->right;
                      p = p2;
                    }
@@ -1608,7 +1609,7 @@ asn1_get_start_end_der (node_asn * root, unsigned char *der, int len,
              break;
            case TYPE_ANY:
              tag = _asn1_get_tag_der (der + counter, &class, &len2);
-             len2 += _asn1_get_length_der (der + counter + len2, &len3);
+             len2 += _ksba_asn_get_length_der (der + counter + len2, &len3);
              counter += len3 + len2;
              move = RIGHT;
              break;
@@ -1634,7 +1635,7 @@ asn1_get_start_end_der (node_asn * root, unsigned char *der, int len,
          else
            move = RIGHT;
        }
-      if ((move == RIGHT) && !(p->type & CONST_SET))
+      if ((move == RIGHT) && !p->flags.is_set)
        {
          if (p->right)
            p = p->right;
@@ -1642,7 +1643,7 @@ asn1_get_start_end_der (node_asn * root, unsigned char *der, int len,
            move = UP;
        }
       if (move == UP)
-       p = _asn1_find_up (p);
+       p = find_up (p);
     }
 
   return ASN_ELEMENT_NOT_FOUND;
index 3971d40..559b9ad 100644 (file)
 
 #include "asn1-func.h"
 
-#define UNIVERSAL        0x00
-#define APPLICATION      0x40
-#define CONTEXT_SPECIFIC 0x80
-#define PRIVATE          0xC0
-#define STRUCTURED       0x20
-
-
 void
 _asn1_octet_der(unsigned char *str,int str_len,unsigned char *der,int *der_len);
 
@@ -44,13 +37,15 @@ int
 _asn1_get_bit_der(unsigned char *der,int *der_len,unsigned char *str, int str_size, int *bit_len);
 
 int 
-asn1_create_der(node_asn *root,char *name,unsigned char *der,int *len);
+asn1_create_der(AsnNode root,char *name,unsigned char *der,int *len);
 
 int 
-asn1_get_der(node_asn *root,unsigned char *der,int len);
+asn1_get_der(AsnNode root,unsigned char *der,int len);
 
 int 
-asn1_get_start_end_der(node_asn *root,unsigned char *der,int len,char *name_element,int *start, int *end);
+asn1_get_start_end_der(AsnNode root,unsigned char *der,int len,char *name_element,int *start, int *end);
+
+unsigned long _ksba_asn_get_length_der (unsigned char *der, int *len);
 
 
 #endif /*ASN1_DER_H*/
index 7fd940a..c337233 100755 (executable)
 #include "asn1-der.h"
 #include "util.h"
 
+static int expand_identifier (AsnNode * node, AsnNode root);
+static int type_choice_config (AsnNode  node);
 
-#define UP     1
-#define RIGHT  2
-#define DOWN   3
 
-
-int parse_mode;
-
-
-/******************************************************/
-/* Function : add_node                                */
-/* Description: adds an element to the list of nodes. */
-/* Parameters:                                        */
-/*   unsigned int type: node description (see TYPE_   */
-/*                      and CONST_ constants)         */
-/* Return: node_asn                                   */
-/*   Pointer to the new element                       */
-/******************************************************/
-node_asn *
-_asn1_add_node (unsigned int type)
+static AsnNode 
+add_node (node_type_t type)
 {
-  node_asn *punt;
+  AsnNode punt;
 
-  if (parse_mode == PARSE_MODE_CHECK)
-    return NULL;
-
-  punt = xmalloc (sizeof (node_asn));
+  punt = xmalloc (sizeof *punt);
 
   punt->left = NULL;
   punt->name = NULL;
@@ -63,39 +46,38 @@ _asn1_add_node (unsigned int type)
   punt->value = NULL;
   punt->down = NULL;
   punt->right = NULL;
-
+  punt->link_next = NULL;
   return punt;
 }
 
 
-node_asn *
-_asn1_set_value (node_asn * node, unsigned char *value, unsigned int len)
+/* Change the value field of the node to the content of buffer value
+   of size LEN.  With VALUE of NULL or LEN of 0 the value field is
+   deleted */
+void
+_ksba_asn_set_value (AsnNode node, const void *value, unsigned int len)
 {
-  if (parse_mode == PARSE_MODE_CHECK)
-    return NULL;
+  return_if_fail (node);
 
-  if (node == NULL)
-    return node;
   if (node->value)
     {
       xfree (node->value);
       node->value = NULL;
     }
-  if (!len)
-    return node;
-  node->value = xmalloc (len);
-  memcpy (node->value, value, len);
-  return node;
+  if (value && len)
+    {
+      node->value = xmalloc (len);
+      memcpy (node->value, value, len);
+    }
 }
 
-node_asn *
-_asn1_set_name (node_asn * node, char *name)
-{
-  if (parse_mode == PARSE_MODE_CHECK)
-    return NULL;
 
-  if (node == NULL)
-    return node;
+/* Change the name field of the node to NAME.  
+   NAME may be NULL */
+void 
+_ksba_asn_set_name (AsnNode node, const char *name)
+{
+  return_if_fail (node);
 
   if (node->name)
     {
@@ -103,26 +85,14 @@ _asn1_set_name (node_asn * node, char *name)
       node->name = NULL;
     }
 
-  if (name == NULL)
-    return node;
-
-  if (strlen (name))
-    {
-      node->name = xmalloc (strlen (name) + 1);
-      strcpy (node->name, name);
-    }
-  else
-    node->name = NULL;
-  return node;
+  if (name && *name)
+      node->name = xstrdup (name);
 }
 
 
-node_asn *
-_asn1_set_right (node_asn * node, node_asn * right)
+static AsnNode 
+set_right (AsnNode  node, AsnNode  right)
 {
-  if (parse_mode == PARSE_MODE_CHECK)
-    return NULL;
-
   if (node == NULL)
     return node;
   node->right = right;
@@ -132,38 +102,9 @@ _asn1_set_right (node_asn * node, node_asn * right)
 }
 
 
-node_asn *
-_asn1_get_right (node_asn * node)
+static AsnNode 
+set_down (AsnNode node, AsnNode down)
 {
-  if (parse_mode == PARSE_MODE_CHECK)
-    return NULL;
-
-  if (node == NULL)
-    return NULL;
-  return node->right;
-}
-
-node_asn *
-_asn1_get_last_right (node_asn * node)
-{
-  node_asn *p;
-
-  if (parse_mode == PARSE_MODE_CHECK)
-    return NULL;
-  if (node == NULL)
-    return NULL;
-  p = node;
-  while (p->right)
-    p = p->right;
-  return p;
-}
-
-node_asn *
-_asn1_set_down (node_asn * node, node_asn * down)
-{
-  if (parse_mode == PARSE_MODE_CHECK)
-    return NULL;
-
   if (node == NULL)
     return node;
   node->down = down;
@@ -172,45 +113,10 @@ _asn1_set_down (node_asn * node, node_asn * down)
   return node;
 }
 
-node_asn *
-_asn1_get_down (node_asn * node)
-{
-  if (parse_mode == PARSE_MODE_CHECK)
-    return NULL;
-
-  if (node == NULL)
-    return NULL;
-  return node->down;
-}
-
-char *
-_asn1_get_name (node_asn * node)
-{
-  if (parse_mode == PARSE_MODE_CHECK)
-    return NULL;
-
-  if (node == NULL)
-    return NULL;
-  return node->name;
-}
-
-node_asn *
-_asn1_mod_type (node_asn * node, unsigned int value)
-{
-  if (parse_mode == PARSE_MODE_CHECK)
-    return NULL;
-
-  if (node == NULL)
-    return node;
-  node->type |= value;
-  return node;
-}
 
 void
-_asn1_remove_node (node_asn * node)
+_ksba_asn_remove_node (AsnNode  node)
 {
-  node_asn *punt, *punt_prev;
-
   if (node == NULL)
     return;
 
@@ -221,10 +127,10 @@ _asn1_remove_node (node_asn * node)
 
 
 
-node_asn *
-_asn1_find_node (node_asn * pointer, char *name)
+AsnNode 
+_ksba_asn_find_node (AsnNode  pointer, char *name)
 {
-  node_asn *p;
+  AsnNode p;
   char *n_start, *n_end, n[128];
 
   if ((name == NULL) || (name[0] == 0))
@@ -303,8 +209,8 @@ _asn1_find_node (node_asn * pointer, char *name)
 }
 
 
-node_asn *
-_asn1_find_left (node_asn * node)
+AsnNode 
+_asn1_find_left (AsnNode  node)
 {
   if ((node == NULL) || (node->left == NULL) || (node->left->down == node))
     return NULL;
@@ -313,10 +219,10 @@ _asn1_find_left (node_asn * node)
 }
 
 
-node_asn *
-_asn1_find_up (node_asn * node)
+static AsnNode 
+find_up (AsnNode  node)
 {
-  node_asn *p;
+  AsnNode p;
 
   if (node == NULL)
     return NULL;
@@ -375,7 +281,7 @@ _asn1_convert_integer (char *value, unsigned char *value_out,
 
 /**
  * Creates the structures needed to manage the ASN1 definitions. ROOT is
- * a vector created by 'asn1_parser_asn1_file_c' function.
+ * a vector created by the asn1-gentables tool.
  * 
  * Input Parameter: 
  *   
@@ -383,7 +289,7 @@ _asn1_convert_integer (char *value, unsigned char *value_out,
  * 
  * Output Parameter:
  * 
- *   node_asn **pointer : return the pointer to the structure created by
+ *   AsnNode *pointer : return the pointer to the structure created by
  *   *ROOT ASN.1 declarations.
  * 
  * Return Value:
@@ -391,11 +297,11 @@ _asn1_convert_integer (char *value, unsigned char *value_out,
  *   ASN_GENERIC_ERROR: an error occured while structure creation.
  */ 
 int
-asn1_create_tree (const static_asn * root, node_asn ** pointer)
+ksba_asn_create_tree (const static_asn * root, AsnNode * pointer)
 {
-  node_asn *p, *p_last;
+  enum { DOWN, UP, RIGHT } move;
+  AsnNode p, p_last;
   unsigned long k;
-  int move;
 
   *pointer = NULL;
   move = UP;
@@ -403,25 +309,27 @@ asn1_create_tree (const static_asn * root, node_asn ** pointer)
   k = 0;
   while (root[k].value || root[k].type || root[k].name)
     {
-      p = _asn1_add_node (root[k].type & (~CONST_DOWN));
+      p = add_node (root[k].type);
+      p->flags = root[k].flags;
+      p->flags.help_down = 0;
       if (root[k].name)
-       _asn1_set_name (p, root[k].name);
+       _ksba_asn_set_name (p, root[k].name);
       if (root[k].value)
-       _asn1_set_value (p, root[k].value, strlen (root[k].value) + 1);
+       _ksba_asn_set_value (p, root[k].value, strlen (root[k].value) + 1);
 
       if (*pointer == NULL)
        *pointer = p;
 
       if (move == DOWN)
-       _asn1_set_down (p_last, p);
+       set_down (p_last, p);
       else if (move == RIGHT)
-       _asn1_set_right (p_last, p);
+       set_right (p_last, p);
 
       p_last = p;
 
-      if (root[k].type & CONST_DOWN)
+      if (root[k].flags.help_down)
        move = DOWN;
-      else if (root[k].type & CONST_RIGHT)
+      else if (root[k].flags.help_right)
        move = RIGHT;
       else
        {
@@ -430,14 +338,14 @@ asn1_create_tree (const static_asn * root, node_asn ** pointer)
              if (p_last == *pointer)
                break;
 
-             p_last = _asn1_find_up (p_last);
+             p_last = find_up (p_last);
 
              if (p_last == NULL)
                break;
 
-             if (p_last->type & CONST_RIGHT)
+             if (p_last->flags.help_right)
                {
-                 p_last->type &= ~CONST_RIGHT;
+                 p_last->flags.help_right = 0;
                  move = RIGHT;
                  break;
                }
@@ -448,132 +356,25 @@ asn1_create_tree (const static_asn * root, node_asn ** pointer)
 
   if (p_last == *pointer)
     {
-      _asn1_change_integer_value (*pointer);
-      _asn1_expand_object_id (*pointer);
+      _ksba_asn_change_integer_value (*pointer);
+      _ksba_asn_expand_object_id (*pointer);
     }
   else
-    asn1_delete_structure (*pointer);
+    ksba_asn_delete_structure (*pointer);
 
   return (p_last == *pointer) ? ASN_OK : ASN_GENERIC_ERROR;
 }
 
 
-int
-_asn1_create_static_structure (node_asn * pointer,
-                              char *file_name, char *out_name)
-{
-  FILE *file;
-  node_asn *p;
-  unsigned long t;
-  char structure_name[128], file_out_name[128], *char_p, *slash_p, *dot_p;
-
-  char_p = file_name;
-  slash_p = file_name;
-  while ((char_p = strchr (char_p, '/')))
-    {
-      char_p++;
-      slash_p = char_p;
-    }
-
-  char_p = slash_p;
-  dot_p = file_name + strlen (file_name);
-
-  while ((char_p = strchr (char_p, '.')))
-    {
-      dot_p = char_p;
-      char_p++;
-    }
-
-  memcpy (structure_name, slash_p, dot_p - slash_p);
-  structure_name[dot_p - slash_p] = 0;
-  strcat (structure_name, "_asn1_tab");
-
-  if (out_name == NULL)
-    {
-      memcpy (file_out_name, file_name, dot_p - file_name);
-      file_out_name[dot_p - file_name] = 0;
-      strcat (file_out_name, "_asn1_tab.c");
-    }
-  else
-    {
-      strncpy (file_out_name, out_name, sizeof (file_out_name));
-    }
-  file = fopen (file_out_name, "w");
-
-  if (file == NULL)
-    return ASN_FILE_NOT_FOUND;
-
-  fprintf (file, "\n#include \"asn1-func.h\"\n\n");
-  fprintf (file, "const static_asn %s[]={\n", structure_name);
-
-  p = pointer;
-
-  while (p)
-    {
-      fprintf (file, "  {");
-
-      if (p->name)
-       fprintf (file, "\"%s\",", p->name);
-      else
-       fprintf (file, "0,");
-
-      t = p->type;
-      if (p->down)
-       t |= CONST_DOWN;
-      if (p->right)
-       t |= CONST_RIGHT;
-
-      fprintf (file, "%lu,", t);
-
-      if (p->value)
-       fprintf (file, "\"%s\"},\n", p->value);
-      else
-       fprintf (file, "0},\n");
-
-      if (p->down)
-       {
-         p = p->down;
-       }
-      else if (p->right)
-       {
-         p = p->right;
-       }
-      else
-       {
-         while (1)
-           {
-             p = _asn1_find_up (p);
-             if (p == pointer)
-               {
-                 p = NULL;
-                 break;
-               }
-             if (p->right)
-               {
-                 p = p->right;
-                 break;
-               }
-           }
-       }
-    }
-
-  fprintf (file, "  {0,0,0}\n};\n");
-
-  fclose (file);
-
-  return ASN_OK;
-}
 
 
 void
-asn1_visit_tree (node_asn * pointer, char *name)
+asn1_visit_tree (AsnNode  pointer, char *name)
 {
-  node_asn *p, *root;
+  AsnNode p, root;
   int k, indent = 0, len, len2, len3;
-  unsigned char class;
-  unsigned long tag;
 
-  root = _asn1_find_node (pointer, name);
+  root = name? _ksba_asn_find_node (pointer, name) : pointer;
 
   if (root == NULL)
     return;
@@ -591,7 +392,7 @@ asn1_visit_tree (node_asn * pointer, char *name)
        printf ("NULL  ");
 
       printf ("type:");
-      switch (type_field (p->type))
+      switch (p->type)
        {
        case TYPE_NULL:
          printf ("NULL");
@@ -610,7 +411,7 @@ asn1_visit_tree (node_asn * pointer, char *name)
          printf ("INTEGER");
          if (p->value)
            {
-             len = _asn1_get_length_der (p->value, &len2);
+             len = _ksba_asn_get_length_der (p->value, &len2);
              printf ("  value:0x");
              for (k = 0; k < len; k++)
                printf ("%02x", (p->value)[k + len2]);
@@ -620,7 +421,7 @@ asn1_visit_tree (node_asn * pointer, char *name)
          printf ("ENUMERATED");
          if (p->value)
            {
-             len = _asn1_get_length_der (p->value, &len2);
+             len = _ksba_asn_get_length_der (p->value, &len2);
              printf ("  value:0x");
              for (k = 0; k < len; k++)
                printf ("%02x", (p->value)[k + len2]);
@@ -648,7 +449,7 @@ asn1_visit_tree (node_asn * pointer, char *name)
          printf ("BIT_STR");
          if (p->value)
            {
-             len = _asn1_get_length_der (p->value, &len2);
+             len = _ksba_asn_get_length_der (p->value, &len2);
              printf ("  value(%i):", (len - 1) * 8 - (p->value[len2]));
              for (k = 1; k < len; k++)
                printf ("%02x", (p->value)[k + len2]);
@@ -658,7 +459,7 @@ asn1_visit_tree (node_asn * pointer, char *name)
          printf ("OCT_STR");
          if (p->value)
            {
-             len = _asn1_get_length_der (p->value, &len2);
+             len = _ksba_asn_get_length_der (p->value, &len2);
              printf ("  value:");
              for (k = 0; k < len; k++)
                printf ("%02x", (p->value)[k + len2]);
@@ -690,7 +491,7 @@ asn1_visit_tree (node_asn * pointer, char *name)
          printf ("ANY");
          if (p->value)
            {
-             len2 = _asn1_get_length_der (p->value, &len3);
+             len2 = _ksba_asn_get_length_der (p->value, &len3);
              printf ("  value:");
              for (k = 0; k < len2; k++)
                printf ("%02x", (p->value)[k + len3]);
@@ -713,51 +514,47 @@ asn1_visit_tree (node_asn * pointer, char *name)
          printf ("ERROR\n");
          break;
        }
-
+      
       if (p->type & 0xFFFFFF00)
-       {
-         printf ("  attr:");
-         if (p->type & CONST_UNIVERSAL)
-           printf ("UNIVERSAL,");
-         if (p->type & CONST_PRIVATE)
-           printf ("PRIVATE,");
-         if (p->type & CONST_APPLICATION)
-           printf ("APPLICATION,");
-         if (p->type & CONST_EXPLICIT)
+        {
+          printf ("  attr:");
+          switch (p->flags.class)
+            { 
+            case CLASS_UNIVERSAL: printf ("UNIVERSAL,"); break;
+            case CLASS_PRIVATE:   printf ("PRIVATE,"); break;
+            case CLASS_APPLICATION: printf ("APPLICTION,"); break;
+            case CLASS_CONTEXT: printf ("CONTEXT,"); break;
+            }
+
+         if (p->flags.explicit)
            printf ("EXPLICIT,");
-         if (p->type & CONST_IMPLICIT)
+         if (p->flags.implicit)
            printf ("IMPLICIT,");
-         if (p->type & CONST_TAG)
+         if (p->flags.has_tag)
            printf ("TAG,");
-         if (p->type & CONST_DEFAULT)
+         if (p->flags.is_default)
            printf ("DEFAULT,");
-         if (p->type & CONST_TRUE)
+         if (p->flags.is_true)
            printf ("TRUE,");
-         if (p->type & CONST_FALSE)
+         if (p->flags.is_false)
            printf ("FALSE,");
-         if (p->type & CONST_LIST)
+         if (p->flags.has_list)
            printf ("LIST,");
-         if (p->type & CONST_MIN_MAX)
+         if (p->flags.has_min_max)
            printf ("MIN_MAX,");
-         if (p->type & CONST_OPTION)
+         if (p->flags.is_optional)
            printf ("OPTION,");
-         if (p->type & CONST_1_PARAM)
+         if (p->flags.one_param)
            printf ("1_PARAM,");
-         if (p->type & CONST_SIZE)
+         if (p->flags.has_size)
            printf ("SIZE,");
-         if (p->type & CONST_DEFINED_BY)
+         if (p->flags.has_defined_by)
            printf ("DEF_BY,");
-         if (p->type & CONST_GENERALIZED)
-           printf ("GENERALIZED,");
-         if (p->type & CONST_UTC)
+         if (p->flags.is_utc_time)
            printf ("UTC,");
-         if (p->type & CONST_IMPORTS)
+         if (p->flags.has_imports)
            printf ("IMPORTS,");
-         if (p->type & CONST_SET)
-           printf ("SET,");
-         if (p->type & CONST_NOT_USED)
-           printf ("NOT_USED,");
-         if (p->type & CONST_ASSIGN)
+         if (p->flags.assignment)
            printf ("ASSIGNEMENT,");
        }
 
@@ -779,7 +576,7 @@ asn1_visit_tree (node_asn * pointer, char *name)
        {
          while (1)
            {
-             p = _asn1_find_up (p);
+             p = find_up (p);
              if (p == root)
                {
                  p = NULL;
@@ -797,9 +594,9 @@ asn1_visit_tree (node_asn * pointer, char *name)
 }
 
 int
-asn1_delete_structure (node_asn * root)
+ksba_asn_delete_structure (AsnNode root)
 {
-  node_asn *p, *p2, *p3;
+  AsnNode p, p2, p3;
 
   if (root == NULL)
     return ASN_ELEMENT_NOT_FOUND;
@@ -816,9 +613,9 @@ asn1_delete_structure (node_asn * root)
          p2 = p->right;
          if (p != root)
            {
-             p3 = _asn1_find_up (p);
-             _asn1_set_down (p3, p2);
-             _asn1_remove_node (p);
+             p3 = find_up (p);
+             set_down (p3, p2);
+             _ksba_asn_remove_node (p);
              p = p3;
            }
          else
@@ -826,9 +623,9 @@ asn1_delete_structure (node_asn * root)
              p3 = _asn1_find_left (p);
              if (!p3)
                {
-                 p3 = _asn1_find_up (p);
+                 p3 = find_up (p);
                  if (p3)
-                   _asn1_set_down (p3, p2);
+                   set_down (p3, p2);
                  else
                    {
                      if (p->right)
@@ -836,8 +633,8 @@ asn1_delete_structure (node_asn * root)
                    }
                }
              else
-               _asn1_set_right (p3, p2);
-             _asn1_remove_node (p);
+               set_right (p3, p2);
+             _ksba_asn_remove_node (p);
              p = NULL;
            }
        }
@@ -846,16 +643,17 @@ asn1_delete_structure (node_asn * root)
 }
 
 
-node_asn *
-_asn1_copy_structure3 (node_asn * source_node)
+AsnNode 
+_asn1_copy_structure3 (AsnNode  source_node)
 {
-  node_asn *dest_node, *p_s, *p_d, *p_d_prev;
-  int len, len2, move;
+  AsnNode dest_node, p_s, p_d, p_d_prev;
+  int len, len2;
+  enum { DOWN, UP, RIGHT } move;
 
   if (source_node == NULL)
     return NULL;
 
-  dest_node = _asn1_add_node (source_node->type);
+  dest_node = add_node (source_node->type);
 
   p_s = source_node;
   p_d = dest_node;
@@ -867,20 +665,20 @@ _asn1_copy_structure3 (node_asn * source_node)
       if (move != UP)
        {
          if (p_s->name)
-           _asn1_set_name (p_d, p_s->name);
+           _ksba_asn_set_name (p_d, p_s->name);
          if (p_s->value)
            {
-             switch (type_field (p_s->type))
+             switch (p_s->type)
                {
                case TYPE_OCTET_STRING:
                case TYPE_BIT_STRING:
                case TYPE_INTEGER:
                case TYPE_DEFAULT:
-                 len = _asn1_get_length_der (p_s->value, &len2);
-                 _asn1_set_value (p_d, p_s->value, len + len2);
+                 len = _ksba_asn_get_length_der (p_s->value, &len2);
+                 _ksba_asn_set_value (p_d, p_s->value, len + len2);
                  break;
                default:
-                 _asn1_set_value (p_d, p_s->value, strlen (p_s->value) + 1);
+                 _ksba_asn_set_value (p_d, p_s->value, strlen (p_s->value) + 1);
                }
            }
          move = DOWN;
@@ -894,8 +692,8 @@ _asn1_copy_structure3 (node_asn * source_node)
            {
              p_s = p_s->down;
              p_d_prev = p_d;
-             p_d = _asn1_add_node (p_s->type);
-             _asn1_set_down (p_d_prev, p_d);
+             p_d = add_node (p_s->type);
+             set_down (p_d_prev, p_d);
            }
          else
            move = RIGHT;
@@ -910,16 +708,16 @@ _asn1_copy_structure3 (node_asn * source_node)
            {
              p_s = p_s->right;
              p_d_prev = p_d;
-             p_d = _asn1_add_node (p_s->type);
-             _asn1_set_right (p_d_prev, p_d);
+             p_d = add_node (p_s->type);
+             set_right (p_d_prev, p_d);
            }
          else
            move = UP;
        }
       if (move == UP)
        {
-         p_s = _asn1_find_up (p_s);
-         p_d = _asn1_find_up (p_d);
+         p_s = find_up (p_s);
+         p_d = find_up (p_d);
        }
     }
   while (p_s != source_node);
@@ -928,12 +726,12 @@ _asn1_copy_structure3 (node_asn * source_node)
 }
 
 
-node_asn *
-_asn1_copy_structure2 (node_asn * root, char *source_name)
+AsnNode 
+_asn1_copy_structure2 (AsnNode  root, char *source_name)
 {
-  node_asn *source_node;
+  AsnNode source_node;
 
-  source_node = _asn1_find_node (root, source_name);
+  source_node = _ksba_asn_find_node (root, source_name);
 
   return _asn1_copy_structure3 (source_node);
 
@@ -941,10 +739,10 @@ _asn1_copy_structure2 (node_asn * root, char *source_name)
 
 
 int
-asn1_create_structure (node_asn * root, char *source_name,
-                      node_asn ** pointer, char *dest_name)
+ksba_asn1_create_structure (AsnNode  root, char *source_name,
+                            AsnNode * pointer, char *dest_name)
 {
-  node_asn *dest_node;
+  AsnNode dest_node;
   int res;
   char *end, n[129];
 
@@ -955,7 +753,7 @@ asn1_create_structure (node_asn * root, char *source_name,
   if (dest_node == NULL)
     return ASN_ELEMENT_NOT_FOUND;
 
-  _asn1_set_name (dest_node, dest_name);
+  _ksba_asn_set_name (dest_node, dest_name);
 
   end = strchr (source_name, '.');
   if (end)
@@ -968,8 +766,8 @@ asn1_create_structure (node_asn * root, char *source_name,
       strcpy (n, source_name);
     }
 
-  res = _asn1_expand_identifier (&dest_node, root);
-  _asn1_type_choice_config (dest_node);
+  res = expand_identifier (&dest_node, root);
+  type_choice_config (dest_node);
 
   *pointer = dest_node;
 
@@ -978,9 +776,9 @@ asn1_create_structure (node_asn * root, char *source_name,
 
 
 int
-_asn1_append_sequence_set (node_asn * node)
+_asn1_append_sequence_set (AsnNode  node)
 {
-  node_asn *p, *p2;
+  AsnNode p, p2;
   char *temp;
   long n;
 
@@ -988,13 +786,12 @@ _asn1_append_sequence_set (node_asn * node)
     return ASN_GENERIC_ERROR;
 
   p = node->down;
-  while ((type_field (p->type) == TYPE_TAG)
-        || (type_field (p->type) == TYPE_SIZE))
+  while (p->type == TYPE_TAG || p->type == TYPE_SIZE)
     p = p->right;
   p2 = _asn1_copy_structure3 (p);
   while (p->right)
     p = p->right;
-  _asn1_set_right (p, p2);
+  set_right (p, p2);
   temp = xmalloc (10);
   if (p->name == NULL)
     strcpy (temp, "?1");
@@ -1005,7 +802,7 @@ _asn1_append_sequence_set (node_asn * node)
       temp[0] = '?';
       _asn1_ltostr (n, temp + 1);
     }
-  _asn1_set_name (p2, temp);
+  _ksba_asn_set_name (p2, temp);
   xfree (temp);
 
   return ASN_OK;
@@ -1013,63 +810,48 @@ _asn1_append_sequence_set (node_asn * node)
 
 
 int
-asn1_write_value (node_asn * node_root, char *name, unsigned char *value,
-                 int len)
+ksba_asn1_write_value (AsnNode  node_root, char *name, unsigned char *value,
+                       int len)
 {
-  node_asn *node, *p, *p2;
+  AsnNode node, p, p2;
   unsigned char *temp, *value_temp, *default_temp, val[4];
   int len2, k, k2, negative;
   unsigned char *root, *n_end;
 
-  node = _asn1_find_node (node_root, name);
+  node = _ksba_asn_find_node (node_root, name);
   if (node == NULL)
     return ASN_ELEMENT_NOT_FOUND;
 
-  if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0))
+  if (node->flags.is_optional && !value && !len)
     {
-      asn1_delete_structure (node);
+      ksba_asn_delete_structure (node);
       return ASN_OK;
     }
 
-  switch (type_field (node->type))
+  switch (node->type)
     {
     case TYPE_BOOLEAN:
-      if (!strcmp (value, "TRUE"))
+      if (!strcmp (value, "TRUE") || !strcmp (value, "FALSE"))
        {
-         if (node->type & CONST_DEFAULT)
+         if (node->flags.is_default)
            {
              p = node->down;
-             while (type_field (p->type) != TYPE_DEFAULT)
+             while (p->type == TYPE_DEFAULT)
                p = p->right;
-             if (p->type & CONST_TRUE)
-               _asn1_set_value (node, NULL, 0);
+             if (*value == 'T'? p->flags.is_true: p->flags.is_false)
+               _ksba_asn_set_value (node, NULL, 0);
              else
-               _asn1_set_value (node, "T", 1);
+               _ksba_asn_set_value (node, value, 1);
            }
          else
-           _asn1_set_value (node, "T", 1);
-       }
-      else if (!strcmp (value, "FALSE"))
-       {
-         if (node->type & CONST_DEFAULT)
-           {
-             p = node->down;
-             while (type_field (p->type) != TYPE_DEFAULT)
-               p = p->right;
-             if (p->type & CONST_FALSE)
-               _asn1_set_value (node, NULL, 0);
-             else
-               _asn1_set_value (node, "F", 1);
-           }
-         else
-           _asn1_set_value (node, "F", 1);
+           _ksba_asn_set_value (node, value, 1);
        }
       else
        return ASN_VALUE_NOT_VALID;
       break;
     case TYPE_INTEGER:
     case TYPE_ENUMERATED:
-      if (len == 0)
+      if (!len)
        {
          if (isdigit (value[0]))
            {
@@ -1078,14 +860,14 @@ asn1_write_value (node_asn * node_root, char *name, unsigned char *value,
            }
          else
            {                   /* is an identifier like v1 */
-             if (!(node->type & CONST_LIST))
+             if (!(node->flags.has_list))
                return ASN_VALUE_NOT_VALID;
              p = node->down;
              while (p)
                {
-                 if (type_field (p->type) == TYPE_CONSTANT)
+                 if (p->type == TYPE_CONSTANT)
                    {
-                     if ((p->name) && (!strcmp (p->name, value)))
+                     if (p->name && !strcmp (p->name, value))
                        {
                          value_temp = xmalloc (4);
                          _asn1_convert_integer (p->value, value_temp, 4,
@@ -1095,7 +877,7 @@ asn1_write_value (node_asn * node_root, char *name, unsigned char *value,
                    }
                  p = p->right;
                }
-             if (p == NULL)
+             if (!p)
                return ASN_VALUE_NOT_VALID;
            }
        }
@@ -1111,7 +893,7 @@ asn1_write_value (node_asn * node_root, char *name, unsigned char *value,
       else
        negative = 0;
 
-      if (negative && (type_field (node->type) == TYPE_ENUMERATED))
+      if (negative && node->type == TYPE_ENUMERATED)
        {
          xfree (value_temp);
          return ASN_VALUE_NOT_VALID;
@@ -1130,14 +912,14 @@ asn1_write_value (node_asn * node_root, char *name, unsigned char *value,
       _asn1_length_der (len - k, NULL, &len2);
       temp = xmalloc (len - k + len2);
       _asn1_octet_der (value_temp + k, len - k, temp, &len2);
-      _asn1_set_value (node, temp, len2);
+      _ksba_asn_set_value (node, temp, len2);
 
       xfree (temp);
 
-      if (node->type & CONST_DEFAULT)
+      if (node->flags.is_default)
        {
          p = node->down;
-         while (type_field (p->type) != TYPE_DEFAULT)
+         while (p->type != TYPE_DEFAULT)
            p = p->right;
          if (isdigit (p->value[0]))
            {
@@ -1146,12 +928,12 @@ asn1_write_value (node_asn * node_root, char *name, unsigned char *value,
            }
          else
            {                   /* is an identifier like v1 */
-             if (!(node->type & CONST_LIST))
+             if (!node->flags.has_list)
                return ASN_VALUE_NOT_VALID;
              p2 = node->down;
              while (p2)
                {
-                 if (type_field (p2->type) == TYPE_CONSTANT)
+                 if (p2->type == TYPE_CONSTANT)
                    {
                      if ((p2->name) && (!strcmp (p2->name, p->value)))
                        {
@@ -1175,7 +957,7 @@ asn1_write_value (node_asn * node_root, char *name, unsigned char *value,
                    break;
                  }
              if (k2 == len2)
-               _asn1_set_value (node, NULL, 0);
+               _ksba_asn_set_value (node, NULL, 0);
            }
          xfree (default_temp);
        }
@@ -1185,10 +967,10 @@ asn1_write_value (node_asn * node_root, char *name, unsigned char *value,
       for (k = 0; k < strlen (value); k++)
        if ((!isdigit (value[k])) && (value[k] != ' ') && (value[k] != '+'))
          return ASN_VALUE_NOT_VALID;
-      _asn1_set_value (node, value, strlen (value) + 1);
+      _ksba_asn_set_value (node, value, strlen (value) + 1);
       break;
     case TYPE_TIME:
-      if (node->type & CONST_UTC)
+      if (node->flags.is_utc_time)
        {
          if (strlen (value) < 11)
            return ASN_VALUE_NOT_VALID;
@@ -1225,26 +1007,26 @@ asn1_write_value (node_asn * node_root, char *name, unsigned char *value,
            default:
              return ASN_VALUE_NOT_FOUND;
            }
-         _asn1_set_value (node, value, strlen (value) + 1);
+         _ksba_asn_set_value (node, value, strlen (value) + 1);
        }
       else
        {                       /* GENERALIZED TIME */
          if (value)
-           _asn1_set_value (node, value, strlen (value) + 1);
+           _ksba_asn_set_value (node, value, strlen (value) + 1);
        }
       break;
     case TYPE_OCTET_STRING:
       _asn1_length_der (len, NULL, &len2);
       temp = xmalloc (len + len2);
       _asn1_octet_der (value, len, temp, &len2);
-      _asn1_set_value (node, temp, len2);
+      _ksba_asn_set_value (node, temp, len2);
       xfree (temp);
       break;
     case TYPE_BIT_STRING:
       _asn1_length_der ((len >> 3) + 2, NULL, &len2);
       temp = xmalloc ((len >> 3) + 2 + len2);
       _asn1_bit_der (value, len, temp, &len2);
-      _asn1_set_value (node, temp, len2);
+      _ksba_asn_set_value (node, temp, len2);
       xfree (temp);
       break;
     case TYPE_CHOICE:
@@ -1258,7 +1040,7 @@ asn1_write_value (node_asn * node_root, char *name, unsigned char *value,
                {
                  if (p2 != p)
                    {
-                     asn1_delete_structure (p2);
+                     ksba_asn_delete_structure (p2);
                      p2 = node->down;
                    }
                  else
@@ -1275,7 +1057,7 @@ asn1_write_value (node_asn * node_root, char *name, unsigned char *value,
       _asn1_length_der (len, NULL, &len2);
       temp = xmalloc (len + len2);
       _asn1_octet_der (value, len, temp, &len2);
-      _asn1_set_value (node, temp, len2);
+      _ksba_asn_set_value (node, temp, len2);
       xfree (temp);
       break;
     case TYPE_SEQUENCE_OF:
@@ -1318,36 +1100,35 @@ asn1_write_value (node_asn * node_root, char *name, unsigned char *value,
 
 
 int
-asn1_read_value (node_asn * root, char *name, unsigned char *value, int *len)
+ksba_asn_read_value (AsnNode root, char *name, unsigned char *value, int *len)
 {
-  node_asn *node, *p;
+  AsnNode node, p;
   int len2, len3;
-  unsigned long tag;
-  unsigned char class;
   int value_size = *len;
 
-  node = _asn1_find_node (root, name);
+  node = _ksba_asn_find_node (root, name);
   if (node == NULL)
     return ASN_ELEMENT_NOT_FOUND;
 
-  if ((type_field (node->type) != TYPE_NULL) &&
-      (type_field (node->type) != TYPE_CHOICE) &&
-      !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) &&
-      (node->value == NULL))
+  if (node->type != TYPE_NULL
+      && node->type != TYPE_CHOICE
+      && !node->flags.is_default
+      && !node->flags.assignment 
+      && !node->value)
     return ASN_VALUE_NOT_FOUND;
 
-  switch (type_field (node->type))
+  switch (node->type)
     {
     case TYPE_NULL:
       PUT_STR_VALUE (value, value_size, "NULL");
       break;
     case TYPE_BOOLEAN:
-      if ((node->type & CONST_DEFAULT) && (node->value == NULL))
+      if (node->flags.is_default && !node->value)
        {
          p = node->down;
-         while (type_field (p->type) != TYPE_DEFAULT)
+         while (p->type != TYPE_DEFAULT)
            p = p->right;
-         if (p->type & CONST_TRUE)
+         if (p->flags.is_true)
            {
              PUT_STR_VALUE (value, value_size, "TRUE");
            }
@@ -1367,10 +1148,10 @@ asn1_read_value (node_asn * root, char *name, unsigned char *value, int *len)
       break;
     case TYPE_INTEGER:
     case TYPE_ENUMERATED:
-      if ((node->type & CONST_DEFAULT) && (node->value == NULL))
+      if (node->flags.is_default && !node->value)
        {
          p = node->down;
-         while (type_field (p->type) != TYPE_DEFAULT)
+         while (p->type != TYPE_DEFAULT)
            p = p->right;
          if (_asn1_convert_integer (p->value, value, value_size, len) !=
              ASN_OK)
@@ -1382,13 +1163,13 @@ asn1_read_value (node_asn * root, char *name, unsigned char *value, int *len)
        return ASN_MEM_ERROR;
       break;
     case TYPE_OBJECT_ID:
-      if (node->type & CONST_ASSIGN)
+      if (node->flags.assignment)
        {
          strcpy (value, "");
          p = node->down;
          while (p)
            {
-             if (type_field (p->type) == TYPE_CONSTANT)
+             if (p->type == TYPE_CONSTANT)
                {
                  ADD_STR_VALUE (value, value_size, p->value);
                  ADD_STR_VALUE (value, value_size, " ");
@@ -1418,7 +1199,7 @@ asn1_read_value (node_asn * root, char *name, unsigned char *value, int *len)
       PUT_STR_VALUE (value, value_size, node->down->name);
       break;
     case TYPE_ANY:
-      len2 = _asn1_get_length_der (node->value, &len3);
+      len2 = _ksba_asn_get_length_der (node->value, &len3);
       PUT_VALUE (value, value_size, node->value + len3, len2);
       break;
     default:
@@ -1429,134 +1210,100 @@ asn1_read_value (node_asn * root, char *name, unsigned char *value, int *len)
 }
 
 
-int
-_asn1_set_default_tag (node_asn * node)
-{
-  node_asn *p;
-
-  if ((node == NULL) || (type_field (node->type) != TYPE_DEFINITIONS))
-    return ASN_ELEMENT_NOT_FOUND;
-
-  p = node;
-  while (p)
-    {
-      if ((type_field (p->type) == TYPE_TAG) &&
-         !(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT))
-       {
-         if (node->type & CONST_EXPLICIT)
-           p->type |= CONST_EXPLICIT;
-         else
-           p->type |= CONST_IMPLICIT;
-       }
-
-      if (p->down)
-       {
-         p = p->down;
-       }
-      else if (p->right)
-       p = p->right;
-      else
-       {
-         while (1)
-           {
-             p = _asn1_find_up (p);
-             if (p == node)
-               {
-                 p = NULL;
-                 break;
-               }
-             if (p->right)
-               {
-                 p = p->right;
-                 break;
-               }
-           }
-       }
-    }
-
-  return ASN_OK;
-}
 
 
 int
-_asn1_check_identifier (node_asn * node)
+_ksba_asn_check_identifier (AsnNode node)
 {
-  node_asn *p, *p2;
+  AsnNode p, p2;
   char name2[129];
 
-  if (node == NULL)
+  if (!node)
     return ASN_ELEMENT_NOT_FOUND;
 
-  p = node;
-  while (p)
+  for (p = node; p; p = _ksba_asn_walk_tree (node, p))
     {
-      if (type_field (p->type) == TYPE_IDENTIFIER)
+      if (p->type == TYPE_IDENTIFIER)
        {
-         strcpy (name2, node->name);
-         strcat (name2, ".");
+          strcpy (name2, node->name);
+          strcat (name2, ".");
          strcat (name2, p->value);
-         p2 = _asn1_find_node (node, name2);
+         p2 = _ksba_asn_find_node (node, name2);
          if (p2 == NULL)
            {
-             printf ("%s\n", name2);
+             fprintf (stderr,"%s\n", name2);
              return ASN_IDENTIFIER_NOT_FOUND;
            }
        }
-      else if ((type_field (p->type) == TYPE_OBJECT_ID) &&
-              (p->type & CONST_ASSIGN))
+      else if (p->type == TYPE_OBJECT_ID
+              && p->flags.assignment)
        {
          p2 = p->down;
-         if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
-           {
+         if (p2 && (p2->type == TYPE_CONSTANT))
+            {
              if (p2->value && !isdigit (p2->value[0]))
                {
-                 strcpy (name2, node->name);
-                 strcat (name2, ".");
+                  strcpy (name2, node->name);
+                  strcat (name2, ".");
                  strcat (name2, p2->value);
-                 p2 = _asn1_find_node (node, name2);
-                 if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) ||
-                     !(p2->type & CONST_ASSIGN))
+                 p2 = _ksba_asn_find_node (node, name2);
+                 if (!p2 || (p2->type != TYPE_OBJECT_ID) 
+                      || !p2->flags.assignment)
                    {
-                     printf ("%s\n", name2);
+                     fprintf (stderr,"%s\n", name2);
                      return ASN_IDENTIFIER_NOT_FOUND;
                    }
                }
            }
        }
+    }
 
-      if (p->down)
-       {
-         p = p->down;
-       }
-      else if (p->right)
-       p = p->right;
+  return ASN_OK;
+}
+
+
+/* Get the next node until root is reached in which case NULL is
+   returned */
+AsnNode
+_ksba_asn_walk_tree (AsnNode root, AsnNode node)
+{
+  if (!node)
+    ;
+  else if (node->down)
+    node = node->down;
+  else
+    {
+      if (node == root)
+        node = NULL;
+      else if (node->right)
+        node = node->right;
       else
-       {
-         while (1)
-           {
-             p = _asn1_find_up (p);
-             if (p == node)
-               {
-                 p = NULL;
-                 break;
-               }
-             if (p->right)
-               {
-                 p = p->right;
-                 break;
-               }
-           }
-       }
+        {
+          for (;;)
+            {
+              node = find_up (node);
+              if (node == root)
+                {
+                  node = NULL;
+                  break;
+                }
+              if (node->right)
+                {
+                  node = node->right;
+                  break;
+                }
+            }
+        }
     }
 
-  return ASN_OK;
+  return node;
 }
 
 
 int
-_asn1_change_integer_value (node_asn * node)
+_ksba_asn_change_integer_value (AsnNode node)
 {
-  node_asn *p, *p2;
+  AsnNode p, p2;
   char negative;
   unsigned char val[4], val2[5], temp;
   int len, k, force_exit;
@@ -1564,45 +1311,15 @@ _asn1_change_integer_value (node_asn * node)
   if (node == NULL)
     return ASN_ELEMENT_NOT_FOUND;
 
-  p = node;
-  while (p)
+  for (p = node; p; p = _ksba_asn_walk_tree (node, p))
     {
-      if ((type_field (p->type) == TYPE_INTEGER) && (p->type & CONST_ASSIGN))
+      if (p->type == TYPE_INTEGER && p->flags.assignment)
        {
          if (p->value)
            {
              _asn1_convert_integer (p->value, val, sizeof (val), &len);
              _asn1_octet_der (val, len, val2, &len);
-             _asn1_set_value (p, val2, len);
-           }
-       }
-
-      if (p->down)
-       {
-         p = p->down;
-       }
-      else
-       {
-         if (p == node)
-           p = NULL;
-         else if (p->right)
-           p = p->right;
-         else
-           {
-             while (1)
-               {
-                 p = _asn1_find_up (p);
-                 if (p == node)
-                   {
-                     p = NULL;
-                     break;
-                   }
-                 if (p->right)
-                   {
-                     p = p->right;
-                     break;
-                   }
-               }
+             _ksba_asn_set_value (p, val2, len);
            }
        }
     }
@@ -1612,72 +1329,40 @@ _asn1_change_integer_value (node_asn * node)
 
 
 int
-_asn1_delete_not_used (node_asn * node)
+_ksba_asn_delete_not_used (AsnNode  node)
 {
-  node_asn *p, *p2;
+  AsnNode p, p2;
 
   if (node == NULL)
     return ASN_ELEMENT_NOT_FOUND;
 
-  p = node;
-  while (p)
+  for (p = node; p; p = _ksba_asn_walk_tree (node, p) )
     {
-      if (p->type & CONST_NOT_USED)
+      if (p->flags.is_not_used)
        {
          p2 = NULL;
          if (p != node)
            {
              p2 = _asn1_find_left (p);
              if (!p2)
-               p2 = _asn1_find_up (p);
+               p2 = find_up (p);
            }
-         asn1_delete_structure (p);
+         ksba_asn_delete_structure (p);
          p = p2;
        }
-
-      if (!p)
-       break;                  /* reach node */
-
-      if (p->down)
-       {
-         p = p->down;
-       }
-      else
-       {
-         if (p == node)
-           p = NULL;
-         else if (p->right)
-           p = p->right;
-         else
-           {
-             while (1)
-               {
-                 p = _asn1_find_up (p);
-                 if (p == node)
-                   {
-                     p = NULL;
-                     break;
-                   }
-                 if (p->right)
-                   {
-                     p = p->right;
-                     break;
-                   }
-               }
-           }
-       }
     }
+
   return ASN_OK;
 }
 
 
 
-int
-_asn1_expand_identifier (node_asn ** node, node_asn * root)
+static int
+expand_identifier (AsnNode * node, AsnNode  root)
 {
-  node_asn *p, *p2, *p3;
+  AsnNode p, p2, p3;
   char name2[129];
-  int move;
+  enum { DOWN, UP, RIGHT } move;
 
   if (node == NULL)
     return ASN_ELEMENT_NOT_FOUND;
@@ -1689,7 +1374,7 @@ _asn1_expand_identifier (node_asn ** node, node_asn * root)
     {
       if (move != UP)
        {
-         if (type_field (p->type) == TYPE_IDENTIFIER)
+         if (p->type == TYPE_IDENTIFIER)
            {
              strcpy (name2, root->name);
              strcat (name2, ".");
@@ -1697,7 +1382,7 @@ _asn1_expand_identifier (node_asn ** node, node_asn * root)
              p2 = _asn1_copy_structure2 (root, name2);
              if (p2 == NULL)
                return ASN_IDENTIFIER_NOT_FOUND;
-             _asn1_set_name (p2, p->name);
+             _ksba_asn_set_name (p2, p->name);
              p2->right = p->right;
              p2->left = p->left;
              if (p->right)
@@ -1707,40 +1392,40 @@ _asn1_expand_identifier (node_asn ** node, node_asn * root)
                {
                  while (p3->right)
                    p3 = p3->right;
-                 _asn1_set_right (p3, p2->down);
-                 _asn1_set_down (p2, p->down);
+                 set_right (p3, p2->down);
+                 set_down (p2, p->down);
                }
 
              p3 = _asn1_find_left (p);
              if (p3)
-               _asn1_set_right (p3, p2);
+               set_right (p3, p2);
              else
                {
-                 p3 = _asn1_find_up (p);
+                 p3 = find_up (p);
                  if (p3)
-                   _asn1_set_down (p3, p2);
+                   set_down (p3, p2);
                  else
                    {
                      p2->left = NULL;
                    }
                }
 
-             if (p->type & CONST_SIZE)
-               p2->type |= CONST_SIZE;
-             if (p->type & CONST_TAG)
-               p2->type |= CONST_TAG;
-             if (p->type & CONST_OPTION)
-               p2->type |= CONST_OPTION;
-             if (p->type & CONST_DEFAULT)
-               p2->type |= CONST_DEFAULT;
-             if (p->type & CONST_SET)
-               p2->type |= CONST_SET;
-             if (p->type & CONST_NOT_USED)
-               p2->type |= CONST_NOT_USED;
+             if (p->flags.has_size)
+               p2->flags.has_size = 1;
+             if (p->flags.has_tag)
+               p2->flags.has_tag = 1;
+             if (p->flags.is_optional)
+               p2->flags.is_optional = 1;
+             if (p->flags.is_default)
+               p2->flags.is_default = 1;
+             if (p->flags.is_set)
+               p2->flags.is_set = 1;;
+             if (p->flags.is_not_used)
+               p2->flags.is_not_used = 1;
 
              if (p == *node)
                *node = p2;
-             _asn1_remove_node (p);
+             _ksba_asn_remove_node (p);
              p = p2;
              move = DOWN;
              continue;
@@ -1772,7 +1457,7 @@ _asn1_expand_identifier (node_asn ** node, node_asn * root)
            move = UP;
        }
       if (move == UP)
-       p = _asn1_find_up (p);
+       p = find_up (p);
     }
 
   return ASN_OK;
@@ -1780,11 +1465,11 @@ _asn1_expand_identifier (node_asn ** node, node_asn * root)
 
 
 
-int
-_asn1_type_choice_config (node_asn * node)
+static int
+type_choice_config (AsnNode  node)
 {
-  node_asn *p, *p2, *p3, *p4;
-  int move;
+  AsnNode p, p2, p3, p4;
+  enum { DOWN, UP, RIGHT } move;
 
   if (node == NULL)
     return ASN_ELEMENT_NOT_FOUND;
@@ -1796,37 +1481,37 @@ _asn1_type_choice_config (node_asn * node)
     {
       if (move != UP)
        {
-         if ((type_field (p->type) == TYPE_CHOICE) && (p->type & CONST_TAG))
+         if (p->type == TYPE_CHOICE && p->flags.has_tag)
            {
              p2 = p->down;
              while (p2)
                {
-                 if (type_field (p2->type) != TYPE_TAG)
+                 if (p2->type != TYPE_TAG)
                    {
-                     p2->type |= CONST_TAG;
+                     p2->flags.has_tag =1;
                      p3 = _asn1_find_left (p2);
                      while (p3)
                        {
-                         if (type_field (p3->type) == TYPE_TAG)
+                         if (p3->type == TYPE_TAG)
                            {
-                             p4 = _asn1_add_node (p3->type);
-                             _asn1_set_value (p4, p3->value,
+                             p4 = add_node (p3->type);
+                             _ksba_asn_set_value (p4, p3->value,
                                               strlen (p3->value) + 1);
-                             _asn1_set_right (p4, p2->down);
-                             _asn1_set_down (p2, p4);
+                             set_right (p4, p2->down);
+                             set_down (p2, p4);
                            }
                          p3 = _asn1_find_left (p3);
                        }
                    }
                  p2 = p2->right;
                }
-             p->type &= ~(CONST_TAG);
+             p->flags.has_tag = 0;
              p2 = p->down;
              while (p2)
                {
                  p3 = p2->right;
-                 if (type_field (p2->type) == TYPE_TAG)
-                   asn1_delete_structure (p2);
+                 if (p2->type == TYPE_TAG)
+                   ksba_asn_delete_structure (p2);
                  p2 = p3;
                }
            }
@@ -1857,79 +1542,21 @@ _asn1_type_choice_config (node_asn * node)
            move = UP;
        }
       if (move == UP)
-       p = _asn1_find_up (p);
+       p = find_up (p);
     }
 
   return ASN_OK;
 }
 
 
-int
-_asn1_type_set_config (node_asn * node)
-{
-  node_asn *p, *p2;
-  int move;
-
-  if (node == NULL)
-    return ASN_ELEMENT_NOT_FOUND;
-
-  p = node;
-  move = DOWN;
-
-  while (!((p == node) && (move == UP)))
-    {
-      if (move != UP)
-       {
-         if (type_field (p->type) == TYPE_SET)
-           {
-             p2 = p->down;
-             while (p2)
-               {
-                 if (type_field (p2->type) != TYPE_TAG)
-                   p2->type |= CONST_SET | CONST_NOT_USED;
-                 p2 = p2->right;
-               }
-           }
-         move = DOWN;
-       }
-      else
-       move = RIGHT;
-
-      if (move == DOWN)
-       {
-         if (p->down)
-           p = p->down;
-         else
-           move = RIGHT;
-       }
-
-      if (p == node)
-       {
-         move = UP;
-         continue;
-       }
-
-      if (move == RIGHT)
-       {
-         if (p->right)
-           p = p->right;
-         else
-           move = UP;
-       }
-      if (move == UP)
-       p = _asn1_find_up (p);
-    }
-
-  return ASN_OK;
-}
 
 
 int
-_asn1_expand_object_id (node_asn * node)
+_ksba_asn_expand_object_id (AsnNode node)
 {
-  node_asn *p, *p2, *p3, *p4, *p5;
+  AsnNode p, p2, p3, p4, p5;
   char name_root[129], name2[129], *c;
-  int move;
+  enum { DOWN, UP, RIGHT } move;
 
   if (node == NULL)
     return ASN_ELEMENT_NOT_FOUND;
@@ -1943,42 +1570,42 @@ _asn1_expand_object_id (node_asn * node)
     {
       if (move != UP)
        {
-         if ((type_field (p->type) == TYPE_OBJECT_ID)
-             && (p->type & CONST_ASSIGN))
+         if (p->type == TYPE_OBJECT_ID
+             && p->flags.assignment)
            {
              p2 = p->down;
-             if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
+             if (p2 && p2->type == TYPE_CONSTANT)
                {
                  if (p2->value && !isdigit (p2->value[0]))
                    {
                      strcpy (name2, name_root);
                      strcat (name2, ".");
                      strcat (name2, p2->value);
-                     p3 = _asn1_find_node (node, name2);
-                     if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) ||
-                         !(p3->type & CONST_ASSIGN))
+                     p3 = _ksba_asn_find_node (node, name2);
+                     if (!p3 || p3->type != TYPE_OBJECT_ID ||
+                         !p3->flags.assignment)
                        return ASN_ELEMENT_NOT_FOUND;
-                     _asn1_set_down (p, p2->right);
-                     _asn1_remove_node (p2);
+                     set_down (p, p2->right);
+                     _ksba_asn_remove_node (p2);
                      p2 = p;
                      p4 = p3->down;
                      while (p4)
                        {
-                         if (type_field (p4->type) == TYPE_CONSTANT)
+                         if (p4->type == TYPE_CONSTANT)
                            {
-                             p5 = _asn1_add_node (TYPE_CONSTANT);
-                             _asn1_set_name (p5, p4->name);
-                             _asn1_set_value (p5, p4->value,
-                                              strlen (p4->value) + 1);
+                             p5 = add_node (TYPE_CONSTANT);
+                             _ksba_asn_set_name (p5, p4->name);
+                             _ksba_asn_set_value (p5, p4->value,
+                                                   strlen (p4->value) + 1);
                              if (p2 == p)
                                {
-                                 _asn1_set_right (p5, p->down);
-                                 _asn1_set_down (p, p5);
+                                 set_right (p5, p->down);
+                                 set_down (p, p5);
                                }
                              else
                                {
-                                 _asn1_set_right (p5, p2->right);
-                                 _asn1_set_right (p2, p5);
+                                 set_right (p5, p2->right);
+                                 set_right (p2, p5);
                                }
                              p2 = p5;
                            }
@@ -2016,8 +1643,88 @@ _asn1_expand_object_id (node_asn * node)
            move = UP;
        }
       if (move == UP)
-       p = _asn1_find_up (p);
+       p = find_up (p);
     }
 
   return ASN_OK;
 }
+
+
+void
+_ksba_asn_set_default_tag (AsnNode node)
+{
+  AsnNode p;
+
+  return_if_fail (node && node->type == TYPE_DEFINITIONS);
+
+  for (p = node; p; p = _ksba_asn_walk_tree (node, p))
+    {
+      if ( p->type == TYPE_TAG
+           && !p->flags.explicit && !p->flags.implicit)
+       {
+         if (node->flags.explicit)
+           p->flags.explicit = 1;
+         else
+           p->flags.implicit = 1;
+       }
+    }
+}
+
+void
+_ksba_asn_type_set_config (AsnNode node)
+{
+  AsnNode p, p2;
+  enum { DOWN, UP, RIGHT } move;
+
+  return_if_fail (node);
+  
+  p = node;
+  move = DOWN;
+  while (!((p == node) && (move == UP)))
+    {
+      if (move != UP)
+       {
+         if (p->type == TYPE_SET)
+           {
+             for (p2 = p->down; p2; p2 = p2->right)
+               {
+                 if (p2->type != TYPE_TAG)
+                    {
+                      p2->flags.is_set = 1;
+                      p2->flags.is_not_used = 1;
+                    }
+                }
+            }
+          move = DOWN;
+        }
+      else
+        move = RIGHT;
+          
+      if (move == DOWN)
+        {
+          if (p->down)
+            p = p->down;
+          else
+            move = RIGHT;
+        }
+      
+      if (p == node)
+        {
+          move = UP;
+          continue;
+        }
+          
+      if (move == RIGHT)
+        {
+          if (p->right)
+            p = p->right;
+          else
+            move = UP;
+        }
+      if (move == UP)
+        p = find_up (p);
+    }
+}
+
+  
+  
index 9c3b499..86a39bd 100755 (executable)
 #ifndef ASN1_FUNC_H
 #define ASN1_FUNC_H
 
-#define PARSE_MODE_CHECK  1
-#define PARSE_MODE_CREATE 2
-
-/* List of constants for field type of typedef node_asn  */
-#define TYPE_CONSTANT     1
-#define TYPE_IDENTIFIER   2
-#define TYPE_INTEGER      3
-#define TYPE_BOOLEAN      4
-#define TYPE_SEQUENCE     5
-#define TYPE_BIT_STRING   6
-#define TYPE_OCTET_STRING 7
-#define TYPE_TAG          8
-#define TYPE_DEFAULT      9
-#define TYPE_SIZE        10
-#define TYPE_SEQUENCE_OF 11
-#define TYPE_OBJECT_ID   12
-#define TYPE_ANY         13
-#define TYPE_SET         14
-#define TYPE_SET_OF      15
-#define TYPE_DEFINITIONS 16
-#define TYPE_TIME        17
-#define TYPE_CHOICE      18
-#define TYPE_IMPORTS     19
-#define TYPE_NULL        20
-#define TYPE_ENUMERATED  21
-
-
-/***********************************************************************/
-/* List of constants for specify better the type of typedef node_asn.  */
-/***********************************************************************/
-/*  Used with TYPE_TAG  */
-#define CONST_UNIVERSAL   (1<<8)
-#define CONST_PRIVATE     (1<<9)
-#define CONST_APPLICATION (1<<10)
-#define CONST_EXPLICIT    (1<<11)
-#define CONST_IMPLICIT    (1<<12)
-
-#define CONST_TAG         (1<<13)  /*  Used in ASN.1 assignement  */
-#define CONST_OPTION      (1<<14)
-#define CONST_DEFAULT     (1<<15)
-#define CONST_TRUE        (1<<16)
-#define CONST_FALSE       (1<<17)
-
-#define CONST_LIST        (1<<18)  /*  Used with TYPE_INTEGER and TYPE_BIT_STRING  */
-#define CONST_MIN_MAX     (1<<19)
-
-#define CONST_1_PARAM     (1<<20)
-
-#define CONST_SIZE        (1<<21)
-
-#define CONST_DEFINED_BY  (1<<22)
-
-#define CONST_GENERALIZED (1<<23)
-#define CONST_UTC         (1<<24)
-
-#define CONST_IMPORTS     (1<<25)
-
-#define CONST_NOT_USED    (1<<26)
-#define CONST_SET         (1<<27)
-#define CONST_ASSIGN      (1<<28)
-
-#define CONST_DOWN        (1<<29)
-#define CONST_RIGHT       (1<<30)
-
-
-#define ASN_OK                    0
-#define ASN_FILE_NOT_FOUND        1
-#define ASN_ELEMENT_NOT_FOUND     2
-#define ASN_IDENTIFIER_NOT_FOUND  3
-#define ASN_DER_ERROR             4
-#define ASN_VALUE_NOT_FOUND       5
-#define ASN_GENERIC_ERROR         6
-#define ASN_VALUE_NOT_VALID       7
-#define ASN_TAG_ERROR             8
-#define ASN_TAG_IMPLICIT          9
-#define ASN_ERROR_TYPE_ANY       10
-#define ASN_SYNTAX_ERROR         11
-#define ASN_MEM_ERROR           12
+/* Error Codes */
+enum {
+  ASN_OK                  =  0,
+  ASN_FILE_NOT_FOUND      =  1,
+  ASN_ELEMENT_NOT_FOUND   =  2,
+  ASN_IDENTIFIER_NOT_FOUND=  3,
+  ASN_DER_ERROR           =  4,
+  ASN_VALUE_NOT_FOUND     =  5,
+  ASN_GENERIC_ERROR       =  6,
+  ASN_VALUE_NOT_VALID     =  7,
+  ASN_TAG_ERROR           =  8,
+  ASN_TAG_IMPLICIT        =  9,
+  ASN_ERROR_TYPE_ANY      = 10,
+  ASN_SYNTAX_ERROR        = 11,
+  ASN_MEM_ERROR           = 12
+};
+
+
+typedef enum {
+  TYPE_NONE = 0,
+  TYPE_BOOLEAN = 1,
+  TYPE_INTEGER = 2,
+  TYPE_BIT_STRING = 3,
+  TYPE_OCTET_STRING = 4,
+  TYPE_OBJECT_ID = 6,
+  TYPE_SEQUENCE = 16,
+  TYPE_SET = 17,
+  TYPE_CONSTANT,
+  TYPE_IDENTIFIER,
+  TYPE_TAG,
+  TYPE_DEFAULT,
+  TYPE_SIZE,
+  TYPE_SEQUENCE_OF,
+  TYPE_ANY,
+  TYPE_SET_OF,
+  TYPE_DEFINITIONS,
+  TYPE_TIME,
+  TYPE_CHOICE,
+  TYPE_IMPORTS,
+  TYPE_NULL,
+  TYPE_ENUMERATED
+} node_type_t;
+
+
+enum tag_class {
+  CLASS_UNIVERSAL = 0,
+  CLASS_APPLICATION = 1,
+  CLASS_CONTEXT = 2,
+  CLASS_PRIVATE =3
+};
+
+struct node_flag_s {
+  enum tag_class class;
+  int explicit:1;
+  int implicit:1;
+  int has_imports:1;
+  int assignment:1;
+  int one_param:1;
+  int has_tag:1; 
+  int has_size:1;
+  int has_list:1;
+  int has_min_max:1;
+  int has_defined_by:1;
+  int is_false:1;
+  int is_true:1;
+  int is_default:1;
+  int is_optional:1;
+  int is_utc_time:1;
+  int is_set:1;       /* check whether this is needed */
+  int is_not_used:1;  /* check whether this is needed */
+  int help_down:1;    /* helper for create_tree */
+  int help_right:1;
+};
 
 /******************************************************/
 /* Structure definition used for the node of the tree */
 /* that rappresent an ASN.1 DEFINITION.               */
 /******************************************************/
-struct node_asn_struct {
+typedef struct asn_node_struct *AsnNode; 
+struct asn_node_struct {
   char *name;                    /* Node name */
-  unsigned int type;             /* Node type */
+  node_type_t type;   
+  struct node_flag_s flags;
+
   unsigned char *value;          /* Node value */
-  struct node_asn_struct *down;  /* Pointer to the son node */
-  struct node_asn_struct *right; /* Pointer to the brother node */
-  struct node_asn_struct *left;  /* Pointer to the next list element */ 
+  AsnNode down;                  /* Pointer to the son node */
+  AsnNode right;                 /* Pointer to the brother node */
+  AsnNode left;                  /* Pointer to the next list element */ 
+  AsnNode link_next;             /* to keep track of all nodes in a tree */
 }; 
-typedef struct node_asn_struct node_asn; /* fixme: replace by below */
-typedef struct node_asn_struct *AsnNode; 
 
+/* Structure to keep an entire ASN.1 parse tree and associated information */
+struct ksba_asn_tree_s {
+  AsnNode parse_tree;
+  AsnNode node_list;  /* for easier release of all nodes */
+  char filename[1];
+};
 
 
-typedef struct static_struct_asn{
+typedef struct static_struct_asn {
   char *name;                    /* Node name */
-  unsigned int type;             /* Node type */
+  node_type_t type;             /* Node type */
+  struct node_flag_s flags;
   unsigned char *value;          /* Node value */
 } static_asn;
 
 
-/****************************************/
-/* Returns the first 8 bits.            */
-/* Used with the field type of node_asn */
-/****************************************/
-#define type_field(x)     (x&0xFF) 
 
 
 /***************************************/
 /*  Functions used by ASN.1 parser     */
 /***************************************/
-node_asn *
-_asn1_add_node(unsigned int type);
-
-node_asn *
-_asn1_set_value(node_asn *node,unsigned char *value,unsigned int len);
-
-node_asn *
-_asn1_set_name(node_asn *node,char *name);
-
-node_asn *
-_asn1_set_right(node_asn *node,node_asn *right);
-
-node_asn *
-_asn1_get_right(node_asn *node);
-
-node_asn *
-_asn1_get_last_right(node_asn *node);
-
-node_asn *
-_asn1_set_down(node_asn *node,node_asn *down);
-
-char *
-_asn1_get_name(node_asn *node);
-
-node_asn *
-_asn1_get_down(node_asn *node);
+void _ksba_asn_set_value (AsnNode node, const void *value, unsigned int len);
+void _ksba_asn_set_name (AsnNode node, const char *name);
+AsnNode _ksba_asn_walk_tree (AsnNode root, AsnNode node);
+AsnNode _ksba_asn_find_node(AsnNode pointer,char *name);
+int _ksba_asn_check_identifier(AsnNode node);
+int _ksba_asn_change_integer_value(AsnNode node);
+int _ksba_asn_delete_not_used(AsnNode node);
+int _ksba_asn_expand_object_id(AsnNode node);
+void _ksba_asn_set_default_tag (AsnNode node);
+void _ksba_asn_type_set_config (AsnNode node);
 
-node_asn *
-_asn1_mod_type(node_asn *node,unsigned int value);
 
-void
-_asn1_append_tree(node_asn *node);
+/*-- asn1-func.c --*/
+int ksba_asn_create_structure (AsnNode root, char *source_name,
+                               AsnNode*pointer , char *dest_name);
+int ksba_asn_delete_structure (AsnNode root);
+int ksba_asn1_create_tree (const static_asn *root,AsnNode*pointer);
+int ksba_asn_read_value(AsnNode root,char *name,unsigned char *value,int *len);
+int ksba_asn_write_value(AsnNode root,char *name,unsigned char *value,int len);
 
-node_asn *
-_asn1_find_node(node_asn *pointer,char *name);
 
-node_asn *
-_asn1_find_up(node_asn *node);
 
-int _asn1_create_static_structure(node_asn *pointer,
-                                  char *file_name, char* out_name);
-
-int _asn1_set_default_tag(node_asn *node);
-int _asn1_check_identifier(node_asn *node);
-int _asn1_change_integer_value(node_asn *node);
-int _asn1_delete_not_used(node_asn *node);
-int _asn1_expand_identifier(node_asn **node,node_asn *root);
-int _asn1_type_choice_config(node_asn *node);
-int _asn1_type_set_config(node_asn *node);
-int _asn1_expand_object_id(node_asn *node);
-
-
-int 
-asn1_parser_asn1(char *file_name,node_asn **pointer);
-
-int
-asn1_create_structure(node_asn *root,char *source_name,node_asn **pointer,
-                char *dest_name);
-
-int
-asn1_delete_structure(node_asn *root);
-
-int 
-asn1_write_value(node_asn *root,char *name,unsigned char *value,int len);
-
-int 
-asn1_read_value(node_asn *root,char *name,unsigned char *value,int *len);
-
-int
-asn1_create_tree(const static_asn *root,node_asn **pointer);
 
 #endif /*ASN1_FUNC_H*/
 
+
index 98d53c2..68f099a 100644 (file)
@@ -25,7 +25,9 @@
 #include <errno.h>
 #include <stdarg.h>
 
-#include "asn1-parse.h"
+#include "util.h"
+
+#include "ksba.h"
 #include "asn1-func.h"
 
 #define PGMNAME "asn1-gentables"
@@ -57,13 +59,116 @@ print_error (const char *fmt, ... )
   
 }
 
+static int
+create_static_structure (AsnNode pointer, const char *file_name)
+{
+  FILE *file;
+  AsnNode p;
+  char *structure_name, *file_out_name;
+  const char *char_p, *slash_p, *dot_p;
+
+  char_p = file_name;
+  slash_p = file_name;
+  while ((char_p = strchr (char_p, '/')))
+    {
+      char_p++;
+      slash_p = char_p;
+    }
+
+  char_p = slash_p;
+  dot_p = file_name + strlen (file_name);
+
+  while ((char_p = strchr (char_p, '.')))
+    {
+      dot_p = char_p;
+      char_p++;
+    }
+
+  structure_name = xmalloc ( dot_p - slash_p + 100 );
+  memcpy (structure_name, slash_p, dot_p - slash_p);
+  structure_name[dot_p - slash_p] = 0;
+  strcat (structure_name, "_asn1_tab");
+
+  file_out_name = xmalloc (dot_p - file_name + 100);
+  memcpy (file_out_name, file_name, dot_p - file_name);
+  file_out_name[dot_p - file_name] = 0;
+  strcat (file_out_name, "_asn1_tab.c");
+  file = fopen (file_out_name, "w");
+  if (!file)
+    {
+      print_error ("error creating `%s': %s\n",
+                   file_out_name, strerror (errno));
+      xfree (structure_name);
+      xfree (file_out_name);
+      return ASN_FILE_NOT_FOUND;
+    }
+
+  fprintf (file, "\n#include \"asn1-func.h\"\n\n");
+  fprintf (file, "const static_asn %s[]={\n", structure_name);
+
+  for (p = pointer; p; p = _ksba_asn_walk_tree (pointer, p))
+    {
+      /* set the help flags */
+      p->flags.help_down  = !!p->down;
+      p->flags.help_right = !!p->right;
+
+      /* write a structure line */
+      fputs ("  {", file);
+      if (p->name)
+       fprintf (file, "\"%s\",", p->name);
+      else
+       fprintf (file, "0");
+      fprintf (file, ",%u", p->type);
+
+      fputs (", {", file);
+      fprintf (file, "%u", p->flags.class);
+      fputs (p->flags.explicit       ? ",1":",0", file);
+      fputs (p->flags.implicit       ? ",1":",0", file);
+      fputs (p->flags.has_imports    ? ",1":",0", file);
+      fputs (p->flags.assignment     ? ",1":",0", file);
+      fputs (p->flags.one_param      ? ",1":",0", file);
+      fputs (p->flags.has_tag        ? ",1":",0", file);
+      fputs (p->flags.has_size       ? ",1":",0", file);
+      fputs (p->flags.has_list       ? ",1":",0", file);
+      fputs (p->flags.has_min_max    ? ",1":",0", file);
+      fputs (p->flags.has_defined_by ? ",1":",0", file);
+      fputs (p->flags.is_false       ? ",1":",0", file);
+      fputs (p->flags.is_true        ? ",1":",0", file);
+      fputs (p->flags.is_default     ? ",1":",0", file);
+      fputs (p->flags.is_optional    ? ",1":",0", file);
+      fputs (p->flags.is_utc_time    ? ",1":",0", file);
+      fputs (p->flags.is_set         ? ",1":",0", file);
+      fputs (p->flags.is_not_used    ? ",1":",0", file);
+      fputs (p->flags.help_down      ? ",1":",0", file);
+      fputs (p->flags.help_right     ? ",1":",0", file);
+      fputs ("}", file);
+
+      if (p->value)
+       fprintf (file, ",\"%s\"", p->value);
+      else
+       fprintf (file, ",0");
+      fputs ("},\n", file);
+    }
+
+  fprintf (file, "  {0,0}\n};\n");
+
+  fclose (file);
+
+  xfree (structure_name);
+  xfree (file_out_name);
+  return ASN_OK;
+}
+
+
 
 static void
 one_file (FILE *fp, const char *fname)
 {
+  KsbaAsnTree tree;
   int rc;
   
-  rc = asn1_parser_asn1_file_c (fname);
+  
+  rc = ksba_asn_parse_file (fname, &tree);
   if (rc==ASN_SYNTAX_ERROR)
       print_error ("error parsing `%s': syntax error\n", fname);
   else if (rc==ASN_IDENTIFIER_NOT_FOUND)
@@ -72,7 +177,11 @@ one_file (FILE *fp, const char *fname)
       print_error ("error parsing `%s': file not found\n", fname);
   else if (rc)
       print_error ("error parsing `%s': unknown error %d\n", fname, rc);
-  
+  else 
+    {
+      asn1_visit_tree (tree->parse_tree, NULL);
+      create_static_structure (tree->parse_tree, fname);
+    }
 }
 
 
index 02a89eb..4537d48 100644 (file)
@@ -21,9 +21,6 @@
 #ifndef ASN1_PARSE_H
 #define ASN1_PARSE_H
 
-int asn1_parser_asn1_file_c (char *file_name);
-
-
 
 
 #endif /*ASN1_PARSE_H*/
index 961846e..847e722 100755 (executable)
 #include <stdio.h>
 #include <string.h>
 #include <assert.h>
+#include <ctype.h>
 
+#include "util.h"
+#include "ksba.h"
 #include "asn1-parse.h"
 #include "asn1-func.h"
 
 #define YYERROR_VERBOSE = 1
-
 #define MAX_STRING_LENGTH 129
 
-FILE *file_asn1;  /* Pointer to file to parse */
-extern int parse_mode;
-int result_parse;
-node_asn *p_tree;
-
-int yylex(void);
-void yyerror (const char *s);
+/* constants used in the grammar */
+enum {
+  CONST_EXPLICIT = 1,
+  CONST_IMPLICIT,
+};
+
+struct parser_control_s {
+  FILE *fp;
+  int lineno;
+  int result_parse;
+  AsnNode parse_tree;
+  AsnNode all_nodes;
+};
+#define PARSECTL ((struct parser_control_s *)parm)
+#define YYPARSE_PARAM parm
+#define YYLEX_PARAM parm
 
 %}
+\f
 
+%pure_parser
+%expect 1
 
 %union {
   unsigned int constant;
   char str[MAX_STRING_LENGTH];
-  node_asn* node;
+  AsnNode node;
 }
 
+%{
+static AsnNode new_node (struct parser_control_s *parsectl, node_type_t type);
+#define NEW_NODE(a)  (new_node (PARSECTL, (a)))
+static void set_name (AsnNode node, const char *name);
+static void set_str_value (AsnNode node, const char *text);
+static void set_right (AsnNode node, AsnNode right);
+static void append_right (AsnNode node, AsnNode right);
+static void set_down (AsnNode node, AsnNode down);
+
+
+static int yylex (YYSTYPE *lvalp, void *parm);
+static void yyerror (const char *s);
+%}
 
 %token ASSIG "::=" 
 %token <str> NUM
@@ -110,22 +137,26 @@ void yyerror (const char *s);
 %type <str>  pos_num neg_num pos_neg_num pos_neg_identifier num_identifier 
 %type <constant> class explicit_implicit
 
+\f
 %%
 
 input:  /* empty */  
        | input definitions
 ;
 
-pos_num :   NUM       {strcpy($$,$1);}
-          | '+' NUM   {strcpy($$,$2);}
+pos_num :   NUM       { strcpy($$,$1); }
+          | '+' NUM   { strcpy($$,$2); }
 ;
 
-neg_num : '-' NUM     {strcpy($$,"-");
-                       strcat($$,$2);}
+neg_num : '-' NUM    
+                {
+                  strcpy($$,"-");
+                  strcat($$,$2);
+                }
 ;
 
-pos_neg_num :  pos_num  {strcpy($$,$1);}
-             | neg_num  {strcpy($$,$1);}
+pos_neg_num :  pos_num  { strcpy($$,$1); }
+             | neg_num  { strcpy($$,$1); }
 ;
 
 num_identifier :  NUM            {strcpy($$,$1);}
@@ -136,123 +167,247 @@ pos_neg_identifier :  pos_neg_num    {strcpy($$,$1);}
                     | IDENTIFIER     {strcpy($$,$1);}
 ;
 
-constant: '(' pos_neg_num ')'   {$$=_asn1_add_node(TYPE_CONSTANT); 
-                         _asn1_set_value($$,$2,strlen($2)+1);}
-        | IDENTIFIER'('pos_neg_num')' {$$=_asn1_add_node(TYPE_CONSTANT);
-                                _asn1_set_name($$,$1); 
-                               _asn1_set_value($$,$3,strlen($3)+1);}
-;
-
-constant_list:  constant   {$$=$1;}
-              | constant_list ',' constant {$$=$1;
-                                            _asn1_set_right(_asn1_get_last_right($1),$3);}
-;
-
-identifier_list  :  IDENTIFIER  {$$=_asn1_add_node(TYPE_IDENTIFIER);
-                                 _asn1_set_name($$,$1);}
-                  | identifier_list IDENTIFIER  
-                                {$$=$1;
-                                 _asn1_set_right(_asn1_get_last_right($$),_asn1_add_node(TYPE_IDENTIFIER));
-                                 _asn1_set_name(_asn1_get_last_right($$),$2);}
-;
-
-obj_constant:  num_identifier     {$$=_asn1_add_node(TYPE_CONSTANT); 
-                                   _asn1_set_value($$,$1,strlen($1)+1);}
-             | IDENTIFIER'('NUM')' {$$=_asn1_add_node(TYPE_CONSTANT);
-                                   _asn1_set_name($$,$1); 
-                                    _asn1_set_value($$,$3,strlen($3)+1);}
-;
-
-obj_constant_list:  obj_constant        {$$=$1;}
-                  | obj_constant_list obj_constant {$$=$1;
-                                                    _asn1_set_right(_asn1_get_last_right($1),$2);}
-;
-
-class :  UNIVERSAL    {$$=CONST_UNIVERSAL;}
-       | PRIVATE      {$$=CONST_PRIVATE;}
-       | APPLICATION  {$$=CONST_APPLICATION;}
-;
-
-tag_type :  '[' NUM ']'    {$$=_asn1_add_node(TYPE_TAG); 
-                            _asn1_set_value($$,$2,strlen($2)+1);}
-          | '[' class NUM ']'  {$$=_asn1_add_node(TYPE_TAG | $2); 
-                                _asn1_set_value($$,$3,strlen($3)+1);}
-;
-
-tag :  tag_type           {$$=$1;}
-     | tag_type EXPLICIT  {$$=_asn1_mod_type($1,CONST_EXPLICIT);}
-     | tag_type IMPLICIT  {$$=_asn1_mod_type($1,CONST_IMPLICIT);}
-;
-
-default :  DEFAULT pos_neg_identifier {$$=_asn1_add_node(TYPE_DEFAULT); 
-                                   _asn1_set_value($$,$2,strlen($2)+1);}
-         | DEFAULT TRUE           {$$=_asn1_add_node(TYPE_DEFAULT|CONST_TRUE);}
-         | DEFAULT FALSE          {$$=_asn1_add_node(TYPE_DEFAULT|CONST_FALSE);}
-;
-
-integer_def: INTEGER   {$$=_asn1_add_node(TYPE_INTEGER);}
-           | INTEGER'{'constant_list'}' {$$=_asn1_add_node(TYPE_INTEGER|CONST_LIST);
-                                        _asn1_set_down($$,$3);}
-           | integer_def'('num_identifier'.''.'num_identifier')'
-                                        {$$=_asn1_add_node(TYPE_INTEGER|CONST_MIN_MAX);
-                                         _asn1_set_down($$,_asn1_add_node(TYPE_SIZE)); 
-                                         _asn1_set_value(_asn1_get_down($$),$6,strlen($6)+1); 
-                                         _asn1_set_name(_asn1_get_down($$),$3);}
-;
-
-boolean_def: BOOLEAN   {$$=_asn1_add_node(TYPE_BOOLEAN);}
-;
-
-Time:   UTCTime          {$$=_asn1_add_node(TYPE_TIME|CONST_UTC);} 
-      | GeneralizedTime  {$$=_asn1_add_node(TYPE_TIME|CONST_GENERALIZED);} 
-;
-
-size_def2: SIZE'('num_identifier')'  {$$=_asn1_add_node(TYPE_SIZE|CONST_1_PARAM);
-                                     _asn1_set_value($$,$3,strlen($3)+1);}
-        | SIZE'('num_identifier'.''.'num_identifier')'  
-                                    {$$=_asn1_add_node(TYPE_SIZE|CONST_MIN_MAX);
-                                      _asn1_set_value($$,$3,strlen($3)+1);
-                                     _asn1_set_name($$,$6);}
-;
-
-size_def:   size_def2          {$$=$1;}
-          | '(' size_def2 ')'  {$$=$2;}
-;
-
-octet_string_def : OCTET STRING   {$$=_asn1_add_node(TYPE_OCTET_STRING);}
-                 | OCTET STRING size_def  {$$=_asn1_add_node(TYPE_OCTET_STRING|CONST_SIZE);
-                                           _asn1_set_down($$,$3);}
-;
-
-bit_element :  IDENTIFIER'('NUM')' {$$=_asn1_add_node(TYPE_CONSTANT);
-                                     _asn1_set_name($$,$1); 
-                                    _asn1_set_value($$,$3,strlen($3)+1);}
-;
-
-bit_element_list :  bit_element   {$$=$1;}
-                  | bit_element_list ',' bit_element  {$$=$1;
-                                                       _asn1_set_right(_asn1_get_last_right($1),$3);}
-;
-
-bit_string_def : BIT STRING    {$$=_asn1_add_node(TYPE_BIT_STRING);}
-               | BIT STRING'{'bit_element_list'}' 
-                               {$$=_asn1_add_node(TYPE_BIT_STRING|CONST_LIST);
-                                _asn1_set_down($$,$4);}
-;
-
-enumerated_def : ENUMERATED'{'bit_element_list'}' 
-                               {$$=_asn1_add_node(TYPE_ENUMERATED|CONST_LIST);
-                                _asn1_set_down($$,$3);}
-;
-
-object_def :  OBJECT STR_IDENTIFIER {$$=_asn1_add_node(TYPE_OBJECT_ID);}
-;
-
-type_assig_right: IDENTIFIER         {$$=_asn1_add_node(TYPE_IDENTIFIER);
-                                      _asn1_set_value($$,$1,strlen($1)+1);}
-                | IDENTIFIER size_def {$$=_asn1_add_node(TYPE_IDENTIFIER|CONST_SIZE);
-                                      _asn1_set_value($$,$1,strlen($1)+1);
-                                      _asn1_set_down($$,$2);}
+constant: '(' pos_neg_num ')'  
+                        {
+                          $$ = NEW_NODE (TYPE_CONSTANT); 
+                          set_str_value ($$, $2);
+                        }
+          | IDENTIFIER'('pos_neg_num')'
+                        {
+                          $$ = NEW_NODE (TYPE_CONSTANT); 
+                          set_name ($$, $1); 
+                          set_str_value ($$, $3);
+                        }
+;
+
+constant_list:  constant   { $$=$1; }
+              | constant_list ',' constant
+                  {
+                    $$ = $1;
+                    append_right ($1, $3);
+                  }
+;
+
+identifier_list  :  IDENTIFIER  
+                        {
+                          $$ = NEW_NODE (TYPE_IDENTIFIER);
+                          set_name($$,$1);
+                        }
+                 | identifier_list IDENTIFIER  
+                        {
+                          AsnNode node;
+
+                          $$=$1;
+                          node = NEW_NODE (TYPE_IDENTIFIER);
+                          set_name (node, $2);
+                          append_right ($$, node);
+                        }
+;
+
+obj_constant:  num_identifier   
+                 { 
+                   $$ = NEW_NODE (TYPE_CONSTANT); 
+                   set_str_value ($$, $1);
+                 }
+             | IDENTIFIER '(' NUM ')'
+                 {
+                   $$ = NEW_NODE (TYPE_CONSTANT);
+                   set_name ($$, $1); 
+                   set_str_value ($$, $3);
+                 }
+;
+
+obj_constant_list:  obj_constant   
+                        { $$=$1;}
+                  | obj_constant_list obj_constant 
+                        {
+                          $$=$1;
+                          append_right ($$, $2);
+                        }
+;
+
+class :  UNIVERSAL    { $$ = CLASS_UNIVERSAL;   }
+       | PRIVATE      { $$ = CLASS_PRIVATE;     }
+       | APPLICATION  { $$ = CLASS_APPLICATION; }
+;
+
+tag_type :  '[' NUM ']'   
+                {
+                  $$ = NEW_NODE (TYPE_TAG); 
+                  $$->flags.class = CLASS_CONTEXT;
+                  set_str_value ($$, $2);
+                }
+          | '[' class NUM ']' 
+                {
+                  $$ = NEW_NODE (TYPE_TAG);
+                  $$->flags.class = $2;
+                  set_str_value ($$, $3);
+                }
+;
+
+tag :  tag_type
+         { $$ = $1; }
+     | tag_type EXPLICIT  
+         {
+           $$ = $1;
+           $$->flags.explicit = 1;
+         }
+     | tag_type IMPLICIT 
+         {
+           $$ = $1;
+           $$->flags.implicit = 1;
+         }
+;
+
+default :  DEFAULT pos_neg_identifier 
+               {
+                 $$ = NEW_NODE (TYPE_DEFAULT); 
+                 set_str_value ($$, $2);
+               }
+         | DEFAULT TRUE 
+               {
+                 $$ = NEW_NODE (TYPE_DEFAULT);
+                 $$->flags.is_true = 1;
+               }
+         | DEFAULT FALSE 
+               {
+                 $$ = NEW_NODE (TYPE_DEFAULT);
+                 $$->flags.is_false = 1;
+               }
+;
+
+integer_def: INTEGER   
+               {
+                 $$ = NEW_NODE (TYPE_INTEGER);
+               }
+           | INTEGER '{' constant_list '}' 
+               {
+                 $$ = NEW_NODE (TYPE_INTEGER);
+                 $$->flags.has_list = 1;
+                 set_down ($$, $3);
+               }
+           | integer_def '(' num_identifier '.' '.' num_identifier ')'
+               {
+                 $$ = NEW_NODE (TYPE_INTEGER);
+                 $$->flags.has_min_max = 1;
+                 /* the following is wrong.  Better use a union for the value*/
+                 set_down ($$, NEW_NODE (TYPE_SIZE) ); 
+                 set_str_value ($$->down, $6); 
+                 set_name ($$->down, $3);
+               }
+;
+
+boolean_def: BOOLEAN  
+              {
+                $$ = NEW_NODE (TYPE_BOOLEAN);
+              }
+;
+
+Time:   UTCTime       
+          {
+            $$ = NEW_NODE (TYPE_TIME);
+            $$->flags.is_utc_time = 1;
+          } 
+      | GeneralizedTime  
+          { 
+            $$ = NEW_NODE (TYPE_TIME);
+          } 
+;
+
+size_def2: SIZE '(' num_identifier ')' 
+             {
+               $$ = NEW_NODE (TYPE_SIZE);
+               $$->flags.one_param = 1;
+               set_str_value ($$, $3);
+             }
+        | SIZE '(' num_identifier '.' '.' num_identifier ')'  
+             {
+               $$ = NEW_NODE (TYPE_SIZE);
+               $$->flags.has_min_max = 1;
+               set_str_value ($$, $3);
+               set_name ($$, $6);
+             }
+;
+
+size_def:   size_def2          
+             {
+               $$=$1;
+             }
+          | '(' size_def2 ')'  
+             {
+               $$=$2;
+             }
+;
+
+octet_string_def : OCTET STRING 
+                     {
+                       $$ = NEW_NODE (TYPE_OCTET_STRING);
+                     }
+                 | OCTET STRING size_def
+                     {
+                       $$ = NEW_NODE (TYPE_OCTET_STRING);
+                       $$->flags.has_size = 1;
+                       set_down ($$,$3);
+                     }
+;
+
+bit_element :  IDENTIFIER'('NUM')'
+                 {
+                   $$ = NEW_NODE (TYPE_CONSTANT);
+                   set_name ($$, $1); 
+                   set_str_value ($$, $3);
+                 }
+;
+
+bit_element_list :  bit_element 
+                      {
+                        $$=$1;
+                      }
+                  | bit_element_list ',' bit_element 
+                      {
+                        $$=$1;
+                        append_right ($$, $3);
+                      }
+;
+
+bit_string_def : BIT STRING 
+                   {
+                     $$ = NEW_NODE (TYPE_BIT_STRING);
+                   }
+               | BIT STRING '{' bit_element_list '}' 
+                   {
+                     $$ = NEW_NODE (TYPE_BIT_STRING);
+                     $$->flags.has_list = 1;
+                     set_down ($$, $4);
+                   }
+;
+
+enumerated_def : ENUMERATED '{' bit_element_list '}' 
+                   {
+                     $$ = NEW_NODE (TYPE_ENUMERATED);
+                     $$->flags.has_list = 1;
+                     set_down ($$, $3);
+                   }
+;
+
+object_def :  OBJECT STR_IDENTIFIER 
+                   {
+                     $$ = NEW_NODE (TYPE_OBJECT_ID);
+                   }
+;
+
+type_assig_right: IDENTIFIER  
+                    {
+                      $$ = NEW_NODE (TYPE_IDENTIFIER);
+                      set_str_value ($$, $1);
+                    }
+                | IDENTIFIER size_def
+                    {
+                      $$ = NEW_NODE (TYPE_IDENTIFIER);
+                      $$->flags.has_size = 1;
+                      set_str_value ($$, $1);
+                      set_down ($$, $2);
+                    }
                 | integer_def        {$$=$1;}
                 | enumerated_def     {$$=$1;}
                 | boolean_def        {$$=$1;}
@@ -264,128 +419,230 @@ type_assig_right: IDENTIFIER         {$$=_asn1_add_node(TYPE_IDENTIFIER);
                 | choise_def         {$$=$1;}
                 | any_def            {$$=$1;}
                 | set_def            {$$=$1;}
-                | TOKEN_NULL         {$$=_asn1_add_node(TYPE_NULL);}
-;
-
-type_assig_right_tag :   type_assig_right  {$$=$1;}
-                       | tag type_assig_right {$$=_asn1_mod_type($2,CONST_TAG);
-                                                   _asn1_set_right($1,_asn1_get_down($$));
-                                                   _asn1_set_down($$,$1);}
-;
-
-type_assig_right_tag_default : type_assig_right_tag  {$$=$1;}
-                      | type_assig_right_tag default  {$$=_asn1_mod_type($1,CONST_DEFAULT);
-                                                       _asn1_set_right($2,_asn1_get_down($$));
-                                                      _asn1_set_down($$,$2);}
-                      | type_assig_right_tag OPTIONAL   {$$=_asn1_mod_type($1,CONST_OPTION);}
+                | TOKEN_NULL  
+                    {
+                      $$ = NEW_NODE(TYPE_NULL);
+                    }
+;
+
+type_assig_right_tag :   type_assig_right  
+                           {
+                             $$ = $1;
+                           }
+                       | tag type_assig_right
+                           {
+                             $2->flags.has_tag = 1;
+                             $$ = $2;
+                             set_right ($1, $$->down );
+                             set_down ($$, $1);
+                           }
+;
+
+type_assig_right_tag_default : type_assig_right_tag  
+                                 {
+                                   $$ = $1;
+                                 }
+                             | type_assig_right_tag default  
+                                 {
+                                   $1->flags.is_default = 1;
+                                   set_right ($2, $$->down);
+                                   set_down ($$, $2);
+                                 }
+                             | type_assig_right_tag OPTIONAL  
+                                 {
+                                   $1->flags.is_optional = 1;
+                                   $$ = $1;
+                                 }
 ;
  
-type_assig : IDENTIFIER type_assig_right_tag_default  {$$=_asn1_set_name($2,$1);}
-;
-
-type_assig_list : type_assig                   {$$=$1;}
-                | type_assig_list','type_assig {$$=$1;
-                                                _asn1_set_right(_asn1_get_last_right($1),$3)}
-;
-
-sequence_def : SEQUENCE'{'type_assig_list'}' {$$=_asn1_add_node(TYPE_SEQUENCE);
-                                              _asn1_set_down($$,$3);}
-   | SEQUENCE OF type_assig_right  {$$=_asn1_add_node(TYPE_SEQUENCE_OF);
-                                    _asn1_set_down($$,$3);}
-   | SEQUENCE size_def OF type_assig_right {$$=_asn1_add_node(TYPE_SEQUENCE_OF|CONST_SIZE);
-                                            _asn1_set_right($2,$4);
-                                            _asn1_set_down($$,$2);}
+type_assig : IDENTIFIER type_assig_right_tag_default
+               {
+                 set_name ($2, $1);
+                 $$ = $2;
+               }
+;
+
+type_assig_list : type_assig         
+                    { $$=$1; }
+                | type_assig_list ',' type_assig 
+                    {
+                      $$=$1;
+                      append_right ($$, $3);
+                    }
+;
+
+sequence_def : SEQUENCE '{' type_assig_list '}'
+                 {
+                   $$ = NEW_NODE (TYPE_SEQUENCE);
+                   set_down ($$, $3);
+                 }
+             | SEQUENCE OF type_assig_right 
+                 {
+                   $$ = NEW_NODE (TYPE_SEQUENCE_OF);
+                   set_down ($$, $3);
+                 }
+             | SEQUENCE size_def OF type_assig_right
+                 {
+                   $$ = NEW_NODE (TYPE_SEQUENCE_OF);
+                   $$->flags.has_size = 1;
+                   set_right ($2,$4);
+                   set_down ($$,$2);
+                 }
 ; 
 
-set_def :  SET'{'type_assig_list'}' {$$=_asn1_add_node(TYPE_SET);
-                                     _asn1_set_down($$,$3);}
-   | SET OF type_assig_right  {$$=_asn1_add_node(TYPE_SET_OF);
-                               _asn1_set_down($$,$3);}
-   | SET size_def OF type_assig_right {$$=_asn1_add_node(TYPE_SET_OF|CONST_SIZE);
-                                       _asn1_set_right($2,$4);
-                                       _asn1_set_down($$,$2);}
+set_def :  SET '{' type_assig_list '}'
+             {
+               $$ = NEW_NODE (TYPE_SET);
+               set_down ($$, $3);
+             }
+         | SET OF type_assig_right
+             {
+               $$ = NEW_NODE (TYPE_SET_OF);
+               set_down ($$, $3);
+             }
+         | SET size_def OF type_assig_right
+             {
+               $$ = NEW_NODE (TYPE_SET_OF);
+               $$->flags.has_size = 1;
+               set_right ($2, $4);
+               set_down ($$, $2);
+             }
 ; 
 
-choise_def :   CHOICE'{'type_assig_list'}'  {$$=_asn1_add_node(TYPE_CHOICE);
-                                              _asn1_set_down($$,$3);}
-;
-
-any_def :  ANY                         {$$=_asn1_add_node(TYPE_ANY);}
-         | ANY DEFINED BY IDENTIFIER   {$$=_asn1_add_node(TYPE_ANY|CONST_DEFINED_BY);
-                                        _asn1_set_down($$,_asn1_add_node(TYPE_CONSTANT));
-                                       _asn1_set_name(_asn1_get_down($$),$4);}
-;
-
-type_def : IDENTIFIER "::=" type_assig_right_tag  {$$=_asn1_set_name($3,$1);}
-;
-
-constant_def :  IDENTIFIER OBJECT STR_IDENTIFIER "::=" '{'obj_constant_list'}'
-                        {$$=_asn1_add_node(TYPE_OBJECT_ID|CONST_ASSIGN);
-                         _asn1_set_name($$,$1);  
-                         _asn1_set_down($$,$6);}
-              | IDENTIFIER IDENTIFIER "::=" '{' obj_constant_list '}'
-                        {$$=_asn1_add_node(TYPE_OBJECT_ID|CONST_ASSIGN|CONST_1_PARAM);
-                         _asn1_set_name($$,$1);  
-                         _asn1_set_value($$,$2,strlen($2)+1);
-                         _asn1_set_down($$,$5);}
-              | IDENTIFIER INTEGER "::=" NUM
-                        {$$=_asn1_add_node(TYPE_INTEGER|CONST_ASSIGN);
-                         _asn1_set_name($$,$1);  
-                         _asn1_set_value($$,$4,strlen($4)+1);}
-;
-
-type_constant:   type_def     {$$=$1;}
-               | constant_def {$$=$1;}
-;
-
-type_constant_list :   type_constant    {$$=$1;}
-                     | type_constant_list type_constant  {$$=$1;
-                                                          _asn1_set_right(_asn1_get_last_right($1),$2);}
-;
-
-definitions_id  :  IDENTIFIER  '{' obj_constant_list '}' {$$=_asn1_add_node(TYPE_OBJECT_ID);
-                                                          _asn1_set_down($$,$3);
-                                                          _asn1_set_name($$,$1)}
-;
-
-imports_def :   /* empty */  {$$=NULL;}
-              | IMPORTS identifier_list FROM IDENTIFIER obj_constant_list 
-                        {$$=_asn1_add_node(TYPE_IMPORTS);
-                         _asn1_set_down($$,_asn1_add_node(TYPE_OBJECT_ID));
-                         _asn1_set_name(_asn1_get_down($$),$4);  
-                         _asn1_set_down(_asn1_get_down($$),$5);
-                         _asn1_set_right($$,$2);}
-;
-
-explicit_implicit :  EXPLICIT  {$$=CONST_EXPLICIT;}
-                   | IMPLICIT  {$$=CONST_IMPLICIT;}
-;
-
-definitions:   definitions_id
-               DEFINITIONS explicit_implicit TAGS "::=" BEGIN imports_def 
-               type_constant_list END
-                   {$$=_asn1_add_node(TYPE_DEFINITIONS|$3|(($7==NULL)?0:CONST_IMPORTS));
-                    _asn1_set_name($$,_asn1_get_name($1));
-                    _asn1_set_name($1,"");
-                    if($7==NULL) _asn1_set_right($1,$8);
-                    else {_asn1_set_right($7,$8);_asn1_set_right($1,$7);}
-                    _asn1_set_down($$,$1);
-                   if(parse_mode==PARSE_MODE_CREATE){
-                     _asn1_set_default_tag($$);
-                     _asn1_type_set_config($$);
-                     result_parse=_asn1_check_identifier($$);
-                     if(result_parse==ASN_IDENTIFIER_NOT_FOUND)
-                       asn1_delete_structure($$);
-                     else p_tree=$$;
-                   }}
+choise_def :  CHOICE '{' type_assig_list '}'
+                {
+                  $$ = NEW_NODE (TYPE_CHOICE);
+                  set_down ($$, $3);
+                }
+;
+
+any_def :  ANY   
+             {
+               $$ = NEW_NODE (TYPE_ANY);
+             }
+         | ANY DEFINED BY IDENTIFIER  
+             {
+               AsnNode node;
+
+               $$ = NEW_NODE (TYPE_ANY);
+               $$->flags.has_defined_by = 1;
+               node = NEW_NODE (TYPE_CONSTANT);
+               set_name (node, $4);
+               set_down($$, node);
+             }
+;
+
+type_def : IDENTIFIER "::=" type_assig_right_tag 
+             {
+               set_name ($3, $1);
+               $$ = $3;
+             }
+;
+
+constant_def : IDENTIFIER OBJECT STR_IDENTIFIER "::=" '{' obj_constant_list '}'
+                 {
+                   $$ = NEW_NODE (TYPE_OBJECT_ID);
+                   $$->flags.assignment = 1;
+                   set_name ($$, $1);  
+                   set_down ($$, $6);
+                   asn1_visit_tree ($$,NULL);
+                 }
+             | IDENTIFIER IDENTIFIER "::=" '{' obj_constant_list '}'
+                 {
+                   $$ = NEW_NODE (TYPE_OBJECT_ID);
+                   $$->flags.assignment = 1;
+                   $$->flags.one_param = 1;
+                   set_name ($$, $1);  
+                   set_str_value ($$, $2);
+                   set_down ($$, $5);
+                 }
+             | IDENTIFIER INTEGER "::=" NUM
+                 {
+                   $$ = NEW_NODE (TYPE_INTEGER);
+                   $$->flags.assignment = 1;
+                   set_name ($$, $1);  
+                   set_str_value ($$, $4);
+                 }
+;
+
+type_constant:   type_def     { $$ = $1; }
+               | constant_def { $$ = $1; }
+;
+
+type_constant_list : type_constant  
+                       { $$ = $1; }
+                   | type_constant_list type_constant 
+                       { 
+                         $$ = $1;
+                         append_right ($$, $2);
+                       }
+;
+
+definitions_id : IDENTIFIER  '{' obj_constant_list '}' 
+                   {
+                     $$ = NEW_NODE (TYPE_OBJECT_ID);
+                     set_down ($$, $3);
+                     set_name ($$, $1);
+                   }
+;
+
+imports_def :  /* empty */ 
+                { $$=NULL;}
+            | IMPORTS identifier_list FROM IDENTIFIER obj_constant_list 
+                {
+                  AsnNode node;
+
+                  $$ = NEW_NODE (TYPE_IMPORTS);
+                  node = NEW_NODE (TYPE_OBJECT_ID);
+                  set_name (node, $4);  
+                  set_down (node, $5);
+                  set_down ($$, node);
+                  set_right ($$, $2);
+                }
+;
+
+explicit_implicit :  EXPLICIT  { $$ = CONST_EXPLICIT; }
+                   | IMPLICIT  { $$ = CONST_IMPLICIT; }
+;
+
+definitions: definitions_id
+             DEFINITIONS explicit_implicit TAGS "::=" BEGIN imports_def 
+             type_constant_list END
+               {
+                 AsnNode node;
+                 
+                 $$ = node = NEW_NODE (TYPE_DEFINITIONS);
+
+                 if ($3 == CONST_EXPLICIT)
+                   node->flags.explicit = 1;
+                 else if ($3 == CONST_IMPLICIT)
+                   node->flags.implicit = 1;
+
+                 if ($7)
+                   node->flags.has_imports = 1;
+
+                 set_name ($$, $1->name);
+                 set_name ($1, "");
+
+                 if (!node->flags.has_imports) 
+                   set_right ($1,$8);
+                 else
+                   {
+                     set_right ($7,$8);
+                     set_right ($1,$7);
+                   }
+
+                 set_down ($$, $1);
+
+                 _ksba_asn_set_default_tag ($$);
+                 _ksba_asn_type_set_config ($$);
+                 PARSECTL->result_parse = _ksba_asn_check_identifier($$);
+                 PARSECTL->parse_tree=$$;
+               }
 ;
 
 %%
 
-
-#include <ctype.h>
-#include <string.h>
-
 const char *key_word[]={"::=","OPTIONAL","INTEGER","SIZE","OCTET","STRING"
                        ,"SEQUENCE","BIT","UNIVERSAL","PRIVATE","OPTIONAL"
                        ,"DEFAULT","CHOICE","OF","OBJECT","IDENTIFIER"
@@ -401,27 +658,30 @@ const int key_word_token[]={ASSIG,OPTIONAL,INTEGER,SIZE,OCTET,STRING
                        ,BEGIN,END,UTCTime,GeneralizedTime,FROM
                        ,IMPORTS,TOKEN_NULL,ENUMERATED};
 
-static int lineno = 1;  /* keep track of input linenumbers */
-
+\f
 /*************************************************************/
 /*  Function: yylex                                          */
 /*  Description: looks for tokens in file_asn1 pointer file. */
 /*  Return: int                                              */
 /*    Token identifier or ASCII code or 0(zero: End Of File) */
 /*************************************************************/
-int 
-yylex() 
+static int 
+yylex (YYSTYPE *lvalp, void *parm)
 {
   int c,counter=0,k;
-  char string[MAX_STRING_LENGTH];  
+  char string[MAX_STRING_LENGTH];
+  FILE *fp = PARSECTL->fp;
+
+  if (!PARSECTL->lineno)
+    PARSECTL->lineno++; /* start with line one */
 
   while (1)
     {
-      while ( (c=fgetc(file_asn1))==' ' || c=='\t')
+      while ( (c=fgetc (fp))==' ' || c=='\t')
         ;
       if (c =='\n')
         {
-          lineno++;
+          PARSECTL->lineno++;
           continue;
         }
       if(c==EOF)
@@ -433,16 +693,16 @@ yylex()
 
       if (c=='-')
         {
-          if ( (c=fgetc(file_asn1))!='-')
+          if ( (c=fgetc(fp))!='-')
             {
-              ungetc(c,file_asn1);
+              ungetc(c,fp);
               return '-';
             }
           else
             {
               /* A comment finishes at the end of line */
               counter=0;
-              while ( (c=fgetc(file_asn1))!=EOF && c != '\n' )
+              while ( (c=fgetc(fp))!=EOF && c != '\n' )
                 ;
               if (c==EOF)
                 return 0;
@@ -450,26 +710,23 @@ yylex()
                 continue; /* repeat the search */
             }
         }
-      if (counter==sizeof (string))
-        {
-          fprintf (stderr,"%s:%d: token too long\n", "myfile:", lineno);
-          return 0; /* EOF */
-        }
       
-      string[counter++]=c;
-      while ( !((c=fgetc(file_asn1))==EOF
-                || c==' '|| c=='\t' || c=='\n' 
-                || c=='(' || c==')' || c=='[' || c==']' 
-                || c=='{' || c=='}' || c==',' || c=='.'))
+      do
         { 
-          if (counter==sizeof (string))
+          if (counter >= DIM (string)-1 )
             {
-              fprintf (stderr,"%s:%d: token too long\n", "myfile:", lineno);
+              fprintf (stderr,"%s:%d: token too long\n", "myfile:",
+                       PARSECTL->lineno);
               return 0; /* EOF */
             }
           string[counter++]=c;
         }
-      ungetc(c,file_asn1);
+      while ( !((c=fgetc(fp))==EOF
+                || c==' '|| c=='\t' || c=='\n' 
+                || c=='(' || c==')' || c=='[' || c==']' 
+                || c=='{' || c=='}' || c==',' || c=='.'));
+      
+      ungetc (c,fp);
       string[counter]=0;
       /*fprintf (stderr, "yylex token `%s'\n", string);*/
 
@@ -481,7 +738,7 @@ yylex()
         }
       if (k>=counter)
         {
-          strcpy (yylval.str,string);  
+          strcpy (lvalp->str,string);  
           return NUM;
         }
       
@@ -493,117 +750,150 @@ yylex()
         }
       
       /* STRING is an IDENTIFIER */
-      strcpy(yylval.str,string);
+      strcpy(lvalp->str,string);
       return IDENTIFIER;
     }
 }
 
-
-/*************************************************************/
-/*  Function: parser_asn1                                    */
-/*  Description: function used to start the parse algorithm. */
-/*  Parameters:                                              */
-/*    char *file_name : file name to parse                   */
-/*  Return: int                                              */
-/*                                                           */
-/*************************************************************/
-int 
-asn1_parser_asn1(char *file_name,node_asn **pointer)
+static void 
+yyerror (const char *s)
 {
-  /*  yydebug=1;  */
-
-  p_tree=NULL;
-  *pointer=NULL;
-  
-  file_asn1=fopen(file_name,"r");
-
-  if(file_asn1==NULL) return ASN_FILE_NOT_FOUND;
-
-  result_parse=ASN_OK;
-
-  parse_mode=PARSE_MODE_CHECK;
-  yyparse();
-
-  if(result_parse==ASN_OK){
-    fclose(file_asn1);
-    file_asn1=fopen(file_name,"r");
+  /* Sends the error description to stderr */
+  fprintf (stderr, "%s\n", s); 
+  /* Why doesn't bison provide a way to pass the parm to yyerror ??*/
+}
 
-    parse_mode=PARSE_MODE_CREATE;
-    yyparse();
-    _asn1_change_integer_value(p_tree);
-    _asn1_expand_object_id(p_tree);
-  }
 
-  fclose(file_asn1);
 
-  parse_mode=PARSE_MODE_CREATE;
+\f
+static AsnNode
+new_node (struct parser_control_s *parsectl, node_type_t type)
+{
+  AsnNode node;
 
-  *pointer=p_tree;
+  node = xcalloc (1, sizeof *node);
+  node->type = type;
+  node->link_next = parsectl->all_nodes;
+  parsectl->all_nodes = node->link_next;
 
-  return result_parse;
+  return node;
 }
 
+static void
+release_all_nodes (AsnNode node)
+{
+  AsnNode node2;
 
+  for (; node; node = node2)
+    {
+      node2 = node->link_next;
+      xfree (node->name);
+      xfree (node->value);
+      xfree (node);
+    }
+}
 
-/*************************************************************/
-/*  Function: parser_asn1_file_c                             */
-/*  Description: function that generates a C structure from  */
-/*               an ASN1 file                                */
-/*  Parameters:                                              */
-/*    char *file_name : file name to parse                   */
-/*  Return: int                                              */
-/*                                                           */
-/*************************************************************/
-int 
-asn1_parser_asn1_file_c(char *file_name)
+static void
+set_name (AsnNode node, const char *name)
 {
-  int result;
-
-  /*  yydebug=1;  */
+  _ksba_asn_set_name (node, name);
+}
 
-  p_tree=NULL;
-    
-  file_asn1=fopen(file_name,"r");
+static void
+set_str_value (AsnNode node, const char *text)
+{
+  _ksba_asn_set_value (node, text, (text && *text)? (strlen (text)+1): 0);
+}
 
-  if(file_asn1==NULL) return ASN_FILE_NOT_FOUND;
+static void
+set_right (AsnNode node, AsnNode right)
+{
+  return_if_fail (node);
 
-  result_parse=ASN_OK;
+  node->right = right;
+  if (right)
+    right->left = node;
+}
 
-  parse_mode=PARSE_MODE_CHECK;
-  yyparse();
+static void
+append_right (AsnNode node, AsnNode right)
+{
+  return_if_fail (node);
 
-  if(result_parse==ASN_OK){
-    fclose(file_asn1);
-    file_asn1=fopen(file_name,"r");
+  while (node->right)
+    node = node->right;
 
-    parse_mode=PARSE_MODE_CREATE;
-    yyparse();
+  node->right = right;
+  if (right)
+    right->left = node;
+}
 
-    result=_asn1_create_static_structure(p_tree,file_name, NULL);
 
-    asn1_delete_structure(p_tree);
-   }
+static void
+set_down (AsnNode node, AsnNode down)
+{
+  return_if_fail (node);
 
-  fclose(file_asn1);
+  node->down = down;
+  if (down)
+    down->left = node;
+}
 
-  parse_mode=PARSE_MODE_CREATE;
+\f
+/**
+ * ksba_asn_parse_file:
+ * @file_name: Filename with the ASN module
+ * @pointer: Returns the syntax tree
+ * 
+ * Parse an ASN.1 file and return an syntax tree.
+ * 
+ * Return value: 0 for okay or an ASN_xx error code
+ **/
+int 
+ksba_asn_parse_file (const char *file_name, KsbaAsnTree *result)
+{
+  struct parser_control_s parsectl;
+     
+  *result = NULL;
+  
+  parsectl.fp = file_name? fopen (file_name, "r") : NULL;
+  if ( !parsectl.fp )
+    return ASN_FILE_NOT_FOUND;
+
+  parsectl.lineno = 0;
+  parsectl.result_parse = ASN_SYNTAX_ERROR;
+  parsectl.parse_tree = NULL;
+  parsectl.all_nodes = NULL;
+  if ( yyparse ((void*)&parsectl) || parsectl.result_parse != ASN_OK )
+    { /* error */
+      release_all_nodes (parsectl.all_nodes);
+      parsectl.all_nodes = NULL;
+    }
+  else 
+    { /* okay */
+      KsbaAsnTree tree;
+
+      _ksba_asn_change_integer_value (parsectl.parse_tree);
+      _ksba_asn_expand_object_id (parsectl.parse_tree);
+      tree = xmalloc ( sizeof *tree + file_name? 1 : strlen (file_name) );
+      tree->parse_tree = parsectl.parse_tree;
+      tree->node_list = parsectl.all_nodes;
+      strcpy (tree->filename, file_name? file_name:"-");
+      *result = tree;
+    }
 
-  return result_parse;
+  if (file_name)
+    fclose (parsectl.fp);
+  return parsectl.result_parse;
 }
 
-
-/*************************************************************/
-/*  Function: yyerror                                        */
-/*  Description: function used with syntax errors            */
-/*  Parameters:                                              */
-/*    char *s : error description                            */
-/*  Return: int                                              */
-/*                                                           */
-/*************************************************************/
-void 
-yyerror (const char *s)
+void
+ksba_asn_tree_release (KsbaAsnTree tree)
 {
-  /* Sends the error description to stdout */
-  fprintf (stderr, "%s:%d: %s\n","myfile", lineno, s); 
-  result_parse = ASN_SYNTAX_ERROR;
+  if (!tree)
+    return;
+  release_all_nodes (tree->node_list);
+  tree->node_list = NULL;
+  xfree (tree);
 }
+
index b1c4a62..fbcf2a5 100644 (file)
@@ -102,6 +102,10 @@ universal_tag_name (unsigned long no)
 
 
 
+
+
+
+
 \f
 BerDecoder
 _ksba_ber_decoder_new (void)
@@ -124,7 +128,7 @@ _ksba_ber_decoder_release (BerDecoder d)
 /**
  * _ksba_ber_decoder_set_module:
  * @d: Decoder object 
- * @module: Modul structure
+ * @module: ASN.1 Parse tree
  * 
  * Initialize the decoder with the ASN.1 module.  Note, that this is a
  * shallow copy of the module.  FIXME: What about ref-counting of
@@ -133,14 +137,14 @@ _ksba_ber_decoder_release (BerDecoder d)
  * Return value: 0 on success or an error code
  **/
 KsbaError
-_ksba_ber_decoder_set_module (BerDecoder d, AsnNode module)
+_ksba_ber_decoder_set_module (BerDecoder d, KsbaAsnTree module)
 {
   if (!d || !module)
     return KSBA_Invalid_Value;
   if (d->module)
     return KSBA_Conflict; /* module already set */
 
-  d->module = module;
+  d->module = module->parse_tree;
   return 0;
 }
 
@@ -161,12 +165,6 @@ _ksba_ber_decoder_set_reader (BerDecoder d, KsbaReader r)
 /**********************************************
  ***********  decoding machinery  *************
  **********************************************/
-enum tag_class {
-  CLASS_UNIVERSAL = 0,
-  CLASS_APPLICATION = 1,
-  CLASS_CONTEXT = 2,
-  CLASS_PRIVATE =3
-};
 
 struct tag_info {
   enum tag_class class;
@@ -262,6 +260,70 @@ read_tl (BerDecoder d, struct tag_info *r_tag,
 }
 
 
+static int
+cmp_tag (AsnNode node, const struct tag_info *ti)
+{
+
+  fprintf (stdout, "cmp_tag `%s' tag=%d",
+           node->name, node->type);
+  if (node->flags.class == CLASS_UNIVERSAL)
+    putchar ('U');
+  if (node->flags.class == CLASS_APPLICATION)
+    putchar ('A');
+  if (node->flags.class == CLASS_PRIVATE)
+    putchar ('P');
+
+  if (ti->tag != node->type)
+    return 0;
+  if (ti->class == node->flags.class)
+    return 1;
+  return 0; 
+}
+
+
+/* Find the matching node for the tag described by ti.  ROOT is the
+   root node of the syntaxtree, node either NULL or the last node
+   matched.  */
+static AsnNode
+find_node (AsnNode root, AsnNode node, const struct tag_info *ti)
+{
+  if (!node)
+    node = root;
+
+  while (node)
+    {
+      if (cmp_tag (node, ti))
+        {
+          puts (" got it");
+          return node; /* found */
+        }
+      putchar ('\n');
+
+      if (node->down)
+        node = node->down;
+      else if (node == root)
+        return NULL; /* not found */
+      else if (node->right)
+        node = node->right;
+      else 
+        { /* go up and right */
+          do
+            {
+              while (node->left && node->left->right == node)
+                node = node->left;
+              node = node->left;
+              
+              if (!node || node == root)
+                return NULL; /* back at the root -> not found */
+            }
+          while (!node->right);
+          node = node->right;
+        }
+    }
+
+  return NULL;
+}
+
 
 KsbaError
 _ksba_ber_decoder_decode (BerDecoder d)
@@ -293,7 +355,10 @@ _ksba_ber_decoder_dump (BerDecoder d, FILE *fp)
     unsigned long length;
     int ndef;
   } stack[100];
+  AsnNode rootnode, curnode, node;
 
+  rootnode = d->module;
+  curnode = NULL;
   while ( !(rc = read_tl (d, &ti, &length, &is_indefinite, &nread)) )
     {
       const char *tagname = NULL;
@@ -321,6 +386,13 @@ _ksba_ber_decoder_dump (BerDecoder d, FILE *fp)
       else
         fprintf (fp, " %lu octets\n", length);
 
+      node = find_node (rootnode, curnode, &ti);
+      if (node)
+        {
+          fprintf (fp, "%*s(found node `%s')\n", depth*2, "", node->name);
+          curnode = node;
+        }
+
       if (!ti.is_constructed)
         { /* primitive: skip value */
           int n;
@@ -368,9 +440,6 @@ _ksba_ber_decoder_dump (BerDecoder d, FILE *fp)
           stack[depth].ndef = is_indefinite;
           depth++;
         }
-
-
-
     }
 
   if (rc==-1 && !d->last_errdesc)
index a8cbc33..6d680cf 100644 (file)
@@ -29,7 +29,7 @@ typedef struct ber_decoder_s *BerDecoder;
 BerDecoder _ksba_ber_decoder_new (void);
 void       _ksba_ber_decoder_release (BerDecoder d);
 
-KsbaError _ksba_ber_decoder_set_module (BerDecoder d, AsnNode module);
+KsbaError _ksba_ber_decoder_set_module (BerDecoder d, KsbaAsnTree module);
 KsbaError _ksba_ber_decoder_set_reader (BerDecoder d, KsbaReader r);
 
 KsbaError _ksba_ber_decoder_dump (BerDecoder d, FILE *fp);
index 7b14a35..aab3977 100644 (file)
@@ -70,7 +70,7 @@ fatal (const char *fmt, ... )
 
 
 static void
-one_file (FILE *fp, const char *fname)
+one_file (FILE *fp, const char *fname, KsbaAsnTree asn_tree)
 {
   KsbaError err;
   KsbaReader r;
@@ -90,6 +90,13 @@ one_file (FILE *fp, const char *fname)
   if (err)
     fatal ("ksba_ber_decoder_set_reader failed: rc=%d\n", err);
   
+  if (asn_tree)
+    {
+      err = _ksba_ber_decoder_set_module (d, asn_tree);
+      if (err)
+        fatal ("ksba_ber_decoder_set_module failed: rc=%d\n", err);
+    }
+
   err = _ksba_ber_decoder_dump (d, stdout);
   if (err)
     print_error ("ksba_ber_decoder_dump failed: rc=%d\n", err);
@@ -99,20 +106,47 @@ one_file (FILE *fp, const char *fname)
 }
 
 
+static void
+usage (int exitcode)
+{
+  fputs ("usage: ber-dump [--module asnfile] [files]\n", stderr);
+  exit (exitcode);
+}
+
 int
 main (int argc, char **argv)
 {
+  const char *asnfile = NULL;
+  KsbaAsnTree asn_tree = NULL;
+  int rc;
+
   if (!argc || (argc > 1 &&
                 (!strcmp (argv[1],"--help") || !strcmp (argv[1],"-h"))) )
-    {
-      fputs ("usage: ber-dump [files]\n", stderr);
-      return 0;
-    }
+    usage (0);
   
   argc--; argv++;
+  if (argc && !strcmp (*argv,"--module"))
+    {
+      argc--; argv++;
+      if (!argc)
+        usage (1);
+      asnfile = *argv;
+      argc--; argv++;
+    }
+
+  if (asnfile)
+    {
+      rc = ksba_asn_parse_file (asnfile, &asn_tree);
+      if (rc)
+        {
+          print_error ("parsing `%s' failed: rc=%d\n", asnfile, rc);
+          exit (1);
+        }
+    }
+
   
   if (!argc)
-    one_file (stdin, "-");
+    one_file (stdin, "-", asn_tree);
   else
     {
       for (; argc; argc--, argv++) 
@@ -124,10 +158,14 @@ main (int argc, char **argv)
               print_error ("can't open `%s': %s\n", *argv, strerror (errno));
           else
             {
-              one_file (fp, *argv);
+              one_file (fp, *argv, asn_tree);
               fclose (fp);
             }
         }
     }
+  
+  ksba_asn_tree_release (asn_tree);
+
   return error_counter? 1:0;
 }
+
index 4de8446..4cd6c04 100644 (file)
@@ -56,13 +56,16 @@ typedef enum {
 struct ksba_cert_s;
 typedef struct ksba_cert_s *KsbaCert;
 
-
 /* This is a reader object vor various purposes
    see ksba_reader_new et al. */
 struct ksba_reader_s;
 typedef struct ksba_reader_s *KsbaReader;
 
-
+/* This is an object to store an ASN.1 parse tree as
+   create by ksba_asn_parse_file() */
+struct ksba_asn_tree_s;
+typedef struct ksba_asn_tree_s *KsbaAsnTree;
+   
 
 /*-- cert.c --*/
 KsbaCert ksba_cert_new (void);
@@ -86,7 +89,9 @@ KsbaError ksba_reader_read (KsbaReader r,
                             char *buffer, size_t length, size_t *nread);
 
 
-
+/*-- asn1-parse.y --*/
+int ksba_asn_parse_file (const char *filename, KsbaAsnTree *result);
+void ksba_asn_tree_release (KsbaAsnTree tree);
 
 
 #ifdef __cplusplus
index 4f21453..ea2768a 100644 (file)
@@ -45,16 +45,16 @@ _ksba_calloc (size_t n, size_t m )
 }
 
 void *
-_ksba_realloc (void *p, size_t n)
+_ksba_realloc (void *mem, size_t n)
 {
-  return realloc (p, n );
+  return realloc (mem, n );
 }
 
 
 char *
-_ksba_strdup (const char *p)
+_ksba_strdup (const char *str)
 {
-  return strdup (p);
+  return strdup (str);
 }
 
 
@@ -93,9 +93,9 @@ _ksba_xcalloc (size_t n, size_t m )
 }
 
 void *
-_ksba_xrealloc (void *p, size_t n)
+_ksba_xrealloc (void *mem, size_t n)
 {
-  void *p = _ksba_realloc (p,n);
+  void *p = _ksba_realloc (mem,n);
   if (!p)
     out_of_core();
   return p;
@@ -103,9 +103,9 @@ _ksba_xrealloc (void *p, size_t n)
 
 
 char *
-_ksba_xstrdup (const char *p)
+_ksba_xstrdup (const char *str)
 {
-  char *p = _ksba_strdup (p);
+  char *p = _ksba_strdup (str);
   if (!p)
     out_of_core();
   return p;
index 8da893e..f6fa483 100644 (file)
@@ -68,6 +68,10 @@ char *_ksba_xstrdup (const char *p);
                  __FILE__, __LINE__, #expr );            \
         return (val);                                   \
     } } while (0)
+#define never_reached() do {                                   \
+        fprintf (stderr, "%s:%d: oops; should never get here", \
+                 __FILE__, __LINE__ );                         \
+    } while (0)
 
 
 #endif /* UTIL_H */