Beispiel #1
0
def keygen():
    data_owner = AttrAuthUser.get_using_jwt_token(request.headers.get("Authorization", None))
    attr_list = request.form.get("attr_list", None)
    api_username = request.form.get("api_username", None)
    device_id = request.form.get("device_id", None)

    arg_check = check_missing_request_argument(
        (attr_list, ATTR_LIST_MISSING_ERROR_MSG),
        (api_username, API_USERNAME_MISSING_ERROR_MSG),
        (device_id, DEVICE_ID_MISSING_ERROR_MSG))
    if arg_check is not True:
        return arg_check

    receiver = AttrAuthUser.get_by_user_name(api_username)
    if receiver is None:
        return http_json_response(False, 400, **{"error": INCORRECT_API_USERNAME_ERROR_MSG})

    attr_list = parse_attr_list(attr_list)
    if not attr_list:
        return http_json_response(False, 400, **{"error": INVALID_ATTR_LIST_ERROR_MSG})

    serialized_private_key = create_private_key(data_owner.master_keypair.data_master,
                                                data_owner.master_keypair.data_public,
                                                attr_list)

    # delegate to receiver of generated key
    old_key = next((k for k in receiver.private_keys if k.challenger == data_owner and k.device_id == int(device_id)), None)
    if old_key:
        db.session.delete(old_key)
    receiver.private_keys.append(PrivateKey(data=serialized_private_key,
                                            challenger=data_owner,
                                            device_id=device_id,
                                            attributes=create_attributes(attr_list)))
    db.session.commit()
    return http_json_response()
Beispiel #2
0
def test_doesnt_have_key_from_owner(app_and_ctx, attr_auth_access_token_two):
    app, ctx = app_and_ctx
    with app.app_context():
        receiver = AttrAuthUser.get_by_id(2)

        owner = AttrAuthUser()

        assert not already_has_key_from_owner(receiver, owner)
Beispiel #3
0
def test_already_has_key_from_owner(app_and_ctx, attr_auth_access_token_one,
                                    attr_auth_access_token_two):
    app, ctx = app_and_ctx
    with app.app_context():
        owner = AttrAuthUser.get_by_id(1)
        receiver = AttrAuthUser.get_by_id(2)

        assert already_has_key_from_owner(receiver, owner)
Beispiel #4
0
def test_get_private_key_based_on_owner_missing():
    decryptor = Mock()
    decryptor.private_keys = [
        PrivateKey(challenger=AttrAuthUser(id=10)),
        PrivateKey(challenger=AttrAuthUser(id=34)),
        PrivateKey(challenger=AttrAuthUser(id=37))
    ]
    owner = AttrAuthUser(id=235)
    with pytest.raises(Exception):
        get_private_key_based_on_owner(decryptor, owner)
Beispiel #5
0
def test_get_private_key_based_on_owner():
    decryptor = Mock()
    expected = PrivateKey(challenger=AttrAuthUser(id=10))
    decryptor.private_keys = [
        PrivateKey(challenger=AttrAuthUser(id=11)), expected,
        PrivateKey(challenger=AttrAuthUser(id=25))
    ]
    owner = expected.challenger
    key = get_private_key_based_on_owner(decryptor, owner)
    assert key == expected
Beispiel #6
0
def test_replace_existing_key(app_and_ctx, attr_auth_access_token_one,
                              attr_auth_access_token_two):
    app, ctx = app_and_ctx
    attr_list = ["TODAY", "TOMORROW"]
    dummy_serialized_key = b'key'
    with app.app_context():
        owner = AttrAuthUser.get_by_id(1)
        receiver = AttrAuthUser.get_by_id(2)

        replace_existing_key(receiver, dummy_serialized_key, owner, attr_list)
        modified_key = receiver.private_keys[0]
        assert modified_key.data == dummy_serialized_key
        assert modified_key.attributes[0].value == "TODAY"
Beispiel #7
0
def decrypt():
    decryptor = AttrAuthUser.get_using_jwt_token(request.headers.get("Authorization", None))
    owner_api_username = request.args.get("api_username", None)
    serialized_ciphertext = request.args.get("ciphertext", None)

    arg_check = check_missing_request_argument(
        (owner_api_username, OWNER_API_USERNAME_MISSING_ERROR_MSG),
        (serialized_ciphertext, CIPHERTEXT_MISSING_ERROR_MSG))
    if arg_check is not True:
        return arg_check

    pairing_group = create_pairing_group()
    cp_abe = create_cp_abe()

    data_owner = db.session.query(AttrAuthUser) \
        .filter(AttrAuthUser.api_username == owner_api_username) \
        .first()
    if data_owner is None:
        return http_json_response(False, 400, **{"error": INVALID_OWNER_API_USERNAME_ERROR_MSG})

    public_key = deserialize_charm_object(data_owner.master_keypair.data_public, pairing_group)
    private_key = deserialize_charm_object(get_private_key_based_on_owner(decryptor, data_owner).data, pairing_group)
    ciphertext = deserialize_charm_object(str.encode(serialized_ciphertext), pairing_group)

    try:
        plaintext = cp_abe.decrypt(public_key, private_key, ciphertext)
    except:
        return http_json_response(False, 400, **{"error": COULD_NOT_DECRYPT_ERROR_MSG})

    # return plaintext
    return http_json_response(**{'plaintext': plaintext.decode("utf-8")})
