]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
minitasn1: updated to latest git version
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 9 Apr 2016 06:17:53 +0000 (08:17 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 9 Apr 2016 06:17:53 +0000 (08:17 +0200)
lib/minitasn1/coding.c
lib/minitasn1/decoding.c
lib/minitasn1/element.c
lib/minitasn1/element.h
lib/minitasn1/int.h
lib/minitasn1/libtasn1.h
lib/minitasn1/parser_aux.c
lib/minitasn1/parser_aux.h
lib/minitasn1/structure.c

index 2dd80ba41953ca00127ba61b5d76e9d15b022d8f..0c0f69c5ceecde93e81cd2b3d7eb8e320943e422 100644 (file)
@@ -443,7 +443,9 @@ asn1_bit_der (const unsigned char *str, int bit_len,
     len_byte++;
   asn1_length_der (len_byte + 1, der, &len_len);
   der[len_len] = len_pad;
-  memcpy (der + len_len + 1, str, len_byte);
+
+  if (str)
+    memcpy (der + len_len + 1, str, len_byte);
   der[len_len + len_byte] &= bit_mask[len_pad];
   *der_len = len_byte + len_len + 1;
 }
@@ -628,7 +630,7 @@ _asn1_insert_tag_der (asn1_node node, unsigned char *der, int *counter,
                                   tag_der, &tag_len);
 
                  *max_len -= tag_len;
-                 if (*max_len >= 0)
+                 if (der && *max_len >= 0)
                    memcpy (der + *counter, tag_der, tag_len);
                  *counter += tag_len;
 
@@ -680,7 +682,7 @@ _asn1_insert_tag_der (asn1_node node, unsigned char *der, int *counter,
     }
 
   *max_len -= tag_len;
-  if (*max_len >= 0)
+  if (der && *max_len >= 0)
     memcpy (der + *counter, tag_der, tag_len);
   *counter += tag_len;
 
@@ -1018,6 +1020,9 @@ asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
   int err;
   unsigned char *der = ider;
 
+  if (ErrorDescription)
+    ErrorDescription[0] = 0;
+
   node = asn1_find_node (element, name);
   if (node == NULL)
     return ASN1_ELEMENT_NOT_FOUND;
@@ -1248,7 +1253,7 @@ asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
                  continue;
                }
              else
-               p = _asn1_get_up (p);
+               p = _asn1_find_up (p);
              move = UP;
            }
          if (move == UP)
@@ -1323,7 +1328,7 @@ asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
            move = UP;
        }
       if (move == UP)
-       p = _asn1_get_up (p);
+       p = _asn1_find_up (p);
     }
 
   *len = counter;
index 42ddc6be032a30f72053f625aef306c47c5a350b..e5513a38b0eba88f2ff585a3db7a1ec1d02f46f2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2002-2014 Free Software Foundation, Inc.
+ * Copyright (C) 2002-2016 Free Software Foundation, Inc.
  *
  * This file is part of LIBTASN1.
  *
@@ -43,6 +43,9 @@
 
 #define HAVE_TWO(x) (x>=2?1:0)
 
+#define DECODE_FLAG_HAVE_TAG 1
+#define DECODE_FLAG_INDEFINITE (1<<1)
+
 #define DECR_LEN(l, s) do { \
          l -= s; \
          if (l < 0) { \
 static int
 _asn1_get_indefinite_length_string (const unsigned char *der, int der_len, int *len);
 
+static int
+_asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
+                       unsigned int _der_len, unsigned char **str,
+                       unsigned int *str_len, unsigned int *ber_len,
+                       unsigned dflags);
+
+static int
+_asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
+                       unsigned int _der_len, const unsigned char **str,
+                       unsigned int *str_len, unsigned dflags);
+
 static void
 _asn1_error_description_tag_error (asn1_node node, char *ErrorDescription)
 {
@@ -236,13 +250,15 @@ asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len)
 /**
  * asn1_get_octet_der:
  * @der: DER data to decode containing the OCTET SEQUENCE.
- * @der_len: Length of DER data to decode.
- * @ret_len: Output variable containing the length of the DER data.
+ * @der_len: The length of the @der data to decode.
+ * @ret_len: Output variable containing the encoded length of the DER data.
  * @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in.
  * @str_size: Length of pre-allocated output buffer.
- * @str_len: Output variable containing the length of the OCTET SEQUENCE.
+ * @str_len: Output variable containing the length of the contents of the OCTET SEQUENCE.
  *
- * Extract an OCTET SEQUENCE from DER data.
+ * Extract an OCTET SEQUENCE from DER data. Note that this function
+ * expects the DER data past the tag field, i.e., the length and
+ * content octets.
  *
  * Returns: Returns %ASN1_SUCCESS on success, or an error.
  **/
@@ -275,9 +291,23 @@ asn1_get_octet_der (const unsigned char *der, int der_len,
   return ASN1_SUCCESS;
 }
 
-/* Returns ASN1_SUCCESS on success or an error code on error.
- * type should be one of ASN1_ETYPE_GENERALIZED_TIME or ASN1_ETYPE_UTC_TIME.
- */
+
+/*- 
+ * _asn1_get_time_der:
+ * @type: %ASN1_ETYPE_GENERALIZED_TIME or %ASN1_ETYPE_UTC_TIME
+ * @der: DER data to decode containing the time
+ * @der_len: Length of DER data to decode.
+ * @ret_len: Output variable containing the length of the DER data.
+ * @str: Pre-allocated output buffer to put the textual time in.
+ * @str_size: Length of pre-allocated output buffer.
+ * @flags: Zero or %ASN1_DECODE_FLAG_STRICT_DER
+ *
+ * Performs basic checks in the DER encoded time object and returns its textual form.
+ * The textual form will be in the YYYYMMDD000000Z format for GeneralizedTime
+ * and YYMMDD000000Z for UTCTime.
+ *
+ * Returns: %ASN1_SUCCESS on success, or an error.
+ -*/
 static int
 _asn1_get_time_der (unsigned type, const unsigned char *der, int der_len, int *ret_len,
                    char *str, int str_size, unsigned flags)
@@ -329,7 +359,7 @@ _asn1_get_time_der (unsigned type, const unsigned char *der, int der_len, int *r
                  }
 
                warn();
-           return ASN1_DER_ERROR;
+               return ASN1_DER_ERROR;
              }
          }
 
