def init_host_key(): from pritunl import settings from pritunl import utils nonce = utils.generate_secret_len(16) nonces_add(nonce) data = { 'n': nonce, 't': int(time.time()), 'h': settings.local.se_host_key, } auth_data = data['n'] + '&' + str(data['t']) + '&' + data['h'] data['a'] = base64.b64encode( hmac.new( settings.local.se_authorize_key, auth_data, hashlib.sha512, ).digest()) gcm = AESGCM(settings.local.se_encryption_key) nonce = os.urandom(12) ciphertext = gcm.encrypt( nonce, json.dumps(data), None, ) nonce64 = base64.b64encode(nonce) nonces_add(nonce64) payload = { 'n': nonce64, 'd': base64.b64encode(ciphertext), } resp = requests.post( 'http://127.0.0.1:9758/key', verify=False, headers={ 'User-Agent': 'pritunl', 'Accept': 'application/json', 'Content-Type': 'application/json', }, data=json.dumps(payload), ) if resp.status_code != 200: raise RequestError('Vault bad status %s' % resp.status_code)
def process(self): from pritunl import settings from pritunl import utils if not len(self._items): return nonce = utils.generate_secret_len(16) nonces_add(nonce) data = { 'n': nonce, 't': int(time.time()), 'i': self._items_data, } gcm = AESGCM(settings.local.se_encryption_key) nonce = os.urandom(12) ciphertext = gcm.encrypt( nonce, json.dumps(data), None, ) nonce64 = base64.b64encode(nonce) nonces_add(nonce64) payload = { 'n': nonce64, 'd': base64.b64encode(ciphertext), } resp = requests.put( 'http://127.0.0.1:9758/process', verify=False, headers={ 'User-Agent': 'pritunl', 'Accept': 'application/json', 'Content-Type': 'application/json', }, data=json.dumps(payload), ) if resp.status_code != 200: raise RequestError('Vault bad status %s' % resp.status_code) crypto_payload = resp.json() crypto_plaintext = gcm.decrypt( base64.b64decode(crypto_payload['n']), base64.b64decode(crypto_payload['d']), None, ) if nonces_contains(crypto_payload['n']): raise RequestError('Vault authorization nonce replay') nonces_add(crypto_payload['n']) crypto_data = json.loads(crypto_plaintext) if nonces_contains(crypto_data['n']): raise RequestError('Vault authorization nonce replay') nonces_add(crypto_data['n']) now = int(time.time()) diff = now - crypto_data['t'] if diff > 10 or diff < -3: raise RequestError('Vault bad timestamp %s' % crypto_data['t']) for item_data in crypto_data['i']: item_id = item_data['c'] + '-' + item_data['i'] + '-' + \ item_data['k'] item = self._items[item_id] item._data = item_data
def init_master_key(cipher_data): prefix = settings.conf.mongodb_collection_prefix or '' client = pymongo.MongoClient(settings.conf.mongodb_uri, connectTimeoutMS=MONGO_CONNECT_TIMEOUT) database = client.get_default_database() settings_db = getattr(database, prefix + 'settings') doc = settings_db.find_one({ '_id': 'se', }) crypto_keys = None if doc and doc['keys']: crypto_keys = doc['keys'] ciphertext = base64.b64decode(cipher_data['c']) plaintext = settings.local.se_client_key.decrypt( ciphertext, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA512()), algorithm=hashes.SHA512(), label=None, ), ) client_key = plaintext.strip() nonce = utils.generate_secret_len(16) nonces_add(nonce) data = { 'n': nonce, 't': int(time.time()), 'h': cipher_data['h'], 's': cipher_data['s'], 'c': client_key, 'o': cipher_data['o'], 'm': cipher_data['m'], } auth_data = data['n'] + '&' + str(data['t']) + '&' + \ data['h'] + '&' + data['s'] + '&' + data['c'] + '&' + \ data['o'] + '&' + data['m'] if crypto_keys: data['k'] = crypto_keys auth_data += '&' + data['k'] data['a'] = base64.b64encode(hmac.new( settings.local.se_authorize_key, auth_data, hashlib.sha512, ).digest()) gcm = AESGCM(settings.local.se_encryption_key) nonce = os.urandom(12) ciphertext = gcm.encrypt( nonce, json.dumps(data), None, ) payload = { 'n': base64.b64encode(nonce), 'd': base64.b64encode(ciphertext), } resp = requests.post( 'http://127.0.0.1:9758/master', verify=False, headers={ 'User-Agent': 'pritunl', 'Accept': 'application/json', 'Content-Type': 'application/json', }, data=json.dumps(payload), ) if resp.status_code != 200: raise RequestError('Vault bad status %s' % resp.status_code) crypto_payload = resp.json() crypto_plaintext = gcm.decrypt( base64.b64decode(crypto_payload['n']), base64.b64decode(crypto_payload['d']), None, ) if nonces_contains(crypto_payload['n']): raise RequestError('Vault authorization nonce replay') nonces_add(crypto_payload['n']) crypto_data = json.loads(crypto_plaintext) now = int(time.time()) diff = now - crypto_data['t'] if diff > 10 or diff < -3: raise RequestError('Vault bad timestamp %s' % crypto_data['t']) crypto_data_auth = crypto_data['n'] + '&' + \ str(crypto_data['t']) + '&' + crypto_data['k'] crypto_data_authr = base64.b64encode(hmac.new( settings.local.se_authorize_key, crypto_data_auth, hashlib.sha512, ).digest()) if not utils.const_compare(crypto_data_authr, crypto_data['a']): raise RequestError('Invalid crypto keys signature') if nonces_contains(crypto_data['n']): raise RequestError('Vault authorization nonce replay') nonces_add(crypto_data['n']) if crypto_data['k'] != crypto_keys: settings_db.update({ '_id': 'se', }, {'$set': { 'keys': crypto_data['k'], }}, upsert=True)