Beispiel #8
0
def set_username():
    user = AttrAuthUser.get_using_jwt_token(request.headers.get("Authorization", None))
    api_username = request.form.get("api_username", None)

    arg_check = check_missing_request_argument((api_username, API_USERNAME_MISSING_ERROR_MSG))
    if arg_check is not True:
        return arg_check

    if AttrAuthUser.get_by_user_name(api_username) is not None:
        return http_json_response(False, 400, **{"error": API_USERNAME_ALREADY_PRESENT_MSG})

    user.api_username = api_username
    db.session.add(user)
    db.session.commit()

    return http_json_response()
Beispiel #9
0
def delete_account_aa():
    user = AttrAuthUser.get_using_jwt_token(
        request.headers.get('Authorization', ""))
    db.session.delete(user)
    db.session.commit()

    return http_json_response()
Beispiel #10
0
def test_set_username(client, app_and_ctx, attr_auth_access_token_one):
    data = {
        "access_token": attr_auth_access_token_one,
        "api_username": "******"
    }
    assert_got_data_from_post(client, '/attr_auth/set_username', data)

    app, ctx = app_and_ctx
    with app.app_context():
        user = AttrAuthUser.get_by_id(1)
        assert user.api_username == "Changed"

        data = {
            "access_token": attr_auth_access_token_one,
            "api_username": "******"
        }
        assert_got_data_from_post(client, '/attr_auth/set_username', data)
        user = AttrAuthUser.get_by_id(1)
        assert user.api_username == "MartinHeinz"
Beispiel #11
0
def test_keygen_already_has_key_from_owner(client, app_and_ctx,
                                           attr_auth_access_token_one,
                                           attr_auth_access_token_two):
    data = {
        "access_token": attr_auth_access_token_one,
        "attr_list": "1 1-2 1-GUEST",
        "api_username": "******",
        "device_id": "1"
    }
    app, ctx = app_and_ctx
    with app.app_context():
        receiver = AttrAuthUser.get_by_id(2)  # TestUser access_token
        old_private_key = next(key for key in receiver.private_keys
                               if key.challenger_id == 1)
        old_private_key_data = old_private_key.data
        old_private_key_key_update = old_private_key.key_update
        private_keys_num = len(receiver.private_keys)

        assert_got_data_from_post(client, '/attr_auth/user/keygen', data)

        receiver = AttrAuthUser.get_by_id(2)  # TestUser access_token
        new_private_key = next(key for key in sorted(
            receiver.private_keys, key=lambda p: p.key_update, reverse=True)
                               if key.challenger_id == 1)

        assert old_private_key_data != new_private_key.data
        assert old_private_key_key_update < new_private_key.key_update

        assert len(receiver.private_keys) > private_keys_num

        # Try to encrypt and decrypt
        pairing_group = create_pairing_group()
        cp_abe = create_cp_abe()
        plaintext = "Hello World"
        data_owner = AttrAuthUser.get_by_id(1)
        policy_str = '(1-GUEST)'
        public_key = deserialize_charm_object(
            data_owner.master_keypair.data_public, pairing_group)
        new_private_key = deserialize_charm_object(new_private_key.data,
                                                   pairing_group)
        ciphertext = cp_abe.encrypt(public_key, plaintext, policy_str)
        decrypted_msg = cp_abe.decrypt(public_key, new_private_key, ciphertext)
        assert plaintext == decrypted_msg.decode("utf-8")
Beispiel #12
0
def retrieve_private_keys():
    user = AttrAuthUser.get_using_jwt_token(request.headers.get("Authorization", None))

    private_keys = [{
        "data": key.data.decode("utf-8"),
        "key_update": key.key_update,
        "attributes": [a.value for a in key.attributes],
        "challenger_id": key.challenger_id,
        "device_id": key.device_id,

    } for key in user.private_keys]
    return http_json_response(**{'private_keys': private_keys})
