]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Update to 0.3.4.
authorSimon Josefsson <simon@josefsson.org>
Wed, 10 May 2006 17:12:36 +0000 (17:12 +0000)
committerSimon Josefsson <simon@josefsson.org>
Wed, 10 May 2006 17:12:36 +0000 (17:12 +0000)
lib/minitasn1/coding.c
lib/minitasn1/decoding.c
lib/minitasn1/element.c
lib/minitasn1/errors.c
lib/minitasn1/gstr.c
lib/minitasn1/libtasn1.h
lib/minitasn1/parser_aux.c
lib/minitasn1/parser_aux.h
lib/minitasn1/structure.c

index aa19d20ef24be0cba1a0d5726ffda57ca8d2bc44..0ca407e837b2cf577fe142580b48057ef942284c 100644 (file)
 /* Return:                                            */
 /******************************************************/
 void
-_asn1_error_description_value_not_found(node_asn *node,char *ErrorDescription)
+_asn1_error_description_value_not_found (node_asn * node,
+                                        char *ErrorDescription)
 {
 
-  if (ErrorDescription == NULL) return;
+  if (ErrorDescription == NULL)
+    return;
 
-  Estrcpy(ErrorDescription,":: value of element '");
-  _asn1_hierarchical_name(node,ErrorDescription+strlen(ErrorDescription),
-                         MAX_ERROR_DESCRIPTION_SIZE-40);
-  Estrcat(ErrorDescription,"' not found");
+  Estrcpy (ErrorDescription, ":: value of element '");
+  _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
+                          MAX_ERROR_DESCRIPTION_SIZE - 40);
+  Estrcat (ErrorDescription, "' not found");
 
 }
 
@@ -68,29 +70,35 @@ _asn1_error_description_value_not_found(node_asn *node,char *ErrorDescription)
  * The @ans buffer is pre-allocated and must have room for the output.
  **/
 void
-asn1_length_der(unsigned long int len, unsigned char *ans, int *ans_len)
+asn1_length_der (unsigned long int len, unsigned char *ans, int *ans_len)
 {
   int k;
   unsigned char temp[SIZEOF_UNSIGNED_LONG_INT];
 
-  if(len<128){
-    /* short form */
-    if(ans!=NULL) ans[0]=(unsigned char)len;
-    *ans_len=1;
-  }
-  else{
-    /* Long form */
-    k=0;
-    while(len){
-      temp[k++]=len&0xFF;
-      len=len>>8;
+  if (len < 128)
+    {
+      /* short form */
+      if (ans != NULL)
+       ans[0] = (unsigned char) len;
+      *ans_len = 1;
     }
-    *ans_len=k+1;
-    if(ans!=NULL){
-      ans[0]=((unsigned char)k&0x7F)+128;
-      while(k--) ans[*ans_len-1-k]=temp[k];
+  else
+    {
+      /* Long form */
+      k = 0;
+      while (len)
+       {
+         temp[k++] = len & 0xFF;
+         len = len >> 8;
+       }
+      *ans_len = k + 1;
+      if (ans != NULL)
+       {
+         ans[0] = ((unsigned char) k & 0x7F) + 128;
+         while (k--)
+           ans[*ans_len - 1 - k] = temp[k];
+       }
     }
-  }
 }
 
 /******************************************************/
@@ -106,28 +114,33 @@ asn1_length_der(unsigned long int len, unsigned char *ans, int *ans_len)
 /* Return:                                            */
 /******************************************************/
 void
-_asn1_tag_der(unsigned char class,unsigned int tag_value,unsigned char *ans,int *ans_len)
+_asn1_tag_der (unsigned char class, unsigned int tag_value,
+              unsigned char *ans, int *ans_len)
 {
   int k;
   unsigned char temp[SIZEOF_UNSIGNED_INT];
 
-  if(tag_value<31){
-    /* short form */
-    ans[0]=(class&0xE0) + ((unsigned char)(tag_value&0x1F));
-    *ans_len=1;
-  }
-  else{
-    /* Long form */
-    ans[0]=(class&0xE0) + 31;
-    k=0;
-    while(tag_value){
-      temp[k++]=tag_value&0x7F;
-      tag_value=tag_value>>7;
+  if (tag_value < 31)
+    {
+      /* short form */
+      ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F));
+      *ans_len = 1;
+    }
+  else
+    {
+      /* Long form */
+      ans[0] = (class & 0xE0) + 31;
+      k = 0;
+      while (tag_value)
+       {
+         temp[k++] = tag_value & 0x7F;
+         tag_value = tag_value >> 7;
+       }
+      *ans_len = k + 1;
+      while (k--)
+       ans[*ans_len - 1 - k] = temp[k] + 128;
+      ans[*ans_len - 1] -= 128;
     }
-    *ans_len=k+1;
-    while(k--) ans[*ans_len-1-k]=temp[k]+128;
-    ans[*ans_len-1]-=128;  
-  }
 }
 
 /**
@@ -140,15 +153,16 @@ _asn1_tag_der(unsigned char class,unsigned int tag_value,unsigned char *ans,int
  * Creates the DER coding for an OCTET type (length included).
  **/
 void
-asn1_octet_der(const unsigned char *str,int str_len,
-              unsigned char *der,int *der_len)
+asn1_octet_der (const unsigned char *str, int str_len,
+               unsigned char *der, int *der_len)
 {
   int len_len;
 
-  if(der==NULL || str_len <= 0) return;
-  asn1_length_der(str_len,der,&len_len);
-  memcpy(der+len_len,str,str_len);
-  *der_len=str_len+len_len;
+  if (der == NULL || str_len <= 0)
+    return;
+  asn1_length_der (str_len, der, &len_len);
+  memcpy (der + len_len, str, str_len);
+  *der_len = str_len + len_len;
 }
 
 /******************************************************/
@@ -166,20 +180,21 @@ asn1_octet_der(const unsigned char *str,int str_len,
 /*   ASN1_SUCCESS otherwise                           */
 /******************************************************/
 asn1_retCode
-_asn1_time_der(unsigned char *str,unsigned char *der,int *der_len)
+_asn1_time_der (unsigned char *str, unsigned char *der, int *der_len)
 {
   int len_len;
   int max_len;
 
-  max_len=*der_len;
+  max_len = *der_len;
 
-  asn1_length_der(strlen(str),(max_len>0)?der:NULL,&len_len);
+  asn1_length_der (strlen (str), (max_len > 0) ? der : NULL, &len_len);
 
-  if((len_len+(int)strlen(str))<=max_len)
-    memcpy(der+len_len,str,strlen(str));
-  *der_len=len_len+strlen(str);
+  if ((len_len + (int) strlen (str)) <= max_len)
+    memcpy (der + len_len, str, strlen (str));
+  *der_len = len_len + strlen (str);
 
-  if((*der_len)>max_len) return ASN1_MEM_ERROR;
+  if ((*der_len) > max_len)
+    return ASN1_MEM_ERROR;
 
   return ASN1_SUCCESS;
 }
@@ -236,67 +251,77 @@ _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
 /*   ASN1_SUCCESS otherwise                           */
 /******************************************************/
 asn1_retCode
-_asn1_objectid_der(unsigned char *str,unsigned char *der,int *der_len)
+_asn1_objectid_der (unsigned char *str, unsigned char *der, int *der_len)
 {
-  int len_len,counter,k,first,max_len;
-  char *temp,*n_end,*n_start;
+  int len_len, counter, k, first, max_len;
+  char *temp, *n_end, *n_start;
   unsigned char bit7;
-  unsigned long val,val1=0;
-
-  max_len=*der_len;
-
-  temp= (char *) _asn1_alloca(strlen(str)+2);
-  if(temp==NULL) return ASN1_MEM_ALLOC_ERROR;
-
-  strcpy(temp, str);
-  strcat(temp, ".");
-
-  counter=0;
-  n_start=temp;
-  while((n_end=strchr(n_start,'.'))){
-    *n_end=0;
-    val=strtoul(n_start,NULL,10);
-    counter++;
-
-    if(counter==1) val1=val;
-    else if(counter==2){
-      if(max_len>0)
-       der[0]=40*val1+val;
-      *der_len=1;
-    }
-    else{
-      first=0;
-      for(k=4;k>=0;k--){
-       bit7=(val>>(k*7))&0x7F;
-       if(bit7 || first || !k){
-         if(k) bit7|=0x80;
-         if(max_len>(*der_len))
-           der[*der_len]=bit7;
-         (*der_len)++;
-         first=1;
+  unsigned long val, val1 = 0;
+
+  max_len = *der_len;
+
+  temp = (char *) _asn1_alloca (strlen (str) + 2);
+  if (temp == NULL)
+    return ASN1_MEM_ALLOC_ERROR;
+
+  strcpy (temp, str);
+  strcat (temp, ".");
+
+  counter = 0;
+  n_start = temp;
+  while ((n_end = strchr (n_start, '.')))
+    {
+      *n_end = 0;
+      val = strtoul (n_start, NULL, 10);
+      counter++;
+
+      if (counter == 1)
+       val1 = val;
+      else if (counter == 2)
+       {
+         if (max_len > 0)
+           der[0] = 40 * val1 + val;
+         *der_len = 1;
        }
-      }
+      else
+       {
+         first = 0;
+         for (k = 4; k >= 0; k--)
+           {
+             bit7 = (val >> (k * 7)) & 0x7F;
+             if (bit7 || first || !k)
+               {
+                 if (k)
+                   bit7 |= 0x80;
+                 if (max_len > (*der_len))
+                   der[*der_len] = bit7;
+                 (*der_len)++;
+                 first = 1;
+               }
+           }
 
+       }
+      n_start = n_end + 1;
     }
-    n_start=n_end+1;
-  }
 
-  asn1_length_der(*der_len,NULL,&len_len);
-  if(max_len>=(*der_len+len_len)){
-    memmove(der+len_len,der,*der_len);
-    asn1_length_der(*der_len,der,&len_len);
-  }
-  *der_len+=len_len;
+  asn1_length_der (*der_len, NULL, &len_len);
+  if (max_len >= (*der_len + len_len))
+    {
+      memmove (der + len_len, der, *der_len);
+      asn1_length_der (*der_len, der, &len_len);
+    }
+  *der_len += len_len;
 
-  _asn1_afree(temp);
+  _asn1_afree (temp);
 
-  if(max_len<(*der_len)) return ASN1_MEM_ERROR;
+  if (max_len < (*der_len))
+    return ASN1_MEM_ERROR;
 
   return ASN1_SUCCESS;
 }
 
 
-const char bit_mask[]={0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80};
+const char bit_mask[] = { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };
 
 /**
  * asn1_bit_der:
@@ -310,21 +335,24 @@ const char bit_mask[]={0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80};
  * included).
  **/
 void
-asn1_bit_der(const unsigned char *str, int bit_len,
-            unsigned char *der, int *der_len)
+asn1_bit_der (const unsigned char *str, int bit_len,
+             unsigned char *der, int *der_len)
 {
-  int len_len,len_byte,len_pad;
-
-  if(der==NULL) return;
-  len_byte=bit_len>>3;
-  len_pad=8-(bit_len&7);
-  if(len_pad==8) len_pad=0;
-  else len_byte++;
-  asn1_length_der(len_byte+1,der,&len_len);
-  der[len_len]=len_pad;
-  memcpy(der+len_len+1,str,len_byte);
-  der[len_len+len_byte]&=bit_mask[len_pad];
-  *der_len=len_byte+len_len+1;
+  int len_len, len_byte, len_pad;
+
+  if (der == NULL)
+    return;
+  len_byte = bit_len >> 3;
+  len_pad = 8 - (bit_len & 7);
+  if (len_pad == 8)
+    len_pad = 0;
+  else
+    len_byte++;
+  asn1_length_der (len_byte + 1, der, &len_len);
+  der[len_len] = len_pad;
+  memcpy (der + len_len + 1, str, len_byte);
+  der[len_len + len_byte] &= bit_mask[len_pad];
+  *der_len = len_byte + len_len + 1;
 }
 
 
@@ -343,48 +371,58 @@ asn1_bit_der(const unsigned char *str, int bit_len,
 /*   otherwise ASN1_SUCCESS.                          */
 /******************************************************/
 asn1_retCode
-_asn1_complete_explicit_tag(node_asn *node,unsigned char *der,int *counter,int *max_len)
+_asn1_complete_explicit_tag (node_asn * node, unsigned char *der,
+                            int *counter, int *max_len)
 {
   node_asn *p;
-  int is_tag_implicit,len2,len3;
+  int is_tag_implicit, len2, len3;
   unsigned char temp[SIZEOF_UNSIGNED_INT];
-  
-  is_tag_implicit=0;
-
-  if(node->type&CONST_TAG){
-    p=node->down;
-    /* When there are nested tags we must complete them reverse to
-       the order they were created. This is because completing a tag
-       modifies all data within it, including the incomplete tags 
-       which store buffer positions -- simon@josefsson.org 2002-09-06
-    */
-    while(p->right)
-      p=p->right;
-    while(p && p!=node->down->left){
-      if(type_field(p->type)==TYPE_TAG){
-       if(p->type&CONST_EXPLICIT){
-         len2=strtol(p->name,NULL,10);
-         _asn1_set_name(p,NULL);
-         asn1_length_der(*counter-len2,temp,&len3);
-         if(len3<=(*max_len)){ 
-           memmove(der+len2+len3,der+len2,*counter-len2);
-           memcpy(der+len2,temp,len3);
-         }
-         *max_len -= len3;
-         *counter+=len3;         
-         is_tag_implicit=0;
-       }
-       else{  /* CONST_IMPLICIT */
-         if(!is_tag_implicit){
-           is_tag_implicit=1;
-         }
+
+  is_tag_implicit = 0;
+
+  if (node->type & CONST_TAG)
+    {
+      p = node->down;
+      /* When there are nested tags we must complete them reverse to
+         the order they were created. This is because completing a tag
+         modifies all data within it, including the incomplete tags 
+         which store buffer positions -- simon@josefsson.org 2002-09-06
+       */
+      while (p->right)
+       p = p->right;
+      while (p && p != node->down->left)
+       {
+         if (type_field (p->type) == TYPE_TAG)
+           {
+             if (p->type & CONST_EXPLICIT)
+               {
+                 len2 = strtol (p->name, NULL, 10);
+                 _asn1_set_name (p, NULL);
+                 asn1_length_der (*counter - len2, temp, &len3);
+                 if (len3 <= (*max_len))
+                   {
+                     memmove (der + len2 + len3, der + len2,
+                              *counter - len2);
+                     memcpy (der + len2, temp, len3);
+                   }
+                 *max_len -= len3;
+                 *counter += len3;
+                 is_tag_implicit = 0;
+               }
+             else
+               {               /* CONST_IMPLICIT */
+                 if (!is_tag_implicit)
+                   {
+                     is_tag_implicit = 1;
+                   }
+               }
+           }
+         p = p->left;
        }
-      }
-      p=p->left;
     }
-  }
 
-  if(*max_len<0) return ASN1_MEM_ERROR;
+  if (*max_len < 0)
+    return ASN1_MEM_ERROR;
 
   return ASN1_SUCCESS;
 }
@@ -406,118 +444,153 @@ _asn1_complete_explicit_tag(node_asn *node,unsigned char *der,int *counter,int *
 /*   otherwise ASN1_SUCCESS.                          */
 /******************************************************/
 asn1_retCode
-_asn1_insert_tag_der(node_asn *node,unsigned char *der,int *counter,int *max_len)
+_asn1_insert_tag_der (node_asn * node, unsigned char *der, int *counter,
+                     int *max_len)
 {
   node_asn *p;
-  int tag_len,is_tag_implicit;
-  unsigned char class,class_implicit=0,temp[SIZEOF_UNSIGNED_INT*3+1];
-  unsigned long tag_implicit=0;
+  int tag_len, is_tag_implicit;
+  unsigned char class, class_implicit = 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1];
+  unsigned long tag_implicit = 0;
   char tag_der[MAX_TAG_LEN];
-   
-  is_tag_implicit=0;
-
-  if(node->type&CONST_TAG){
-    p=node->down;
-    while(p){
-      if(type_field(p->type)==TYPE_TAG){
-       if(p->type&CONST_APPLICATION) class=ASN1_CLASS_APPLICATION;
-       else if(p->type&CONST_UNIVERSAL) class=ASN1_CLASS_UNIVERSAL;
-       else if(p->type&CONST_PRIVATE) class=ASN1_CLASS_PRIVATE;
-       else class=ASN1_CLASS_CONTEXT_SPECIFIC;
-       
-       if(p->type&CONST_EXPLICIT){
-         if(is_tag_implicit)
-           _asn1_tag_der(class_implicit,tag_implicit,tag_der,&tag_len);
-         else
-           _asn1_tag_der(class|ASN1_CLASS_STRUCTURED,strtoul(p->value,NULL,10),tag_der,&tag_len);
 
-         *max_len -= tag_len;
-         if(*max_len>=0)
-           memcpy(der+*counter,tag_der,tag_len);
-         *counter+=tag_len;
-
-         _asn1_ltostr(*counter,temp);
-         _asn1_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)) class|=ASN1_CLASS_STRUCTURED;
-           class_implicit=class;
-           tag_implicit=strtoul(p->value,NULL,10);
-           is_tag_implicit=1;
-         }
+  is_tag_implicit = 0;
+
+  if (node->type & CONST_TAG)
+    {
+      p = node->down;
+      while (p)
+       {
+         if (type_field (p->type) == TYPE_TAG)
+           {
+             if (p->type & CONST_APPLICATION)
+               class = ASN1_CLASS_APPLICATION;
+             else if (p->type & CONST_UNIVERSAL)
+               class = ASN1_CLASS_UNIVERSAL;
+             else if (p->type & CONST_PRIVATE)
+               class = ASN1_CLASS_PRIVATE;
+             else
+               class = ASN1_CLASS_CONTEXT_SPECIFIC;
+
+             if (p->type & CONST_EXPLICIT)
+               {
+                 if (is_tag_implicit)
+                   _asn1_tag_der (class_implicit, tag_implicit, tag_der,
+                                  &tag_len);
+                 else
+                   _asn1_tag_der (class | ASN1_CLASS_STRUCTURED,
+                                  strtoul (p->value, NULL, 10), tag_der,
+                                  &tag_len);
+
+                 *max_len -= tag_len;
+                 if (*max_len >= 0)
+                   memcpy (der + *counter, tag_der, tag_len);
+                 *counter += tag_len;
+
+                 _asn1_ltostr (*counter, temp);
+                 _asn1_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))
+                       class |= ASN1_CLASS_STRUCTURED;
+                     class_implicit = class;
+                     tag_implicit = strtoul (p->value, NULL, 10);
+                     is_tag_implicit = 1;
+                   }
+               }
+           }
+         p = p->right;
        }
-      }
-      p=p->right;
     }
-  }
-  
-  if(is_tag_implicit){
-    _asn1_tag_der(class_implicit,tag_implicit,tag_der,&tag_len);
-  }
-  else{
-    switch(type_field(node->type)){
-    case TYPE_NULL:
-      _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_NULL,tag_der,&tag_len);
-      break;
-    case TYPE_BOOLEAN:
-      _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_BOOLEAN,tag_der,&tag_len);
-      break;
-    case TYPE_INTEGER:
-      _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_INTEGER,tag_der,&tag_len);
-      break;
-    case TYPE_ENUMERATED:
-      _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_ENUMERATED,tag_der,&tag_len);
-      break;
-    case TYPE_OBJECT_ID:
-      _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_OBJECT_ID,tag_der,&tag_len);
-      break;
-    case TYPE_TIME:
-      if(node->type&CONST_UTC){
-       _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_UTCTime,tag_der,&tag_len);
-      }
-      else _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_GENERALIZEDTime,tag_der,&tag_len);
-      break;
-    case TYPE_OCTET_STRING:
-      _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_OCTET_STRING,tag_der,&tag_len);
-      break;
-    case TYPE_GENERALSTRING:
-      _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_GENERALSTRING,tag_der,&tag_len);
-      break;
-    case TYPE_BIT_STRING:
-      _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_BIT_STRING,tag_der,&tag_len);
-      break;
-    case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
-      _asn1_tag_der(ASN1_CLASS_UNIVERSAL|ASN1_CLASS_STRUCTURED,ASN1_TAG_SEQUENCE,tag_der,&tag_len);
-      break;
-    case TYPE_SET: case TYPE_SET_OF:
-      _asn1_tag_der(ASN1_CLASS_UNIVERSAL|ASN1_CLASS_STRUCTURED,ASN1_TAG_SET,tag_der,&tag_len);
-      break;
-    case TYPE_TAG:
-      tag_len=0;
-      break;
-    case TYPE_CHOICE:
-      tag_len=0;
-      break;
-    case TYPE_ANY:
-      tag_len=0;
-      break;
-    default:
-      return ASN1_GENERIC_ERROR;
+
+  if (is_tag_implicit)
+    {
+      _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len);
+    }
+  else
+    {
+      switch (type_field (node->type))
+       {
+       case TYPE_NULL:
+         _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_NULL, tag_der,
+                        &tag_len);
+         break;
+       case TYPE_BOOLEAN:
+         _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BOOLEAN, tag_der,
+                        &tag_len);
+         break;
+       case TYPE_INTEGER:
+         _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_INTEGER, tag_der,
+                        &tag_len);
+         break;
+       case TYPE_ENUMERATED:
+         _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_ENUMERATED, tag_der,
+                        &tag_len);
+         break;
+       case TYPE_OBJECT_ID:
+         _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OBJECT_ID, tag_der,
+                        &tag_len);
+         break;
+       case TYPE_TIME:
+         if (node->type & CONST_UTC)
+           {
+             _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_UTCTime, tag_der,
+                            &tag_len);
+           }
+         else
+           _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALIZEDTime,
+                          tag_der, &tag_len);
+         break;
+       case TYPE_OCTET_STRING:
+         _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OCTET_STRING, tag_der,
+                        &tag_len);
+         break;
+       case TYPE_GENERALSTRING:
+         _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALSTRING,
+                        tag_der, &tag_len);
+         break;
+       case TYPE_BIT_STRING:
+         _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BIT_STRING, tag_der,
+                        &tag_len);
+         break;
+       case TYPE_SEQUENCE:
+       case TYPE_SEQUENCE_OF:
+         _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
+                        ASN1_TAG_SEQUENCE, tag_der, &tag_len);
+         break;
+       case TYPE_SET:
+       case TYPE_SET_OF:
+         _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
+                        ASN1_TAG_SET, tag_der, &tag_len);
+         break;
+       case TYPE_TAG:
+         tag_len = 0;
+         break;
+       case TYPE_CHOICE:
+         tag_len = 0;
+         break;
+       case TYPE_ANY:
+         tag_len = 0;
+         break;
+       default:
+         return ASN1_GENERIC_ERROR;
+       }
     }
-  }
 
   *max_len -= tag_len;
-  if(*max_len>=0)
-    memcpy(der+*counter,tag_der,tag_len);
-  *counter+=tag_len;
+  if (*max_len >= 0)
+    memcpy (der + *counter, tag_der, tag_len);
+  *counter += tag_len;
 
-  if(*max_len<0) return ASN1_MEM_ERROR;
+  if (*max_len < 0)
+    return ASN1_MEM_ERROR;
 
   return ASN1_SUCCESS;
 }
