0

I've got an extension which is described as follows:

Extension().setComponentByPosition(0, ObjectIdentifier(2.5.29.19))
           .setComponentByPosition(1, Boolean('False'))
           .setComponentByPosition(2, Any(hexValue='04023000'))

So based on the id, it's a BasicConstraints extension. However if I try to parse the value as the extension itself, I get an error:

decoder.decode(decoder.decode(e['extnValue'])[0], rfc2459.BasicConstraints())
# PyAsn1Error: Uninitialized component #0 at BasicConstraints()

That string decodes to an empty sequence, so it can legally be a BasicConstraints - name length optional/missing and ca is default, so not encoded in DER.

So what am I missing here? How do I decode this extension to the BasicConstraints class?

PS. this issue seems similar to an issue in mailing list, but I'm using 0.1.8 which should already include the mentioned fix

viraptor
  • 33,322
  • 10
  • 107
  • 191

1 Answers1

1

Since BasicConstraints is a SEQUENCE derivative, its minimum possible serialisation is SEQUENCE tag and zero length. Then its value could be an empty string, as you suggested. And this is in fact how it is:

>>> derSerialisation, _ = decode(OctetString(hexValue='04023000'))
>>> derSerialisation.prettyPrint()
'0x3000'
>>> constraint, _ = decode(derSerialisation)
>>> constraint.prettyPrint()
'Sequence:\n'

The ANY value is opaque (tagless), but embedded DER serialisation is itself encoded as OCTET STRING. So make sure you extract DER contents from OCTET STRING serialisation before passing it to decoder to recover BasicConstraints.

Mailing list bug is not relevant - that was in indefinite encoding mode.

UPDATED

It turned out to be a bug in rfc2459.BasicConstraints specification. While official fix/release is being prepared, I could advise the following monkey patch to pyasn1_modules.rfc2459:

>>> from pyasn1.type import namedtype
>>> from pyasn1_modules import rfc2459
>>> rfc2459.BasicConstraints.componentType = namedtype.NamedTypes(
...     namedtype.DefaultedNamedType(*rfc2459.BasicConstraints.componentType[0]),
...     rfc2459.BasicConstraints.componentType[1]
... )

which basically marks 'cA' component as defaulted. Once applied, your serialization can be decoded:

>>> s
Any(hexValue='04023000')
>>> basicConstraints, _ = decoder.decode(decoder.decode(s)[0], rfc2459.BasicConstraints())
>>> print(basicConstraints.prettyPrint())
BasicConstraints:
 cA='False'

UPDATED AGAIN

The above bug is fixed in pyasn1-modules 0.0.7

Ilya Etingof
  • 5,440
  • 1
  • 17
  • 21
  • Sure, I can decode it to a simple Sequence - but that's not the problem. Like I wrote - I cannot decode the extension to a BasicConstraints structure. In my code snippet the first decode results in a string, the second decode should result in BasicConstraints. The second decode works without asn1Spec=..., but fails with it. – viraptor Jul 23 '15 at 23:05
  • 1
    Updated my answer, sorry for misunderstanding. – Ilya Etingof Jul 29 '15 at 12:10
  • No worries, glad we got there. Thanks for guarding StackOverflow Ilya! – viraptor Jul 30 '15 at 11:53
  • 1
    Please try pyasn1-modules 0.0.7 – Ilya Etingof Aug 01 '15 at 15:13