@@ -346,8 +376,20 @@ _asn1_get_time_der (unsigned type, const unsigned char *der, int der_len, int *r
   return ASN1_SUCCESS;
 }
 
-static int
-_asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len,
+/**
+ * asn1_get_objectid_der:
+ * @der: DER data to decode containing the OBJECT IDENTIFIER
+ * @der_len: Length of DER data to decode.
+ * @ret_len: Output variable containing the length of the DER data.
+ * @str: Pre-allocated output buffer to put the textual object id in.
+ * @str_size: Length of pre-allocated output buffer.
+ *
+ * Converts a DER encoded object identifier to its textual form.
+ *
+ * Returns: %ASN1_SUCCESS on success, or an error.
+ **/
+int
+asn1_get_object_id_der (const unsigned char *der, int der_len, int *ret_len,
                        char *str, int str_size)
 {
   int len_len, len, k;
@@ -419,7 +461,7 @@ _asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len,
  *
  * Extract a BIT SEQUENCE from DER data.
  *
- * Returns: Return %ASN1_SUCCESS on success, or an error.
+ * Returns: %ASN1_SUCCESS on success, or an error.
  **/
 int
 asn1_get_bit_der (const unsigned char *der, int der_len,
@@ -454,10 +496,12 @@ asn1_get_bit_der (const unsigned char *der, int der_len,
   return ASN1_SUCCESS;
 }
 
-
+/* tag_len: the total tag length (explicit+inner)
+ * inner_tag_len: the inner_tag length
+ */
 static int
 _asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len,
-                      int *ret_len, unsigned flags)
+                      int *tag_len, int *inner_tag_len, unsigned flags)
 {
   asn1_node p;
   int counter, len2, len3, is_tag_implicit;
@@ -568,7 +612,9 @@ _asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len,
       unsigned type = type_field (node->type);
       if (type == ASN1_ETYPE_TAG)
        {
-         *ret_len = 0;
+         *tag_len = 0;
+         if (inner_tag_len)
+           *inner_tag_len = 0;
          return ASN1_SUCCESS;
        }
 
@@ -628,7 +674,9 @@ _asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len,
     }
 
   counter += len2;
-  *ret_len = counter;
+  *tag_len = counter;
+  if (inner_tag_len)
+    *inner_tag_len = len2;
   return ASN1_SUCCESS;
 
 cleanup:
@@ -637,7 +685,7 @@ cleanup:
 
 static int
 extract_tag_der_recursive(asn1_node node, const unsigned char *der, int der_len,
-                      int *ret_len, unsigned flags)
+                      int *ret_len, int *inner_len, unsigned flags)
 {
 asn1_node p;
 int ris = ASN1_DER_ERROR;
@@ -647,7 +695,7 @@ int ris = ASN1_DER_ERROR;
       p = node->down;
       while (p)
         {
-          ris = _asn1_extract_tag_der (p, der, der_len, ret_len, flags);
+          ris = _asn1_extract_tag_der (p, der, der_len, ret_len, inner_len, flags);
           if (ris == ASN1_SUCCESS)
             break;
           p = p->right;
@@ -657,7 +705,7 @@ int ris = ASN1_DER_ERROR;
       return ris;
     }
   else
-    return _asn1_extract_tag_der (node, der, der_len, ret_len, flags);
+    return _asn1_extract_tag_der (node, der, der_len, ret_len, inner_len, flags);
 }
 
 static int
@@ -678,7 +726,7 @@ _asn1_delete_not_used (asn1_node node)
            {
              p2 = _asn1_find_left (p);
              if (!p2)
-               p2 = _asn1_get_up (p);
+               p2 = _asn1_find_up (p);
            }
          asn1_delete_structure (&p);
          p = p2;
