Merge branch 'tmp-oid-fix' into 'master'

asn1_get_object_id_der: enhance the range of decoded OIDs

Closes #25

See merge request gnutls/libtasn1!55
diff --git a/.gitignore b/.gitignore
index fc0f113..28ab335 100644
--- a/.gitignore
+++ b/.gitignore
@@ -202,3 +202,4 @@
 tests/*.trs
 windows/libtasn1-*-win??.zip
 windows/tmp
+tests/object-id-encoding
diff --git a/NEWS b/NEWS
index 103efbc..737f2d0 100644
--- a/NEWS
+++ b/NEWS
@@ -1,9 +1,13 @@
 GNU Libtasn1 NEWS                                     -*- outline -*-
 
-* Noteworthy changes in release 4.15.1 (unreleased) [stable]
+* Noteworthy changes in release 4.16.0 (unreleased) [stable]
 - asn1_decode_simple_ber: added support for constructed definite
   octet strings. This allows this function decode the whole set of
   BER encodings for OCTET STRINGs.
+- asn1_get_object_id_der: enhance the range of decoded OIDs (#25).
+  This also makes OID encoding and decoding more strict on invalid
+  input.
+- asn1_object_id_der: introduced.
 
 
 * Noteworthy changes in release 4.15.0 (released 2019-11-21) [stable]
diff --git a/devel/libtasn1-latest-x86_64.abi b/devel/libtasn1-latest-x86_64.abi
index 63ad753..3b38339 100644
--- a/devel/libtasn1-latest-x86_64.abi
+++ b/devel/libtasn1-latest-x86_64.abi
@@ -32,6 +32,7 @@
     <elf-symbol name='asn1_get_tag_der' version='LIBTASN1_0_3' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
     <elf-symbol name='asn1_length_der' version='LIBTASN1_0_3' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
     <elf-symbol name='asn1_number_of_elements' version='LIBTASN1_0_3' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='asn1_object_id_der' version='LIBTASN1_4_16_0' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
     <elf-symbol name='asn1_octet_der' version='LIBTASN1_0_3' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
     <elf-symbol name='asn1_parser2array' version='LIBTASN1_0_3' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
     <elf-symbol name='asn1_parser2tree' version='LIBTASN1_0_3' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -44,8 +45,8 @@
     <elf-symbol name='asn1_strerror' version='LIBTASN1_0_3' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
     <elf-symbol name='asn1_write_value' version='LIBTASN1_0_3' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
   </elf-function-symbols>
-  <abi-instr version='1.0' address-size='64' path='ASN1.c' comp-dir-path='/usr/oms/src/libtasn1/lib' language='LANG_C99'>
-    <union-decl name='YYSTYPE' size-in-bits='576' visibility='default' id='type-id-1'>
+  <abi-instr version='1.0' address-size='64' path='ASN1.c' comp-dir-path='/home/nmavrogi/cvs/libtasn1/lib' language='LANG_C99'>
+    <union-decl name='_ASN1_YYSTYPE' size-in-bits='576' visibility='default' id='type-id-1'>
       <data-member access='private'>
         <var-decl name='constant' type-id='type-id-2' visibility='default'/>
       </data-member>
@@ -113,7 +114,7 @@
       <subrange length='16' type-id='type-id-6' id='type-id-15'/>
 
     </array-type-def>
-    <typedef-decl name='YYSTYPE' type-id='type-id-1' id='type-id-16'/>
+    <typedef-decl name='_ASN1_YYSTYPE' type-id='type-id-1' id='type-id-16'/>
     <var-decl name='_asn1_yylval' type-id='type-id-16' visibility='default'/>
     <qualified-type-def type-id='type-id-5' const='yes' id='type-id-17'/>
     <pointer-type-def type-id='type-id-17' size-in-bits='64' id='type-id-18'/>
@@ -132,9 +133,94 @@
       <parameter type-id='type-id-19' name='error_desc'/>
       <return type-id='type-id-10'/>
     </function-decl>
+    <type-decl name='void' id='type-id-21'/>
+    <function-decl name='malloc' mangled-name='malloc' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='__builtin_memcpy' mangled-name='memcpy' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='fopen' mangled-name='fopen' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='fclose' mangled-name='fclose' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_delete_list_and_nodes' mangled-name='_asn1_delete_list_and_nodes' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_set_default_tag' mangled-name='_asn1_set_default_tag' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_type_set_config' mangled-name='_asn1_type_set_config' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_check_identifier' mangled-name='_asn1_check_identifier' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='strchr' mangled-name='strchr' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='strlen' mangled-name='strlen' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='strdup' mangled-name='strdup' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_create_static_structure' mangled-name='_asn1_create_static_structure' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='free' mangled-name='free' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_change_integer_value' mangled-name='_asn1_change_integer_value' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_expand_object_id' mangled-name='_asn1_expand_object_id' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_delete_list' mangled-name='_asn1_delete_list' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='snprintf' mangled-name='snprintf' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='fprintf' mangled-name='fprintf' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='exit' mangled-name='exit' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='fgetc' mangled-name='fgetc' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='ungetc' mangled-name='ungetc' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='strcmp' mangled-name='strcmp' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_add_static_node' mangled-name='_asn1_add_static_node' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_set_name' mangled-name='_asn1_set_name' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_set_value' mangled-name='_asn1_set_value' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_get_last_right' mangled-name='_asn1_get_last_right' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_set_right' mangled-name='_asn1_set_right' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='stpcpy' mangled-name='stpcpy' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
   </abi-instr>
-  <abi-instr version='1.0' address-size='64' path='coding.c' comp-dir-path='/usr/oms/src/libtasn1/lib' language='LANG_C99'>
-    <class-decl name='tag_and_class_st' size-in-bits='128' is-struct='yes' visibility='default' id='type-id-21'>
+  <abi-instr version='1.0' address-size='64' path='coding.c' comp-dir-path='/home/nmavrogi/cvs/libtasn1/lib' language='LANG_C99'>
+    <class-decl name='tag_and_class_st' size-in-bits='128' is-struct='yes' visibility='default' id='type-id-22'>
       <data-member access='public' layout-offset-in-bits='0'>
         <var-decl name='tag' type-id='type-id-2' visibility='default'/>
       </data-member>
@@ -145,24 +231,23 @@
         <var-decl name='desc' type-id='type-id-18' visibility='default'/>
       </data-member>
     </class-decl>
-    <typedef-decl name='tag_and_class_st' type-id='type-id-21' id='type-id-22'/>
-    <qualified-type-def type-id='type-id-22' const='yes' id='type-id-23'/>
+    <typedef-decl name='tag_and_class_st' type-id='type-id-22' id='type-id-23'/>
+    <qualified-type-def type-id='type-id-23' const='yes' id='type-id-24'/>
 
-    <array-type-def dimensions='1' type-id='type-id-23' size-in-bits='infinite' id='type-id-24'>
-      <subrange length='infinite' id='type-id-25'/>
+    <array-type-def dimensions='1' type-id='type-id-24' size-in-bits='infinite' id='type-id-25'>
+      <subrange length='infinite' id='type-id-26'/>
 
     </array-type-def>
-    <qualified-type-def type-id='type-id-24' const='yes' id='type-id-26'/>
-    <var-decl name='_asn1_tags' type-id='type-id-26' visibility='default'/>
+    <qualified-type-def type-id='type-id-25' const='yes' id='type-id-27'/>
+    <var-decl name='_asn1_tags' type-id='type-id-27' visibility='default'/>
     <var-decl name='_asn1_tags_size' type-id='type-id-2' visibility='default'/>
-    <qualified-type-def type-id='type-id-13' const='yes' id='type-id-27'/>
-    <pointer-type-def type-id='type-id-27' size-in-bits='64' id='type-id-28'/>
-    <typedef-decl name='asn1_node_const' type-id='type-id-28' id='type-id-29'/>
-    <type-decl name='void' id='type-id-30'/>
-    <pointer-type-def type-id='type-id-30' size-in-bits='64' id='type-id-31'/>
+    <qualified-type-def type-id='type-id-13' const='yes' id='type-id-28'/>
+    <pointer-type-def type-id='type-id-28' size-in-bits='64' id='type-id-29'/>
+    <typedef-decl name='asn1_node_const' type-id='type-id-29' id='type-id-30'/>
+    <pointer-type-def type-id='type-id-21' size-in-bits='64' id='type-id-31'/>
     <pointer-type-def type-id='type-id-10' size-in-bits='64' id='type-id-32'/>
     <function-decl name='asn1_der_coding' mangled-name='asn1_der_coding' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_der_coding@@LIBTASN1_0_3'>
-      <parameter type-id='type-id-29' name='element'/>
+      <parameter type-id='type-id-30' name='element'/>
       <parameter type-id='type-id-18' name='name'/>
       <parameter type-id='type-id-31' name='ider'/>
       <parameter type-id='type-id-32' name='len'/>
@@ -176,7 +261,14 @@
       <parameter type-id='type-id-10' name='bit_len'/>
       <parameter type-id='type-id-9' name='der'/>
       <parameter type-id='type-id-32' name='der_len'/>
-      <return type-id='type-id-30'/>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='asn1_object_id_der' mangled-name='asn1_object_id_der' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_object_id_der@@LIBTASN1_4_16_0'>
+      <parameter type-id='type-id-18' name='str'/>
+      <parameter type-id='type-id-9' name='der'/>
+      <parameter type-id='type-id-32' name='der_len'/>
+      <parameter type-id='type-id-2' name='flags'/>
+      <return type-id='type-id-10'/>
     </function-decl>
     <pointer-type-def type-id='type-id-2' size-in-bits='64' id='type-id-35'/>
     <function-decl name='asn1_encode_simple_der' mangled-name='asn1_encode_simple_der' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_encode_simple_der@@LIBTASN1_0_3'>
@@ -192,16 +284,64 @@
       <parameter type-id='type-id-10' name='str_len'/>
       <parameter type-id='type-id-9' name='der'/>
       <parameter type-id='type-id-32' name='der_len'/>
-      <return type-id='type-id-30'/>
+      <return type-id='type-id-21'/>
     </function-decl>
     <function-decl name='asn1_length_der' mangled-name='asn1_length_der' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_length_der@@LIBTASN1_0_3'>
       <parameter type-id='type-id-6' name='len'/>
       <parameter type-id='type-id-9' name='der'/>
       <parameter type-id='type-id-32' name='der_len'/>
-      <return type-id='type-id-30'/>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_ltostr' mangled-name='_asn1_ltostr' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='strtoul' mangled-name='strtoul' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='strtol' mangled-name='strtol' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='memmove' mangled-name='memmove' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='realloc' mangled-name='realloc' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='asn1_get_tag_der' mangled-name='asn1_get_tag_der' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='asn1_get_length_der' mangled-name='asn1_get_length_der' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='qsort' mangled-name='qsort' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='asn1_find_node' mangled-name='asn1_find_node' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_copy_structure3' mangled-name='_asn1_copy_structure3' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='asn1_delete_structure' mangled-name='asn1_delete_structure' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_find_up' mangled-name='_asn1_find_up' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='memcmp' mangled-name='memcmp' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_str_cpy' mangled-name='_asn1_str_cpy' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_hierarchical_name' mangled-name='_asn1_hierarchical_name' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_str_cat' mangled-name='_asn1_str_cat' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
     </function-decl>
   </abi-instr>
-  <abi-instr version='1.0' address-size='64' path='decoding.c' comp-dir-path='/usr/oms/src/libtasn1/lib' language='LANG_C99'>
+  <abi-instr version='1.0' address-size='64' path='decoding.c' comp-dir-path='/home/nmavrogi/cvs/libtasn1/lib' language='LANG_C99'>
     <pointer-type-def type-id='type-id-9' size-in-bits='64' id='type-id-36'/>
     <function-decl name='asn1_decode_simple_ber' mangled-name='asn1_decode_simple_ber' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_decode_simple_ber@@LIBTASN1_0_3'>
       <parameter type-id='type-id-2' name='etype'/>
@@ -222,14 +362,14 @@
       <return type-id='type-id-10'/>
     </function-decl>
     <function-decl name='asn1_expand_octet_string' mangled-name='asn1_expand_octet_string' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_expand_octet_string@@LIBTASN1_0_3'>
-      <parameter type-id='type-id-29' name='definitions'/>
+      <parameter type-id='type-id-30' name='definitions'/>
       <parameter type-id='type-id-20' name='element'/>
       <parameter type-id='type-id-18' name='octetName'/>
       <parameter type-id='type-id-18' name='objectName'/>
       <return type-id='type-id-10'/>
     </function-decl>
     <function-decl name='asn1_expand_any_defined_by' mangled-name='asn1_expand_any_defined_by' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_expand_any_defined_by@@LIBTASN1_0_3'>
-      <parameter type-id='type-id-29' name='definitions'/>
+      <parameter type-id='type-id-30' name='definitions'/>
       <parameter type-id='type-id-20' name='element'/>
       <return type-id='type-id-10'/>
     </function-decl>
@@ -274,14 +414,6 @@
       <parameter type-id='type-id-32' name='bit_len'/>
       <return type-id='type-id-10'/>
     </function-decl>
-    <function-decl name='asn1_get_object_id_der' mangled-name='asn1_get_object_id_der' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_get_object_id_der@@LIBTASN1_0_3'>
-      <parameter type-id='type-id-34' name='der'/>
-      <parameter type-id='type-id-10' name='der_len'/>
-      <parameter type-id='type-id-32' name='ret_len'/>
-      <parameter type-id='type-id-19' name='str'/>
-      <parameter type-id='type-id-10' name='str_size'/>
-      <return type-id='type-id-10'/>
-    </function-decl>
     <function-decl name='asn1_get_octet_der' mangled-name='asn1_get_octet_der' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_get_octet_der@@LIBTASN1_0_3'>
       <parameter type-id='type-id-34' name='der'/>
       <parameter type-id='type-id-10' name='der_len'/>
@@ -298,6 +430,12 @@
       <parameter type-id='type-id-32' name='len'/>
       <return type-id='type-id-38'/>
     </function-decl>
+    <function-decl name='asn1_get_length_der' mangled-name='asn1_get_length_der' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_get_length_der@@LIBTASN1_0_3'>
+      <parameter type-id='type-id-34' name='der'/>
+      <parameter type-id='type-id-10' name='der_len'/>
+      <parameter type-id='type-id-32' name='len'/>
+      <return type-id='type-id-38'/>
+    </function-decl>
     <pointer-type-def type-id='type-id-6' size-in-bits='64' id='type-id-39'/>
     <function-decl name='asn1_get_tag_der' mangled-name='asn1_get_tag_der' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_get_tag_der@@LIBTASN1_0_3'>
       <parameter type-id='type-id-34' name='der'/>
@@ -307,14 +445,37 @@
       <parameter type-id='type-id-39' name='tag'/>
       <return type-id='type-id-10'/>
     </function-decl>
-    <function-decl name='asn1_get_length_der' mangled-name='asn1_get_length_der' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_get_length_der@@LIBTASN1_0_3'>
+    <function-decl name='asn1_get_object_id_der' mangled-name='asn1_get_object_id_der' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_get_object_id_der@@LIBTASN1_0_3'>
       <parameter type-id='type-id-34' name='der'/>
       <parameter type-id='type-id-10' name='der_len'/>
-      <parameter type-id='type-id-32' name='len'/>
-      <return type-id='type-id-38'/>
+      <parameter type-id='type-id-32' name='ret_len'/>
+      <parameter type-id='type-id-19' name='str'/>
+      <parameter type-id='type-id-10' name='str_size'/>
+      <return type-id='type-id-10'/>
+    </function-decl>
+    <function-decl name='__builtin_strcpy' mangled-name='strcpy' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='asn1_read_value' mangled-name='asn1_read_value' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='asn1_create_element' mangled-name='asn1_create_element' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_cpy_name' mangled-name='_asn1_cpy_name' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_set_value_lv' mangled-name='_asn1_set_value_lv' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_find_left' mangled-name='_asn1_find_left' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_append_sequence_set' mangled-name='_asn1_append_sequence_set' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
     </function-decl>
   </abi-instr>
-  <abi-instr version='1.0' address-size='64' path='element.c' comp-dir-path='/usr/oms/src/libtasn1/lib' language='LANG_C99'>
+  <abi-instr version='1.0' address-size='64' path='element.c' comp-dir-path='/home/nmavrogi/cvs/libtasn1/lib' language='LANG_C99'>
     <class-decl name='asn1_data_node_st' size-in-bits='192' is-struct='yes' visibility='default' id='type-id-40'>
       <data-member access='public' layout-offset-in-bits='0'>
         <var-decl name='name' type-id='type-id-18' visibility='default'/>
@@ -332,19 +493,19 @@
     <typedef-decl name='asn1_data_node_st' type-id='type-id-40' id='type-id-41'/>
     <pointer-type-def type-id='type-id-41' size-in-bits='64' id='type-id-42'/>
     <function-decl name='asn1_read_node_value' mangled-name='asn1_read_node_value' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_read_node_value@@LIBTASN1_0_3'>
-      <parameter type-id='type-id-29' name='node'/>
+      <parameter type-id='type-id-30' name='node'/>
       <parameter type-id='type-id-42' name='data'/>
       <return type-id='type-id-10'/>
     </function-decl>
     <function-decl name='asn1_read_tag' mangled-name='asn1_read_tag' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_read_tag@@LIBTASN1_0_3'>
-      <parameter type-id='type-id-29' name='root'/>
+      <parameter type-id='type-id-30' name='root'/>
       <parameter type-id='type-id-18' name='name'/>
       <parameter type-id='type-id-32' name='tagValue'/>
       <parameter type-id='type-id-32' name='classValue'/>
       <return type-id='type-id-10'/>
     </function-decl>
     <function-decl name='asn1_read_value_type' mangled-name='asn1_read_value_type' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_read_value_type@@LIBTASN1_0_3'>
-      <parameter type-id='type-id-29' name='root'/>
+      <parameter type-id='type-id-30' name='root'/>
       <parameter type-id='type-id-18' name='name'/>
       <parameter type-id='type-id-31' name='ivalue'/>
       <parameter type-id='type-id-32' name='len'/>
@@ -352,7 +513,7 @@
       <return type-id='type-id-10'/>
     </function-decl>
     <function-decl name='asn1_read_value' mangled-name='asn1_read_value' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_read_value@@LIBTASN1_0_3'>
-      <parameter type-id='type-id-29' name='root'/>
+      <parameter type-id='type-id-30' name='root'/>
       <parameter type-id='type-id-18' name='name'/>
       <parameter type-id='type-id-31' name='ivalue'/>
       <parameter type-id='type-id-32' name='len'/>
@@ -365,44 +526,85 @@
       <parameter type-id='type-id-10' name='len'/>
       <return type-id='type-id-10'/>
     </function-decl>
+    <function-decl name='asn1_get_octet_der' mangled-name='asn1_get_octet_der' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='strcat' mangled-name='strcat' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='asn1_get_bit_der' mangled-name='asn1_get_bit_der' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='asn1_length_der' mangled-name='asn1_length_der' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='asn1_bit_der' mangled-name='asn1_bit_der' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_set_value_m' mangled-name='_asn1_set_value_m' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
   </abi-instr>
-  <abi-instr version='1.0' address-size='64' path='errors.c' comp-dir-path='/usr/oms/src/libtasn1/lib' language='LANG_C99'>
+  <abi-instr version='1.0' address-size='64' path='errors.c' comp-dir-path='/home/nmavrogi/cvs/libtasn1/lib' language='LANG_C99'>
     <function-decl name='asn1_strerror' mangled-name='asn1_strerror' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_strerror@@LIBTASN1_0_3'>
       <parameter type-id='type-id-10' name='error'/>
       <return type-id='type-id-18'/>
     </function-decl>
     <function-decl name='asn1_perror' mangled-name='asn1_perror' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_perror@@LIBTASN1_0_3'>
       <parameter type-id='type-id-10' name='error'/>
-      <return type-id='type-id-30'/>
+      <return type-id='type-id-21'/>
     </function-decl>
   </abi-instr>
-  <abi-instr version='1.0' address-size='64' path='parser_aux.c' comp-dir-path='/usr/oms/src/libtasn1/lib' language='LANG_C99'>
+  <abi-instr version='1.0' address-size='64' path='gstr.c' comp-dir-path='/home/nmavrogi/cvs/libtasn1/lib' language='LANG_C99'>
+    <function-decl name='strncat' mangled-name='strncat' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+  </abi-instr>
+  <abi-instr version='1.0' address-size='64' path='parser_aux.c' comp-dir-path='/home/nmavrogi/cvs/libtasn1/lib' language='LANG_C99'>
     <function-decl name='asn1_find_node' mangled-name='asn1_find_node' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_find_node@@LIBTASN1_0_3'>
-      <parameter type-id='type-id-29' name='pointer'/>
+      <parameter type-id='type-id-30' name='pointer'/>
       <parameter type-id='type-id-18' name='name'/>
       <return type-id='type-id-4'/>
     </function-decl>
+    <function-decl name='_asn1_delete_structure' mangled-name='_asn1_delete_structure' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_add_single_node' mangled-name='_asn1_add_single_node' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_convert_integer' mangled-name='_asn1_convert_integer' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='asn1_octet_der' mangled-name='asn1_octet_der' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='__builtin_memset' mangled-name='memset' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='calloc' mangled-name='calloc' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
   </abi-instr>
-  <abi-instr version='1.0' address-size='64' path='structure.c' comp-dir-path='/usr/oms/src/libtasn1/lib' language='LANG_C99'>
+  <abi-instr version='1.0' address-size='64' path='structure.c' comp-dir-path='/home/nmavrogi/cvs/libtasn1/lib' language='LANG_C99'>
     <function-decl name='asn1_dup_node' mangled-name='asn1_dup_node' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_dup_node@@LIBTASN1_0_3'>
-      <parameter type-id='type-id-29' name='src'/>
+      <parameter type-id='type-id-30' name='src'/>
       <parameter type-id='type-id-18' name='src_name'/>
       <return type-id='type-id-4'/>
     </function-decl>
     <function-decl name='asn1_copy_node' mangled-name='asn1_copy_node' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_copy_node@@LIBTASN1_0_3'>
       <parameter type-id='type-id-4' name='dst'/>
       <parameter type-id='type-id-18' name='dst_name'/>
-      <parameter type-id='type-id-29' name='src'/>
+      <parameter type-id='type-id-30' name='src'/>
       <parameter type-id='type-id-18' name='src_name'/>
       <return type-id='type-id-10'/>
     </function-decl>
     <function-decl name='asn1_find_structure_from_oid' mangled-name='asn1_find_structure_from_oid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_find_structure_from_oid@@LIBTASN1_0_3'>
-      <parameter type-id='type-id-29' name='definitions'/>
+      <parameter type-id='type-id-30' name='definitions'/>
       <parameter type-id='type-id-18' name='oidValue'/>
       <return type-id='type-id-18'/>
     </function-decl>
     <function-decl name='asn1_number_of_elements' mangled-name='asn1_number_of_elements' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_number_of_elements@@LIBTASN1_0_3'>
-      <parameter type-id='type-id-29' name='element'/>
+      <parameter type-id='type-id-30' name='element'/>
       <parameter type-id='type-id-18' name='name'/>
       <parameter type-id='type-id-32' name='num'/>
       <return type-id='type-id-10'/>
@@ -507,7 +709,7 @@
       <subrange length='1' type-id='type-id-6' id='type-id-57'/>
 
     </array-type-def>
-    <typedef-decl name='_IO_lock_t' type-id='type-id-30' id='type-id-58'/>
+    <typedef-decl name='_IO_lock_t' type-id='type-id-21' id='type-id-58'/>
     <pointer-type-def type-id='type-id-58' size-in-bits='64' id='type-id-50'/>
     <typedef-decl name='__off64_t' type-id='type-id-38' id='type-id-51'/>
     <class-decl name='_IO_codecvt' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-59'/>
@@ -524,13 +726,13 @@
     <pointer-type-def type-id='type-id-62' size-in-bits='64' id='type-id-63'/>
     <function-decl name='asn1_print_structure' mangled-name='asn1_print_structure' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_print_structure@@LIBTASN1_0_3'>
       <parameter type-id='type-id-63' name='out'/>
-      <parameter type-id='type-id-29' name='structure'/>
+      <parameter type-id='type-id-30' name='structure'/>
       <parameter type-id='type-id-18' name='name'/>
       <parameter type-id='type-id-10' name='mode'/>
-      <return type-id='type-id-30'/>
+      <return type-id='type-id-21'/>
     </function-decl>
     <function-decl name='asn1_create_element' mangled-name='asn1_create_element' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_create_element@@LIBTASN1_0_3'>
-      <parameter type-id='type-id-29' name='definitions'/>
+      <parameter type-id='type-id-30' name='definitions'/>
       <parameter type-id='type-id-18' name='source_name'/>
       <parameter type-id='type-id-20' name='element'/>
       <return type-id='type-id-10'/>
@@ -569,11 +771,35 @@
       <parameter type-id='type-id-19' name='errorDescription'/>
       <return type-id='type-id-10'/>
     </function-decl>
+    <function-decl name='asn1_der_coding' mangled-name='asn1_der_coding' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='asn1_der_decoding' mangled-name='asn1_der_decoding' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='__builtin_fputs' mangled-name='fputs' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='__builtin_fwrite' mangled-name='fwrite' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='__builtin_fputc' mangled-name='fputc' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_remove_node' mangled-name='_asn1_remove_node' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
+    <function-decl name='_asn1_delete_node_from_list' mangled-name='_asn1_delete_node_from_list' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
   </abi-instr>
-  <abi-instr version='1.0' address-size='64' path='version.c' comp-dir-path='/usr/oms/src/libtasn1/lib' language='LANG_C99'>
+  <abi-instr version='1.0' address-size='64' path='version.c' comp-dir-path='/home/nmavrogi/cvs/libtasn1/lib' language='LANG_C99'>
     <function-decl name='asn1_check_version' mangled-name='asn1_check_version' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='asn1_check_version@@LIBTASN1_0_3'>
       <parameter type-id='type-id-18' name='req_version'/>
       <return type-id='type-id-18'/>
     </function-decl>
+    <function-decl name='strverscmp' mangled-name='strverscmp' visibility='default' binding='global' size-in-bits='64'>
+      <return type-id='type-id-21'/>
+    </function-decl>
   </abi-instr>
 </abi-corpus>
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 6fe5ab1..787c304 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -71,6 +71,7 @@
 gdoc_MANS += man/asn1_length_der.3
 gdoc_MANS += man/asn1_octet_der.3
 gdoc_MANS += man/asn1_encode_simple_der.3
+gdoc_MANS += man/asn1_object_id_der.3
 gdoc_MANS += man/asn1_bit_der.3
 gdoc_MANS += man/asn1_der_coding.3
 gdoc_MANS += man/asn1_write_value.3
@@ -121,6 +122,7 @@
 gdoc_TEXINFOS += texi/asn1_length_der.texi
 gdoc_TEXINFOS += texi/asn1_octet_der.texi
 gdoc_TEXINFOS += texi/asn1_encode_simple_der.texi
+gdoc_TEXINFOS += texi/asn1_object_id_der.texi
 gdoc_TEXINFOS += texi/asn1_bit_der.texi
 gdoc_TEXINFOS += texi/asn1_der_coding.texi
 gdoc_TEXINFOS += texi/asn1_write_value.texi
diff --git a/lib/coding.c b/lib/coding.c
index 90d6203..f7e15bb 100644
--- a/lib/coding.c
+++ b/lib/coding.c
@@ -121,7 +121,7 @@
 /******************************************************/
 static void
 _asn1_tag_der (unsigned char class, unsigned int tag_value,
-	       unsigned char *ans, int *ans_len)
+	       unsigned char ans[ASN1_MAX_TAG_SIZE], int *ans_len)
 {
   int k;
   unsigned char temp[ASN1_MAX_TAG_SIZE];
@@ -320,8 +320,30 @@
 }
 */
 
