From 7b3940e51424e8571cd916fb0919dd66f5d85477 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Fri, 23 Jun 2017 10:35:08 +0200 Subject: [PATCH] add crypto.py option to output cnf-compatible scrypt object --- deltatar/crypto.py | 62 +++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 47 insertions(+), 15 deletions(-) diff --git a/deltatar/crypto.py b/deltatar/crypto.py index 5841830..18b72f5 100755 --- a/deltatar/crypto.py +++ b/deltatar/crypto.py @@ -126,6 +126,7 @@ first object doesn’t necessarily apply to any of the subsequent objects. """ +import base64 import binascii import bisect import ctypes @@ -1233,6 +1234,14 @@ SELF = None PDTCRYPT_DEFAULT_VER = 1 PDTCRYPT_DEFAULT_PVER = 1 +# scrypt hashing output control +PDTCRYPT_SCRYPT_INTRANATOR = 0 +PDTCRYPT_SCRYPT_PARAMETERS = 1 + +PDTCRYPT_SCRYPT_FORMAT = \ + { "i2n" : PDTCRYPT_SCRYPT_INTRANATOR + , "params" : PDTCRYPT_SCRYPT_PARAMETERS } + class PDTDecryptionError (Exception): """Decryption failed.""" @@ -1492,14 +1501,15 @@ def mode_depdtcrypt (mode, secret, ins, outs): return 0 -def mode_scrypt (pw, ins=None, nacl=None): +def mode_scrypt (pw, ins=None, nacl=None, fmt=PDTCRYPT_SCRYPT_INTRANATOR): hsh = None + paramversion = PDTCRYPT_DEFAULT_PVER if ins is not None: hsh, nacl, version, paramversion = scrypt_hashsource (pw, ins) defs = ENCRYPTION_PARAMETERS.get(paramversion, None) else: nacl = binascii.unhexlify (nacl) - defs = ENCRYPTION_PARAMETERS.get(PDTCRYPT_DEFAULT_PVER, None) + defs = ENCRYPTION_PARAMETERS.get(paramversion, None) version = PDTCRYPT_DEFAULT_VER kdfname, params = defs ["kdf"] @@ -1508,16 +1518,26 @@ def mode_scrypt (pw, ins=None, nacl=None): hsh, _void = kdf (pw, nacl) import json - out = json.dumps ({ "salt" : binascii.hexlify (nacl).decode () - , "hash" : binascii.hexlify (hsh).decode () - , "version" : version - , "scrypt_params" : { "N" : params ["N"] - , "r" : params ["r"] - , "p" : params ["p"] - , "dkLen" : params ["dkLen"] } }) + + if fmt == PDTCRYPT_SCRYPT_INTRANATOR: + out = json.dumps ({ "salt" : base64.b64encode (nacl).decode () + , "key" : base64.b64encode (hsh) .decode () + , "paramversion" : paramversion }) + elif fmt == PDTCRYPT_SCRYPT_PARAMETERS: + out = json.dumps ({ "salt" : binascii.hexlify (nacl).decode () + , "key" : binascii.hexlify (hsh) .decode () + , "version" : version + , "scrypt_params" : { "N" : params ["N"] + , "r" : params ["r"] + , "p" : params ["p"] + , "dkLen" : params ["dkLen"] } }) + else: + raise RuntimeError ("bad scrypt output scheme %r" % fmt) + print (out) + def usage (err=False): out = print if err is True: @@ -1529,6 +1549,7 @@ def usage (err=False): out (" %s [ { -n | --nacl } { SALT } ]" % indent) out (" %s [ { -o | --out } { - | DESTINATION } ]" % indent) out (" %s [ -D | --no-decrypt ] [ -S | --split ]" % indent) + out (" %s [ -f | --format ]" % indent) out ("") out ("\twhere") out ("\t\tSUBCOMMAND main mode: { process | scrypt }") @@ -1545,6 +1566,7 @@ def usage (err=False): out ("\t\t-S split into files at object boundaries; this") out ("\t\t requires DESTINATION to refer to directory") out ("\t\t-D PDT header and ciphertext passthrough") + out ("\t\t-f format of SCRYPT hash output (“default” or “parameters”)") out ("") out ("\tinstead of filenames, “-” may used to specify stdin / stdout") out ("") @@ -1560,11 +1582,12 @@ def bail (msg): def parse_argv (argv): global SELF - mode = PDTCRYPT_DECRYPT - secret = None - insspec = None - outsspec = None - nacl = None + mode = PDTCRYPT_DECRYPT + secret = None + insspec = None + outsspec = None + nacl = None + scrypt_format = None argvi = iter (argv) SELF = os.path.basename (next (argvi)) @@ -1633,6 +1656,14 @@ def parse_argv (argv): if arg in [ "-n", "--nacl", "--salt" ]: nacl = checked_arg () if PDTCRYPT_VERBOSE is True: noise ("PDT: salt key with %s" % nacl) + elif arg in [ "-f", "--format" ]: + arg = checked_arg () + try: + scrypt_format = PDTCRYPT_SCRYPT_FORMAT [arg] + except KeyError: + bail ("ERROR: invalid scrypt output format %s" % arg) + if PDTCRYPT_VERBOSE is True: + noise ("PDT: scrypt output format “%s”" % scrypt_format) else: bail ("ERROR: unexpected positional argument “%s”" % arg) @@ -1670,7 +1701,8 @@ def parse_argv (argv): ins = deptdcrypt_mk_stream (PDTCRYPT_SOURCE, insspec or "-") if subcommand == PDTCRYPT_SUB_SCRYPT: - return True, partial (mode_scrypt, secret [1].encode (), ins, nacl) + return True, partial (mode_scrypt, secret [1].encode (), ins, nacl, + fmt=scrypt_format) if mode & PDTCRYPT_SPLIT: # destination must be directory if outsspec is None or outsspec == "-": -- 1.7.1