1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19   
 20   
 21   
 22  __all__ = [ 
 23      'asn1_build', 
 24      'asn1_parse', 
 25      'ASN1FormatError', 
 26      'BIT_STRING', 
 27      'INTEGER', 
 28      'SEQUENCE', 
 29      'OBJECT_IDENTIFIER', 
 30      'OCTET_STRING', 
 31      'NULL', 
 32      ] 
 33   
 34  INTEGER = 0x02 
 35  BIT_STRING = 0x03 
 36  OCTET_STRING = 0x04 
 37  NULL = 0x05 
 38  OBJECT_IDENTIFIER = 0x06 
 39  SEQUENCE = 0x30 
 40   
 41   
 44   
 45   
 47      """Parse a data structure according to an ASN.1 template. 
 48   
 49      @param template: tuples comprising the ASN.1 template 
 50      @param data: byte string data to parse 
 51      @return: decoded structure 
 52      """ 
 53      data = bytearray(data) 
 54      r = [] 
 55      i = 0 
 56      try: 
 57        for t in template: 
 58            tag = data[i] 
 59            i += 1 
 60            if tag == t[0]: 
 61                length = data[i] 
 62                i += 1 
 63                if length & 0x80: 
 64                    n = length & 0x7f 
 65                    length = 0 
 66                    for j in range(n): 
 67                        length = (length << 8) | data[i] 
 68                        i += 1 
 69                if tag == INTEGER: 
 70                    n = 0 
 71                    for j in range(length): 
 72                        n = (n << 8) | data[i] 
 73                        i += 1 
 74                    r.append(n) 
 75                elif tag == BIT_STRING: 
 76                    r.append(data[i:i+length]) 
 77                    i += length 
 78                elif tag == NULL: 
 79                    assert length == 0 
 80                    r.append(None) 
 81                elif tag == OBJECT_IDENTIFIER: 
 82                    r.append(data[i:i+length]) 
 83                    i += length 
 84                elif tag == SEQUENCE: 
 85                    r.append(asn1_parse(t[1], data[i:i+length])) 
 86                    i += length 
 87                else: 
 88                    raise ASN1FormatError( 
 89                        "Unexpected tag in template: %02x" % tag) 
 90            else: 
 91                raise ASN1FormatError( 
 92                    "Unexpected tag (got %02x, expecting %02x)" % (tag, t[0])) 
 93        return r 
 94      except IndexError: 
 95        raise ASN1FormatError("Data truncated at byte %d"%i) 
  96   
 97   
 99      """Return a string representing a field length in ASN.1 format. 
100   
101      @param n: integer field length 
102      @return: ASN.1 field length 
103      """ 
104      assert n >= 0 
105      if n < 0x7f: 
106          return bytearray([n]) 
107      r = bytearray() 
108      while n > 0: 
109          r.insert(n & 0xff) 
110          n >>= 8 
111      return r 
 112   
113   
115      length = asn1_length(len(data)) 
116      length.insert(0, type) 
117      length.extend(data) 
118      return length 
 119   
120   
141