Repository: borgbackup/borg

Issue:
[1.1] and [1.2] Key algorithm forward compatibility
borg 1.3 Introduces a change to the format of our keys (#747). 1.3 will happily work with either format and even allow the user to switch back and forth between the two, but 1.1 and 1.2 will produce an unhelpful error when they encounter the new format:
```
borg info /path/to/repo/
/path/to/repo is not a valid repository. Check repo config.
```

We should make a new release in the 1.1 and 1.2 branches that would implement a more helpful error


Discussion:
1.1-maint and 1.2-maint about a 1.3 repo:
```
/Users/tw/w/borg/repo13 does not have a valid configuration. Check repo config [repository version 2 is not supported by this borg version].
```

This is because the repo version is checked first, before the key is even touched.

I transplanted a key from 1.3 to 1.2, then got this:

```
(borg-env) tw@mba2020 borg % borg list repo12test
Local Exception
Traceback (most recent call last):
  File "/Users/tw/w/borg/src/borg/archiver.py", line 5113, in main
    exit_code = archiver.run(args)
  File "/Users/tw/w/borg/src/borg/archiver.py", line 5044, in run
    return set_ec(func(args))
  File "/Users/tw/w/borg/src/borg/archiver.py", line 170, in wrapper
    kwargs['manifest'], kwargs['key'] = Manifest.load(repository, compatibility)
  File "/Users/tw/w/borg/src/borg/helpers/manifest.py", line 187, in load
    key = key_factory(repository, cdata)
  File "/Users/tw/w/borg/src/borg/crypto/key.py", line 134, in key_factory
    return identify_key(manifest_data).detect(repository, manifest_data)
  File "/Users/tw/w/borg/src/borg/crypto/key.py", line 590, in detect
    if not key.load(target, passphrase):
  File "/Users/tw/w/borg/src/borg/crypto/key.py", line 814, in load
    success = self._load(key_data, passphrase)
  File "/Users/tw/w/borg/src/borg/crypto/key.py", line 612, in _load
    data = self.decrypt_key_file(cdata, passphrase)
  File "/Users/tw/w/borg/src/borg/crypto/key.py", line 633, in decrypt_key_file
    assert enc_key.algorithm == 'sha256'
AssertionError

Platform: Darwin mba2020.fritz.box 21.4.0 Darwin Kernel Version 21.4.0: Fri Mar 18 00:47:26 PDT 2022; root:xnu-8020.101.4~15/RELEASE_ARM64_T8101 arm64
Borg: 1.2.1.dev104+g55f90286  Python: CPython 3.9.12 msgpack: 1.0.3 fuse: None [pyfuse3,llfuse]
PID: 45226  CWD: /Users/tw/w/borg
sys.argv: ['/Users/tw/w/borg-env/bin/borg', 'list', 'repo12test']
SSH_ORIGINAL_COMMAND: None

```

Resolving patch:
diff --git a/src/borg/crypto/key.py b/src/borg/crypto/key.py
--- a/src/borg/crypto/key.py
+++ b/src/borg/crypto/key.py
@@ -614,7 +614,7 @@ def _load(self, key_data, passphrase):
             data = msgpack.unpackb(data)
             key = Key(internal_dict=data)
             if key.version != 1:
-                raise IntegrityError('Invalid key file header')
+                raise Error("key version %d is not supported by this borg version.")
             self.repository_id = key.repository_id
             self.enc_key = key.enc_key
             self.enc_hmac_key = key.enc_hmac_key
@@ -629,8 +629,10 @@ def decrypt_key_file(self, data, passphrase):
         unpacker.feed(data)
         data = unpacker.unpack()
         enc_key = EncryptedKey(internal_dict=data)
-        assert enc_key.version == 1
-        assert enc_key.algorithm == 'sha256'
+        if enc_key.version != 1:
+            raise Error("encrypted key version %d is not supported by this borg version." % enc_key.version)
+        if enc_key.algorithm != 'sha256':
+            raise Error("encrypted key algorithm '%s' is not supported by this borg version." % enc_key.algorithm)
         key = passphrase.kdf(enc_key.salt, enc_key.iterations, 32)
         data = AES(key, b'\0'*16).decrypt(enc_key.data)
         if hmac.compare_digest(hmac_sha256(key, data), enc_key.hash):


Test patch: