2011-04-01 8 views
14

Tengo algunos datos que pyOpenSSL me dio, '0\r\x82\x0bexample.com'. Este debería ser el valor de una extensión subjectAltName X509. Traté de codificar las partes necesarias de la especificación ASN1 para esta extensión utilizando pyasn1 (y basado en uno de los ejemplos pyasn1):¿Cómo analizo los datos de la extensión subjectAltName usando pyasn1?

from pyasn1.type import univ, constraint, char, namedtype 

from pyasn1.codec.der.decoder import decode 

MAX = 64 

class DirectoryString(univ.Choice): 
    componentType = namedtype.NamedTypes(
     namedtype.NamedType(
      'teletexString', char.TeletexString().subtype(
       subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), 
     namedtype.NamedType(
      'printableString', char.PrintableString().subtype(
       subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), 
     namedtype.NamedType(
      'universalString', char.UniversalString().subtype(
       subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), 
     namedtype.NamedType(
      'utf8String', char.UTF8String().subtype(
       subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), 
     namedtype.NamedType(
      'bmpString', char.BMPString().subtype(
       subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), 
     namedtype.NamedType(
      'ia5String', char.IA5String().subtype(
       subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), 
     ) 


class AttributeValue(DirectoryString): 
    pass 


class AttributeType(univ.ObjectIdentifier): 
    pass 


class AttributeTypeAndValue(univ.Sequence): 
    componentType = namedtype.NamedTypes(
     namedtype.NamedType('type', AttributeType()), 
     namedtype.NamedType('value', AttributeValue()), 
     ) 


class RelativeDistinguishedName(univ.SetOf): 
    componentType = AttributeTypeAndValue() 

class RDNSequence(univ.SequenceOf): 
    componentType = RelativeDistinguishedName() 


class Name(univ.Choice): 
    componentType = namedtype.NamedTypes(
     namedtype.NamedType('', RDNSequence()), 
     ) 


class Extension(univ.Sequence): 
    componentType = namedtype.NamedTypes(
     namedtype.NamedType('extnID', univ.ObjectIdentifier()), 
     namedtype.DefaultedNamedType('critical', univ.Boolean('False')), 
     namedtype.NamedType('extnValue', univ.OctetString()), 
     ) 


class Extensions(univ.SequenceOf): 
    componentType = Extension() 
    sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX) 


class GeneralName(univ.Choice): 
    componentType = namedtype.NamedTypes(
     # namedtype.NamedType('otherName', AnotherName()), 
     namedtype.NamedType('rfc822Name', char.IA5String()), 
     namedtype.NamedType('dNSName', char.IA5String()), 
     # namedtype.NamedType('x400Address', ORAddress()), 
     namedtype.NamedType('directoryName', Name()), 
     # namedtype.NamedType('ediPartyName', EDIPartyName()), 
     namedtype.NamedType('uniformResourceIdentifier', char.IA5String()), 
     namedtype.NamedType('iPAddress', univ.OctetString()), 
     namedtype.NamedType('registeredID', univ.ObjectIdentifier()), 
     ) 


class GeneralNames(univ.SequenceOf): 
    componentType = GeneralName() 
    sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX) 


class SubjectAltName(GeneralNames): 
    pass 

print decode('0\r\x82\x0bexample.com', asn1Spec=GeneralNames()) 

Claramente me dieron un poco aburrido hacia el final y no especificó plenamente la GeneralName tipo. Sin embargo, la cadena de prueba debe contener un dNSName, no uno de los valores omitidos, así que espero que no importe.

Cuando se ejecuta el programa, se produce un error que no soy capaz de interpretar:

Traceback (most recent call last): 
    File "x509.py", line 94, in <module> 
    print decode('0\r\x82\x0bexample.com', asn1Spec=GeneralNames()) 
    File "/usr/lib/pymodules/python2.6/pyasn1/v1/codec/ber/decoder.py", line 493, in __call__ 
    length, stGetValueDecoder, decodeFun 
    File "/usr/lib/pymodules/python2.6/pyasn1/v1/codec/ber/decoder.py", line 202, in valueDecoder 
    substrate, asn1Spec 
    File "/usr/lib/pymodules/python2.6/pyasn1/v1/codec/ber/decoder.py", line 453, in __call__ 
    __chosenSpec.getTypeMap().has_key(tagSet): 
    File "/usr/lib/pymodules/python2.6/pyasn1/v1/type/univ.py", line 608, in getTypeMap 
    return Set.getComponentTypeMap(self) 
    File "/usr/lib/pymodules/python2.6/pyasn1/v1/type/univ.py", line 535, in getComponentTypeMap 
    def getComponentTypeMap(self): return self._componentType.getTypeMap(1) 
    File "/usr/lib/pymodules/python2.6/pyasn1/v1/type/namedtype.py", line 126, in getTypeMap 
    'Duplicate type %s in map %s'%(k,self.__typeMap) 
pyasn1.error.PyAsn1Error: Duplicate type TagSet(Tag(tagClass=0, tagFormat=0, tagId=22)) in map {TagSet(Tag(tagClass=0, tagFormat=0, tagId=22)): IA5String()} 

Algún consejo sobre que hice mal y cómo analizar con éxito este tipo de extensión con pyasn1 sería mucho apreciado.

Respuesta

15

He publicado esta pregunta en la lista de usuarios de pyasn1 e Ilya Etingof (el autor de pyasn1) ha señalado mi error. En resumen, cada NamedType en GeneralName.componentType necesita recibir información de etiqueta. Esto se hace con el método subtype. Por ejemplo, en lugar de:

namedtype.NamedType('rfc822Name', char.IA5String()), 

la definición debe ser:

namedtype.NamedType('rfc822Name', char.IA5String().subtype(
     implicitTag=tag.Tag(tag.tagClassContext, 
          tag.tagFormatSimple, 1))), 

donde 1 proviene de la definición ASN.1 de GeneralName:

GeneralName ::= CHOICE { 
    otherName      [0]  OtherName, 
    rfc822Name      [1]  IA5String, 
    dNSName       [2]  IA5String, 
    x400Address      [3]  ORAddress, 
    directoryName     [4]  Name, 
    ediPartyName     [5]  EDIPartyName, 
    uniformResourceIdentifier  [6]  IA5String, 
    iPAddress      [7]  OCTET STRING, 
    registeredID     [8]  OBJECT IDENTIFIER 
} 

Después de definir una etiqueta para cada uno de estos campos del componentType, el análisis tiene éxito:

(GeneralNames().setComponentByPosition(
    0, GeneralName().setComponentByPosition(1, IA5String('example.com'))), '') 
Cuestiones relacionadas