libtasn1-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU libtasn1 branch, master, updated. libtasn1_3_0-26-g1d02266


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU libtasn1 branch, master, updated. libtasn1_3_0-26-g1d02266
Date: Fri, 23 Nov 2012 20:25:31 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU libtasn1".

http://git.savannah.gnu.org/cgit/libtasn1.git/commit/?id=1d02266a174c939e9ca1460641c8eaa9dc2a7843

The branch, master has been updated
       via  1d02266a174c939e9ca1460641c8eaa9dc2a7843 (commit)
       via  d23e8f3918d401fbaa25a1342b5db368f9f3adef (commit)
       via  f4e6030e0ee82a3d10ad9c0f55fad972d1c3a2c5 (commit)
       via  1153d7fa1ba99b6320cfc152395508692480440d (commit)
      from  ce0dbb2d2e8c5c18532afce2833af334440ae00c (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 1d02266a174c939e9ca1460641c8eaa9dc2a7843
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Nov 23 21:00:50 2012 +0100

    simplified and renamed asn1_encode_string_der() and asn1_decode_string_der()

commit d23e8f3918d401fbaa25a1342b5db368f9f3adef
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Nov 23 20:29:02 2012 +0100

    renamed types

commit f4e6030e0ee82a3d10ad9c0f55fad972d1c3a2c5
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Nov 23 20:24:35 2012 +0100

    Added asn1_decode_string_der() and asn1_encode_string_der().

commit 1153d7fa1ba99b6320cfc152395508692480440d
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Nov 23 09:47:24 2012 +0100

    zeroize last_error_token on unknown errors.

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

Summary of changes:
 .gitignore           |    4 +
 NEWS                 |    1 +
 configure.ac         |    1 +
 lib/ASN1.c           |   38 ++++++------
 lib/ASN1.y           |   38 ++++++------
 lib/coding.c         |  167 ++++++++++++++++++++++++++++++++++++++------------
 lib/decoding.c       |  125 ++++++++++++++++++++++++++-----------
 lib/element.c        |   38 ++++++------
 lib/int.h            |   21 ++++---
 lib/libtasn1.h       |   81 ++++++++++++++-----------
 lib/libtasn1.map     |    2 +
 lib/parser_aux.c     |    6 +-
 lib/parser_aux.h     |    2 +-
 lib/structure.c      |   16 +++---
 tests/Makefile.am    |    7 +-
 tests/Test_strings.c |   98 +++++++++++++++++++++++++++++
 16 files changed, 454 insertions(+), 191 deletions(-)
 create mode 100644 tests/Test_strings.c

diff --git a/.gitignore b/.gitignore
index e6f9fc5..2b5f79c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+tags
+*~
 *.gcda
 *.gcno
 *.gcov
@@ -188,6 +190,8 @@ tests/Makefile
 tests/Makefile.in
 tests/Test_encoding
 tests/Test_encoding.o
+tests/Test_strings.o
+tests/Test_strings
 tests/Test_errors
 tests/Test_errors.o
 tests/Test_indefinite
diff --git a/NEWS b/NEWS
index be519ba..a29e187 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,7 @@ GNU Libtasn1 NEWS                                     -*- 
outline -*-
   PrintableString, UniversalString, BMPString, UTF8String. When re-defined
   a warning is being print instead of failing.
 - Parser outputs more detailed syntax error message.
+- Added asn1_decode_simple_der() and asn1_encode_simple_der().
 
 * Noteworthy changes in release 3.0 (2012-10-28) [stable]
 - Added tool in tests/ to benchmark X.509 structure decoding.
diff --git a/configure.ac b/configure.ac
index 0acd74a..839fc6b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -78,6 +78,7 @@ if test "$gl_gcc_warnings" = yes; then
   nw="$nw -Wundef"                  #
   nw="$nw -Wunreachable-code"       # Too many false positives
   nw="$nw -Wunused-macros"          # Breaks on bison generated ASN1.c
+  nw="$nw -Wswitch-default"         # Breaks on bison generated ASN1.c
   nw="$nw -Wunsafe-loop-optimizations"
   nw="$nw -Wstrict-overflow"
   nw="$nw -Wsuggest-attribute=pure" # Is it worth using pure attributes?
diff --git a/lib/ASN1.c b/lib/ASN1.c
index 075c81c..928d28d 100644
--- a/lib/ASN1.c
+++ b/lib/ASN1.c
@@ -2047,14 +2047,14 @@ yyreduce:
 
 /* Line 1806 of yacc.c  */
 #line 254 "ASN1.y"
-    
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_NUMERICSTRING|CONST_UNIVERSAL);}
+    
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_NUMERIC_STRING|CONST_UNIVERSAL);}
     break;
 
   case 47:
 
 /* Line 1806 of yacc.c  */
 #line 255 "ASN1.y"
-    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_NUMERICSTRING|CONST_SIZE);
+    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_NUMERIC_STRING|CONST_SIZE);
                                          
_asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
     break;
 
@@ -2062,14 +2062,14 @@ yyreduce:
 
 /* Line 1806 of yacc.c  */
 #line 259 "ASN1.y"
-    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_IA5STRING);}
+    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_IA5_STRING);}
     break;
 
   case 49:
 
 /* Line 1806 of yacc.c  */
 #line 260 "ASN1.y"
-    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_IA5STRING|CONST_SIZE);
+    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_IA5_STRING|CONST_SIZE);
                                          
_asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
     break;
 
@@ -2077,14 +2077,14 @@ yyreduce:
 
 /* Line 1806 of yacc.c  */
 #line 264 "ASN1.y"
-    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_TELETEXSTRING);}
+    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_TELETEX_STRING);}
     break;
 
   case 51:
 
 /* Line 1806 of yacc.c  */
 #line 265 "ASN1.y"
-    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_TELETEXSTRING|CONST_SIZE);
+    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_TELETEX_STRING|CONST_SIZE);
                                          
_asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
     break;
 
@@ -2092,14 +2092,14 @@ yyreduce:
 
 /* Line 1806 of yacc.c  */
 #line 269 "ASN1.y"
-    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_PRINTABLESTRING);}
+    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_PRINTABLE_STRING);}
     break;
 
   case 53:
 
 /* Line 1806 of yacc.c  */
 #line 270 "ASN1.y"
-    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_PRINTABLESTRING|CONST_SIZE);
+    
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_PRINTABLE_STRING|CONST_SIZE);
                                          
_asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
     break;
 
@@ -2107,14 +2107,14 @@ yyreduce:
 
 /* Line 1806 of yacc.c  */
 #line 274 "ASN1.y"
-    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_UNIVERSALSTRING);}
+    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_UNIVERSAL_STRING);}
     break;
 
   case 55:
 
 /* Line 1806 of yacc.c  */
 #line 275 "ASN1.y"
-    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_UNIVERSALSTRING|CONST_SIZE);
+    
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_UNIVERSAL_STRING|CONST_SIZE);
                                          
_asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
     break;
 
@@ -2122,14 +2122,14 @@ yyreduce:
 
 /* Line 1806 of yacc.c  */
 #line 279 "ASN1.y"
-    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_BMPSTRING);}
+    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_BMP_STRING);}
     break;
 
   case 57:
 
 /* Line 1806 of yacc.c  */
 #line 280 "ASN1.y"
