15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""Helper module for ASN.1/DER encoding."""
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import binascii
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import struct
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Tags as defined by ASN.1.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INTEGER = 2
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BIT_STRING = 3
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NULL = 5
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OBJECT_IDENTIFIER = 6
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SEQUENCE = 0x30
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def Data(tag, data):
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """Generic type-length-value encoder.
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Args:
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tag: the tag.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data: the data for the given tag.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Returns:
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encoded TLV value.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if len(data) == 0:
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return struct.pack(">BB", tag, 0);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert len(data) <= 0xffff;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return struct.pack(">BBH", tag, 0x82, len(data)) + data;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def Integer(value):
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """Encodes an integer.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Args:
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    value: the long value.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Returns:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encoded TLV value.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data = '%x' % value
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Data(INTEGER, binascii.unhexlify('00' + '0' * (len(data) % 2) + data))
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def Bitstring(value):
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """Encodes a bit string.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Args:
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    value: a string holding the binary data.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Returns:
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encoded TLV value.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Data(BIT_STRING, '\x00' + value)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def Sequence(values):
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """Encodes a sequence of other values.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Args:
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    values: the list of values, must be strings holding already encoded data.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Returns:
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    encoded TLV value.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Data(SEQUENCE, ''.join(values))
61