1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#!/usr/bin/python2.5
2ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen# Copyright (c) 2011 The Chromium Authors. All rights reserved.
3ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen# Use of this source code is governed by a BSD-style license that can be
4ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen# found in the LICENSE file.
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen"""Helper module for ASN.1/DER encoding."""
7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenimport binascii
9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenimport struct
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen# Tags as defined by ASN.1.
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenINTEGER = 2
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenBIT_STRING = 3
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenNULL = 5
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenOBJECT_IDENTIFIER = 6
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSEQUENCE = 0x30
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsendef Data(tag, data):
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  """Generic type-length-value encoder.
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Args:
22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    tag: the tag.
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    data: the data for the given tag.
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Returns:
25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    encoded TLV value.
26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  """
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if len(data) == 0:
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return struct.pack(">BB", tag, 0);
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  assert len(data) <= 0xffff;
30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return struct.pack(">BBH", tag, 0x82, len(data)) + data;
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsendef Integer(value):
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  """Encodes an integer.
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Args:
36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    value: the long value.
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Returns:
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    encoded TLV value.
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  """
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  data = '%x' % value
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return Data(INTEGER, binascii.unhexlify('00' + '0' * (len(data) % 2) + data))
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsendef Bitstring(value):
44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  """Encodes a bit string.
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Args:
47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    value: a string holding the binary data.
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Returns:
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    encoded TLV value.
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  """
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return Data(BIT_STRING, '\x00' + value)
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsendef Sequence(values):
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  """Encodes a sequence of other values.
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Args:
57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    values: the list of values, must be strings holding already encoded data.
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Returns:
59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    encoded TLV value.
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  """
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return Data(SEQUENCE, ''.join(values))
62