-    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_BMPSTRING|CONST_SIZE);
+    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_BMP_STRING|CONST_SIZE);
                                          
_asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
     break;
 
@@ -2137,14 +2137,14 @@ yyreduce:
 
 /* Line 1806 of yacc.c  */
 #line 284 "ASN1.y"
-    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_UTF8STRING);}
+    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_UTF8_STRING);}
     break;
 
   case 59:
 
 /* Line 1806 of yacc.c  */
 #line 285 "ASN1.y"
-    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_UTF8STRING|CONST_SIZE);
+    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_UTF8_STRING|CONST_SIZE);
                                          
_asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
     break;
 
@@ -2152,14 +2152,14 @@ yyreduce:
 
 /* Line 1806 of yacc.c  */
 #line 289 "ASN1.y"
-    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_VISIBLESTRING);}
+    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_VISIBLE_STRING);}
     break;
 
   case 61:
 
 /* Line 1806 of yacc.c  */
 #line 290 "ASN1.y"
-    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_VISIBLESTRING|CONST_SIZE);
+    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_VISIBLE_STRING|CONST_SIZE);
                                          
_asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
     break;
 
@@ -3286,16 +3286,16 @@ _asn1_yyerror (const char *s)
       snprintf (last_error_token, ASN1_MAX_ERROR_DESCRIPTION_SIZE,
                 "%s", last_token);
       fprintf(stderr, 
-               "%s:%ld: Warning: %s is a built-in ASN.1 type.\n",
+               "%s:%u: Warning: %s is a built-in ASN.1 type.\n",
                file_name, line_number, last_token);
       return;
     }
-
+  last_error_token[0] = 0;
 
   if (result_parse != ASN1_NAME_TOO_LONG)
     {
       snprintf (last_error, ASN1_MAX_ERROR_DESCRIPTION_SIZE,
-                "%s:%ld: Error: %s near '%s'", file_name,
+                "%s:%u: Error: %s near '%s'", file_name,
                 line_number, s, last_token);
       result_parse = ASN1_SYNTAX_ERROR;
     }
