[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
- [PATCH] pickles: asn1-ber: fix issues in long-form length/tag handling,
Daiki Ueno <=