+static
+void encode_val(uint64_t val, unsigned char *der, int max_len, int *der_len)
+{
+  int first, k;
+  unsigned char bit7;
+
+  first = 0;
+  for (k = sizeof(val); k >= 0; k--)
+    {
+      bit7 = (val >> (k * 7)) & 0x7F;
+      if (bit7 || first || !k)
+	{
+	  if (k)
+	    bit7 |= 0x80;
+	  if (max_len > (*der_len))
+	    der[*der_len] = bit7;
+	  (*der_len)++;
+	  first = 1;
+	}
+    }
+}
+
 /******************************************************/
-/* Function : _asn1_objectid_der                      */
+/* Function : _asn1_object_id_der                     */
 /* Description: creates the DER coding for an         */
 /* OBJECT IDENTIFIER  type (length included).         */
 /* Parameters:                                        */
@@ -336,15 +358,15 @@
 /*   or an error value.                               */
 /******************************************************/
 static int
-_asn1_objectid_der (unsigned char *str, unsigned char *der, int *der_len)
+_asn1_object_id_der (const char *str, unsigned char *der, int *der_len)
 {
-  int len_len, counter, k, first, max_len;
+  int len_len, counter, max_len;
   char *temp, *n_end, *n_start;
-  unsigned char bit7;
   uint64_t val, val1 = 0;
   int str_len = _asn1_strlen (str);
 
   max_len = *der_len;
+  *der_len = 0;
 
   if (der == NULL && max_len > 0)
     return ASN1_VALUE_NOT_VALID;
@@ -366,30 +388,30 @@
       counter++;
 
       if (counter == 1)
-	val1 = val;
+        {
+	  val1 = val;
+	}
       else if (counter == 2)
 	{
-	  if (max_len > 0)
-	    der[0] = 40 * val1 + val;
-	  *der_len = 1;
+	  uint64_t val0;
+
+          if (val1 > 2)
+            {
+              free(temp);
+              return ASN1_VALUE_NOT_VALID;
+            }
+          else if ((val1 == 0 || val1 == 1) && val > 39)
+            {
+              free(temp);
+              return ASN1_VALUE_NOT_VALID;
+            }
+
+	  val0 = 40 * val1 + val;
+	  encode_val(val0, der, max_len, der_len);
 	}
       else
 	{
-	  first = 0;
-	  for (k = sizeof(val); k >= 0; k--)
-	    {
-	      bit7 = (val >> (k * 7)) & 0x7F;
-	      if (bit7 || first || !k)
-		{
-		  if (k)
-		    bit7 |= 0x80;
-		  if (max_len > (*der_len))
-		    der[*der_len] = bit7;
-		  (*der_len)++;
-		  first = 1;
-		}
-	    }
-
+	  encode_val(val, der, max_len, der_len);
 	}
       n_start = n_end + 1;
     }
