Exemplo n.º 1
0
def db_gen_user_keys(session, tid, user, password):
    """
    Transaction generating and saving user keys

    :param session: An ORM session
    :param tid: A tenant ID
    :param user: A user object
    :param password: A user's password
    :return: A private key generated for the user
    """
    enc_key = GCE.derive_key(password.encode(), user.salt)
    crypto_prv_key, user.crypto_pub_key = GCE.generate_keypair()
    user.crypto_bkp_key, user.crypto_rec_key = GCE.generate_recovery_key(
        crypto_prv_key)
    user.crypto_prv_key = Base64Encoder.encode(
        GCE.symmetric_encrypt(enc_key, crypto_prv_key))

    # Create an escrow backup for the root tenant
    tid_1_escrow = config.ConfigFactory(session,
                                        1).get_val('crypto_escrow_pub_key')
    if tid_1_escrow:
        user.crypto_escrow_bkp1_key = Base64Encoder.encode(
            GCE.asymmetric_encrypt(tid_1_escrow, crypto_prv_key))

    # Create an escrow backup for the actual tenant
    tid_n_escrow = config.ConfigFactory(session,
                                        tid).get_val('crypto_escrow_pub_key')
    if tid_n_escrow:
        user.crypto_escrow_bkp2_key = Base64Encoder.encode(
            GCE.asymmetric_encrypt(tid_n_escrow, crypto_prv_key))

    return crypto_prv_key
Exemplo n.º 2
0
def set_user_password(tid, user, password, cc):
    # Regenerate the password hash only if different from the best choice on the platform
    if user.hash_alg != 'ARGON2':
        user.hash_alg = 'ARGON2'
        user.salt = GCE.generate_salt()

    password_hash = GCE.hash_password(password, user.salt)

    # Check that the new password is different form the current password
    if user.password == password_hash:
        raise errors.PasswordReuseError

    user.password = password_hash
    user.password_change_date = datetime_now()

    if not State.tenant_cache[tid].encryption and cc == '':
        return None

    enc_key = GCE.derive_key(password.encode(), user.salt)
    if not cc:
        # The first password change triggers the generation
        # of the user encryption private key and its backup
        cc, user.crypto_pub_key = GCE.generate_keypair()
        user.crypto_bkp_key, user.crypto_rec_key = GCE.generate_recovery_key(cc)

    user.crypto_prv_key = Base64Encoder.encode(GCE.symmetric_encrypt(enc_key, cc))

    if State.tenant_cache[1].crypto_escrow_pub_key:
        user.crypto_escrow_bkp1_key = Base64Encoder.encode(GCE.asymmetric_encrypt(State.tenant_cache[1].crypto_escrow_pub_key, cc))

    if State.tenant_cache[tid].crypto_escrow_pub_key:
        user.crypto_escrow_bkp2_key = Base64Encoder.encode(GCE.asymmetric_encrypt(State.tenant_cache[tid].crypto_escrow_pub_key, cc))

    return cc
Exemplo n.º 3
0
 def test_recovery_key(self):
     prv_key, _ = GCE.generate_keypair()
     bck_key, rec_key = GCE.generate_recovery_key(prv_key)
     plain_rec_key = GCE.asymmetric_decrypt(prv_key,
                                            Base64Encoder.decode(rec_key))
     x = GCE.symmetric_decrypt(plain_rec_key, Base64Encoder.decode(bck_key))
     self.assertEqual(x, prv_key)
Exemplo n.º 4
0
################################################################################
# BEGIN MOCKS NECESSARY FOR DETERMINISTIC ENCRYPTION
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)
Exemplo n.º 5
0
def db_user_update_user(session, tid, user_session, request):
    """
    Updates the specified user.
    This version of the function is specific for users that with comparison with
    admins can change only few things:
      - real name
      - email address
      - preferred language
      - the password (with old password check)
      - pgp key
    raises: globaleaks.errors.ResourceNotFound` if the receiver does not exist.
    """
    from globaleaks.handlers.admin.notification import db_get_notification
    from globaleaks.handlers.admin.node import db_admin_serialize_node

    user = models.db_get(session, models.User,
                         models.User.id == user_session.user_id)

    user.language = request.get('language',
                                State.tenant_cache[tid].default_language)
    user.name = request['name']
    new_password = request['password']
    old_password = request['old_password']

    if new_password:
        if user.password_change_needed:
            user.password_change_needed = False
        else:
            if not GCE.check_password(user.hash_alg, old_password, user.salt,
                                      user.password):
                raise errors.InvalidOldPassword

        # Regenerate the password hash only if different from the best choice on the platform
        if user.hash_alg != GCE.HASH:
            user.hash_alg = GCE.HASH
            user.salt = GCE.generate_salt()

        password_hash = GCE.hash_password(new_password, user.salt)

        # Check that the new password is different form the current password
        if user.password == password_hash:
            raise errors.PasswordReuseError

        user.password = password_hash
        user.password_change_date = datetime_now()

        if State.tenant_cache[tid].encryption:
            enc_key = GCE.derive_key(request['password'].encode(), user.salt)
            if not user_session.cc:
                # Th First first password change triggers the generation
                # of the user encryption private key and its backup
                user_session.cc, user.crypto_pub_key = GCE.generate_keypair()
                user.crypto_bkp_key, user.crypto_rec_key = GCE.generate_recovery_key(
                    user_session.cc)

                # If the user had already enabled two factor before encryption was not enable
                # encrypt the two factor secret
                if user.two_factor_secret:
                    user.two_factor_secret = GCE.asymmetric_encrypt(
                        user.crypto_pub_key, user.two_factor_secret)

            user.crypto_prv_key = GCE.symmetric_encrypt(
                enc_key, user_session.cc)

    # If the email address changed, send a validation email
    if request['mail_address'] != user.mail_address:
        user.change_email_address = request['mail_address']
        user.change_email_date = datetime_now()
        user.change_email_token = generateRandomKey(32)

        user_desc = user_serialize_user(session, user, user.language)

        user_desc['mail_address'] = request['mail_address']

        template_vars = {
            'type': 'email_validation',
            'user': user_desc,
            'new_email_address': request['mail_address'],
            'validation_token': user.change_email_token,
            'node': db_admin_serialize_node(session, tid, user.language),
            'notification': db_get_notification(session, tid, user.language)
        }

        State.format_and_send_mail(session, tid, user_desc, template_vars)

    # If the platform allows users to change PGP keys, process it
    if State.tenant_cache[tid]['enable_user_pgp_key_upload'] is True:
        parse_pgp_options(user, request)

    return user