poke-devel
[Top][All Lists]
Advanced

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

[PATCH] pickles: asn1-ber: fix issues in long-form length/tag handling


From: Daiki Ueno
Subject: [PATCH] pickles: asn1-ber: fix issues in long-form length/tag handling
Date: Mon, 7 Mar 2022 17:29:33 +0100

This commit fixes long-form definite length decoding in BER_Length and
BER_Data_Value, so that the octet components are ordered in big-endian
as mentioned in [1], each length octet is not necessarily < 0x80, and
the use of such lengths is not restricted to primitive types:
constructed types such as SEQUENCE can also have definite length.

Besides those this also fixes long-form tag number handling in
BER_Identifier, where it is indicated with 0b11111 not 0b01111.

To reproduce those issues:

  $ wget 
https://gitlab.com/gnutls/gnutls/-/raw/master/doc/credentials/x509/ca.pem
  $ certtool -i --infile ca.pem --outder --outfile ca.der
  $ ls -al ca.der
  -rw-r--r--. 1 ueno ueno 852 Mar  7 10:18 ca.der
  $ poke ca.der
  (poke) load "asn1-ber.pk"
  (poke) BER_Data_Value @ 0#B
  unhandled constraint violation exception
  (poke) var l = BER_Length @ 1#B
  (poke) l.get
  10246UL#B <-- this should be 848 (= 852 - 4 bytes header)

1. https://en.wikipedia.org/wiki/X.690#Definite_form

2022-03-07  Daiki Ueno  <ueno@gnu.org>

        * pickles/asn1-ber.pk (BER_Identifier): Fix long-form tag number
        handling.
        (BER_Length): Fix long-form definite length calculation.
        (BER_Data_Value): Allow constructed types can also have definite
        length.
---
 ChangeLog           |  6 ++++++
 pickles/asn1-ber.pk | 24 ++++++++++++------------
 2 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 24c58423..44612e8a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2022-03-07  Daiki Ueno  <ueno@gnu.org>
+
+       * pickles/asn1-ber.pk (BER_Identifier): Fix long-form tag number
+       handling.
+       (BER_Length): Fix long-form definite length calculation.
+
 2022-03-07  Jose E. Marchesi  <jemarch@gnu.org>
 
        * .x-sc_bindtextdomain: Add poked/*.
diff --git a/pickles/asn1-ber.pk b/pickles/asn1-ber.pk
index d52c1d6d..8f9c2deb 100644
--- a/pickles/asn1-ber.pk
+++ b/pickles/asn1-ber.pk
@@ -84,7 +84,7 @@ var ber_tag_class_name = [
 var BER_ENCODING_PRIMITIVE = 0b0,
     BER_ENCODING_CONSTRUCTED = 0b1;
 
-/* The "identifier octects", as they are called in the spec, act as a
+/* The "identifier octets", as they are called in the spec, act as a
    sort of a header for BER data value.  It specifies the class,
    encoding and number of a tag.  */
 
@@ -107,16 +107,16 @@ type BER_Identifier =
         uint<7> rest;
       };
 
-    Additional_Octet[] octects if tag_number == 0b11111;
+    Additional_Octet[] octets if tag_number == 0b11111;
 
     method get_tag_number = uint<64>:
     {
-      if (tag_number < 0b1111)
+      if (tag_number < 0b11111)
        return tag_number;
       else
       {
         var number = 0;
-        for (o in octects)
+        for (o in octets)
           number += o.rest;
         return number;
       }
@@ -145,7 +145,7 @@ type BER_Length =
     {
       uint<1> first : first == 1;
       uint<7> len;
-      byte[len] octects;
+      byte[len] octets;
     } long_form : long_form.first:::long_form.len != 0b1111_1111;
 
     method get = offset<uint<64>,B>:
@@ -153,14 +153,15 @@ type BER_Length =
       try return short_form;
       catch if E_elem
       {
-        var shift = 0;
-        var l = 0UL;
+        var l = 0;
+        var i = 0;
 
-        for (o in long_form.octects)
+        for (; i < long_form.octets'length - 1; i++)
           {
-            l += l | (o & 0x7f) <<. shift;
-            shift += 7;
+            l += long_form.octets[i] & 0xff;
+            l <<.= 8;
           }
+        l += long_form.octets[i] & 0xff;
 
         return l#B;
       }
@@ -211,8 +212,7 @@ type BER_Data_Value =
     BER_Identifier identifier;
     union
     {
-      BER_Length definite
-        : identifier.encoding == BER_ENCODING_PRIMITIVE;
+      BER_Length definite;
       byte indefinite : indefinite == 0b1000_0000;
 
       method is_indefinite = int:
-- 
2.34.1




reply via email to

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