diff --git a/lib/ASN1.y b/lib/ASN1.y
index d975632..dafe15a 100644
--- a/lib/ASN1.y
+++ b/lib/ASN1.y
@@ -251,43 +251,43 @@ generalstring_def: GeneralString 
{$$=_asn1_add_static_node(ASN1_ETYPE_GENERALSTR
                                          _asn1_set_down($$,$2);}
 ;
 
-numericstring_def: NumericString 
{$$=_asn1_add_static_node(ASN1_ETYPE_NUMERICSTRING|CONST_UNIVERSAL);}
-                | NumericString size_def 
{$$=_asn1_add_static_node(ASN1_ETYPE_NUMERICSTRING|CONST_SIZE);
+numericstring_def: NumericString 
{$$=_asn1_add_static_node(ASN1_ETYPE_NUMERIC_STRING|CONST_UNIVERSAL);}
+                | NumericString size_def 
{$$=_asn1_add_static_node(ASN1_ETYPE_NUMERIC_STRING|CONST_SIZE);
                                          _asn1_set_down($$,$2);}
 ;
 
-ia5string_def: IA5String {$$=_asn1_add_static_node(ASN1_ETYPE_IA5STRING);}
-                | IA5String size_def 
{$$=_asn1_add_static_node(ASN1_ETYPE_IA5STRING|CONST_SIZE);
+ia5string_def: IA5String {$$=_asn1_add_static_node(ASN1_ETYPE_IA5_STRING);}
+                | IA5String size_def 
{$$=_asn1_add_static_node(ASN1_ETYPE_IA5_STRING|CONST_SIZE);
                                          _asn1_set_down($$,$2);}
 ;
 
-teletexstring_def: TeletexString 
{$$=_asn1_add_static_node(ASN1_ETYPE_TELETEXSTRING);}
-                | TeletexString size_def 
{$$=_asn1_add_static_node(ASN1_ETYPE_TELETEXSTRING|CONST_SIZE);
+teletexstring_def: TeletexString 
{$$=_asn1_add_static_node(ASN1_ETYPE_TELETEX_STRING);}
+                | TeletexString size_def 
{$$=_asn1_add_static_node(ASN1_ETYPE_TELETEX_STRING|CONST_SIZE);
                                          _asn1_set_down($$,$2);}
 ;
 
-printablestring_def: PrintableString 
{$$=_asn1_add_static_node(ASN1_ETYPE_PRINTABLESTRING);}
-                | PrintableString size_def 
{$$=_asn1_add_static_node(ASN1_ETYPE_PRINTABLESTRING|CONST_SIZE);
+printablestring_def: PrintableString 
{$$=_asn1_add_static_node(ASN1_ETYPE_PRINTABLE_STRING);}
+                | PrintableString size_def 
{$$=_asn1_add_static_node(ASN1_ETYPE_PRINTABLE_STRING|CONST_SIZE);
                                          _asn1_set_down($$,$2);}
 ;
 
-universalstring_def: UniversalString 
{$$=_asn1_add_static_node(ASN1_ETYPE_UNIVERSALSTRING);}
-                | UniversalString size_def 
{$$=_asn1_add_static_node(ASN1_ETYPE_UNIVERSALSTRING|CONST_SIZE);
+universalstring_def: UniversalString 
{$$=_asn1_add_static_node(ASN1_ETYPE_UNIVERSAL_STRING);}
+                | UniversalString size_def 
{$$=_asn1_add_static_node(ASN1_ETYPE_UNIVERSAL_STRING|CONST_SIZE);
                                          _asn1_set_down($$,$2);}
 ;
 
-bmpstring_def: BMPString {$$=_asn1_add_static_node(ASN1_ETYPE_BMPSTRING);}
-                | BMPString size_def 
{$$=_asn1_add_static_node(ASN1_ETYPE_BMPSTRING|CONST_SIZE);
+bmpstring_def: BMPString {$$=_asn1_add_static_node(ASN1_ETYPE_BMP_STRING);}
+                | BMPString size_def 
{$$=_asn1_add_static_node(ASN1_ETYPE_BMP_STRING|CONST_SIZE);
                                          _asn1_set_down($$,$2);}
 ;
 
-utf8string_def: UTF8String {$$=_asn1_add_static_node(ASN1_ETYPE_UTF8STRING);}
-                | UTF8String size_def 
{$$=_asn1_add_static_node(ASN1_ETYPE_UTF8STRING|CONST_SIZE);
+utf8string_def: UTF8String {$$=_asn1_add_static_node(ASN1_ETYPE_UTF8_STRING);}
+                | UTF8String size_def 
{$$=_asn1_add_static_node(ASN1_ETYPE_UTF8_STRING|CONST_SIZE);
                                          _asn1_set_down($$,$2);}
 ;
 
-visiblestring_def: VisibleString 
{$$=_asn1_add_static_node(ASN1_ETYPE_VISIBLESTRING);}
-                | VisibleString size_def 
{$$=_asn1_add_static_node(ASN1_ETYPE_VISIBLESTRING|CONST_SIZE);
+visiblestring_def: VisibleString 
{$$=_asn1_add_static_node(ASN1_ETYPE_VISIBLE_STRING);}
+                | VisibleString size_def 
{$$=_asn1_add_static_node(ASN1_ETYPE_VISIBLE_STRING|CONST_SIZE);
                                          _asn1_set_down($$,$2);}
 ;
 
@@ -872,16 +872,16 @@ _asn1_yyerror (const char *s)
       snprintf (last_error_token, ASN1_MAX_ERROR_DESCRIPTION_SIZE,
                 "%s", last_token);
       fprintf(stderr, 
-               "%s:%ld: Warning: %s is a built-in ASN.1 type.\n",
+               "%s:%u: Warning: %s is a built-in ASN.1 type.\n",
                file_name, line_number, last_token);
       return;
     }
-
+  last_error_token[0] = 0;
 
   if (result_parse != ASN1_NAME_TOO_LONG)
     {
       snprintf (last_error, ASN1_MAX_ERROR_DESCRIPTION_SIZE,
-                "%s:%ld: Error: %s near '%s'", file_name,
+                "%s:%u: Error: %s near '%s'", file_name,
                 line_number, s, last_token);
       result_parse = ASN1_SYNTAX_ERROR;
     }
diff --git a/lib/coding.c b/lib/coding.c
index 0802f73..aa777f3 100644
--- a/lib/coding.c
+++ b/lib/coding.c
@@ -61,24 +61,30 @@ _asn1_error_description_value_not_found (asn1_node node,
 /**
  * asn1_length_der:
  * @len: value to convert.
- * @ans: string returned.
- * @ans_len: number of meaningful bytes of ANS (ans[0]..ans[ans_len-1]).
+ * @der: the encoding (may be %NULL).
+ * @der_len: number of meaningful bytes of ANS (der[0]..der[der_len-1]).
  *
- * Creates the DER coding for the LEN parameter (only the length).
- * The @ans buffer is pre-allocated and must have room for the output.
+ * Creates the DER encoding of the provided length value.
+ * The @der buffer must have enough room for the output. The maximum
+ * length this function will encode is %ASN1_MAX_LENGTH_SIZE.
+ * 
+ * To know the size of the DER encoding use a %NULL value for @der.
  **/
 void
-asn1_length_der (unsigned long int len, unsigned char *ans, int *ans_len)
+asn1_length_der (unsigned long int len, unsigned char *der, int *der_len)
 {
   int k;
-  unsigned char temp[SIZEOF_UNSIGNED_LONG_INT];
+  unsigned char temp[ASN1_MAX_LENGTH_SIZE];
+#if SIZEOF_UNSIGNED_LONG_INT > 8
+  len &= 0xFFFFFFFFFFFFFFFF;
+#endif
 
   if (len < 128)
     {
       /* short form */
-      if (ans != NULL)
-       ans[0] = (unsigned char) len;
-      *ans_len = 1;
+      if (der != NULL)
+       der[0] = (unsigned char) len;
+      *der_len = 1;
     }
   else
     {
@@ -89,12 +95,12 @@ asn1_length_der (unsigned long int len, unsigned char *ans, 
int *ans_len)
          temp[k++] = len & 0xFF;
          len = len >> 8;
        }
-      *ans_len = k + 1;
-      if (ans != NULL)
+      *der_len = k + 1;
+      if (der != NULL)
        {
-         ans[0] = ((unsigned char) k & 0x7F) + 128;
+         der[0] = ((unsigned char) k & 0x7F) + 128;
          while (k--)
-           ans[*ans_len - 1 - k] = temp[k];
+           der[*der_len - 1 - k] = temp[k];
        }
     }
 }
@@ -103,6 +109,7 @@ asn1_length_der (unsigned long int len, unsigned char *ans, 
int *ans_len)
 /* Function : _asn1_tag_der                           */
 /* Description: creates the DER coding for the CLASS  */
 /* and TAG parameters.                                */
+/* It is limited by the ASN1_MAX_TAG_SIZE variable    */
 /* Parameters:                                        */
 /*   class: value to convert.                         */
 /*   tag_value: value to convert.                     */
@@ -116,7 +123,7 @@ _asn1_tag_der (unsigned char class, unsigned int tag_value,
               unsigned char *ans, int *ans_len)
 {
   int k;
-  unsigned char temp[SIZEOF_UNSIGNED_INT];
+  unsigned char temp[ASN1_MAX_TAG_SIZE];
 
   if (tag_value < 31)
     {
@@ -129,10 +136,13 @@ _asn1_tag_der (unsigned char class, unsigned int 
tag_value,
       /* Long form */
       ans[0] = (class & 0xE0) + 31;
       k = 0;
-      while (tag_value)
+      while (tag_value != 0)
        {
          temp[k++] = tag_value & 0x7F;
-         tag_value = tag_value >> 7;
+         tag_value >>= 7;
+         
+         if (k > ASN1_MAX_TAG_SIZE-1)
+           break; /* will not encode larger tags */
        }
       *ans_len = k + 1;
       while (k--)
@@ -143,12 +153,20 @@ _asn1_tag_der (unsigned char class, unsigned int 
tag_value,
 
 /**
  * asn1_octet_der:
- * @str: OCTET string.
- * @str_len: STR length (str[0]..str[str_len-1]).
- * @der: string returned.
- * @der_len: number of meaningful bytes of DER (der[0]..der[ans_len-1]).
+ * @str: the input data.
+ * @str_len: STR length (str[0]..str[*str_len-1]).
+ * @der: encoded string returned.
+ * @der_len: number of meaningful bytes of DER (der[0]..der[der_len-1]).
  *
- * Creates the DER coding for an OCTET type (length included).
+ * Creates a length-value DER encoding for the input data.
+ * The DER encoding of the input data will be placed in the @der variable.
+ *
+ * Note that the OCTET STRING tag is not included in the output.
+ *
+ * This function does not return any value because it is expected
+ * that @der_len will contain enough bytes to store the string
+ * plus the DER encoding. The DER encoding size can be obtained using
+ * asn1_length_der().
  **/
 void
 asn1_octet_der (const unsigned char *str, int str_len,
@@ -158,11 +176,70 @@ asn1_octet_der (const unsigned char *str, int str_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;
 }
 
+
+/**
+ * asn1_encode_simple_der:
+ * @etype: The type of the string to be encoded (ASN1_ETYPE_)
+ * @str: the string data.
+ * @str_len: the string length
+ * @tl: the encoded tag and length
+ * @tl_len: the bytes of the @tl field
+ *
+ * Creates the DER encoding for various simple ASN.1 types like strings etc.
+ * It stores the tag and length in @tl, which should have space for at least 
+ * %ASN1_MAX_TL_SIZE bytes. Initially @tl_len should contain the size of @tl.
+ *
+ * The complete DER encoding should consist of the value in @tl appended
+ * with the provided @str.
+ *
+ * Returns: %ASN1_SUCCESS if successful or an error value. 
+ **/
+int
+asn1_encode_simple_der (unsigned int etype, const unsigned char *str, unsigned 
int str_len,
+                        unsigned char *tl, unsigned int *tl_len)
+{
+  int tag_len, len_len;
+  unsigned tlen;
+  unsigned char der_tag[ASN1_MAX_TAG_SIZE];
+  unsigned char der_length[ASN1_MAX_LENGTH_SIZE];
+  unsigned char* p;
+
+  if (str == NULL)
+    return ASN1_VALUE_NOT_VALID;
+
+  if (ETYPE_OK(etype) == 0)
+    return ASN1_VALUE_NOT_VALID;
+    
+
+  _asn1_tag_der (ETYPE_CLASS(etype), ETYPE_TAG(etype),
+                der_tag, &tag_len);
+
+  asn1_length_der(str_len, der_length, &len_len);
+
+  if (tag_len <= 0 || len_len <= 0)
+    return ASN1_VALUE_NOT_VALID;
+  
+  tlen = tag_len + len_len;
+
+  if (*tl_len < tlen)
+    return ASN1_MEM_ERROR;
+
+  p = tl;
+  memcpy(p, der_tag, tag_len);
+  p+=tag_len;
+  memcpy(p, der_length, len_len);
+  
+  *tl_len = tlen;
+
+  return ASN1_SUCCESS;
+}
+
 /******************************************************/
 /* Function : _asn1_time_der                          */
 /* Description: creates the DER coding for a TIME     */
@@ -333,8 +410,16 @@ static const unsigned char bit_mask[] =
  * @der_len: number of meaningful bytes of DER
  *   (der[0]..der[ans_len-1]).
  *
- * Creates the DER coding for a BIT STRING type (length and pad
- * included).
+ * Creates a length-value DER encoding for the input data
+ * as it would have been for a BIT STRING.
+ * The DER encoded data will be copied in @der.
+ *
+ * Note that the BIT STRING tag is not included in the output.
+ *
+ * This function does not return any value because it is expected
+ * that @der_len will contain enough bytes to store the string
+ * plus the DER encoding. The DER encoding size can be obtained using
+ * asn1_length_der().
  **/
 void
 asn1_bit_der (const unsigned char *str, int bit_len,
@@ -344,6 +429,7 @@ asn1_bit_der (const unsigned char *str, int bit_len,
 
   if (der == NULL)
     return;
+
   len_byte = bit_len >> 3;
   len_pad = 8 - (bit_len & 7);
   if (len_pad == 8)
@@ -432,15 +518,15 @@ _asn1_complete_explicit_tag (asn1_node node, unsigned 
char *der,
 const tag_and_class_st _asn1_tags[] =
 {
   [ASN1_ETYPE_GENERALSTRING] = {ASN1_TAG_GENERALSTRING, ASN1_CLASS_UNIVERSAL, 
"type:GENERALSTRING"},
-  [ASN1_ETYPE_NUMERICSTRING] = {ASN1_TAG_NUMERICSTRING, ASN1_CLASS_UNIVERSAL, 
"type:NUMERIC_STR"},
-  [ASN1_ETYPE_IA5STRING] =     {ASN1_TAG_IA5STRING, ASN1_CLASS_UNIVERSAL, 
"type:IA5_STR"},
-  [ASN1_ETYPE_TELETEXSTRING] = {ASN1_TAG_TELETEXSTRING, ASN1_CLASS_UNIVERSAL, 
"type:TELETEX_STR"},
-  [ASN1_ETYPE_PRINTABLESTRING] = {ASN1_TAG_PRINTABLESTRING, 
ASN1_CLASS_UNIVERSAL, "type:PRINTABLE_STR"},
-  [ASN1_ETYPE_UNIVERSALSTRING] = {ASN1_TAG_UNIVERSALSTRING, 
ASN1_CLASS_UNIVERSAL, "type:UNIVERSAL_STR"},
-  [ASN1_ETYPE_BMPSTRING] =     {ASN1_TAG_BMPSTRING, ASN1_CLASS_UNIVERSAL, 
"type:BMP_STR"},
-  [ASN1_ETYPE_UTF8STRING] =    {ASN1_TAG_UTF8STRING, ASN1_CLASS_UNIVERSAL, 
"type:UTF8_STR"},
-  [ASN1_ETYPE_VISIBLESTRING] = {ASN1_TAG_VISIBLESTRING, ASN1_CLASS_UNIVERSAL, 
"type:VISIBLE_STR"},
-  [ASN1_ETYPE_OCTET_STRING] = {ASN1_TAG_OCTET_STRING, ASN1_CLASS_UNIVERSAL, 
"type:OCT_STR"},
+  [ASN1_ETYPE_NUMERIC_STRING] = {ASN1_TAG_NUMERIC_STRING, 
ASN1_CLASS_UNIVERSAL, "type:NUMERIC_STR"},
+  [ASN1_ETYPE_IA5_STRING] =     {ASN1_TAG_IA5_STRING, ASN1_CLASS_UNIVERSAL, 
"type:IA5_STR"},
+  [ASN1_ETYPE_TELETEX_STRING] = {ASN1_TAG_TELETEX_STRING, 
ASN1_CLASS_UNIVERSAL, "type:TELETEX_STR"},
+  [ASN1_ETYPE_PRINTABLE_STRING] = {ASN1_TAG_PRINTABLE_STRING, 
ASN1_CLASS_UNIVERSAL, "type:PRINTABLE_STR"},
+  [ASN1_ETYPE_UNIVERSAL_STRING] = {ASN1_TAG_UNIVERSAL_STRING, 
ASN1_CLASS_UNIVERSAL, "type:UNIVERSAL_STR"},
+  [ASN1_ETYPE_BMP_STRING] =       {ASN1_TAG_BMP_STRING, ASN1_CLASS_UNIVERSAL, 
"type:BMP_STR"},
+  [ASN1_ETYPE_UTF8_STRING] =      {ASN1_TAG_UTF8_STRING, ASN1_CLASS_UNIVERSAL, 
"type:UTF8_STR"},
+  [ASN1_ETYPE_VISIBLE_STRING] =   {ASN1_TAG_VISIBLE_STRING, 
ASN1_CLASS_UNIVERSAL, "type:VISIBLE_STR"},
+  [ASN1_ETYPE_OCTET_STRING] =    {ASN1_TAG_OCTET_STRING, ASN1_CLASS_UNIVERSAL, 
"type:OCT_STR"},
   [ASN1_ETYPE_BIT_STRING] = {ASN1_TAG_BIT_STRING, ASN1_CLASS_UNIVERSAL, 
"type:BIT_STR"},
   [ASN1_ETYPE_OBJECT_ID] =  {ASN1_TAG_OBJECT_ID, ASN1_CLASS_UNIVERSAL, 
"type:OBJ_STR"},
   [ASN1_ETYPE_NULL] =       {ASN1_TAG_NULL, ASN1_CLASS_UNIVERSAL, "type:NULL"},
@@ -452,6 +538,7 @@ const tag_and_class_st _asn1_tags[] =
   [ASN1_ETYPE_SET] =        {ASN1_TAG_SET, ASN1_CLASS_UNIVERSAL | 
ASN1_CLASS_STRUCTURED, "type:SET"},
   [ASN1_ETYPE_SET_OF] =     {ASN1_TAG_SET, ASN1_CLASS_UNIVERSAL | 
ASN1_CLASS_STRUCTURED, "type:SET_OF"},
 };
+unsigned int _asn1_tags_size = sizeof(_asn1_tags)/sizeof(_asn1_tags[0]);
 
 /******************************************************/
 /* Function : _asn1_insert_tag_der                    */
@@ -996,14 +1083,14 @@ asn1_der_coding (asn1_node element, const char *name, 
void *ider, int *len,
          break;
        case ASN1_ETYPE_OCTET_STRING:
        case ASN1_ETYPE_GENERALSTRING:
-       case ASN1_ETYPE_NUMERICSTRING:
-       case ASN1_ETYPE_IA5STRING:
-       case ASN1_ETYPE_TELETEXSTRING:
-       case ASN1_ETYPE_PRINTABLESTRING:
-       case ASN1_ETYPE_UNIVERSALSTRING:
-       case ASN1_ETYPE_BMPSTRING:
-       case ASN1_ETYPE_UTF8STRING:
-       case ASN1_ETYPE_VISIBLESTRING:
+       case ASN1_ETYPE_NUMERIC_STRING:
+       case ASN1_ETYPE_IA5_STRING:
+       case ASN1_ETYPE_TELETEX_STRING:
+       case ASN1_ETYPE_PRINTABLE_STRING:
+       case ASN1_ETYPE_UNIVERSAL_STRING:
+       case ASN1_ETYPE_BMP_STRING:
+       case ASN1_ETYPE_UTF8_STRING:
+       case ASN1_ETYPE_VISIBLE_STRING:
        case ASN1_ETYPE_BIT_STRING:
          if (p->value == NULL)
            {
diff --git a/lib/decoding.c b/lib/decoding.c
index eb4ca0e..5df1f36 100644
--- a/lib/decoding.c
+++ b/lib/decoding.c
@@ -498,14 +498,14 @@ _asn1_extract_tag_der (asn1_node node, const unsigned 
char *der, int der_len,
        case ASN1_ETYPE_ENUMERATED:
        case ASN1_ETYPE_OBJECT_ID:
        case ASN1_ETYPE_GENERALSTRING:
-       case ASN1_ETYPE_NUMERICSTRING:
-       case ASN1_ETYPE_IA5STRING:
-       case ASN1_ETYPE_TELETEXSTRING:
-       case ASN1_ETYPE_PRINTABLESTRING:
-       case ASN1_ETYPE_UNIVERSALSTRING:
-       case ASN1_ETYPE_BMPSTRING:
-       case ASN1_ETYPE_UTF8STRING:
-       case ASN1_ETYPE_VISIBLESTRING:
+       case ASN1_ETYPE_NUMERIC_STRING:
+       case ASN1_ETYPE_IA5_STRING:
+       case ASN1_ETYPE_TELETEX_STRING:
+       case ASN1_ETYPE_PRINTABLE_STRING:
+       case ASN1_ETYPE_UNIVERSAL_STRING:
+       case ASN1_ETYPE_BMP_STRING:
+       case ASN1_ETYPE_UTF8_STRING:
+       case ASN1_ETYPE_VISIBLE_STRING:
        case ASN1_ETYPE_BIT_STRING:
        case ASN1_ETYPE_SEQUENCE:
        case ASN1_ETYPE_SEQUENCE_OF:
@@ -1078,14 +1078,14 @@ asn1_der_decoding (asn1_node * element, const void 
*ider, int len,
              move = RIGHT;
              break;
            case ASN1_ETYPE_GENERALSTRING:
-            case ASN1_ETYPE_NUMERICSTRING:
-            case ASN1_ETYPE_IA5STRING:
-            case ASN1_ETYPE_TELETEXSTRING:
-            case ASN1_ETYPE_PRINTABLESTRING:
-            case ASN1_ETYPE_UNIVERSALSTRING:
-            case ASN1_ETYPE_BMPSTRING:
-            case ASN1_ETYPE_UTF8STRING:
-            case ASN1_ETYPE_VISIBLESTRING:
+            case ASN1_ETYPE_NUMERIC_STRING:
+            case ASN1_ETYPE_IA5_STRING:
+            case ASN1_ETYPE_TELETEX_STRING:
+            case ASN1_ETYPE_PRINTABLE_STRING:
+            case ASN1_ETYPE_UNIVERSAL_STRING:
+            case ASN1_ETYPE_BMP_STRING:
+            case ASN1_ETYPE_UTF8_STRING:
+            case ASN1_ETYPE_VISIBLE_STRING:
            case ASN1_ETYPE_BIT_STRING:
              len2 =
                asn1_get_length_der (der + counter, len - counter, &len3);
@@ -1277,7 +1277,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, 
int len,
              if (len4 != -1)
                {
                  len2 += len4;
-                 _asn1_set_value_octet (p, der + counter, len2 + len3);
+                 _asn1_set_value_lv (p, der + counter, len2 + len3);
                  counter += len2 + len3;
                }
              else
@@ -1294,7 +1294,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, 
int len,
                  if (result != ASN1_SUCCESS)
                    goto cleanup;
 
-                 _asn1_set_value_octet (p, der + counter, len2);
+                 _asn1_set_value_lv (p, der + counter, len2);
                  counter += len2;
 
                  /* Check if a couple of 0x00 are present due to an EXPLICIT 
TAG with
@@ -1756,14 +1756,14 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
              move = RIGHT;
              break;
            case ASN1_ETYPE_GENERALSTRING:
-            case ASN1_ETYPE_NUMERICSTRING:
-            case ASN1_ETYPE_IA5STRING:
-            case ASN1_ETYPE_TELETEXSTRING:
-            case ASN1_ETYPE_PRINTABLESTRING:
-            case ASN1_ETYPE_UNIVERSALSTRING:
-            case ASN1_ETYPE_BMPSTRING:
-            case ASN1_ETYPE_UTF8STRING:
-            case ASN1_ETYPE_VISIBLESTRING:
+            case ASN1_ETYPE_NUMERIC_STRING:
+            case ASN1_ETYPE_IA5_STRING:
+            case ASN1_ETYPE_TELETEX_STRING:
+            case ASN1_ETYPE_PRINTABLE_STRING:
+            case ASN1_ETYPE_UNIVERSAL_STRING:
+            case ASN1_ETYPE_BMP_STRING:
+            case ASN1_ETYPE_UTF8_STRING:
+            case ASN1_ETYPE_VISIBLE_STRING:
            case ASN1_ETYPE_BIT_STRING:
              len2 =
                asn1_get_length_der (der + counter, len - counter, &len3);
@@ -1973,7 +1973,7 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
                  len2 += len4;
                  if (state == FOUND)
                    {
-                     _asn1_set_value_octet (p, der + counter, len2 + len3);
+                     _asn1_set_value_lv (p, der + counter, len2 + len3);
 
                      if (p == nodeFound)
                        state = EXIT;
@@ -1996,7 +1996,7 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
 
                  if (state == FOUND)
                    {
-                     _asn1_set_value_octet (p, der + counter, len2);
+                     _asn1_set_value_lv (p, der + counter, len2);
 
                      if (p == nodeFound)
                        state = EXIT;
@@ -2352,14 +2352,14 @@ asn1_der_decoding_startEnd (asn1_node element, const 
void *ider, int len,
            case ASN1_ETYPE_INTEGER:
            case ASN1_ETYPE_ENUMERATED:
            case ASN1_ETYPE_GENERALSTRING:
-            case ASN1_ETYPE_NUMERICSTRING:
-            case ASN1_ETYPE_IA5STRING:
-            case ASN1_ETYPE_TELETEXSTRING:
-            case ASN1_ETYPE_PRINTABLESTRING:
-            case ASN1_ETYPE_UNIVERSALSTRING:
-            case ASN1_ETYPE_BMPSTRING:
-            case ASN1_ETYPE_UTF8STRING:
-            case ASN1_ETYPE_VISIBLESTRING:
+            case ASN1_ETYPE_NUMERIC_STRING:
+            case ASN1_ETYPE_IA5_STRING:
+            case ASN1_ETYPE_TELETEX_STRING:
+            case ASN1_ETYPE_PRINTABLE_STRING:
+            case ASN1_ETYPE_UNIVERSAL_STRING:
+            case ASN1_ETYPE_BMP_STRING:
+            case ASN1_ETYPE_UTF8_STRING:
+            case ASN1_ETYPE_VISIBLE_STRING:
            case ASN1_ETYPE_BIT_STRING:
              len2 =
                asn1_get_length_der (der + counter, len - counter, &len3);
@@ -2866,3 +2866,56 @@ asn1_expand_octet_string (asn1_node definitions, 
asn1_node * element,
 
   return retCode;
 }
+
+/**
+ * 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)
+{
+  int tag_len, len_len;
+  const unsigned char* p;
+  unsigned char class;
+  unsigned long tag;
+  long ret;
+
+  if (der == NULL || der_len == 0)
+    return ASN1_VALUE_NOT_VALID;
+
+  if (ETYPE_OK(etype) == 0)
+    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;
+
+  p += tag_len;
+  der_len -= tag_len;
+  
+  ret = asn1_get_length_der (p, der_len, &len_len);
+  if (ret < 0) 
+    return ASN1_DER_ERROR;
+
+  p += len_len;
+  der_len -= len_len;
+  
+  *str_len = ret;
+  *str = p;
+
+  return ASN1_SUCCESS;
+}
diff --git a/lib/element.c b/lib/element.c
index f85fb2f..d5df2e5 100644
--- a/lib/element.c
+++ b/lib/element.c
@@ -408,7 +408,7 @@ asn1_write_value (asn1_node node_root, const char *name,
          (!negative && (value_temp[k] & 0x80)))
        k--;
 
-      _asn1_set_value_octet (node, value_temp + k, len - k);
+      _asn1_set_value_lv (node, value_temp + k, len - k);
 
       if (node->type & CONST_DEFAULT)
        {
@@ -544,17 +544,17 @@ asn1_write_value (asn1_node node_root, const char *name,
       break;
     case ASN1_ETYPE_OCTET_STRING:
     case ASN1_ETYPE_GENERALSTRING:
-    case ASN1_ETYPE_NUMERICSTRING:
-    case ASN1_ETYPE_IA5STRING:
-    case ASN1_ETYPE_TELETEXSTRING:
-    case ASN1_ETYPE_PRINTABLESTRING:
-    case ASN1_ETYPE_UNIVERSALSTRING:
-    case ASN1_ETYPE_BMPSTRING:
-    case ASN1_ETYPE_UTF8STRING:
-    case ASN1_ETYPE_VISIBLESTRING:
+    case ASN1_ETYPE_NUMERIC_STRING:
+    case ASN1_ETYPE_IA5_STRING:
+    case ASN1_ETYPE_TELETEX_STRING:
+    case ASN1_ETYPE_PRINTABLE_STRING:
+    case ASN1_ETYPE_UNIVERSAL_STRING:
+    case ASN1_ETYPE_BMP_STRING:
+    case ASN1_ETYPE_UTF8_STRING:
+    case ASN1_ETYPE_VISIBLE_STRING:
       if (len == 0)
        len = _asn1_strlen (value);
-      _asn1_set_value_octet (node, value, len);
+      _asn1_set_value_lv (node, value, len);
       break;
     case ASN1_ETYPE_BIT_STRING:
       if (len == 0)
@@ -593,7 +593,7 @@ asn1_write_value (asn1_node node_root, const char *name,
        return ASN1_ELEMENT_NOT_FOUND;
       break;
     case ASN1_ETYPE_ANY:
-      _asn1_set_value_octet (node, value, len);
+      _asn1_set_value_lv (node, value, len);
       break;
     case ASN1_ETYPE_SEQUENCE_OF:
     case ASN1_ETYPE_SET_OF:
@@ -823,14 +823,14 @@ asn1_read_value (asn1_node root, const char *name, void 
*ivalue, int *len)
       break;
     case ASN1_ETYPE_OCTET_STRING:
     case ASN1_ETYPE_GENERALSTRING:
-    case ASN1_ETYPE_NUMERICSTRING:
-    case ASN1_ETYPE_IA5STRING:
-    case ASN1_ETYPE_TELETEXSTRING:
-    case ASN1_ETYPE_PRINTABLESTRING:
-    case ASN1_ETYPE_UNIVERSALSTRING:
-    case ASN1_ETYPE_BMPSTRING:
-    case ASN1_ETYPE_UTF8STRING:
-    case ASN1_ETYPE_VISIBLESTRING:
+    case ASN1_ETYPE_NUMERIC_STRING:
+    case ASN1_ETYPE_IA5_STRING:
+    case ASN1_ETYPE_TELETEX_STRING:
+    case ASN1_ETYPE_PRINTABLE_STRING:
+    case ASN1_ETYPE_UNIVERSAL_STRING:
+    case ASN1_ETYPE_BMP_STRING:
+    case ASN1_ETYPE_UTF8_STRING:
+    case ASN1_ETYPE_VISIBLE_STRING:
       len2 = -1;
       if (asn1_get_octet_der
          (node->value, node->value_len, &len2, value, value_size,
diff --git a/lib/int.h b/lib/int.h
index 70fa896..9400cb8 100644
--- a/lib/int.h
+++ b/lib/int.h
@@ -73,20 +73,25 @@ typedef struct tag_and_class_st {
        case ASN1_ETYPE_OBJECT_ID: \
        case ASN1_ETYPE_OCTET_STRING: \
        case ASN1_ETYPE_GENERALSTRING: \
-        case ASN1_ETYPE_NUMERICSTRING: \
-        case ASN1_ETYPE_IA5STRING: \
-        case ASN1_ETYPE_TELETEXSTRING: \
-        case ASN1_ETYPE_PRINTABLESTRING: \
-        case ASN1_ETYPE_UNIVERSALSTRING: \
-        case ASN1_ETYPE_BMPSTRING: \
-        case ASN1_ETYPE_UTF8STRING: \
-        case ASN1_ETYPE_VISIBLESTRING: \
+        case ASN1_ETYPE_NUMERIC_STRING: \
+        case ASN1_ETYPE_IA5_STRING: \
+        case ASN1_ETYPE_TELETEX_STRING: \
+        case ASN1_ETYPE_PRINTABLE_STRING: \
+        case ASN1_ETYPE_UNIVERSAL_STRING: \
+        case ASN1_ETYPE_BMP_STRING: \
+        case ASN1_ETYPE_UTF8_STRING: \
+        case ASN1_ETYPE_VISIBLE_STRING: \
        case ASN1_ETYPE_BIT_STRING: \
        case ASN1_ETYPE_SEQUENCE: \
        case ASN1_ETYPE_SEQUENCE_OF: \
        case ASN1_ETYPE_SET: \
        case ASN1_ETYPE_SET_OF
 
+#define ETYPE_TAG(etype) (_asn1_tags[etype].tag)
+#define ETYPE_CLASS(etype) (_asn1_tags[etype].class)
+#define ETYPE_OK(etype) ((etype <= _asn1_tags_size)?1:0)
+
+extern unsigned int _asn1_tags_size;
 extern const tag_and_class_st _asn1_tags[];
 
 #define _asn1_strlen(s) strlen((const char *) s)
diff --git a/lib/libtasn1.h b/lib/libtasn1.h
index ad3b554..6a164b0 100644
--- a/lib/libtasn1.h
+++ b/lib/libtasn1.h
@@ -100,14 +100,14 @@ extern "C"
 #define ASN1_TAG_ENUMERATED            0x0A
 #define ASN1_TAG_NULL                  0x05
 #define ASN1_TAG_GENERALSTRING         0x1B
-#define ASN1_TAG_NUMERICSTRING         0x12
-#define ASN1_TAG_IA5STRING             0x16
-#define ASN1_TAG_TELETEXSTRING         0x14
-#define ASN1_TAG_PRINTABLESTRING       0x13
-#define ASN1_TAG_UNIVERSALSTRING       0x1C
-#define ASN1_TAG_BMPSTRING             0x1E
-#define ASN1_TAG_UTF8STRING            0x0C
-#define ASN1_TAG_VISIBLESTRING         0x1A
+#define ASN1_TAG_NUMERIC_STRING                0x12
+#define ASN1_TAG_IA5_STRING            0x16
+#define ASN1_TAG_TELETEX_STRING                0x14
+#define ASN1_TAG_PRINTABLE_STRING      0x13
+#define ASN1_TAG_UNIVERSAL_STRING      0x1C
+#define ASN1_TAG_BMP_STRING            0x1E
+#define ASN1_TAG_UTF8_STRING           0x0C
+#define ASN1_TAG_VISIBLE_STRING                0x1A
 
   /******************************************************/
   /* Structure definition used for the node of the tree */
@@ -157,14 +157,14 @@ extern "C"
 #define ASN1_ETYPE_NULL          20
 #define ASN1_ETYPE_ENUMERATED    21
 #define ASN1_ETYPE_GENERALSTRING 27
-#define ASN1_ETYPE_NUMERICSTRING 28
-#define ASN1_ETYPE_IA5STRING     29
-#define ASN1_ETYPE_TELETEXSTRING 30
-#define ASN1_ETYPE_PRINTABLESTRING 31
-#define ASN1_ETYPE_UNIVERSALSTRING 32
-#define ASN1_ETYPE_BMPSTRING     33
-#define ASN1_ETYPE_UTF8STRING    34
-#define ASN1_ETYPE_VISIBLESTRING 35
+#define ASN1_ETYPE_NUMERIC_STRING 28
+#define ASN1_ETYPE_IA5_STRING     29
+#define ASN1_ETYPE_TELETEX_STRING 30
+#define ASN1_ETYPE_PRINTABLE_STRING 31
+#define ASN1_ETYPE_UNIVERSAL_STRING 32
+#define ASN1_ETYPE_BMP_STRING     33
+#define ASN1_ETYPE_UTF8_STRING    34
+#define ASN1_ETYPE_VISIBLE_STRING 35
 
   struct asn1_data_node_st
   {
@@ -272,7 +272,36 @@ extern "C"
 
   extern ASN1_API void asn1_perror (int error);
 
-  /* DER utility functions. */
+#define ASN1_MAX_TAG_SIZE 4
+#define ASN1_MAX_LENGTH_SIZE 9
+#define ASN1_MAX_TL_SIZE (ASN1_MAX_TAG_SIZE+ASN1_MAX_LENGTH_SIZE)
+  extern ASN1_API long
+    asn1_get_length_der (const unsigned char *der, int der_len, int *len);
+
+  extern ASN1_API long
+    asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len);
+
+  extern ASN1_API void
+    asn1_length_der (unsigned long int len, unsigned char *ans, int *ans_len);
+
+  /* Other utility functions. */
+
+  extern ASN1_API 
+    int asn1_decode_simple_der (unsigned int etype, const unsigned char *der, 
unsigned int der_len,
+                        const unsigned char **str, unsigned int *str_len);
+
+  extern ASN1_API int
+    asn1_encode_simple_der (unsigned int etype, const unsigned char *str, 
unsigned int str_len,
+                        unsigned char *tl, unsigned int *tl_len);
+
+  extern ASN1_API asn1_node
+    asn1_find_node (asn1_node pointer, const char *name);
+
+  extern ASN1_API int
+    asn1_copy_node (asn1_node dst, const char *dst_name,
+                   asn1_node src, const char *src_name);
+
+  /* Internal and low-level DER utility functions. */
 
   extern ASN1_API int
     asn1_get_tag_der (const unsigned char *der, int der_len,
@@ -295,24 +324,6 @@ extern "C"
                      int *ret_len, unsigned char *str,
                      int str_size, int *bit_len);
 
-  extern ASN1_API long
-    asn1_get_length_der (const unsigned char *der, int der_len, int *len);
-
-  extern ASN1_API long
-    asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len);
-
-  extern ASN1_API void
-    asn1_length_der (unsigned long int len, unsigned char *ans, int *ans_len);
-
-  /* Other utility functions. */
-
-  extern ASN1_API asn1_node
-    asn1_find_node (asn1_node pointer, const char *name);
-
-  extern ASN1_API int
-    asn1_copy_node (asn1_node dst, const char *dst_name,
-                   asn1_node src, const char *src_name);
-
 /* Compatibility types */
 
 typedef int asn1_retCode;      /* type returned by libtasn1 functions */
diff --git a/lib/libtasn1.map b/lib/libtasn1.map
index 83235ed..a2b9416 100644
--- a/lib/libtasn1.map
+++ b/lib/libtasn1.map
@@ -50,6 +50,8 @@ LIBTASN1_0_3
     asn1_strerror;
     asn1_write_value;
     asn1_read_node_value;
+    asn1_encode_simple_der;
+    asn1_decode_simple_der;
 
     # Old symbols
     libtasn1_strerror;
diff --git a/lib/parser_aux.c b/lib/parser_aux.c
index cced582..7d16fa3 100644
--- a/lib/parser_aux.c
+++ b/lib/parser_aux.c
@@ -241,10 +241,10 @@ _asn1_set_value (asn1_node node, const void *value, 
unsigned int len)
 }
 
 /******************************************************************/
-/* Function : _asn1_set_value_octet                               */
+/* Function : _asn1_set_value_lv                                  */
 /* Description: sets the field VALUE in a NODE_ASN element. The   */
 /*              previous value (if exist) will be lost. The value */
-/*             given is stored as an octet string.               */
+/*             given is stored as an length-value format (LV     */
 /* Parameters:                                                    */
 /*   node: element pointer.                                       */
 /*   value: pointer to the value that you want to set.            */
@@ -252,7 +252,7 @@ _asn1_set_value (asn1_node node, const void *value, 
unsigned int len)
 /* Return: pointer to the NODE_ASN element.                       */
 /******************************************************************/
 asn1_node
-_asn1_set_value_octet (asn1_node node, const void *value, unsigned int len)
+_asn1_set_value_lv (asn1_node node, const void *value, unsigned int len)
 {
   int len2;
   void *temp;
diff --git a/lib/parser_aux.h b/lib/parser_aux.h
index df369c7..f270b73 100644
--- a/lib/parser_aux.h
+++ b/lib/parser_aux.h
@@ -35,7 +35,7 @@ _asn1_set_value (asn1_node node, const void *value, unsigned 
int len);
 asn1_node _asn1_set_value_m (asn1_node node, void *value, unsigned int len);
 
 asn1_node
-_asn1_set_value_octet (asn1_node node, const void *value, unsigned int len);
+_asn1_set_value_lv (asn1_node node, const void *value, unsigned int len);
 
 asn1_node
 _asn1_append_value (asn1_node node, const void *value, unsigned int len);
diff --git a/lib/structure.c b/lib/structure.c
index 9136799..a508030 100644
--- a/lib/structure.c
+++ b/lib/structure.c
@@ -855,14 +855,14 @@ asn1_print_structure (FILE * out, asn1_node structure, 
const char *name,
              break;
            case ASN1_ETYPE_OCTET_STRING:
            case ASN1_ETYPE_GENERALSTRING:
-           case ASN1_ETYPE_NUMERICSTRING:
-           case ASN1_ETYPE_IA5STRING:
-           case ASN1_ETYPE_TELETEXSTRING:
-           case ASN1_ETYPE_PRINTABLESTRING:
-           case ASN1_ETYPE_UNIVERSALSTRING:
-           case ASN1_ETYPE_BMPSTRING:
-           case ASN1_ETYPE_UTF8STRING:
-           case ASN1_ETYPE_VISIBLESTRING:
+           case ASN1_ETYPE_NUMERIC_STRING:
+           case ASN1_ETYPE_IA5_STRING:
+           case ASN1_ETYPE_TELETEX_STRING:
+           case ASN1_ETYPE_PRINTABLE_STRING:
+           case ASN1_ETYPE_UNIVERSAL_STRING:
+           case ASN1_ETYPE_BMP_STRING:
+           case ASN1_ETYPE_UTF8_STRING:
+           case ASN1_ETYPE_VISIBLE_STRING:
              if (p->value)
                {
                  len2 = -1;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index a7f8336..8f01d35 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -33,11 +33,12 @@ dist_check_SCRIPTS += threadsafety
 
 MOSTLYCLEANFILES = Test_parser_ERROR.asn
 
-check_PROGRAMS = Test_parser Test_tree Test_encoding Test_indefinite   \
-       Test_errors Test_simple Test_overflow
+check_PROGRAMS = Test_parser Test_tree Test_encoding Test_indefinite \
+       Test_errors Test_simple Test_overflow Test_strings
 
 TESTS = Test_parser Test_tree Test_encoding Test_indefinite    \
-       Test_errors Test_simple Test_overflow crlf threadsafety
+       Test_errors Test_simple Test_overflow crlf threadsafety \
+       Test_strings
 
 TESTS_ENVIRONMENT = \
        ASN1PARSER=$(srcdir)/Test_parser.asn \
diff --git a/tests/Test_strings.c b/tests/Test_strings.c
new file mode 100644
index 0000000..b43620f
--- /dev/null
+++ b/tests/Test_strings.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of LIBTASN1.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Written by Simon Josefsson
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "libtasn1.h"
+
+struct tv
+{
+  unsigned int etype;
+  unsigned int str_len;
+  const void *str;
+  unsigned int der_len;
+  const void *der;
+};
+
+static const struct tv tv[] = {
+  {ASN1_ETYPE_IA5_STRING, 20, 
"\x63\x73\x63\x61\x40\x70\x61\x73\x73\x70\x6f\x72\x74\x2e\x67\x6f\x76\x2e\x67\x72",
+                          22, 
"\x16\x14\x63\x73\x63\x61\x40\x70\x61\x73\x73\x70\x6f\x72\x74\x2e\x67\x6f\x76\x2e\x67\x72"},
+  {ASN1_ETYPE_PRINTABLE_STRING, 5, "\x4e\x69\x6b\x6f\x73", 
+                               7, "\x13\x05\x4e\x69\x6b\x6f\x73"},
+  {ASN1_ETYPE_UTF8_STRING, 12, "Αττική",
+                          14, 
"\x0c\x0c\xce\x91\xcf\x84\xcf\x84\xce\xb9\xce\xba\xce\xae"},
+  {ASN1_ETYPE_TELETEX_STRING, 15, 
"\x53\x69\x6d\x6f\x6e\x20\x4a\x6f\x73\x65\x66\x73\x73\x6f\x6e",
+                             17, 
"\x14\x0f\x53\x69\x6d\x6f\x6e\x20\x4a\x6f\x73\x65\x66\x73\x73\x6f\x6e"},
+  {ASN1_ETYPE_OCTET_STRING, 36, 
"\x30\x22\x80\x0F\x32\x30\x31\x31\x30\x38\x32\x31\x30\x38\x30\x30\x30\x36\x5A\x81\x0F\x32\x30\x31\x31\x30\x38\x32\x33\x32\x30\x35\x39\x35\x39\x5A",
+                           38, 
"\x04\x24\x30\x22\x80\x0F\x32\x30\x31\x31\x30\x38\x32\x31\x30\x38\x30\x30\x30\x36\x5A\x81\x0F\x32\x30\x31\x31\x30\x38\x32\x33\x32\x30\x35\x39\x35\x39\x5A"}
+};
+
+int
+main (int argc, char *argv[])
+{
+  int ret;
+  unsigned char tl[ASN1_MAX_TL_SIZE];
+  unsigned int tl_len, der_len, str_len;
+  const unsigned char* str;
+  unsigned int i;
+
+  /* Dummy test */
+
+  for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+    {
+      /* Encode */
+      tl_len = sizeof(tl);
+      ret = asn1_encode_simple_der(tv[i].etype, tv[i].str, tv[i].str_len,
+                                   tl, &tl_len);
+      if (ret != ASN1_SUCCESS)
+        {
+          fprintf(stderr, "Encoding error in %u: %s\n", i, asn1_strerror(ret));
+          return 1;
+        }
+      der_len = tl_len+tv[i].str_len;
+        
+      if (der_len != tv[i].der_len || memcmp(tl, tv[i].der, tl_len) != 0)
+        {
+          fprintf(stderr, "DER encoding differs in %u! (size: %u, expected: 
%u)\n", i, der_len, tv[i].der_len);
+          return 1;
+        }
+
+      /* decoding */
+      ret = asn1_decode_simple_der(tv[i].etype, tv[i].der, tv[i].der_len, 
&str, &str_len);
+      if (ret != ASN1_SUCCESS)
+        {
+          fprintf(stderr, "Decoding error in %u: %s\n", i, asn1_strerror(ret));
+          return 1;
+        }
+
+      if (str_len != tv[i].str_len || memcmp(str, tv[i].str, str_len) != 0)
+        {
+          fprintf(stderr, "DER decoded data differ in %u! (size: %u, expected: 
%u)\n", i, der_len, tv[i].str_len);
+          return 1;
+        }
+    }
+
+
+  return 0;
+}


hooks/post-receive
-- 
GNU libtasn1



reply via email to

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