@@ -701,7 +749,7 @@ _asn1_delete_not_used (asn1_node node)
            {
              while (1)
                {
-                 p = _asn1_get_up (p);
+                 p = _asn1_find_up (p);
                  if (p == node)
                    {
                      p = NULL;
@@ -719,167 +767,6 @@ _asn1_delete_not_used (asn1_node node)
   return ASN1_SUCCESS;
 }
 
-static int
-_asn1_extract_der_octet (asn1_node node, const unsigned char *der,
-                        int der_len, unsigned flags)
-{
-  int len2, len3;
-  int counter, counter_end;
-  int result;
-
-  len2 = asn1_get_length_der (der, der_len, &len3);
-  if (len2 < -1)
-    return ASN1_DER_ERROR;
-
-  counter = len3 + 1;
-  DECR_LEN(der_len, len3);
-
-  if (len2 == -1)
-    counter_end = der_len - 2;
-  else
-    counter_end = der_len;
-
-  while (counter < counter_end)
-    {
-      DECR_LEN(der_len, 1);
-      len2 = asn1_get_length_der (der + counter, der_len, &len3);
-
-      if (IS_ERR(len2, flags))
-       {
-         warn();
-         return ASN1_DER_ERROR;
-       }
-
-      if (len2 >= 0)
-       {
-         DECR_LEN(der_len, len2+len3);
-         _asn1_append_value (node, der + counter + len3, len2);
-       }
-      else
-       {                       /* indefinite */
-         DECR_LEN(der_len, len3);
-         result =
-           _asn1_extract_der_octet (node, der + counter + len3,
-                                    der_len, flags);
-         if (result != ASN1_SUCCESS)
-           return result;
-         len2 = 0;
-       }
-
-      counter += len2 + len3 + 1;
-    }
-
-  return ASN1_SUCCESS;
-
-cleanup:
-  return result;
-}
-
-static int
-_asn1_get_octet_string (asn1_node node, const unsigned char *der, int der_len,
-                        int *len, unsigned flags)
-{
-  int len2, len3, counter, tot_len, indefinite;
-  int result;
-  int orig_der_len = der_len;
-
-  counter = 0;
-
-  if (*(der - 1) & ASN1_CLASS_STRUCTURED)
-    {
-      tot_len = 0;
-
-      indefinite = asn1_get_length_der (der, der_len, &len3);
-      if (IS_ERR(indefinite, flags))
-       {
-         warn();
-         return ASN1_DER_ERROR;
-       }
-
-      counter += len3;
-      DECR_LEN(der_len, len3);
-
-      if (indefinite >= 0)
-       indefinite += len3;
-
-      while (1)
-       {
-         if (indefinite == -1)
-           {
-             if (HAVE_TWO(der_len) && (der[counter] == 0) && (der[counter + 1] == 0))
-               {
-                 counter += 2;
-                 DECR_LEN(der_len, 2);
-                 break;
-               }
-           }
-         else if (counter >= indefinite)
-           break;
-
-          DECR_LEN(der_len, 1);
-         if (der[counter] != ASN1_TAG_OCTET_STRING)
-           {
-             warn();
-             return ASN1_DER_ERROR;
-           }
-
-         counter++;
-
-         len2 = asn1_get_length_der (der + counter, der_len, &len3);
-         if (len2 <= 0)
-           {
-             warn();
-             return ASN1_DER_ERROR;
-           }
-
-          DECR_LEN(der_len, len3 + len2);
-         counter += len3 + len2;
-
-         tot_len += len2;
-       }
-
-      /* copy */
-      if (node)
-       {
-         unsigned char temp[ASN1_MAX_LENGTH_SIZE];
-         int ret;
-
-         len2 = sizeof (temp);
-
-         asn1_length_der (tot_len, temp, &len2);
-         _asn1_set_value (node, temp, len2);
-
-         ret = _asn1_extract_der_octet (node, der, orig_der_len, flags);
-         if (ret != ASN1_SUCCESS)
-           {
-             warn();
-             return ret;
-           }
-
-       }
-    }
-  else
-    {                          /* NOT STRUCTURED */
-      len2 = asn1_get_length_der (der, der_len, &len3);
-      if (len2 < 0)
-        {
-          warn();
-         return ASN1_DER_ERROR;
-       }
-
-      DECR_LEN(der_len, len3+len2);
-      counter = len3 + len2;
-      if (node)
-       _asn1_set_value (node, der, counter);
-    }
-
-  *len = counter;
-  return ASN1_SUCCESS;
-
-cleanup:
-  return result;
-}
-
 static int
 _asn1_get_indefinite_length_string (const unsigned char *der,
                                    int der_len, int *len)
@@ -982,11 +869,14 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
   asn1_node node, p, p2, p3;
   char temp[128];
   int counter, len2, len3, len4, move, ris, tlen;
-  asn1_node ptail = NULL;
+  struct node_tail_cache_st tcache = {NULL, NULL};
   unsigned char class;
   unsigned long tag;
   int tag_len;
   int indefinite, result, total_len = *max_ider_len, ider_len = *max_ider_len;
+  int inner_tag_len;
+  unsigned char *ptmp;
+  const unsigned char *ptag;
   const unsigned char *der = ider;
 
   node = *element;
@@ -1010,12 +900,13 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
   while (1)
     {
       tag_len = 0;
+      inner_tag_len = 0;
       ris = ASN1_SUCCESS;
       if (move != UP)
        {
          if (p->type & CONST_SET)
            {
-             p2 = _asn1_get_up (p);
+             p2 = _asn1_find_up (p);
              len2 = p2->tmp_ival;
              if (len2 == -1)
                {
@@ -1047,7 +938,7 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
                    {
                      ris =
                          extract_tag_der_recursive (p2, der + counter,
-                                                    ider_len, &len2, flags);
+                                                    ider_len, &len2, NULL, flags);
                      if (ris == ASN1_SUCCESS)
                        {
                          p2->type &= ~CONST_NOT_USED;
@@ -1071,7 +962,7 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
 
          if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
            {
-             p2 = _asn1_get_up (p);
+             p2 = _asn1_find_up (p);
              len2 = p2->tmp_ival;
              if (counter == len2)
                {
@@ -1097,7 +988,7 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
                {
                  ris =
                      extract_tag_der_recursive (p->down, der + counter,
-                                                ider_len, &len2, flags);
+                                                ider_len, &len2, NULL, flags);
 
                  if (ris == ASN1_SUCCESS)
                    {
@@ -1134,7 +1025,7 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
 
          if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
            {
-             p2 = _asn1_get_up (p);
+             p2 = _asn1_find_up (p);
              len2 = p2->tmp_ival;
 
              if ((len2 != -1) && (counter > len2))
@@ -1144,7 +1035,7 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
          if (ris == ASN1_SUCCESS)
            ris =
              extract_tag_der_recursive (p, der + counter, ider_len, 
-                                        &tag_len, flags);
+                                        &tag_len, &inner_tag_len, flags);
 
          if (ris != ASN1_SUCCESS)
            {
@@ -1224,7 +1115,7 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
              break;
            case ASN1_ETYPE_OBJECT_ID:
              result =
-               _asn1_get_objectid_der (der + counter, ider_len, &len2,
+               asn1_get_object_id_der (der + counter, ider_len, &len2,
                                        temp, sizeof (temp));
              if (result != ASN1_SUCCESS)
                {
@@ -1262,15 +1153,51 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
              move = RIGHT;
              break;
            case ASN1_ETYPE_OCTET_STRING:
-             result = _asn1_get_octet_string (p, der + counter, ider_len, &len3, flags);
-             if (result != ASN1_SUCCESS)
+             if (counter < inner_tag_len)
                {
+                 result = ASN1_DER_ERROR;
                   warn();
                  goto cleanup;
-               }
+               }
+
+              ptag = der + counter - inner_tag_len;
+              if (flags & ASN1_DECODE_FLAG_STRICT_DER || !(ptag[0] & ASN1_CLASS_STRUCTURED))
+                {
+                 len2 =
+                   asn1_get_length_der (der + counter, ider_len, &len3);
+                 if (len2 < 0)
+                   {
+                     result = ASN1_DER_ERROR;
+                      warn();
+                     goto cleanup;
+                   }
+
+                 DECR_LEN(ider_len, len3+len2);
+
+                 _asn1_set_value (p, der + counter, len3 + len2);
+                 counter += len3 + len2;
+                }
+              else
+                {
+                  unsigned dflags = 0, vlen, ber_len;
+
+                  if (ptag[0] & ASN1_CLASS_STRUCTURED)
+                    dflags |= DECODE_FLAG_INDEFINITE;
 
-             DECR_LEN(ider_len, len3);
-             counter += len3;
+                  result = _asn1_decode_simple_ber(type_field (p->type), der+counter, ider_len, &ptmp, &vlen, &ber_len, dflags);
+                 if (result != ASN1_SUCCESS)
+                   {
+                      warn();
+                     goto cleanup;
+                   }
+
+                 DECR_LEN(ider_len, ber_len);
+
+                 _asn1_set_value_lv (p, ptmp, vlen);
+
+                 counter += ber_len;
+                 free(ptmp);
+                }
              move = RIGHT;
              break;
            case ASN1_ETYPE_GENERALSTRING:
@@ -1377,14 +1304,15 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
                    {           /* indefinite length method */
                      if (!HAVE_TWO(ider_len) || ((der[counter]) || der[counter + 1]))
                        {
-                         _asn1_append_sequence_set (p, &ptail);
-                         p = ptail;
+                         _asn1_append_sequence_set (p, &tcache);
+                         p = tcache.tail;
                          move = RIGHT;
                          continue;
                        }
 
                      p->tmp_ival = 0;
-                     ptail = NULL; /* finished decoding this structure */
+                     tcache.tail = NULL; /* finished decoding this structure */
+                     tcache.head = NULL;
                      DECR_LEN(ider_len, 2);
                      counter += 2;
                    }
@@ -1392,14 +1320,15 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
                    {           /* definite length method */
                      if (len2 > counter)
                        {
-                         _asn1_append_sequence_set (p, &ptail);
-                         p = ptail;
+                         _asn1_append_sequence_set (p, &tcache);
+                         p = tcache.tail;
                          move = RIGHT;
                          continue;
                        }
 
                      p->tmp_ival = 0;
-                     ptail = NULL; /* finished decoding this structure */
+                     tcache.tail = NULL; /* finished decoding this structure */
+                     tcache.head = NULL;
 
                      if (len2 != counter)
                        {
@@ -1437,7 +1366,7 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
                             || (type_field (p2->type) == ASN1_ETYPE_SIZE))
                        p2 = p2->right;
                      if (p2->right == NULL)
-                       _asn1_append_sequence_set (p, &ptail);
+                       _asn1_append_sequence_set (p, &tcache);
                      p = p2;
                    }
                }
@@ -1553,7 +1482,7 @@ asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
            move = UP;
        }
       if (move == UP)
-       p = _asn1_get_up (p);
+       p = _asn1_find_up (p);
     }
 
   _asn1_delete_not_used (*element);
@@ -1766,7 +1695,7 @@ asn1_expand_any_defined_by (asn1_node definitions, asn1_node * element)
                  break;
                }
 
-             p3 = _asn1_get_up (p);
+             p3 = _asn1_find_up (p);
 
              if (!p3)
                {
@@ -1786,8 +1715,8 @@ asn1_expand_any_defined_by (asn1_node definitions, asn1_node * element)
                  (p3->value == NULL))
                {
 
-                 p3 = _asn1_get_up (p);
-                 p3 = _asn1_get_up (p3);
+                 p3 = _asn1_find_up (p);
+                 p3 = _asn1_find_up (p3);
 
                  if (!p3)
                    {
@@ -1922,7 +1851,7 @@ asn1_expand_any_defined_by (asn1_node definitions, asn1_node * element)
        {
          while (1)
            {
-             p = _asn1_get_up (p);
+             p = _asn1_find_up (p);
              if (p == *element)
                {
                  p = NULL;
@@ -2082,23 +2011,24 @@ asn1_expand_octet_string (asn1_node definitions, asn1_node * element,
   return retCode;
 }
 
-/**
- * asn1_decode_simple_der:
+/*-
+ * _asn1_decode_simple_der:
  * @etype: The type of the string to be encoded (ASN1_ETYPE_)
  * @der: the encoded string
  * @_der_len: the bytes of the encoded string
  * @str: a pointer to the data
  * @str_len: the length of the data
+ * @dflags: DECODE_FLAG_*
  *
  * Decodes a simple DER encoded type (e.g. a string, which is not constructed).
  * The output is a pointer inside the @der.
  *
  * Returns: %ASN1_SUCCESS if successful or an error value.
**/
-int
-asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
-*/
+static int
+_asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
                        unsigned int _der_len, const unsigned char **str,
-                       unsigned int *str_len)
+                       unsigned int *str_len, unsigned dflags)
 {
   int tag_len, len_len;
   const unsigned char *p;
@@ -2110,25 +2040,33 @@ asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
   if (der == NULL || der_len == 0)
     return ASN1_VALUE_NOT_VALID;
 
-  if (ETYPE_OK (etype) == 0)
+  if (ETYPE_OK (etype) == 0 || ETYPE_IS_STRING(etype) == 0)
     return ASN1_VALUE_NOT_VALID;
 
   /* doesn't handle constructed classes */
-  if (ETYPE_CLASS (etype) != ASN1_CLASS_UNIVERSAL)
+  class = ETYPE_CLASS(etype);
+  if (class != ASN1_CLASS_UNIVERSAL)
     return ASN1_VALUE_NOT_VALID;
 
   p = der;
-  ret = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag);
-  if (ret != ASN1_SUCCESS)
-    return ret;
 
-  if (class != ETYPE_CLASS (etype) || tag != ETYPE_TAG (etype))
-    return ASN1_DER_ERROR;
+  if (dflags & DECODE_FLAG_HAVE_TAG)
+    {
+      ret = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag);
+      if (ret != ASN1_SUCCESS)
+        return ret;
 
-  p += tag_len;
-  der_len -= tag_len;
-  if (der_len <= 0)
-    return ASN1_DER_ERROR;
+      if (class != ETYPE_CLASS (etype) || tag != ETYPE_TAG (etype))
+        {
+          warn();
+          return ASN1_DER_ERROR;
+        }
+
+      p += tag_len;
+      der_len -= tag_len;
+      if (der_len <= 0)
+        return ASN1_DER_ERROR;
+    }
 
   ret = asn1_get_length_der (p, der_len, &len_len);
   if (ret < 0)
@@ -2145,9 +2083,30 @@ asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
   return ASN1_SUCCESS;
 }
 
+/**
+ * asn1_decode_simple_der:
+ * @etype: The type of the string to be encoded (ASN1_ETYPE_)
+ * @der: the encoded string
+ * @_der_len: the bytes of the encoded string
+ * @str: a pointer to the data
+ * @str_len: the length of the data
+ *
+ * Decodes a simple DER encoded type (e.g. a string, which is not constructed).
+ * The output is a pointer inside the @der.
+ *
+ * Returns: %ASN1_SUCCESS if successful or an error value.
+ **/
+int
+asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
+                       unsigned int _der_len, const unsigned char **str,
+                       unsigned int *str_len)
+{
+  return _asn1_decode_simple_der(etype, der, _der_len, str, str_len, DECODE_FLAG_HAVE_TAG);
+}
+
 static int append(uint8_t **dst, unsigned *dst_size, const unsigned char *src, unsigned src_size)
 {
-  *dst = realloc(*dst, *dst_size+src_size);
+  *dst = _asn1_realloc(*dst, *dst_size+src_size);
   if (*dst == NULL)
     return ASN1_MEM_ERROR;
   memcpy(*dst + *dst_size, src, src_size);
@@ -2155,25 +2114,27 @@ static int append(uint8_t **dst, unsigned *dst_size, const unsigned char *src, u
   return ASN1_SUCCESS;
 }
 
-/**
- * asn1_decode_simple_ber:
+/*-
+ * _asn1_decode_simple_ber:
  * @etype: The type of the string to be encoded (ASN1_ETYPE_)
  * @der: the encoded string
  * @_der_len: the bytes of the encoded string
  * @str: a pointer to the data
  * @str_len: the length of the data
  * @ber_len: the total length occupied by BER (may be %NULL)
+ * @have_tag: whether a DER tag is included
  *
  * Decodes a BER encoded type. The output is an allocated value 
  * of the data. This decodes BER STRINGS only. Other types are
  * decoded as DER.
  *
  * Returns: %ASN1_SUCCESS if successful or an error value.
**/
-int
-asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
-*/
+static int
+_asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
                        unsigned int _der_len, unsigned char **str,
-                       unsigned int *str_len, unsigned int *ber_len)
+                       unsigned int *str_len, unsigned int *ber_len,
+                       unsigned dflags)
 {
   int tag_len, len_len;
   const unsigned char *p;
@@ -2183,8 +2144,9 @@ asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
   unsigned char class;
   unsigned long tag;
   unsigned char *out = NULL;
+  const unsigned char *cout = NULL;
   unsigned out_len;
-  long ret;
+  long result;
 
   if (ber_len) *ber_len = 0;
 
@@ -2200,53 +2162,52 @@ asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
       return ASN1_VALUE_NOT_VALID;
     }
 
-  /* doesn't handle constructed classes */
-  if (ETYPE_CLASS (etype) != ASN1_CLASS_UNIVERSAL)
+  /* doesn't handle constructed + definite classes */
+  class = ETYPE_CLASS (etype);
+  if (class != ASN1_CLASS_UNIVERSAL)
     {
       warn();
       return ASN1_VALUE_NOT_VALID;
     }
 
   p = der;
-  ret = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag);
-  if (ret != ASN1_SUCCESS)
+
+  if (dflags & DECODE_FLAG_HAVE_TAG)
     {
-      warn();
-      return ret;
-    }
+      result = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag);
+        if (result != ASN1_SUCCESS)
+          {
+            warn();
+            return result;
+          }
 
-  if (ber_len) *ber_len += tag_len;
+        if (tag != ETYPE_TAG (etype))
+          {
+            warn();
+            return ASN1_DER_ERROR;
+          }
 
-  if (tag != ETYPE_TAG (etype))
-    {
-      warn();
-      return ASN1_DER_ERROR;
-    }
+        p += tag_len;
 
-  p += tag_len;
-  der_len -= tag_len;
-  if (der_len <= 0)
-    return ASN1_DER_ERROR;
+        DECR_LEN(der_len, tag_len);
 
-  if (class == ASN1_CLASS_STRUCTURED && (etype == ASN1_ETYPE_GENERALSTRING ||
-      etype == ASN1_ETYPE_NUMERIC_STRING || etype == ASN1_ETYPE_IA5_STRING ||
-      etype == ASN1_ETYPE_TELETEX_STRING || etype == ASN1_ETYPE_PRINTABLE_STRING ||
-      etype == ASN1_ETYPE_UNIVERSAL_STRING || etype == ASN1_ETYPE_BMP_STRING ||
-      etype == ASN1_ETYPE_UTF8_STRING || etype == ASN1_ETYPE_VISIBLE_STRING ||
-      etype == ASN1_ETYPE_OCTET_STRING))
-    {
+        if (ber_len) *ber_len += tag_len;
+    }
 
+  /* indefinite constructed */
+  if (((dflags & DECODE_FLAG_INDEFINITE) || class == ASN1_CLASS_STRUCTURED) && ETYPE_IS_STRING(etype))
+    {
       len_len = 1;
+
+      DECR_LEN(der_len, len_len);
       if (p[0] != 0x80)
         {
           warn();
-          return ASN1_DER_ERROR;
+          result = ASN1_DER_ERROR;
+          goto cleanup;
         }
 
       p += len_len;
-      der_len -= len_len;
-      if (der_len <= 0)
-        return ASN1_DER_ERROR;
 
       if (ber_len) *ber_len += len_len;
 
@@ -2255,38 +2216,48 @@ asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
         {
           unsigned tmp_len;
 
-          ret = asn1_decode_simple_ber(etype, p, der_len, &out, &out_len, &tmp_len);
-          if (ret != ASN1_SUCCESS)
+          result = asn1_decode_simple_ber(etype, p, der_len, &out, &out_len, &tmp_len);
+          if (result != ASN1_SUCCESS)
             {
-              free(total);
-              return ret;
+              warn();
+              goto cleanup;
             }
+
           p += tmp_len;
-          der_len -= tmp_len;
+          DECR_LEN(der_len, tmp_len);
+
           if (ber_len) *ber_len += tmp_len;
 
-          if (der_len < 2) /* we need the EOC */
-            {
-              free(total);
-              return ASN1_DER_ERROR;
-            }
+          DECR_LEN(der_len, 2); /* we need the EOC */
 
          if (out_len > 0)
            {
-              ret = append(&total, &total_size, out, out_len);
-              free(out);
-              if (ret != ASN1_SUCCESS)
+              result = append(&total, &total_size, out, out_len);
+              if (result != ASN1_SUCCESS)
                 {
-                  free(total);
-                  return ret;
+                  warn();
+                  goto cleanup;
                 }
            }
 
+          free(out);
+          out = NULL;
+
          if (p[0] == 0 && p[1] == 0) /* EOC */
            {
               if (ber_len) *ber_len += 2;
              break;
            }
+
+          /* no EOC */
+          der_len += 2;
+
+          if (der_len == 2)
+            {
+              warn();
+              result = ASN1_DER_ERROR;
+              goto cleanup;
+            }
         }
       while(1);
     }
@@ -2294,29 +2265,67 @@ asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
     {
       if (ber_len)
         {
-          ret = asn1_get_length_der (p, der_len, &len_len);
-          if (ret < 0)
+          result = asn1_get_length_der (p, der_len, &len_len);
+          if (result < 0)
             {
               warn();
-              return ASN1_DER_ERROR;
+              result = ASN1_DER_ERROR;
+              goto cleanup;
             }
-          *ber_len += ret + len_len;
+          *ber_len += result + len_len;
         }
 
       /* non-string values are decoded as DER */
-      ret = asn1_decode_simple_der(etype, der, _der_len, (const unsigned char**)&out, &out_len);
-      if (ret != ASN1_SUCCESS)
-        return ret;
+      result = _asn1_decode_simple_der(etype, der, _der_len, &cout, &out_len, dflags);
+      if (result != ASN1_SUCCESS)
+        {
+          warn();
+          goto cleanup;
+        }
 
-      ret = append(&total, &total_size, out, out_len);
-      if (ret != ASN1_SUCCESS)
-        return ret;
+      result = append(&total, &total_size, cout, out_len);
+      if (result != ASN1_SUCCESS)
+        {
+          warn();
+          goto cleanup;
+        }
     }
   else
-    return ASN1_DER_ERROR;
+    {
+      warn();
+      result = ASN1_DER_ERROR;
+      goto cleanup;
+    }
 
   *str = total;
   *str_len = total_size;
 
   return ASN1_SUCCESS;
+cleanup:
+  free(out);
+  free(total);
+  return result;
+}
+
+/**
+ * asn1_decode_simple_ber:
+ * @etype: The type of the string to be encoded (ASN1_ETYPE_)
+ * @der: the encoded string
+ * @_der_len: the bytes of the encoded string
+ * @str: a pointer to the data
+ * @str_len: the length of the data
+ * @ber_len: the total length occupied by BER (may be %NULL)
+ *
+ * Decodes a BER encoded type. The output is an allocated value 
+ * of the data. This decodes BER STRINGS only. Other types are
+ * decoded as DER.
+ *
+ * Returns: %ASN1_SUCCESS if successful or an error value.
+ **/
+int
+asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
+                       unsigned int _der_len, unsigned char **str,
+                       unsigned int *str_len, unsigned int *ber_len)
+{
+  return _asn1_decode_simple_ber(etype, der, _der_len, str, str_len, ber_len, DECODE_FLAG_HAVE_TAG);
 }
index 321302af06fa6d2b171f4cea269dd2473c074879..dceb8ba83e5d4cba8e93442a6ec22fe551a8913a 100644 (file)
@@ -52,7 +52,7 @@ _asn1_hierarchical_name (asn1_node node, char *name, int name_size)
          _asn1_str_cat (name, name_size, ".");
          _asn1_str_cat (name, name_size, tmp_name);
        }
-      p = _asn1_get_up (p);
+      p = _asn1_find_up (p);
     }
 
   if (name[0] == 0)
@@ -132,14 +132,14 @@ _asn1_convert_integer (const unsigned char *value, unsigned char *value_out,
  * node. The new element will have a name of '?number', where number
  * is a monotonically increased serial number.
  *
- * The last element in the list may be provided in @ptail, to avoid
+ * The last element in the list may be provided in @pcache, to avoid
  * traversing the list, an expensive operation in long lists.
  *
- * On success it returns in @ptail the added element (which is the 
+ * On success it returns in @pcache the added element (which is the 
  * tail in the list of added elements).
  */
 int
-_asn1_append_sequence_set (asn1_node node, asn1_node *ptail)
+_asn1_append_sequence_set (asn1_node node, struct node_tail_cache_st *pcache)
 {
   asn1_node p, p2;
   char temp[LTOSTR_MAX_SIZE];
@@ -154,18 +154,24 @@ _asn1_append_sequence_set (asn1_node node, asn1_node *ptail)
     p = p->right;
   p2 = _asn1_copy_structure3 (p);
 
-  if (ptail == NULL || *ptail == NULL || (*ptail)->up != p->up)
-    while (p->right) {
-      p = p->right;
+  if (pcache == NULL || pcache->tail == NULL || pcache->head != node)
+    {
+      while (p->right)
+        {
+          p = p->right;
+        }
     }
   else
     {
-      p = *ptail;
+      p = pcache->tail;
     }
 
   _asn1_set_right (p, p2);
-  if (ptail)
-    *ptail = p2;
+  if (pcache)
+    {
+      pcache->head = node;
+      pcache->tail = p2;
+    }
 
   if (p->name[0] == 0)
     _asn1_str_cpy (temp, sizeof (temp), "?1");
index 65a484569953dd6246043ac11dd25513542781fc..4e45367415ce6b15425428dedaf538bbf7b9e4d1 100644 (file)
 #define _ELEMENT_H
 
 
-int _asn1_append_sequence_set (asn1_node node, asn1_node *pcached);
+struct node_tail_cache_st
+{
+       asn1_node head; /* the first element of the sequence */
+       asn1_node tail;
+};
+
+int _asn1_append_sequence_set (asn1_node node, struct node_tail_cache_st *pcached);
 
 int _asn1_convert_integer (const unsigned char *value,
                           unsigned char *value_out,
index 8cc79cca2e61d57823ddef2bba86c4c38ff5dcb9..f1f13024e4b5bc3a4893c79a05028d8db2180f78 100644 (file)
@@ -51,7 +51,6 @@ struct asn1_node_st
   unsigned int type;           /* Node type */
   unsigned char *value;                /* Node value */
   int value_len;
-  asn1_node up;                        /* Pointer to the parent node */
   asn1_node down;              /* Pointer to the son node */
   asn1_node right;             /* Pointer to the brother node */
   asn1_node left;              /* Pointer to the next list element */
@@ -98,9 +97,16 @@ typedef struct tag_and_class_st
 
 #define ETYPE_TAG(etype) (_asn1_tags[etype].tag)
 #define ETYPE_CLASS(etype) (_asn1_tags[etype].class)
-#define ETYPE_OK(etype) ((etype != ASN1_ETYPE_INVALID && \
-                          etype <= _asn1_tags_size && \
-                          _asn1_tags[etype].desc != NULL)?1:0)
+#define ETYPE_OK(etype) (((etype) != ASN1_ETYPE_INVALID && \
+                          (etype) <= _asn1_tags_size && \
+                          _asn1_tags[(etype)].desc != NULL)?1:0)
+
+#define ETYPE_IS_STRING(etype) ((etype == ASN1_ETYPE_GENERALSTRING || \
+       etype == ASN1_ETYPE_NUMERIC_STRING || etype == ASN1_ETYPE_IA5_STRING || \
+       etype == ASN1_ETYPE_TELETEX_STRING || etype == ASN1_ETYPE_PRINTABLE_STRING || \
+       etype == ASN1_ETYPE_UNIVERSAL_STRING || etype == ASN1_ETYPE_BMP_STRING || \
+       etype == ASN1_ETYPE_UTF8_STRING || etype == ASN1_ETYPE_VISIBLE_STRING || \
+       etype == ASN1_ETYPE_OCTET_STRING)?1:0)
 
 extern unsigned int _asn1_tags_size;
 extern const tag_and_class_st _asn1_tags[];
