diff options
author | drebs <drebs@leap.se> | 2012-12-24 10:14:24 -0200 |
---|---|---|
committer | drebs <drebs@leap.se> | 2012-12-24 10:14:24 -0200 |
commit | ca5fb41a55e1292005ed186baf3710831d9ad678 (patch) | |
tree | ac7eb9e8f5d993732e769607903ef626518749cd /src/leap/soledad/__init__.py | |
parent | 564b82fa30ebcd8a0abfea54e00506dd77446a54 (diff) | |
parent | 277f17aa7b7bbcc48583149a3d72d8621f83c0ff (diff) |
Merge branch 'feature/u1db-openstack-backend' into develop
Diffstat (limited to 'src/leap/soledad/__init__.py')
-rw-r--r-- | src/leap/soledad/__init__.py | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/leap/soledad/__init__.py b/src/leap/soledad/__init__.py new file mode 100644 index 00000000..6a3707ea --- /dev/null +++ b/src/leap/soledad/__init__.py @@ -0,0 +1,87 @@ +# License? + +"""A U1DB implementation for using Object Stores as its persistence layer.""" + +import os +import string +import random +import cStringIO +import hmac +from soledad.util import GPGWrapper + +class Soledad(object): + + PREFIX = os.environ['HOME'] + '/.config/leap/soledad' + SECRET_PATH = PREFIX + '/secret.gpg' + GNUPG_HOME = PREFIX + '/gnupg' + SECRET_LENGTH = 50 + + def __init__(self, user_email, gpghome=None): + self._user_email = user_email + if not os.path.isdir(self.PREFIX): + os.makedirs(self.PREFIX) + if not gpghome: + gpghome = self.GNUPG_HOME + self._gpg = GPGWrapper(gpghome=gpghome) + # load OpenPGP keypair + if not self._has_openpgp_keypair(): + self._gen_openpgp_keypair() + self._load_openpgp_keypair() + # load secret + if not self._has_secret(): + self._gen_secret() + self._load_secret() + + def _has_secret(self): + if os.path.isfile(self.SECRET_PATH): + return True + return False + + def _load_secret(self): + try: + with open(self.SECRET_PATH) as f: + self._secret = str(self._gpg.decrypt(f.read())) + except IOError as e: + raise IOError('Failed to open secret file %s.' % self.SECRET_PATH) + + def _gen_secret(self): + self._secret = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(self.SECRET_LENGTH)) + ciphertext = self._gpg.encrypt(self._secret, self._fingerprint, self._fingerprint) + f = open(self.SECRET_PATH, 'w') + f.write(str(ciphertext)) + f.close() + + + def _has_openpgp_keypair(self): + try: + self._gpg.find_key(self._user_email) + return True + except LookupError: + return False + + def _gen_openpgp_keypair(self): + params = self._gpg.gen_key_input( + key_type='RSA', + key_length=4096, + name_real=self._user_email, + name_email=self._user_email, + name_comment='Generated by LEAP Soledad.') + self._gpg.gen_key(params) + + def _load_openpgp_keypair(self): + self._fingerprint = self._gpg.find_key(self._user_email)['fingerprint'] + + def encrypt(self, data, sign=None, passphrase=None, symmetric=False): + return str(self._gpg.encrypt(data, self._fingerprint, sign=sign, + passphrase=passphrase, symmetric=symmetric)) + + def encrypt_symmetric(self, doc_id, data, sign=None): + h = hmac.new(self._secret, doc_id).hexdigest() + return self.encrypt(data, sign=sign, passphrase=h, symmetric=True) + + def decrypt(self, data, passphrase=None, symmetric=False): + return str(self._gpg.decrypt(data, passphrase=passphrase)) + + def decrypt_symmetric(self, doc_id, data): + h = hmac.new(self._secret, doc_id).hexdigest() + return self.decrypt(data, passphrase=h) |