clicada/clicada/cli/auth.py

76 lines
2.0 KiB
Python

# standard imports
import os
import hashlib
import logging
# external imports
import gnupg
from usumbufu.client.hoba import HobaClientSession
# local imports
from clicada.error import AuthError
logg = logging.getLogger(__name__)
class PGPAuthCrypt(HobaClientSession):
typ = 'gnupg'
alg = '969'
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()
def sign_auth_challenge(self, plaintext, hoba, encoding):
r = self.gpg.sign(plaintext, passphrase=self.passphrase, detach=True)
if encoding == 'base64':
r = r.data
hoba.signature = r
return str(hoba)
def __str__(self):
return 'clicada hoba/pgp auth'
def __repr__(self):
return 'clicada hoba/pgp auth'