#!/usr/bin/python
# Copyright 2017 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.

"""Pretty-prints certificates as an openssl-annotated PEM file."""

import argparse
import base64
import errno
import hashlib
import os
import re
import subprocess
import sys


def read_file_to_string(path):
  with open(path, 'r') as f:
    return f.read()


def read_certificates_data_from_server(hostname):
  """Uses openssl to fetch the PEM-encoded certificates for an SSL server."""
  p = subprocess.Popen(["openssl", "s_client", "-showcerts",
                        "-servername", hostname,
                        "-connect", hostname + ":443"],
                        stdin=subprocess.PIPE,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.PIPE)
  result = p.communicate()

  if p.returncode == 0:
    return result[0]

  sys.stderr.write("Failed getting certificates for %s:\n%s\n" % (
      hostname, result[1]))
  return ""


def read_sources_from_commandline(sources):
  """Processes the command lines and returns an array of all the sources
  bytes."""
  sources_bytes = []

  if not sources:
    # If no command-line arguments were given to the program, read input from
    # stdin.
    sources_bytes.append(sys.stdin.read())
  else:
    for arg in sources:
      # If the argument identifies a file path, read it
      if os.path.exists(arg):
        sources_bytes.append(read_file_to_string(arg))
      else:
        # Otherwise treat it as a web server address.
        sources_bytes.append(read_certificates_data_from_server(arg))

  return sources_bytes


def strip_indentation_whitespace(text):
  """Strips leading whitespace from each line."""
  stripped_lines = [line.lstrip() for line in text.split("\n")]
  return "\n".join(stripped_lines)


def strip_all_whitespace(text):
  pattern = re.compile(r'\s+')
  return re.sub(pattern, '', text)


def extract_certificates_from_pem(pem_bytes):
  certificates_der = []

  regex = re.compile(
      r'-----BEGIN (CERTIFICATE|PKCS7)-----(.*?)-----END \1-----', re.DOTALL)

  for match in regex.finditer(pem_bytes):
    der = base64.b64decode(strip_all_whitespace(match.group(2)))
    if match.group(1) == 'CERTIFICATE':
      certificates_der.append(der)
    else:
      certificates_der.extend(extract_certificates_from_der_pkcs7(der))

  return certificates_der


def extract_certificates_from_der_pkcs7(der_bytes):
  pkcs7_certs_pem = process_data_with_command(
      ['openssl','pkcs7','-print_certs', '-inform', 'DER'], der_bytes)
  # The output will be one or more PEM encoded certificates.
  # (Or CRLS, but those will be ignored.)
  if pkcs7_certs_pem:
    return extract_certificates_from_pem(pkcs7_certs_pem)
  return []


def extract_certificates_from_der_ascii(input_text):
  certificates_der = []

  # Look for beginning and end of Certificate SEQUENCE. The indentation is
  # significant. (The SEQUENCE must be non-indented, and the rest of the DER
  # ASCII must be indented until the closing } which again is non-indented.)
  # The output of der2ascii meets this, but it is not a requirement of the DER
  # ASCII language.
  # TODO(mattm): consider alternate approach of doing ascii2der on entire
  # input, and handling the multiple concatenated DER certificates.
  regex = re.compile(r'^(SEQUENCE {.*?^})', re.DOTALL | re.MULTILINE)

  for match in regex.finditer(input_text):
    der_ascii_bytes = match.group(1)
    der_bytes = process_data_with_command(["ascii2der"], der_ascii_bytes)
    if der_bytes:
      certificates_der.append(der_bytes)

  return certificates_der


def decode_netlog_hexdump(netlog_text):
  lines = netlog_text.splitlines()

  # Skip the text preceeding the actual hexdump.
  # TODO(eroman): New logs name this field "bytes" and it is Base64 encoded.
  while lines and 'hex_encoded_bytes' not in lines[0]:
    del lines[0]
  if not lines:
    return None
  del lines[0]

  bytes = []
  hex_re = re.compile('\s*([0-9A-Fa-f ]{48})')
  for line in lines:
    m = hex_re.search(line)
    if not m:
      break
    hex_string = m.group(1)
    bytes.extend(chr(int(part, 16)) for part in hex_string.split())

  return ''.join(bytes)


class ByteReader:
  """Iteratively consume data from a byte string.

  Automatically tracks and advances current position in the string as data is
  consumed, and will throw an exception if attempting to read past the end of
  the string.
  """
  def __init__(self, data):
    self.data = data
    self.pos = 0

  def consume_byte(self):
    i = ord(self.data[self.pos])
    self.pos += 1
    return i

  def consume_int24(self):
    return ((self.consume_byte() << 16) + (self.consume_byte() << 8) +
            self.consume_byte())

  def consume_bytes(self, n):
    b = self.data[self.pos:self.pos+n]
    if len(b) != n:
      raise IndexError('requested:%d bytes  actual:%d bytes'%(n, len(b)))
    self.pos += n
    return b

  def remaining_byte_count(self):
    return len(self.data) - self.pos


def decode_tls_certificate_message(certificate_message):
  reader = ByteReader(certificate_message)
  if reader.consume_byte() != 11:
    sys.stderr.write('HandshakeType != 11. Not a Certificate Message.\n')
    return []

  message_length = reader.consume_int24()
  if reader.remaining_byte_count() != message_length:
    sys.stderr.write(
        'message_length(%d) != remaining_byte_count(%d)\n' % (
            message_length, reader.remaining_byte_count()))
    return []

  certificate_list_length = reader.consume_int24()
  if reader.remaining_byte_count() != certificate_list_length:
    sys.stderr.write(
        'certificate_list_length(%d) != remaining_byte_count(%d)\n' % (
            certificate_list_length, reader.remaining_byte_count()))
    return []

  certificates_der = []
  while reader.remaining_byte_count():
    cert_len = reader.consume_int24()
    certificates_der.append(reader.consume_bytes(cert_len))

  return certificates_der


