# Copyright (c) 2011 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Helper module for ASN.1/DER encoding.""" import binascii import struct # Tags as defined by ASN.1. INTEGER = 2 BIT_STRING = 3 NULL = 5 OBJECT_IDENTIFIER = 6 SEQUENCE = 0x30 def Data(tag, data): """Generic type-length-value encoder. Args: tag: the tag. data: the data for the given tag. Returns: encoded TLV value. """ if len(data) < 128: return struct.pack(">BB", tag, len(data)) + data; assert len(data) <= 0xffff; return struct.pack(">BBH", tag, 0x82, len(data)) + data; def Integer(value): """Encodes an integer. Args: value: the long value. Returns: encoded TLV value. """ data = '%x' % value if (len(data) % 2 == 1): # Odd number of non-zero bytes - pad out our data to a full number of bytes. data = '0' + data # If the high bit is set, need to prepend a null byte to denote a positive # number. if (int(data[0], 16) >= 8): data = '00' + data return Data(INTEGER, binascii.unhexlify(data)) def Bitstring(value): """Encodes a bit string. Args: value: a string holding the binary data. Returns: encoded TLV value. """ return Data(BIT_STRING, '\x00' + value) def Sequence(values): """Encodes a sequence of other values. Args: values: the list of values, must be strings holding already encoded data. Returns: encoded TLV value. """ return Data(SEQUENCE, ''.join(values))