def __init__(self, key, dir=None, cipher=None, name=None, header_data=None, long_running=False, use_filter=FILTER_MD5): self.cipher = cipher or self.PREFERRED_CIPHER or PREFERRED_CIPHER self.nonce, self.key = self._nonce_and_mutated_key(key) self.header_data = (header_data if header_data is not None else self.EXTRA_DATA) self.encode_buffer = '' if self.cipher == 'aes-128-ctr': self.encryptor = aes_ctr_encryptor(self.key, self.nonce) self.encoder = base64.encodestring self.encode_batches = self.FILTER_BLOCKSIZE elif self.cipher == 'none': self.encryptor = lambda d: d self.encoder = base64.encodestring self.encode_batches = self.FILTER_BLOCKSIZE elif self.cipher == 'broken': self.encoder = self.encryptor = lambda d: d self.encode_batches = None else: self.encoder = self.encryptor = None self.encode_batches = None ChecksummingStreamer.__init__(self, dir=dir, name=name, long_running=long_running, use_filter=use_filter) # These are necessary for two reasons: # # 1. Prevent the public checksum from revealing what was encrypted. # 2. When using malleable encryption modes (such as CTR), make it # infeasable for attackers to generate a checksum that validates # modified data. # # As this is for data at rest, we are not particularly concerned with # oracle attacks. If an attacker has access to your mailpile on disk # while it is in use (so they can inject new messages), there are # other attacks which are both easier and more severe. # self.inner_sha256 = None self.inner_sha = hashlib.sha256() self.inner_sha.update(self.key) self.inner_sha.update(self.nonce or '') self._send_key()