make crypto.py CLI accept hex-encoded keys again
authorPhilipp Gesang <philipp.gesang@intra2net.com>
Mon, 28 Aug 2017 07:17:41 +0000 (09:17 +0200)
committerThomas Jarosch <thomas.jarosch@intra2net.com>
Mon, 2 Apr 2018 11:34:09 +0000 (13:34 +0200)
Also handle decoding of those keys at the same level as base64
encoded ones.

deltatar/crypto.py

index 843cccf..2012a1a 100755 (executable)
@@ -144,7 +144,7 @@ try:
 except ImportError as exn:
     pass
 
-if __name__ == "__main__": ## Work around the import mechanism’s lest Python’s
+if __name__ == "__main__": ## Work around the import mechanism lest Python’s
     pwd = os.getcwd()      ## preference for local imports causes a cyclical
     ## import (crypto → pylibscrypt → […] → ./tarfile → crypto).
     sys.path = [ p for p in sys.path if p.find ("deltatar") < 0 ]
@@ -616,7 +616,7 @@ def try_decrypt (ifd, off, hdr, secret, ofd=-1):
     if ks == PDTCRYPT_SECRET_PW:
         decr = Decrypt (password=secret [1])
     elif ks == PDTCRYPT_SECRET_KEY:
-        key = binascii.unhexlify (secret [1])
+        key = secret [1]
         decr = Decrypt (key=key)
     else:
         raise RuntimeError
@@ -701,11 +701,17 @@ def make_secret (password=None, key=None):
         if isinstance (key, bytes) is True:
             if len (key) == AES_KEY_SIZE:
                 return (PDTCRYPT_SECRET_KEY, key)
+            if len (key) == AES_KEY_SIZE * 2:
+                try:
+                    key = binascii.unhexlify (key)
+                    return (PDTCRYPT_SECRET_KEY, key)
+                except binascii.Error: # garbage in string
+                    pass
             if len (key) == AES_KEY_SIZE_B64:
                 try:
                     key = base64.b64decode (key)
                     # the base64 processor is very tolerant and allows for
-                    # arbitrary traling and leading data thus the data obtained
+                    # arbitrary trailing and leading data thus the data obtained
                     # must be checked for the proper length
                     if len (key) == AES_KEY_SIZE:
                         return (PDTCRYPT_SECRET_KEY, key)
@@ -1565,7 +1571,7 @@ def depdtcrypt (mode, secret, ins, outs):
         if ks == PDTCRYPT_SECRET_PW:
             decr = Decrypt (password=secret [1], strict_ivs=PDTCRYPT_STRICTIVS)
         elif ks == PDTCRYPT_SECRET_KEY:
-            key = binascii.unhexlify (secret [1])
+            key = secret [1]
             decr = Decrypt (key=key, strict_ivs=PDTCRYPT_STRICTIVS)
         else:
             raise InternalError ("‘%d’ does not specify a valid kind of secret"
@@ -2072,7 +2078,7 @@ def parse_argv (argv):
         if subcommand == PDTCRYPT_SUB_SCRYPT:
             bail ("ERROR: scrypt hash mode requested but no password given")
         elif mode & PDTCRYPT_DECRYPT:
-            bail ("ERROR: encryption requested but no password given")
+            bail ("ERROR: decryption requested but no password given")
 
     if mode & PDTCRYPT_SPLIT and outsspec is None:
         bail ("ERROR: split mode is incompatible with stdout sink "