54 lines
1.5 KiB
Python
54 lines
1.5 KiB
Python
|
# standard imports
|
||
|
import os
|
||
|
import hashlib
|
||
|
import logging
|
||
|
|
||
|
# external imports
|
||
|
import gnupg
|
||
|
|
||
|
# local imports
|
||
|
from clicada.error import AuthError
|
||
|
|
||
|
logg = logging.getLogger(__name__)
|
||
|
|
||
|
|
||
|
class PGPAuthCrypt:
|
||
|
|
||
|
def __init__(self, db_dir, auth_key, pgp_dir=None):
|
||
|
self.db_dir = db_dir
|
||
|
try:
|
||
|
bytes.fromhex(auth_key)
|
||
|
except TypeError:
|
||
|
raise AuthError('invalid key {}'.format(auth_key))
|
||
|
except ValueError:
|
||
|
raise AuthError('invalid key {}'.format(auth_key))
|
||
|
self.auth_key = auth_key
|
||
|
self.gpg = gnupg.GPG(gnupghome=pgp_dir)
|
||
|
|
||
|
|
||
|
def get_secret(self, passphrase=''):
|
||
|
if passphrase == None:
|
||
|
passphrase = ''
|
||
|
p = os.path.join(self.db_dir, '.secret')
|
||
|
try:
|
||
|
f = open(p, 'rb')
|
||
|
except FileNotFoundError:
|
||
|
h = hashlib.sha256()
|
||
|
h.update(bytes.fromhex(self.auth_key))
|
||
|
h.update(passphrase.encode('utf-8'))
|
||
|
z = h.digest()
|
||
|
secret = self.gpg.encrypt(z, [self.auth_key])
|
||
|
if not secret.ok:
|
||
|
raise AuthError('could not encrypt secret for {}'.format(auth_key))
|
||
|
|
||
|
d = os.path.dirname(p)
|
||
|
os.makedirs(d, exist_ok=True)
|
||
|
f = open(p, 'wb')
|
||
|
f.write(secret.data)
|
||
|
f.close()
|
||
|
f = open(p, 'rb')
|
||
|
self.secret = self.gpg.decrypt_file(f, passphrase=passphrase)
|
||
|
if not self.secret.ok:
|
||
|
raise AuthError('could not decrypt encryption secret. wrong password?')
|
||
|
f.close()
|