コード例 #1
0
def _trigger_action_by_nonowner(device_id, device_name, name, token):
    data = {
        "device_name_bi": blind_index(get_device_bi_key(device_id),
                                      device_name),
        "name_bi": blind_index(get_device_bi_key(device_id), name),
        "additional_data": b2a_hex(os.urandom(32)).decode()
    }
    return requests.get(URL_TRIGGER_ACTION,
                        headers={"Authorization": token},
                        params=data,
                        verify=VERIFY_CERTS)
コード例 #2
0
def add_scene_action(scene_name, action_name, device_id, token):
    if not is_global_bi_key_missing(
            create_device, "Blind index key for scene name is missing"):
        data = {
            "scene_name_bi":
            blind_index(get_global_bi_key(), scene_name),
            "action_name_bi":
            blind_index(get_device_bi_key(device_id), action_name),
        }
        r = requests.post(URL_ADD_ACTION_TO_SCENE,
                          headers={"Authorization": token},
                          data=data,
                          verify=VERIFY_CERTS)
        click.echo(r.content.decode('unicode-escape'))
コード例 #3
0
def create_device(device_type_id, device_name, password, token):
    password_hash = pbkdf2_hash(password)
    bi_key = os.urandom(32)
    device_name_key = key_to_hex(
        os.urandom(32))  # NOTE: retrieve key as `key_to_hex(key)`
    device_status_key = key_to_hex(os.urandom(32))
    data = {
        "type_id": device_type_id,
        "name": hex_to_fernet(device_name_key).encrypt(device_name.encode()),
        "correctness_hash": correctness_hash(device_name),
        "name_bi": blind_index(bi_key, device_name),
        "password": password_hash
    }
    r = requests.post(URL_CREATE_DEVICE,
                      headers={"Authorization": token},
                      data=data,
                      verify=VERIFY_CERTS)
    content = json.loads(r.content.decode('unicode-escape'))
    if content["success"]:
        insert_into_tinydb(
            path, 'device_keys', {
                'device_id': str(content["id"]),
                'bi_key': key_to_hex(bi_key),
                'device:name': device_name_key,
                'device:status': device_status_key
            })
    click.echo(r.content.decode('unicode-escape'))
コード例 #4
0
def _trigger_action_by_owner(device_id, device_name, name, token, real):
    data = {
        "device_name_bi": blind_index(get_device_bi_key(device_id),
                                      device_name),
        "name_bi": blind_index(get_device_bi_key(device_id), name),
    }
    if real:
        data["additional_data"] = "real"
    else:
        data["additional_data"] = "fake"

    data["additional_data"] = encrypt_using_fernet_hex(
        get_shared_key_by_device_id(path, device_id),
        data["additional_data"]).decode()
    return requests.get(URL_TRIGGER_ACTION,
                        headers={"Authorization": token},
                        params=data,
                        verify=VERIFY_CERTS)
コード例 #5
0
def revoke_user(device_id, device_name, revoke_user_id, token):
    data = {
        "device_name_bi": blind_index(get_device_bi_key(device_id),
                                      device_name),
        "revoke_user_id": revoke_user_id
    }
    r = requests.post(URL_REVOKE_USER,
                      headers={"Authorization": token},
                      data=data,
                      verify=VERIFY_CERTS)
    click.echo(r.content.decode('unicode-escape'))
コード例 #6
0
def get_device_data(user_id, device_id, device_name, owner, token):
    """
    Queries server for data of :param device_id device and then verifies the received data using
    integrity information from device (received using MQTT Broker) and correctness hash attribute
    of each DB row.
    """
    user_id = int(user_id)
    device_name_bi = blind_index(get_device_bi_key(device_id), device_name)
    data = {"device_name_bi": device_name_bi}

    r = requests.get(URL_GET_DEVICE_DATA,
                     headers={"Authorization": token},
                     params=data,
                     verify=VERIFY_CERTS)
    content = r.content.decode('unicode-escape')
    json_content = json_string_with_bytes_to_dict(content)

    if not json_content["success"]:
        click.echo(json_content["error"])
        return

    if owner:
        _get_fake_tuple_data(user_id, int(device_id))
        decrypted_fake_tuple_data = {
            "device_data":
            json.loads(
                decrypt_using_fernet_hex(
                    get_shared_key_by_device_id(path, device_id),
                    fake_tuple_data["device_data"]).decode())
        }

        fake_tuples, rows = _divide_fake_and_real_data(
            json_content["device_data"], device_id, decrypted_fake_tuple_data)
        # NOTE:      ^ Not checking for ability of user to decrypt (having SK that satisfies Ciphertext) because owner should have keys setup
        #              so that he can decrypt all data from his devices

        verify_integrity_data(
            generate_fake_tuples_in_range(
                decrypted_fake_tuple_data["device_data"]), fake_tuples)
        check_correctness_hash(rows, 'added', 'data', 'num_data', 'tid')

        result = []
        for row in rows:
            try:
                result.append(unpad_row("data", row))
            except Exception as e:
                click.echo(str(e))
        click.echo(result)
    else:
        get_foreign_device_data(device_id, json_content)
