Native encoder fails to convert object decoded by DER
Hi. I would very much appreciate advice on how to move forward. When using the native encoder to obtain python built-ins from an object decoded with DER, I get the error: AttributeError: 'tuple' object has no attribute 'tagClass'. My use of pyasn1 is straightforward:
from pyasn1.codec.der.decoder import decode
from pyasn1.codec.native.encoder import encode
dictionary = encode(decode(der)[0])
Stepping through the source code as it executes reveals that the call to tag.TagSet, below, is where the AttributeError is raised.
class Encoder:
try:
concreteEncoder = self.__typeMap[value.typeId]
except KeyError:
# use base type for codec lookup to recover untagged types
baseTagSet = tag.TagSet(value.tagSet.baseTag, value.tagSet.baseTag)
Below is the output from the pyasn1 debugger:
SetOf:
Sequence:
field-0=lbl1
field-1=
Sequence:
field-0=lbl2
field-1=0
Sequence:
field-0=lbl3
field-1=0
SequenceOf:
lbl4 gm Sequence:
field-0=lbl5
field-1=1718187085
SequenceOf:
lbl6 ZoneFit metadata SequenceOf:
lbl7 ZoneFit metadata SequenceOf:
lbl8 com.mygym.fit.metadata Sequence:
field-0=strt
field-1=20170410174341.023814Z
Sequence:
field-0=stop
field-1=20170410174341.023814Z
SequenceOf:
desc ipso facto presto change. SequenceOf:
lbla EC5DDE8E-B486-4FAE-AC27-95FE53AA5288 Sequence:
field-0=status
field-1=5681a7954094305bf604e2214479950496e693e94c69c0c71e7097115f0250a9+2fcae427f4bf8557cfff36110ea92bbdbdcc53fa8d88275ed2b6b8e5fecdaa85
...remaining substrate is: <none>
2018-06-08 14:26:08,142 pyasn1: decoder left scope , call completed
...and here is another, different example:
2018-06-08 14:14:58,340 pyasn1: codec SetOrSetOfDecoder yields type SetOf, value:
SetOf:
SequenceOf:
lbl1 SequenceOf:
lbl2 Sequence:
field-0=lbl3
field-1=
Sequence:
field-0=lbl4
field-1=0
Sequence:
field-0=lbl5
field-1=0
SequenceOf:
lbl6 gm SequenceOf:
lbl7 AnotherTransaction1234 Sequence:
field-0=lbl8
field-1=20170410181013.631371Z
Sequence:
field-0=lbl9
field-1=20170410181013.631371Z
SequenceOf:
lbla AnotherTransaction1234 SequenceOf:
lblb 006952772G.com.mygym.homegymfit0 Sequence:
field-0=UserID
field-1=98E0F442-E181-4C66-8126-1751D99F474E
...remaining substrate is: <none>
2018-06-08 14:14:58,340 pyasn1: decoder left scope , call completed
That looks like a bug. Could you please give me a reproducer e.g. that DER blob causing this exception?
Thanks for the quick reply! I uploaded a sample DER files that I have confirmed do not throw errors during DER decode. Please let me know if I can be of further assistance in troubleshooting the issue I reported. Thanks!
Is this helpful? Using this online decoder by OSS, I decoded one of the DER files i previously uploaded. Looking at this structure, i fail to see the distinction made by pyASN to interpret some records as Sequence and others as SequenceOf. Ideally, they would all be key-value pairs that get converted to the dictionary python type.
31 8201AE(430)
30 08
0C 04 6C626C31
04 00
30 09
0C 04 6C626C32
02 01 00
30 09
0C 04 6C626C33
02 01 00
30 0A
0C 04 6C626C34
0C 02 676D
30 0C
0C 04 6C626C35
02 04 6669744D
30 18
0C 04 6C626C36
0C 10 5A6F6E65466974206D65746164617461
30 18
0C 04 6C626C37
0C 10 5A6F6E65466974206D65746164617461
30 1E
0C 04 6C626C38
0C 16 636F6D2E6D7967796D2E6669742E6D65746164617461
30 1E
0C 04 73747274
18 16 32303137303431303137343334312E3032333831345A
30 1E
0C 04 73746F70
18 16 32303137303431303137343334312E3032333831345A
30 21
0C 04 64657363
0C 19 6970736F20666163746F2070726573746F206368616E67652E
30 2C
0C 04 6C626C61
0C 24 45433544444538452D423438362D344641452D414332372D393546453533414135...
30 818C(140)
0C 06 737461747573
04 8181(129) 353638316137393534303934333035626636303465323231343437393935...
Thank you for your samples! I think this is indeed a bug which should be fixed in #132 . It would be awesome if you could re-test your application with this fix applied.
... I fail to see the distinction made by pyASN to interpret some records as Sequence and others as SequenceOf.
Trouble is that on the wire BER Sequence is indistinguishable from SequenceOf. I'm not quite sure why BER serialization has been designed that way, but this is how it is.
The only solution I can immediately offer is to give a hint to BER decoder which is Sequence and which is SequenceOf in your ASN.1 structure (the same applies to Set/SetOf). You can do that by passing ASN.1 schema to decoder through asn1Spec parameter.
2018-07-02 18:19:39,457 pyasn1: using value codec SequenceEncoder chosen by <TagSet object at 0x7f3eff003e10 tags 0:32:16>
2018-07-02 18:19:39,457 pyasn1: encoder called for type UTF8String <lbl1>
File "/local/lib/python2.7/site-packages/pyasn1/codec/native/encoder.py", line 81, in encode
substrate[key] = encodeFun(subValue, **options)
File "/local/lib/python2.7/site-packages/pyasn1/codec/native/encoder.py", line 173, in __call__
baseTagSet = tag.TagSet(value.tagSet.baseTag, value.tagSet.baseTag)
File "/local/lib/python2.7/site-packages/pyasn1/type/tag.py", line 189, in __init__
[(superTag.tagClass, superTag.tagId) for superTag in superTags]
AttributeError: 'tuple' object has no attribute 'tagClass'
Nooo! That can't happen! Can you please make sure that you actually import the fixed pyasn1 version? Specifically, this patch to encoder.py should be present in /local/lib/python2.7/site-packages/pyasn1/codec/native/encoder.py.
Thanks!
Forgive me, I am no expert in python. i pulled your latest commit:
commit 939be5fabe8c8ed8fcb334b07c84349f99cb0e59
Author: Ilya Etingof <[email protected]>
Date: Tue Jul 3 08:37:13 2018 +0200
To make this library available to my project, i ran these commands in the pyasn1 project folder, which concluded with debugging output:
pip uninstall pyasn1
python setup.py build
python setup.py install
<output omitted>
Processing pyasn1-0.4.3-py2.7.egg
Copying pyasn1-0.4.3-py2.7.egg to lib/python2.7/site-packages
Adding pyasn1 0.4.3 to easy-install.pth file
Installed lib/python2.7/site-packages/pyasn1-0.4.3-py2.7.egg
Processing dependencies for pyasn1==0.4.3
Finished processing dependencies for pyasn1==0.4.3
... and now 'pip list' shows pyasn1 0.4.3