def get_recovery_key(session, user_tid, user_id, user_cc): user = db_get_user(session, user_tid, user_id) if not user.crypto_rec_key: return '' return Base32Encoder().encode(GCE.asymmetric_decrypt(user_cc, user.crypto_rec_key)).replace(b'=', b'')
def validate_password_reset(session, reset_token, auth_code, recovery_key): """ Retrieves a user given a password reset validation token :param session: An ORM session :param reset_token: A reset token :param auth_code: A two factor authentication code (optional) :param recovery_key: An encryption recovery key (optional) :return: A descriptor describing the result of the operation """ now = datetime.now() prv_key = '' user = session.query(models.User).filter( models.User.reset_password_token == reset_token, models.User.reset_password_date >= now - timedelta(hours=72) ).one_or_none() # If the authentication token is invalid if user is None: return {'status': 'invalid_reset_token_provided'} # If encryption is enabled require the recovery key if user.crypto_prv_key: try: x = State.TempKeys.pop(user.id, None) if x: enc_key = GCE.derive_key(reset_token.encode(), user.salt) prv_key = GCE.symmetric_decrypt(enc_key, Base64Encoder.decode(x)) else: recovery_key = recovery_key.replace('-', '').upper() + '====' recovery_key = Base32Encoder.decode(recovery_key.encode()) prv_key = GCE.symmetric_decrypt(recovery_key, Base64Encoder.decode(user.crypto_bkp_key)) except: return {'status': 'require_recovery_key'} elif user.two_factor_enable: two_factor_secret = user.two_factor_secret if not pyotp.TOTP(two_factor_secret).verify(auth_code, valid_window=1): return {'status': 'require_two_factor_authentication'} # Token is used, void it out user.reset_password_token = None user.reset_password_date = now # Require password change user.password_change_needed = True session = Sessions.new(user.tid, user.id, user.tid, user.role, user.password_change_needed, user.two_factor_enable, prv_key, user.crypto_escrow_prv_key) return {'status': 'success', 'token': session.id}
def get_recovery_key(session, tid, user_id, user_cc): """ Transaction to get a user recovery key :param session: An ORM session :param tid: The tenant ID :param user_id: The user ID :param user_cc: The user key :return: The recovery key encoded base32 """ user = db_get_user(session, tid, user_id) if not user.crypto_rec_key: return '' return Base32Encoder.encode(GCE.asymmetric_decrypt(user_cc, Base64Encoder.decode(user.crypto_rec_key.encode()))).replace(b'=', b'')
def validate_password_reset(session, tid, reset_token, auth_code, recovery_key): """Retrieves a user given a password reset validation token""" now = datetime.now() prv_key = '' user = session.query(models.User).filter( models.User.reset_password_token == reset_token, models.User.reset_password_date >= now - timedelta(hours=72)).one_or_none() # If the authentication token is invalid if user is None: return {'status': 'invalid_reset_token_provided'} # If encryption is enabled require the recovery key if user.crypto_prv_key: try: recovery_key = recovery_key.replace('-', '').upper() + '====' recovery_key = Base32Encoder().decode(recovery_key.encode('utf-8')) prv_key = GCE.symmetric_decrypt(recovery_key, user.crypto_bkp_key) except: return {'status': 'require_recovery_key'} elif user.two_factor_enable: two_factor_secret = user.two_factor_secret.decode('utf-8') if not pyotp.TOTP(two_factor_secret).verify(auth_code, valid_window=1): return {'status': 'require_two_factor_authentication'} # Token is used, void it out user.reset_password_token = None user.reset_password_date = now user.password_change_needed = True session = Sessions.new(tid, user.id, user.tid, user.role, user.password_change_needed, user.two_factor_enable, prv_key) return {'status': 'success', 'token': session.id}
VALID_PASSWORD1 = 'ACollectionOfDiplomaticHistorySince_1966_ToThe_Pr esentDay#' VALID_PASSWORD2 = VALID_PASSWORD1 VALID_SALT1 = GCE.generate_salt() VALID_SALT2 = GCE.generate_salt() VALID_HASH1 = GCE.hash_password(VALID_PASSWORD1, VALID_SALT1) VALID_HASH2 = GCE.hash_password(VALID_PASSWORD2, VALID_SALT2) VALID_BASE64_IMG = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII=' INVALID_PASSWORD = '******' KEY = GCE.generate_key() USER_KEY = GCE.derive_key(VALID_PASSWORD1, VALID_SALT1) USER_PRV_KEY, USER_PUB_KEY = GCE.generate_keypair() USER_PRV_KEY_ENC = Base64Encoder.encode(GCE.symmetric_encrypt(USER_KEY, USER_PRV_KEY)) USER_BKP_KEY, USER_REC_KEY = GCE.generate_recovery_key(USER_PRV_KEY) USER_REC_KEY_PLAIN = GCE.asymmetric_decrypt(USER_PRV_KEY, Base64Encoder.decode(USER_REC_KEY)) USER_REC_KEY_PLAIN = Base32Encoder.encode(USER_REC_KEY_PLAIN).replace(b'=', b'').decode('utf-8') GCE_orig_generate_key = GCE.generate_key GCE_orig_generate_keypair = GCE.generate_keypair def GCE_mock_generate_key(): return KEY def GCE_mock_generate_keypair(): return USER_PRV_KEY, USER_PUB_KEY setattr(GCE, 'generate_key', GCE_mock_generate_key) setattr(GCE, 'generate_keypair', GCE_mock_generate_keypair) # END MOCKS NECESSARY FOR DETERMINISTIC ENCRYPTION
VALID_PASSWORD1 = u'ACollectionOfDiplomaticHistorySince_1966_ToThe_Pr esentDay#' VALID_PASSWORD2 = VALID_PASSWORD1 VALID_SALT1 = GCE.generate_salt() VALID_SALT2 = GCE.generate_salt() VALID_HASH1 = GCE.hash_password(VALID_PASSWORD1, VALID_SALT1) VALID_HASH2 = GCE.hash_password(VALID_PASSWORD2, VALID_SALT2) VALID_BASE64_IMG = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII=' INVALID_PASSWORD = u'antani' KEY = GCE.generate_key() USER_KEY = GCE.derive_key(VALID_PASSWORD1, VALID_SALT1) USER_PRV_KEY, USER_PUB_KEY = GCE.generate_keypair() USER_PRV_KEY_ENC = GCE.symmetric_encrypt(USER_KEY, USER_PRV_KEY) USER_BKP_KEY, USER_REC_KEY = GCE.generate_recovery_key(USER_PRV_KEY) USER_REC_KEY_PLAIN = GCE.asymmetric_decrypt(USER_PRV_KEY, USER_REC_KEY) USER_REC_KEY_PLAIN = Base32Encoder().encode(USER_REC_KEY_PLAIN).replace(b'=', b'').decode() GCE_orig_generate_key = GCE.generate_key GCE_orig_generate_keypair = GCE.generate_keypair def GCE_mock_generate_key(): return KEY def GCE_mock_generate_keypair(): return USER_PRV_KEY, USER_PUB_KEY setattr(GCE, 'generate_key', GCE_mock_generate_key) setattr(GCE, 'generate_keypair', GCE_mock_generate_keypair) # END MOCKS NECESSARY FOR DETERMINISTIC ENCRYPTION