From 8cd37f3d3dd1bf7a2201dc959eab8bf108d5a01c Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Fri, 7 Apr 2017 09:29:27 +0200 Subject: [PATCH] specify salt and version in ctor when encrypting MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Simplify the signature of Encrypt.next() by removing the salt and version arguments: This will make the encryptor reuse the values it already has which was either passed to or randomly generated by the ctor. Currently there is no case where we’d need to change the salt or version during encryption. When decrypting, the values from the headers are used anyways so nothing changes over there. --- deltatar/crypto.py | 37 +++++++++++++++++-------------------- deltatar/deltatar.py | 15 +++++++++------ deltatar/tarfile.py | 7 +------ 3 files changed, 27 insertions(+), 32 deletions(-) diff --git a/deltatar/crypto.py b/deltatar/crypto.py index 56b7a66..5bfefe7 100755 --- a/deltatar/crypto.py +++ b/deltatar/crypto.py @@ -368,14 +368,14 @@ class Crypto (object): cnt = None # file counter (uint32_t != 0) iv = None # current IV pfx = None # accu for 64 bit fixed parts of IV - password = None + password = None + paramversion = None stats = { "in" : 0 , "out" : 0 , "obj" : 0 } ctsize = -1 ptsize = -1 - paramversion = None info_counter_used = False def __init__ (self, *al, **akv): @@ -419,7 +419,6 @@ class Crypto (object): kdf = kdf_by_version (paramversion) if kdf is not None: self.key, self.nacl = kdf (password, nacl) - self.paramversion = paramversion @@ -448,19 +447,17 @@ class Crypto (object): class Encrypt (Crypto): - curobj = None - hdrdum = None - paramversion = None + lastinfo = None + version = None paramenc = None - def __init__ (self, password, paramversion, nacl=None, + def __init__ (self, password, version, paramversion, nacl=None, counter=AES_GCM_IV_CNT_DATA): if len (password) == 0: raise Exception ("XXX refusing to encrypt with empty password") - self.pfx = [ ] - self.paramversion = paramversion - defs = ENCRYPTION_PARAMETERS.get(self.paramversion) - self.paramenc = defs ["enc"] + self.pfx = [ ] + self.version = version + self.paramenc = ENCRYPTION_PARAMETERS.get (paramversion) ["enc"] super().__init__ (password, paramversion, nacl, counter=counter, nextpfx=lambda: self.pfx.append (os.urandom(8))) @@ -470,8 +467,7 @@ class Encrypt (Crypto): return struct.pack(FMT_I2N_IV, self.pfx [-1], self.cnt) - def next (self, filename, version, nacl, counter=None): - self.curobj = (filename, version, nacl or self.nacl) + def next (self, filename, counter=None): self.iv = self.iv_make () if self.paramenc == "aes-gcm": self.enc = Cipher \ @@ -484,22 +480,23 @@ class Encrypt (Crypto): else: raise Exception ("XXX garbage encryption parameter %d → %r" % (self.paramversion, enc)) - self.hdrdum = hdr_make_dummy (filename) - super().next (self.password, self.paramversion, nacl) + hdrdum = hdr_make_dummy (filename) + self.lastinfo = (filename, hdrdum) + super().next (self.password, self.paramversion, self.nacl) self.set_object_counter (counter if counter is not None else self.cnt + 1) - return self.hdrdum + return hdrdum def done (self, cmpdata): - if cmpdata != self.hdrdum: + filename, hdrdum = self.lastinfo + if cmpdata != hdrdum: raise Exception ("XXX bad sync for writing header") ## we need to converge on a sensible error handling strategy data = self.enc.finalize () self.stats ["out"] += len (data) self.ctsize += len (data) - (filename, version, nacl) = self.curobj - ok, hdr = hdr_from_params (version, self.paramversion, nacl, self.iv, - self.ctsize, self.enc.tag) + ok, hdr = hdr_from_params (self.version, self.paramversion, self.nacl, + self.iv, self.ctsize, self.enc.tag) if ok is False: raise Exception ("XXX error constructing header: %r" % hdr) ## we need to converge on a sensible error handling strategy return data, hdr, self.pfx diff --git a/deltatar/deltatar.py b/deltatar/deltatar.py index 0fa8e48..bd0dc67 100644 --- a/deltatar/deltatar.py +++ b/deltatar/deltatar.py @@ -601,8 +601,10 @@ class DeltaTar(object): # setup for encrypting payload if self.password is not None: - self.crypto_ctx = crypto.Encrypt (self.password, - paramversion=DELTATAR_PARAMETER_VERSION) + self.crypto_ctx = \ + crypto.Encrypt (self.password, + version=DELTATAR_HEADER_VERSION, + paramversion=DELTATAR_PARAMETER_VERSION) # some initialization self.vol_no = 0 @@ -689,8 +691,7 @@ class DeltaTar(object): index_sink = self.open_auxiliary_file(index_path, 'w') # **NOT** an fd if index_sink.encryption is not None: self.nacl = index_sink.encryption.nacl - dummyhdr = index_sink.encryption.next \ - (path, version=DELTATAR_HEADER_VERSION, nacl=self.nacl) + dummyhdr = index_sink.encryption.next (path) index_sink.write (dummyhdr) index_sink.write (index_accu.getvalue ()) index_sink.close () @@ -771,8 +772,10 @@ class DeltaTar(object): # setup for encrypting payload if self.password is not None: - self.crypto_ctx = crypto.Encrypt (self.password, - paramversion=DELTATAR_PARAMETER_VERSION) + self.crypto_ctx = \ + crypto.Encrypt (self.password, + version=DELTATAR_HEADER_VERSION, + paramversion=DELTATAR_PARAMETER_VERSION) # some initialization self.vol_no = 0 diff --git a/deltatar/tarfile.py b/deltatar/tarfile.py index 4143821..62b76f6 100644 --- a/deltatar/tarfile.py +++ b/deltatar/tarfile.py @@ -115,9 +115,6 @@ GNU_FORMAT = 1 # GNU tar format PAX_FORMAT = 2 # POSIX.1-2001 (pax) format DEFAULT_FORMAT = GNU_FORMAT -DELTATAR_HEADER_VERSION = 1 -DELTATAR_PARAMETER_VERSION = 1 - GZ_FMT_HEADER = b"