etingof/pyasn1

DEFAULT inside an OPTIONAL SEQUENCE does not produce expected result

russhousley opened this issue · 1 comments

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.

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