Beispiel #13
0
def test_keygen_replaces_old_key(client, app_and_ctx,
                                 attr_auth_access_token_one,
                                 attr_auth_access_token_two):
    data = {
        "access_token": attr_auth_access_token_one,
        "attr_list": "1 1-2 1-GUEST",
        "api_username": "******",
        "device_id": "99"
    }
    app, ctx = app_and_ctx
    with app.app_context():

        assert_got_data_from_post(client, '/attr_auth/user/keygen', data)

        receiver = AttrAuthUser.get_by_id(2)
        old_private_key = next(
            key for key in receiver.private_keys
            if key.challenger_id == 1 and key.device_id == 99)
        old_private_key_data = old_private_key.data
        old_private_key_key_update = old_private_key.key_update
        old_private_keys_num = len(receiver.private_keys)

        assert_got_data_from_post(
            client, '/attr_auth/user/keygen',
            data)  # This should replace old_private_key_data

        receiver = AttrAuthUser.get_by_id(2)
        new_private_key = next(
            key for key in receiver.private_keys
            if key.challenger_id == 1 and key.device_id == 99)
        new_private_key_data = new_private_key.data
        new_private_key_key_update = new_private_key.key_update

        assert old_private_key_data != new_private_key_data
        assert old_private_key_key_update < new_private_key_key_update
        assert old_private_keys_num == len(receiver.private_keys)

        db.session.delete(new_private_key)
        db.session.commit()
Beispiel #14
0
def test_key_setup(client, app_and_ctx, attr_auth_access_token_one):
    data = {"access_token": attr_auth_access_token_one}

    status_code, json_data = get_data_from_get(client, '/attr_auth/setup',
                                               data)
    assert status_code == 200
    serialized_public_key_response = json_data["public_key"]

    app, ctx = app_and_ctx
    with app.app_context():
        serialized_public_key_from_db = AttrAuthUser.get_by_id(
            1).master_keypair.data_public.decode("utf-8")
        assert serialized_public_key_response == serialized_public_key_from_db
Beispiel #15
0
def test_keygen_doesnt_have_key_from_owner(client, app_and_ctx,
                                           attr_auth_access_token_one,
                                           attr_auth_access_token_two):
    data = {
        "access_token": attr_auth_access_token_two,
        "attr_list": "2 2-1 2-GUEST",
        "api_username": "******",
        "device_id": "1"
    }
    app, ctx = app_and_ctx
    with app.app_context():
        receiver = AttrAuthUser.get_by_id(1)

        num_of_old_keys = len(receiver.private_keys)

        assert_got_data_from_post(client, '/attr_auth/user/keygen', data)

        receiver = AttrAuthUser.get_by_id(1)
        new_private_key = next(key for key in receiver.private_keys
                               if key.challenger_id == 2)

        assert len(receiver.private_keys) == num_of_old_keys + 1

        # Try to encrypt and decrypt
        pairing_group = create_pairing_group()
        cp_abe = create_cp_abe()
        plaintext = "Hello World"
        data_owner = AttrAuthUser.get_by_id(2)
        policy_str = '(2-GUEST)'
        public_key = deserialize_charm_object(
            data_owner.master_keypair.data_public, pairing_group)
        new_private_key = deserialize_charm_object(new_private_key.data,
                                                   pairing_group)
        ciphertext = cp_abe.encrypt(public_key, plaintext, policy_str)
        decrypted_msg = cp_abe.decrypt(public_key, new_private_key, ciphertext)
        assert plaintext == decrypted_msg.decode("utf-8")
Beispiel #16
0
def validate_token(bind, token):
    s = Serializer(current_app.config['SECRET_KEY'])
    try:
        data = s.loads(token)
    except SignatureExpired:
        return False  # valid token, but expired
    except BadSignature:
        return False  # invalid token
    if bind is None:
        user = User.get_by_id(data['id'])
    else:
        user = AttrAuthUser.get_by_id(data['id'])

    if user is not None:
        return bcrypt.verify(data["token"], user.access_token)
    return False
Beispiel #17
0
def test_delete_account(client, app_and_ctx):
    server_data = {}
    aa_data = {}
    server_provider_token = "server_token"
    aa_provider_token = "aa_token"

    device_id = 99999
    token_hash = bcrypt.using(rounds=13).hash(server_provider_token)
    aa_token_hash = bcrypt.using(rounds=13).hash(aa_provider_token)

    user = User(access_token=token_hash,
                access_token_update=datetime.now(),
                owned_devices=[
                    Device(id=device_id, name=b"test", correctness_hash="")
                ])
    aa_user = AttrAuthUser(access_token=aa_token_hash,
                           access_token_update=datetime.now())

    db.session.add(aa_user)
    db.session.add(user)
    db.session.commit()

    app, ctx = app_and_ctx

    with app.app_context():
        server_data["access_token"] = generate_auth_token(
            user.id, server_provider_token)
        aa_data["access_token"] = generate_auth_token(user.id,
                                                      aa_provider_token)

    assert db.session.query(User).filter(
        User.access_token == token_hash).first() is not None
    assert db.session.query(Device).filter(
        Device.id == device_id).first() is not None
    assert db.session.query(AttrAuthUser).filter(
        AttrAuthUser.access_token == aa_token_hash).first() is not None

    assert_got_data_from_post(client, '/delete_account', server_data)
    assert_got_data_from_post(client, '/attr_auth/delete_account', aa_data)

    assert db.session.query(User).filter(
        User.access_token == token_hash).first() is None
    assert db.session.query(Device).filter(
        Device.id == device_id).first() is None
    assert db.session.query(AttrAuthUser).filter(
        AttrAuthUser.access_token == aa_token_hash).first() is None