@@ -191,4 +197,20 @@ convert_old_type (unsigned int ntype)
     return ntype;
 }
 
+static inline
+void *_asn1_realloc(void *ptr, size_t size)
+{
+  void *ret;
+
+  if (size == 0)
+    return ptr;
+
+  ret = realloc(ptr, size);
+  if (ret == NULL)
+    {
+      free(ptr);
+    }
+  return ret;
+}
+
 #endif /* INT_H */
index 53cec5e6a1dc3c3f36500aa6fb112a2aca2b2492..aa9e8a480cdf03ee828c6b96e763678954a668c9 100644 (file)
@@ -44,7 +44,7 @@ extern "C"
 {
 #endif
 
-#define ASN1_VERSION "4.4"
+#define ASN1_VERSION "4.8"
 
 #if defined(__GNUC__) && !defined(ASN1_INTERNAL_BUILD)
 # define _ASN1_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
@@ -374,6 +374,11 @@ extern "C"
                      int *ret_len, unsigned char *str,
                      int str_size, int *bit_len);
 
+  extern ASN1_API int
+    asn1_get_object_id_der (const unsigned char *der,
+                            int der_len, int *ret_len,
+                           char *str, int str_size);
+
 /* Compatibility types */
 
   typedef int asn1_retCode;    /* type returned by libtasn1 functions */
