etingof / pyasn1-modules

ASN.1 modules for pyasn1 library
http://snmplabs.com/pyasn1/
BSD 2-Clause "Simplified" License
41 stars 45 forks source link

Parsing certificate extensions exception in 0.2.1 #15

Closed rcritten closed 6 years ago

rcritten commented 6 years ago

Parsing certificate extensions with pyasn1 0.4.3 and modules 0.1.5 is successful but fails in 0.2.1 with:

pyasn1.error.PyAsn1Error: <TagSet object at 0x7f66f3050e80 tags 0:32:16> not in asn1Spec: <OctetString schema object at 0x7f66f28410b8 tagSet <TagSet object at 0x7f66f2861438 tags 0:0:4> encoding iso-8859-1>

rcritten commented 6 years ago

Pasting because github won't accept any extensions for this I throw at it :-(

from pyasn1.codec.der import decoder from pyasn1_modules import pem, rfc2459

from pyasn1.type import univ

pem_text = """\ MIIEiTCCA3GgAwIBAgIBCjANBgkqhkiG9w0BAQsFADA2MRQwEgYDVQQKDAtHUkVZ T0FLLkNPTTEeMBwGA1UEAwwVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTE4MDUy NTE1NTQxOFoXDTIwMDUyNTE1NTQxOFowMzEUMBIGA1UECgwLR1JFWU9BSy5DT00x GzAZBgNVBAMMEm1hc3Rlci5ncmV5b2FrLmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD ggEPADCCAQoCggEBAP4S75hylr7LVJN537+Auz78LNuRACWs1HnLjJcQ6I2CYUOH 6ThvSZCw+WpsoxG60LV4Av7sKzbjJ6PmtxWgGR/FIPO7GOB24k3LXci44B8jV0M8 9kAVNDU+Q21JEwwVdvv055959ai51h3UHsc5M+FpU1oLTu6HWEfZDv1OsCmn5awz NqjufOdnZSIbyMSEplSF/O8xb7SUyPaRliJ/nJRMAtDzw18Y969CuMGMyp+q7axc LuHsFQxtBo0mBhcUAQxwurktYMOqsbgMfWJ04+4MAcnI+7PFww2N3/DE4ALyuFXi R0XcTE5fdJTZ8hhaWormoxcipaUX47kX/SiomHsCAwEAAaOCAaMwggGfMB8GA1Ud IwQYMBaAFCD8zrR5lvXDu35+W2iQ/NOOQA9kMD0GCCsGAQUFBwEBBDEwLzAtBggr BgEFBQcwAYYhaHR0cDovL2lwYS1jYS5ncmV5b2FrLmNvbS9jYS9vY3NwMA4GA1Ud DwEB/wQEAwIE8DAcBgNVHSUEFTATBggrBgEFBQcDAQYHKwYBBQIDBTB2BgNVHR8E bzBtMGugM6Axhi9odHRwOi8vaXBhLWNhLmdyZXlvYWsuY29tL2lwYS9jcmwvTWFz dGVyQ1JMLmJpbqI0pDIwMDEOMAwGA1UECgwFaXBhY2ExHjAcBgNVBAMMFUNlcnRp ZmljYXRlIEF1dGhvcml0eTAdBgNVHQ4EFgQU5boeP7HxofJuVusTZE5Va1+pw+Ew eAYDVR0RBHEwb6AuBgorBgEEAYI3FAIDoCAMHmtyYnRndC9HUkVZT0FLLkNPTUBH UkVZT0FLLkNPTaA9BgYrBgEFAgKgMzAxoA0bC0dSRVlPQUsuQ09NoSAwHqADAgEB oRcwFRsGa3JidGd0GwtHUkVZT0FLLkNPTTANBgkqhkiG9w0BAQsFAAOCAQEAiC2A H80rsiQnlWBSogzLGTPDngcB70B9GTyMLKIn+1oRnOS6600EeS2c5vOYPdmmeYFa YcgIKL0VSzOt0uwXwWnkaGPbYk6moclAwAKjBVa4kcN/gVFzoytUjoVkUaLPr1tJ 0eWJnkuRC/qR5/g2J1U+0jcAGZ59IKP/CMvzkoKQDmexJ/eigNSEsDtDMZCR9DYg A+fEDb46RWUeeMcBri5TWpTXEk3Q3wgOygrBq5qewL4wYkZmwzcctZSEBVYoyMHN zDPjJbA91efHgzU+I9WQXuPSmC3X9pVc+Q9r35j/yr5ht9uImObtXp9v7+/Qn42P wszyL/W4Lpg4sC/NNw== """

substrate = pem.readBase64fromText(pem_text)

asn1Object, rest = decoder.decode(substrate, rfc2459.Certificate())

tbs = asn1Object['tbsCertificate'] extensions = tbs['extensions'] OID_SAN = univ.ObjectIdentifier('2.5.29.17') gns = [] for ext in extensions: if ext['extnID'] == OID_SAN: der = decoder.decode( ext['extnValue'], asn1Spec=univ.OctetString())[0] gns = decoder.decode(der, asn1Spec=rfc2459.SubjectAltName())[0]

print(gns)

etingof commented 6 years ago

I believe starting from version 0.4.x the outermost container (e.g. OctetString) gets decoded automatically so you do not need to deal with that:

for ext in extensions:
    if ext['extnID'] == OID_SAN:
        gns = decoder.decode(ext['extnValue'], asn1Spec=rfc2459.SubjectAltName())[0]
        print(gns)
etingof commented 6 years ago

BTW, there is a better way:

asn1Object, rest = decoder.decode(substrate, rfc2459.Certificate(), decodeOpenTypes=True)
print(asn1Object.prettyPrint())

This should decode all extensions known to rfc2459.py (you can pass your own if you need).