コード例 #7
0
def trigger_scene(name, token, real):
    data = {"name_bi": blind_index(get_global_bi_key(), name)}
    if real:
        data["additional_data"] = "real"
    else:
        data["additional_data"] = "fake"

    data["additional_data"] = encrypt_using_fernet_hex(
        key_to_hex(get_global_scene_key()), data["additional_data"]).decode()
    r = requests.get(URL_TRIGGER_SCENE,
                     headers={"Authorization": token},
                     params=data,
                     verify=VERIFY_CERTS)
    click.echo(r.content.decode('unicode-escape'))
コード例 #8
0
def create_row(data, num_data, tid, added):
    user_data = get_user_data()
    encrypted = encrypt_row(
        {
            "added": added,
            "num_data": num_data,
            "data": pad_payload_attr(str(data)),
            "tid": str(tid)
        }, get_key_type_pair(user_data))
    encrypted["correctness_hash"] = correctness_hash(
        added, pad_payload_attr(str(data)), num_data, tid)
    encrypted["tid_bi"] = blind_index(hex_to_key(get_bi_key()), str(tid))

    return encrypted
コード例 #9
0
def get_devices(device_name, device_id, token):
    """Triggered using: ./cli.py -b "172.26.0.8" user get-devices test_device 46 --token 5c36ab84439c55a3c196f4csd9bd7b3d9291f39g"""
    device_name_bi = blind_index(get_device_bi_key(device_id), device_name)
    data = {"name_bi": device_name_bi}
    r = requests.get(URL_GET_DEVICE,
                     headers={"Authorization": token},
                     params=data,
                     verify=VERIFY_CERTS)
    content = json.loads(r.content.decode('unicode-escape'))

    table = get_tinydb_table(path, 'device_keys')

    for device in content["devices"]:
        ciphertext = device["name"]
        doc = table.get(Query().device_id == str(device["id"]))
        plaintext = decrypt_using_fernet_hex(doc["device:name"], ciphertext)
        device["name"] = plaintext.decode()

    check_correctness_hash(content["devices"], "name")
    click.echo(content["devices"])
コード例 #10
0
def get_fake_tuple(bound):
    try:
        table = get_tinydb_table(path, 'users')
        doc = get_user_data()

        if bound == "lower_bound" and not can_remove_fake_row(
                doc["integrity"]["device_data"]):
            return  # "Can't remove row that was not yet inserted (lower bound equals upper bound)"

        fake_tuple = {**generate(doc["integrity"]["device_data"], bound=bound)}
        fake_tuple["data"] = pad_payload_attr(str(fake_tuple["data"]),
                                              fake=True)

        keys = get_key_type_pair(doc)

        fake_tuple_hash = correctness_hash([
            fake_tuple["added"], fake_tuple["data"], fake_tuple["num_data"],
            fake_tuple["tid"]
        ])
        encrypted_fake_tuple = encrypt_row(fake_tuple, keys)
        row = {
            **encrypted_fake_tuple, "correctness_hash": fake_tuple_hash,
            "tid_bi": blind_index(hex_to_key(get_bi_key()),
                                  str(fake_tuple["tid"]))
        }

        if bound == "upper_bound":
            doc["integrity"]["device_data"] = increment_bounds(
                doc["integrity"]["device_data"])
        if bound == "lower_bound":
            doc["integrity"]["device_data"] = increment_bounds(
                doc["integrity"]["device_data"], bound=bound)

        payload = dict_to_payload(**row)
        table.update(doc)
        click.echo(payload)

    except Exception as e:  # pragma: no exc cover
        _, _, exc_tb = sys.exc_info()
        line = exc_tb.tb_lineno
        click.echo(f"{repr(e)} at line: {line}")
コード例 #11
0
def create_scene(name, description, token):
    if not is_global_bi_key_missing(
            init_global_keys, "Blind index key for scene name is missing"):
        if len(get_tinydb_table(path, 'scene_keys')) == 0:
            init_scene_keys()
        table = get_tinydb_table(path, 'scene_keys')
        doc = table.all()[0]
        name_ciphertext = encrypt_using_fernet_hex(doc["name"], name)
        desc_ciphertext = encrypt_using_fernet_hex(doc["description"],
                                                   description)
        data = {
            "name": name_ciphertext,
            "correctness_hash": correctness_hash(name),
            "name_bi": blind_index(get_global_bi_key(), name),
            "description": desc_ciphertext
        }
        r = requests.post(URL_CREATE_SCENE,
                          headers={"Authorization": token},
                          data=data,
                          verify=VERIFY_CERTS)
        click.echo(r.content.decode('unicode-escape'))