index da9a388fe3204d22f56a138af319ee8a9b77d7f0..52700c6d0ae18b07080eaee67216f02777b8964e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ * Copyright (C) 2000-2016 Free Software Foundation, Inc.
  *
  * This file is part of LIBTASN1.
  *
@@ -316,39 +316,49 @@ _asn1_append_value (asn1_node node, const void *value, unsigned int len)
 {
   if (node == NULL)
     return node;
-  if (node->value != NULL && node->value != node->small_value)
+
+  if (node->value == NULL)
+    return _asn1_set_value (node, value, len);
+
+  if (len == 0)
+    return node;
+
+  if (node->value == node->small_value)
     {
-      /* value is allocated */
+      /* value is in node */
       int prev_len = node->value_len;
       node->value_len += len;
-      node->value = realloc (node->value, node->value_len);
+      node->value = malloc (node->value_len);
       if (node->value == NULL)
        {
          node->value_len = 0;
          return NULL;
        }
+
+      if (prev_len > 0)
+        memcpy (node->value, node->small_value, prev_len);
+
       memcpy (&node->value[prev_len], value, len);
 
       return node;
     }
-  else if (node->value == node->small_value)
+  else /* if (node->value != NULL && node->value != node->small_value) */
     {
-      /* value is in node */
+      /* value is allocated */
       int prev_len = node->value_len;
       node->value_len += len;
-      node->value = malloc (node->value_len);
+
+      node->value = _asn1_realloc (node->value, node->value_len);
       if (node->value == NULL)
        {
          node->value_len = 0;
          return NULL;
        }
-      memcpy (node->value, node->small_value, prev_len);
+
       memcpy (&node->value[prev_len], value, len);
 
       return node;
     }
-  else                         /* node->value == NULL */
-    return _asn1_set_value (node, value, len);
 }
 
 /******************************************************************/
