# Copyright (c) 2012 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.

# This file implements very minimal ASN.1, DER serialization.

import types


def ToDER(obj):
  '''ToDER converts the given object into DER encoding'''
  if type(obj) == types.NoneType:
    # None turns into NULL
    return TagAndLength(5, 0)
  if type(obj) == types.StringType:
    # Strings are PRINTABLESTRING
    return TagAndLength(19, len(obj)) + obj
  if type(obj) == types.BooleanType:
    val = "\x00"
    if obj:
      val = "\xff"
    return TagAndLength(1, 1) + val
  if type(obj) == types.IntType or type(obj) == types.LongType:
    big_endian = []
    val = obj
    while val != 0:
      big_endian.append(val & 0xff)
      val >>= 8

    if len(big_endian) == 0 or big_endian[-1] >= 128:
      big_endian.append(0)

    big_endian.reverse()
    return TagAndLength(2, len(big_endian)) + ToBytes(big_endian)

  return obj.ToDER()


def ToBytes(array_of_bytes):
  '''ToBytes converts the array of byte values into a binary string'''
  return ''.join([chr(x) for x in array_of_bytes])


def TagAndLength(tag, length):
  der = [tag]
  if length < 128:
    der.append(length)
  elif length < 256:
    der.append(0x81)
    der.append(length)
  elif length < 65535:
    der.append(0x82)
    der.append(length >> 8)
    der.append(length & 0xff)
  else:
    assert False

  return ToBytes(der)


class Raw(object):
  '''Raw contains raw DER encoded bytes that are used verbatim'''
  def __init__(self, der):
    self.der = der

  def ToDER(self):
    return self.der


class Explicit(object):
  '''Explicit prepends an explicit tag'''
  def __init__(self, tag, child):
    self.tag = tag
    self.child = child

  def ToDER(self):
    der = ToDER(self.child)
    tag = self.tag
    tag |= 0x80 # content specific
    tag |= 0x20 # complex
    return TagAndLength(tag, len(der)) + der


class ENUMERATED(object):
  def __init__(self, value):
    self.value = value

  def ToDER(self):
    return TagAndLength(10, 1) + chr(self.value)


class SEQUENCE(object):
  def __init__(self, children):
    self.children = children

  def ToDER(self):
    der = ''.join([ToDER(x) for x in self.children])
    return TagAndLength(0x30, len(der)) + der


class SET(object):
  def __init__(self, children):
    self.children = children

  def ToDER(self):
    der = ''.join([ToDER(x) for x in self.children])
    return TagAndLength(0x31, len(der)) + der


class OCTETSTRING(object):
  def __init__(self, val):
    self.val = val

  def ToDER(self):
    return TagAndLength(4, len(self.val)) + self.val


class OID(object):
  def __init__(self, parts):
    self.parts = parts

  def ToDER(self):
    if len(self.parts) < 2 or self.parts[0] > 6 or self.parts[1] >= 40:
      assert False

    der = [self.parts[0]*40 + self.parts[1]]
    for x in self.parts[2:]:
      if x == 0:
        der.append(0)
      else:
        octets = []
        while x != 0:
          v = x & 0x7f
          if len(octets) > 0:
            v |= 0x80
          octets.append(v)
          x >>= 7
        octets.reverse()
        der = der + octets

    return TagAndLength(6, len(der)) + ToBytes(der)


class UTCTime(object):
  def __init__(self, time_str):
    self.time_str = time_str

  def ToDER(self):
    return TagAndLength(23, len(self.time_str)) + self.time_str


class GeneralizedTime(object):
  def __init__(self, time_str):
    self.time_str = time_str

  def ToDER(self):
    return TagAndLength(24, len(self.time_str)) + self.time_str


class BitString(object):
  def __init__(self, bits):
    self.bits = bits

  def ToDER(self):
    return TagAndLength(3, 1 + len(self.bits)) + "\x00" + self.bits
