etingof / pyasn1

Generic ASN.1 library for Python
http://snmplabs.com/pyasn1
BSD 2-Clause "Simplified" License
244 stars 118 forks source link

DEFAULT inside an OPTIONAL SEQUENCE does not produce expected result #195

Open russhousley opened 4 years ago

russhousley commented 4 years ago

Here is a small code fragment to illustrate the problem:

import binascii from pyasn1.codec.der.decoder import decode as der_decode from pyasn1.codec.der.encoder import encode as der_encode from pyasn1.type import univ, namedtype from pyasn1_modules import rfc5280

oid = univ.ObjectIdentifier((1, 2, 410, 200046, 1, 2))

class PadAlgo(univ.Choice): componentType = namedtype.NamedTypes( namedtype.NamedType('specifiedPadAlgo', univ.OctetString()), namedtype.NamedType('generalPadAlgo', univ.ObjectIdentifier()) )

pad_algo_1 = PadAlgo() pad_algo_1['specifiedPadAlgo'] = univ.OctetString(hexValue='01')

class CbcParameters(univ.Sequence): componentType = namedtype.NamedTypes( namedtype.DefaultedNamedType('m', univ.Integer().subtype(value=1)), namedtype.DefaultedNamedType('padAlgo', pad_algo_1) )

algorithmIdentifierMapUpdate = { oid: CbcParameters(), }

rfc5280.algorithmIdentifierMap.update(algorithmIdentifierMapUpdate)

So, then using this code:

param = CbcParameters() param['m'] = 1 param['padAlgo'] = pad_algo_1

AlgoId = rfc5280.AlgorithmIdentifier() AlgoId['algorithm'] = oid AlgoId['parameters'] = der_encode(param)

substrate = der_encode(AlgoId) print(binascii.hexlify(substrate))

asn1Object, rest = der_decode(substrate, asn1Spec=rfc5280.AlgorithmIdentifier(), decodeOpenTypes=True)

substrate = der_encode(asn1Object) print(binascii.hexlify(substrate))

This produces two different hex strings:

300c06082a831a8c9a6e01023000 300a06082a831a8c9a6e0102

I believe that the first one is correct! The empty SEQUENCE should not be omitted in this situation.

russhousley commented 4 years ago

Argh! The indenting was removed when I entered the issue. I hope you can figure out what I was doing. I am attaching a file that shows the problem. try.py.txt