From 38899dcbab7988ff031651035c819e36f097383d Mon Sep 17 00:00:00 2001 From: Sergey Kolupaev Date: Fri, 27 Dec 2024 10:53:01 -0800 Subject: [PATCH] RSA sunset --- keepercommander/api.py | 3 +- keepercommander/commands/enterprise.py | 12 ++- keepercommander/commands/enterprise_common.py | 3 + keepercommander/commands/transfer_account.py | 101 +++++++++++++----- 4 files changed, 90 insertions(+), 29 deletions(-) diff --git a/keepercommander/api.py b/keepercommander/api.py index 1c54adcf6..3433ae54d 100644 --- a/keepercommander/api.py +++ b/keepercommander/api.py @@ -310,7 +310,8 @@ def load_user_public_keys(params, emails, send_invites=False): # type: (KeeperP if pk.errorCode in ['', 'success']: rsa = pk.publicKey ec = pk.publicEccKey - params.key_cache[email] = PublicKeys(rsa=rsa, ec=ec) + aes = params.data_key if email == params.user else None + params.key_cache[email] = PublicKeys(aes=aes, rsa=rsa, ec=ec) elif pk.errorCode == 'no_active_share_exist': need_share_accept.append(pk.username) if len(need_share_accept) > 0 and send_invites: diff --git a/keepercommander/commands/enterprise.py b/keepercommander/commands/enterprise.py index 95e7cc9b2..8ab89a310 100644 --- a/keepercommander/commands/enterprise.py +++ b/keepercommander/commands/enterprise.py @@ -1654,13 +1654,16 @@ def execute(self, params, **kwargs): rq['tree_key'] = utils.base64_url_encode(encrypted_tree_key) if role_key: encrypted_role_key = crypto.encrypt_ec(role_key, ec_key) + rq['role_admin_key_type'] = 'encrypted_by_public_key_ecc' rq['role_admin_key'] = utils.base64_url_encode(encrypted_role_key) elif not params.forbid_rsa and public_key.rsa: rsa_key = crypto.load_rsa_public_key(public_key.rsa) encrypted_tree_key = crypto.encrypt_rsa(tree_key, rsa_key) + rq['tree_key_type'] = 'encrypted_by_public_key' rq['tree_key'] = utils.base64_url_encode(encrypted_tree_key) if role_key: encrypted_role_key = crypto.encrypt_rsa(role_key, rsa_key) + rq['role_admin_key_type'] = 'encrypted_by_public_key' rq['role_admin_key'] = utils.base64_url_encode(encrypted_role_key) else: continue @@ -2356,11 +2359,11 @@ def execute(self, params, **kwargs): for node_id in node_changes: is_add, node_name = node_changes[node_id] is_update = is_add and self.is_node_managed_by_role(params, node_id, role_id) - action = 'remove' if not is_add \ - else 'update' if is_update \ - else 'add' + command = 'role_managed_node_remove' if not is_add \ + else 'role_managed_node_update' if is_update \ + else 'role_managed_node_add' rq = { - "command": f'role_managed_node_{action}', + "command": command, "role_id": role_id, "managed_node_id": node_id } @@ -2390,6 +2393,7 @@ def execute(self, params, **kwargs): rq['tree_keys'].append({ 'enterprise_user_id': user_id, 'tree_key': utils.base64_url_encode(encrypted_tree_key), + 'tree_key_type': 'encrypted_by_public_key' }) else: continue diff --git a/keepercommander/commands/enterprise_common.py b/keepercommander/commands/enterprise_common.py index c4f2ed276..6a82b00b0 100644 --- a/keepercommander/commands/enterprise_common.py +++ b/keepercommander/commands/enterprise_common.py @@ -106,13 +106,16 @@ def get_role_users_change_batch(self, params, roles, add_user, remove_user, forc if role_key: encrypted_role_key = crypto.encrypt_ec(role_key, ec_key) rq['role_admin_key'] = utils.base64_url_encode(encrypted_role_key) + rq['role_admin_key_type'] = 'encrypted_by_public_key_ecc' elif not params.forbid_rsa and public_key.rsa: rsa_key = crypto.load_rsa_public_key(public_key.rsa) encrypted_tree_key = crypto.encrypt_rsa(tree_key, rsa_key) rq['tree_key'] = utils.base64_url_encode(encrypted_tree_key) + rq['tree_key_type'] = 'encrypted_by_public_key' if role_key: encrypted_role_key = crypto.encrypt_rsa(role_key, rsa_key) rq['role_admin_key'] = utils.base64_url_encode(encrypted_role_key) + rq['role_admin_key_type'] = 'encrypted_by_public_key' else: continue diff --git a/keepercommander/commands/transfer_account.py b/keepercommander/commands/transfer_account.py index 955730de4..c85399cf7 100644 --- a/keepercommander/commands/transfer_account.py +++ b/keepercommander/commands/transfer_account.py @@ -210,7 +210,8 @@ def verify_user(username): # type: (str) -> Optional[str] @staticmethod def transfer_user_account(params, username, target_user, target_public_key): # type: (KeeperParams, str, str, PublicKeys) -> bool - ec_public_key = crypto.load_ec_public_key(target_public_key.ec) if target_public_key.ec and params.forbid_rsa else None + aes_key = target_public_key.aes + ec_public_key = crypto.load_ec_public_key(target_public_key.ec) if target_public_key.ec else None rsa_public_key = crypto.load_rsa_public_key(target_public_key.rsa) if target_public_key.rsa and not params.forbid_rsa else None if not ec_public_key and not rsa_public_key: raise Exception(f'Cannot user target user public key') @@ -278,8 +279,6 @@ def transfer_user_account(params, username, target_user, target_public_key): 'from_user': username, 'to_user': target_user } - if ec_public_key: - rqt['key_type'] = 'encrypted_by_public_key_ecc' if 'record_keys' in rs: rqt['record_keys'] = [] @@ -301,13 +300,15 @@ def transfer_user_account(params, username, target_user, target_public_key): record_key = user_data_key else: raise Exception(f'Unsupported record key type') - if ec_public_key: encrypted_record_key = crypto.encrypt_ec(record_key, ec_public_key) record_key_type = 'encrypted_by_public_key_ecc' - else: + elif rsa_public_key: encrypted_record_key = crypto.encrypt_rsa(record_key, rsa_public_key) record_key_type = 'encrypted_by_public_key' + else: + raise Exception(f'Cannot re-encrypt record key') + rqt['record_keys'].append({ 'record_uid': record_uid, 'record_key': utils.base64_url_encode(encrypted_record_key), @@ -336,12 +337,25 @@ def transfer_user_account(params, username, target_user, target_public_key): else: raise Exception(f'Unsupported shared folder key type') - if ec_public_key: - encrypted_shared_folder_key = crypto.encrypt_ec(shared_folder_key, ec_public_key) - shared_folder_key_type = 'encrypted_by_public_key_ecc' + if params.forbid_rsa: + if aes_key: + encrypted_shared_folder_key = crypto.encrypt_aes_v2(shared_folder_key, aes_key) + shared_folder_key_type = 'encrypted_by_data_key_gcm' + elif ec_public_key: + encrypted_shared_folder_key = crypto.encrypt_ec(shared_folder_key, ec_public_key) + shared_folder_key_type = 'encrypted_by_public_key_ecc' + else: + raise Exception(f'Cannot re-encrypt shared folder key') else: - encrypted_shared_folder_key = crypto.encrypt_rsa(shared_folder_key, rsa_public_key) - shared_folder_key_type = 'encrypted_by_public_key' + if aes_key: + encrypted_shared_folder_key = crypto.encrypt_aes_v1(shared_folder_key, aes_key) + shared_folder_key_type = 'encrypted_by_data_key' + elif rsa_public_key: + encrypted_shared_folder_key = crypto.encrypt_rsa(shared_folder_key, rsa_public_key) + shared_folder_key_type = 'encrypted_by_public_key' + else: + raise Exception(f'Cannot re-encrypt shared folder key') + rqt['shared_folder_keys'].append({ 'shared_folder_uid': shared_folder_uid, 'shared_folder_key': utils.base64_url_encode(encrypted_shared_folder_key), @@ -370,12 +384,24 @@ def transfer_user_account(params, username, target_user, target_public_key): else: raise Exception(f'Unsupported team key type') - if ec_public_key: - encrypted_team_key = crypto.encrypt_ec(team_key, ec_public_key) - team_key_type = 'encrypted_by_public_key_ecc' + if params.forbid_rsa: + if aes_key: + encrypted_team_key = crypto.encrypt_aes_v2(team_key, aes_key) + team_key_type = 'encrypted_by_data_key_gcm' + elif ec_public_key: + encrypted_team_key = crypto.encrypt_ec(team_key, ec_public_key) + team_key_type = 'encrypted_by_public_key_ecc' + else: + raise Exception(f'Cannot re-encrypt team key') else: - encrypted_team_key = crypto.encrypt_rsa(team_key, rsa_public_key) - team_key_type = 'encrypted_by_public_key' + if aes_key: + encrypted_team_key = crypto.encrypt_aes_v1(team_key, aes_key) + team_key_type = 'encrypted_by_data_key' + elif rsa_public_key: + encrypted_team_key = crypto.encrypt_rsa(team_key, rsa_public_key) + team_key_type = 'encrypted_by_public_key' + else: + raise Exception(f'Cannot re-encrypt team key') rqt['team_keys'].append({ 'team_uid': team_uid, 'team_key': utils.base64_url_encode(encrypted_team_key), @@ -391,13 +417,29 @@ def transfer_user_account(params, username, target_user, target_public_key): folder_key = utils.generate_aes_key() folder_data = json.dumps({ 'name': f'Transfer from {username}' }).encode('utf-8') folder_data = crypto.encrypt_aes_v1(folder_data, folder_key) - if ec_public_key: - encrypted_folder_key = crypto.encrypt_ec(folder_key, ec_public_key) + if params.forbid_rsa: + if aes_key: + encrypted_folder_key = crypto.encrypt_aes_v2(folder_key, aes_key) + folder_key_type = 'encrypted_by_data_key_gcm' + elif ec_public_key: + encrypted_folder_key = crypto.encrypt_ec(folder_key, ec_public_key) + folder_key_type = 'encrypted_by_public_key_ecc' + else: + raise Exception(f'Cannot re-encrypt user folder key') else: - encrypted_folder_key = crypto.encrypt_rsa(folder_key, rsa_public_key) + if aes_key: + encrypted_folder_key = crypto.encrypt_aes_v1(folder_key, aes_key) + folder_key_type = 'encrypted_by_data_key' + elif rsa_public_key: + encrypted_folder_key = crypto.encrypt_rsa(folder_key, rsa_public_key) + folder_key_type = 'encrypted_by_public_key' + else: + raise Exception(f'Cannot re-encrypt user folder key') + rqt['user_folder_transfer'] = { 'transfer_folder_uid': utils.generate_uid(), 'transfer_folder_key': utils.base64_url_encode(encrypted_folder_key), + 'transfer_folder_key_type': folder_key_type, 'transfer_folder_data': utils.base64_url_encode(folder_data) } for ufk in rs['user_folder_keys']: @@ -415,13 +457,24 @@ def transfer_user_account(params, username, target_user, target_public_key): user_folder_key = crypto.decrypt_ec(user_folder_key, user_ecc_private_key) else: raise Exception(f'Unsupported user folder key type') - - if ec_public_key: - encrypted_user_folder_key = crypto.encrypt_ec(user_folder_key, ec_public_key) - user_folder_key_type = 'encrypted_by_public_key_ecc' + if params.forbid_rsa: + if aes_key: + encrypted_user_folder_key = crypto.encrypt_aes_v2(user_folder_key, aes_key) + user_folder_key_type = 'encrypted_by_data_key_gcm' + elif ec_public_key: + encrypted_user_folder_key = crypto.encrypt_ec(user_folder_key, ec_public_key) + user_folder_key_type = 'encrypted_by_public_key_ecc' + else: + raise Exception(f'Cannot re-encrypt user folder key') else: - encrypted_user_folder_key = crypto.encrypt_rsa(user_folder_key, rsa_public_key) - user_folder_key_type = 'encrypted_by_public_key' + if aes_key: + encrypted_user_folder_key = crypto.encrypt_aes_v1(user_folder_key, aes_key) + user_folder_key_type = 'encrypted_by_data_key' + elif ec_public_key: + encrypted_user_folder_key = crypto.encrypt_rsa(user_folder_key, rsa_public_key) + user_folder_key_type = 'encrypted_by_public_key' + else: + raise Exception(f'Cannot re-encrypt user folder key') rqt['user_folder_keys'].append({ 'user_folder_uid': user_folder_uid, 'user_folder_key': utils.base64_url_encode(encrypted_user_folder_key),