@@ -425,11 +435,7 @@ _asn1_set_right (asn1_node node, asn1_node right)
     return node;
   node->right = right;
   if (right)
-    {
-      right->left = node;
-      if (right->up == NULL)
-        right->up = node->up;
-    }
+    right->left = node;
   return node;
 }
 
@@ -625,7 +631,7 @@ _asn1_change_integer_value (asn1_node node)
            {
              while (1)
                {
-                 p = _asn1_get_up (p);
+                 p = _asn1_find_up (p);
                  if (p == node)
                    {
                      p = NULL;
@@ -753,7 +759,7 @@ _asn1_expand_object_id (asn1_node node)
            move = UP;
        }
       if (move == UP)
-       p = _asn1_get_up (p);
+       p = _asn1_find_up (p);
     }
 
 
@@ -786,6 +792,9 @@ _asn1_expand_object_id (asn1_node node)
                    {
                      if (type_field (p4->type) == ASN1_ETYPE_CONSTANT)
                        {
+                         if (p4->value == NULL)
+                           return ASN1_VALUE_NOT_FOUND;
+
                          if (name2[0])
                            _asn1_str_cat (name2, sizeof (name2), ".");
                          _asn1_str_cat (name2, sizeof (name2),
@@ -825,7 +834,7 @@ _asn1_expand_object_id (asn1_node node)
            move = UP;
        }
       if (move == UP)
-       p = _asn1_get_up (p);
+       p = _asn1_find_up (p);
     }
 
   return ASN1_SUCCESS;
@@ -895,7 +904,7 @@ _asn1_type_set_config (asn1_node node)
            move = UP;
        }
       if (move == UP)
-       p = _asn1_get_up (p);
+       p = _asn1_find_up (p);
     }
 
   return ASN1_SUCCESS;
