def import_private_key(self, new_password, existing_password=None, alias=None, key_data=None, filepath=None): if not key_data: if not filepath: raise KeyImportError("Neither key_data nor filepath provided") with open(filepath, "rb") as fp: key_data = fp.read() try: ic = ICrypto() ic.load_pem_private_key("k", key_data, existing_password)\ .public_from_private("pub", "k") \ .get_public_key_fingerprint("pkfp", "pub") \ .encrypt_private_key("kenc", "k", bytes(new_password, "utf8")) logging.debug("Private key loaded successfully. Saving...") self.save_user_key(pkfp=ic["pkfp"], public=ic["pub"], private=ic["kenc"], alias=alias) except Exception as e: logging.error(str(e)) raise KeyImportError(e)
class TestConfig(unittest.TestCase): def test_getters_setters(self): self.ic = ICrypto() self.ic.add_blob("test", "Hello world") assert self.ic["test"] == "Hello world" def test_key_creation(self): self.ic = ICrypto() self.ic.add_blob("boo", "Hello world")\ .create_rsa_keypair("keys") print(self.ic["keys"]) def test_file_hash(self): self.ic = ICrypto() path = "D:\\downloads\\10126usb.iso" self.ic.hash_file("h", path) print(self.ic["h"]) def test_key_creation(self): self.ic = ICrypto() self.ic.add_blob("boo", "Hello world")\ .create_rsa_keypair("keys")\ .encrypt_private_key("pem", "keys", bytes("blablabla", "utf8")) print(self.ic["pem"]) print(self.ic["keys"]) with open("key.pem", "wb") as f: f.write(self.ic["pem"]) def test_priv_key_dump(self): self.ic = ICrypto() self.ic.add_blob("boo", "Hello world") \ .create_rsa_keypair("keys") \ .encrypt_private_key("pem", "keys", bytes("blablabla", "utf8")) print(self.ic["pem"]) print(self.ic["keys"]) with open("key.pem", "wb") as f: f.write(self.ic["pem"]) self.read_key() def read_key(self): with open("key.pem", "rb") as f: data = f.read() ic = ICrypto() ic.load_pem_private_key("priv", data, "blablabla") print(ic["priv"]) def test_pkfp(self): with open("key.pem", "rb") as f: data = f.read() ic = ICrypto() ic.load_pem_private_key("priv", data, "blablabla") \ .public_from_private("pub", "priv") \ .get_public_key_fingerprint("pkfp", "pub") print(str(ic["priv"], "utf8")) print(str(ic["pub"], "utf8")) with open("pub.pem", "wb") as pubf: pubf.write(ic["pub"]) print("PKFP: " + str(ic["pkfp"], "utf8"))
def test_key_creation(self): self.ic = ICrypto() self.ic.add_blob("boo", "Hello world")\ .create_rsa_keypair("keys")\ .encrypt_private_key("pem", "keys", bytes("blablabla", "utf8")) print(self.ic["pem"]) print(self.ic["keys"]) with open("key.pem", "wb") as f: f.write(self.ic["pem"])
def test_pkfp(self): with open("key.pem", "rb") as f: data = f.read() ic = ICrypto() ic.load_pem_private_key("priv", data, "blablabla") \ .public_from_private("pub", "priv") \ .get_public_key_fingerprint("pkfp", "pub") print(str(ic["priv"], "utf8")) print(str(ic["pub"], "utf8")) with open("pub.pem", "wb") as pubf: pubf.write(ic["pub"]) print("PKFP: " + str(ic["pkfp"], "utf8"))
def sign_source(self, key_data, key_password, path_to_image): ic = ICrypto() log.debug("Processing private key...") log.debug("key data %s" % str(key_data)) log.debug("key password %s " % str(key_password)) ic.load_pem_private_key("priv", key_data, key_password) \ .public_from_private("pub", "priv") \ .get_public_key_fingerprint("pkfp", "pub") \ .hash_file("hash", path_to_image) \ .private_key_sign("sign", "hash", "priv") log.debug("Crypto complete") return ic
def generate_encrypted_user_key(self, password, size=2048): """ Creates new private key and saves it in the key folder :param password: String password in utf8 format :note String: arbitrary note for user's reference :param size: :return: """ ic = ICrypto() ic.create_rsa_keypair("k") \ .public_from_private("pub", "k") \ .get_public_key_fingerprint("pkfp", "pub") \ .encrypt_private_key("kenc", "k", bytes(password, "utf8")) return {"pkfp": ic["pkfp"], "public": ic["pub"], "private": ic["kenc"]}
def is_key_trusted(self, pkfp): """ Given public key fingerprint checks if it is registered as trusted key :param pkfp: utf8 encoded public key fingerprint :return: """ key_path = None if pkfp in os.listdir(self.trusted_keys_path): log.debug("pkfp found in trusted keys") key_path = os.path.join(self.trusted_keys_path, pkfp) elif pkfp in os.listdir(self.user_keys_path): log.debug("pkfp found in user keys") key_path = os.path.join(self.user_keys_path, pkfp) else: log.debug("pkfp not recognized as trusted") return False with open(os.path.join(key_path, "public.pem"), "rb") as fp: log.debug("Checking public key") ic = ICrypto() ic.load_pem_public_key("pub", fp.read()) \ .get_public_key_fingerprint("pkfp", "pub") return str(ic["pkfp"], "utf8") == pkfp
def import_public_key(self, key_data=None, filepath=None, alias=None): """ Adds given public key to the trusted keys storage and registers it as trusted :param key_data: Must be not encoded :param filepath: :param alias: :return: """ if not (key_data or filepath): raise KeyImportError("Neither key_data nor filepath provided") if filepath: with open(filepath, "rb") as fp: key_data = fp.read() try: ic = ICrypto() ic.load_pem_public_key("pub", key_data) \ .get_public_key_fingerprint("pkfp", "pub") self.save_trusted_public_key(pkfp=ic["pkfp"], public=ic["pub"], alias=alias) except Exception as e: logging.error(e) raise KeyImportError(e)
def test_getters_setters(self): self.ic = ICrypto() self.ic.add_blob("test", "Hello world") assert self.ic["test"] == "Hello world"
def read_key(self): with open("key.pem", "rb") as f: data = f.read() ic = ICrypto() ic.load_pem_private_key("priv", data, "blablabla") print(ic["priv"])
def test_file_hash(self): self.ic = ICrypto() path = "D:\\downloads\\10126usb.iso" self.ic.hash_file("h", path) print(self.ic["h"])
def test_key_creation(self): self.ic = ICrypto() self.ic.add_blob("boo", "Hello world")\ .create_rsa_keypair("keys") print(self.ic["keys"])
def verify_image(self, temp_dir): """ Given the path to temporary directory where image data has been unpacked scans the structure of the image data and verifies hashes and signatures Also checks if public key is trusted :param temp_dir: temporary directory where content of zip archive was unpacked it should be a folder with 3 files in it :return: list of found errors. List will be empty if no errors found Errors come from ImageVerificationError enum """ errors = [] image_dir = os.path.join(temp_dir, self.config["image_dirname"]) try: path_to_image, path_to_info, path_to_signature = self._get_paths(image_dir) except InvalidImageContent as e: log.info("Invalid image content.") errors.append(ImageVerificationError.IMAGE_DATA_INVALID) return errors except Exception as e: log.exception(e) raise e info, info_sign = None, None ic = ICrypto() # load info with open(path_to_info, "r") as info_fp, \ open(path_to_signature, "rb") as sign_fp: info = json.load(info_fp) info_sign = sign_fp.read() # checking protocol if "authoring_protocol" not in info or info["authoring_protocol"] != self.authoring_protocol: log.exception("Authoring protocol don't match! \n%s" % get_stack()) errors.append(ImageVerificationError.AUTHORING_PROTOCOL_MISMATCH) ic.hash_file("image_hash", path_to_image) image_hash = ic["image_hash"] if bytes(info["hash"], "utf8") != image_hash: log.error("Image hash does not match with hash specified in the info: \n%s\n%s" % (str(image_hash), str(info["hash"]))) errors.append(ImageVerificationError.HASH_MISMATCH) try: ic.hash_file("infohash", path_to_info) \ .add_blob("sign", info_sign) \ .load_pem_public_key("pub", bytes(info["public_key"], "utf8")) \ .public_key_verify("res_infohash", "infohash", "pub", "sign") \ .get_public_key_fingerprint("pkfp", "pub") \ .add_blob("image_hash", image_hash) \ .add_blob("image_sign", bytes(info["sign"], "utf8")) \ .public_key_verify("res_image", "image_hash", "pub", "image_sign") except Exception as e: errors.append(ImageVerificationError.CRYPTO_ERROR) return errors if ic["res_infohash"] is False: log.error("Info signature is invalid") errors.append(ImageVerificationError.INFO_SIGNATURE_INVAILD) if ic["res_image"] is False: log.error("Image signature is invalid") errors.append(ImageVerificationError.IMAGE_SIGNATURE_INVALID) if ic["pkfp"] != bytes(info["pkfp"], "utf8"): msg = "Pkfp does not match" log.error("Pkfp does not match") errors.append(msg) log.info("Checking if pkfp is in trusted keys...") if not self.key_manager.is_key_trusted(str(ic["pkfp"], "utf8")): log.error("Key is not trusted") errors.append(ImageVerificationError.KEY_NOT_TRUSTED) return errors