Skip to content

Commit 5e5f801

Browse files
authored
Fix up ObjectIdentifier first subidentifier encoding/decoding
1 parent e25213a commit 5e5f801

3 files changed

Lines changed: 35 additions & 14 deletions

File tree

CHANGELOG.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
Changelog
22
=========
33

4+
UNRELEASED
5+
----------
6+
7+
* Fix OID encoding/decoding for the first octet according to ITU-T X.690
8+
49
2.7.0 (2023-01-17)
510
------------------
611

src/asn1.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ def _encode_object_identifier(self, oid): # type: (str) -> bytes
388388
if not self._re_oid.match(oid):
389389
raise Error('Illegal object identifier')
390390
cmps = list(map(int, oid.split('.')))
391-
if cmps[0] > 39 or cmps[1] > 39:
391+
if (cmps[0] <= 1 and cmps[1] > 39) or cmps[0] > 2:
392392
raise Error('Illegal object identifier')
393393
cmps = [40 * cmps[0] + cmps[1]] + cmps[2:]
394394
cmps.reverse()
@@ -686,9 +686,12 @@ def _decode_object_identifier(bytes_data): # type: (bytes) -> str
686686
if not byte & 0x80:
687687
result.append(value)
688688
value = 0
689-
if len(result) == 0 or result[0] > 1599:
689+
if len(result) == 0:
690690
raise Error('ASN1 syntax error')
691-
result = [result[0] // 40, result[0] % 40] + result[1:]
691+
if result[0] // 40 <= 1:
692+
result = [result[0] // 40, result[0] % 40] + result[1:]
693+
else:
694+
result = [2, result[0] - 80] + result[1:]
692695
result = list(map(str, result))
693696
return str('.'.join(result))
694697

tests/test_asn1.py

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,14 @@ def test_object_identifier(self):
177177
def test_long_object_identifier(self):
178178
enc = asn1.Encoder()
179179
enc.start()
180-
enc.write('39.2.3', asn1.Numbers.ObjectIdentifier)
180+
enc.write('2.60.3', asn1.Numbers.ObjectIdentifier)
181181
res = enc.output()
182182
assert res == b'\x06\x03\x8c\x1a\x03'
183183
enc.start()
184+
enc.write('2.999.3', asn1.Numbers.ObjectIdentifier)
185+
res = enc.output()
186+
assert res == b'\x06\x03\x88\x37\x03'
187+
enc.start()
184188
enc.write('1.39.3', asn1.Numbers.ObjectIdentifier)
185189
res = enc.output()
186190
assert res == b'\x06\x02\x4f\x03'
@@ -341,8 +345,9 @@ def test_error_object_identifier(self):
341345
enc = asn1.Encoder()
342346
enc.start()
343347
pytest.raises(asn1.Error, enc.write, '1', asn1.Numbers.ObjectIdentifier)
344-
pytest.raises(asn1.Error, enc.write, '40.2.3', asn1.Numbers.ObjectIdentifier)
348+
pytest.raises(asn1.Error, enc.write, '2.2.3', asn1.Numbers.ObjectIdentifier)
345349
pytest.raises(asn1.Error, enc.write, '1.40.3', asn1.Numbers.ObjectIdentifier)
350+
pytest.raises(asn1.Error, enc.write, '3.1', asn1.Numbers.objectIdentifier)
346351
pytest.raises(asn1.Error, enc.write, '1.2.3.', asn1.Numbers.ObjectIdentifier)
347352
pytest.raises(asn1.Error, enc.write, '.1.2.3', asn1.Numbers.ObjectIdentifier)
348353
pytest.raises(asn1.Error, enc.write, 'foo', asn1.Numbers.ObjectIdentifier)
@@ -521,7 +526,11 @@ def test_long_object_identifier(self):
521526
buf = b'\x06\x03\x8c\x1a\x03'
522527
dec.start(buf)
523528
tag, val = dec.read()
524-
assert val == u'39.2.3'
529+
assert val == u'2.60.3'
530+
buf = b'\x06\x03\x88\x37\x03'
531+
dec.start(buf)
532+
tag, val = dec.read()
533+
assert val == u'2.999.3'
525534
buf = b'\x06\x02\x4f\x03'
526535
dec.start(buf)
527536
tag, val = dec.read()
@@ -745,13 +754,7 @@ def test_error_non_normalized_negative_integer(self):
745754
pytest.raises(asn1.Error, dec.read)
746755

747756
def test_error_non_normalised_object_identifier(self):
748-
buf = b'\x06\x02\x80\x01'
749-
dec = asn1.Decoder()
750-
dec.start(buf)
751-
pytest.raises(asn1.Error, dec.read)
752-
753-
def test_error_object_identifier_with_too_large_first_component(self):
754-
buf = b'\x06\x02\x8c\x40'
757+
buf = b'\x06\x02\x01\x80'
755758
dec = asn1.Decoder()
756759
dec.start(buf)
757760
pytest.raises(asn1.Error, dec.read)
@@ -1079,12 +1082,22 @@ def test_octet_string(self):
10791082
def test_null(self):
10801083
TestEncoderDecoder.assert_encode_decode(None, asn1.Numbers.Null)
10811084

1082-
def test_object_identifier(self):
1085+
def test_real_object_identifier(self):
10831086
TestEncoderDecoder.assert_encode_decode(
10841087
'1.2.840.113554.1.2.1.1',
10851088
asn1.Numbers.ObjectIdentifier
10861089
)
10871090

1091+
def test_long_object_identifier(self):
1092+
for v in \
1093+
(
1094+
'2.60.3',
1095+
'2.999.3',
1096+
'1.39.3',
1097+
'1.2.300000'
1098+
):
1099+
TestEncoderDecoder.assert_encode_decode(v, asn1.Numbers.ObjectIdentifier)
1100+
10881101
def test_enumerated(self):
10891102
for v in (1, 2, 42):
10901103
TestEncoderDecoder.assert_encode_decode(v, asn1.Numbers.Enumerated)

0 commit comments

Comments
 (0)