@@ -992,7 +1001,7 @@ _asn1_check_identifier (asn1_node node)
        {
          while (1)
            {
-             p = _asn1_get_up (p);
+             p = _asn1_find_up (p);
              if (p == node)
                {
                  p = NULL;
@@ -1052,7 +1061,7 @@ _asn1_set_default_tag (asn1_node node)
        {
          while (1)
            {
-             p = _asn1_get_up (p);
+             p = _asn1_find_up (p);
              if (p == node)
                {
                  p = NULL;
index 437f1c863f5653615bf85e38dc1c0b5037c70720..10b864b0f5eca73dfd3800757ba09040d266a6d8 100644 (file)
@@ -58,14 +58,6 @@ char *_asn1_ltostr (long v, char str[LTOSTR_MAX_SIZE]);
 
 asn1_node _asn1_find_up (asn1_node node);
 
-inline static asn1_node _asn1_get_up(asn1_node node)
-{
-       if (node && node->up)
-               return node->up;
-       else
-               return _asn1_find_up(node);
-}
-
 int _asn1_change_integer_value (asn1_node node);
 
 int _asn1_expand_object_id (asn1_node node);
@@ -108,10 +100,7 @@ _asn1_set_down (asn1_node node, asn1_node down)
     return node;
   node->down = down;
   if (down)
-    {
-      down->left = node;
-      down->up = node;
-    }
+    down->left = node;
   return node;
 }
 
index ffb6aa50922dd7a63a5985afebe404b86ab1a506..01715b138baef14dd422756b5a8c17718360d8de 100644 (file)
@@ -134,7 +134,7 @@ _asn1_create_static_structure (asn1_node pointer, char *output_file_name,
        {
          while (1)
            {
-             p = _asn1_get_up (p);
+             p = _asn1_find_up (p);
              if (p == pointer)
                {
                  p = NULL;
@@ -183,6 +183,8 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions,
   int result;
   unsigned int type;
 
+  if (errorDescription)
+    errorDescription[0] = 0;
 
   if (*definitions != NULL)
     return ASN1_ELEMENT_NOT_EMPTY;
@@ -221,7 +223,7 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions,
              if (p_last == *definitions)
                break;
 
-             p_last = _asn1_get_up (p_last);
+             p_last = _asn1_find_up (p_last);
 
              if (p_last == NULL)
                break;
@@ -321,7 +323,7 @@ asn1_delete_structure2 (asn1_node * structure, unsigned int flags)
          p2 = p->right;
          if (p != *structure)
            {
-             p3 = _asn1_get_up (p);
+             p3 = _asn1_find_up (p);
              _asn1_set_down (p3, p2);
              _asn1_remove_node (p, flags);
              p = p3;
@@ -331,7 +333,7 @@ asn1_delete_structure2 (asn1_node * structure, unsigned int flags)
              p3 = _asn1_find_left (p);
              if (!p3)
                {
-                 p3 = _asn1_get_up (p);
+                 p3 = _asn1_find_up (p);
                  if (p3)
                    _asn1_set_down (p3, p2);
                  else
@@ -379,7 +381,7 @@ asn1_delete_element (asn1_node structure, const char *element_name)
   p3 = _asn1_find_left (source_node);
   if (!p3)
     {
-      p3 = _asn1_get_up (source_node);
+      p3 = _asn1_find_up (source_node);
       if (p3)
        _asn1_set_down (p3, p2);
       else if (source_node->right)
@@ -441,8 +443,8 @@ _asn1_copy_structure3 (asn1_node source_node)
       else
        {
          move = UP;
-         p_s = _asn1_get_up (p_s);
-         p_d = _asn1_get_up (p_d);
+         p_s = _asn1_find_up (p_s);
+         p_d = _asn1_find_up (p_d);
        }
     }
   while (p_s != source_node);
@@ -542,7 +544,7 @@ _asn1_type_choice_config (asn1_node node)
            move = UP;
        }
       if (move == UP)
-       p = _asn1_get_up (p);
+       p = _asn1_find_up (p);
     }
 
   return ASN1_SUCCESS;
@@ -593,7 +595,7 @@ _asn1_expand_identifier (asn1_node * node, asn1_node root)
                _asn1_set_right (p3, p2);
              else
                {
-                 p3 = _asn1_get_up (p);
+                 p3 = _asn1_find_up (p);
                  if (p3)
                    _asn1_set_down (p3, p2);
                  else
@@ -649,7 +651,7 @@ _asn1_expand_identifier (asn1_node * node, asn1_node root)
            move = UP;
        }
       if (move == UP)
-       p = _asn1_get_up (p);
+       p = _asn1_find_up (p);
     }
 
   return ASN1_SUCCESS;
@@ -832,7 +834,7 @@ asn1_print_structure (FILE * out, asn1_node structure, const char *name,
                  fprintf (out, "  value:0x");
                  if (len > 0)
                    for (k = 0; k < len; k++)
-                     fprintf (out, "%02x", (p->value)[k + len2]);
+                     fprintf (out, "%02x", (unsigned) (p->value)[k + len2]);
                }
              break;
            case ASN1_ETYPE_ENUMERATED:
@@ -843,7 +845,7 @@ asn1_print_structure (FILE * out, asn1_node structure, const char *name,
                  fprintf (out, "  value:0x");
                  if (len > 0)
                    for (k = 0; k < len; k++)
-                     fprintf (out, "%02x", (p->value)[k + len2]);
+                     fprintf (out, "%02x", (unsigned) (p->value)[k + len2]);
                }
              break;
            case ASN1_ETYPE_BOOLEAN:
@@ -865,7 +867,7 @@ asn1_print_structure (FILE * out, asn1_node structure, const char *name,
                      fprintf (out, "  value(%i):",
                               (len - 1) * 8 - (p->value[len2]));
                      for (k = 1; k < len; k++)
-                       fprintf (out, "%02x", (p->value)[k + len2]);
+                       fprintf (out, "%02x", (unsigned) (p->value)[k + len2]);
                    }
                }
              break;
@@ -905,7 +907,7 @@ asn1_print_structure (FILE * out, asn1_node structure, const char *name,
                  fprintf (out, "  value:");
                  if (len > 0)
                    for (k = 0; k < len; k++)
-                     fprintf (out, "%02x", (p->value)[k + len2]);
+                     fprintf (out, "%02x", (unsigned) (p->value)[k + len2]);
                }
              break;
            case ASN1_ETYPE_OBJECT_ID:
@@ -920,7 +922,7 @@ asn1_print_structure (FILE * out, asn1_node structure, const char *name,
                  fprintf (out, "  value:");
                  if (len2 > 0)
                    for (k = 0; k < len2; k++)
-                     fprintf (out, "%02x", (p->value)[k + len3]);
+                     fprintf (out, "%02x", (unsigned) (p->value)[k + len3]);
                }
              break;
            case ASN1_ETYPE_SET:
@@ -1017,7 +1019,7 @@ asn1_print_structure (FILE * out, asn1_node structure, const char *name,
        {
          while (1)
            {
-             p = _asn1_get_up (p);
+             p = _asn1_find_up (p);
              if (p == root)
                {
                  p = NULL;