Skip to content

Latest commit

 

History

History
209 lines (186 loc) · 12.9 KB

README.md

File metadata and controls

209 lines (186 loc) · 12.9 KB

User CLI

This is directory that contains source code responsible for CLI for user to interact with server, broker and devices.

Prerequisites

  • Docker

For running on host:

Running using Docker (recommended)

  • docker pull martinheinz/iot_cloud_cli:latest
  • docker run -it --network host martinheinz/iot_cloud_cli

Install

Note: this is only needed when running on host (not using Docker)

To install CLI

  • Create Python venv (Python 3.x required; from IoT-Cloud directory):
    python3 -m venv venv
  • Activate venv:
    source ./venv/bin/activate
  • install CLI (from IoT-Cloud directory): pip install --editable .
  • Test if it's working: iot-cloud-cli --help

Expected output:


Options:
  --debug / --no-debug
  -b, --broker TEXT
  -p, --port INTEGER
  --help                Show this message and exit.

Commands:
  device
  user

Example Flows

These are example sequences of commands to show how to perform various tasks using CLI

  • Register to Server by accessing https://localhost/login

  • Set Server access_token returned by registration: export ACCESS_TOKEN=<value>

  • Register to AA by accessing https://localhost/attr_auth/login

  • Set AA access_token returned by registration: export AA_ACCESS_TOKEN=<value>

  • Set AA username to that is used in Server (your GitHub username) : iot-cloud-cli user attr-auth-set-api-username <GitHub username>

  • Set broker URL on MQTT_BROKER variable in ./client/cli.py (or use -b option in following commands)

  • Register to broker

    • iot-cloud-cli user register-to-broker <your-password>
    • broker_id and broker_password are added to keystore.json
  • Initialize per-user global hashing and encryption keys

    • iot-cloud-cli user init-global-keys
  • Create new device type

    • iot-cloud-cli user create-device-type <some-description>
    • Save the device type ID from response for future use
    • example ID: "type_id": "3d5a490c-42da-43c4-abe8-b687c49c51b5"
  • Create device

    • iot-cloud-cli user create-device <type_id> <device_name> <device_pass>
    • Device, ACLs and association with user are created on server
    • Client saves device record in keystore.json (device_id and client generated device keys)
    • Save device_id, device_name and device_pass for future use
  • Initialize device client

    • iot-cloud-cli device init <device_id> <device_pass> <user_broker_id> <list_of_action_names>
    • example: iot-cloud-cli device init 46 test_pass 11890454 On Off
    • Device record is created in data.json as well data for integrity checking (column seeds, bounds of inserted rows and types of encryption used in columns)
  • Connect device to broker

  • Start exchange of shared key with device

    • iot-cloud-cli user send-key-to-device <device_id>
    • users public key is send to device
    • public and private keys are temporarily saved to keystore.json
    • device receives user public key, generates own key-pair and performs exchange (generates shared key), which is saved to data.json
    • device sends public key to server for user to retrieve
    • device key-pair is wiped
  • Retrieve device public key

    • iot-cloud-cli user retrieve-device-public-key <device_id>
    • user retrieves device public key and performs key exchange
    • shared key is saved to keystore.json and user key-pair is wiped
  • Perform key setup for ABE keys

    • iot-cloud-cli user get-attr-auth-keys
    • Key setup is performed by server - public key and master key are generated by AA, public key and master key are saved at AA, public key is send to user
    • user saves public key to keystore.json
  • Request private ABE key for device

    • iot-cloud-cli user attr-auth-device-keygen <device_id> <attr_list>
    • example: iot-cloud-cli user attr-auth-device-keygen 46 U-11890454 D-46 D-46-GUEST where 11890454 is a user_broker_id, also please use only capital letters in attributes, because when parsing policies all letters are evaluated to caps
    • Device private key is generated by AA using user master and public keys saved at AA and provided attribute list and then sent to user
    • Device private key is saved to users keystore.json together with attribute list
  • Generate and send all encryption keys to device

    • iot-cloud-cli user send-column-keys <user_id> <device_id> <policy>
    • example: iot-cloud-cli user send-column-keys 11890454 46 "(u-11890454 OR d-46 OR d-46-GUEST)", Note: policy here evaluates to ((U-11890454 or D-46) or D-46-GUEST), so if you previously used attributes with lowercase chars, then you won't be able to decrypt.
    • user client generates all column keys and encrypts them together with ABE device private key using shared key and sends them using MQTT broker to device
    • device retrieves encrypted keys, decrypts them and saves them in data.json
  • User sets device actions on server

    • iot-cloud-cli user set-action <device_id> <action_name>
    • example: iot-cloud-cli user set-action 46 On and iot-cloud-cli user set-action 46 Off
  • Now user can trigger device action

    • iot-cloud-cli user trigger-action <device_id> <device_name> <action_name>
    • Note: there is also optional --real/--fake parameter (--real by default) that allows user to send fake action
    • user client computes Blind Index of device_name and action_name and sends it to server
    • server looks up device and action using Blind Index and sends message using MQTT broker
    • device receives message, decrypts it and resolves whether it is real of fake
    • if it's real, action is triggered (see node-red debug output)
  • User can also send raw JSON message

    • iot-cloud-cli user send-message <user_id> <device_id> <JSON string>
    • example: iot-cloud-cli user send-message 11890454 46 "{\"action\": stuff}"
    • Message is sent directly over broker and encrypted using shared key

