[back]
ASN.1 Data Python Reading Example
modified: 2015-03-22 04:22:15

If you are like me you have used a drag net across the internet looking for a simple understandable example of reading data in the ASN.1 format. You have likely seen and tried to read the overly complex technical specifications only to wonder why someone has to make something so complex.. I do not know the answer. The following will read basic ASN.1 data. It tries to error out when it gets to something more complex than it is designed to read such as indefinite length data and data that does not use 7-bit or 16-bit length fields. Such as an 8-bit (if possible) or larger than 16-bit. I used the following resources. I wrote this a while back and had to revisit it because I ran into a problem. I found out my code is working correctly, but here are the resources I found this recent time when searching that helped.

    def readASN1Data(data):
        fields = []
    
        data = data[4:]
        ndx = 0
    
        while len(data) > 0:
            type = data[0]
            data = data[1:]
    
            #print('type:%s' % type)
    
            if type & 0x40 == 0x40:
                raise Exception('ASN.1 Entry Used Indefinite Length')
    
            # read the first length
            sz = data[0]
            data = data[1:]
    
            #print('sz:%s' % sz)
    
            # if bit 7 is set then we use more bytes for the length
            if sz & 0x80 == 0x80:
                # get the length of the length field
                c = sz & 0x7F
                # make sure we are not in over our head and
                # if so then let someone know that we are
                if c != 2:
                    raise Exception('ASN.1 Entry Used Length File Not 2 Bytes')
                # read the length of the data
                sz = data[0] << 8 | data[1]
                #print('   2sz:%s' % sz)
                # remove the length
                data = data[2:]
    
            # create field
            field = (type, data[0:sz])
            # drop used data
            data = data[sz:]
    
            # add field
            fields.append(field)
            fields[ndx] = field
            ndx = ndx + 1
    
        return fields