| 
														
															@@ -8,9 +8,10 @@ from unittest.mock import MagicMock 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 import pytest 
														 | 
														
														 | 
														
															 import pytest 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 from ..crypto.key import bin_to_hex 
														 | 
														
														 | 
														
															 from ..crypto.key import bin_to_hex 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-from ..crypto.key import PlaintextKey, AuthenticatedKey, RepoKey, KeyfileKey, \ 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    Blake2KeyfileKey, Blake2RepoKey, Blake2AuthenticatedKey, \ 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    AESOCBKeyfileKey, AESOCBRepoKey, CHPOKeyfileKey, CHPORepoKey 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+from ..crypto.key import PlaintextKey, AuthenticatedKey, Blake2AuthenticatedKey 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+from ..crypto.key import RepoKey, KeyfileKey, Blake2RepoKey, Blake2KeyfileKey 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+from ..crypto.key import AESOCBRepoKey, AESOCBKeyfileKey, CHPORepoKey, CHPOKeyfileKey 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+from ..crypto.key import Blake2AESOCBRepoKey, Blake2AESOCBKeyfileKey, Blake2CHPORepoKey, Blake2CHPOKeyfileKey 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 from ..crypto.key import ID_HMAC_SHA_256, ID_BLAKE2b_256 
														 | 
														
														 | 
														
															 from ..crypto.key import ID_HMAC_SHA_256, ID_BLAKE2b_256 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 from ..crypto.key import TAMRequiredError, TAMInvalid, TAMUnsupportedSuiteError, UnsupportedManifestError, UnsupportedKeyFormatError 
														 | 
														
														 | 
														
															 from ..crypto.key import TAMRequiredError, TAMInvalid, TAMUnsupportedSuiteError, UnsupportedManifestError, UnsupportedKeyFormatError 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 from ..crypto.key import identify_key 
														 | 
														
														 | 
														
															 from ..crypto.key import identify_key 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -76,16 +77,17 @@ class TestKey: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         return tmpdir 
														 | 
														
														 | 
														
															         return tmpdir 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     @pytest.fixture(params=( 
														 | 
														
														 | 
														
															     @pytest.fixture(params=( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        # not encrypted 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         PlaintextKey, 
														 | 
														
														 | 
														
															         PlaintextKey, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        AuthenticatedKey, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        KeyfileKey, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        RepoKey, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        AuthenticatedKey, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        Blake2KeyfileKey, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        Blake2RepoKey, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        Blake2AuthenticatedKey, 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        AuthenticatedKey, Blake2AuthenticatedKey, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        # legacy crypto 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        KeyfileKey, Blake2KeyfileKey, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        RepoKey, Blake2RepoKey, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        # new crypto 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         AESOCBKeyfileKey, AESOCBRepoKey, 
														 | 
														
														 | 
														
															         AESOCBKeyfileKey, AESOCBRepoKey, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        Blake2AESOCBKeyfileKey, Blake2AESOCBRepoKey, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         CHPOKeyfileKey, CHPORepoKey, 
														 | 
														
														 | 
														
															         CHPOKeyfileKey, CHPORepoKey, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        Blake2CHPOKeyfileKey, Blake2CHPORepoKey, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     )) 
														 | 
														
														 | 
														
															     )) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     def key(self, request, monkeypatch): 
														 | 
														
														 | 
														
															     def key(self, request, monkeypatch): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         monkeypatch.setenv('BORG_PASSPHRASE', 'test') 
														 | 
														
														 | 
														
															         monkeypatch.setenv('BORG_PASSPHRASE', 'test') 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -143,33 +145,21 @@ class TestKey: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         id = key.id_hash(chunk) 
														 | 
														
														 | 
														
															         id = key.id_hash(chunk) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         assert chunk == key2.decrypt(id, key.encrypt(id, chunk)) 
														 | 
														
														 | 
														
															         assert chunk == key2.decrypt(id, key.encrypt(id, chunk)) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    def test_keyfile_nonce_rollback_protection(self, monkeypatch, keys_dir): 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        monkeypatch.setenv('BORG_PASSPHRASE', 'test') 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        repository = self.MockRepository() 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        with open(os.path.join(get_security_dir(repository.id_str), 'nonce'), "w") as fd: 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-            fd.write("0000000000002000") 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        key = KeyfileKey.create(repository, self.MockArgs()) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        chunk = b'ABC' 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        id = key.id_hash(chunk) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        data = key.encrypt(id, chunk) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        assert key.cipher.extract_iv(data) == 0x2000 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        assert key.decrypt(id, data) == chunk 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															- 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     def test_keyfile_kfenv(self, tmpdir, monkeypatch): 
														 | 
														
														 | 
														
															     def test_keyfile_kfenv(self, tmpdir, monkeypatch): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         keyfile = tmpdir.join('keyfile') 
														 | 
														
														 | 
														
															         keyfile = tmpdir.join('keyfile') 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         monkeypatch.setenv('BORG_KEY_FILE', str(keyfile)) 
														 | 
														
														 | 
														
															         monkeypatch.setenv('BORG_KEY_FILE', str(keyfile)) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         monkeypatch.setenv('BORG_PASSPHRASE', 'testkf') 
														 | 
														
														 | 
														
															         monkeypatch.setenv('BORG_PASSPHRASE', 'testkf') 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         assert not keyfile.exists() 
														 | 
														
														 | 
														
															         assert not keyfile.exists() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        key = KeyfileKey.create(self.MockRepository(), self.MockArgs()) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        key = CHPOKeyfileKey.create(self.MockRepository(), self.MockArgs()) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         assert keyfile.exists() 
														 | 
														
														 | 
														
															         assert keyfile.exists() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         chunk = b'ABC' 
														 | 
														
														 | 
														
															         chunk = b'ABC' 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         chunk_id = key.id_hash(chunk) 
														 | 
														
														 | 
														
															         chunk_id = key.id_hash(chunk) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         chunk_cdata = key.encrypt(chunk_id, chunk) 
														 | 
														
														 | 
														
															         chunk_cdata = key.encrypt(chunk_id, chunk) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        key = KeyfileKey.detect(self.MockRepository(), chunk_cdata) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        key = CHPOKeyfileKey.detect(self.MockRepository(), chunk_cdata) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         assert chunk == key.decrypt(chunk_id, chunk_cdata) 
														 | 
														
														 | 
														
															         assert chunk == key.decrypt(chunk_id, chunk_cdata) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         keyfile.remove() 
														 | 
														
														 | 
														
															         keyfile.remove() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         with pytest.raises(FileNotFoundError): 
														 | 
														
														 | 
														
															         with pytest.raises(FileNotFoundError): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-            KeyfileKey.detect(self.MockRepository(), chunk_cdata) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            CHPOKeyfileKey.detect(self.MockRepository(), chunk_cdata) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     def test_keyfile2(self, monkeypatch, keys_dir): 
														 | 
														
														 | 
														
															     def test_keyfile2(self, monkeypatch, keys_dir): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         with keys_dir.join('keyfile').open('w') as fd: 
														 | 
														
														 | 
														
															         with keys_dir.join('keyfile').open('w') as fd: 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -275,7 +265,7 @@ class TestTAM: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     @pytest.fixture 
														 | 
														
														 | 
														
															     @pytest.fixture 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     def key(self, monkeypatch): 
														 | 
														
														 | 
														
															     def key(self, monkeypatch): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         monkeypatch.setenv('BORG_PASSPHRASE', 'test') 
														 | 
														
														 | 
														
															         monkeypatch.setenv('BORG_PASSPHRASE', 'test') 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        return KeyfileKey.create(TestKey.MockRepository(), TestKey.MockArgs()) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        return CHPOKeyfileKey.create(TestKey.MockRepository(), TestKey.MockArgs()) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     def test_unpack_future(self, key): 
														 | 
														
														 | 
														
															     def test_unpack_future(self, key): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         blob = b'\xc1\xc1\xc1\xc1foobar' 
														 | 
														
														 | 
														
															         blob = b'\xc1\xc1\xc1\xc1foobar' 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -385,7 +375,7 @@ class TestTAM: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 def test_decrypt_key_file_unsupported_algorithm(): 
														 | 
														
														 | 
														
															 def test_decrypt_key_file_unsupported_algorithm(): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     """We will add more algorithms in the future. We should raise a helpful error.""" 
														 | 
														
														 | 
														
															     """We will add more algorithms in the future. We should raise a helpful error.""" 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    key = KeyfileKey(None) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    key = CHPOKeyfileKey(None) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     encrypted = msgpack.packb({ 
														 | 
														
														 | 
														
															     encrypted = msgpack.packb({ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         'algorithm': 'THIS ALGORITHM IS NOT SUPPORTED', 
														 | 
														
														 | 
														
															         'algorithm': 'THIS ALGORITHM IS NOT SUPPORTED', 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         'version': 1, 
														 | 
														
														 | 
														
															         'version': 1, 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -397,7 +387,7 @@ def test_decrypt_key_file_unsupported_algorithm(): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 def test_decrypt_key_file_v2_is_unsupported(): 
														 | 
														
														 | 
														
															 def test_decrypt_key_file_v2_is_unsupported(): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     """There may eventually be a version 2 of the format. For now we should raise a helpful error.""" 
														 | 
														
														 | 
														
															     """There may eventually be a version 2 of the format. For now we should raise a helpful error.""" 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    key = KeyfileKey(None) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    key = CHPOKeyfileKey(None) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     encrypted = msgpack.packb({ 
														 | 
														
														 | 
														
															     encrypted = msgpack.packb({ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         'version': 2, 
														 | 
														
														 | 
														
															         'version': 2, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     }) 
														 | 
														
														 | 
														
															     }) 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -415,10 +405,10 @@ def test_key_file_roundtrip(monkeypatch, cli_argument, expected_algorithm): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     repository = MagicMock(id=b'repository_id') 
														 | 
														
														 | 
														
															     repository = MagicMock(id=b'repository_id') 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     monkeypatch.setenv('BORG_PASSPHRASE', "hello, pass phrase") 
														 | 
														
														 | 
														
															     monkeypatch.setenv('BORG_PASSPHRASE', "hello, pass phrase") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    save_me = RepoKey.create(repository, args=MagicMock(key_algorithm=cli_argument)) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    save_me = AESOCBRepoKey.create(repository, args=MagicMock(key_algorithm=cli_argument)) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     saved = repository.save_key.call_args.args[0] 
														 | 
														
														 | 
														
															     saved = repository.save_key.call_args.args[0] 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     repository.load_key.return_value = saved 
														 | 
														
														 | 
														
															     repository.load_key.return_value = saved 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    load_me = RepoKey.detect(repository, manifest_data=None) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    load_me = AESOCBRepoKey.detect(repository, manifest_data=None) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     assert to_dict(load_me) == to_dict(save_me) 
														 | 
														
														 | 
														
															     assert to_dict(load_me) == to_dict(save_me) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     assert msgpack.unpackb(a2b_base64(saved))['algorithm'] == expected_algorithm 
														 | 
														
														 | 
														
															     assert msgpack.unpackb(a2b_base64(saved))['algorithm'] == expected_algorithm 
														 |