google/openhtf

Replacing `M2Crypto` dependency with `cryptography`

facutuesca opened this issue · 0 comments

Hi! Would you be open to a PR to replace the M2Crypto dependency with cryptography?

  • cryptography provides wheels for most platforms, whereas M2Crypto only provides a source tarball, meaning it has to be built from scratch every time.
  • M2Crypto needs swig to be installed in order to be built, which means installing with pip install openhtf[usb_plugs] will fail unless sudo apt install swig (or equivalent) is run before.
  • cryptography is actively maintained by the Python Cryptographic Authority

Since M2Crypto is only used to implement a adb_protocol.AuthSigner subclass (M2CryptoSigner), only needing to load RSA keys and sign with them, it could be easily replaced with something like:

from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives import hashes

def get_passphrase() -> Optional[str]:
  from getpass import getpass
  try:
    return getpass('Enter passphrase:')
  except KeyboardInterrupt:
    return None

class CryptographySigner(adb_protocol.AuthSigner):
  """AuthSigner using cryptography."""
  def __init__(self, rsa_key_path):
    with open(rsa_key_path + '.pub') as rsa_pub_file:
      self.public_key = rsa_pub_file.read()

    with open(rsa_key_path, "rb") as rsa_file:
      self.rsa_key = serialization.load_pem_private_key(rsa_file.read(),
                                                        password=get_passphrase())

  def sign(self, data):
    return self.rsa_key.sign(data, hashes.SHA1)

  def get_public_key(self):
    """Return the public key."""
    return self.public_key