@@ -532,88 +605,108 @@ _asn1_insert_tag_der(node_asn *node,unsigned char *der,int *counter,int *max_len
 /* Return:                                            */
 /******************************************************/
 void
-_asn1_ordering_set(unsigned char *der, int der_len, node_asn *node)
+_asn1_ordering_set (unsigned char *der, int der_len, node_asn * node)
 {
-  struct vet{
+  struct vet
+  {
     int end;
     unsigned long value;
-    struct vet *next,*prev;
+    struct vet *next, *prev;
   };
 
-  int counter,len,len2;
-  struct vet *first,*last,*p_vet,*p2_vet;
+  int counter, len, len2;
+  struct vet *first, *last, *p_vet, *p2_vet;
   node_asn *p;
-  unsigned char class,*temp;
+  unsigned char class, *temp;
   unsigned long tag;
 
-  counter=0;
-
-  if(type_field(node->type)!=TYPE_SET) return;
+  counter = 0;
 
-  p=node->down;
-  while((type_field(p->type)==TYPE_TAG)  || (type_field(p->type)==TYPE_SIZE)) p=p->right;
-
-  if((p==NULL) || (p->right==NULL)) return;
+  if (type_field (node->type) != TYPE_SET)
+    return;
 
-  first=last=NULL;
-  while(p){
-    p_vet=(struct vet *)_asn1_alloca( sizeof(struct vet));
-    if (p_vet==NULL) return;
-    
-    p_vet->next=NULL;
-    p_vet->prev=last;
-    if(first==NULL) first=p_vet;
-    else last->next=p_vet;
-    last=p_vet;
+  p = node->down;
+  while ((type_field (p->type) == TYPE_TAG)
+        || (type_field (p->type) == TYPE_SIZE))
+    p = p->right;
 
-    /* tag value calculation */
-    if (asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS)
-       return;
-    p_vet->value=(class<<24)|tag;
-    counter+=len2;
+  if ((p == NULL) || (p->right == NULL))
+    return;
 
-    /* extraction and length */
-    len2=asn1_get_length_der(der+counter,der_len-counter,&len);
-    if (len2<0) return;
-    counter+=len+len2;
+  first = last = NULL;
+  while (p)
+    {
+      p_vet = (struct vet *) _asn1_alloca (sizeof (struct vet));
+      if (p_vet == NULL)
+       return;
+
+      p_vet->next = NULL;
+      p_vet->prev = last;
+      if (first == NULL)
+       first = p_vet;
+      else
+       last->next = p_vet;
+      last = p_vet;
+
+      /* tag value calculation */
+      if (asn1_get_tag_der
+         (der + counter, der_len - counter, &class, &len2,
+          &tag) != ASN1_SUCCESS)
+       return;
+      p_vet->value = (class << 24) | tag;
+      counter += len2;
+
+      /* extraction and length */
+      len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
+      if (len2 < 0)
+       return;
+      counter += len + len2;
+
+      p_vet->end = counter;
+      p = p->right;
+    }
 
-    p_vet->end=counter;
-    p=p->right;
-  }
+  p_vet = first;
+
+  while (p_vet)
+    {
+      p2_vet = p_vet->next;
+      counter = 0;
+      while (p2_vet)
+       {
+         if (p_vet->value > p2_vet->value)
+           {
+             /* change position */
+             temp = (unsigned char *) _asn1_alloca (p_vet->end - counter);
+             if (temp == NULL)
+               return;
+
+             memcpy (temp, der + counter, p_vet->end - counter);
+             memcpy (der + counter, der + p_vet->end,
+                     p2_vet->end - p_vet->end);
+             memcpy (der + counter + p2_vet->end - p_vet->end, temp,
+                     p_vet->end - counter);
+             _asn1_afree (temp);
+
+             tag = p_vet->value;
+             p_vet->value = p2_vet->value;
+             p2_vet->value = tag;
+
+             p_vet->end = counter + (p2_vet->end - p_vet->end);
+           }
+         counter = p_vet->end;
+
+         p2_vet = p2_vet->next;
+         p_vet = p_vet->next;
+       }
 
-  p_vet=first;
-
-  while(p_vet){
-    p2_vet=p_vet->next;
-    counter=0;
-    while(p2_vet){
-      if(p_vet->value>p2_vet->value){
-       /* change position */
-       temp=(unsigned char *)_asn1_alloca( p_vet->end-counter);
-       if (temp==NULL) return;
-       
-       memcpy(temp,der+counter,p_vet->end-counter);
-       memcpy(der+counter,der+p_vet->end,p2_vet->end-p_vet->end);
-       memcpy(der+counter+p2_vet->end-p_vet->end,temp,p_vet->end-counter);
-       _asn1_afree(temp);
-       
-       tag=p_vet->value;
-       p_vet->value=p2_vet->value;
-       p2_vet->value=tag;
-       
-       p_vet->end=counter+(p2_vet->end-p_vet->end);
-      }
-      counter=p_vet->end;
-      
-      p2_vet=p2_vet->next;
-      p_vet=p_vet->next;
+      if (p_vet != first)
+       p_vet->prev->next = NULL;
+      else
+       first = NULL;
+      _asn1_afree (p_vet);
+      p_vet = first;
     }
-
-    if(p_vet!=first) p_vet->prev->next=NULL;
-    else first=NULL;
-    _asn1_afree(p_vet);
-    p_vet=first;
-  }
 }
 
 /******************************************************/
@@ -626,98 +719,128 @@ _asn1_ordering_set(unsigned char *der, int der_len, node_asn *node)
 /* Return:                                            */
 /******************************************************/
 void
-_asn1_ordering_set_of(unsigned char *der, int der_len, node_asn *node)
+_asn1_ordering_set_of (unsigned char *der, int der_len, node_asn * node)
 {
-  struct vet{
+  struct vet
+  {
     int end;
-    struct vet *next,*prev;
+    struct vet *next, *prev;
   };
 
-  int counter,len,len2,change;
-  struct vet *first,*last,*p_vet,*p2_vet;
+  int counter, len, len2, change;
+  struct vet *first, *last, *p_vet, *p2_vet;
   node_asn *p;
-  unsigned char *temp,class;
-  unsigned long k,max;
-
-  counter=0;
-
-  if(type_field(node->type)!=TYPE_SET_OF) return;
-
-  p=node->down;
-  while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
-  p=p->right;
-
-  if((p==NULL) || (p->right==NULL)) return;
-
-  first=last=NULL;
-  while(p){
-    p_vet=(struct vet *)_asn1_alloca(sizeof(struct vet));
-    if (p_vet==NULL) return;
-    
-    p_vet->next=NULL;
-    p_vet->prev=last;
-    if(first==NULL) first=p_vet;
-    else last->next=p_vet;
-    last=p_vet;
-
-    /* extraction of tag and length */
-    if (der_len-counter > 0) {
-
-       if (asn1_get_tag_der(der+counter, der_len - counter, &class,&len,NULL)!=ASN1_SUCCESS)
-          return;
-       counter+=len;
-    
-       len2=asn1_get_length_der(der+counter,der_len-counter,&len);
-       if (len2<0) return;
-       counter+=len+len2;
-    }
+  unsigned char *temp, class;
+  unsigned long k, max;
 
-    p_vet->end=counter;
-    p=p->right;
-  }
+  counter = 0;
+
+  if (type_field (node->type) != TYPE_SET_OF)
+    return;
 
-  p_vet=first;
+  p = node->down;
+  while ((type_field (p->type) == TYPE_TAG)
+        || (type_field (p->type) == TYPE_SIZE))
+    p = p->right;
+  p = p->right;
+
+  if ((p == NULL) || (p->right == NULL))
+    return;
 
-  while(p_vet){
-    p2_vet=p_vet->next;
-    counter=0;
-    while(p2_vet){
-      if((p_vet->end-counter)>(p2_vet->end-p_vet->end))
-       max=p_vet->end-counter;
+  first = last = NULL;
+  while (p)
+    {
+      p_vet = (struct vet *) _asn1_alloca (sizeof (struct vet));
+      if (p_vet == NULL)
+       return;
+
+      p_vet->next = NULL;
+      p_vet->prev = last;
+      if (first == NULL)
+       first = p_vet;
       else
-       max=p2_vet->end-p_vet->end;
-
-      change=-1;
-      for(k=0;k<max;k++) 
-       if(der[counter+k]>der[p_vet->end+k]){change=1;break;}
-       else if(der[counter+k]<der[p_vet->end+k]){change=0;break;}
-
-      if((change==-1) && ((p_vet->end-counter)>(p2_vet->end-p_vet->end)))
-       change=1;
-
-      if(change==1){
-       /* change position */
-       temp=(unsigned char *)_asn1_alloca(p_vet->end-counter);
-       if (temp==NULL) return;
-       
-       memcpy(temp,der+counter,(p_vet->end)-counter);
-       memcpy(der+counter,der+(p_vet->end),(p2_vet->end)-(p_vet->end));
-       memcpy(der+counter+(p2_vet->end)-(p_vet->end),temp,(p_vet->end)-counter);
-       _asn1_afree(temp);
-       
-       p_vet->end=counter+(p2_vet->end-p_vet->end);
-      }
-      counter=p_vet->end;
-      
-      p2_vet=p2_vet->next;
-      p_vet=p_vet->next;
+       last->next = p_vet;
+      last = p_vet;
+
+      /* extraction of tag and length */
+      if (der_len - counter > 0)
+       {
+
+         if (asn1_get_tag_der
+             (der + counter, der_len - counter, &class, &len,
+              NULL) != ASN1_SUCCESS)
+           return;
+         counter += len;
+
+         len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
+         if (len2 < 0)
+           return;
+         counter += len + len2;
+       }
+
+      p_vet->end = counter;
+      p = p->right;
     }
 
-    if(p_vet!=first) p_vet->prev->next=NULL;
-    else first=NULL;
-    _asn1_afree(p_vet);
-    p_vet=first;
-  }
+  p_vet = first;
+
+  while (p_vet)
+    {
+      p2_vet = p_vet->next;
+      counter = 0;
+      while (p2_vet)
+       {
+         if ((p_vet->end - counter) > (p2_vet->end - p_vet->end))
+           max = p_vet->end - counter;
+         else
+           max = p2_vet->end - p_vet->end;
+
+         change = -1;
+         for (k = 0; k < max; k++)
+           if (der[counter + k] > der[p_vet->end + k])
+             {
+               change = 1;
+               break;
+             }
+           else if (der[counter + k] < der[p_vet->end + k])
+             {
+               change = 0;
+               break;
+             }
+
+         if ((change == -1)
+             && ((p_vet->end - counter) > (p2_vet->end - p_vet->end)))
+           change = 1;
+
+         if (change == 1)
+           {
+             /* change position */
+             temp = (unsigned char *) _asn1_alloca (p_vet->end - counter);
+             if (temp == NULL)
+               return;
+
+             memcpy (temp, der + counter, (p_vet->end) - counter);
+             memcpy (der + counter, der + (p_vet->end),
+                     (p2_vet->end) - (p_vet->end));
+             memcpy (der + counter + (p2_vet->end) - (p_vet->end), temp,
+                     (p_vet->end) - counter);
+             _asn1_afree (temp);
+
+             p_vet->end = counter + (p2_vet->end - p_vet->end);
+           }
+         counter = p_vet->end;
+
+         p2_vet = p2_vet->next;
+         p_vet = p_vet->next;
+       }
+
+      if (p_vet != first)
+       p_vet->prev->next = NULL;
+      else
+       first = NULL;
+      _asn1_afree (p_vet);
+      p_vet = first;
+    }
 }
 
 /**
@@ -748,300 +871,358 @@ _asn1_ordering_set_of(unsigned char *der, int der_len, node_asn *node)
   *
   **/
 asn1_retCode
-asn1_der_coding(ASN1_TYPE element,const char *name,void *ider,int *len,
-                char *ErrorDescription)
+asn1_der_coding (ASN1_TYPE element, const char *name, void *ider, int *len,
+                char *ErrorDescription)
 {
-  node_asn *node,*p,*p2;
-  char temp[SIZEOF_UNSIGNED_LONG_INT*3+1];
-  int counter,counter_old,len2,len3,tlen,move,max_len,max_len_old;
+  node_asn *node, *p, *p2;
+  char temp[SIZEOF_UNSIGNED_LONG_INT * 3 + 1];
+  int counter, counter_old, len2, len3, tlen, move, max_len, max_len_old;
   asn1_retCode err;
-  unsigned charder = ider;
+  unsigned char *der = ider;
 
-  node=asn1_find_node(element,name);
-  if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
+  node = asn1_find_node (element, name);
+  if (node == NULL)
+    return ASN1_ELEMENT_NOT_FOUND;
 
   /* Node is now a locally allocated variable.
    * That is because in some point we modify the
    * structure, and I don't know why! --nmav
-  */
-  node = _asn1_copy_structure3node);
+   */
+  node = _asn1_copy_structure3 (node);
   if (node == NULL)
     return ASN1_ELEMENT_NOT_FOUND;
 
-  max_len=*len;
-
-  counter=0;
-  move=DOWN;
-  p=node;
-  while(1){
-    
-    counter_old=counter;
-    max_len_old=max_len;
-    if(move!=UP){
-      err = _asn1_insert_tag_der(p,der,&counter,&max_len);
-      if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
-         goto error;
-    }
-    switch(type_field(p->type)){
-    case TYPE_NULL:
-      max_len--;
-      if(max_len>=0)
-       der[counter++]=0;
-      move=RIGHT;
-      break;
-    case TYPE_BOOLEAN:
-      if((p->type&CONST_DEFAULT) && (p->value==NULL)){
-       counter=counter_old;
-       max_len=max_len_old;
-      }
-      else{
-       if(p->value==NULL){
-         _asn1_error_description_value_not_found(p,ErrorDescription);
-         err = ASN1_VALUE_NOT_FOUND;
-         goto error;
-       }
-       max_len -= 2;
-       if(max_len>=0){
-         der[counter++]=1;
-         if(p->value[0]=='F') der[counter++]=0;
-         else der[counter++]=0xFF;
-       }
-       else 
-         counter+=2;
-      }
-      move=RIGHT;
-      break;
-    case TYPE_INTEGER: case TYPE_ENUMERATED:
-      if((p->type&CONST_DEFAULT) && (p->value==NULL)){
-       counter=counter_old;
-       max_len=max_len_old;
-      }
-      else{
-       if(p->value==NULL){
-         _asn1_error_description_value_not_found(p,ErrorDescription);
-         err = ASN1_VALUE_NOT_FOUND;
-         goto error;
+  max_len = *len;
+
+  counter = 0;
+  move = DOWN;
+  p = node;
+  while (1)
+    {
+
+      counter_old = counter;
+      max_len_old = max_len;
+      if (move != UP)
+       {
+         err = _asn1_insert_tag_der (p, der, &counter, &max_len);
+         if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
+           goto error;
        }
-       len2=asn1_get_length_der(p->value,p->value_len, &len3);
-       if (len2<0) {
-         err = ASN1_DER_ERROR;
-         goto error;
-        }
-       max_len -= len2+len3;
-       if(max_len>=0)
-         memcpy(der+counter,p->value,len3+len2);
-       counter+=len3+len2;
-      }
-      move=RIGHT;
-      break;
-    case TYPE_OBJECT_ID:
-      if((p->type&CONST_DEFAULT) && (p->value==NULL)){
-       counter=counter_old;
-       max_len=max_len_old;
-      }
-      else{
-       if(p->value==NULL){
-         _asn1_error_description_value_not_found(p,ErrorDescription);
-         err = ASN1_VALUE_NOT_FOUND;
-         goto error;
-       }
-       len2=max_len;
-       err = _asn1_objectid_der(p->value,der+counter,&len2);
-        if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
-         goto error;
-
-       max_len-=len2;
-       counter+=len2;
-      }
-      move=RIGHT;
-      break;
-    case TYPE_TIME:
-      if(p->value==NULL){
-       _asn1_error_description_value_not_found(p,ErrorDescription);
-       err = ASN1_VALUE_NOT_FOUND;
-       goto error;
-      }
-      len2=max_len;
-      err = _asn1_time_der(p->value,der+counter,&len2);
-      if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
-        goto error;
-
-      max_len-=len2;
-      counter+=len2;
-      move=RIGHT;
-      break;
-    case TYPE_OCTET_STRING:
-      if(p->value==NULL){
-       _asn1_error_description_value_not_found(p,ErrorDescription);
-       err = ASN1_VALUE_NOT_FOUND;
-       goto error;
-      }
-      len2=asn1_get_length_der(p->value,p->value_len,&len3);
-      if (len2<0) {
-        err = ASN1_DER_ERROR;
-        goto error;
-      }
-      max_len-=len2+len3;
-      if(max_len>=0)
-       memcpy(der+counter,p->value,len3+len2);
-      counter+=len3+len2;
-      move=RIGHT;
-      break;
-    case TYPE_GENERALSTRING:
-      if(p->value==NULL){
-       _asn1_error_description_value_not_found(p,ErrorDescription);
-       err = ASN1_VALUE_NOT_FOUND;
-       goto error;
-      }
-      len2=asn1_get_length_der(p->value,p->value_len,&len3);
-      if (len2<0) {
-        err = ASN1_DER_ERROR;
-        goto error;
-      }
-      max_len-=len2+len3;
-      if(max_len>=0)
-       memcpy(der+counter,p->value,len3+len2);
-      counter+=len3+len2;
-      move=RIGHT;
-      break;
-    case TYPE_BIT_STRING:
-      if(p->value==NULL){
-       _asn1_error_description_value_not_found(p,ErrorDescription);
-       err = ASN1_VALUE_NOT_FOUND;
-       goto error;
-      }
-      len2=asn1_get_length_der(p->value,p->value_len,&len3);
-      if (len2<0) {
-        err = ASN1_DER_ERROR;\
-        goto error;
-      }
-      max_len-=len2+len3;
-      if(max_len>=0)
-       memcpy(der+counter,p->value,len3+len2);
-      counter+=len3+len2;
-      move=RIGHT;
-      break;
-    case TYPE_SEQUENCE: case TYPE_SET: 
-      if(move!=UP){
-       _asn1_ltostr(counter,temp);
-       tlen = strlen(temp);
-       if (tlen > 0)
-          _asn1_set_value(p,temp,tlen+1);
-       if(p->down==NULL){
-         move=UP;
-         continue;
-       }
-       else{
-         p2=p->down;
-         while(p2 && (type_field(p2->type)==TYPE_TAG)) p2=p2->right;
-         if(p2){
-           p=p2;
-           move=RIGHT;
-           continue;
-         }
-         move=UP;
-         continue;
+      switch (type_field (p->type))
+       {
+       case TYPE_NULL:
+         max_len--;
+         if (max_len >= 0)
+           der[counter++] = 0;
+         move = RIGHT;
+         break;
+       case TYPE_BOOLEAN:
+         if ((p->type & CONST_DEFAULT) && (p->value == NULL))
+           {
+             counter = counter_old;
+             max_len = max_len_old;
+           }
+         else
+           {
+             if (p->value == NULL)
+               {
+                 _asn1_error_description_value_not_found (p,
+                                                          ErrorDescription);
+                 err = ASN1_VALUE_NOT_FOUND;
+                 goto error;
+               }
+             max_len -= 2;
+             if (max_len >= 0)
+               {
+                 der[counter++] = 1;
+                 if (p->value[0] == 'F')
+                   der[counter++] = 0;
+                 else
+                   der[counter++] = 0xFF;
+               }
+             else
+               counter += 2;
+           }
+         move = RIGHT;
+         break;
+       case TYPE_INTEGER:
+       case TYPE_ENUMERATED:
+         if ((p->type & CONST_DEFAULT) && (p->value == NULL))
+           {
+             counter = counter_old;
+             max_len = max_len_old;
+           }
+         else
+           {
+             if (p->value == NULL)
+               {
+                 _asn1_error_description_value_not_found (p,
+                                                          ErrorDescription);
+                 err = ASN1_VALUE_NOT_FOUND;
+                 goto error;
+               }
+             len2 = asn1_get_length_der (p->value, p->value_len, &len3);
+             if (len2 < 0)
+               {
+                 err = ASN1_DER_ERROR;
+                 goto error;
+               }
+             max_len -= len2 + len3;
+             if (max_len >= 0)
+               memcpy (der + counter, p->value, len3 + len2);
+             counter += len3 + len2;
+           }
+         move = RIGHT;
+         break;
+       case TYPE_OBJECT_ID:
+         if ((p->type & CONST_DEFAULT) && (p->value == NULL))
+           {
+             counter = counter_old;
+             max_len = max_len_old;
+           }
+         else
+           {
+             if (p->value == NULL)
+               {
+                 _asn1_error_description_value_not_found (p,
+                                                          ErrorDescription);
+                 err = ASN1_VALUE_NOT_FOUND;
+                 goto error;
+               }
+             len2 = max_len;
+             err = _asn1_objectid_der (p->value, der + counter, &len2);
+             if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
+               goto error;
+
+             max_len -= len2;
+             counter += len2;
+           }
+         move = RIGHT;
+         break;
+       case TYPE_TIME:
+         if (p->value == NULL)
+           {
+             _asn1_error_description_value_not_found (p, ErrorDescription);
+             err = ASN1_VALUE_NOT_FOUND;
+             goto error;
+           }
+         len2 = max_len;
+         err = _asn1_time_der (p->value, der + counter, &len2);
+         if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
+           goto error;
+
+         max_len -= len2;
+         counter += len2;
+         move = RIGHT;
+         break;
+       case TYPE_OCTET_STRING:
+         if (p->value == NULL)
+           {
+             _asn1_error_description_value_not_found (p, ErrorDescription);
+             err = ASN1_VALUE_NOT_FOUND;
+             goto error;
+           }
+         len2 = asn1_get_length_der (p->value, p->value_len, &len3);
+         if (len2 < 0)
+           {
+             err = ASN1_DER_ERROR;
+             goto error;
+           }
+         max_len -= len2 + len3;
+         if (max_len >= 0)
+           memcpy (der + counter, p->value, len3 + len2);
+         counter += len3 + len2;
+         move = RIGHT;
+         break;
+       case TYPE_GENERALSTRING:
+         if (p->value == NULL)
+           {
+             _asn1_error_description_value_not_found (p, ErrorDescription);
+             err = ASN1_VALUE_NOT_FOUND;
+             goto error;
+           }
+         len2 = asn1_get_length_der (p->value, p->value_len, &len3);
+         if (len2 < 0)
+           {
+             err = ASN1_DER_ERROR;
+             goto error;
+           }
+         max_len -= len2 + len3;
+         if (max_len >= 0)
+           memcpy (der + counter, p->value, len3 + len2);
+         counter += len3 + len2;
+         move = RIGHT;
+         break;
+       case TYPE_BIT_STRING:
+         if (p->value == NULL)
+           {
+             _asn1_error_description_value_not_found (p, ErrorDescription);
+             err = ASN1_VALUE_NOT_FOUND;
+             goto error;
+           }
+         len2 = asn1_get_length_der (p->value, p->value_len, &len3);
+         if (len2 < 0)
+           {
+             err = ASN1_DER_ERROR;
+             goto error;
+           }
+         max_len -= len2 + len3;
+         if (max_len >= 0)
+           memcpy (der + counter, p->value, len3 + len2);
+         counter += len3 + len2;
+         move = RIGHT;
+         break;
+       case TYPE_SEQUENCE:
+       case TYPE_SET:
+         if (move != UP)
+           {
+             _asn1_ltostr (counter, temp);
+             tlen = strlen (temp);
+             if (tlen > 0)
+               _asn1_set_value (p, temp, tlen + 1);
+             if (p->down == NULL)
+               {
+                 move = UP;
+                 continue;
+               }
+             else
+               {
+                 p2 = p->down;
+                 while (p2 && (type_field (p2->type) == TYPE_TAG))
+                   p2 = p2->right;
+                 if (p2)
+                   {
+                     p = p2;
+                     move = RIGHT;
+                     continue;
+                   }
+                 move = UP;
+                 continue;
+               }
+           }
+         else
+           {                   /* move==UP */
+             len2 = strtol (p->value, NULL, 10);
+             _asn1_set_value (p, NULL, 0);
+             if ((type_field (p->type) == TYPE_SET) && (max_len >= 0))
+               _asn1_ordering_set (der + len2, max_len - len2, p);
+             asn1_length_der (counter - len2, temp, &len3);
+             max_len -= len3;
+             if (max_len >= 0)
+               {
+                 memmove (der + len2 + len3, der + len2, counter - len2);
+                 memcpy (der + len2, temp, len3);
+               }
+             counter += len3;
+             move = RIGHT;
+           }
+         break;
+       case TYPE_SEQUENCE_OF:
+       case TYPE_SET_OF:
+         if (move != UP)
+           {
+             _asn1_ltostr (counter, temp);
+             tlen = strlen (temp);
+
+             if (tlen > 0)
+               _asn1_set_value (p, temp, tlen + 1);
+             p = p->down;
+             while ((type_field (p->type) == TYPE_TAG)
+                    || (type_field (p->type) == TYPE_SIZE))
+               p = p->right;
+             if (p->right)
+               {
+                 p = p->right;
+                 move = RIGHT;
+                 continue;
+               }
+             else
+               p = _asn1_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)
+                 && (max_len - len2 > 0))
+               {
+                 _asn1_ordering_set_of (der + len2, max_len - len2, p);
+               }
+             asn1_length_der (counter - len2, temp, &len3);
+             max_len -= len3;
+             if (max_len >= 0)
+               {
+                 memmove (der + len2 + len3, der + len2, counter - len2);
+                 memcpy (der + len2, temp, len3);
+               }
+             counter += len3;
+             move = RIGHT;
+           }
+         break;
+       case TYPE_ANY:
+         if (p->value == NULL)
+           {
+             _asn1_error_description_value_not_found (p, ErrorDescription);
+             err = ASN1_VALUE_NOT_FOUND;
+             goto error;
+           }
+         len2 = asn1_get_length_der (p->value, p->value_len, &len3);
+         if (len2 < 0)
+           {
+             err = ASN1_DER_ERROR;
+             goto error;
+           }
+         max_len -= len2;
+         if (max_len >= 0)
+           memcpy (der + counter, p->value + len3, len2);
+         counter += len2;
+         move = RIGHT;
+         break;
+       default:
+         move = (move == UP) ? RIGHT : DOWN;
+         break;
        }
-      }
-      else{   /* move==UP */
-       len2=strtol(p->value,NULL,10);
-       _asn1_set_value(p,NULL,0);
-       if((type_field(p->type)==TYPE_SET) && (max_len>=0))
-         _asn1_ordering_set(der+len2, max_len-len2,p);
-       asn1_length_der(counter-len2,temp,&len3);
-       max_len-=len3;
-       if(max_len>=0){
-         memmove(der+len2+len3,der+len2,counter-len2);
-         memcpy(der+len2,temp,len3);
+
+      if ((move != DOWN) && (counter != counter_old))
+       {
+         err = _asn1_complete_explicit_tag (p, der, &counter, &max_len);
+         if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
+           goto error;
        }
-       counter+=len3;
-       move=RIGHT;
-      }
-      break;
-    case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
-      if(move!=UP){
-       _asn1_ltostr(counter,temp);
-       tlen = strlen(temp);
-       
-       if (tlen > 0)
-          _asn1_set_value(p,temp,tlen+1);
-       p=p->down;
-       while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
-       if(p->right){
-         p=p->right;
-         move=RIGHT;
-         continue;
+
+      if (p == node && move != DOWN)
+       break;
+
+      if (move == DOWN)
+       {
+         if (p->down)
+           p = p->down;
+         else
+           move = RIGHT;
        }
-       else p=_asn1_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) && (max_len-len2>0)) {
-         _asn1_ordering_set_of(der+len2, max_len-len2,p);
-        }
-       asn1_length_der(counter-len2,temp,&len3);
-       max_len-=len3;
-       if(max_len>=0){
-         memmove(der+len2+len3,der+len2,counter-len2);
-         memcpy(der+len2,temp,len3);
+      if (move == RIGHT)
+       {
+         if (p->right)
+           p = p->right;
+         else
+           move = UP;
        }
-       counter+=len3;
-       move=RIGHT;
-      }
-      break;
-    case TYPE_ANY:
-      if(p->value==NULL){
-       _asn1_error_description_value_not_found(p,ErrorDescription);
-       err = ASN1_VALUE_NOT_FOUND;
-       goto error;
-      }
-      len2=asn1_get_length_der(p->value,p->value_len,&len3);
-      if (len2<0) {
-        err = ASN1_DER_ERROR;
-        goto error;
-      }
-      max_len-=len2;
-      if(max_len>=0)
-       memcpy(der+counter,p->value+len3,len2);
-      counter+=len2;
-      move=RIGHT;
-      break;
-    default:
-       move=(move==UP)?RIGHT:DOWN;
-      break;
-    }
-
-    if((move!=DOWN) && (counter!=counter_old)){
-      err=_asn1_complete_explicit_tag(p,der,&counter,&max_len);
-      if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
-        goto error;
+      if (move == UP)
+       p = _asn1_find_up (p);
     }
 
-    if(p==node && move!=DOWN) break;
+  *len = counter;
 
-    if(move==DOWN){
-      if(p->down) p=p->down;
-      else move=RIGHT;
+  if (max_len < 0)
+    {
+      err = ASN1_MEM_ERROR;
+      goto error;
     }
-    if(move==RIGHT){
-      if(p->right) p=p->right;
-      else move=UP;
-    }
-   if(move==UP) p=_asn1_find_up(p);
-  }
-
-  *len=counter;
-
-  if(max_len<0) {
-    err = ASN1_MEM_ERROR;
-    goto error;
-  }
 
   err = ASN1_SUCCESS;
 
 error:
-  asn1_delete_structure(&node);
+  asn1_delete_structure (&node);
   return err;
 }
index 15396660cd636556f3e65bf88b9d55c79b3da3b5..3df85318e6164482b7c3dd4c290e2c6ffed2b209 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  * 02110-1301, USA
  */
+
 
 /*****************************************************/
 /* File: decoding.c                                  */
 /* Description: Functions to manage DER decoding     */
 /*****************************************************/
+
 #include <int.h>
 #include <errors.h>
 #include "parser_aux.h"
 
 
 void
-_asn1_error_description_tag_error(node_asn *node,char *ErrorDescription)
+_asn1_error_description_tag_error (node_asn * node, char *ErrorDescription)
 {
 
-  Estrcpy(ErrorDescription,":: tag error near element '");
-  _asn1_hierarchical_name(node,ErrorDescription+strlen(ErrorDescription),
-                         MAX_ERROR_DESCRIPTION_SIZE-40);
-  Estrcat(ErrorDescription,"'");
+  Estrcpy (ErrorDescription, ":: tag error near element '");
+  _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
+                          MAX_ERROR_DESCRIPTION_SIZE - 40);
+  Estrcat (ErrorDescription, "'");
 
 }
 
@@ -57,41 +57,47 @@ _asn1_error_description_tag_error(node_asn *node,char *ErrorDescription)
  *   length, or -2 when the value was too big.
  **/
 signed long
-asn1_get_length_der(const unsigned char *der, int der_len, int  *len)
+asn1_get_length_der (const unsigned char *der, int der_len, int *len)
 {
   unsigned long ans;
-  int k,punt;
+  int k, punt;
 
   *len = 0;
-  if (der_len <= 0) return 0;
-
-  if(!(der[0]&128)){
-    /* short form */
-    *len=1;
-    return der[0];
-  }
-  else{
-    /* Long form */
-    k=der[0]&0x7F;
-    punt=1;
-    if(k){  /* definite length method */
-      ans=0;
-      while(punt<=k && punt < der_len) {
-       unsigned long last = ans;
-
-       ans=ans*256+der[punt++];
-       if (ans < last)
-         /* we wrapped around, no bignum support... */
-         return -2;
-      }
-    }
-    else{  /* indefinite length method */
-      ans=-1;
+  if (der_len <= 0)
+    return 0;
+
+  if (!(der[0] & 128))
+    {
+      /* short form */
+      *len = 1;
+      return der[0];
     }
+  else
+    {
+      /* Long form */
+      k = der[0] & 0x7F;
+      punt = 1;
+      if (k)
+       {                       /* definite length method */
+         ans = 0;
+         while (punt <= k && punt < der_len)
+           {
+             unsigned long last = ans;
+
+             ans = ans * 256 + der[punt++];
+             if (ans < last)
+               /* we wrapped around, no bignum support... */
+               return -2;
+           }
+       }
+      else
+       {                       /* indefinite length method */
+         ans = -1;
+       }
 
-    *len=punt;
-    return ans;
-  }
+      *len = punt;
+      return ans;
+    }
 }
 
 
@@ -110,43 +116,47 @@ asn1_get_length_der(const unsigned char *der, int der_len, int  *len)
  * Return value: Returns ASN1_SUCCESS on success, or an error.
  **/
 int
-asn1_get_tag_der(const unsigned char *der, int der_len,
-                unsigned char *class,int  *len, unsigned long *tag)
+asn1_get_tag_der (const unsigned char *der, int der_len,
+                 unsigned char *class, int *len, unsigned long *tag)
 {
-  int punt,ris;
-
-  if (der==NULL || der_len <= 0 || len == NULL) return ASN1_DER_ERROR;
-
-  *class=der[0]&0xE0;
-  if((der[0]&0x1F)!=0x1F){
-    /* short form */
-    *len=1;
-    ris=der[0]&0x1F;
-  }
-  else{
-    /* Long form */
-    punt=1;
-    ris=0;
-    while(punt <= der_len && der[punt]&128)
+  int punt, ris;
+
+  if (der == NULL || der_len <= 0 || len == NULL)
+    return ASN1_DER_ERROR;
+
+  *class = der[0] & 0xE0;
+  if ((der[0] & 0x1F) != 0x1F)
+    {
+      /* short form */
+      *len = 1;
+      ris = der[0] & 0x1F;
+    }
+  else
+    {
+      /* Long form */
+      punt = 1;
+      ris = 0;
+      while (punt <= der_len && der[punt] & 128)
+       {
+         int last = ris;
+         ris = ris * 128 + (der[punt++] & 0x7F);
+         if (ris < last)
+           /* wrapper around, and no bignums... */
+           return ASN1_DER_ERROR;
+       }
+      if (punt >= der_len)
+       return ASN1_DER_ERROR;
       {
        int last = ris;
-       ris=ris*128+(der[punt++]&0x7F);
+       ris = ris * 128 + (der[punt++] & 0x7F);
        if (ris < last)
          /* wrapper around, and no bignums... */
          return ASN1_DER_ERROR;
       }
-    if (punt >= der_len)
-      return ASN1_DER_ERROR;
-    {
-      int last = ris;
-      ris=ris*128+(der[punt++]&0x7F);
-      if (ris < last)
-       /* wrapper around, and no bignums... */
-       return ASN1_DER_ERROR;
+      *len = punt;
     }
-    *len=punt;
-  }
-  if (tag) *tag = ris;
+  if (tag)
+    *tag = ris;
   return ASN1_SUCCESS;
 }
 
@@ -167,25 +177,28 @@ asn1_get_tag_der(const unsigned char *der, int der_len,
  * Return value: Returns ASN1_SUCCESS on success, or an error.
  **/
 int
-asn1_get_octet_der(const unsigned char *der, int der_len,
-                  int *ret_len,unsigned char *str, int str_size, int *str_len)
+asn1_get_octet_der (const unsigned char *der, int der_len,
+                   int *ret_len, unsigned char *str, int str_size,
+                   int *str_len)
 {
   int len_len;
 
-  if (der_len <= 0) return ASN1_GENERIC_ERROR;
+  if (der_len <= 0)
+    return ASN1_GENERIC_ERROR;
 
   /* if(str==NULL) return ASN1_SUCCESS; */
-  *str_len=asn1_get_length_der(der, der_len, &len_len);
+  *str_len = asn1_get_length_der (der, der_len, &len_len);
 
   if (*str_len < 0)
-     return ASN1_DER_ERROR;
+    return ASN1_DER_ERROR;
 
-  *ret_len=*str_len+len_len;
-  if ( str_size >= *str_len)
-    memcpy(str,der+len_len,*str_len);
-  else {
-    return ASN1_MEM_ERROR;
-  }
+  *ret_len = *str_len + len_len;
+  if (str_size >= *str_len)
+    memcpy (str, der + len_len, *str_len);
+  else
+    {
+      return ASN1_MEM_ERROR;
+    }
 
   return ASN1_SUCCESS;
 }
@@ -195,56 +208,64 @@ asn1_get_octet_der(const unsigned char *der, int der_len,
 /* Returns ASN1_SUCCESS on success or an error code on error.
  */
 int
-_asn1_get_time_der(const unsigned char *der, int der_len, int *ret_len,unsigned char *str,int str_size)
+_asn1_get_time_der (const unsigned char *der, int der_len, int *ret_len,
+                   char *str, int str_size)
 {
-  int len_len,str_len;
-
-  if(der_len <=0 || str==NULL) return ASN1_DER_ERROR;
-  str_len=asn1_get_length_der(der, der_len, &len_len);
-  if (str_len < 0 || str_size < str_len) 
-     return ASN1_DER_ERROR;
-  memcpy(str,der+len_len,str_len);
-  str[str_len]=0;
-  *ret_len=str_len+len_len;
-  
+  int len_len, str_len;
+
+  if (der_len <= 0 || str == NULL)
+    return ASN1_DER_ERROR;
+  str_len = asn1_get_length_der (der, der_len, &len_len);
+  if (str_len < 0 || str_size < str_len)
+    return ASN1_DER_ERROR;
+  memcpy (str, der + len_len, str_len);
+  str[str_len] = 0;
+  *ret_len = str_len + len_len;
+
   return ASN1_SUCCESS;
 }
 
 
 
 void
-_asn1_get_objectid_der(const unsigned char *der,int der_len, int *ret_len,unsigned char *str, int str_size)
+_asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len,
+                       char *str, int str_size)
 {
-  int len_len,len,k;
+  int len_len, len, k;
   char temp[20];
-  unsigned long val,val1;
+  unsigned long val, val1;
 
   *ret_len = 0;
-  if (str && str_size > 0) str[0] = 0; /* no oid */
-
-  if(str==NULL || der_len <= 0) return;
-  len=asn1_get_length_der(der,der_len, &len_len);
-  
-  if (len < 0 || len > der_len || len_len > der_len) return;
-  
-  val1=der[len_len]/40;
-  val=der[len_len]-val1*40;
-
-  _asn1_str_cpy(str, str_size, _asn1_ltostr(val1,temp));
-  _asn1_str_cat(str, str_size, ".");
-  _asn1_str_cat(str, str_size, _asn1_ltostr(val,temp));
-
-  val=0;
-  for(k=1;k<len;k++){
-    val=val<<7;
-    val|=der[len_len+k]&0x7F;
-    if(!(der[len_len+k]&0x80)){
-      _asn1_str_cat(str, str_size,".");
-      _asn1_str_cat(str, str_size,_asn1_ltostr(val,temp));
-      val=0;
+  if (str && str_size > 0)
+    str[0] = 0;                        /* no oid */
+
+  if (str == NULL || der_len <= 0)
+    return;
+  len = asn1_get_length_der (der, der_len, &len_len);
+
+  if (len < 0 || len > der_len || len_len > der_len)
+    return;
+
+  val1 = der[len_len] / 40;
+  val = der[len_len] - val1 * 40;
+
+  _asn1_str_cpy (str, str_size, _asn1_ltostr (val1, temp));
+  _asn1_str_cat (str, str_size, ".");
+  _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
+
+  val = 0;
+  for (k = 1; k < len; k++)
+    {
+      val = val << 7;
+      val |= der[len_len + k] & 0x7F;
+      if (!(der[len_len + k] & 0x80))
+       {
+         _asn1_str_cat (str, str_size, ".");
+         _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
+         val = 0;
+       }
     }
-  }
-  *ret_len=len+len_len;
+  *ret_len = len + len_len;
 }
 
 
@@ -264,24 +285,27 @@ _asn1_get_objectid_der(const unsigned char *der,int der_len, int *ret_len,unsign
  * Return value: Return ASN1_SUCCESS on success, or an error.
  **/
 int
-asn1_get_bit_der(const unsigned char *der, int der_len,
-                int *ret_len, unsigned char *str, int str_size, int *bit_len)
+asn1_get_bit_der (const unsigned char *der, int der_len,
+                 int *ret_len, unsigned char *str, int str_size,
+                 int *bit_len)
 {
-  int len_len,len_byte;
+  int len_len, len_byte;
 
-  if (der_len <=0) return ASN1_GENERIC_ERROR;
-  len_byte=asn1_get_length_der(der,der_len,&len_len)-1;
+  if (der_len <= 0)
+    return ASN1_GENERIC_ERROR;
+  len_byte = asn1_get_length_der (der, der_len, &len_len) - 1;
   if (len_byte < 0)
     return ASN1_DER_ERROR;
 
-  *ret_len=len_byte+len_len+1;
-  *bit_len=len_byte*8-der[len_len];
+  *ret_len = len_byte + len_len + 1;
+  *bit_len = len_byte * 8 - der[len_len];
 
   if (str_size >= len_byte)
-    memcpy(str,der+len_len+1,len_byte);
-  else {
-    return ASN1_MEM_ERROR;
-  }
+    memcpy (str, der + len_len + 1, len_byte);
+  else
+    {
+      return ASN1_MEM_ERROR;
+    }
 
   return ASN1_SUCCESS;
 }
@@ -290,320 +314,412 @@ asn1_get_bit_der(const unsigned char *der, int der_len,
 
 
 int
-_asn1_extract_tag_der(node_asn *node,const unsigned char *der, int der_len,int *ret_len)
+_asn1_extract_tag_der (node_asn * node, const unsigned char *der, int der_len,
+                      int *ret_len)
 {
   node_asn *p;
-  int counter,len2,len3,is_tag_implicit;
-  unsigned long tag,tag_implicit=0;
-  unsigned char class,class2,class_implicit=0;
-
-  if (der_len <= 0) return ASN1_GENERIC_ERROR;
-  
-  counter=is_tag_implicit=0;
-
-  if(node->type&CONST_TAG){
-    p=node->down;
-    while(p){
-      if(type_field(p->type)==TYPE_TAG){
-       if(p->type&CONST_APPLICATION) class2=ASN1_CLASS_APPLICATION;
-       else if(p->type&CONST_UNIVERSAL) class2=ASN1_CLASS_UNIVERSAL;
-       else if(p->type&CONST_PRIVATE) class2=ASN1_CLASS_PRIVATE;
-       else class2=ASN1_CLASS_CONTEXT_SPECIFIC;
-       
-       if(p->type&CONST_EXPLICIT){
-         if (asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS)
-            return ASN1_DER_ERROR;
-         if (counter+len2 > der_len)
-           return ASN1_DER_ERROR;
-         counter+=len2;
-         len3=asn1_get_length_der(der+counter,der_len-counter, &len2);
-         if (len3 < 0)
-           return ASN1_DER_ERROR;
-         counter+=len2;
-         if(!is_tag_implicit){
-           if((class!=(class2|ASN1_CLASS_STRUCTURED)) ||
-              (tag!=strtoul(p->value,NULL,10)))
-             return ASN1_TAG_ERROR;
-         }
-         else{    /* ASN1_TAG_IMPLICIT */
-           if((class!=class_implicit) || (tag!=tag_implicit))
-             return ASN1_TAG_ERROR;
-         }
-
-         is_tag_implicit=0;
-       }
-       else{    /* ASN1_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))  class2|=ASN1_CLASS_STRUCTURED;
-           class_implicit=class2;
-           tag_implicit=strtoul(p->value,NULL,10);
-           is_tag_implicit=1;
-         }
+  int counter, len2, len3, is_tag_implicit;
+  unsigned long tag, tag_implicit = 0;
+  unsigned char class, class2, class_implicit = 0;
+
+  if (der_len <= 0)
+    return ASN1_GENERIC_ERROR;
+
+  counter = is_tag_implicit = 0;
+
+  if (node->type & CONST_TAG)
+    {
+      p = node->down;
+      while (p)
+       {
+         if (type_field (p->type) == TYPE_TAG)
+           {
+             if (p->type & CONST_APPLICATION)
+               class2 = ASN1_CLASS_APPLICATION;
+             else if (p->type & CONST_UNIVERSAL)
+               class2 = ASN1_CLASS_UNIVERSAL;
+             else if (p->type & CONST_PRIVATE)
+               class2 = ASN1_CLASS_PRIVATE;
+             else
+               class2 = ASN1_CLASS_CONTEXT_SPECIFIC;
+
+             if (p->type & CONST_EXPLICIT)
+               {
+                 if (asn1_get_tag_der
+                     (der + counter, der_len - counter, &class, &len2,
+                      &tag) != ASN1_SUCCESS)
+                   return ASN1_DER_ERROR;
+                 if (counter + len2 > der_len)
+                   return ASN1_DER_ERROR;
+                 counter += len2;
+                 len3 =
+                   asn1_get_length_der (der + counter, der_len - counter,
+                                        &len2);
+                 if (len3 < 0)
+                   return ASN1_DER_ERROR;
+                 counter += len2;
+                 if (!is_tag_implicit)
+                   {
+                     if ((class != (class2 | ASN1_CLASS_STRUCTURED)) ||
+                         (tag != strtoul ((char *) p->value, NULL, 10)))
+                       return ASN1_TAG_ERROR;
+                   }
+                 else
+                   {           /* ASN1_TAG_IMPLICIT */
+                     if ((class != class_implicit) || (tag != tag_implicit))
+                       return ASN1_TAG_ERROR;
+                   }
+
+                 is_tag_implicit = 0;
+               }
+             else
+               {               /* ASN1_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))
+                       class2 |= ASN1_CLASS_STRUCTURED;
+                     class_implicit = class2;
+                     tag_implicit = strtoul ((char *) p->value, NULL, 10);
+                     is_tag_implicit = 1;
+                   }
+               }
+           }
+         p = p->right;
        }
-      }
-      p=p->right;
     }
-  }
 
-  if(is_tag_implicit){
-    if (asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS)
-            return ASN1_DER_ERROR;
-    if (counter+len2 > der_len)
-      return ASN1_DER_ERROR;
+  if (is_tag_implicit)
+    {
+      if (asn1_get_tag_der
+         (der + counter, der_len - counter, &class, &len2,
+          &tag) != ASN1_SUCCESS)
+       return ASN1_DER_ERROR;
+      if (counter + len2 > der_len)
+       return ASN1_DER_ERROR;
 
-    if((class!=class_implicit) || (tag!=tag_implicit)){
-      if(type_field(node->type)==TYPE_OCTET_STRING){
-       class_implicit |= ASN1_CLASS_STRUCTURED;
-       if((class!=class_implicit) || (tag!=tag_implicit))
-         return ASN1_TAG_ERROR;
-      }
-      else
-       return ASN1_TAG_ERROR;
-    }
-  }
-  else{
-    if(type_field(node->type)==TYPE_TAG){
-      counter=0;
-      *ret_len=counter;
-      return ASN1_SUCCESS;
+      if ((class != class_implicit) || (tag != tag_implicit))
+       {
+         if (type_field (node->type) == TYPE_OCTET_STRING)
+           {
+             class_implicit |= ASN1_CLASS_STRUCTURED;
+             if ((class != class_implicit) || (tag != tag_implicit))
+               return ASN1_TAG_ERROR;
+           }
+         else
+           return ASN1_TAG_ERROR;
+       }
     }
+  else
+    {
+      if (type_field (node->type) == TYPE_TAG)
+       {
+         counter = 0;
+         *ret_len = counter;
+         return ASN1_SUCCESS;
+       }
 
-    if (asn1_get_tag_der(der+counter, der_len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
-     return ASN1_DER_ERROR;
-    if (counter+len2 > der_len)
-      return ASN1_DER_ERROR;
-
-    switch(type_field(node->type)){
-    case TYPE_NULL:
-      if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_NULL)) return ASN1_DER_ERROR;
-       break;
-    case TYPE_BOOLEAN:
-      if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_BOOLEAN)) return ASN1_DER_ERROR;
-       break;
-    case TYPE_INTEGER:
-      if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_INTEGER)) return ASN1_DER_ERROR;
-       break;
-    case TYPE_ENUMERATED:
-      if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_ENUMERATED)) return ASN1_DER_ERROR;
-       break;
-    case TYPE_OBJECT_ID:
-      if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_OBJECT_ID)) return ASN1_DER_ERROR;
-       break;
-    case TYPE_TIME:
-      if(node->type&CONST_UTC){
-       if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_UTCTime)) return ASN1_DER_ERROR;
-      }
-      else{
-       if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_GENERALIZEDTime))
-         return ASN1_DER_ERROR;
-      }
-      break;
-    case TYPE_OCTET_STRING:
-      if(((class!=ASN1_CLASS_UNIVERSAL) && (class!=(ASN1_CLASS_UNIVERSAL|ASN1_CLASS_STRUCTURED)))
-        || (tag!=ASN1_TAG_OCTET_STRING)) return ASN1_DER_ERROR;
-      break;
-    case TYPE_GENERALSTRING:
-      if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_GENERALSTRING)) return ASN1_DER_ERROR;
-      break;
-    case TYPE_BIT_STRING:
-      if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_BIT_STRING)) return ASN1_DER_ERROR;
-      break;
-    case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
-      if((class!=(ASN1_CLASS_UNIVERSAL|ASN1_CLASS_STRUCTURED)) || (tag!=ASN1_TAG_SEQUENCE))
+      if (asn1_get_tag_der
+         (der + counter, der_len - counter, &class, &len2,
+          &tag) != ASN1_SUCCESS)
        return ASN1_DER_ERROR;
-      break;
-    case TYPE_SET: case TYPE_SET_OF:
-      if((class!=(ASN1_CLASS_UNIVERSAL|ASN1_CLASS_STRUCTURED)) || (tag!=ASN1_TAG_SET))
+      if (counter + len2 > der_len)
        return ASN1_DER_ERROR;
-      break;
-    case TYPE_ANY:
-      counter-=len2;
-      break;
-    default:
-      return ASN1_DER_ERROR;
-      break;
+
+      switch (type_field (node->type))
+       {
+       case TYPE_NULL:
+         if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_NULL))
+           return ASN1_DER_ERROR;
+         break;
+       case TYPE_BOOLEAN:
+         if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BOOLEAN))
+           return ASN1_DER_ERROR;
+         break;
+       case TYPE_INTEGER:
+         if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_INTEGER))
+           return ASN1_DER_ERROR;
+         break;
+       case TYPE_ENUMERATED:
+         if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_ENUMERATED))
+           return ASN1_DER_ERROR;
+         break;
+       case TYPE_OBJECT_ID:
+         if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_OBJECT_ID))
+           return ASN1_DER_ERROR;
+         break;
+       case TYPE_TIME:
+         if (node->type & CONST_UTC)
+           {
+             if ((class != ASN1_CLASS_UNIVERSAL)
+                 || (tag != ASN1_TAG_UTCTime))
+               return ASN1_DER_ERROR;
+           }
+         else
+           {
+             if ((class != ASN1_CLASS_UNIVERSAL)
+                 || (tag != ASN1_TAG_GENERALIZEDTime))
+               return ASN1_DER_ERROR;
+           }
+         break;
+       case TYPE_OCTET_STRING:
+         if (((class != ASN1_CLASS_UNIVERSAL)
+              && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
+             || (tag != ASN1_TAG_OCTET_STRING))
+           return ASN1_DER_ERROR;
+         break;
+       case TYPE_GENERALSTRING:
+         if ((class != ASN1_CLASS_UNIVERSAL)
+             || (tag != ASN1_TAG_GENERALSTRING))
+           return ASN1_DER_ERROR;
+         break;
+       case TYPE_BIT_STRING:
+         if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BIT_STRING))
+           return ASN1_DER_ERROR;
+         break;
+       case TYPE_SEQUENCE:
+       case TYPE_SEQUENCE_OF:
+         if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
+             || (tag != ASN1_TAG_SEQUENCE))
+           return ASN1_DER_ERROR;
+         break;
+       case TYPE_SET:
+       case TYPE_SET_OF:
+         if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
+             || (tag != ASN1_TAG_SET))
+           return ASN1_DER_ERROR;
+         break;
+       case TYPE_ANY:
+         counter -= len2;
+         break;
+       default:
+         return ASN1_DER_ERROR;
+         break;
+       }
     }
-  }
 
-  counter+=len2;
-  *ret_len=counter;
+  counter += len2;
+  *ret_len = counter;
   return ASN1_SUCCESS;
 }
 
 
-int 
-_asn1_delete_not_used(node_asn *node)
+int
+_asn1_delete_not_used (node_asn * node)
 {
-  node_asn *p,*p2;
+  node_asn *p, *p2;
 
-  if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
+  if (node == NULL)
+    return ASN1_ELEMENT_NOT_FOUND;
 
-  p=node;
-  while(p){
-    if(p->type&CONST_NOT_USED){
-      p2=NULL;
-      if(p!=node){
-       p2=_asn1_find_left(p);
-       if(!p2) p2=_asn1_find_up(p);
-      }
-      asn1_delete_structure(&p);
-      p=p2;
-    } 
+  p = node;
+  while (p)
+    {
+      if (p->type & CONST_NOT_USED)
+       {
+         p2 = NULL;
+         if (p != node)
+           {
+             p2 = _asn1_find_left (p);
+             if (!p2)
+               p2 = _asn1_find_up (p);
+           }
+         asn1_delete_structure (&p);
+         p = p2;
+       }
 
-    if(!p) break;  /* reach node */
+      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;
-         }
+      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 ASN1_SUCCESS;
 }
 
 
 asn1_retCode
-_asn1_get_octet_string(const unsigned char* der, node_asn *node,int* len)
+_asn1_get_octet_string (const unsigned char *der, node_asn * node, int *len)
 {
-  int len2,len3,counter,counter2,counter_end,tot_len,indefinite;
-  char *temp,*temp2;
+  int len2, len3, counter, counter2, counter_end, tot_len, indefinite;
+  unsigned char *temp, *temp2;
 
-  counter=0;
+  counter = 0;
 
-  if(*(der-1) & ASN1_CLASS_STRUCTURED){
-    tot_len=0;
-    indefinite=asn1_get_length_der(der, *len, &len3);
-    if (indefinite < -1)
-      return ASN1_DER_ERROR;
+  if (*(der - 1) & ASN1_CLASS_STRUCTURED)
+    {
+      tot_len = 0;
+      indefinite = asn1_get_length_der (der, *len, &len3);
+      if (indefinite < -1)
+       return ASN1_DER_ERROR;
 
-    counter+=len3;
-    if(indefinite>=0) indefinite+=len3;
-    while(1){
-      if(counter>(*len)) return ASN1_DER_ERROR;
+      counter += len3;
+      if (indefinite >= 0)
+       indefinite += len3;
 
-      if(indefinite==-1){
-       if((der[counter]==0) && (der[counter+1]==0)){
-         counter+=2;
-         break;
+      while (1)
+       {
+         if (counter > (*len))
+           return ASN1_DER_ERROR;
+
+         if (indefinite == -1)
+           {
+             if ((der[counter] == 0) && (der[counter + 1] == 0))
+               {
+                 counter += 2;
+                 break;
+               }
+           }
+         else if (counter >= indefinite)
+           break;
+
+         if (der[counter] != ASN1_TAG_OCTET_STRING)
+           return ASN1_DER_ERROR;
+
+         counter++;
+
+         len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
+         if (len2 <= 0)
+           return ASN1_DER_ERROR;
+
+         counter += len3 + len2;
+         tot_len += len2;
        }
-      }
-      else if(counter>=indefinite) break;
 
-      if(der[counter] != ASN1_TAG_OCTET_STRING) return ASN1_DER_ERROR;
+      /* copy */
+      if (node)
+       {
+         asn1_length_der (tot_len, NULL, &len2);
+         temp = _asn1_alloca (len2 + tot_len);
+         if (temp == NULL)
+           {
+             return ASN1_MEM_ALLOC_ERROR;
+           }
 
-      counter++;
+         asn1_length_der (tot_len, temp, &len2);
+         tot_len += len2;
+         temp2 = temp + len2;
+         len2 = asn1_get_length_der (der, *len, &len3);
+         if (len2 < -1)
+           return ASN1_DER_ERROR;
+         counter2 = len3 + 1;
 
-      len2=asn1_get_length_der(der+counter,*len-counter, &len3);
-      if(len2 <= 0) return ASN1_DER_ERROR;
+         if (indefinite == -1)
+           counter_end = counter - 2;
+         else
+           counter_end = counter;
+
+         while (counter2 < counter_end)
+           {
+             len2 =
+               asn1_get_length_der (der + counter2, *len - counter, &len3);
+             if (len2 < -1)
+               return ASN1_DER_ERROR;
+
+             /* FIXME: to be checked. Is this ok? Has the
+              * size been checked before?
+              */
+             memcpy (temp2, der + counter2 + len3, len2);
+             temp2 += len2;
+             counter2 += len2 + len3 + 1;
+           }
 
-      counter+=len3+len2;
-      tot_len+=len2;
+         _asn1_set_value (node, temp, tot_len);
+         _asn1_afree (temp);
+       }
     }
-
-    /* copy */
-    if(node){
-      asn1_length_der(tot_len,NULL,&len2);
-      temp=(unsigned char *)_asn1_alloca(len2+tot_len);
-      if (temp==NULL){
-       return ASN1_MEM_ALLOC_ERROR;
-      }
-      
-      asn1_length_der(tot_len,temp,&len2);
-      tot_len+=len2;
-      temp2=temp+len2;
-      len2=asn1_get_length_der(der,*len,&len3);
-      if(len2 < -1) return ASN1_DER_ERROR;
-      counter2=len3+1;
-
-      if(indefinite==-1) counter_end=counter-2;
-      else counter_end=counter;
-      
-      while(counter2<counter_end){
-       len2=asn1_get_length_der(der+counter2, *len-counter, &len3);
-       if(len2 < -1) return ASN1_DER_ERROR;
-
-       /* FIXME: to be checked. Is this ok? Has the
-        * size been checked before?
-        */
-       memcpy(temp2,der+counter2+len3,len2);
-       temp2+=len2;
-       counter2+=len2+len3+1;
-      }
-      
-      _asn1_set_value(node,temp,tot_len);
-      _asn1_afree(temp);
+  else
+    {                          /* NOT STRUCTURED */
+      len2 = asn1_get_length_der (der, *len, &len3);
+      if (len2 < 0)
+       return ASN1_DER_ERROR;
+      if (len3 + len2 > *len)
+       return ASN1_DER_ERROR;
+      if (node)
+       _asn1_set_value (node, der, len3 + len2);
+      counter = len3 + len2;
     }
-  }
-  else{  /* NOT STRUCTURED */
-    len2=asn1_get_length_der(der, *len, &len3);
-    if(len2 < 0) return ASN1_DER_ERROR;
-    if (len3+len2 > *len) return ASN1_DER_ERROR;
-    if(node)
-      _asn1_set_value(node,der,len3+len2);
-    counter=len3+len2;
-  }   
-
-  *len=counter;
+
+  *len = counter;
   return ASN1_SUCCESS;
 
 }
 
 
 asn1_retCode
-_asn1_get_indefinite_length_string(const unsigned char* der, int* len)
+_asn1_get_indefinite_length_string (const unsigned char *der, int *len)
 {
-  int len2,len3,counter,indefinite;
+  int len2, len3, counter, indefinite;
   unsigned long tag;
   unsigned char class;
 
-  counter=indefinite=0;
+  counter = indefinite = 0;
 
-  while(1){
-    if((*len)<counter) return ASN1_DER_ERROR;
+  while (1)
+    {
+      if ((*len) < counter)
+       return ASN1_DER_ERROR;
 
-    if((der[counter]==0) && (der[counter+1]==0)){
-      counter+=2;
-      indefinite--;
-      if(indefinite<=0) break;
-      else continue;
-    }
+      if ((der[counter] == 0) && (der[counter + 1] == 0))
+       {
+         counter += 2;
+         indefinite--;
+         if (indefinite <= 0)
+           break;
+         else
+           continue;
+       }
 
-    if(asn1_get_tag_der(der+counter, *len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
-     return ASN1_DER_ERROR;
-    if (counter+len2 > *len)
-      return ASN1_DER_ERROR;
-    counter+=len2;
-    len2=asn1_get_length_der(der+counter, *len-counter,&len3);
-    if(len2 < -1) return ASN1_DER_ERROR;
-    if(len2 == -1){
-      indefinite++;
-      counter+=1;
-    }
-    else{
-      counter+=len2+len3;
+      if (asn1_get_tag_der
+         (der + counter, *len - counter, &class, &len2,
+          &tag) != ASN1_SUCCESS)
+       return ASN1_DER_ERROR;
+      if (counter + len2 > *len)
+       return ASN1_DER_ERROR;
+      counter += len2;
+      len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
+      if (len2 < -1)
+       return ASN1_DER_ERROR;
+      if (len2 == -1)
+       {
+         indefinite++;
+         counter += 1;
+       }
+      else
+       {
+         counter += len2 + len3;
+       }
     }
-  }
 
-  *len=counter;
+  *len = counter;
   return ASN1_SUCCESS;
 
 }
@@ -634,416 +750,541 @@ _asn1_get_indefinite_length_string(const unsigned char* der, int* len)
   **/
 
 asn1_retCode
-asn1_der_decoding(ASN1_TYPE *element,const void *ider,int len,
-                 char *errorDescription)
+asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
+                  char *errorDescription)
 {
-  node_asn *node,*p,*p2,*p3;
+  node_asn *node, *p, *p2, *p3;
   char temp[128];
-  int counter,len2,len3,len4,move,ris,tlen;
-  unsigned char class,*temp2;
+  int counter, len2, len3, len4, move, ris, tlen;
+  unsigned char class, *temp2;
   unsigned long tag;
   int indefinite, result;
-  const unsigned charder = ider;
+  const unsigned char *der = ider;
 
-  node=*element;
+  node = *element;
 
-  if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
+  if (node == ASN1_TYPE_EMPTY)
+    return ASN1_ELEMENT_NOT_FOUND;
 
-  if(node->type&CONST_OPTION){
-    asn1_delete_structure(element);
-    return ASN1_GENERIC_ERROR;
-  }
-
-  counter=0;
-  move=DOWN;
-  p=node;
-  while(1){
-    ris=ASN1_SUCCESS;
-    if(move!=UP){
-      if(p->type&CONST_SET){
-       p2=_asn1_find_up(p);
-       len2=strtol(p2->value,NULL,10);
-       if(len2==-1){
-         if(!der[counter] && !der[counter+1]){
-           p=p2;
-           move=UP;
-           counter+=2;
-           continue;
-         }
-       }
-       else if(counter==len2){
-         p=p2;
-         move=UP;
-         continue;
-       }
-       else if(counter>len2){
-         asn1_delete_structure(element);
-         return ASN1_DER_ERROR;
-       }
-       p2=p2->down;
-       while(p2){
-         if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
-           if(type_field(p2->type)!=TYPE_CHOICE)
-             ris=_asn1_extract_tag_der(p2,der+counter,len-counter, &len2);
-           else{
-             p3=p2->down;
-             while(p3){
-               ris=_asn1_extract_tag_der(p3,der+counter,len-counter, &len2);
-               if(ris==ASN1_SUCCESS) break;
-               p3=p3->right;
-             }
-           }
-           if(ris==ASN1_SUCCESS){
-             p2->type&=~CONST_NOT_USED;
-             p=p2;
-             break;
-           }
-         }
-         p2=p2->right;
-       }
-       if(p2==NULL){
-         asn1_delete_structure(element);
-         return ASN1_DER_ERROR;
-       }
-      }
+  if (node->type & CONST_OPTION)
+    {
+      asn1_delete_structure (element);
+      return ASN1_GENERIC_ERROR;
+    }
 
-      if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
-       p2=_asn1_find_up(p);
-       len2=strtol(p2->value,NULL,10);
-       if(counter==len2){
-         if(p->right){
-           p2=p->right;
-           move=RIGHT;
-         }
-         else move=UP;
+  counter = 0;
+  move = DOWN;
+  p = node;
+  while (1)
+    {
+      ris = ASN1_SUCCESS;
+      if (move != UP)
+       {
+         if (p->type & CONST_SET)
+           {
+             p2 = _asn1_find_up (p);
+             len2 = strtol (p2->value, NULL, 10);
+             if (len2 == -1)
+               {
+                 if (!der[counter] && !der[counter + 1])
+                   {
+                     p = p2;
+                     move = UP;
+                     counter += 2;
+                     continue;
+                   }
+               }
+             else if (counter == len2)
+               {
+                 p = p2;
+                 move = UP;
+                 continue;
+               }
+             else if (counter > len2)
+               {
+                 asn1_delete_structure (element);
+                 return ASN1_DER_ERROR;
+               }
+             p2 = p2->down;
+             while (p2)
+               {
+                 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
+                   {
+                     if (type_field (p2->type) != TYPE_CHOICE)
+                       ris =
+                         _asn1_extract_tag_der (p2, der + counter,
+                                                len - counter, &len2);
+                     else
+                       {
+                         p3 = p2->down;
+                         while (p3)
+                           {
+                             ris =
+                               _asn1_extract_tag_der (p3, der + counter,
+                                                      len - counter, &len2);
+                             if (ris == ASN1_SUCCESS)
+                               break;
+                             p3 = p3->right;
+                           }
+                       }
+                     if (ris == ASN1_SUCCESS)
+                       {
+                         p2->type &= ~CONST_NOT_USED;
+                         p = p2;
+                         break;
+                       }
+                   }
+                 p2 = p2->right;
+               }
+             if (p2 == NULL)
+               {
+                 asn1_delete_structure (element);
+                 return ASN1_DER_ERROR;
+               }
+           }
 
-         if(p->type&CONST_OPTION) asn1_delete_structure(&p);
+         if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
+           {
+             p2 = _asn1_find_up (p);
+             len2 = strtol (p2->value, NULL, 10);
+             if (counter == len2)
+               {
+                 if (p->right)
+                   {
+                     p2 = p->right;
+                     move = RIGHT;
+                   }
+                 else
+                   move = UP;
 
-         p=p2;
-         continue;
-       }
-      }
+                 if (p->type & CONST_OPTION)
+                   asn1_delete_structure (&p);
 
-      if(type_field(p->type)==TYPE_CHOICE){
-       while(p->down){
-         if(counter<len)
-           ris=_asn1_extract_tag_der(p->down,der+counter,len-counter,&len2);
-         else
-           ris=ASN1_DER_ERROR;
-         if(ris==ASN1_SUCCESS){
-           while(p->down->right){
-             p2=p->down->right;
-             asn1_delete_structure(&p2);
+                 p = p2;
+                 continue;
+               }
            }
-           break;
-         }
-         else if(ris==ASN1_ERROR_TYPE_ANY){
-           asn1_delete_structure(element);
-           return ASN1_ERROR_TYPE_ANY;
-         }
-         else{
-           p2=p->down;
-           asn1_delete_structure(&p2);
-         }
-       }
-
-        if(p->down==NULL){
-         if(!(p->type&CONST_OPTION)){
-           asn1_delete_structure(element);
-           return ASN1_DER_ERROR;
-         }
-       }
-       else
-         p=p->down;
-      }
 
-      if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
-       p2=_asn1_find_up(p);
-       len2=strtol(p2->value,NULL,10);
-       if((len2!=-1) && (counter>len2)) ris=ASN1_TAG_ERROR;
-      }
-     
-      if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
-      if(ris!=ASN1_SUCCESS){
-       if(p->type&CONST_OPTION){
-         p->type|=CONST_NOT_USED;
-         move=RIGHT;
-       }
-       else if(p->type&CONST_DEFAULT) {
-         _asn1_set_value(p,NULL,0);
-         move=RIGHT;
-       }
-       else {
-         if (errorDescription!=NULL)
-           _asn1_error_description_tag_error(p,errorDescription);
-         
-         asn1_delete_structure(element);
-         return ASN1_TAG_ERROR;
-       }
-      } 
-      else counter+=len2;
-    }
+         if (type_field (p->type) == TYPE_CHOICE)
+           {
+             while (p->down)
+               {
+                 if (counter < len)
+                   ris =
+                     _asn1_extract_tag_der (p->down, der + counter,
+                                            len - counter, &len2);
+                 else
+                   ris = ASN1_DER_ERROR;
+                 if (ris == ASN1_SUCCESS)
+                   {
+                     while (p->down->right)
+                       {
+                         p2 = p->down->right;
+                         asn1_delete_structure (&p2);
+                       }
+                     break;
+                   }
+                 else if (ris == ASN1_ERROR_TYPE_ANY)
+                   {
+                     asn1_delete_structure (element);
+                     return ASN1_ERROR_TYPE_ANY;
+                   }
+                 else
+                   {
+                     p2 = p->down;
+                     asn1_delete_structure (&p2);
+                   }
+               }
 
-    if(ris==ASN1_SUCCESS){
-      switch(type_field(p->type)){
-      case TYPE_NULL:
-       if(der[counter]){
-         asn1_delete_structure(element);
-         return ASN1_DER_ERROR;
-       }
-       counter++;
-       move=RIGHT;
-       break;
-      case TYPE_BOOLEAN:
-       if(der[counter++]!=1){
-         asn1_delete_structure(element);
-         return ASN1_DER_ERROR;
-       }
-       if(der[counter++]==0) _asn1_set_value(p,"F",1);
-       else _asn1_set_value(p,"T",1);
-       move=RIGHT;
-       break;
-      case TYPE_INTEGER: case TYPE_ENUMERATED:
-       len2=asn1_get_length_der(der+counter,len-counter, &len3);
-       if(len2 < 0) return ASN1_DER_ERROR;
-       if (len2+len3 > len-counter) return ASN1_DER_ERROR;
-       _asn1_set_value(p,der+counter,len3+len2);
-       counter+=len3+len2;
-       move=RIGHT;
-       break;
-      case TYPE_OBJECT_ID:
-       _asn1_get_objectid_der(der+counter,len-counter,&len2, temp, sizeof(temp));
-       tlen = strlen(temp);
-       if( tlen > 0)
-          _asn1_set_value(p,temp,tlen+1);
-       counter+=len2;
-       move=RIGHT;
-      break;
-      case TYPE_TIME:
-       result = _asn1_get_time_der(der+counter,len-counter,&len2,temp,sizeof(temp)-1);
-       if (result != ASN1_SUCCESS) {
-               asn1_delete_structure(element);
-               return result;
-       }
-       tlen = strlen(temp);
-       if (tlen > 0)
-          _asn1_set_value(p,temp,tlen+1);
-       counter+=len2;
-       move=RIGHT;
-       break;
-      case TYPE_OCTET_STRING:
-       len3=len-counter;
-       ris=_asn1_get_octet_string(der+counter,p,&len3);
-       if(ris != ASN1_SUCCESS) return ris; 
-       counter+=len3;
-       move=RIGHT;
-       break;
-      case TYPE_GENERALSTRING:
-       len2=asn1_get_length_der(der+counter,len-counter,&len3);
-       if(len2 < 0) return ASN1_DER_ERROR;
-       if (len3+len2 > len-counter) return ASN1_DER_ERROR;
-          _asn1_set_value(p,der+counter,len3+len2);
-       counter+=len3+len2;
-       move=RIGHT;
-       break;
-      case TYPE_BIT_STRING:
-       len2=asn1_get_length_der(der+counter,len-counter,&len3);
-       if(len2 < 0) return ASN1_DER_ERROR;
-       if (len3+len2 > len-counter) return ASN1_DER_ERROR;
-          _asn1_set_value(p,der+counter,len3+len2);
-       counter+=len3+len2;
-       move=RIGHT;
-       break;
-      case TYPE_SEQUENCE:  case TYPE_SET:
-       if(move==UP){
-         len2=strtol(p->value,NULL,10);
-         _asn1_set_value(p,NULL,0);
-         if(len2==-1){ /* indefinite length method */
-           if (len-counter+1 > 0) {
-             if((der[counter]) || der[counter+1]){
-               asn1_delete_structure(element);
-               return ASN1_DER_ERROR;
-             }
-            } else return ASN1_DER_ERROR;
-           counter+=2;
-         }
-         else{ /* definite length method */
-           if(len2!=counter){
-             asn1_delete_structure(element);
-             return ASN1_DER_ERROR;
-           }
-         }
-         move=RIGHT;
-       }
-       else{   /* move==DOWN || move==RIGHT */
-         len3=asn1_get_length_der(der+counter,len-counter,&len2);
-         if(len3 < -1) return ASN1_DER_ERROR;
-         counter+=len2;
-         if(len3>0){
-           _asn1_ltostr(counter+len3,temp);
-           tlen = strlen(temp);
-           if (tlen > 0)
-              _asn1_set_value(p,temp,tlen+1);
-           move=DOWN; 
-         }
-         else if(len3==0){
-           p2=p->down;
-           while(p2){
-             if(type_field(p2->type)!=TYPE_TAG){
-               p3=p2->right;
-               asn1_delete_structure(&p2);
-               p2=p3;
-             }
+             if (p->down == NULL)
+               {
+                 if (!(p->type & CONST_OPTION))
+                   {
+                     asn1_delete_structure (element);
+                     return ASN1_DER_ERROR;
+                   }
+               }
              else
-               p2=p2->right;
-           }
-           move=RIGHT;
-         }
-         else{ /* indefinite length method */
-           _asn1_set_value(p,"-1",3);
-           move=DOWN; 
-         }
-       }
-       break;
-      case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
-       if(move==UP){
-         len2=strtol(p->value,NULL,10);
-         if(len2==-1){ /* indefinite length method */
-           if((counter+2)>len) return ASN1_DER_ERROR;
-           if((der[counter]) || der[counter+1]){
-             _asn1_append_sequence_set(p);
-             p=p->down;
-             while(p->right) p=p->right;
-             move=RIGHT;
-             continue;
-           }
-           _asn1_set_value(p,NULL,0);
-           counter+=2;
-         }
-         else{ /* definite length method */
-           if(len2>counter){
-             _asn1_append_sequence_set(p);
-             p=p->down;
-             while(p->right) p=p->right;
-             move=RIGHT;
-             continue;
+               p = p->down;
            }
-           _asn1_set_value(p,NULL,0);
-           if(len2!=counter){
-             asn1_delete_structure(element);
-             return ASN1_DER_ERROR;
-           }
-         }
-       }
-       else{   /* move==DOWN || move==RIGHT */
-         len3=asn1_get_length_der(der+counter,len-counter,&len2);
-         if(len3 < -1) return ASN1_DER_ERROR;
-         counter+=len2;
-         if(len3){
-           if(len3>0){ /* definite length method */
-           _asn1_ltostr(counter+len3,temp);
-           tlen = strlen(temp);
-           
-           if (tlen > 0)
-              _asn1_set_value(p,temp,tlen+1);
+
+         if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
+           {
+             p2 = _asn1_find_up (p);
+             len2 = strtol (p2->value, NULL, 10);
+             if ((len2 != -1) && (counter > len2))
+               ris = ASN1_TAG_ERROR;
            }
-           else { /* indefinite length method */
-             _asn1_set_value(p,"-1",3);              
+
+         if (ris == ASN1_SUCCESS)
+           ris =
+             _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
+         if (ris != ASN1_SUCCESS)
+           {
+             if (p->type & CONST_OPTION)
+               {
+                 p->type |= CONST_NOT_USED;
+                 move = RIGHT;
+               }
+             else if (p->type & CONST_DEFAULT)
+               {
+                 _asn1_set_value (p, NULL, 0);
+                 move = RIGHT;
+               }
+             else
+               {
+                 if (errorDescription != NULL)
+                   _asn1_error_description_tag_error (p, errorDescription);
+
+                 asn1_delete_structure (element);
+                 return ASN1_TAG_ERROR;
+               }
            }
-           p2=p->down;
-           while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
-           if(p2->right==NULL) _asn1_append_sequence_set(p);
-           p=p2;
-         }
-       }
-       move=RIGHT;
-       break;
-      case TYPE_ANY:
-       if(asn1_get_tag_der(der+counter,len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
-       return ASN1_DER_ERROR;
-       if (counter+len2 > len)
-         return ASN1_DER_ERROR;
-       len4=asn1_get_length_der(der+counter+len2,len-counter-len2,&len3);
-       if(len4 < -1) return ASN1_DER_ERROR;
-       if(len4 > len-counter+len2+len3) return ASN1_DER_ERROR;
-       if(len4 != -1){
-         len2+=len4;
-         asn1_length_der(len2+len3,NULL,&len4);
-         temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
-         if (temp2==NULL){
-           asn1_delete_structure(element);
-           return ASN1_MEM_ALLOC_ERROR;
-         }
-        
-         asn1_octet_der(der+counter,len2+len3,temp2,&len4);
-         _asn1_set_value(p,temp2,len4);
-         _asn1_afree(temp2);
-         counter+=len2+len3;
-       }
-       else{ /* indefinite length */
-         /* Check indefinite lenth method in an EXPLICIT TAG */
-         if((p->type&CONST_TAG) && (der[counter-1]==0x80))
-           indefinite=1;
          else
-           indefinite=0;
-
-         len2=len-counter;
-         ris=_asn1_get_indefinite_length_string(der+counter,&len2);
-         if(ris != ASN1_SUCCESS){
-           asn1_delete_structure(element);
-           return ris;
-         }
-         asn1_length_der(len2,NULL,&len4);
-         temp2=(unsigned char *)_asn1_alloca(len2+len4);
-         if (temp2==NULL){
-           asn1_delete_structure(element);
-           return ASN1_MEM_ALLOC_ERROR;
-         }
-        
-         asn1_octet_der(der+counter,len2,temp2,&len4);
-         _asn1_set_value(p,temp2,len4);
-         _asn1_afree(temp2);
-         counter+=len2;
-
-         /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
-            an indefinite length method. */
-         if(indefinite){
-           if(!der[counter] && !der[counter+1]){ 
-             counter+=2;
-           }
-           else{
-             asn1_delete_structure(element);
-             return ASN1_DER_ERROR;
-           }
-         }
-       }
-       move=RIGHT;
-       break;
-      default:
-       move=(move==UP)?RIGHT:DOWN;
-       break;
-      }
-    }
+           counter += len2;
+       }
+
+      if (ris == ASN1_SUCCESS)
+       {
+         switch (type_field (p->type))
+           {
+           case TYPE_NULL:
+             if (der[counter])
+               {
+                 asn1_delete_structure (element);
+                 return ASN1_DER_ERROR;
+               }
+             counter++;
+             move = RIGHT;
+             break;
+           case TYPE_BOOLEAN:
+             if (der[counter++] != 1)
+               {
+                 asn1_delete_structure (element);
+                 return ASN1_DER_ERROR;
+               }
+             if (der[counter++] == 0)
+               _asn1_set_value (p, "F", 1);
+             else
+               _asn1_set_value (p, "T", 1);
+             move = RIGHT;
+             break;
+           case TYPE_INTEGER:
+           case TYPE_ENUMERATED:
+             len2 =
+               asn1_get_length_der (der + counter, len - counter, &len3);
+             if (len2 < 0)
+               return ASN1_DER_ERROR;
+             if (len2 + len3 > len - counter)
+               return ASN1_DER_ERROR;
+             _asn1_set_value (p, der + counter, len3 + len2);
+             counter += len3 + len2;
+             move = RIGHT;
+             break;
+           case TYPE_OBJECT_ID:
+             _asn1_get_objectid_der (der + counter, len - counter, &len2,
+                                     temp, sizeof (temp));
+             tlen = strlen (temp);
+             if (tlen > 0)
+               _asn1_set_value (p, temp, tlen + 1);
+             counter += len2;
+             move = RIGHT;
+             break;
+           case TYPE_TIME:
+             result =
+               _asn1_get_time_der (der + counter, len - counter, &len2, temp,
+                                   sizeof (temp) - 1);
+             if (result != ASN1_SUCCESS)
+               {
+                 asn1_delete_structure (element);
+                 return result;
+               }
+             tlen = strlen (temp);
+             if (tlen > 0)
+               _asn1_set_value (p, temp, tlen + 1);
+             counter += len2;
+             move = RIGHT;
+             break;
+           case TYPE_OCTET_STRING:
+             len3 = len - counter;
+             ris = _asn1_get_octet_string (der + counter, p, &len3);
+             if (ris != ASN1_SUCCESS)
+               return ris;
+             counter += len3;
+             move = RIGHT;
+             break;
+           case TYPE_GENERALSTRING:
+             len2 =
+               asn1_get_length_der (der + counter, len - counter, &len3);
+             if (len2 < 0)
+               return ASN1_DER_ERROR;
+             if (len3 + len2 > len - counter)
+               return ASN1_DER_ERROR;
+             _asn1_set_value (p, der + counter, len3 + len2);
+             counter += len3 + len2;
+             move = RIGHT;
+             break;
+           case TYPE_BIT_STRING:
+             len2 =
+               asn1_get_length_der (der + counter, len - counter, &len3);
+             if (len2 < 0)
+               return ASN1_DER_ERROR;
+             if (len3 + len2 > len - counter)
+               return ASN1_DER_ERROR;
+             _asn1_set_value (p, der + counter, len3 + len2);
+             counter += len3 + len2;
+             move = RIGHT;
+             break;
+           case TYPE_SEQUENCE:
+           case TYPE_SET:
+             if (move == UP)
+               {
+                 len2 = strtol (p->value, NULL, 10);
+                 _asn1_set_value (p, NULL, 0);
+                 if (len2 == -1)
+                   {           /* indefinite length method */
+                     if (len - counter + 1 > 0)
+                       {
+                         if ((der[counter]) || der[counter + 1])
+                           {
+                             asn1_delete_structure (element);
+                             return ASN1_DER_ERROR;
+                           }
+                       }
+                     else
+                       return ASN1_DER_ERROR;
+                     counter += 2;
+                   }
+                 else
+                   {           /* definite length method */
+                     if (len2 != counter)
+                       {
+                         asn1_delete_structure (element);
+                         return ASN1_DER_ERROR;
+                       }
+                   }
+                 move = RIGHT;
+               }
+             else
+               {               /* move==DOWN || move==RIGHT */
+                 len3 =
+                   asn1_get_length_der (der + counter, len - counter, &len2);
+                 if (len3 < -1)
+                   return ASN1_DER_ERROR;
+                 counter += len2;
+                 if (len3 > 0)
+                   {
+                     _asn1_ltostr (counter + len3, temp);
+                     tlen = strlen (temp);
+                     if (tlen > 0)
+                       _asn1_set_value (p, temp, tlen + 1);
+                     move = DOWN;
+                   }
+                 else if (len3 == 0)
+                   {
+                     p2 = p->down;
+                     while (p2)
+                       {
+                         if (type_field (p2->type) != TYPE_TAG)
+                           {
+                             p3 = p2->right;
+                             asn1_delete_structure (&p2);
+                             p2 = p3;
+                           }
+                         else
+                           p2 = p2->right;
+                       }
+                     move = RIGHT;
+                   }
+                 else
+                   {           /* indefinite length method */
+                     _asn1_set_value (p, "-1", 3);
+                     move = DOWN;
+                   }
+               }
+             break;
+           case TYPE_SEQUENCE_OF:
+           case TYPE_SET_OF:
+             if (move == UP)
+               {
+                 len2 = strtol (p->value, NULL, 10);
+                 if (len2 == -1)
+                   {           /* indefinite length method */
+                     if ((counter + 2) > len)
+                       return ASN1_DER_ERROR;
+                     if ((der[counter]) || der[counter + 1])
+                       {
+                         _asn1_append_sequence_set (p);
+                         p = p->down;
+                         while (p->right)
+                           p = p->right;
+                         move = RIGHT;
+                         continue;
+                       }
+                     _asn1_set_value (p, NULL, 0);
+                     counter += 2;
+                   }
+                 else
+                   {           /* definite length method */
+                     if (len2 > counter)
+                       {
+                         _asn1_append_sequence_set (p);
+                         p = p->down;
+                         while (p->right)
+                           p = p->right;
+                         move = RIGHT;
+                         continue;
+                       }
+                     _asn1_set_value (p, NULL, 0);
+                     if (len2 != counter)
+                       {
+                         asn1_delete_structure (element);
+                         return ASN1_DER_ERROR;
+                       }
+                   }
+               }
+             else
+               {               /* move==DOWN || move==RIGHT */
+                 len3 =
+                   asn1_get_length_der (der + counter, len - counter, &len2);
+                 if (len3 < -1)
+                   return ASN1_DER_ERROR;
+                 counter += len2;
+                 if (len3)
+                   {
+                     if (len3 > 0)
+                       {       /* definite length method */
+                         _asn1_ltostr (counter + len3, temp);
+                         tlen = strlen (temp);
+
+                         if (tlen > 0)
+                           _asn1_set_value (p, temp, tlen + 1);
+                       }
+                     else
+                       {       /* indefinite length method */
+                         _asn1_set_value (p, "-1", 3);
+                       }
+                     p2 = p->down;
+                     while ((type_field (p2->type) == TYPE_TAG)
+                            || (type_field (p2->type) == TYPE_SIZE))
+                       p2 = p2->right;
+                     if (p2->right == NULL)
+                       _asn1_append_sequence_set (p);
+                     p = p2;
+                   }
+               }
+             move = RIGHT;
+             break;
+           case TYPE_ANY:
+             if (asn1_get_tag_der
+                 (der + counter, len - counter, &class, &len2,
+                  &tag) != ASN1_SUCCESS)
+               return ASN1_DER_ERROR;
+             if (counter + len2 > len)
+               return ASN1_DER_ERROR;
+             len4 =
+               asn1_get_length_der (der + counter + len2,
+                                    len - counter - len2, &len3);
+             if (len4 < -1)
+               return ASN1_DER_ERROR;
+             if (len4 > len - counter + len2 + len3)
+               return ASN1_DER_ERROR;
+             if (len4 != -1)
+               {
+                 len2 += len4;
+                 asn1_length_der (len2 + len3, NULL, &len4);
+                 temp2 = (unsigned char *) _asn1_alloca (len2 + len3 + len4);
+                 if (temp2 == NULL)
+                   {
+                     asn1_delete_structure (element);
+                     return ASN1_MEM_ALLOC_ERROR;
+                   }
+
+                 asn1_octet_der (der + counter, len2 + len3, temp2, &len4);
+                 _asn1_set_value (p, temp2, len4);
+                 _asn1_afree (temp2);
+                 counter += len2 + len3;
+               }
+             else
+               {               /* indefinite length */
+                 /* Check indefinite lenth method in an EXPLICIT TAG */
+                 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
+                   indefinite = 1;
+                 else
+                   indefinite = 0;
+
+                 len2 = len - counter;
+                 ris =
+                   _asn1_get_indefinite_length_string (der + counter, &len2);
+                 if (ris != ASN1_SUCCESS)
+                   {
+                     asn1_delete_structure (element);
+                     return ris;
+                   }
+                 asn1_length_der (len2, NULL, &len4);
+                 temp2 = (unsigned char *) _asn1_alloca (len2 + len4);
+                 if (temp2 == NULL)
+                   {
+                     asn1_delete_structure (element);
+                     return ASN1_MEM_ALLOC_ERROR;
+                   }
+
+                 asn1_octet_der (der + counter, len2, temp2, &len4);
+                 _asn1_set_value (p, temp2, len4);
+                 _asn1_afree (temp2);
+                 counter += len2;
+
+                 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
+                    an indefinite length method. */
+                 if (indefinite)
+                   {
+                     if (!der[counter] && !der[counter + 1])
+                       {
+                         counter += 2;
+                       }
+                     else
+                       {
+                         asn1_delete_structure (element);
+                         return ASN1_DER_ERROR;
+                       }
+                   }
+               }
+             move = RIGHT;
+             break;
+           default:
+             move = (move == UP) ? RIGHT : DOWN;
+             break;
+           }
+       }
 
-    if(p==node && move!=DOWN) break;
+      if (p == node && move != DOWN)
+       break;
 
-    if(move==DOWN){
-      if(p->down) p=p->down;
-      else move=RIGHT;
-    }
-    if((move==RIGHT) && !(p->type&CONST_SET)){
-      if(p->right) p=p->right;
-      else move=UP;
+      if (move == DOWN)
+       {
+         if (p->down)
+           p = p->down;
+         else
+           move = RIGHT;
+       }
+      if ((move == RIGHT) && !(p->type & CONST_SET))
+       {
+         if (p->right)
+           p = p->right;
+         else
+           move = UP;
+       }
+      if (move == UP)
+       p = _asn1_find_up (p);
     }
-    if(move==UP) p=_asn1_find_up(p);
-  }
 
-  _asn1_delete_not_used(*element);
+  _asn1_delete_not_used (*element);
 
-  if(counter != len){
-    asn1_delete_structure(element);
-    return ASN1_DER_ERROR;
-  }
+  if (counter != len)
+    {
+      asn1_delete_structure (element);
+      return ASN1_DER_ERROR;
+    }
 
   return ASN1_SUCCESS;
 }
@@ -1082,582 +1323,761 @@ asn1_der_decoding(ASN1_TYPE *element,const void *ider,int len,
   *
   **/
 asn1_retCode
-asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName,
-                         const void *ider,int len,char *errorDescription)
+asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
+                          const void *ider, int len, char *errorDescription)
 {
-  node_asn *node,*p,*p2,*p3,*nodeFound=ASN1_TYPE_EMPTY;
-  char temp[128],currentName[MAX_NAME_SIZE*10],*dot_p,*char_p;
-  int nameLen=MAX_NAME_SIZE*10-1,state;
-  int counter,len2,len3,len4,move,ris, tlen;
-  unsigned char class,*temp2;
+  node_asn *node, *p, *p2, *p3, *nodeFound = ASN1_TYPE_EMPTY;
+  char temp[128], currentName[MAX_NAME_SIZE * 10], *dot_p, *char_p;
+  int nameLen = MAX_NAME_SIZE * 10 - 1, state;
+  int counter, len2, len3, len4, move, ris, tlen;
+  unsigned char class, *temp2;
   unsigned long tag;
   int indefinite, result;
-  const unsigned char* der = ider;
-
-  node=*structure;
+  const unsigned char *der = ider;
 
-  if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
+  node = *structure;
 
-  if(elementName == NULL){
-    asn1_delete_structure(structure);    
+  if (node == ASN1_TYPE_EMPTY)
     return ASN1_ELEMENT_NOT_FOUND;
-  }
-
-  if(node->type&CONST_OPTION){
-    asn1_delete_structure(structure);
-    return ASN1_GENERIC_ERROR;
-  }
 
-  if((*structure)->name){  /* Has *structure got a name? */
-    nameLen-=strlen((*structure)->name);
-    if(nameLen>0) strcpy(currentName,(*structure)->name);
-    else{
-      asn1_delete_structure(structure);
-      return ASN1_MEM_ERROR;
-    }
-    if(!(strcmp(currentName,elementName))){ 
-      state=FOUND;
-      nodeFound=*structure;
+  if (elementName == NULL)
+    {
+      asn1_delete_structure (structure);
+      return ASN1_ELEMENT_NOT_FOUND;
     }
-    else if(!memcmp(currentName,elementName,strlen(currentName))) 
-      state=SAME_BRANCH;
-    else 
-      state=OTHER_BRANCH;
-  }
-  else{  /* *structure doesn't have a name? */
-    currentName[0]=0;
-    if(elementName[0]==0){
-      state=FOUND;
-      nodeFound=*structure;
+
+  if (node->type & CONST_OPTION)
+    {
+      asn1_delete_structure (structure);
+      return ASN1_GENERIC_ERROR;
     }
-    else{
-      state=SAME_BRANCH;
+
+  if ((*structure)->name)
+    {                          /* Has *structure got a name? */
+      nameLen -= strlen ((*structure)->name);
+      if (nameLen > 0)
+       strcpy (currentName, (*structure)->name);
+      else
+       {
+         asn1_delete_structure (structure);
+         return ASN1_MEM_ERROR;
+       }
+      if (!(strcmp (currentName, elementName)))
+       {
+         state = FOUND;
+         nodeFound = *structure;
+       }
+      else if (!memcmp (currentName, elementName, strlen (currentName)))
+       state = SAME_BRANCH;
+      else
+       state = OTHER_BRANCH;
     }
-  }
-
-  counter=0;
-  move=DOWN;
-  p=node;
-  while(1){
-
-    ris=ASN1_SUCCESS;
-
-    if(move!=UP){
-      if(p->type&CONST_SET){
-       p2=_asn1_find_up(p);
-       len2=strtol(p2->value,NULL,10);
-       if(counter==len2){
-         p=p2;
-         move=UP;
-         continue;
+  else
+    {                          /* *structure doesn't have a name? */
+      currentName[0] = 0;
+      if (elementName[0] == 0)
+       {
+         state = FOUND;
+         nodeFound = *structure;
        }
-       else if(counter>len2){
-         asn1_delete_structure(structure);
-         return ASN1_DER_ERROR;
+      else
+       {
+         state = SAME_BRANCH;
        }
-       p2=p2->down;
-       while(p2){
-         if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
-           if(type_field(p2->type)!=TYPE_CHOICE)
-             ris=_asn1_extract_tag_der(p2,der+counter,len-counter,&len2);
-           else{
-             p3=p2->down;
-             while(p3){
-               ris=_asn1_extract_tag_der(p3,der+counter,len-counter,&len2);
-               if(ris==ASN1_SUCCESS) break;
-               p3=p3->right;
-             }
+    }
+
+  counter = 0;
+  move = DOWN;
+  p = node;
+  while (1)
+    {
+
+      ris = ASN1_SUCCESS;
+
+      if (move != UP)
+       {
+         if (p->type & CONST_SET)
+           {
+             p2 = _asn1_find_up (p);
+             len2 = strtol (p2->value, NULL, 10);
+             if (counter == len2)
+               {
+                 p = p2;
+                 move = UP;
+                 continue;
+               }
+             else if (counter > len2)
+               {
+                 asn1_delete_structure (structure);
+                 return ASN1_DER_ERROR;
+               }
+             p2 = p2->down;
+             while (p2)
+               {
+                 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
+                   {
+                     if (type_field (p2->type) != TYPE_CHOICE)
+                       ris =
+                         _asn1_extract_tag_der (p2, der + counter,
+                                                len - counter, &len2);
+                     else
+                       {
+                         p3 = p2->down;
+                         while (p3)
+                           {
+                             ris =
+                               _asn1_extract_tag_der (p3, der + counter,
+                                                      len - counter, &len2);
+                             if (ris == ASN1_SUCCESS)
+                               break;
+                             p3 = p3->right;
+                           }
+                       }
+                     if (ris == ASN1_SUCCESS)
+                       {
+                         p2->type &= ~CONST_NOT_USED;
+                         p = p2;
+                         break;
+                       }
+                   }
+                 p2 = p2->right;
+               }
+             if (p2 == NULL)
+               {
+                 asn1_delete_structure (structure);
+                 return ASN1_DER_ERROR;
+               }
            }
-           if(ris==ASN1_SUCCESS){
-             p2->type&=~CONST_NOT_USED;
-             p=p2;
-             break;
+
+         if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
+           {
+             p2 = _asn1_find_up (p);
+             len2 = strtol (p2->value, NULL, 10);
+             if (counter == len2)
+               {
+                 if (p->right)
+                   {
+                     p2 = p->right;
+                     move = RIGHT;
+                   }
+                 else
+                   move = UP;
+
+                 if (p->type & CONST_OPTION)
+                   asn1_delete_structure (&p);
+
+                 p = p2;
+                 continue;
+               }
            }
-         }
-         p2=p2->right;
-       }
-       if(p2==NULL){
-         asn1_delete_structure(structure);
-         return ASN1_DER_ERROR;
-       }
-      }
 
-      if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
-       p2=_asn1_find_up(p);
-       len2=strtol(p2->value,NULL,10);
-       if(counter==len2){
-         if(p->right){
-           p2=p->right;
-           move=RIGHT;
-         }
-         else move=UP;
+         if (type_field (p->type) == TYPE_CHOICE)
+           {
+             while (p->down)
+               {
+                 if (counter < len)
+                   ris =
+                     _asn1_extract_tag_der (p->down, der + counter,
+                                            len - counter, &len2);
+                 else
+                   ris = ASN1_DER_ERROR;
+                 if (ris == ASN1_SUCCESS)
+                   {
+                     while (p->down->right)
+                       {
+                         p2 = p->down->right;
+                         asn1_delete_structure (&p2);
+                       }
+                     break;
+                   }
+                 else if (ris == ASN1_ERROR_TYPE_ANY)
+                   {
+                     asn1_delete_structure (structure);
+                     return ASN1_ERROR_TYPE_ANY;
+                   }
+                 else
+                   {
+                     p2 = p->down;
+                     asn1_delete_structure (&p2);
+                   }
+               }
+
+             if (p->down == NULL)
+               {
+                 if (!(p->type & CONST_OPTION))
+                   {
+                     asn1_delete_structure (structure);
+                     return ASN1_DER_ERROR;
+                   }
+               }
+             else
+               p = p->down;
+           }
 
-         if(p->type&CONST_OPTION) asn1_delete_structure(&p);
+         if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
+           {
+             p2 = _asn1_find_up (p);
+             len2 = strtol (p2->value, NULL, 10);
+             if (counter > len2)
+               ris = ASN1_TAG_ERROR;
+           }
 
-         p=p2;
-         continue;
-       }
-      }
+         if (ris == ASN1_SUCCESS)
+           ris =
+             _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
+         if (ris != ASN1_SUCCESS)
+           {
+             if (p->type & CONST_OPTION)
+               {
+                 p->type |= CONST_NOT_USED;
+                 move = RIGHT;
+               }
+             else if (p->type & CONST_DEFAULT)
+               {
+                 _asn1_set_value (p, NULL, 0);
+                 move = RIGHT;
+               }
+             else
+               {
+                 if (errorDescription != NULL)
+                   _asn1_error_description_tag_error (p, errorDescription);
 
-      if(type_field(p->type)==TYPE_CHOICE){
-       while(p->down){
-         if(counter<len)
-           ris=_asn1_extract_tag_der(p->down,der+counter,len-counter,&len2);
-         else
-           ris=ASN1_DER_ERROR;
-         if(ris==ASN1_SUCCESS){
-           while(p->down->right){
-             p2=p->down->right;
-             asn1_delete_structure(&p2);
+                 asn1_delete_structure (structure);
+                 return ASN1_TAG_ERROR;
+               }
            }
-           break;
-         }
-         else if(ris==ASN1_ERROR_TYPE_ANY){
-           asn1_delete_structure(structure);
-           return ASN1_ERROR_TYPE_ANY;
-         }
-         else{
-           p2=p->down;
-           asn1_delete_structure(&p2);
-         }
-       }
+         else
+           counter += len2;
+       }
+
+      if (ris == ASN1_SUCCESS)
+       {
+         switch (type_field (p->type))
+           {
+           case TYPE_NULL:
+             if (der[counter])
+               {
+                 asn1_delete_structure (structure);
+                 return ASN1_DER_ERROR;
+               }
 
-       if(p->down==NULL){
-         if(!(p->type&CONST_OPTION)){
-           asn1_delete_structure(structure);
-           return ASN1_DER_ERROR;
-         }
-       }
-       else
-         p=p->down;
-      }
+             if (p == nodeFound)
+               state = EXIT;
 
-      if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
-       p2=_asn1_find_up(p);
-       len2=strtol(p2->value,NULL,10);
-       if(counter>len2) ris=ASN1_TAG_ERROR;
-      }
+             counter++;
+             move = RIGHT;
+             break;
+           case TYPE_BOOLEAN:
+             if (der[counter++] != 1)
+               {
+                 asn1_delete_structure (structure);
+                 return ASN1_DER_ERROR;
+               }
 
-      if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
-      if(ris!=ASN1_SUCCESS){
-       if(p->type&CONST_OPTION){
-         p->type|=CONST_NOT_USED;
-         move=RIGHT;
-       }
-       else if(p->type&CONST_DEFAULT) {
-         _asn1_set_value(p,NULL,0);
-         move=RIGHT;
-       }
-       else {
-         if (errorDescription!=NULL)
-           _asn1_error_description_tag_error(p,errorDescription);
-         
-         asn1_delete_structure(structure);
-         return ASN1_TAG_ERROR;
-       }
-      } 
-      else counter+=len2;
-    }
+             if (state == FOUND)
+               {
+                 if (der[counter++] == 0)
+                   _asn1_set_value (p, "F", 1);
+                 else
+                   _asn1_set_value (p, "T", 1);
 
-    if(ris==ASN1_SUCCESS){
-      switch(type_field(p->type)){
-      case TYPE_NULL:
-       if(der[counter]){
-         asn1_delete_structure(structure);
-         return ASN1_DER_ERROR;
-       }
-       
-       if(p==nodeFound) state=EXIT;
-        
-       counter++;
-       move=RIGHT;
-       break;
-      case TYPE_BOOLEAN:
-       if(der[counter++]!=1){
-         asn1_delete_structure(structure);
-         return ASN1_DER_ERROR;
-       }
+                 if (p == nodeFound)
+                   state = EXIT;
 
-       if(state==FOUND){
-         if(der[counter++]==0) _asn1_set_value(p,"F",1);
-         else _asn1_set_value(p,"T",1);
-        
-         if(p==nodeFound) state=EXIT;
+               }
+             else
+               counter++;
 
-       }
-       else
-         counter++;
+             move = RIGHT;
+             break;
+           case TYPE_INTEGER:
+           case TYPE_ENUMERATED:
+             len2 =
+               asn1_get_length_der (der + counter, len - counter, &len3);
+             if (len2 < 0)
+               return ASN1_DER_ERROR;
+             if (state == FOUND)
+               {
+                 if (len3 + len2 > len - counter)
+                   return ASN1_DER_ERROR;
+                 _asn1_set_value (p, der + counter, len3 + len2);
+
+                 if (p == nodeFound)
+                   state = EXIT;
+               }
+             counter += len3 + len2;
+             move = RIGHT;
+             break;
+           case TYPE_OBJECT_ID:
+             if (state == FOUND)
+               {
+                 _asn1_get_objectid_der (der + counter, len - counter, &len2,
+                                         temp, sizeof (temp));
+                 tlen = strlen (temp);
+
+                 if (tlen > 0)
+                   _asn1_set_value (p, temp, tlen + 1);
+
+                 if (p == nodeFound)
+                   state = EXIT;
+               }
+             else
+               {
+                 len2 =
+                   asn1_get_length_der (der + counter, len - counter, &len3);
+                 if (len2 < 0)
+                   return ASN1_DER_ERROR;
+                 len2 += len3;
+               }
 
-       move=RIGHT;
-       break;
-      case TYPE_INTEGER: case TYPE_ENUMERATED:
-       len2=asn1_get_length_der(der+counter,len-counter,&len3);
-       if(len2 < 0) return ASN1_DER_ERROR;
-       if(state==FOUND){
-         if (len3+len2 > len-counter) return ASN1_DER_ERROR;
-         _asn1_set_value(p,der+counter,len3+len2);
-         
-         if(p==nodeFound) state=EXIT;
-       }
-       counter+=len3+len2;
-       move=RIGHT;
-       break;
-      case TYPE_OBJECT_ID:
-       if(state==FOUND){
-         _asn1_get_objectid_der(der+counter,len-counter,&len2, temp, sizeof(temp));
-         tlen = strlen(temp);
-         
-         if (tlen > 0)
-            _asn1_set_value(p,temp,tlen+1);
-         
-         if(p==nodeFound) state=EXIT;
-       }
-       else{
-         len2=asn1_get_length_der(der+counter,len-counter,&len3);
-         if(len2 < 0) return ASN1_DER_ERROR;
-         len2+=len3;
-       }
+             counter += len2;
+             move = RIGHT;
+             break;
+           case TYPE_TIME:
+             if (state == FOUND)
+               {
+                 result =
+                   _asn1_get_time_der (der + counter, len - counter, &len2,
+                                       temp, sizeof (temp) - 1);
+                 if (result != ASN1_SUCCESS)
+                   {
+                     asn1_delete_structure (structure);
+                     return result;
+                   }
 
-       counter+=len2;
-       move=RIGHT;
-      break;
-      case TYPE_TIME:
-       if(state==FOUND){
-         result = _asn1_get_time_der(der+counter,len-counter,&len2,temp,sizeof(temp)-1);
-         if (result != ASN1_SUCCESS) {
-               asn1_delete_structure(structure);
-               return result;
-         }
-
-         tlen = strlen(temp);
-         if (tlen > 0)
-            _asn1_set_value(p,temp,tlen+1);
-         
-         if(p==nodeFound) state=EXIT;
-       }
-       else{
-         len2=asn1_get_length_der(der+counter,len-counter,&len3);
-         if(len2 < 0) return ASN1_DER_ERROR;
-         len2+=len3;
-       }
+                 tlen = strlen (temp);
+                 if (tlen > 0)
+                   _asn1_set_value (p, temp, tlen + 1);
 
-       counter+=len2;
-       move=RIGHT;
-       break;
-      case TYPE_OCTET_STRING:
-       len3=len-counter;
-       if(state==FOUND){
-         ris=_asn1_get_octet_string(der+counter,p,&len3);
-         if(p==nodeFound) state=EXIT;
-       }
-       else
-         ris=_asn1_get_octet_string(der+counter,NULL,&len3);
+                 if (p == nodeFound)
+                   state = EXIT;
+               }
+             else
+               {
+                 len2 =
+                   asn1_get_length_der (der + counter, len - counter, &len3);
+                 if (len2 < 0)
+                   return ASN1_DER_ERROR;
+                 len2 += len3;
+               }
 
-       if(ris != ASN1_SUCCESS) return ris; 
-       counter+=len3;
-       move=RIGHT;
-       break;
-      case TYPE_GENERALSTRING:
-       len2=asn1_get_length_der(der+counter,len-counter,&len3);
-       if(len2 < 0) return ASN1_DER_ERROR;
-       if(state==FOUND){
-         if (len3+len2 > len-counter) return ASN1_DER_ERROR;
-         _asn1_set_value(p,der+counter,len3+len2);
-        
-         if(p==nodeFound) state=EXIT;
-       }
-       counter+=len3+len2;
-       move=RIGHT;
-       break;
-      case TYPE_BIT_STRING:
-       len2=asn1_get_length_der(der+counter,len-counter,&len3);
-       if(len2 < 0) return ASN1_DER_ERROR;
-       if(state==FOUND){
-         if (len3+len2 > len-counter) return ASN1_DER_ERROR;
-         _asn1_set_value(p,der+counter,len3+len2);
-         
-         if(p==nodeFound) state=EXIT;
-       }
-       counter+=len3+len2;
-       move=RIGHT;
-       break;
-      case TYPE_SEQUENCE:  case TYPE_SET:
-       if(move==UP){
-         len2=strtol(p->value,NULL,10);
-         _asn1_set_value(p,NULL,0);
-         if(len2==-1){ /* indefinite length method */
-           if((der[counter]) || der[counter+1]){
-             asn1_delete_structure(structure);
-             return ASN1_DER_ERROR;
-           }
-           counter+=2;
-         }
-         else{ /* definite length method */
-           if(len2!=counter){
-             asn1_delete_structure(structure);
-             return ASN1_DER_ERROR;
-           }
-         }
-         if(p==nodeFound) state=EXIT;    
-         move=RIGHT;
-       }
-       else{   /* move==DOWN || move==RIGHT */
-         if(state==OTHER_BRANCH){
-           len3=asn1_get_length_der(der+counter,len-counter,&len2);
-           if(len3 < 0) return ASN1_DER_ERROR;
-           counter+=len2+len3;
-           move=RIGHT;
-         }
-         else { /*  state==SAME_BRANCH or state==FOUND */
-           len3=asn1_get_length_der(der+counter,len-counter,&len2);
-           if(len3 < 0) return ASN1_DER_ERROR;
-           counter+=len2;
-           if(len3>0){
-             _asn1_ltostr(counter+len3,temp);
-             tlen = strlen(temp);
-             
-             if(tlen > 0)
-                 _asn1_set_value(p,temp,tlen+1);
-             move=DOWN;
-           }
-           else if(len3==0){
-             p2=p->down;
-             while(p2){
-               if(type_field(p2->type)!=TYPE_TAG){
-                 p3=p2->right;
-                 asn1_delete_structure(&p2);
-               p2=p3;
-               }
-               else
-                 p2=p2->right;
-             }
-             move=RIGHT;
-           }
-           else{ /* indefinite length method */
-             _asn1_set_value(p,"-1",3);
-             move=DOWN;
-           } 
-         }
-       }
-       break;
-      case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
-       if(move==UP){
-         len2=strtol(p->value,NULL,10);
-         if(len2>counter){
-           _asn1_append_sequence_set(p);
-           p=p->down;
-           while(p->right) p=p->right;
-           move=RIGHT;
-           continue;
-         }
-         _asn1_set_value(p,NULL,0);
-         if(len2!=counter){
-           asn1_delete_structure(structure);
-           return ASN1_DER_ERROR;
-         }
+             counter += len2;
+             move = RIGHT;
+             break;
+           case TYPE_OCTET_STRING:
+             len3 = len - counter;
+             if (state == FOUND)
+               {
+                 ris = _asn1_get_octet_string (der + counter, p, &len3);
+                 if (p == nodeFound)
+                   state = EXIT;
+               }
+             else
+               ris = _asn1_get_octet_string (der + counter, NULL, &len3);
 
-         if(p==nodeFound) state=EXIT;
-       }
-       else{   /* move==DOWN || move==RIGHT */
-         if(state==OTHER_BRANCH){
-           len3=asn1_get_length_der(der+counter,len-counter,&len2);
-           if(len3 < 0) return ASN1_DER_ERROR;
-           counter+=len2+len3;
-           move=RIGHT;
-         }
-         else{ /* state==FOUND or state==SAME_BRANCH */
-           len3=asn1_get_length_der(der+counter,len-counter,&len2);
-           if(len3 < 0) return ASN1_DER_ERROR;
-           counter+=len2;
-           if(len3){
-             _asn1_ltostr(counter+len3,temp);
-             tlen = strlen(temp);
-             
-             if (tlen > 0)
-                 _asn1_set_value(p,temp,tlen+1);
-             p2=p->down;
-             while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
-             if(p2->right==NULL) _asn1_append_sequence_set(p);
-             p=p2;
-             state=FOUND;
+             if (ris != ASN1_SUCCESS)
+               return ris;
+             counter += len3;
+             move = RIGHT;
+             break;
+           case TYPE_GENERALSTRING:
+             len2 =
+               asn1_get_length_der (der + counter, len - counter, &len3);
+             if (len2 < 0)
+               return ASN1_DER_ERROR;
+             if (state == FOUND)
+               {
+                 if (len3 + len2 > len - counter)
+                   return ASN1_DER_ERROR;
+                 _asn1_set_value (p, der + counter, len3 + len2);
+
+                 if (p == nodeFound)
+                   state = EXIT;
+               }
+             counter += len3 + len2;
+             move = RIGHT;
+             break;
+           case TYPE_BIT_STRING:
+             len2 =
+               asn1_get_length_der (der + counter, len - counter, &len3);
+             if (len2 < 0)
+               return ASN1_DER_ERROR;
+             if (state == FOUND)
+               {
+                 if (len3 + len2 > len - counter)
+                   return ASN1_DER_ERROR;
+                 _asn1_set_value (p, der + counter, len3 + len2);
+
+                 if (p == nodeFound)
+                   state = EXIT;
+               }
+             counter += len3 + len2;
+             move = RIGHT;
+             break;
+           case TYPE_SEQUENCE:
+           case TYPE_SET:
+             if (move == UP)
+               {
+                 len2 = strtol (p->value, NULL, 10);
+                 _asn1_set_value (p, NULL, 0);
+                 if (len2 == -1)
+                   {           /* indefinite length method */
+                     if ((der[counter]) || der[counter + 1])
+                       {
+                         asn1_delete_structure (structure);
+                         return ASN1_DER_ERROR;
+                       }
+                     counter += 2;
+                   }
+                 else
+                   {           /* definite length method */
+                     if (len2 != counter)
+                       {
+                         asn1_delete_structure (structure);
+                         return ASN1_DER_ERROR;
+                       }
+                   }
+                 if (p == nodeFound)
+                   state = EXIT;
+                 move = RIGHT;
+               }
+             else
+               {               /* move==DOWN || move==RIGHT */
+                 if (state == OTHER_BRANCH)
+                   {
+                     len3 =
+                       asn1_get_length_der (der + counter, len - counter,
+                                            &len2);
+                     if (len3 < 0)
+                       return ASN1_DER_ERROR;
+                     counter += len2 + len3;
+                     move = RIGHT;
+                   }
+                 else
+                   {           /*  state==SAME_BRANCH or state==FOUND */
+                     len3 =
+                       asn1_get_length_der (der + counter, len - counter,
+                                            &len2);
+                     if (len3 < 0)
+                       return ASN1_DER_ERROR;
+                     counter += len2;
+                     if (len3 > 0)
+                       {
+                         _asn1_ltostr (counter + len3, temp);
+                         tlen = strlen (temp);
+
+                         if (tlen > 0)
+                           _asn1_set_value (p, temp, tlen + 1);
+                         move = DOWN;
+                       }
+                     else if (len3 == 0)
+                       {
+                         p2 = p->down;
+                         while (p2)
+                           {
+                             if (type_field (p2->type) != TYPE_TAG)
+                               {
+                                 p3 = p2->right;
+                                 asn1_delete_structure (&p2);
+                                 p2 = p3;
+                               }
+                             else
+                               p2 = p2->right;
+                           }
+                         move = RIGHT;
+                       }
+                     else
+                       {       /* indefinite length method */
+                         _asn1_set_value (p, "-1", 3);
+                         move = DOWN;
+                       }
+                   }
+               }
+             break;
+           case TYPE_SEQUENCE_OF:
+           case TYPE_SET_OF:
+             if (move == UP)
+               {
+                 len2 = strtol (p->value, NULL, 10);
+                 if (len2 > counter)
+                   {
+                     _asn1_append_sequence_set (p);
+                     p = p->down;
+                     while (p->right)
+                       p = p->right;
+                     move = RIGHT;
+                     continue;
+                   }
+                 _asn1_set_value (p, NULL, 0);
+                 if (len2 != counter)
+                   {
+                     asn1_delete_structure (structure);
+                     return ASN1_DER_ERROR;
+                   }
+
+                 if (p == nodeFound)
+                   state = EXIT;
+               }
+             else
+               {               /* move==DOWN || move==RIGHT */
+                 if (state == OTHER_BRANCH)
+                   {
+                     len3 =
+                       asn1_get_length_der (der + counter, len - counter,
+                                            &len2);
+                     if (len3 < 0)
+                       return ASN1_DER_ERROR;
+                     counter += len2 + len3;
+                     move = RIGHT;
+                   }
+                 else
+                   {           /* state==FOUND or state==SAME_BRANCH */
+                     len3 =
+                       asn1_get_length_der (der + counter, len - counter,
+                                            &len2);
+                     if (len3 < 0)
+                       return ASN1_DER_ERROR;
+                     counter += len2;
+                     if (len3)
+                       {
+                         _asn1_ltostr (counter + len3, temp);
+                         tlen = strlen (temp);
+
+                         if (tlen > 0)
+                           _asn1_set_value (p, temp, tlen + 1);
+                         p2 = p->down;
+                         while ((type_field (p2->type) == TYPE_TAG)
+                                || (type_field (p2->type) == TYPE_SIZE))
+                           p2 = p2->right;
+                         if (p2->right == NULL)
+                           _asn1_append_sequence_set (p);
+                         p = p2;
+                         state = FOUND;
+                       }
+                   }
+               }
+
+             break;
+           case TYPE_ANY:
+             if (asn1_get_tag_der
+                 (der + counter, len - counter, &class, &len2,
+                  &tag) != ASN1_SUCCESS)
+               return ASN1_DER_ERROR;
+             if (counter + len2 > len)
+               return ASN1_DER_ERROR;
+
+             len4 =
+               asn1_get_length_der (der + counter + len2,
+                                    len - counter - len2, &len3);
+             if (len4 < -1)
+               return ASN1_DER_ERROR;
+
+             if (len4 != -1)
+               {
+                 len2 += len4;
+                 if (state == FOUND)
+                   {
+                     asn1_length_der (len2 + len3, NULL, &len4);
+                     temp2 =
+                       (unsigned char *) _asn1_alloca (len2 + len3 + len4);
+                     if (temp2 == NULL)
+                       {
+                         asn1_delete_structure (structure);
+                         return ASN1_MEM_ALLOC_ERROR;
+                       }
+
+                     asn1_octet_der (der + counter, len2 + len3, temp2,
+                                     &len4);
+                     _asn1_set_value (p, temp2, len4);
+                     _asn1_afree (temp2);
+
+                     if (p == nodeFound)
+                       state = EXIT;
+                   }
+                 counter += len2 + len3;
+               }
+             else
+               {               /* indefinite length */
+                 /* Check indefinite lenth method in an EXPLICIT TAG */
+                 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
+                   indefinite = 1;
+                 else
+                   indefinite = 0;
+
+                 len2 = len - counter;
+                 ris =
+                   _asn1_get_indefinite_length_string (der + counter, &len2);
+                 if (ris != ASN1_SUCCESS)
+                   {
+                     asn1_delete_structure (structure);
+                     return ris;
+                   }
+
+                 if (state == FOUND)
+                   {
+                     asn1_length_der (len2, NULL, &len4);
+                     temp2 = (unsigned char *) _asn1_alloca (len2 + len4);
+                     if (temp2 == NULL)
+                       {
+                         asn1_delete_structure (structure);
+                         return ASN1_MEM_ALLOC_ERROR;
+                       }
+
+                     asn1_octet_der (der + counter, len2, temp2, &len4);
+                     _asn1_set_value (p, temp2, len4);
+                     _asn1_afree (temp2);
+
+                     if (p == nodeFound)
+                       state = EXIT;
+                   }
+
+                 counter += len2;
+
+                 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
+                    an indefinite length method. */
+                 if (indefinite)
+                   {
+                     if (!der[counter] && !der[counter + 1])
+                       {
+                         counter += 2;
+                       }
+                     else
+                       {
+                         asn1_delete_structure (structure);
+                         return ASN1_DER_ERROR;
+                       }
+                   }
+               }
+             move = RIGHT;
+             break;
+
+           default:
+             move = (move == UP) ? RIGHT : DOWN;
+             break;
            }
-         }
        }
-       
-       break;
-      case TYPE_ANY:
-       if(asn1_get_tag_der(der+counter, len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
-          return ASN1_DER_ERROR;
-       if (counter+len2 > len)
-         return ASN1_DER_ERROR;
 
-       len4=asn1_get_length_der(der+counter+len2,len-counter-len2,&len3);
-       if(len4 < -1) return ASN1_DER_ERROR;
+      if ((p == node && move != DOWN) || (state == EXIT))
+       break;
 
-       if(len4 != -1){
-         len2+=len4;
-         if(state==FOUND){
-           asn1_length_der(len2+len3,NULL,&len4);
-           temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
-           if (temp2==NULL){
-             asn1_delete_structure(structure);
-             return ASN1_MEM_ALLOC_ERROR;
+      if (move == DOWN)
+       {
+         if (p->down)
+           {
+             p = p->down;
+
+             if (state != FOUND)
+               {
+                 nameLen -= strlen (p->name) + 1;
+                 if (nameLen > 0)
+                   {
+                     if (currentName[0])
+                       strcat (currentName, ".");
+                     strcat (currentName, p->name);
+                   }
+                 else
+                   {
+                     asn1_delete_structure (structure);
+                     return ASN1_MEM_ERROR;
+                   }
+                 if (!(strcmp (currentName, elementName)))
+                   {
+                     state = FOUND;
+                     nodeFound = p;
+                   }
+                 else
+                   if (!memcmp
+                       (currentName, elementName, strlen (currentName)))
+                   state = SAME_BRANCH;
+                 else
+                   state = OTHER_BRANCH;
+               }
            }
-           
-           asn1_octet_der(der+counter,len2+len3,temp2,&len4);
-           _asn1_set_value(p,temp2,len4);
-           _asn1_afree(temp2);
-
-           if(p==nodeFound) state=EXIT;
-         }
-         counter+=len2+len3;
-       }
-       else{ /* indefinite length */
-         /* Check indefinite lenth method in an EXPLICIT TAG */
-         if((p->type&CONST_TAG) && (der[counter-1]==0x80))
-           indefinite=1;
          else
-           indefinite=0;
-
-         len2=len-counter;
-         ris=_asn1_get_indefinite_length_string(der+counter,&len2);
-         if(ris != ASN1_SUCCESS){
-           asn1_delete_structure(structure);
-           return ris;
-         }
-         
-         if(state==FOUND){
-           asn1_length_der(len2,NULL,&len4);
-           temp2=(unsigned char *)_asn1_alloca(len2+len4);
-           if (temp2==NULL){
-             asn1_delete_structure(structure);
-             return ASN1_MEM_ALLOC_ERROR;
-           }
-        
-           asn1_octet_der(der+counter,len2,temp2,&len4);
-           _asn1_set_value(p,temp2,len4);
-           _asn1_afree(temp2);
+           move = RIGHT;
+       }
+
+      if ((move == RIGHT) && !(p->type & CONST_SET))
+       {
+         if (p->right)
+           {
+             p = p->right;
+
+             if (state != FOUND)
+               {
+                 dot_p = char_p = currentName;
+                 while ((char_p = strchr (char_p, '.')))
+                   {
+                     dot_p = char_p++;
+                     dot_p++;
+                   }
 
-           if(p==nodeFound) state=EXIT;
-         }
+                 nameLen += strlen (currentName) - (dot_p - currentName);
+                 *dot_p = 0;
 
-         counter+=len2;
+                 nameLen -= strlen (p->name);
+                 if (nameLen > 0)
+                   strcat (currentName, p->name);
+                 else
+                   {
+                     asn1_delete_structure (structure);
+                     return ASN1_MEM_ERROR;
+                   }
 
-         /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
-            an indefinite length method. */
-         if(indefinite){
-           if(!der[counter] && !der[counter+1]){ 
-             counter+=2;
-           }
-           else{
-             asn1_delete_structure(structure);
-             return ASN1_DER_ERROR;
+                 if (!(strcmp (currentName, elementName)))
+                   {
+                     state = FOUND;
+                     nodeFound = p;
+                   }
+                 else
+                   if (!memcmp
+                       (currentName, elementName, strlen (currentName)))
+                   state = SAME_BRANCH;
+                 else
+                   state = OTHER_BRANCH;
+               }
            }
-         }
+         else
+           move = UP;
        }
-       move=RIGHT;
-       break;
-
-      default:
-       move=(move==UP)?RIGHT:DOWN;
-       break;
-      }
-    }
 
-    if((p==node && move!=DOWN) || (state==EXIT)) break;
-
-    if(move==DOWN){
-      if(p->down){
-       p=p->down;
-
-       if(state != FOUND){
-         nameLen-=strlen(p->name)+1;
-         if(nameLen>0){
-           if(currentName[0]) strcat(currentName,".");
-           strcat(currentName,p->name);
-         }
-         else{
-           asn1_delete_structure(structure);
-           return ASN1_MEM_ERROR;
-         }
-         if(!(strcmp(currentName,elementName))){ 
-           state=FOUND;
-           nodeFound=p;
-         }
-         else if(!memcmp(currentName,elementName,strlen(currentName))) 
-           state=SAME_BRANCH;
-         else 
-           state=OTHER_BRANCH;
-       }
-      }
-      else move=RIGHT;
-    }
+      if (move == UP)
+       {
+         p = _asn1_find_up (p);
 
-    if((move==RIGHT) && !(p->type&CONST_SET)){
-      if(p->right){
-       p=p->right;
-
-       if(state != FOUND){
-         dot_p=char_p=currentName;
-         while((char_p=strchr(char_p,'.'))){
-           dot_p=char_p++;
-           dot_p++;
-         }
-         
-         nameLen+=strlen(currentName)-(dot_p-currentName);
-         *dot_p=0;
-
-         nameLen-=strlen(p->name);
-         if(nameLen>0) strcat(currentName,p->name);
-         else{
-           asn1_delete_structure(structure);
-           return ASN1_MEM_ERROR;
-         }
-         
-         if(!(strcmp(currentName,elementName))){ 
-           state=FOUND;
-           nodeFound=p;
-         }
-         else if(!memcmp(currentName,elementName,strlen(currentName))) 
-           state=SAME_BRANCH;
-         else 
-           state=OTHER_BRANCH;
-       }
-      }
-      else move=UP;
-    }
+         if (state != FOUND)
+           {
+             dot_p = char_p = currentName;
+             while ((char_p = strchr (char_p, '.')))
+               {
+                 dot_p = char_p++;
+                 dot_p++;
+               }
 
-    if(move==UP){
-      p=_asn1_find_up(p);
+             nameLen += strlen (currentName) - (dot_p - currentName);
+             *dot_p = 0;
 
-      if(state != FOUND){
-       dot_p=char_p=currentName;
-       while((char_p=strchr(char_p,'.'))){
-         dot_p=char_p++;
-         dot_p++;
-       }
-       
-       nameLen+=strlen(currentName)-(dot_p-currentName);
-       *dot_p=0;
-       
-       if(!(strcmp(currentName,elementName))){ 
-       state=FOUND;
-       nodeFound=p;
+             if (!(strcmp (currentName, elementName)))
+               {
+                 state = FOUND;
+                 nodeFound = p;
+               }
+             else
+               if (!memcmp (currentName, elementName, strlen (currentName)))
+               state = SAME_BRANCH;
+             else
+               state = OTHER_BRANCH;
+           }
        }
-       else if(!memcmp(currentName,elementName,strlen(currentName))) 
-         state=SAME_BRANCH;
-       else 
-         state=OTHER_BRANCH;
-      }
     }
-  }
 
-  _asn1_delete_not_used(*structure);
+  _asn1_delete_not_used (*structure);
 
-  if(counter > len){
-    asn1_delete_structure(structure);
-    return ASN1_DER_ERROR;
-  }
+  if (counter > len)
+    {
+      asn1_delete_structure (structure);
+      return ASN1_DER_ERROR;
+    }
 
   return ASN1_SUCCESS;
 }
@@ -1695,242 +2115,322 @@ asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName,
   *
   **/
 asn1_retCode
-asn1_der_decoding_startEnd(ASN1_TYPE element,const void *ider,int len,
-                          const char *name_element,int *start, int *end)
+asn1_der_decoding_startEnd (ASN1_TYPE element, const void *ider, int len,
+                           const char *name_element, int *start, int *end)
 {
-  node_asn *node,*node_to_find,*p,*p2,*p3;
-  int counter,len2,len3,len4,move,ris;
+  node_asn *node, *node_to_find, *p, *p2, *p3;
+  int counter, len2, len3, len4, move, ris;
   unsigned char class;
   unsigned long tag;
   int indefinite;
-  const unsigned char* der = ider;
-
-  node=element;
-
-  if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
-
-  node_to_find=asn1_find_node(node,name_element);
-
-  if(node_to_find==NULL) return ASN1_ELEMENT_NOT_FOUND;
-
-  if(node_to_find==node){
-    *start=0;
-    *end=len-1;
-    return ASN1_SUCCESS;
-  }
-
-  if(node->type&CONST_OPTION) return ASN1_GENERIC_ERROR;
-
-  counter=0;
-  move=DOWN;
-  p=node;
-  while(1){
-    ris=ASN1_SUCCESS;
-    
-    if(move!=UP){
-      if(p->type&CONST_SET){
-       p2=_asn1_find_up(p);
-       len2=strtol(p2->value,NULL,10);
-       if(len2==-1){
-         if(!der[counter] && !der[counter+1]){
-           p=p2;
-           move=UP;
-           counter+=2;
-           continue;
-         }
-       }
-       else if(counter==len2){
-         p=p2;
-         move=UP;
-         continue;
-       }
-       else if(counter>len2) return ASN1_DER_ERROR;
-       p2=p2->down;
-       while(p2){
-         if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){  /* CONTROLLARE */
-           if(type_field(p2->type)!=TYPE_CHOICE)
-             ris=_asn1_extract_tag_der(p2,der+counter,len-counter,&len2);
-           else{
-             p3=p2->down;
-             ris=_asn1_extract_tag_der(p3,der+counter,len-counter,&len2);
-           }
-           if(ris==ASN1_SUCCESS){
-             p2->type&=~CONST_NOT_USED;
-             p=p2;
-             break;
-           }
-         }
-         p2=p2->right;
-       }
-       if(p2==NULL) return ASN1_DER_ERROR;
-      }
+  const unsigned char *der = ider;
 
-      if(p==node_to_find) *start=counter;
+  node = element;
 
-      if(type_field(p->type)==TYPE_CHOICE){
-       p=p->down;
-       ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
-       if(p==node_to_find) *start=counter;
-      }
+  if (node == ASN1_TYPE_EMPTY)
+    return ASN1_ELEMENT_NOT_FOUND;
 
-      if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
-      if(ris!=ASN1_SUCCESS){
-       if(p->type&CONST_OPTION){
-         p->type|=CONST_NOT_USED;
-         move=RIGHT;
-       }
-       else if(p->type&CONST_DEFAULT) {
-         move=RIGHT;
-       }
-       else {
-         return ASN1_TAG_ERROR;
-       }
-      } 
-      else counter+=len2;
+  node_to_find = asn1_find_node (node, name_element);
+
+  if (node_to_find == NULL)
+    return ASN1_ELEMENT_NOT_FOUND;
+
+  if (node_to_find == node)
+    {
+      *start = 0;
+      *end = len - 1;
+      return ASN1_SUCCESS;
     }
 
-    if(ris==ASN1_SUCCESS){
-      switch(type_field(p->type)){
-      case TYPE_NULL:
-       if(der[counter]) return ASN1_DER_ERROR;
-       counter++;
-       move=RIGHT;
-       break;
-      case TYPE_BOOLEAN:
-       if(der[counter++]!=1) return ASN1_DER_ERROR;
-       counter++;
-       move=RIGHT;
-       break;
-      case TYPE_INTEGER: case TYPE_ENUMERATED:
-       len2=asn1_get_length_der(der+counter,len-counter,&len3);
-       if(len2 < 0) return ASN1_DER_ERROR;
-       counter+=len3+len2;
-       move=RIGHT;
-       break;
-      case TYPE_OBJECT_ID:
-       len2=asn1_get_length_der(der+counter,len-counter,&len3);
-       if(len2 < 0) return ASN1_DER_ERROR;
-       counter+=len2+len3;
-       move=RIGHT;
-      break;
-      case TYPE_TIME:
-       len2=asn1_get_length_der(der+counter,len-counter,&len3);
-       if(len2 < 0) return ASN1_DER_ERROR;
-       counter+=len2+len3;
-       move=RIGHT;
-       break;
-      case TYPE_OCTET_STRING:
-       len3=len-counter;
-       ris=_asn1_get_octet_string(der+counter,NULL,&len3);
-       if(ris != ASN1_SUCCESS) return ris; 
-       counter+=len3;
-       move=RIGHT;
-       break;
-      case TYPE_GENERALSTRING:
-       len2=asn1_get_length_der(der+counter,len-counter,&len3);
-       if(len2 < 0) return ASN1_DER_ERROR;
-       counter+=len3+len2;
-       move=RIGHT;
-       break;
-      case TYPE_BIT_STRING:
-       len2=asn1_get_length_der(der+counter,len-counter,&len3);
-       if(len2 < 0) return ASN1_DER_ERROR;
-       counter+=len3+len2;
-       move=RIGHT;
-       break;
-      case TYPE_SEQUENCE:  case TYPE_SET:
-       if(move!=UP){
-         len3=asn1_get_length_der(der+counter,len-counter,&len2);
-         if(len3 < -1) return ASN1_DER_ERROR;
-         counter+=len2;
-         if(len3==0) move=RIGHT;
-         else move=DOWN; 
-       }
-       else{
-         if(!der[counter] && !der[counter+1]) /* indefinite length method */
-           counter+=2;
-         move=RIGHT;
-       }
-       break;
-      case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
-       if(move!=UP){
-         len3=asn1_get_length_der(der+counter,len-counter,&len2);
-         if(len3 < -1) return ASN1_DER_ERROR;
-         counter+=len2;
-         if((len3==-1) && !der[counter] && !der[counter+1])
-           counter+=2;
-         else if(len3){
-           p2=p->down;
-           while((type_field(p2->type)==TYPE_TAG) || 
-                 (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
-           p=p2;
-         }
-       }
-       else{
-         if(!der[counter] && !der[counter+1]) /* indefinite length method */
-           counter+=2;
-       }
-       move=RIGHT;
-       break;
-      case TYPE_ANY:
-       if (asn1_get_tag_der(der+counter, len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
-        return ASN1_DER_ERROR;
-       if (counter+len2 > len)
-         return ASN1_DER_ERROR;
+  if (node->type & CONST_OPTION)
+    return ASN1_GENERIC_ERROR;
+
+  counter = 0;
+  move = DOWN;
+  p = node;
+  while (1)
+    {
+      ris = ASN1_SUCCESS;
+
+      if (move != UP)
+       {
+         if (p->type & CONST_SET)
+           {
+             p2 = _asn1_find_up (p);
+             len2 = strtol (p2->value, NULL, 10);
+             if (len2 == -1)
+               {
+                 if (!der[counter] && !der[counter + 1])
+                   {
+                     p = p2;
+                     move = UP;
+                     counter += 2;
+                     continue;
+                   }
+               }
+             else if (counter == len2)
+               {
+                 p = p2;
+                 move = UP;
+                 continue;
+               }
+             else if (counter > len2)
+               return ASN1_DER_ERROR;
+             p2 = p2->down;
+             while (p2)
+               {
+                 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
+                   {           /* CONTROLLARE */
+                     if (type_field (p2->type) != TYPE_CHOICE)
+                       ris =
+                         _asn1_extract_tag_der (p2, der + counter,
+                                                len - counter, &len2);
+                     else
+                       {
+                         p3 = p2->down;
+                         ris =
+                           _asn1_extract_tag_der (p3, der + counter,
+                                                  len - counter, &len2);
+                       }
+                     if (ris == ASN1_SUCCESS)
+                       {
+                         p2->type &= ~CONST_NOT_USED;
+                         p = p2;
+                         break;
+                       }
+                   }
+                 p2 = p2->right;
+               }
+             if (p2 == NULL)
+               return ASN1_DER_ERROR;
+           }
 
-       len4=asn1_get_length_der(der+counter+len2,len-counter-len2,&len3);
-       if(len4 < -1) return ASN1_DER_ERROR;
+         if (p == node_to_find)
+           *start = counter;
+
+         if (type_field (p->type) == TYPE_CHOICE)
+           {
+             p = p->down;
+             ris =
+               _asn1_extract_tag_der (p, der + counter, len - counter,
+                                      &len2);
+             if (p == node_to_find)
+               *start = counter;
+           }
 
-       if(len4 != -1){
-         counter+=len2+len4+len3;
-       }
-       else{ /* indefinite length */
-         /* Check indefinite lenth method in an EXPLICIT TAG */
-         if((p->type&CONST_TAG) && (der[counter-1]==0x80))
-           indefinite=1;
+         if (ris == ASN1_SUCCESS)
+           ris =
+             _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
+         if (ris != ASN1_SUCCESS)
+           {
+             if (p->type & CONST_OPTION)
+               {
+                 p->type |= CONST_NOT_USED;
+                 move = RIGHT;
+               }
+             else if (p->type & CONST_DEFAULT)
+               {
+                 move = RIGHT;
+               }
+             else
+               {
+                 return ASN1_TAG_ERROR;
+               }
+           }
          else
-           indefinite=0;
-         
-         len2=len-counter;
-         ris=_asn1_get_indefinite_length_string(der+counter,&len2);
-         if(ris != ASN1_SUCCESS)
-           return ris;
-         counter+=len2;
-
-         /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
-            an indefinite length method. */
-         if(indefinite){
-           if(!der[counter] && !der[counter+1])
-             counter+=2;
-           else
-             return ASN1_DER_ERROR;
-         }
+           counter += len2;
+       }
+
+      if (ris == ASN1_SUCCESS)
+       {
+         switch (type_field (p->type))
+           {
+           case TYPE_NULL:
+             if (der[counter])
+               return ASN1_DER_ERROR;
+             counter++;
+             move = RIGHT;
+             break;
+           case TYPE_BOOLEAN:
+             if (der[counter++] != 1)
+               return ASN1_DER_ERROR;
+             counter++;
+             move = RIGHT;
+             break;
+           case TYPE_INTEGER:
+           case TYPE_ENUMERATED:
+             len2 =
+               asn1_get_length_der (der + counter, len - counter, &len3);
+             if (len2 < 0)
+               return ASN1_DER_ERROR;
+             counter += len3 + len2;
+             move = RIGHT;
+             break;
+           case TYPE_OBJECT_ID:
+             len2 =
+               asn1_get_length_der (der + counter, len - counter, &len3);
+             if (len2 < 0)
+               return ASN1_DER_ERROR;
+             counter += len2 + len3;
+             move = RIGHT;
+             break;
+           case TYPE_TIME:
+             len2 =
+               asn1_get_length_der (der + counter, len - counter, &len3);
+             if (len2 < 0)
+               return ASN1_DER_ERROR;
+             counter += len2 + len3;
+             move = RIGHT;
+             break;
+           case TYPE_OCTET_STRING:
+             len3 = len - counter;
+             ris = _asn1_get_octet_string (der + counter, NULL, &len3);
+             if (ris != ASN1_SUCCESS)
+               return ris;
+             counter += len3;
+             move = RIGHT;
+             break;
+           case TYPE_GENERALSTRING:
+             len2 =
+               asn1_get_length_der (der + counter, len - counter, &len3);
+             if (len2 < 0)
+               return ASN1_DER_ERROR;
+             counter += len3 + len2;
+             move = RIGHT;
+             break;
+           case TYPE_BIT_STRING:
+             len2 =
+               asn1_get_length_der (der + counter, len - counter, &len3);
+             if (len2 < 0)
+               return ASN1_DER_ERROR;
+             counter += len3 + len2;
+             move = RIGHT;
+             break;
+           case TYPE_SEQUENCE:
+           case TYPE_SET:
+             if (move != UP)
+               {
+                 len3 =
+                   asn1_get_length_der (der + counter, len - counter, &len2);
+                 if (len3 < -1)
+                   return ASN1_DER_ERROR;
+                 counter += len2;
+                 if (len3 == 0)
+                   move = RIGHT;
+                 else
+                   move = DOWN;
+               }
+             else
+               {
+                 if (!der[counter] && !der[counter + 1])       /* indefinite length method */
+                   counter += 2;
+                 move = RIGHT;
+               }
+             break;
+           case TYPE_SEQUENCE_OF:
+           case TYPE_SET_OF:
+             if (move != UP)
+               {
+                 len3 =
+                   asn1_get_length_der (der + counter, len - counter, &len2);
+                 if (len3 < -1)
+                   return ASN1_DER_ERROR;
+                 counter += len2;
+                 if ((len3 == -1) && !der[counter] && !der[counter + 1])
+                   counter += 2;
+                 else if (len3)
+                   {
+                     p2 = p->down;
+                     while ((type_field (p2->type) == TYPE_TAG) ||
+                            (type_field (p2->type) == TYPE_SIZE))
+                       p2 = p2->right;
+                     p = p2;
+                   }
+               }
+             else
+               {
+                 if (!der[counter] && !der[counter + 1])       /* indefinite length method */
+                   counter += 2;
+               }
+             move = RIGHT;
+             break;
+           case TYPE_ANY:
+             if (asn1_get_tag_der
+                 (der + counter, len - counter, &class, &len2,
+                  &tag) != ASN1_SUCCESS)
+               return ASN1_DER_ERROR;
+             if (counter + len2 > len)
+               return ASN1_DER_ERROR;
+
+             len4 =
+               asn1_get_length_der (der + counter + len2,
+                                    len - counter - len2, &len3);
+             if (len4 < -1)
+               return ASN1_DER_ERROR;
+
+             if (len4 != -1)
+               {
+                 counter += len2 + len4 + len3;
+               }
+             else
+               {               /* indefinite length */
+                 /* Check indefinite lenth method in an EXPLICIT TAG */
+                 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
+                   indefinite = 1;
+                 else
+                   indefinite = 0;
+
+                 len2 = len - counter;
+                 ris =
+                   _asn1_get_indefinite_length_string (der + counter, &len2);
+                 if (ris != ASN1_SUCCESS)
+                   return ris;
+                 counter += len2;
+
+                 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
+                    an indefinite length method. */
+                 if (indefinite)
+                   {
+                     if (!der[counter] && !der[counter + 1])
+                       counter += 2;
+                     else
+                       return ASN1_DER_ERROR;
+                   }
+               }
+             move = RIGHT;
+             break;
+           default:
+             move = (move == UP) ? RIGHT : DOWN;
+             break;
+           }
        }
-       move=RIGHT;
-       break;
-      default:
-       move=(move==UP)?RIGHT:DOWN;
-       break;
-      }
-    }
 
-    if((p==node_to_find) && (move==RIGHT)){
-      *end=counter-1;
-      return ASN1_SUCCESS;
-    }
+      if ((p == node_to_find) && (move == RIGHT))
+       {
+         *end = counter - 1;
+         return ASN1_SUCCESS;
+       }
 
-    if(p==node && move!=DOWN) break;
+      if (p == node && move != DOWN)
+       break;
 
-    if(move==DOWN){
-      if(p->down) p=p->down;
-      else move=RIGHT;
-    }
-    if((move==RIGHT) && !(p->type&CONST_SET)){
-      if(p->right) p=p->right;
-      else move=UP;
+      if (move == DOWN)
+       {
+         if (p->down)
+           p = p->down;
+         else
+           move = RIGHT;
+       }
+      if ((move == RIGHT) && !(p->type & CONST_SET))
+       {
+         if (p->right)
+           p = p->right;
+         else
+           move = UP;
+       }
+      if (move == UP)
+       p = _asn1_find_up (p);
     }
-    if(move==UP) p=_asn1_find_up(p);
-  }
 
   return ASN1_ELEMENT_NOT_FOUND;
 }
@@ -1959,173 +2459,213 @@ asn1_der_decoding_startEnd(ASN1_TYPE element,const void *ider,int len,
   **/
 
 asn1_retCode
-asn1_expand_any_defined_by(ASN1_TYPE definitions,ASN1_TYPE *element)
+asn1_expand_any_defined_by (ASN1_TYPE definitions, ASN1_TYPE * element)
 {
-  char definitionsName[MAX_NAME_SIZE],name[2*MAX_NAME_SIZE+1],value[MAX_NAME_SIZE];
-  asn1_retCode retCode=ASN1_SUCCESS,result;
-  int len,len2,len3;
-  ASN1_TYPE p,p2,p3,aux=ASN1_TYPE_EMPTY;
+  char definitionsName[MAX_NAME_SIZE], name[2 * MAX_NAME_SIZE + 1],
+    value[MAX_NAME_SIZE];
+  asn1_retCode retCode = ASN1_SUCCESS, result;
+  int len, len2, len3;
+  ASN1_TYPE p, p2, p3, aux = ASN1_TYPE_EMPTY;
   char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
 
-  if((definitions==ASN1_TYPE_EMPTY) || (*element==ASN1_TYPE_EMPTY))
+  if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
     return ASN1_ELEMENT_NOT_FOUND;
 
-  strcpy(definitionsName,definitions->name);
-  strcat(definitionsName,".");
-
-  p=*element;
-  while(p){
-    
-    switch(type_field(p->type)){
-    case TYPE_ANY:
-      if((p->type&CONST_DEFINED_BY) && (p->value)){
-       /* search the "DEF_BY" element */
-       p2=p->down;
-       while((p2) && (type_field(p2->type)!=TYPE_CONSTANT))
-         p2=p2->right;
-       
-       if(!p2){
-         retCode=ASN1_ERROR_TYPE_ANY;
-         break;
-       }
-       
-       p3=_asn1_find_up(p);
-       
-       if(!p3){
-         retCode=ASN1_ERROR_TYPE_ANY;
-         break;
-       }
+  strcpy (definitionsName, definitions->name);
+  strcat (definitionsName, ".");
 
-       p3=p3->down;
-       while(p3){
-         if((p3->name) && !(strcmp(p3->name,p2->name))) break;
-         p3=p3->right;
-       }
-       
-       if((!p3) || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
-          (p3->value==NULL)){
+  p = *element;
+  while (p)
+    {
+
+      switch (type_field (p->type))
+       {
+       case TYPE_ANY:
+         if ((p->type & CONST_DEFINED_BY) && (p->value))
+           {
+             /* search the "DEF_BY" element */
+             p2 = p->down;
+             while ((p2) && (type_field (p2->type) != TYPE_CONSTANT))
+               p2 = p2->right;
+
+             if (!p2)
+               {
+                 retCode = ASN1_ERROR_TYPE_ANY;
+                 break;
+               }
 
-         p3=_asn1_find_up(p);
-         p3=_asn1_find_up(p3);
+             p3 = _asn1_find_up (p);
 
-         if(!p3){
-           retCode=ASN1_ERROR_TYPE_ANY;
-           break;
-         }
-
-         p3=p3->down;
-         while(p3){
-           if((p3->name) && !(strcmp(p3->name,p2->name))) break;
-           p3=p3->right;
-         }
-        
-         if((!p3) || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
-            (p3->value==NULL)){
-           retCode=ASN1_ERROR_TYPE_ANY;
-           break;
-         }
-       }
-       
-       /* search the OBJECT_ID into definitions */
-       p2=definitions->down;
-       while(p2){
-         if((type_field(p2->type)==TYPE_OBJECT_ID) &&
-            (p2->type & CONST_ASSIGN)){ 
-           strcpy(name,definitionsName);
-           strcat(name,p2->name);
-           
-           len=MAX_NAME_SIZE;
-           result=asn1_read_value(definitions,name,value,&len);
-           if((result == ASN1_SUCCESS) && (!strcmp(p3->value,value))){
-             p2=p2->right; /* pointer to the structure to 
-                              use for expansion */
-             while((p2) && (p2->type & CONST_ASSIGN))
-               p2=p2->right;
-             
-             if(p2){
-               strcpy(name,definitionsName);
-               strcat(name,p2->name);
-               
-               result=asn1_create_element(definitions,name,&aux);
-               if(result == ASN1_SUCCESS){
-                 _asn1_set_name(aux,p->name);
-                 len2=asn1_get_length_der(p->value,p->value_len,&len3);
-                 if(len2 < 0) return ASN1_DER_ERROR;
-
-                 result=asn1_der_decoding(&aux,p->value+len3,len2,
-                                          errorDescription);
-                 if(result == ASN1_SUCCESS){
-                   
-                   _asn1_set_right(aux,p->right);
-                   _asn1_set_right(p,aux);
-
-                   result=asn1_delete_structure(&p);
-                   if(result == ASN1_SUCCESS){
-                     p=aux;
-                     aux=ASN1_TYPE_EMPTY;
+             if (!p3)
+               {
+                 retCode = ASN1_ERROR_TYPE_ANY;
+                 break;
+               }
+
+             p3 = p3->down;
+             while (p3)
+               {
+                 if ((p3->name) && !(strcmp (p3->name, p2->name)))
+                   break;
+                 p3 = p3->right;
+               }
+
+             if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
+                 (p3->value == NULL))
+               {
+
+                 p3 = _asn1_find_up (p);
+                 p3 = _asn1_find_up (p3);
+
+                 if (!p3)
+                   {
+                     retCode = ASN1_ERROR_TYPE_ANY;
                      break;
                    }
-                   else{ /* error with asn1_delete_structure */
-                     asn1_delete_structure(&aux);
-                     retCode=result;
+
+                 p3 = p3->down;
+
+                 while (p3)
+                   {
+                     if ((p3->name) && !(strcmp (p3->name, p2->name)))
+                       break;
+                     p3 = p3->right;
+                   }
+
+                 if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
+                     (p3->value == NULL))
+                   {
+                     retCode = ASN1_ERROR_TYPE_ANY;
                      break;
                    }
-                 }
-                 else{/* error with asn1_der_decoding */
-                   retCode=result;
-                   break;
-                 }
                }
-               else{/* error with asn1_create_element */
-                 retCode=result;
+
+             /* search the OBJECT_ID into definitions */
+             p2 = definitions->down;
+             while (p2)
+               {
+                 if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
+                     (p2->type & CONST_ASSIGN))
+                   {
+                     strcpy (name, definitionsName);
+                     strcat (name, p2->name);
+
+                     len = MAX_NAME_SIZE;
+                     result =
+                       asn1_read_value (definitions, name, value, &len);
+
+                     if ((result == ASN1_SUCCESS)
+                         && (!strcmp (p3->value, value)))
+                       {
+                         p2 = p2->right;       /* pointer to the structure to 
+                                                  use for expansion */
+                         while ((p2) && (p2->type & CONST_ASSIGN))
+                           p2 = p2->right;
+
+                         if (p2)
+                           {
+                             strcpy (name, definitionsName);
+                             strcat (name, p2->name);
+
+                             result =
+                               asn1_create_element (definitions, name, &aux);
+                             if (result == ASN1_SUCCESS)
+                               {
+                                 _asn1_set_name (aux, p->name);
+                                 len2 =
+                                   asn1_get_length_der (p->value,
+                                                        p->value_len, &len3);
+                                 if (len2 < 0)
+                                   return ASN1_DER_ERROR;
+
+                                 result =
+                                   asn1_der_decoding (&aux, p->value + len3,
+                                                      len2,
+                                                      errorDescription);
+                                 if (result == ASN1_SUCCESS)
+                                   {
+
+                                     _asn1_set_right (aux, p->right);
+                                     _asn1_set_right (p, aux);
+
+                                     result = asn1_delete_structure (&p);
+                                     if (result == ASN1_SUCCESS)
+                                       {
+                                         p = aux;
+                                         aux = ASN1_TYPE_EMPTY;
+                                         break;
+                                       }
+                                     else
+                                       {       /* error with asn1_delete_structure */
+                                         asn1_delete_structure (&aux);
+                                         retCode = result;
+                                         break;
+                                       }
+                                   }
+                                 else
+                                   {   /* error with asn1_der_decoding */
+                                     retCode = result;
+                                     break;
+                                   }
+                               }
+                             else
+                               {       /* error with asn1_create_element */
+                                 retCode = result;
+                                 break;
+                               }
+                           }
+                         else
+                           {   /* error with the pointer to the structure to exapand */
+                             retCode = ASN1_ERROR_TYPE_ANY;
+                             break;
+                           }
+                       }
+                   }
+                 p2 = p2->right;
+               }               /* end while */
+
+             if (!p2)
+               {
+                 retCode = ASN1_ERROR_TYPE_ANY;
                  break;
                }
-             }
-             else{/* error with the pointer to the structure to exapand */
-               retCode=ASN1_ERROR_TYPE_ANY;
-               break;
-             }
+
            }
-         }           
-         p2=p2->right;
-       } /* end while */
-       
-       if(!p2){
-         retCode=ASN1_ERROR_TYPE_ANY;
+         break;
+       default:
          break;
        }
-       
-      }
-      break;
-    default:
-      break;
-    }
-    
 
-    if(p->down){
-      p=p->down;
-    }
-    else if(p==*element){
-      p=NULL;
-      break;
-    }
-    else if(p->right) p=p->right;
-    else{
-      while(1){
-       p=_asn1_find_up(p);
-       if(p==*element){
-         p=NULL;
-         break;
+
+      if (p->down)
+       {
+         p = p->down;
        }
-       if(p->right){
-         p=p->right;
+      else if (p == *element)
+       {
+         p = NULL;
          break;
        }
-      }
+      else if (p->right)
+       p = p->right;
+      else
+       {
+         while (1)
+           {
+             p = _asn1_find_up (p);
+             if (p == *element)
+               {
+                 p = NULL;
+                 break;
+               }
+             if (p->right)
+               {
+                 p = p->right;
+                 break;
+               }
+           }
+       }
     }
-  }
 
   return retCode;
 }
@@ -2157,109 +2697,125 @@ asn1_expand_any_defined_by(ASN1_TYPE definitions,ASN1_TYPE *element)
   *   other errors: result of der decoding process.
   **/
 asn1_retCode
-asn1_expand_octet_string(ASN1_TYPE definitions,ASN1_TYPE *element,
-                        const char *octetName,const char *objectName)
+asn1_expand_octet_string (ASN1_TYPE definitions, ASN1_TYPE * element,
+                         const char *octetName, const char *objectName)
 {
-  char name[2*MAX_NAME_SIZE+1],value[MAX_NAME_SIZE];
-  asn1_retCode retCode=ASN1_SUCCESS,result;
-  int len,len2,len3;
-  ASN1_TYPE p2,aux=ASN1_TYPE_EMPTY;
-  ASN1_TYPE octetNode=ASN1_TYPE_EMPTY,objectNode=ASN1_TYPE_EMPTY;
+  char name[2 * MAX_NAME_SIZE + 1], value[MAX_NAME_SIZE];
+  asn1_retCode retCode = ASN1_SUCCESS, result;
+  int len, len2, len3;
+  ASN1_TYPE p2, aux = ASN1_TYPE_EMPTY;
+  ASN1_TYPE octetNode = ASN1_TYPE_EMPTY, objectNode = ASN1_TYPE_EMPTY;
   char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
 
-  if((definitions==ASN1_TYPE_EMPTY) || (*element==ASN1_TYPE_EMPTY))
+  if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
     return ASN1_ELEMENT_NOT_FOUND;
 
-  octetNode=asn1_find_node(*element,octetName);
-  if(octetNode==ASN1_TYPE_EMPTY)
+  octetNode = asn1_find_node (*element, octetName);
+  if (octetNode == ASN1_TYPE_EMPTY)
     return ASN1_ELEMENT_NOT_FOUND;
-  if(type_field(octetNode->type)!=TYPE_OCTET_STRING)
+  if (type_field (octetNode->type) != TYPE_OCTET_STRING)
     return ASN1_ELEMENT_NOT_FOUND;
-  if(octetNode->value==NULL)
+  if (octetNode->value == NULL)
     return ASN1_VALUE_NOT_FOUND;
 
-  objectNode=asn1_find_node(*element,objectName);
-  if(objectNode==ASN1_TYPE_EMPTY)
+  objectNode = asn1_find_node (*element, objectName);
+  if (objectNode == ASN1_TYPE_EMPTY)
     return ASN1_ELEMENT_NOT_FOUND;
 
-  if(type_field(objectNode->type)!=TYPE_OBJECT_ID)
+  if (type_field (objectNode->type) != TYPE_OBJECT_ID)
     return ASN1_ELEMENT_NOT_FOUND;
 
-  if(objectNode->value==NULL)
+  if (objectNode->value == NULL)
     return ASN1_VALUE_NOT_FOUND;
 
-       
+
   /* search the OBJECT_ID into definitions */
-  p2=definitions->down;
-  while(p2){
-    if((type_field(p2->type)==TYPE_OBJECT_ID) &&
-       (p2->type & CONST_ASSIGN)){ 
-      strcpy(name,definitions->name);
-      strcat(name,".");
-      strcat(name,p2->name);
-    
-      len = sizeof(value);
-      result=asn1_read_value(definitions,name,value,&len);
-
-      if((result == ASN1_SUCCESS) && (!strcmp(objectNode->value,value))){
-
-       p2=p2->right; /* pointer to the structure to 
-                        use for expansion */
-       while((p2) && (p2->type & CONST_ASSIGN))
-         p2=p2->right;
-             
-       if(p2){
-         strcpy(name,definitions->name);
-         strcat(name,".");
-         strcat(name,p2->name);
-               
-         result=asn1_create_element(definitions,name,&aux);
-         if(result == ASN1_SUCCESS){
-           _asn1_set_name(aux,octetNode->name);          
-           len2=asn1_get_length_der(octetNode->value,octetNode->value_len,&len3);
-           if(len2 < 0) return ASN1_DER_ERROR;
-
-           result=asn1_der_decoding(&aux,octetNode->value+len3,len2,
-                                    errorDescription);
-           if(result == ASN1_SUCCESS){
-             
-             _asn1_set_right(aux,octetNode->right);
-             _asn1_set_right(octetNode,aux);
-             
-             result=asn1_delete_structure(&octetNode);
-             if(result == ASN1_SUCCESS){
-               aux=ASN1_TYPE_EMPTY;
-               break;
-             }
-             else{ /* error with asn1_delete_structure */
-               asn1_delete_structure(&aux);
-               retCode=result;
-               break;
-             }
-           }
-           else{/* error with asn1_der_decoding */
-             retCode=result;
-             break;
+  p2 = definitions->down;
+  while (p2)
+    {
+      if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
+         (p2->type & CONST_ASSIGN))
+       {
+         strcpy (name, definitions->name);
+         strcat (name, ".");
+         strcat (name, p2->name);
+
+         len = sizeof (value);
+         result = asn1_read_value (definitions, name, value, &len);
+
+         if ((result == ASN1_SUCCESS)
+             && (!strcmp (objectNode->value, value)))
+           {
+
+             p2 = p2->right;   /* pointer to the structure to 
+                                  use for expansion */
+             while ((p2) && (p2->type & CONST_ASSIGN))
+               p2 = p2->right;
+
+             if (p2)
+               {
+                 strcpy (name, definitions->name);
+                 strcat (name, ".");
+                 strcat (name, p2->name);
+
+                 result = asn1_create_element (definitions, name, &aux);
+                 if (result == ASN1_SUCCESS)
+                   {
+                     _asn1_set_name (aux, octetNode->name);
+                     len2 =
+                       asn1_get_length_der (octetNode->value,
+                                            octetNode->value_len, &len3);
+                     if (len2 < 0)
+                       return ASN1_DER_ERROR;
+
+                     result =
+                       asn1_der_decoding (&aux, octetNode->value + len3,
+                                          len2, errorDescription);
+                     if (result == ASN1_SUCCESS)
+                       {
+
+                         _asn1_set_right (aux, octetNode->right);
+                         _asn1_set_right (octetNode, aux);
+
+                         result = asn1_delete_structure (&octetNode);
+                         if (result == ASN1_SUCCESS)
+                           {
+                             aux = ASN1_TYPE_EMPTY;
+                             break;
+                           }
+                         else
+                           {   /* error with asn1_delete_structure */
+                             asn1_delete_structure (&aux);
+                             retCode = result;
+                             break;
+                           }
+                       }
+                     else
+                       {       /* error with asn1_der_decoding */
+                         retCode = result;
+                         break;
+                       }
+                   }
+                 else
+                   {           /* error with asn1_create_element */
+                     retCode = result;
+                     break;
+                   }
+               }
+             else
+               {               /* error with the pointer to the structure to exapand */
+                 retCode = ASN1_VALUE_NOT_VALID;
+                 break;
+               }
            }
-         }
-         else{/* error with asn1_create_element */
-           retCode=result;
-           break;
-         }
        }
-       else{/* error with the pointer to the structure to exapand */
-         retCode=ASN1_VALUE_NOT_VALID;
-         break;
-       }
-      }
-    }  
-    
-    p2=p2->right;
 
-  }
+      p2 = p2->right;
 
-  if(!p2) retCode=ASN1_VALUE_NOT_VALID;
+    }
+
+  if (!p2)
+    retCode = ASN1_VALUE_NOT_VALID;
 
   return retCode;
 }
-
index afc1423d207db256c187e89d4406eb8d3dea58b1..fd66f248aaa4d498b06e8e9b52185e53c31ad03a 100644 (file)
 #include "structure.h"
 
 void
-_asn1_hierarchical_name(node_asn *node,char *name,int name_size)
+_asn1_hierarchical_name (node_asn * node, char *name, int name_size)
 {
   node_asn *p;
   char tmp_name[64];
 
-  p=node;
+  p = node;
 
-  name[0]=0;
+  name[0] = 0;
 
-  while(p != NULL){
-    if(p->name != NULL){
-      _asn1_str_cpy(tmp_name,sizeof(tmp_name),name),
-
-      _asn1_str_cpy(name,name_size,p->name);
-      _asn1_str_cat(name,name_size,".");
-      _asn1_str_cat(name,name_size,tmp_name);
+  while (p != NULL)
+    {
+      if (p->name != NULL)
+       {
+         _asn1_str_cpy (tmp_name, sizeof (tmp_name), name),
+           _asn1_str_cpy (name, name_size, p->name);
+         _asn1_str_cat (name, name_size, ".");
+         _asn1_str_cat (name, name_size, tmp_name);
+       }
+      p = _asn1_find_up (p);
     }
-    p=_asn1_find_up(p);
-  }
 
-  if(name[0]==0) _asn1_str_cpy(name,name_size,"ROOT");
+  if (name[0] == 0)
+    _asn1_str_cpy (name, name_size, "ROOT");
 }
 
 
@@ -73,45 +75,52 @@ _asn1_hierarchical_name(node_asn *node,char *name,int name_size)
 /* Return: ASN1_MEM_ERROR or ASN1_SUCCESS                         */
 /******************************************************************/
 asn1_retCode
-_asn1_convert_integer(const char *value,unsigned char *value_out,int value_out_size, int *len)
+_asn1_convert_integer (const char *value, unsigned char *value_out,
+                      int value_out_size, int *len)
 {
   char negative;
   unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
   long valtmp;
-  int k,k2;
+  int k, k2;
 
-  valtmp=strtol(value,NULL,10);
-  
-  for(k=0;k<SIZEOF_UNSIGNED_LONG_INT;k++){
-    val[SIZEOF_UNSIGNED_LONG_INT-k-1]=(valtmp >> (8*k)) & 0xFF;
-  }
+  valtmp = strtol (value, NULL, 10);
 
-  if(val[0]&0x80) negative=1;
-  else negative=0;
+  for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
+    {
+      val[SIZEOF_UNSIGNED_LONG_INT - k - 1] = (valtmp >> (8 * k)) & 0xFF;
+    }
 
-  for(k=0;k<SIZEOF_UNSIGNED_LONG_INT-1;k++){
-    if(negative && (val[k]!=0xFF)) break;
-    else if(!negative && val[k]) break;
-  }
-       
-  if((negative && !(val[k]&0x80)) ||
-     (!negative && (val[k]&0x80))) k--; 
+  if (val[0] & 0x80)
+    negative = 1;
+  else
+    negative = 0;
 
-  *len=SIZEOF_UNSIGNED_LONG_INT-k;  
+  for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++)
+    {
+      if (negative && (val[k] != 0xFF))
+       break;
+      else if (!negative && val[k])
+       break;
+    }
+
+  if ((negative && !(val[k] & 0x80)) || (!negative && (val[k] & 0x80)))
+    k--;
 
-  if (SIZEOF_UNSIGNED_LONG_INT-k> value_out_size)
+  *len = SIZEOF_UNSIGNED_LONG_INT - k;
+
+  if (SIZEOF_UNSIGNED_LONG_INT - k > value_out_size)
     /* VALUE_OUT is too short to contain the value conversion */
     return ASN1_MEM_ERROR;
 
-  for(k2=k;k2<SIZEOF_UNSIGNED_LONG_INT;k2++)
-    value_out[k2-k]=val[k2];
+  for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++)
+    value_out[k2 - k] = val[k2];
 
 
 #ifdef LIBTASN1_DEBUG_INTEGER
-  _libtasn1_log("_asn1_convert_integer: valueIn=%s, lenOut=%d",value,*len);
-  for(k=0;k<SIZEOF_UNSIGNED_LONG_INT;k++)
-    _libtasn1_log(", vOut[%d]=%d",k,value_out[k]);
-  _libtasn1_log("\n");
+  _libtasn1_log ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len);
+  for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
+    _libtasn1_log (", vOut[%d]=%d", k, value_out[k]);
+  _libtasn1_log ("\n");
 #endif
 
 
@@ -119,29 +128,35 @@ _asn1_convert_integer(const char *value,unsigned char *value_out,int value_out_s
 }
 
 
-int 
-_asn1_append_sequence_set(node_asn *node)
+int
+_asn1_append_sequence_set (node_asn * node)
 {
-  node_asn *p,*p2;
+  node_asn *p, *p2;
   char temp[10];
   long n;
 
-  if(!node || !(node->down)) return ASN1_GENERIC_ERROR;
-
-  p=node->down;
-  while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
-  p2=_asn1_copy_structure3(p);
-  while(p->right) p=p->right;
-  _asn1_set_right(p,p2);
-  
-  if(p->name==NULL) _asn1_str_cpy(temp,sizeof(temp),"?1");
-  else{
-    n=strtol(p->name+1,NULL,0);
-    n++;
-    temp[0]='?';
-    _asn1_ltostr(n,temp+1);
-  } 
-  _asn1_set_name(p2,temp);
+  if (!node || !(node->down))
+    return ASN1_GENERIC_ERROR;
+
+  p = node->down;
+  while ((type_field (p->type) == TYPE_TAG)
+        || (type_field (p->type) == TYPE_SIZE))
+    p = p->right;
+  p2 = _asn1_copy_structure3 (p);
+  while (p->right)
+    p = p->right;
+  _asn1_set_right (p, p2);
+
+  if (p->name == NULL)
+    _asn1_str_cpy (temp, sizeof (temp), "?1");
+  else
+    {
+      n = strtol (p->name + 1, NULL, 0);
+      n++;
+      temp[0] = '?';
+      _asn1_ltostr (n, temp + 1);
+    }
+  _asn1_set_name (p2, temp);
   /*  p2->type |= CONST_OPTION; */
 
   return ASN1_SUCCESS;
@@ -260,262 +275,362 @@ _asn1_append_sequence_set(node_asn *node)
   *
   **/
 asn1_retCode
-asn1_write_value(ASN1_TYPE node_root,const char *name,
-                const void *ivalue,int len)
+asn1_write_value (ASN1_TYPE node_root, const char *name,
+                 const void *ivalue, int len)
 {
-  node_asn *node,*p,*p2;
-  unsigned char *temp,*value_temp=NULL,*default_temp=NULL;
-  int len2,k,k2,negative;
-  const unsigned char* value = ivalue;
-
-  node=asn1_find_node(node_root,name);
-  if(node==NULL) return  ASN1_ELEMENT_NOT_FOUND;
-
-  if((node->type & CONST_OPTION) && (value==NULL) && (len==0)){
-    asn1_delete_structure(&node);
-    return ASN1_SUCCESS;
-  }
-
-  if((type_field(node->type) == TYPE_SEQUENCE_OF) && (value == NULL) && (len==0)){
-    p=node->down;
-    while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
-
-    while(p->right)
-      asn1_delete_structure(&p->right);
-
-    return ASN1_SUCCESS;
-  }
-
-  switch(type_field(node->type)){
-  case TYPE_BOOLEAN:
-    if(!strcmp(value,"TRUE")){
-      if(node->type&CONST_DEFAULT){
-       p=node->down;
-       while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
-       if(p->type&CONST_TRUE) _asn1_set_value(node,NULL,0);
-       else _asn1_set_value(node,"T",1);
-      }
-      else _asn1_set_value(node,"T",1);
+  node_asn *node, *p, *p2;
+  unsigned char *temp, *value_temp = NULL, *default_temp = NULL;
+  int len2, k, k2, negative;
+  const unsigned char *value = ivalue;
+
+  node = asn1_find_node (node_root, name);
+  if (node == NULL)
+    return ASN1_ELEMENT_NOT_FOUND;
+
+  if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0))
+    {
+      asn1_delete_structure (&node);
+      return ASN1_SUCCESS;
     }
-    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);
-    }
-    else return ASN1_VALUE_NOT_VALID;
-    break;
-  case TYPE_INTEGER: case TYPE_ENUMERATED:
-    if(len==0){
-      if((isdigit(value[0])) || (value[0]=='-')){
-       value_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT);
-       if (value_temp==NULL) return ASN1_MEM_ALLOC_ERROR;
-
-       _asn1_convert_integer(value,value_temp,SIZEOF_UNSIGNED_LONG_INT, &len);
-      }
-      else{ /* is an identifier like v1 */
-       if(!(node->type&CONST_LIST)) return ASN1_VALUE_NOT_VALID;
-       p=node->down;
-       while(p){
-         if(type_field(p->type)==TYPE_CONSTANT){
-           if((p->name) && (!strcmp(p->name,value))){
-             value_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT);
-             if (value_temp==NULL) return ASN1_MEM_ALLOC_ERROR;
-
-             _asn1_convert_integer(p->value,value_temp,SIZEOF_UNSIGNED_LONG_INT, &len);
-             break;
-           }
-         }
-         p=p->right;
-       }
-       if(p==NULL) return ASN1_VALUE_NOT_VALID;
-      }
-    }
-    else{ /* len != 0 */
-      value_temp=(unsigned char *)_asn1_alloca(len);
-      if (value_temp==NULL) return ASN1_MEM_ALLOC_ERROR;
-      memcpy(value_temp,value,len);
-    }
-
-
-    if(value_temp[0]&0x80) negative=1;
-    else negative=0;
 
-    if(negative && (type_field(node->type)==TYPE_ENUMERATED)) 
-      {_asn1_afree(value_temp);return ASN1_VALUE_NOT_VALID;}
+  if ((type_field (node->type) == TYPE_SEQUENCE_OF) && (value == NULL)
+      && (len == 0))
+    {
+      p = node->down;
+      while ((type_field (p->type) == TYPE_TAG)
+            || (type_field (p->type) == TYPE_SIZE))
+       p = p->right;
 
-    for(k=0;k<len-1;k++)
-      if(negative && (value_temp[k]!=0xFF)) break;
-      else if(!negative && value_temp[k]) break;
+      while (p->right)
+       asn1_delete_structure (&p->right);
 
-    if((negative && !(value_temp[k]&0x80)) ||
-       (!negative && (value_temp[k]&0x80))) k--; 
+      return ASN1_SUCCESS;
+    }
 
-    asn1_length_der(len-k,NULL,&len2);
-    temp=(unsigned char *)_asn1_alloca(len-k+len2);
-    if (temp==NULL) return ASN1_MEM_ALLOC_ERROR;
+  switch (type_field (node->type))
+    {
+    case TYPE_BOOLEAN:
+      if (!strcmp (value, "TRUE"))
+       {
+         if (node->type & CONST_DEFAULT)
+           {
+             p = node->down;
+             while (type_field (p->type) != TYPE_DEFAULT)
+               p = p->right;
+             if (p->type & CONST_TRUE)
+               _asn1_set_value (node, NULL, 0);
+             else
+               _asn1_set_value (node, "T", 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);
+       }
+      else
+       return ASN1_VALUE_NOT_VALID;
+      break;
+    case TYPE_INTEGER:
+    case TYPE_ENUMERATED:
+      if (len == 0)
+       {
+         if ((isdigit (value[0])) || (value[0] == '-'))
+           {
+             value_temp =
+               (unsigned char *) _asn1_alloca (SIZEOF_UNSIGNED_LONG_INT);
+             if (value_temp == NULL)
+               return ASN1_MEM_ALLOC_ERROR;
+
+             _asn1_convert_integer (value, value_temp,
+                                    SIZEOF_UNSIGNED_LONG_INT, &len);
+           }
+         else
+           {                   /* is an identifier like v1 */
+             if (!(node->type & CONST_LIST))
+               return ASN1_VALUE_NOT_VALID;
+             p = node->down;
+             while (p)
+               {
+                 if (type_field (p->type) == TYPE_CONSTANT)
+                   {
+                     if ((p->name) && (!strcmp (p->name, value)))
+                       {
+                         value_temp =
+                           (unsigned char *)
+                           _asn1_alloca (SIZEOF_UNSIGNED_LONG_INT);
+                         if (value_temp == NULL)
+                           return ASN1_MEM_ALLOC_ERROR;
+
+                         _asn1_convert_integer (p->value,
+                                                value_temp,
+                                                SIZEOF_UNSIGNED_LONG_INT,
+                                                &len);
+                         break;
+                       }
+                   }
+                 p = p->right;
+               }
+             if (p == NULL)
+               return ASN1_VALUE_NOT_VALID;
+           }
+       }
+      else
+       {                       /* len != 0 */
+         value_temp = (unsigned char *) _asn1_alloca (len);
+         if (value_temp == NULL)
+           return ASN1_MEM_ALLOC_ERROR;
+         memcpy (value_temp, value, len);
+       }
 
-    asn1_octet_der(value_temp+k,len-k,temp,&len2);
-    _asn1_set_value(node,temp,len2);
 
-    _asn1_afree(temp);
+      if (value_temp[0] & 0x80)
+       negative = 1;
+      else
+       negative = 0;
 
+      if (negative && (type_field (node->type) == TYPE_ENUMERATED))
+       {
+         _asn1_afree (value_temp);
+         return ASN1_VALUE_NOT_VALID;
+       }
 
-    if(node->type&CONST_DEFAULT){
-      p=node->down;
-      while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
-      if((isdigit(p->value[0])) || (p->value[0]=='-')){
-       default_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT);
-        if (default_temp==NULL) return ASN1_MEM_ALLOC_ERROR;
+      for (k = 0; k < len - 1; k++)
+       if (negative && (value_temp[k] != 0xFF))
+         break;
+       else if (!negative && value_temp[k])
+         break;
+
+      if ((negative && !(value_temp[k] & 0x80)) ||
+         (!negative && (value_temp[k] & 0x80)))
+       k--;
+
+      asn1_length_der (len - k, NULL, &len2);
+      temp = (unsigned char *) _asn1_alloca (len - k + len2);
+      if (temp == NULL)
+       return ASN1_MEM_ALLOC_ERROR;
+
+      asn1_octet_der (value_temp + k, len - k, temp, &len2);
+      _asn1_set_value (node, temp, len2);
+
+      _asn1_afree (temp);
+
+
+      if (node->type & CONST_DEFAULT)
+       {
+         p = node->down;
+         while (type_field (p->type) != TYPE_DEFAULT)
+           p = p->right;
+         if ((isdigit (p->value[0])) || (p->value[0] == '-'))
+           {
+             default_temp =
+               (unsigned char *) _asn1_alloca (SIZEOF_UNSIGNED_LONG_INT);
+             if (default_temp == NULL)
+               return ASN1_MEM_ALLOC_ERROR;
+
+             _asn1_convert_integer (p->value, default_temp,
+                                    SIZEOF_UNSIGNED_LONG_INT, &len2);
+           }
+         else
+           {                   /* is an identifier like v1 */
+             if (!(node->type & CONST_LIST))
+               return ASN1_VALUE_NOT_VALID;
+             p2 = node->down;
+             while (p2)
+               {
+                 if (type_field (p2->type) == TYPE_CONSTANT)
+                   {
+                     if ((p2->name) && (!strcmp (p2->name, p->value)))
+                       {
+                         default_temp =
+                           (unsigned char *)
+                           _asn1_alloca (SIZEOF_UNSIGNED_LONG_INT);
+                         if (default_temp == NULL)
+                           return ASN1_MEM_ALLOC_ERROR;
+
+                         _asn1_convert_integer (p2->value,
+                                                default_temp,
+                                                SIZEOF_UNSIGNED_LONG_INT,
+                                                &len2);
+                         break;
+                       }
+                   }
+                 p2 = p2->right;
+               }
+             if (p2 == NULL)
+               return ASN1_VALUE_NOT_VALID;
+           }
 
-       _asn1_convert_integer(p->value,default_temp,SIZEOF_UNSIGNED_LONG_INT,&len2);
-      }
-      else{ /* is an identifier like v1 */
-       if(!(node->type&CONST_LIST)) return ASN1_VALUE_NOT_VALID;
-       p2=node->down;
-       while(p2){
-         if(type_field(p2->type)==TYPE_CONSTANT){
-           if((p2->name) && (!strcmp(p2->name,p->value))){
-             default_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT);
-             if (default_temp==NULL) return ASN1_MEM_ALLOC_ERROR;
 
-             _asn1_convert_integer(p2->value,default_temp,SIZEOF_UNSIGNED_LONG_INT,&len2);
+         if ((len - k) == len2)
+           {
+             for (k2 = 0; k2 < len2; k2++)
+               if (value_temp[k + k2] != default_temp[k2])
+                 {
+                   break;
+                 }
+             if (k2 == len2)
+               _asn1_set_value (node, NULL, 0);
+           }
+         _asn1_afree (default_temp);
+       }
+      _asn1_afree (value_temp);
+      break;
+    case TYPE_OBJECT_ID:
+      for (k = 0; k < strlen (value); k++)
+       if ((!isdigit (value[k])) && (value[k] != '.') && (value[k] != '+'))
+         return ASN1_VALUE_NOT_VALID;
+      if (node->type & CONST_DEFAULT)
+       {
+         p = node->down;
+         while (type_field (p->type) != TYPE_DEFAULT)
+           p = p->right;
+         if (!strcmp (value, p->value))
+           {
+             _asn1_set_value (node, NULL, 0);
              break;
            }
-         }
-         p2=p2->right;
        }
-       if(p2==NULL) return ASN1_VALUE_NOT_VALID;
-      }
-
-
-      if((len-k)==len2){
-       for(k2=0;k2<len2;k2++) 
-         if(value_temp[k+k2]!=default_temp[k2]){
-           break;
-         }
-       if(k2==len2) _asn1_set_value(node,NULL,0);
-      }
-      _asn1_afree(default_temp);
-    }
-    _asn1_afree(value_temp);
-    break;
-  case TYPE_OBJECT_ID:
-    for(k=0;k<strlen(value);k++)
-      if((!isdigit(value[k])) && (value[k]!='.') && (value[k]!='+')) 
-       return ASN1_VALUE_NOT_VALID; 
-    if(node->type&CONST_DEFAULT){
-      p=node->down;
-      while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
-      if(!strcmp(value,p->value)){
-       _asn1_set_value(node,NULL,0);
-       break;
-      } 
-    }
-    _asn1_set_value(node,value,strlen(value)+1);
-    break;
-  case TYPE_TIME:
-    if(node->type&CONST_UTC){
-      if(strlen(value)<11) return ASN1_VALUE_NOT_VALID;
-      for(k=0;k<10;k++) 
-       if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID;
-      switch(strlen(value)){
-      case 11:
-      if(value[10]!='Z') return ASN1_VALUE_NOT_VALID;
+      _asn1_set_value (node, value, strlen (value) + 1);
       break;
-      case 13:
-       if((!isdigit(value[10])) || (!isdigit(value[11])) ||
-          (value[12]!='Z')) return ASN1_VALUE_NOT_VALID;
-       break;
-      case 15:
-       if((value[10]!='+') && (value[10]!='-')) return ASN1_VALUE_NOT_VALID;
-       for(k=11;k<15;k++) 
-         if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID;
-       break;
-      case 17:
-       if((!isdigit(value[10])) || (!isdigit(value[11]))) 
-          return ASN1_VALUE_NOT_VALID;
-       if((value[12]!='+') && (value[12]!='-')) return ASN1_VALUE_NOT_VALID;
-       for(k=13;k<17;k++) 
-         if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID;
-       break; 
-      default:
-       return ASN1_VALUE_NOT_FOUND;
-      }
-      _asn1_set_value(node,value,strlen(value)+1);
-    }
-    else{  /* GENERALIZED TIME */
-      if(value) _asn1_set_value(node,value,strlen(value)+1);
-    }
-    break;
-  case  TYPE_OCTET_STRING:
-    if(len==0)
-      len=strlen(value);
-    asn1_length_der(len,NULL,&len2);
-    temp=(unsigned char *)_asn1_alloca(len+len2);
-    if (temp==NULL) return ASN1_MEM_ALLOC_ERROR;
-
-    asn1_octet_der(value,len,temp,&len2);
-    _asn1_set_value(node,temp,len2);
-    _asn1_afree(temp);
-    break;
-  case  TYPE_GENERALSTRING:
-    if(len==0)
-      len=strlen(value);
-    asn1_length_der(len,NULL,&len2);
-    temp=(unsigned char *)_asn1_alloca(len+len2);
-    if (temp==NULL) return ASN1_MEM_ALLOC_ERROR;
-
-    asn1_octet_der(value,len,temp,&len2);
-    _asn1_set_value(node,temp,len2);
-    _asn1_afree(temp);
-    break;
-  case  TYPE_BIT_STRING:
-    if(len==0)
-      len=strlen(value);
-    asn1_length_der((len>>3)+2,NULL,&len2);
-    temp=(unsigned char *)_asn1_alloca((len>>3)+2+len2);
-    if (temp==NULL) return ASN1_MEM_ALLOC_ERROR;
-
-    asn1_bit_der(value,len,temp,&len2);
-    _asn1_set_value(node,temp,len2);
-    _asn1_afree(temp);
-    break;
-  case  TYPE_CHOICE:
-    p=node->down;
-    while(p){
-      if(!strcmp(p->name,value)){
-       p2=node->down;
-       while(p2){
-         if(p2!=p){asn1_delete_structure(&p2); p2=node->down;}
-         else p2=p2->right;
+    case TYPE_TIME:
+      if (node->type & CONST_UTC)
+       {
+         if (strlen (value) < 11)
+           return ASN1_VALUE_NOT_VALID;
+         for (k = 0; k < 10; k++)
+           if (!isdigit (value[k]))
+             return ASN1_VALUE_NOT_VALID;
+         switch (strlen (value))
+           {
+           case 11:
+             if (value[10] != 'Z')
+               return ASN1_VALUE_NOT_VALID;
+             break;
+           case 13:
+             if ((!isdigit (value[10])) || (!isdigit (value[11])) ||
+                 (value[12] != 'Z'))
+               return ASN1_VALUE_NOT_VALID;
+             break;
+           case 15:
+             if ((value[10] != '+') && (value[10] != '-'))
+               return ASN1_VALUE_NOT_VALID;
+             for (k = 11; k < 15; k++)
+               if (!isdigit (value[k]))
+                 return ASN1_VALUE_NOT_VALID;
+             break;
+           case 17:
+             if ((!isdigit (value[10])) || (!isdigit (value[11])))
+               return ASN1_VALUE_NOT_VALID;
+             if ((value[12] != '+') && (value[12] != '-'))
+               return ASN1_VALUE_NOT_VALID;
+             for (k = 13; k < 17; k++)
+               if (!isdigit (value[k]))
+                 return ASN1_VALUE_NOT_VALID;
+             break;
+           default:
+             return ASN1_VALUE_NOT_FOUND;
+           }
+         _asn1_set_value (node, value, strlen (value) + 1);
        }
-       break;
-      }
-      p=p->right;
+      else
+       {                       /* GENERALIZED TIME */
+         if (value)
+           _asn1_set_value (node, value, strlen (value) + 1);
+       }
+      break;
+    case TYPE_OCTET_STRING:
+      if (len == 0)
+       len = strlen (value);
+      asn1_length_der (len, NULL, &len2);
+      temp = (unsigned char *) _asn1_alloca (len + len2);
+      if (temp == NULL)
+       return ASN1_MEM_ALLOC_ERROR;
+
+      asn1_octet_der (value, len, temp, &len2);
+      _asn1_set_value (node, temp, len2);
+      _asn1_afree (temp);
+      break;
+    case TYPE_GENERALSTRING:
+      if (len == 0)
+       len = strlen (value);
+      asn1_length_der (len, NULL, &len2);
+      temp = (unsigned char *) _asn1_alloca (len + len2);
+      if (temp == NULL)
+       return ASN1_MEM_ALLOC_ERROR;
+
+      asn1_octet_der (value, len, temp, &len2);
+      _asn1_set_value (node, temp, len2);
+      _asn1_afree (temp);
+      break;
+    case TYPE_BIT_STRING:
+      if (len == 0)
+       len = strlen (value);
+      asn1_length_der ((len >> 3) + 2, NULL, &len2);
+      temp = (unsigned char *) _asn1_alloca ((len >> 3) + 2 + len2);
+      if (temp == NULL)
+       return ASN1_MEM_ALLOC_ERROR;
+
+      asn1_bit_der (value, len, temp, &len2);
+      _asn1_set_value (node, temp, len2);
+      _asn1_afree (temp);
+      break;
+    case TYPE_CHOICE:
+      p = node->down;
+      while (p)
+       {
+         if (!strcmp (p->name, value))
+           {
+             p2 = node->down;
+             while (p2)
+               {
+                 if (p2 != p)
+                   {
+                     asn1_delete_structure (&p2);
+                     p2 = node->down;
+                   }
+                 else
+                   p2 = p2->right;
+               }
+             break;
+           }
+         p = p->right;
+       }
+      if (!p)
+       return ASN1_ELEMENT_NOT_FOUND;
+      break;
+    case TYPE_ANY:
+      asn1_length_der (len, NULL, &len2);
+      temp = (unsigned char *) _asn1_alloca (len + len2);
+      if (temp == NULL)
+       return ASN1_MEM_ALLOC_ERROR;
+
+      asn1_octet_der (value, len, temp, &len2);
+      _asn1_set_value (node, temp, len2);
+      _asn1_afree (temp);
+      break;
+    case TYPE_SEQUENCE_OF:
+    case TYPE_SET_OF:
+      if (strcmp (value, "NEW"))
+       return ASN1_VALUE_NOT_VALID;
+      _asn1_append_sequence_set (node);
+      break;
+    default:
+      return ASN1_ELEMENT_NOT_FOUND;
+      break;
     }
-    if(!p) return ASN1_ELEMENT_NOT_FOUND;
-    break;
-  case TYPE_ANY:
-    asn1_length_der(len,NULL,&len2);
-    temp=(unsigned char *)_asn1_alloca(len+len2);
-    if (temp==NULL) return ASN1_MEM_ALLOC_ERROR;
-
-    asn1_octet_der(value,len,temp,&len2);
-    _asn1_set_value(node,temp,len2);
-    _asn1_afree(temp);
-    break;
-  case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
-    if(strcmp(value,"NEW")) return ASN1_VALUE_NOT_VALID;    
-    _asn1_append_sequence_set(node);
-    break;
-  default:
-    return  ASN1_ELEMENT_NOT_FOUND;
-    break;
-  }
 
   return ASN1_SUCCESS;
 }
@@ -537,7 +652,7 @@ asn1_write_value(ASN1_TYPE node_root,const char *name,
                /* this strcpy is checked */ \
                strcpy(ptr, data); \
        }
-               
+
 #define ADD_STR_VALUE( ptr, ptr_size, data) \
        *len = strlen(data) + 1; \
        if (ptr_size < strlen(ptr)+(*len)) { \
@@ -614,124 +729,164 @@ asn1_write_value(ASN1_TYPE node_root,const char *name,
   *
   **/
 asn1_retCode
-asn1_read_value(ASN1_TYPE root,const char *name,void* ivalue, int *len)
+asn1_read_value (ASN1_TYPE root, const char *name, void *ivalue, int *len)
 {
-  node_asn *node,*p,*p2;
-  int len2,len3;
+  node_asn *node, *p, *p2;
+  int len2, len3;
   int value_size = *len;
-  unsigned charvalue = ivalue;
+  unsigned char *value = ivalue;
 
-  node=asn1_find_node(root,name);
-  if(node==NULL) return  ASN1_ELEMENT_NOT_FOUND;
+  node = asn1_find_node (root, name);
+  if (node == NULL)
+    return ASN1_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 ((type_field (node->type) != TYPE_NULL) &&
+      (type_field (node->type) != TYPE_CHOICE) &&
+      !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) &&
+      (node->value == NULL))
     return ASN1_VALUE_NOT_FOUND;
 
-  switch(type_field(node->type)){
-  case TYPE_NULL:
-    PUT_STR_VALUE( value, value_size, "NULL");
-    break;
-  case TYPE_BOOLEAN:
-    if((node->type&CONST_DEFAULT) && (node->value==NULL)){
-      p=node->down;
-      while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
-      if(p->type&CONST_TRUE) {
-       PUT_STR_VALUE( value, value_size, "TRUE");
-      } else {
-       PUT_STR_VALUE(value, value_size, "FALSE");
-      }
-    }
-    else if(node->value[0]=='T') {
-       PUT_STR_VALUE(value, value_size, "TRUE");
-    }
-    else {
-       PUT_STR_VALUE(value, value_size, "FALSE");
-    }
-    break;
-  case TYPE_INTEGER: case TYPE_ENUMERATED:
-    if((node->type&CONST_DEFAULT) && (node->value==NULL)){
-      p=node->down;
-      while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
-      if((isdigit(p->value[0])) || (p->value[0]=='-') || (p->value[0]=='+')){
-       if (_asn1_convert_integer(p->value,value,value_size, len) != 
-           ASN1_SUCCESS) 
-         return ASN1_MEM_ERROR;
-      }
-      else{ /* is an identifier like v1 */
-       p2=node->down;
-       while(p2){
-         if(type_field(p2->type)==TYPE_CONSTANT){
-           if((p2->name) && (!strcmp(p2->name,p->value))){
-             if (_asn1_convert_integer(p2->value,value,value_size, len) != 
-                 ASN1_SUCCESS) 
+  switch (type_field (node->type))
+    {
+    case TYPE_NULL:
+      PUT_STR_VALUE (value, value_size, "NULL");
+      break;
+    case TYPE_BOOLEAN:
+      if ((node->type & CONST_DEFAULT) && (node->value == NULL))
+       {
+         p = node->down;
+         while (type_field (p->type) != TYPE_DEFAULT)
+           p = p->right;
+         if (p->type & CONST_TRUE)
+           {
+             PUT_STR_VALUE (value, value_size, "TRUE");
+           }
+         else
+           {
+             PUT_STR_VALUE (value, value_size, "FALSE");
+           }
+       }
+      else if (node->value[0] == 'T')
+       {
+         PUT_STR_VALUE (value, value_size, "TRUE");
+       }
+      else
+       {
+         PUT_STR_VALUE (value, value_size, "FALSE");
+       }
+      break;
+    case TYPE_INTEGER:
+    case TYPE_ENUMERATED:
+      if ((node->type & CONST_DEFAULT) && (node->value == NULL))
+       {
+         p = node->down;
+         while (type_field (p->type) != TYPE_DEFAULT)
+           p = p->right;
+         if ((isdigit (p->value[0])) || (p->value[0] == '-')
+             || (p->value[0] == '+'))
+           {
+             if (_asn1_convert_integer
+                 (p->value, value, value_size, len) != ASN1_SUCCESS)
                return ASN1_MEM_ERROR;
-             break;
            }
-         }
-         p2=p2->right;
+         else
+           {                   /* is an identifier like v1 */
+             p2 = node->down;
+             while (p2)
+               {
+                 if (type_field (p2->type) == TYPE_CONSTANT)
+                   {
+                     if ((p2->name) && (!strcmp (p2->name, p->value)))
+                       {
+                         if (_asn1_convert_integer
+                             (p2->value, value, value_size,
+                              len) != ASN1_SUCCESS)
+                           return ASN1_MEM_ERROR;
+                         break;
+                       }
+                   }
+                 p2 = p2->right;
+               }
+           }
        }
-      }
-    }
-    else{
-      len2=-1;
-      if (asn1_get_octet_der(node->value,node->value_len,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
-    }
-    break;
-  case TYPE_OBJECT_ID:
-    if(node->type&CONST_ASSIGN){
-      value[0]=0;
-      p=node->down;
-      while(p){
-       if(type_field(p->type)==TYPE_CONSTANT){
-         ADD_STR_VALUE(value,value_size,p->value);       
-         if(p->right) {
-         ADD_STR_VALUE(value,value_size,".");
-         }
+      else
+       {
+         len2 = -1;
+         if (asn1_get_octet_der
+             (node->value, node->value_len, &len2, value, value_size,
+              len) != ASN1_SUCCESS)
+           return ASN1_MEM_ERROR;
+       }
+      break;
+    case TYPE_OBJECT_ID:
+      if (node->type & CONST_ASSIGN)
+       {
+         value[0] = 0;
+         p = node->down;
+         while (p)
+           {
+             if (type_field (p->type) == TYPE_CONSTANT)
+               {
+                 ADD_STR_VALUE (value, value_size, p->value);
+                 if (p->right)
+                   {
+                     ADD_STR_VALUE (value, value_size, ".");
+                   }
+               }
+             p = p->right;
+           }
+         *len = strlen (value) + 1;
+       }
+      else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
+       {
+         p = node->down;
+         while (type_field (p->type) != TYPE_DEFAULT)
+           p = p->right;
+         PUT_STR_VALUE (value, value_size, p->value);
        }
-       p=p->right;
-      }
-      *len = strlen(value) + 1;
-    } 
-    else if((node->type&CONST_DEFAULT) && (node->value==NULL)){
-      p=node->down;
-      while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
-      PUT_STR_VALUE(value, value_size, p->value);
-      }
-    else {
-      PUT_STR_VALUE(value, value_size, node->value);
+      else
+       {
+         PUT_STR_VALUE (value, value_size, node->value);
+       }
+      break;
+    case TYPE_TIME:
+      PUT_STR_VALUE (value, value_size, node->value);
+      break;
+    case TYPE_OCTET_STRING:
+      len2 = -1;
+      if (asn1_get_octet_der
+         (node->value, node->value_len, &len2, value, value_size,
+          len) != ASN1_SUCCESS)
+       return ASN1_MEM_ERROR;
+      break;
+    case TYPE_GENERALSTRING:
+      len2 = -1;
+      if (asn1_get_octet_der
+         (node->value, node->value_len, &len2, value, value_size,
+          len) != ASN1_SUCCESS)
+       return ASN1_MEM_ERROR;
+      break;
+    case TYPE_BIT_STRING:
+      len2 = -1;
+      if (asn1_get_bit_der
+         (node->value, node->value_len, &len2, value, value_size,
+          len) != ASN1_SUCCESS)
+       return ASN1_MEM_ERROR;
+      break;
+    case TYPE_CHOICE:
+      PUT_STR_VALUE (value, value_size, node->down->name);
+      break;
+    case TYPE_ANY:
+      len3 = -1;
+      len2 = asn1_get_length_der (node->value, node->value_len, &len3);
+      if (len2 < 0)
+       return ASN1_DER_ERROR;
+      PUT_VALUE (value, value_size, node->value + len3, len2);
+      break;
+    default:
+      return ASN1_ELEMENT_NOT_FOUND;
+      break;
     }
-    break;
-  case TYPE_TIME:
-    PUT_STR_VALUE( value, value_size, node->value);
-    break;
-  case TYPE_OCTET_STRING:
-    len2=-1;
-    if (asn1_get_octet_der(node->value,node->value_len,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
-    break;
-  case TYPE_GENERALSTRING:
-    len2=-1;
-    if (asn1_get_octet_der(node->value,node->value_len,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
-    break;
-  case TYPE_BIT_STRING:
-    len2=-1;
-    if (asn1_get_bit_der(node->value,node->value_len,&len2,value,value_size,len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
-    break;
-  case TYPE_CHOICE:
-    PUT_STR_VALUE( value, value_size, node->down->name);
-    break; 
-  case TYPE_ANY:
-    len3=-1;
-    len2=asn1_get_length_der(node->value,node->value_len,&len3);
-    if (len2 < 0) return ASN1_DER_ERROR;
-    PUT_VALUE( value, value_size, node->value+len3, len2);
-    break;
-  default:
-    return  ASN1_ELEMENT_NOT_FOUND;
-    break;
-  }
   return ASN1_SUCCESS;
 }
 
@@ -755,76 +910,102 @@ asn1_read_value(ASN1_TYPE root,const char *name,void* ivalue, int *len)
   *   ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
   *
   **/
-asn1_retCode 
-asn1_read_tag(node_asn *root,const char *name,int *tagValue, int *classValue)
+asn1_retCode
+asn1_read_tag (node_asn * root, const char *name, int *tagValue,
+              int *classValue)
 {
-  node_asn *node,*p,*pTag;
-  node=asn1_find_node(root,name);
-  if(node==NULL) return  ASN1_ELEMENT_NOT_FOUND;
+  node_asn *node, *p, *pTag;
 
-  p=node->down;
+  node = asn1_find_node (root, name);
+  if (node == NULL)
+    return ASN1_ELEMENT_NOT_FOUND;
+
+  p = node->down;
 
   /* pTag will points to the IMPLICIT TAG */
-  pTag=NULL;
-  if(node->type&CONST_TAG){
-    while(p){
-      if(type_field(p->type)==TYPE_TAG){
-       if((p->type&CONST_IMPLICIT) && (pTag==NULL))
-         pTag=p;
-       else if(p->type&CONST_EXPLICIT)
-         pTag=NULL;
-      }
-      p=p->right;
+  pTag = NULL;
+  if (node->type & CONST_TAG)
+    {
+      while (p)
+       {
+         if (type_field (p->type) == TYPE_TAG)
+           {
+             if ((p->type & CONST_IMPLICIT) && (pTag == NULL))
+               pTag = p;
+             else if (p->type & CONST_EXPLICIT)
+               pTag = NULL;
+           }
+         p = p->right;
+       }
     }
-  }
-
-  if(pTag){
-    *tagValue=strtoul(pTag->value,NULL,10);
-  
-    if(pTag->type&CONST_APPLICATION) *classValue=ASN1_CLASS_APPLICATION;
-    else if(pTag->type&CONST_UNIVERSAL) *classValue=ASN1_CLASS_UNIVERSAL;
-    else if(pTag->type&CONST_PRIVATE) *classValue=ASN1_CLASS_PRIVATE;
-    else *classValue=ASN1_CLASS_CONTEXT_SPECIFIC;
-  }
-  else{
-    *classValue=ASN1_CLASS_UNIVERSAL;
-
-    switch(type_field(node->type)){
-    case TYPE_NULL:
-      *tagValue=ASN1_TAG_NULL;break;
-    case TYPE_BOOLEAN:
-      *tagValue=ASN1_TAG_BOOLEAN;break;
-    case TYPE_INTEGER:
-      *tagValue=ASN1_TAG_INTEGER;break;
-    case TYPE_ENUMERATED:
-      *tagValue=ASN1_TAG_ENUMERATED;break;
-    case TYPE_OBJECT_ID:
-      *tagValue=ASN1_TAG_OBJECT_ID;break;
-    case TYPE_TIME:
-      if(node->type&CONST_UTC){
-       *tagValue=ASN1_TAG_UTCTime;
-      }
-      else *tagValue=ASN1_TAG_GENERALIZEDTime;
-      break;
-    case TYPE_OCTET_STRING:
-      *tagValue=ASN1_TAG_OCTET_STRING;break;
-    case TYPE_GENERALSTRING:
-      *tagValue=ASN1_TAG_GENERALSTRING;break;
-    case TYPE_BIT_STRING:
-      *tagValue=ASN1_TAG_BIT_STRING;break;
-    case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
-      *tagValue=ASN1_TAG_SEQUENCE;break;
-    case TYPE_SET: case TYPE_SET_OF:
-      *tagValue=ASN1_TAG_SET;break;
-    case TYPE_TAG:
-    case TYPE_CHOICE:
-    case TYPE_ANY:
-      break;
-    default:
-      break;
+
+  if (pTag)
+    {
+      *tagValue = strtoul (pTag->value, NULL, 10);
+
+      if (pTag->type & CONST_APPLICATION)
+       *classValue = ASN1_CLASS_APPLICATION;
+      else if (pTag->type & CONST_UNIVERSAL)
+       *classValue = ASN1_CLASS_UNIVERSAL;
+      else if (pTag->type & CONST_PRIVATE)
+       *classValue = ASN1_CLASS_PRIVATE;
+      else
+       *classValue = ASN1_CLASS_CONTEXT_SPECIFIC;
+    }
+  else
+    {
+      *classValue = ASN1_CLASS_UNIVERSAL;
+
+      switch (type_field (node->type))
+       {
+       case TYPE_NULL:
+         *tagValue = ASN1_TAG_NULL;
+         break;
+       case TYPE_BOOLEAN:
+         *tagValue = ASN1_TAG_BOOLEAN;
+         break;
+       case TYPE_INTEGER:
+         *tagValue = ASN1_TAG_INTEGER;
+         break;
+       case TYPE_ENUMERATED:
+         *tagValue = ASN1_TAG_ENUMERATED;
+         break;
+       case TYPE_OBJECT_ID:
+         *tagValue = ASN1_TAG_OBJECT_ID;
+         break;
+       case TYPE_TIME:
+         if (node->type & CONST_UTC)
+           {
+             *tagValue = ASN1_TAG_UTCTime;
+           }
+         else
+           *tagValue = ASN1_TAG_GENERALIZEDTime;
+         break;
+       case TYPE_OCTET_STRING:
+         *tagValue = ASN1_TAG_OCTET_STRING;
+         break;
+       case TYPE_GENERALSTRING:
+         *tagValue = ASN1_TAG_GENERALSTRING;
+         break;
+       case TYPE_BIT_STRING:
+         *tagValue = ASN1_TAG_BIT_STRING;
+         break;
+       case TYPE_SEQUENCE:
+       case TYPE_SEQUENCE_OF:
+         *tagValue = ASN1_TAG_SEQUENCE;
+         break;
+       case TYPE_SET:
+       case TYPE_SET_OF:
+         *tagValue = ASN1_TAG_SET;
+         break;
+       case TYPE_TAG:
+       case TYPE_CHOICE:
+       case TYPE_ANY:
+         break;
+       default:
+         break;
+       }
     }
-  }
 
 
   return ASN1_SUCCESS;
index b1224da03a37df1a6354c2f1e5ccda683552cc0d..0d3e4a2b22389508ec1629a6bff0652b7ed28cfd 100644 (file)
 #define LIBTASN1_ERROR_ENTRY(name) \
        { #name, name }
 
-struct libtasn1_error_entry {
-       const char *name;
-       int  number;
+struct libtasn1_error_entry
+{
+  const char *name;
+  int number;
 };
 typedef struct libtasn1_error_entry libtasn1_error_entry;
 
 static const libtasn1_error_entry error_algorithms[] = {
-       LIBTASN1_ERROR_ENTRY( ASN1_SUCCESS ),
-       LIBTASN1_ERROR_ENTRY( ASN1_FILE_NOT_FOUND ),
-       LIBTASN1_ERROR_ENTRY( ASN1_ELEMENT_NOT_FOUND ),
-       LIBTASN1_ERROR_ENTRY( ASN1_IDENTIFIER_NOT_FOUND ),
-       LIBTASN1_ERROR_ENTRY( ASN1_DER_ERROR ),
-       LIBTASN1_ERROR_ENTRY( ASN1_VALUE_NOT_FOUND ),
-       LIBTASN1_ERROR_ENTRY( ASN1_GENERIC_ERROR ),
-       LIBTASN1_ERROR_ENTRY( ASN1_VALUE_NOT_VALID ),
-       LIBTASN1_ERROR_ENTRY( ASN1_TAG_ERROR ),
-       LIBTASN1_ERROR_ENTRY( ASN1_TAG_IMPLICIT ),
-       LIBTASN1_ERROR_ENTRY( ASN1_ERROR_TYPE_ANY ),
-       LIBTASN1_ERROR_ENTRY( ASN1_SYNTAX_ERROR ),
-       LIBTASN1_ERROR_ENTRY( ASN1_MEM_ERROR ),
-       LIBTASN1_ERROR_ENTRY( ASN1_MEM_ALLOC_ERROR ),
-       LIBTASN1_ERROR_ENTRY( ASN1_DER_OVERFLOW ),
-       LIBTASN1_ERROR_ENTRY( ASN1_NAME_TOO_LONG ),
-       LIBTASN1_ERROR_ENTRY( ASN1_ARRAY_ERROR ),
-       LIBTASN1_ERROR_ENTRY( ASN1_ELEMENT_NOT_EMPTY ),
-       {0}
+  LIBTASN1_ERROR_ENTRY (ASN1_SUCCESS),
+  LIBTASN1_ERROR_ENTRY (ASN1_FILE_NOT_FOUND),
+  LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_FOUND),
+  LIBTASN1_ERROR_ENTRY (ASN1_IDENTIFIER_NOT_FOUND),
+  LIBTASN1_ERROR_ENTRY (ASN1_DER_ERROR),
+  LIBTASN1_ERROR_ENTRY (ASN1_VALUE_NOT_FOUND),
+  LIBTASN1_ERROR_ENTRY (ASN1_GENERIC_ERROR),
+  LIBTASN1_ERROR_ENTRY (ASN1_VALUE_NOT_VALID),
+  LIBTASN1_ERROR_ENTRY (ASN1_TAG_ERROR),
+  LIBTASN1_ERROR_ENTRY (ASN1_TAG_IMPLICIT),
+  LIBTASN1_ERROR_ENTRY (ASN1_ERROR_TYPE_ANY),
+  LIBTASN1_ERROR_ENTRY (ASN1_SYNTAX_ERROR),
+  LIBTASN1_ERROR_ENTRY (ASN1_MEM_ERROR),
+  LIBTASN1_ERROR_ENTRY (ASN1_MEM_ALLOC_ERROR),
+  LIBTASN1_ERROR_ENTRY (ASN1_DER_OVERFLOW),
+  LIBTASN1_ERROR_ENTRY (ASN1_NAME_TOO_LONG),
+  LIBTASN1_ERROR_ENTRY (ASN1_ARRAY_ERROR),
+  LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_EMPTY),
+  {0}
 };
 
 #define LIBTASN1_ERROR_LOOP(b) \
@@ -74,16 +75,16 @@ static const libtasn1_error_entry error_algorithms[] = {
   * This function is like perror(). The only difference is that it
   * accepts an error returned by a libtasn1 function.
   **/
-void libtasn1_perror(asn1_retCode error)
+void
+libtasn1_perror (asn1_retCode error)
 {
-       const char *ret = NULL;
+  const char *ret = NULL;
+
+  /* avoid prefix */
+  LIBTASN1_ERROR_ALG_LOOP (ret = p->name + sizeof ("ASN1_") - 1);
 
-       /* avoid prefix */
-       LIBTASN1_ERROR_ALG_LOOP(ret =
-                             p->name + sizeof("ASN1_") - 1);
+  fprintf (stderr, "LIBTASN1 ERROR: %s\n", ret);
 
-       _libtasn1_log( "LIBTASN1 ERROR: %s\n", ret);
-       
 }
 
 
@@ -97,34 +98,38 @@ void libtasn1_perror(asn1_retCode error)
   * Returns: Pointer to static zero-terminated string describing error
   *   code.
   **/
-const char* libtasn1_strerror(asn1_retCode error)
+const char *
+libtasn1_strerror (asn1_retCode error)
 {
-       const char *ret = NULL;
+  const char *ret = NULL;
 
-       /* avoid prefix */
-       LIBTASN1_ERROR_ALG_LOOP(ret =
-                             p->name + sizeof("ASN1_") - 1);
+  /* avoid prefix */
+  LIBTASN1_ERROR_ALG_LOOP (ret = p->name + sizeof ("ASN1_") - 1);
 
-       return ret;
+  return ret;
 }
 
 /* this function will output a message.
  */
 #ifdef LIBTASN1_DEBUG
-void _libtasn1_log( const char *fmt, ...) {
- va_list args;
- char str[MAX_LOG_SIZE];
+void
+_libtasn1_log (const char *fmt, ...)
+{
+  va_list args;
+  char str[MAX_LOG_SIZE];
 
va_start(args,fmt);
vsprintf( str,fmt,args); /* Flawfinder: ignore */
va_end(args);
 va_start (args, fmt);
 vsprintf (str, fmt, args);   /* Flawfinder: ignore */
 va_end (args);
 
fprintf(stderr, str);
 fprintf (stderr, str);
 
- return;
 return;
 }
 #else /* not DEBUG */
-void _libtasn1_log( const char *fmt, ...) {
+void
+_libtasn1_log (const char *fmt, ...)
+{
   return;
 }
 #endif /* DEBUG */
index 7946b3ec5624466dd64dfaad5ec1c56b2d3ba2af..a09364315b626dd17218c36eca84fd169d00d323 100644 (file)
  *
  * They should be used only with null terminated strings.
  */
-void _asn1_str_cat( char* dest, size_t dest_tot_size, const char* src) {
-size_t str_size = strlen(src);
-size_t dest_size = strlen(dest);
+void
+_asn1_str_cat (char *dest, size_t dest_tot_size, const char *src)
+{
+  size_t str_size = strlen (src);
+  size_t dest_size = strlen (dest);
 
-       if ( dest_tot_size - dest_size > str_size) {
-               strcat( dest, src);
-       } else {
-               if ( dest_tot_size - dest_size > 0) {
-                       strncat( dest, src, (dest_tot_size - dest_size) -1);
-                       dest[dest_tot_size-1] = 0;
-               }
+  if (dest_tot_size - dest_size > str_size)
+    {
+      strcat (dest, src);
+    }
+  else
+    {
+      if (dest_tot_size - dest_size > 0)
+       {
+         strncat (dest, src, (dest_tot_size - dest_size) - 1);
+         dest[dest_tot_size - 1] = 0;
        }
+    }
 }
 
-void _asn1_str_cpy( char* dest, size_t dest_tot_size, const char* src) {
-size_t str_size = strlen(src);
+void
+_asn1_str_cpy (char *dest, size_t dest_tot_size, const char *src)
+{
+  size_t str_size = strlen (src);
 
-       if ( dest_tot_size > str_size) {
-               strcpy( dest, src);
-       } else {
-               if ( dest_tot_size > 0) {
-                       strncpy( dest, src, (dest_tot_size) -1);
-                       dest[dest_tot_size-1] = 0;
-               }
+  if (dest_tot_size > str_size)
+    {
+      strcpy (dest, src);
+    }
+  else
+    {
+      if (dest_tot_size > 0)
+       {
+         strncpy (dest, src, (dest_tot_size) - 1);
+         dest[dest_tot_size - 1] = 0;
        }
+    }
 }
index 1c2509aa959e5a4f30580808325e3fba14e0d215..95d598a638099aedb888dce52b188e35ce9a77dc 100644 (file)
@@ -31,7 +31,7 @@ extern "C"
 {
 #endif
 
-#define LIBTASN1_VERSION "0.3.2"
+#define LIBTASN1_VERSION "0.3.4"
 
 #include <sys/types.h>
 #include <time.h>
@@ -124,9 +124,9 @@ extern "C"
 
   struct static_struct_asn
   {
-    char *name;                        /* Node name */
+    const char *name;                  /* Node name */
     unsigned int type;         /* Node type */
-    unsigned char *value;      /* Node value */
+    const void *value; /* Node value */
   };
 
   typedef struct static_struct_asn ASN1_ARRAY_TYPE;
@@ -210,7 +210,7 @@ extern "C"
   /* DER utility functions. */
 
   int asn1_get_tag_der (const unsigned char *der, int der_len,
-                       unsigned char *class, int *len, unsigned long *tag);
+                       unsigned char *cls, int *len, unsigned long *tag);
 
   void asn1_octet_der (const unsigned char *str, int str_len,
                       unsigned char *der, int *der_len);
index 05048162e10871f562284a38a1e53b4d748d2843..fbb6a8005b1b135e5f93c517ee3455b0650eeeea 100644 (file)
 #include "structure.h"
 #include "element.h"
 
-char _asn1_identifierMissing[MAX_NAME_SIZE+1]; /* identifier name not found */
+char _asn1_identifierMissing[MAX_NAME_SIZE + 1];       /* identifier name not found */
 
 /***********************************************/
 /* Type: list_type                             */
 /* Description: type used in the list during   */
 /* the structure creation.                     */
 /***********************************************/
-typedef struct list_struct{
-  node_asn           *node;
+typedef struct list_struct
+{
+  node_asn *node;
   struct list_struct *next;
 } list_type;
 
 
 /* Pointer to the first element of the list */
-list_type *firstElement=NULL;
+list_type *firstElement = NULL;
 
 /******************************************************/
 /* Function : _asn1_add_node                          */
@@ -53,30 +54,27 @@ list_type *firstElement=NULL;
 /* Return: pointer to the new element.                */
 /******************************************************/
 node_asn *
-_asn1_add_node(unsigned int type)
+_asn1_add_node (unsigned int type)
 {
   list_type *listElement;
   node_asn *punt;
 
-  punt=(node_asn *) _asn1_malloc(sizeof(node_asn));
-  if (punt==NULL) return NULL;
-  
-  listElement=(list_type *) _asn1_malloc(sizeof(list_type));
-  if(listElement==NULL){
-    _asn1_free(punt);
+  punt = (node_asn *) _asn1_calloc (1, sizeof (node_asn));
+  if (punt == NULL)
     return NULL;
-  }
 
-  listElement->node=punt;
-  listElement->next=firstElement;
-  firstElement=listElement;
+  listElement = (list_type *) _asn1_malloc (sizeof (list_type));
+  if (listElement == NULL)
+    {
+      _asn1_free (punt);
+      return NULL;
+    }
+
+  listElement->node = punt;
+  listElement->next = firstElement;
+  firstElement = listElement;
 
-  punt->left=NULL;
-  punt->name=NULL;
-  punt->type=type; 
-  punt->value=NULL;
-  punt->down=NULL;
-  punt->right=NULL; 
+  punt->type = type;
 
   return punt;
 }
@@ -94,75 +92,97 @@ _asn1_add_node(unsigned int type)
  * Return value: the searching result. NULL if not found.
  **/
 ASN1_TYPE
-asn1_find_node(ASN1_TYPE pointer, const char *name)
+asn1_find_node (ASN1_TYPE pointer, const char *name)
 {
   node_asn *p;
-  char *n_end,n[MAX_NAME_SIZE+1];
+  char *n_end, n[MAX_NAME_SIZE + 1];
   const char *n_start;
 
-  if(pointer == NULL) return NULL;
+  if (pointer == NULL)
+    return NULL;
 
-  if(name==NULL) return NULL;
+  if (name == NULL)
+    return NULL;
 
-  p=pointer;
-  n_start=name;
+  p = pointer;
+  n_start = name;
 
-  if(p->name != NULL){ /* has *pointer got a name ? */
-    n_end=strchr(n_start,'.');     /* search the first dot */
-    if(n_end){
-      memcpy(n,n_start,n_end-n_start);
-      n[n_end-n_start]=0;
-      n_start=n_end;
-      n_start++;
-    }
-    else{
-      _asn1_str_cpy(n,sizeof(n),n_start);
-      n_start=NULL;
-    }
-    
-    while(p){
-      if((p->name) && (!strcmp(p->name,n))) break;
-      else p=p->right;
-    } /* while */
-    
-    if(p==NULL) return NULL;
-  }
-  else{ /* *pointer doesn't have a name */
-    if(n_start[0]==0)
-      return p;
-  }
-
-  while(n_start){   /* Has the end of NAME been reached? */
-    n_end=strchr(n_start,'.');    /* search the next dot */
-    if(n_end){
-      memcpy(n,n_start,n_end-n_start);
-      n[n_end-n_start]=0;
-      n_start=n_end;
-      n_start++;
+  if (p->name != NULL)
+    {                          /* has *pointer got a name ? */
+      n_end = strchr (n_start, '.');   /* search the first dot */
+      if (n_end)
+       {
+         memcpy (n, n_start, n_end - n_start);
+         n[n_end - n_start] = 0;
+         n_start = n_end;
+         n_start++;
+       }
+      else
+       {
+         _asn1_str_cpy (n, sizeof (n), n_start);
+         n_start = NULL;
+       }
+
+      while (p)
+       {
+         if ((p->name) && (!strcmp (p->name, n)))
+           break;
+         else
+           p = p->right;
+       }                       /* while */
+
+      if (p == NULL)
+       return NULL;
     }
-    else{
-      _asn1_str_cpy(n,sizeof(n),n_start);
-      n_start=NULL;
+  else
+    {                          /* *pointer doesn't have a name */
+      if (n_start[0] == 0)
+       return p;
     }
 
-    if(p->down==NULL) return NULL;
+  while (n_start)
+    {                          /* Has the end of NAME been reached? */
+      n_end = strchr (n_start, '.');   /* search the next dot */
+      if (n_end)
+       {
+         memcpy (n, n_start, n_end - n_start);
+         n[n_end - n_start] = 0;
+         n_start = n_end;
+         n_start++;
+       }
+      else
+       {
+         _asn1_str_cpy (n, sizeof (n), n_start);
+         n_start = NULL;
+       }
+
+      if (p->down == NULL)
+       return NULL;
 
-    p=p->down;
+      p = p->down;
 
-    /* The identifier "?LAST" indicates the last element 
-       in the right chain. */
-    if(!strcmp(n,"?LAST")){
-      if(p==NULL) return NULL;
-      while(p->right) p=p->right;
-    }
-    else{   /* no "?LAST" */
-      while(p){
-       if((p->name) && (!strcmp(p->name,n))) break;
-       else p=p->right;
-      }
-      if(p==NULL) return NULL;
-    }
-  } /* while */
+      /* The identifier "?LAST" indicates the last element 
+         in the right chain. */
+      if (!strcmp (n, "?LAST"))
+       {
+         if (p == NULL)
+           return NULL;
+         while (p->right)
+           p = p->right;
+       }
+      else
+       {                       /* no "?LAST" */
+         while (p)
+           {
+             if ((p->name) && (!strcmp (p->name, n)))
+               break;
+             else
+               p = p->right;
+           }
+         if (p == NULL)
+           return NULL;
+       }
+    }                          /* while */
 
   return p;
 }
@@ -179,21 +199,26 @@ asn1_find_node(ASN1_TYPE pointer, const char *name)
 /* Return: pointer to the NODE_ASN element.                       */
 /******************************************************************/
 node_asn *
-_asn1_set_value(node_asn *node,const unsigned char *value,unsigned int len)
+_asn1_set_value (node_asn * node, const void *_value, unsigned int len)
 {
-
-  if(node==NULL) return node;
-  if(node->value){
-    _asn1_free(node->value);
-    node->value=NULL;  
-    node->value_len = 0;
-  }
-  if(!len) return node;
-  node->value=(unsigned char *) _asn1_malloc(len);
-  if (node->value==NULL) return NULL;
+  const unsigned char *value = _value;
+
+  if (node == NULL)
+    return node;
+  if (node->value)
+    {
+      _asn1_free (node->value);
+      node->value = NULL;
+      node->value_len = 0;
+    }
+  if (!len)
+    return node;
+  node->value = (unsigned char *) _asn1_malloc (len);
+  if (node->value == NULL)
+    return NULL;
   node->value_len = len;
-  
-  memcpy(node->value,value,len);
+
+  memcpy (node->value, value, len);
   return node;
 }
 
@@ -208,23 +233,28 @@ _asn1_set_value(node_asn *node,const unsigned char *value,unsigned int len)
 /* Return: pointer to the NODE_ASN element.                       */
 /******************************************************************/
 node_asn *
-_asn1_set_name(node_asn *node,const char *name)
+_asn1_set_name (node_asn * node, const char *name)
 {
-  if(node==NULL) return node;
+  if (node == NULL)
+    return node;
 
-  if(node->name){
-    _asn1_free(node->name);
-    node->name=NULL;
-  }
+  if (node->name)
+    {
+      _asn1_free (node->name);
+      node->name = NULL;
+    }
 
-  if(name==NULL) return node;
+  if (name == NULL)
+    return node;
 
-  if(strlen(name))
-       {
-       node->name=(char *) _asn1_strdup( name);
-       if (node->name==NULL) return NULL;
-      }
-  else node->name=NULL;
+  if (strlen (name))
+    {
+      node->name = (char *) _asn1_strdup (name);
+      if (node->name == NULL)
+       return NULL;
+    }
+  else
+    node->name = NULL;
   return node;
 }
 
@@ -238,11 +268,13 @@ _asn1_set_name(node_asn *node,const char *name)
 /* Return: pointer to *NODE.                                      */
 /******************************************************************/
 node_asn *
-_asn1_set_right(node_asn *node,node_asn *right)
+_asn1_set_right (node_asn * node, node_asn * right)
 {
-  if(node==NULL) return node;
-  node->right=right;
-  if(right) right->left=node;
+  if (node == NULL)
+    return node;
+  node->right = right;
+  if (right)
+    right->left = node;
   return node;
 }
 
@@ -255,9 +287,10 @@ _asn1_set_right(node_asn *node,node_asn *right)
 /* Return: field RIGHT of NODE.                                   */
 /******************************************************************/
 node_asn *
-_asn1_get_right(node_asn *node)
+_asn1_get_right (node_asn * node)
 {
-  if(node==NULL) return NULL;
+  if (node == NULL)
+    return NULL;
   return node->right;
 }
 
@@ -269,13 +302,15 @@ _asn1_get_right(node_asn *node)
 /* Return: pointer to the last element along the right chain.     */
 /******************************************************************/
 node_asn *
-_asn1_get_last_right(node_asn *node)
+_asn1_get_last_right (node_asn * node)
 {
   node_asn *p;
 
-  if(node==NULL) return NULL;
-  p=node;
-  while(p->right) p=p->right;
+  if (node == NULL)
+    return NULL;
+  p = node;
+  while (p->right)
+    p = p->right;
   return p;
 }
 
@@ -289,11 +324,13 @@ _asn1_get_last_right(node_asn *node)
 /* Return: pointer to *NODE.                                      */
 /******************************************************************/
 node_asn *
-_asn1_set_down(node_asn *node,node_asn *down)
+_asn1_set_down (node_asn * node, node_asn * down)
 {
-  if(node==NULL) return node;
-  node->down=down;
-  if(down) down->left=node;
+  if (node == NULL)
+    return node;
+  node->down = down;
+  if (down)
+    down->left = node;
   return node;
 }
 
@@ -306,9 +343,10 @@ _asn1_set_down(node_asn *node,node_asn *down)
 /* Return: field DOWN of NODE.                                    */
 /******************************************************************/
 node_asn *
-_asn1_get_down(node_asn *node)
+_asn1_get_down (node_asn * node)
 {
-  if(node==NULL) return NULL;
+  if (node == NULL)
+    return NULL;
   return node->down;
 }
 
@@ -320,9 +358,10 @@ _asn1_get_down(node_asn *node)
 /* Return: a null terminated string.                              */
 /******************************************************************/
 char *
-_asn1_get_name(node_asn *node)
+_asn1_get_name (node_asn * node)
 {
-  if(node==NULL) return NULL;
+  if (node == NULL)
+    return NULL;
   return node->name;
 }
 
@@ -338,10 +377,11 @@ _asn1_get_name(node_asn *node)
 /* Return: NODE pointer.                                          */
 /******************************************************************/
 node_asn *
-_asn1_mod_type(node_asn *node,unsigned int value)
+_asn1_mod_type (node_asn * node, unsigned int value)
 {
-  if(node==NULL) return node;
-  node->type|=value;
+  if (node == NULL)
+    return node;
+  node->type |= value;
   return node;
 }
 
@@ -354,15 +394,16 @@ _asn1_mod_type(node_asn *node,unsigned int value)
 /*   node: NODE_ASN element pointer.                              */
 /******************************************************************/
 void
-_asn1_remove_node(node_asn *node)
+_asn1_remove_node (node_asn * node)
 {
-  if(node==NULL) return;
-
-  if (node->name!=NULL)
-         _asn1_free(node->name);
-  if (node->value!=NULL)
-         _asn1_free(node->value);
-  _asn1_free(node);
+  if (node == NULL)
+    return;
+
+  if (node->name != NULL)
+    _asn1_free (node->name);
+  if (node->value != NULL)
+    _asn1_free (node->value);
+  _asn1_free (node);
 }
 
 /******************************************************************/
@@ -373,15 +414,17 @@ _asn1_remove_node(node_asn *node)
 /* Return: Null if not found.                                     */
 /******************************************************************/
 node_asn *
-_asn1_find_up(node_asn *node)
+_asn1_find_up (node_asn * node)
 {
   node_asn *p;
 
-  if(node==NULL) return NULL;
+  if (node == NULL)
+    return NULL;
 
-  p=node;
+  p = node;
 
-  while((p->left!=NULL) && (p->left->right==p)) p=p->left;
+  while ((p->left != NULL) && (p->left->right == p))
+    p = p->left;
 
   return p->left;
 }
@@ -392,15 +435,16 @@ _asn1_find_up(node_asn *node)
 /*  pointed by them).                                             */
 /******************************************************************/
 void
-_asn1_delete_list(void)
+_asn1_delete_list (void)
 {
   list_type *listElement;
 
-  while(firstElement){
-    listElement=firstElement;
-    firstElement=firstElement->next;
-    _asn1_free(listElement);
-  }
+  while (firstElement)
+    {
+      listElement = firstElement;
+      firstElement = firstElement->next;
+      _asn1_free (listElement);
+    }
 }
 
 /******************************************************************/
@@ -409,44 +453,50 @@ _asn1_delete_list(void)
 /*  pointed by them.                                              */
 /******************************************************************/
 void
-_asn1_delete_list_and_nodes(void)
+_asn1_delete_list_and_nodes (void)
 {
   list_type *listElement;
 
-  while(firstElement){
-    listElement=firstElement;
-    firstElement=firstElement->next;
-    _asn1_remove_node(listElement->node);
-    _asn1_free(listElement);
-  }
+  while (firstElement)
+    {
+      listElement = firstElement;
+      firstElement = firstElement->next;
+      _asn1_remove_node (listElement->node);
+      _asn1_free (listElement);
+    }
 }
 
 
 char *
-_asn1_ltostr(long v,char *str)
+_asn1_ltostr (long v, char *str)
 {
-  long d,r;
+  long d, r;
   char temp[20];
-  int count,k,start;
-
-  if(v<0){
-    str[0]='-';
-    start=1;
-    v=-v;
-  }
-  else start=0;
-
-  count=0;
-  do{
-    d=v/10;
-    r=v-d*10;
-    temp[start+count]='0'+(char)r;
-    count++;
-    v=d;
-  }while(v);
-
-  for(k=0;k<count;k++) str[k+start]=temp[start+count-k-1];
-  str[count+start]=0;
+  int count, k, start;
+
+  if (v < 0)
+    {
+      str[0] = '-';
+      start = 1;
+      v = -v;
+    }
+  else
+    start = 0;
+
+  count = 0;
+  do
+    {
+      d = v / 10;
+      r = v - d * 10;
+      temp[start + count] = '0' + (char) r;
+      count++;
+      v = d;
+    }
+  while (v);
+
+  for (k = 0; k < count; k++)
+    str[k + start] = temp[start + count - k - 1];
+  str[count + start] = 0;
   return str;
 }
 
@@ -461,47 +511,59 @@ _asn1_ltostr(long v,char *str)
 /*   ASN1_ELEMENT_NOT_FOUND if NODE is NULL,                       */
 /*   otherwise ASN1_SUCCESS                                             */
 /******************************************************************/
-asn1_retCode 
-_asn1_change_integer_value(ASN1_TYPE node)
+asn1_retCode
+_asn1_change_integer_value (ASN1_TYPE node)
 {
   node_asn *p;
   unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
-  unsigned char val2[SIZEOF_UNSIGNED_LONG_INT+1];
+  unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1];
   int len;
 
-  if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
+  if (node == NULL)
+    return ASN1_ELEMENT_NOT_FOUND;
 
-  p=node;
-  while(p){
-    if((type_field(p->type)==TYPE_INTEGER) && (p->type&CONST_ASSIGN)){
-      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);
-      }
-    }
+  p = node;
+  while (p)
+    {
+      if ((type_field (p->type) == TYPE_INTEGER) && (p->type & CONST_ASSIGN))
+       {
+         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;
-         }
+      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 ASN1_SUCCESS;
 }
@@ -517,127 +579,171 @@ _asn1_change_integer_value(ASN1_TYPE node)
 /*   otherwise ASN1_SUCCESS                                             */
 /******************************************************************/
 asn1_retCode
-_asn1_expand_object_id(ASN1_TYPE node)
+_asn1_expand_object_id (ASN1_TYPE node)
 {
-  node_asn *p,*p2,*p3,*p4,*p5;
-  char name_root[MAX_NAME_SIZE],name2[2*MAX_NAME_SIZE+1];
+  node_asn *p, *p2, *p3, *p4, *p5;
+  char name_root[MAX_NAME_SIZE], name2[2 * MAX_NAME_SIZE + 1];
   int move, tlen;
-  if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
-
-  _asn1_str_cpy(name_root, sizeof(name_root), node->name);
-
-  p=node;
-  move=DOWN;
-
-  while(!((p==node) && (move==UP))){
-    if(move!=UP){
-      if((type_field(p->type)==TYPE_OBJECT_ID) && (p->type&CONST_ASSIGN)){
-       p2=p->down;
-        if(p2 && (type_field(p2->type)==TYPE_CONSTANT)){
-         if(p2->value && !isdigit(p2->value[0])){
-           _asn1_str_cpy(name2, sizeof(name2), name_root);
-           _asn1_str_cat(name2, sizeof(name2), ".");
-           _asn1_str_cat(name2, sizeof(name2), p2->value);
-           p3=asn1_find_node(node,name2);
-           if(!p3 || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
-              !(p3->type&CONST_ASSIGN)) return ASN1_ELEMENT_NOT_FOUND;
-           _asn1_set_down(p,p2->right);
-           _asn1_remove_node(p2);
-           p2=p;
-           p4=p3->down;
-           while(p4){
-             if(type_field(p4->type)==TYPE_CONSTANT){
-               p5=_asn1_add_node_only(TYPE_CONSTANT);
-               _asn1_set_name(p5,p4->name);
-               tlen = strlen( p4->value);
-               if (tlen > 0)
-                   _asn1_set_value(p5,p4->value,tlen+1);
-               if(p2==p){
-                 _asn1_set_right(p5,p->down);
-                 _asn1_set_down(p,p5);
-               }
-               else{
-                 _asn1_set_right(p5,p2->right);
-                 _asn1_set_right(p2,p5);
+
+  if (node == NULL)
+    return ASN1_ELEMENT_NOT_FOUND;
+
+  _asn1_str_cpy (name_root, sizeof (name_root), node->name);
+
+  p = node;
+  move = DOWN;
+
+  while (!((p == node) && (move == UP)))
+    {
+      if (move != UP)
+       {
+         if ((type_field (p->type) == TYPE_OBJECT_ID)
+             && (p->type & CONST_ASSIGN))
+           {
+             p2 = p->down;
+             if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
+               {
+                 if (p2->value && !isdigit (p2->value[0]))
+                   {
+                     _asn1_str_cpy (name2, sizeof (name2), name_root);
+                     _asn1_str_cat (name2, sizeof (name2), ".");
+                     _asn1_str_cat (name2, sizeof (name2), p2->value);
+                     p3 = asn1_find_node (node, name2);
+                     if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) ||
+                         !(p3->type & CONST_ASSIGN))
+                       return ASN1_ELEMENT_NOT_FOUND;
+                     _asn1_set_down (p, p2->right);
+                     _asn1_remove_node (p2);
+                     p2 = p;
+                     p4 = p3->down;
+                     while (p4)
+                       {
+                         if (type_field (p4->type) == TYPE_CONSTANT)
+                           {
+                             p5 = _asn1_add_node_only (TYPE_CONSTANT);
+                             _asn1_set_name (p5, p4->name);
+                             tlen = strlen (p4->value);
+                             if (tlen > 0)
+                               _asn1_set_value (p5, p4->value, tlen + 1);
+                             if (p2 == p)
+                               {
+                                 _asn1_set_right (p5, p->down);
+                                 _asn1_set_down (p, p5);
+                               }
+                             else
+                               {
+                                 _asn1_set_right (p5, p2->right);
+                                 _asn1_set_right (p2, p5);
+                               }
+                             p2 = p5;
+                           }
+                         p4 = p4->right;
+                       }
+                     move = DOWN;
+                     continue;
+                   }
                }
-               p2=p5;
-             }
-             p4=p4->right;
            }
-           move=DOWN;
-           continue;
-         }
+         move = DOWN;
        }
-      }
-      move=DOWN;
-    }
-    else move=RIGHT;
+      else
+       move = RIGHT;
 
-    if(move==DOWN){
-      if(p->down) p=p->down;
-      else move=RIGHT;
-    }
-    
-    if(p==node) {move=UP; continue;}
+      if (move == DOWN)
+       {
+         if (p->down)
+           p = p->down;
+         else
+           move = RIGHT;
+       }
 
-    if(move==RIGHT){
-      if(p->right) p=p->right;
-      else move=UP;
+      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);
     }
-    if(move==UP) p=_asn1_find_up(p);
-  }
 
 
   /*******************************/
   /*       expand DEFAULT        */
   /*******************************/
-  p=node;
-  move=DOWN;
-
-  while(!((p==node) && (move==UP))){
-    if(move!=UP){
-      if((type_field(p->type)==TYPE_OBJECT_ID) && 
-        (p->type&CONST_DEFAULT)){
-       p2=p->down;
-        if(p2 && (type_field(p2->type)==TYPE_DEFAULT)){
-         _asn1_str_cpy(name2, sizeof(name2), name_root);
-         _asn1_str_cat(name2, sizeof(name2), ".");
-         _asn1_str_cat(name2, sizeof(name2), p2->value);
-         p3=asn1_find_node(node,name2);
-         if(!p3 || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
-            !(p3->type&CONST_ASSIGN)) return ASN1_ELEMENT_NOT_FOUND;
-         p4=p3->down;
-         name2[0]=0;
-         while(p4){
-           if(type_field(p4->type)==TYPE_CONSTANT){
-             if(name2[0]) _asn1_str_cat(name2,sizeof(name2),".");
-             _asn1_str_cat(name2,sizeof(name2),p4->value);
+  p = node;
+  move = DOWN;
+
+  while (!((p == node) && (move == UP)))
+    {
+      if (move != UP)
+       {
+         if ((type_field (p->type) == TYPE_OBJECT_ID) &&
+             (p->type & CONST_DEFAULT))
+           {
+             p2 = p->down;
+             if (p2 && (type_field (p2->type) == TYPE_DEFAULT))
+               {
+                 _asn1_str_cpy (name2, sizeof (name2), name_root);
+                 _asn1_str_cat (name2, sizeof (name2), ".");
+                 _asn1_str_cat (name2, sizeof (name2), p2->value);
+                 p3 = asn1_find_node (node, name2);
+                 if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) ||
+                     !(p3->type & CONST_ASSIGN))
+                   return ASN1_ELEMENT_NOT_FOUND;
+                 p4 = p3->down;
+                 name2[0] = 0;
+                 while (p4)
+                   {
+                     if (type_field (p4->type) == TYPE_CONSTANT)
+                       {
+                         if (name2[0])
+                           _asn1_str_cat (name2, sizeof (name2), ".");
+                         _asn1_str_cat (name2, sizeof (name2), p4->value);
+                       }
+                     p4 = p4->right;
+                   }
+                 tlen = strlen (name2);
+                 if (tlen > 0)
+                   _asn1_set_value (p2, name2, tlen + 1);
+               }
            }
-           p4=p4->right;
-         }
-         tlen = strlen(name2);
-         if (tlen > 0)
-             _asn1_set_value(p2,name2,tlen+1);
+         move = DOWN;
        }
-      }
-      move=DOWN;
-    }
-    else move=RIGHT;
+      else
+       move = RIGHT;
 
-    if(move==DOWN){
-      if(p->down) p=p->down;
-      else move=RIGHT;
-    }
-    
-    if(p==node) {move=UP; continue;}
+      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 == RIGHT)
+       {
+         if (p->right)
+           p = p->right;
+         else
+           move = UP;
+       }
+      if (move == UP)
+       p = _asn1_find_up (p);
     }
-    if(move==UP) p=_asn1_find_up(p);
-  }
 
   return ASN1_SUCCESS;
 }
@@ -653,44 +759,61 @@ _asn1_expand_object_id(ASN1_TYPE node)
 /*   ASN1_ELEMENT_NOT_FOUND if NODE is NULL,                       */
 /*   otherwise ASN1_SUCCESS                                             */
 /******************************************************************/
-asn1_retCode 
-_asn1_type_set_config(ASN1_TYPE node)
+asn1_retCode
+_asn1_type_set_config (ASN1_TYPE node)
 {
-  node_asn *p,*p2;
+  node_asn *p, *p2;
   int move;
-  if(node==NULL) return ASN1_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;
+
+  if (node == NULL)
+    return ASN1_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;
        }
-      }
-      move=DOWN;
-    }
-    else move=RIGHT;
+      else
+       move = RIGHT;
 
-    if(move==DOWN){
-      if(p->down) p=p->down;
-      else move=RIGHT;
-    }
+      if (move == DOWN)
+       {
+         if (p->down)
+           p = p->down;
+         else
+           move = RIGHT;
+       }
 
-    if(p==node) {move=UP; continue;}
+      if (p == node)
+       {
+         move = UP;
+         continue;
+       }
 
-    if(move==RIGHT){
-      if(p->right) p=p->right;
-      else move=UP;
+      if (move == RIGHT)
+       {
+         if (p->right)
+           p = p->right;
+         else
+           move = UP;
+       }
+      if (move == UP)
+       p = _asn1_find_up (p);
     }
-    if(move==UP) p=_asn1_find_up(p);
-  }
 
   return ASN1_SUCCESS;
 }
@@ -709,79 +832,94 @@ _asn1_type_set_config(ASN1_TYPE node)
 /*   ASN1_IDENTIFIER_NOT_FOUND   if an identifier is not defined, */
 /*   otherwise ASN1_SUCCESS                                       */
 /******************************************************************/
-asn1_retCode 
-_asn1_check_identifier(ASN1_TYPE node)
+asn1_retCode
+_asn1_check_identifier (ASN1_TYPE node)
 {
-  node_asn *p,*p2;
-  char name2[MAX_NAME_SIZE*2+2];
-
-  if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
-
-  p=node;
-  while(p){
-    if(type_field(p->type)==TYPE_IDENTIFIER){
-      _asn1_str_cpy(name2, sizeof(name2), node->name);
-      _asn1_str_cat(name2, sizeof(name2), ".");
-      _asn1_str_cat(name2, sizeof(name2), p->value);
-      p2=asn1_find_node(node,name2);
-      if(p2==NULL){
-       strcpy(_asn1_identifierMissing,p->value);
-       return ASN1_IDENTIFIER_NOT_FOUND;
-      } 
-    }
-    else if((type_field(p->type)==TYPE_OBJECT_ID) && 
-           (p->type&CONST_DEFAULT)){
-      p2=p->down;
-      if(p2 && (type_field(p2->type)==TYPE_DEFAULT)){
-       _asn1_str_cpy(name2, sizeof(name2), node->name);
-       _asn1_str_cat(name2, sizeof(name2), ".");
-       _asn1_str_cat(name2, sizeof(name2), p2->value);
-       strcpy(_asn1_identifierMissing,p2->value);
-       p2=asn1_find_node(node,name2);
-       if(!p2 || (type_field(p2->type)!=TYPE_OBJECT_ID) ||
-          !(p2->type&CONST_ASSIGN))
-         return ASN1_IDENTIFIER_NOT_FOUND;
-       else
-         _asn1_identifierMissing[0]=0;
-      }
-    }
-    else if((type_field(p->type)==TYPE_OBJECT_ID) && 
-           (p->type&CONST_ASSIGN)){
-      p2=p->down;
-      if(p2 && (type_field(p2->type)==TYPE_CONSTANT)){
-       if(p2->value && !isdigit(p2->value[0])){
-         _asn1_str_cpy(name2, sizeof(name2), node->name);
-         _asn1_str_cat(name2, sizeof(name2), ".");
-         _asn1_str_cat(name2, sizeof(name2), p2->value);
-         strcpy(_asn1_identifierMissing,p2->value);
-         p2=asn1_find_node(node,name2);
-         if(!p2 || (type_field(p2->type)!=TYPE_OBJECT_ID) ||
-            !(p2->type&CONST_ASSIGN))
-           return ASN1_IDENTIFIER_NOT_FOUND;
-         else
-           _asn1_identifierMissing[0]=0;
+  node_asn *p, *p2;
+  char name2[MAX_NAME_SIZE * 2 + 2];
+
+  if (node == NULL)
+    return ASN1_ELEMENT_NOT_FOUND;
+
+  p = node;
+  while (p)
+    {
+      if (type_field (p->type) == TYPE_IDENTIFIER)
+       {
+         _asn1_str_cpy (name2, sizeof (name2), node->name);
+         _asn1_str_cat (name2, sizeof (name2), ".");
+         _asn1_str_cat (name2, sizeof (name2), p->value);
+         p2 = asn1_find_node (node, name2);
+         if (p2 == NULL)
+           {
+             strcpy (_asn1_identifierMissing, p->value);
+             return ASN1_IDENTIFIER_NOT_FOUND;
+           }
        }
-      }
-    }
-    
-    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;
+      else if ((type_field (p->type) == TYPE_OBJECT_ID) &&
+              (p->type & CONST_DEFAULT))
+       {
+         p2 = p->down;
+         if (p2 && (type_field (p2->type) == TYPE_DEFAULT))
+           {
+             _asn1_str_cpy (name2, sizeof (name2), node->name);
+             _asn1_str_cat (name2, sizeof (name2), ".");
+             _asn1_str_cat (name2, sizeof (name2), p2->value);
+             strcpy (_asn1_identifierMissing, p2->value);
+             p2 = asn1_find_node (node, name2);
+             if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) ||
+                 !(p2->type & CONST_ASSIGN))
+               return ASN1_IDENTIFIER_NOT_FOUND;
+             else
+               _asn1_identifierMissing[0] = 0;
+           }
+       }
+      else if ((type_field (p->type) == TYPE_OBJECT_ID) &&
+              (p->type & CONST_ASSIGN))
+       {
+         p2 = p->down;
+         if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
+           {
+             if (p2->value && !isdigit (p2->value[0]))
+               {
+                 _asn1_str_cpy (name2, sizeof (name2), node->name);
+                 _asn1_str_cat (name2, sizeof (name2), ".");
+                 _asn1_str_cat (name2, sizeof (name2), p2->value);
+                 strcpy (_asn1_identifierMissing, p2->value);
+                 p2 = asn1_find_node (node, name2);
+                 if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) ||
+                     !(p2->type & CONST_ASSIGN))
+                   return ASN1_IDENTIFIER_NOT_FOUND;
+                 else
+                   _asn1_identifierMissing[0] = 0;
+               }
+           }
+       }
+
+      if (p->down)
+       {
+         p = p->down;
        }
-       if(p->right){
-         p=p->right;
-         break;
+      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 ASN1_SUCCESS;
 }
@@ -798,79 +936,89 @@ _asn1_check_identifier(ASN1_TYPE node)
 /*     a DEFINITIONS element,                                     */
 /*   otherwise ASN1_SUCCESS                                       */
 /******************************************************************/
-asn1_retCode 
-_asn1_set_default_tag(ASN1_TYPE node)
+asn1_retCode
+_asn1_set_default_tag (ASN1_TYPE node)
 {
   node_asn *p;
 
-  if((node==NULL) || (type_field(node->type)!=TYPE_DEFINITIONS))
-    return ASN1_ELEMENT_NOT_FOUND; 
+  if ((node == NULL) || (type_field (node->type) != TYPE_DEFINITIONS))
+    return ASN1_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;
-    }
+  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;
-         }
-      }
+      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 ASN1_SUCCESS;
 }
 
 
 
-static const char*
-parse_version_number( const char *s, int *number )
+static const char *
+parse_version_number (const char *s, int *number)
 {
-    int val = 0;
-
-    if( *s == '0' && isdigit(s[1]) )
-       return NULL; /* leading zeros are not allowed */
-    for ( ; isdigit(*s); s++ ) {
-       val *= 10;
-       val += *s - '0';
+  int val = 0;
+
+  if (*s == '0' && isdigit (s[1]))
+    return NULL;               /* leading zeros are not allowed */
+  for (; isdigit (*s); s++)
+    {
+      val *= 10;
+      val += *s - '0';
     }
-    *number = val;
-    return val < 0? NULL : s;
+  *number = val;
+  return val < 0 ? NULL : s;
 }
 
 /* The parse version functions were copied from libgcrypt.
  */
 static const char *
-parse_version_string( const char *s, int *major, int *minor, int *micro )
+parse_version_string (const char *s, int *major, int *minor, int *micro)
 {
-    s = parse_version_number( s, major );
-    if( !s || *s != '.' )
-       return NULL;
-    s++;
-    s = parse_version_number( s, minor );
-    if( !s || *s != '.' )
-       return NULL;
-    s++;
-    s = parse_version_number( s, micro );
-    if( !s )
-       return NULL;
-    return s; /* patchlevel */
+  s = parse_version_number (s, major);
+  if (!s || *s != '.')
+    return NULL;
+  s++;
+  s = parse_version_number (s, minor);
+  if (!s || *s != '.')
+    return NULL;
+  s++;
+  s = parse_version_number (s, micro);
+  if (!s)
+    return NULL;
+  return s;                    /* patchlevel */
 }
 
 /**
@@ -888,32 +1036,32 @@ parse_version_string( const char *s, int *major, int *minor, int *micro )
  *   run-time library does not meet the required version number.
  */
 const char *
-asn1_check_version( const char *req_version )
+asn1_check_version (const char *req_version)
 {
-    const char *ver = LIBTASN1_VERSION;
-    int my_major, my_minor, my_micro;
-    int rq_major, rq_minor, rq_micro;
-    const char *my_plvl, *rq_plvl;
-
-    if ( !req_version )
-       return ver;
-
-    my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro );
-    if ( !my_plvl )
-       return NULL;  /* very strange our own version is bogus */
-    rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor,
-                                                               &rq_micro );
-    if ( !rq_plvl )
-       return NULL;  /* req version string is invalid */
-
-    if ( my_major > rq_major
-       || (my_major == rq_major && my_minor > rq_minor)
-       || (my_major == rq_major && my_minor == rq_minor
-                                && my_micro > rq_micro)
-       || (my_major == rq_major && my_minor == rq_minor
-                                && my_micro == rq_micro
-                                && strcmp( my_plvl, rq_plvl ) >= 0) ) {
-       return ver;
+  const char *ver = LIBTASN1_VERSION;
+  int my_major, my_minor, my_micro;
+  int rq_major, rq_minor, rq_micro;
+  const char *my_plvl, *rq_plvl;
+
+  if (!req_version)
+    return ver;
+
+  my_plvl = parse_version_string (ver, &my_major, &my_minor, &my_micro);
+  if (!my_plvl)
+    return NULL;               /* very strange our own version is bogus */
+  rq_plvl = parse_version_string (req_version, &rq_major, &rq_minor,
+                                 &rq_micro);
+  if (!rq_plvl)
+    return NULL;               /* req version string is invalid */
+
+  if (my_major > rq_major
+      || (my_major == rq_major && my_minor > rq_minor)
+      || (my_major == rq_major && my_minor == rq_minor
+         && my_micro > rq_micro)
+      || (my_major == rq_major && my_minor == rq_minor
+         && my_micro == rq_micro && strcmp (my_plvl, rq_plvl) >= 0))
+    {
+      return ver;
     }
-    return NULL;
+  return NULL;
 }
index 6edf67aac876feed5e0313181a4e5e2be667e14b..3055510cbefb04c6c72bfc1028f4af19214fa5c6 100644 (file)
@@ -10,7 +10,7 @@ node_asn *
 _asn1_add_node(unsigned int type);
 
 node_asn *
-_asn1_set_value(node_asn *node,const unsigned char *value,unsigned int len);
+_asn1_set_value(node_asn *node,const void *value,unsigned int len);
 
 node_asn *
 _asn1_set_name(node_asn *node,const char *name);
index 70bc17246f055deaf14776d3daec303d6c98c176..4b2ee5099e3bcb7f917c423f2d13a7bdc7d9a3dd 100644 (file)
@@ -51,16 +51,11 @@ _asn1_add_node_only (unsigned int type)
 {
   node_asn *punt;
 
-  punt = (node_asn *) _asn1_malloc (sizeof (node_asn));
+  punt = (node_asn *) _asn1_calloc (1, sizeof (node_asn));
   if (punt == NULL)
     return NULL;
 
-  punt->left = NULL;
-  punt->name = NULL;
   punt->type = type;
-  punt->value = NULL;
-  punt->down = NULL;
-  punt->right = NULL;
 
   return punt;
 }