@@ -410,6 +432,47 @@
   return ASN1_SUCCESS;
 }
 
+/**
+ * asn1_object_id_der:
+ * @str: An object identifier in numeric, dot format.
+ * @der: buffer to hold the returned encoding (may be %NULL).
+ * @der_len: initially the size of @der; will hold the final size.
+ * @flags: must be zero
+ *
+ * Creates the DER encoding of the provided object identifier.
+ *
+ * Returns: %ASN1_SUCCESS if DER encoding was OK, %ASN1_VALUE_NOT_VALID
+ *   if @str is not a valid OID, %ASN1_MEM_ERROR if the @der
+ *   vector isn't big enough and in this case @der_len will contain the
+ *   length needed.
+ **/
+int
+asn1_object_id_der (const char *str, unsigned char *der, int *der_len, unsigned flags)
+{
+  unsigned char tag_der[MAX_TAG_LEN];
+  int tag_len = 0, r;
+  int max_len = *der_len;
+
+  *der_len = 0;
+
+  _asn1_tag_der (ETYPE_CLASS (ASN1_ETYPE_OBJECT_ID), ETYPE_TAG (ASN1_ETYPE_OBJECT_ID),
+                 tag_der, &tag_len);
+
+  if (max_len > tag_len)
+    {
+      memcpy(der, tag_der, tag_len);
+    }
+  max_len -= tag_len;
+  der += tag_len;
+
+  r = _asn1_object_id_der (str, der, &max_len);
+  if (r == ASN1_MEM_ERROR || r == ASN1_SUCCESS)
+    {
+      *der_len = max_len + tag_len;
+    }
+
+  return r;
+}
 
 static const unsigned char bit_mask[] =
   { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };
