Assemble the trust chain.

  This assembly method uses the certificates subject and issuer common name and
  should be used for informational purposes only. It does *not*
  cryptographically verify the chain!

  :param OpenSSL.crypto.X509 leaf: The leaf certificate from which to build the
    chain.
  :param list[OpenSSL.crypto.X509] store: A list of certificates to use to
    resolve the chain.
  :return: The trust chain.
  :rtype: list[OpenSSL.crypto.X509]

def assemble_chain(leaf, store):
  """Assemble the trust chain.

  This assembly method uses the certificates subject and issuer common name and
  should be used for informational purposes only. It does *not*
  cryptographically verify the chain!

  :param OpenSSL.crypto.X509 leaf: The leaf certificate from which to build the
    chain.
  :param list[OpenSSL.crypto.X509] store: A list of certificates to use to
    resolve the chain.
  :return: The trust chain.
  :rtype: list[OpenSSL.crypto.X509]

  """
  store_dict = {}
  for cert in store:
    store_dict[cert.get_subject().CN] = cert

  chain = [leaf]

  current = leaf
  try:
    while current.get_issuer().CN != current.get_subject().CN:
      chain.append(store_dict[current.get_issuer().CN])
      current = store_dict[current.get_issuer().CN]
  except KeyError:
    invalid = crypto.X509()
    patch_certificate(invalid)
    invalid.set_subject(current.get_issuer())
    chain.append(invalid)

  chain.reverse()
  return chain