def _remove_certs_from_list(self, cert_list):  # pylint: disable=no-self-use
        """Remove a certificate from the LIST file.

        :param list cert_list: Must contain valid certs, each is of type
            :class:`letsencrypt.client.revoker.Cert`

        """
        list_path2 = tempfile.mktemp(".tmp", "LIST")
        idx = 0

        with open(self.list_path, "rb") as orgfile:
            csvreader = csv.reader(orgfile)
            with open(list_path2, "wb") as newfile:
                csvwriter = csv.writer(newfile)

                for row in csvreader:
                    if idx >= len(
                            cert_list) or row != cert_list[idx].get_row():
                        csvwriter.writerow(row)
                    else:
                        idx += 1

        # This should never happen...
        if idx != len(cert_list):
            raise errors.LetsEncryptRevokerError(
                "Did not find all cert_list items to remove from LIST")

        shutil.copy2(list_path2, self.list_path)
        os.remove(list_path2)
    def _acme_revoke(self, cert):
        """Revoke the certificate with the ACME server.

        :param cert: certificate to revoke
        :type cert: :class:`letsencrypt.client.revoker.Cert`

        :returns: TODO

        """
        # These will both have to change in the future away from M2Crypto
        # pylint: disable=protected-access
        certificate = jose_util.ComparableX509(cert._cert)
        try:
            with open(cert.backup_key_path, "rU") as backup_key_file:
                key = Crypto.PublicKey.RSA.importKey(backup_key_file.read())

        # If the key file doesn't exist... or is corrupted
        except (IndexError, ValueError, TypeError):
            raise errors.LetsEncryptRevokerError(
                "Corrupted backup key file: %s" % cert.backup_key_path)

        # TODO: Catch error associated with already revoked and proceed.
        return self.network.send_and_receive_expected(
            messages.RevocationRequest.create(certificate=certificate,
                                              key=key), messages.Revocation)
    def revoke_from_key(self, authkey):
        """Revoke all certificates under an authorized key.

        :param authkey: Authorized key used in previous transactions
        :type authkey: :class:`letsencrypt.client.le_util.Key`

        """
        certs = []
        try:
            clean_pem = Crypto.PublicKey.RSA.importKey(
                authkey.pem).exportKey("PEM")
        # https://www.dlitz.net/software/pycrypto/api/current/Crypto.PublicKey.RSA-module.html
        except (IndexError, ValueError, TypeError):
            raise errors.LetsEncryptRevokerError(
                "Invalid key file specified to revoke_from_key")

        with open(self.list_path, "rb") as csvfile:
            csvreader = csv.reader(csvfile)
            for row in csvreader:
                # idx, cert, key
                # Add all keys that match to marked list
                # Note: The key can be different than the pub key found in the
                #    certificate.
                _, b_k = self._row_to_backup(row)
                try:
                    test_pem = Crypto.PublicKey.RSA.importKey(
                        open(b_k).read()).exportKey("PEM")
                except (IndexError, ValueError, TypeError):
                    # This should never happen given the assumptions of the
                    # module. If it does, it is probably best to delete the
                    # the offending key/cert. For now... just raise an exception
                    raise errors.LetsEncryptRevokerError(
                        "%s - backup file is corrupted.")

                if clean_pem == test_pem:
                    certs.append(Cert.fromrow(row,
                                              self.config.cert_key_backup))
        if certs:
            self._safe_revoke(certs)
        else:
            logging.info(
                "No certificates using the authorized key were found.")
    def __init__(self, cert_path):
        """Cert initialization

        :param str cert_filepath: Name of file containing certificate in
            PEM format.

        """
        try:
            self._cert = M2Crypto.X509.load_cert(cert_path)
        except (IOError, M2Crypto.X509.X509Error):
            raise errors.LetsEncryptRevokerError(
                "Error loading certificate: %s" % cert_path)

        self.idx = -1

        self.orig = None
        self.orig_key = None
        self.backup_path = ""
        self.backup_key_path = ""

        self.installed = ["Unknown"]