@@ -1142,7 +1205,7 @@
 		  goto error;
 		}
 	      len2 = max_len;
-	      err = _asn1_objectid_der (p->value, der + counter, &len2);
+	      err = _asn1_object_id_der ((char*)p->value, der + counter, &len2);
 	      if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
 		goto error;
 
diff --git a/lib/decoding.c b/lib/decoding.c
index 5e809ff..ff04eb7 100644
--- a/lib/decoding.c
+++ b/lib/decoding.c
@@ -410,9 +410,9 @@
 			char *str, int str_size)
 {
   int len_len, len, k;
-  int leading;
+  int leading, parsed;
   char temp[LTOSTR_MAX_SIZE];
-  uint64_t val, val1;
+  uint64_t val, val1, val0;
 
   *ret_len = 0;
   if (str && str_size > 0)
@@ -426,16 +426,48 @@
   if (len <= 0 || len + len_len > der_len)
     return ASN1_DER_ERROR;
 
-  val1 = der[len_len] / 40;
-  val = der[len_len] - val1 * 40;
+  /* leading octet can never be 0x80 */
+  if (der[len_len] == 0x80)
+    return ASN1_DER_ERROR;
 
-  _asn1_str_cpy (str, str_size, _asn1_ltostr (val1, temp));
+  val0 = 0;
+
+  for (k = 0; k < len; k++)
+    {
+      if (INT_LEFT_SHIFT_OVERFLOW (val0, 7))
+	return ASN1_DER_ERROR;
+
+      val0 <<= 7;
+      val0 |= der[len_len + k] & 0x7F;
+      if (!(der[len_len + k] & 0x80))
+	break;
+    }
+  parsed = ++k;
+
+  /* val0 = (X*40) + Y, X={0,1,2}, Y<=39 when X={0,1} */
+  /* X = val, Y = val1 */
+
+  /* check if X == 0  */
+  val = 0;
+  val1 = val0;
+  if (val1 > 39)
+    {
+      val = 1;
+      val1 = val0 - 40;
+      if (val1  > 39)
+        {
+          val = 2;
+          val1 = val0 - 80;
+        }
+    }
+
+  _asn1_str_cpy (str, str_size, _asn1_ltostr (val, temp));
   _asn1_str_cat (str, str_size, ".");
-  _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
+  _asn1_str_cat (str, str_size, _asn1_ltostr (val1, temp));
 
   val = 0;
   leading = 1;
-  for (k = 1; k < len; k++)
+  for (k = parsed; k < len; k++)
     {
       /* X.690 mandates that the leading byte must never be 0x80
        */
diff --git a/lib/includes/libtasn1.h.in b/lib/includes/libtasn1.h.in
index 7e4baaf..8664fee 100644
--- a/lib/includes/libtasn1.h.in
+++ b/lib/includes/libtasn1.h.in
@@ -485,6 +485,10 @@
                           int der_len, int *ret_len,
                           char *str, int str_size);
 
+extern ASN1_API int
+  asn1_object_id_der (const char *str, unsigned char *der, int *der_len,
+                      unsigned flags);
+
 /* Compatibility types */
 
 /**
diff --git a/lib/libtasn1.map b/lib/libtasn1.map
index 007925c..1f76486 100644
--- a/lib/libtasn1.map
+++ b/lib/libtasn1.map
@@ -61,3 +61,8 @@
   local:
     *;
 };
+
+LIBTASN1_4_16_0 {
+  global:
+    asn1_object_id_der;
+} LIBTASN1_0_3;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index c73a442..f850df7 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -61,7 +61,7 @@
 	Test_errors Test_simple Test_overflow Test_strings Test_choice \
 	Test_encdec copynode coding-decoding2 strict-der Test_choice_ocsp \
 	ocsp-basic-response octet-string coding-long-oid object-id-decoding \
-	spc_pe_image_data setof CVE-2018-1000654 reproducers
+	spc_pe_image_data setof CVE-2018-1000654 reproducers object-id-encoding
 
 TESTS = Test_parser Test_tree Test_encoding Test_indefinite	\
 	Test_errors Test_simple Test_overflow crlf threadsafety \
@@ -69,7 +69,7 @@
 	strict-der Test_choice_ocsp decoding decoding-invalid-x509 \
 	ocsp-basic-response octet-string coding-long-oid object-id-decoding \
 	spc_pe_image_data decoding-invalid-pkcs7 coding setof \
-	CVE-2018-1000654 parser.sh reproducers
+	CVE-2018-1000654 parser.sh reproducers object-id-encoding
 
 CVE-2018-1000654-1_asn1_tab.h: $(srcdir)/CVE-2018-1000654-1.asn
 	$(top_builddir)/src/asn1Parser$(EXEEXT) $^ -o $@
diff --git a/tests/object-id-decoding.c b/tests/object-id-decoding.c
index e3e9669..7052b4f 100644
--- a/tests/object-id-decoding.c
+++ b/tests/object-id-decoding.c
@@ -27,18 +27,44 @@
 struct tv
 {
   int der_len;
-  const unsigned char *der_str;
+  const unsigned char *der;
   const char *oid;
   int expected_error;
 };
 
 static const struct tv tv[] = {
+  {.der_len = 5,
+   .der = (void *) "\x06\x03\x80\x37\x03",
+   .oid = "2.999.3",
+   .expected_error = ASN1_DER_ERROR /* leading 0x80 */
+  },
   {.der_len = 12,
-   .der_str = (void *) "\x06\x0a\x2b\x06\x01\x04\x01\x92\x08\x09\x05\x01",
+   .der = (void *) "\x06\x0a\x2b\x06\x01\x80\x01\x92\x08\x09\x05\x01",
+   .oid = "1.3.6.1.4.1.2312.9.5.1",
+   .expected_error = ASN1_DER_ERROR /* leading 0x80 */
+  },
+  {.der_len = 6,
+   .der = (void *) "\x06\x04\x01\x02\x03\x04",
+   .oid = "0.1.2.3.4",
+   .expected_error = ASN1_SUCCESS},
+  {.der_len = 5,
+   .der = (void *) "\x06\x03\x51\x02\x03",
+   .oid = "2.1.2.3",
+   .expected_error = ASN1_SUCCESS},
+  {.der_len = 5,
+   .der = (void *) "\x06\x03\x88\x37\x03",
+   .oid = "2.999.3",
+   .expected_error = ASN1_SUCCESS},
+  {.der_len = 12,
+   .der = (void *) "\x06\x0a\x2b\x06\x01\x04\x01\x92\x08\x09\x05\x01",
    .oid = "1.3.6.1.4.1.2312.9.5.1",
    .expected_error = ASN1_SUCCESS},
   {.der_len = 19,
-   .der_str =
+   .der = (void *) "\x06\x11\xfa\x80\x00\x00\x00\x0e\x01\x0e\xfa\x80\x00\x00\x00\x0e\x63\x6f\x6d",
+   .oid = "2.1998768.0.0.14.1.14.1998848.0.0.14.99.111.109",
+   .expected_error = ASN1_SUCCESS},
+  {.der_len = 19,
+   .der =
    (void *)
    "\x06\x11\x2b\x06\x01\x04\x01\x92\x08\x09\x02\xaa\xda\xbe\xbe\xfa\x72\x01\x07",
    .oid = "1.3.6.1.4.1.2312.9.2.1467399257458.1.7",
@@ -56,17 +82,20 @@
     {
       /* decode */
       ret =
-	asn1_get_object_id_der (tv[i].der_str+1,
+	asn1_get_object_id_der (tv[i].der+1,
 				tv[i].der_len-1, &ret_len, str,
 				sizeof (str));
       if (ret != tv[i].expected_error)
 	{
 	  fprintf (stderr,
-		   "%d: asn1_get_object_id_der iter %lu: got %d expected %d\n",
-		   __LINE__, (unsigned long) i, ret, tv[i].expected_error);
+		   "%d: asn1_get_object_id_der iter %lu: got '%s' expected %d\n",
+		   __LINE__, (unsigned long) i, asn1_strerror(ret), tv[i].expected_error);
 	  return 1;
 	}
 
+      if (tv[i].expected_error != ASN1_SUCCESS)
+        continue;
+
       if (ret_len != tv[i].der_len-1)
 	{
 	  fprintf (stderr,
diff --git a/tests/object-id-encoding.c b/tests/object-id-encoding.c
new file mode 100644
index 0000000..8736abd
--- /dev/null
+++ b/tests/object-id-encoding.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2019 Nikos Mavrogiannopoulos
+ *
+ * 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/>.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "libtasn1.h"
+
+struct tv
+{
+  int der_len;
+  const unsigned char *der;
+  const char *oid;
+  int expected_error;
+};
+
+static const struct tv tv[] = {
+  {.der_len = 0,
+   .der = (void *) "",
+   .oid = "5.999.3",
+   .expected_error = ASN1_VALUE_NOT_VALID /* cannot start with 5 */
+  },
+  {.der_len = 0,
+   .der = (void *) "",
+   .oid = "0.48.9",
+   .expected_error = ASN1_VALUE_NOT_VALID /* second field cannot be 48 */
+  },
+  {.der_len = 0,
+   .der = (void *) "",
+   .oid = "1.40.9",
+   .expected_error = ASN1_VALUE_NOT_VALID /* second field cannot be 40 */
+  },
+  {.der_len = 4,
+   .der = (void *) "\x06\x02\x4f\x63",
+   .oid = "1.39.99",
+   .expected_error = ASN1_SUCCESS,
+  },
+  {.der_len = 6,
+   .der = (void *) "\x06\x04\x01\x02\x03\x04",
+   .oid = "0.1.2.3.4",
+   .expected_error = ASN1_SUCCESS},
+  {.der_len = 5,
+   .der = (void *) "\x06\x03\x51\x02\x03",
+   .oid = "2.1.2.3",
+   .expected_error = ASN1_SUCCESS},
+  {.der_len = 5,
+   .der = (void *) "\x06\x03\x88\x37\x03",
+   .oid = "2.999.3",
+   .expected_error = ASN1_SUCCESS},
+  {.der_len = 12,
+   .der = (void *) "\x06\x0a\x2b\x06\x01\x04\x01\x92\x08\x09\x05\x01",
+   .oid = "1.3.6.1.4.1.2312.9.5.1",
+   .expected_error = ASN1_SUCCESS},
+  {.der_len = 19,
+   .der = (void *) "\x06\x11\xfa\x80\x00\x00\x00\x0e\x01\x0e\xfa\x80\x00\x00\x00\x0e\x63\x6f\x6d",
+   .oid = "2.1998768.0.0.14.1.14.1998848.0.0.14.99.111.109",
+   .expected_error = ASN1_SUCCESS},
+  {.der_len = 19,
+   .der =
+   (void *)
+   "\x06\x11\x2b\x06\x01\x04\x01\x92\x08\x09\x02\xaa\xda\xbe\xbe\xfa\x72\x01\x07",
+   .oid = "1.3.6.1.4.1.2312.9.2.1467399257458.1.7",
+   .expected_error = ASN1_SUCCESS},
+};
+
+int
+main (int argc, char *argv[])
+{
+  unsigned char der[128];
+  int ret, der_len, i, j;
+
+  for (i = 0; i < (int)(sizeof (tv) / sizeof (tv[0])); i++)
+    {
+      der_len = sizeof(der);
+      ret = asn1_object_id_der(tv[i].oid, der, &der_len, 0);
+      if (ret != ASN1_SUCCESS)
+	{
+	  if (ret == tv[i].expected_error)
+	    continue;
+	  fprintf (stderr,
+		   "%d: iter %lu, encoding of OID failed: %s\n",
+		   __LINE__, (unsigned long) i, asn1_strerror(ret));
+	  return 1;
+	}
+      else if (ret != tv[i].expected_error)
+        {
+	  fprintf (stderr,
+		   "%d: iter %lu, encoding of OID %s succeeded when expecting failure\n",
+		   __LINE__, (unsigned long) i, tv[i].oid);
+          return 1;
+        }
+
+      if (der_len != tv[i].der_len || memcmp(der, tv[i].der, der_len) != 0)
+	{
+	  fprintf (stderr,
+		   "%d: iter %lu, re-encoding of OID %s resulted to different string (%d vs %d bytes)\n",
+		   __LINE__, (unsigned long) i, tv[i].oid, der_len, tv[i].der_len);
+          fprintf(stderr, "\nGot:\t\t");
+          for (j=0;j<der_len;j++)
+            fprintf(stderr, "%.2x", der[j]);
+
+          fprintf(stderr, "\nExpected:\t");
+          for (j=0;j<tv[i].der_len;j++)
+            fprintf(stderr, "%.2x", tv[i].der[j]);
+          fprintf(stderr, "\n");
+
+	  return 1;
+	}
+    }
+
+  return 0;
+}