pyasn1 icon indicating copy to clipboard operation
pyasn1 copied to clipboard

Native encoder fails to convert object decoded by DER

Open Commodore1024 opened this issue 7 years ago • 8 comments

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

Commodore1024 avatar Jun 06 '18 21:06 Commodore1024

That looks like a bug. Could you please give me a reproducer e.g. that DER blob causing this exception?

etingof avatar Jun 07 '18 05:06 etingof

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!

Commodore1024 avatar Jun 07 '18 17:06 Commodore1024

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...

Commodore1024 avatar Jun 25 '18 16:06 Commodore1024

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.

etingof avatar Jun 30 '18 21:06 etingof

... 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.

etingof avatar Jun 30 '18 21:06 etingof

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'

Commodore1024 avatar Jul 02 '18 22:07 Commodore1024

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!

etingof avatar Jul 03 '18 06:07 etingof

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

Commodore1024 avatar Jul 03 '18 14:07 Commodore1024