1# Copyright (c) 2011 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Helper module for ASN.1/DER encoding."""
6
7import binascii
8import struct
9
10# Tags as defined by ASN.1.
11INTEGER = 2
12BIT_STRING = 3
13NULL = 5
14OBJECT_IDENTIFIER = 6
15SEQUENCE = 0x30
16
17def Data(tag, data):
18  """Generic type-length-value encoder.
19
20  Args:
21    tag: the tag.
22    data: the data for the given tag.
23  Returns:
24    encoded TLV value.
25  """
26  if len(data) < 128:
27    return struct.pack(">BB", tag, len(data)) + data;
28  assert len(data) <= 0xffff;
29  return struct.pack(">BBH", tag, 0x82, len(data)) + data;
30
31def Integer(value):
32  """Encodes an integer.
33
34  Args:
35    value: the long value.
36  Returns:
37    encoded TLV value.
38  """
39  data = '%x' % value
40  if (len(data) % 2 == 1):
41    # Odd number of non-zero bytes - pad out our data to a full number of bytes.
42    data = '0' + data
43
44  # If the high bit is set, need to prepend a null byte to denote a positive
45  # number.
46  if (int(data[0], 16) >= 8):
47    data = '00' + data
48
49  return Data(INTEGER, binascii.unhexlify(data))
50
51def Bitstring(value):
52  """Encodes a bit string.
53
54  Args:
55    value: a string holding the binary data.
56  Returns:
57    encoded TLV value.
58  """
59  return Data(BIT_STRING, '\x00' + value)
60
61def Sequence(values):
62  """Encodes a sequence of other values.
63
64  Args:
65    values: the list of values, must be strings holding already encoded data.
66  Returns:
67    encoded TLV value.
68  """
69  return Data(SEQUENCE, ''.join(values))
70