コード例 #12
0
def set_action(device_id, name, token):
    doc = search_tinydb_doc(path, 'device_keys',
                            Query().device_id == str(device_id))
    if not doc:
        with click.Context(send_column_keys) as ctx:
            click.echo(
                f"Keys for device {device_id} not present, please use: {ctx.command.name}"
            )
            click.echo(send_column_keys.get_help(ctx))
            return

    data = {
        "device_id": device_id,
        "name": encrypt_using_fernet_hex(doc["action:name"], name),
        "correctness_hash": correctness_hash(name),
        "name_bi": blind_index(get_device_bi_key(device_id), name)
    }
    r = requests.post(URL_SET_ACTION,
                      headers={"Authorization": token},
                      data=data,
                      verify=VERIFY_CERTS)
    click.echo(r.content.decode('unicode-escape'))
コード例 #13
0
def create_data():
    dal = setup()
    session = dal.Session()

    Base.metadata.drop_all(dal.engine)
    Base.metadata.create_all(dal.engine)

    rows = []
    rows_num = 10000
    global searched_row
    global searched_name

    for i in range(1, rows_num):
        name = ''.join(random.choices(string.ascii_uppercase + string.digits, k=10))
        if i == searched_row:
            searched_name = name
        rows.append(BlindIndex(
            id=i,
            name=name,
            name_bi=blind_index(key, name)
        ))

    session.add_all(rows)
    session.commit()
コード例 #14
0
def get_device_data_by_num_range(user_id,
                                 device_id,
                                 device_name,
                                 lower=None,
                                 upper=None,
                                 token=""):
    if lower is not None and upper is not None and upper <= lower:
        click.echo("Upper bound needs to be greater then lower bound.")
        return
    device_name_bi = blind_index(get_device_bi_key(device_id), device_name)
    if lower is not None and upper is not None:
        data = {
            "lower": int(lower),
            "upper": int(upper),
            "device_name_bi": device_name_bi
        }
    elif lower is not None and upper is None:
        upper = 214748364700  # 100000000000
        data = {"lower": int(lower), "device_name_bi": device_name_bi}
    elif lower is None and upper is not None:
        lower = -214748364800  # -100000000000
        data = {"upper": int(upper), "device_name_bi": device_name_bi}
    else:
        lower = -214748364800  # -100000000000
        upper = 214748364700  # 100000000000
        data = {
            "lower": lower,
            "upper": upper,
            "device_name_bi": device_name_bi
        }
    r = requests.get(URL_GET_DEVICE_DATA_BY_RANGE,
                     headers={"Authorization": token},
                     params=data,
                     verify=VERIFY_CERTS)
    content = r.content.decode('unicode-escape')
    json_content = json_string_with_bytes_to_dict(content)

    _get_fake_tuple_data(int(user_id), int(device_id))
    decrypted_fake_tuple_data = {
        "device_data":
        json.loads(
            decrypt_using_fernet_hex(
                get_shared_key_by_device_id(path, device_id),
                fake_tuple_data["device_data"]).decode())
    }

    fake_tuples, rows = _divide_fake_and_real_data(json_content["device_data"],
                                                   str(device_id),
                                                   decrypted_fake_tuple_data)
    generated_tuples = generate_fake_tuples_in_range(
        decrypted_fake_tuple_data["device_data"])
    expected_fake_rows = slice_by_range(generated_tuples, int(lower),
                                        int(upper), "device_data:num_data")
    verify_integrity_data(expected_fake_rows, fake_tuples)

    if json_content["success"]:
        check_correctness_hash(rows, 'added', 'data', 'num_data', 'tid')

    result = []
    for row in rows:
        try:
            result.append(unpad_row("data", row))
        except Exception as e:
            click.echo(str(e))
    click.echo('{"device_data":' + str(result).replace("'", '"') + '}')
コード例 #15
0
def query_orm(session, name):
    return session.query(BlindIndex).filter(BlindIndex.name_bi == blind_index(key, name)).scalar()
コード例 #16
0
session = dal.Session()

rows = []
rows_num = 1000
searched_row = 500
searched_name = ""
key = b'\xb8z\x1dU)\xb7YY~\xd3>\x00\x85^\x11|\x12K\x95e\xd4\xca\xc9\xf2,\xe0g\xe4\xc44\xd3W'

for i in range(1, rows_num):
    name = ''.join(random.choices(string.ascii_uppercase + string.digits, k=10))
    if i == searched_row:
        searched_name = name
    rows.append(BlindIndex(
        id=i,
        name=name,
        name_bi=blind_index(key, name)
    ))

session.add_all(rows)
session.commit()


start = timer()
result = session.query(BlindIndex).filter(BlindIndex.name_bi == blind_index(key, searched_name)).scalar()
end = timer()

print(f'We searched for row with name: {searched_name}')
print(f'We found row: {result}')
print(f'Search over {rows_num} rows took {end - start}\n')

uri = urlparse(dal.conn_string)