# -*- coding: utf-8 -*- # Copyright (c) 2018 Michael Rasmussen # This file is part of SecureMail. # SecureMail is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # SecureMail is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with SecureMail. If not, see . import pickle from db import DBInterface as DBI from cryptonize import Cryptonize from nacl.public import PublicKey class NoSuchUser(Exception): pass class User: """ Class implementing the backend users """ def __init__(self, key=None): if key is not None: self.load(key) else: self.pubkeys = {} def store(self, key): crypto = Cryptonize() cipher = crypto.symmetric_encrypt(key, pickle.dumps(self)) DBI.store_user(crypto.generate_hash(key), cipher) def load(self, key): crypto = Cryptonize() cipher = DBI.load_user(crypto.generate_hash(key)) if cipher is None: raise NoSuchUser('{0}: User not found'.format(key)) plain = crypto.symmetric_decrypt(key, cipher) try: obj = pickle.loads(plain) self.__dict__.update(obj.__dict__) except pickle.UnpicklingError as e: raise e def add_pubkey(self, email, key): if email not in self.pubkeys: self.pubkeys[email] = key.encode() else: raise KeyError('{0}: Exists'.format(email)) def update_pubkey(self, email, key): self.pubkeys[email] = key.encode() def delete_pubkey(self, email): if email in self.pubkeys: del self.pubkeys[email] def get_pubkey(self, email): if email in self.pubkeys: key = self.pubkeys[email] key = PublicKey(key) else: key = None return key @property def name(self): return self._name @name.setter def name(self, name): self._name = name @property def email(self): return self._email @email.setter def email(self, email): self._email = email @property def pubkeys(self): return self._pubkeys @pubkeys.setter def pubkeys(self, pubkeys): if type(pubkeys) is not type({}): raise ValueError('Not dictionary') self._pubkeys = pubkeys if __name__ == '__main__': try: u = User('test') for attr, value in u.__dict__.items(): print ('{0}: {1}'.format(attr, value)) print ('{0} - {1} - {2}'.format(u.name, u.email, u.pubkeys)) key = '' for i in range(40): key += '{0}'.format(i) u = User() u.name = 'testname1' u.email = 'testname1@securemail.icu' u.pubkeys = {'test': 'some test', 'test1': 'some test 1'} try: u.store(key) except: u = User(key) for attr, value in u.__dict__.items(): print ('{0}: {1}'.format(attr, value)) print ('{0} - {1} - {2}'.format(u.name, u.email, u.pubkeys)) from nacl.public import Box c = Cryptonize() keypair1 = c.get_key_pair() keypair2 = c.get_key_pair() try: u.add_pubkey('test', keypair2[1]) except KeyError: u.update_pubkey('test', keypair2[1]) bob_box = Box(keypair1[0], u.get_pubkey('test')) message = "Kill all humans æøåÅØÆ" encrypted = bob_box.encrypt(message.encode()) alice_box = Box(keypair2[0], keypair1[1]) plaintext = alice_box.decrypt(encrypted) print (plaintext.decode()) # c = Cryptonize() # key = 'æselØre' #c.get_random_key() # cipher = c.symmetric_encrypt(key, pickle.dumps(u)) # obj = pickle.loads(c.symmetric_decrypt(key, cipher)) # for attr, value in obj.__dict__.items(): # print ('{0}: {1}'.format(attr, value)) except NoSuchUser: u = User() u.name = 'testname' u.email = 'testname@securemail.icu' u.store('test') except Exception as e: print (e)