Send data, send/remove fake data and retrieve device data

  • To send fake data from device to server, click send_add_fake_tuple inject node in node-red flow

    • When node is clicked device generates fake tuple using integrity data - upper index bound and seed are used to generate fake values, these values are then encrypted using column keys. Also correctness hash and tuple ID (positive) Blind Index are created
    • Generated tuple is sent to server over MQTT, where it is saved
  • To remove fake data by device, click remove_add_fake_tuple inject node in node-red flow

    • Here happens same thing as with send_add_fake_tuple, only difference is that device uses lower index bound for tuple values and tuple ID
    • This generated tuple is send to server over MQTT, which deletes it
  • To send real device data from device, click send_save_data inject node in node-red flow

    • Data (parameters of node) are encrypted and together with tuple ID (negative) and correctness hash are send to server over MQTT
    • Server saves received payload
  • To retrieve device data

    • iot-cloud-cli user get-device-data <user_id> <device_id> <device_name>
    • users client computes device name Blind Index and sends data request to server
    • server returns all device data
    • users client sends fake tuple information request to device over MQTT
    • device returns fake tuple information encrypted with shared key
    • users client decrypts fake tuple information and uses it to generate expected fake records
    • users client decrypts data from server
    • users client divides fake and real records using tuple ID
    • users client verifies presence of all expected fake records
    • users client verifies integrity of each row using correctness hash attached to each row
    • users client outputs decrypted real data and info about integrity checks
  • To retrieve device data using range query

    • iot-cloud-cli user get-device-data-by-num-range <user_id> <device_id> <device_name> --lower <lower_bound> --upper <upper_bound>
    • Same as previous option, only difference is that server uses encrypted bounds to make range query and returns only data that satisfy the range

Create Scene, Add Actions to Scene, Trigger Scene

  • To create scene
    • iot-cloud-cli user create-scene <scene_name> <scene_description>
    • users client generates Blind Index for scene_name
    • users client encrypts scene_name and scene_description
    • users client sends data to server which saves it
  • To add action to scene
    • iot-cloud-cli user add-scene-action <scene_name> <action_name> <device_id>
    • users client generates Blind Indices for scene_name and action_name and sends them to server
    • server looks up scene and action by Blind Indices and adds this action to scene
    • Note: if you want to create another device to trigger actions of multiple devices, you will have to copy whole project and repeat whole process of setting device. As an alternative you can add multiple actions of single device to scene to see multiple actions being triggered
  • To trigger scene
    • iot-cloud-cli user trigger-scene <scene_name>
    • user client generates Blind Index for scene_name and sends it to server
    • server looks up scene and sends messages over MQTT to all devices with actions associated with scene
    • rest is same as when triggering one action
    • to see actions being triggered see node-red debug console
    • Note: it's also possible to use --fake option to make fake trigger of scene

Authorize user, Revoke user

  • Note: to have multiple users on same device, you will have to copy project or temporarily remove existing keystore.json when performing actions as other user
  • To authorize user
    • iot-cloud-cli user authorize-user <device_id> <device_name> <other_user_id>
    • user client generates Blind Index for device_name and sends it to server together with other_user_id
    • server creates ACLs for user being authorized and for device, as well as association object and saves them
  • To revoke user
    • iot-cloud-cli user revoke-user <device_id> <device_name> <other_user_id>
    • user client generates Blind Index for device_name and sends it to server together with other_user_id
    • server removes ACLs and association object for user being revoked and for device

Trigger Action and Query data with authorized user

  • Setup device
    • First owner needs to generate private key for authorized user
      • iot-cloud-cli user attr-auth-keygen <auth_user_api_username> <device_id> <attr_list>
      • private ABE key with attributes in attr_list is generated for user with auth_user_api_username to query data from device with device_id, the key is stored at AA, so the user can retrieve it
    • Next, authorized user needs to setup the device keys
      • iot-cloud-cli user setup-authorized-device <device_id> <path_to_owners_public_ABE_key> <device_blind_index_key> --token <authorized_users_aa_access_token>
      • authorized users client adds record for device with device_id into keystore.json. This record also includes ABE public key and device Blind Index key provided by owner as well as private key generated by owner, which is retrieved from AA
  • Trigger action
    • iot-cloud-cli user trigger-action <device_id> <device_name> <action_name> --no-owner
    • Note: to make it possible for authorized user to trigger action owner has to share action names
  • To query device data
    • iot-cloud-cli user get-device-data <authorized_user_id> <device_id> <device_name> --no-owner --token <authorized_users_access_token>

Using Fake Actions

  • User can trigger fake actions using
    • iot-cloud-cli user trigger-action <device_id> <device_name> <action_name> --fake
    • here device can distinguish between real and fake action by decrypting additional_data field added by users client, only if the value is real action is triggered
  • User can schedule fake actions
    • iot-cloud-cli user schedule-fake-actions <device_id> <device_name> <start_time> <end_time> <number_of_actions> <actions_name_list>
    • example: iot-cloud-cli user schedule-fake-actions 46 test_device '2019-04-06 18:29:00' '2019-04-06 18:30:00' 3 On Off
    • Scheduler sends specified number of fake actions at random times in the time range, each time choosing random action from supplied list