Beispiel #18
0
def key_setup():
    pairing_group = create_pairing_group()
    cp_abe = create_cp_abe()

    public_key, master_key = cp_abe.setup()

    # "store keypair in DB"
    user = AttrAuthUser.get_using_jwt_token(request.headers.get("Authorization", None))

    serialized_public_key = serialize_charm_object(public_key, pairing_group)
    serialized_master_key = serialize_charm_object(master_key, pairing_group)
    user.master_keypair = MasterKeypair(data_public=serialized_public_key,
                                        data_master=serialized_master_key)
    db.session.add(user)
    db.session.commit()

    # return pk, msk
    return http_json_response(**{'public_key': serialized_public_key.decode("utf-8")})
Beispiel #19
0
def encrypt():
    data_owner = AttrAuthUser.get_using_jwt_token(request.headers.get("Authorization", None))
    plaintext = request.args.get("message", None)
    policy_string = request.args.get("policy_string", None)

    arg_check = check_missing_request_argument(
        (plaintext, MESSAGE_MISSING_ERROR_MSG),
        (policy_string, POLICY_STRING_MISSING_ERROR_MSG))
    if arg_check is not True:
        return arg_check

    pairing_group = create_pairing_group()
    cp_abe = create_cp_abe()
    public_key = deserialize_charm_object(data_owner.master_keypair.data_public, pairing_group)
    ciphertext = cp_abe.encrypt(public_key, plaintext, policy_string)

    # return ciphertext
    return http_json_response(**{'ciphertext': serialize_charm_object(ciphertext, pairing_group).decode("utf-8")})
Beispiel #20
0
def device_keygen():
    data_owner = AttrAuthUser.get_using_jwt_token(request.headers.get("Authorization", None))
    attr_list = request.form.get("attr_list", None)

    arg_check = check_missing_request_argument(
        (attr_list, ATTR_LIST_MISSING_ERROR_MSG))
    if arg_check is not True:
        return arg_check

    attr_list = parse_attr_list(attr_list)
    if not attr_list:
        return http_json_response(False, 400, **{"error": INVALID_ATTR_LIST_ERROR_MSG})

    serialized_private_key = create_private_key(data_owner.master_keypair.data_master,
                                                data_owner.master_keypair.data_public,
                                                attr_list)

    # delegate to receiver of generated key
    return http_json_response(private_key=serialized_private_key.decode("utf-8"))
Beispiel #21
0
def save_user(remote, user_info, token):
    user = get_user(remote, user_info)
    if user is None:
        if remote.name == "github":
            user = User(id=user_info["sub"],
                        name=user_info["preferred_username"],
                        email=parse_email(
                            query_github_api(token["access_token"])))
        else:
            user = AttrAuthUser(id=user_info["sub"],
                                name=user_info["preferred_username"])

    db.session.flush()
    user.access_token = bcrypt.using(rounds=13).hash(token["access_token"])
    user.access_token_update = datetime.datetime.utcnow()
    db.session.add(user)
    db.session.commit()

    return generate_auth_token(user.id, token["access_token"])
Beispiel #22
0
# pickle.dump(users, open("users.p", "wb"))

db.session.add_all(users)
db.session.add_all(device_types)
db.session.add_all(devices)
db.session.commit()

aa_users = []

for i, user in enumerate(users):
    access_token = random_string()
    token_hash = bcrypt.using(rounds=13).hash(access_token)
    # noinspection PyArgumentList
    aa_user = AttrAuthUser(name=user.name,
                           id=user.id,
                           access_token=token_hash,
                           access_token_update=random_date(d1, d2),
                           api_username=user.name)
    keypair = MasterKeypair(data_public=keypairs[i][0],
                            data_master=keypairs[i][1],
                            attr_auth_user=aa_user)

    keys["users"][user.id]["aa_access_token"] = generate_auth_token(
        user.id, access_token).decode()

    db.session.add(aa_user)
    db.session.add(keypair)
    db.session.flush()

    attr_list = [
        f"U-{user.id}", f"U-{user.id}-D-{user.owned_devices[0].id}",