def extract_tls_certificate_message(netlog_text):
  raw_certificate_message = decode_netlog_hexdump(netlog_text)
  if not raw_certificate_message:
    return []
  return decode_tls_certificate_message(raw_certificate_message)


def extract_certificates(source_bytes):
  if "BEGIN CERTIFICATE" in source_bytes or "BEGIN PKCS7" in source_bytes:
    return extract_certificates_from_pem(source_bytes)

  if "SEQUENCE {" in source_bytes:
    return extract_certificates_from_der_ascii(source_bytes)

  if "SSL_HANDSHAKE_MESSAGE_RECEIVED" in source_bytes:
    return extract_tls_certificate_message(source_bytes)

  # DER encoding of PKCS #7 signedData OID (1.2.840.113549.1.7.2)
  if "\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x07\x02" in source_bytes:
    return extract_certificates_from_der_pkcs7(source_bytes)

  # Otherwise assume it is the DER for a single certificate
  return [source_bytes]


def process_data_with_command(command, data):
  try:
    p = subprocess.Popen(command,
                         stdin=subprocess.PIPE,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
  except OSError, e:
    if e.errno == errno.ENOENT:
      sys.stderr.write("Failed to execute %s\n" % command[0])
      return ""
    raise

  result = p.communicate(data)

  if p.returncode == 0:
    return result[0]

  # Otherwise failed.
  sys.stderr.write("Failed: %s: %s\n" % (" ".join(command), result[1]))
  return ""


def openssl_text_pretty_printer(certificate_der, unused_certificate_number):
  return process_data_with_command(["openssl", "x509", "-text", "-inform",
                                   "DER", "-noout"], certificate_der)


def pem_pretty_printer(certificate_der, unused_certificate_number):
  return process_data_with_command(["openssl", "x509", "-inform", "DER",
                                   "-outform", "PEM"], certificate_der)


def der2ascii_pretty_printer(certificate_der, unused_certificate_number):
  return process_data_with_command(["der2ascii"], certificate_der)


def header_pretty_printer(certificate_der, certificate_number):
  cert_hash = hashlib.sha256(certificate_der).hexdigest()
  return """===========================================
Certificate%d: %s
===========================================""" % (certificate_number, cert_hash)


# This is actually just used as a magic value, since pretty_print_certificates
# special-cases der output.
def der_printer():
  raise RuntimeError


def pretty_print_certificates(certificates_der, pretty_printers):
  # Need to special-case DER output to avoid adding any newlines, and to
  # only allow a single certificate to be output.
  if pretty_printers == [der_printer]:
    if len(certificates_der) > 1:
      sys.stderr.write("DER output only supports a single certificate, "
                       "ignoring %d remaining certs\n" % (
                           len(certificates_der) - 1))
    return certificates_der[0]

  result = ""
  for i in range(len(certificates_der)):
    certificate_der = certificates_der[i]
    pretty = []
    for pretty_printer in pretty_printers:
      pretty_printed = pretty_printer(certificate_der, i)
      if pretty_printed:
        pretty.append(pretty_printed)
    result += "\n".join(pretty) + "\n"
  return result


def parse_outputs(outputs):
  pretty_printers = []
  output_map = {"der2ascii": der2ascii_pretty_printer,
                "openssl_text": openssl_text_pretty_printer,
                "pem": pem_pretty_printer,
                "header": header_pretty_printer,
                "der": der_printer}
  for output_name in outputs.split(','):
    if output_name not in output_map:
      sys.stderr.write("Invalid output type: %s\n" % output_name)
      return []
    pretty_printers.append(output_map[output_name])
  if der_printer in pretty_printers and len(pretty_printers) > 1:
      sys.stderr.write("Output type der must be used alone.\n")
      return []
  return pretty_printers


def main():
  parser = argparse.ArgumentParser(
      description=__doc__, formatter_class=argparse.RawTextHelpFormatter)

  parser.add_argument('sources', metavar='SOURCE', nargs='*',
                      help='''Each SOURCE can be one of:
  (1) A server name such as www.google.com.
  (2) A PEM [*] file containing one or more CERTIFICATE or PKCS7 blocks
  (3) A file containing one or more DER ASCII certificates
  (4) A text NetLog dump of a TLS certificate message
      (must include the SSL_HANDSHAKE_MESSAGE_RECEIVED line)
  (5) A binary file containing DER-encoded PKCS #7 signedData
  (6) A binary file containing DER-encoded certificate

When multiple SOURCEs are listed, all certificates in them
are concatenated. If no SOURCE is given then data will be
read from stdin.

[*] Parsing of PEM files is relaxed - leading indentation
whitespace will be stripped (needed for copy-pasting data
from NetLogs).''')

  parser.add_argument(
      '--output', dest='outputs', action='store',
      default="header,der2ascii,openssl_text,pem",
      help='output formats to use. Default: %(default)s')

  args = parser.parse_args()

  sources_bytes = read_sources_from_commandline(args.sources)

  pretty_printers = parse_outputs(args.outputs)
  if not pretty_printers:
    sys.stderr.write('No pretty printers selected.\n')
    sys.exit(1)

  certificates_der = []
  for source_bytes in sources_bytes:
    certificates_der.extend(extract_certificates(source_bytes))

  sys.stdout.write(pretty_print_certificates(certificates_der, pretty_printers))


if __name__ == "__main__":
  main()
