Skip to content

Latest commit

 

History

History
497 lines (380 loc) · 17.4 KB

README.md

File metadata and controls

497 lines (380 loc) · 17.4 KB

SecretStroll

Introduction

In this project, you will develop a location-based application, SecretStroll, that enables users to search for nearby points of interest (POI). We provide you with an instructions handout and a skeleton to help with the development.

Virtualization. We provide a virtual machine (VM) to facilitate the setup and configuration of the SecretStroll and reduce potential networking problems while running the application in different environments.

Also, we use Docker to enforce isolation between the client and server on the virtual machine. Docker is a piece of software that uses the capabilities of the Linux kernel to run processes in a sandboxed environment. Thus, both the server and the client will "think" they are running in two independent systems.

Skeleton. Both the client and the server provide a command-line interface to run and interact with the server. The underlying location-based service is already implemented in the skeleton, and your task is to add the authentication with attribute-based credentials.

We strongly recommend to use the petrelic cryptographic-pairing library to implement PS credentials. You can find the project repository in petrelic and you can visit https://petrelic.readthedocs.io for documentation. This library is bundled in the provided Docker container and virtual machine.

The skeleton has already implemented and integrated capabilities to save, manage, and load keys and credentials as byte arrays. You need to implement (de)serialization methods to match the API. We provide serialization.py as a petrelic extension of jsonpickle, a serialization library, to help you with the serialization of cryptographic objects.

Our skeleton and Docker infrastructure takes care of syncing and deploying your code. You only need to implement attribute-based credentials and update the stroll.py file to use it.

Testing. An integral part of system development is testing the system. In your implementation, you should check both success and failure paths when your working with cryptographic primitives. In this project, you must use the pytest framework to test your system. You can visit pytest tutorial for guides.

Setting up the development environment

Virtual machine

We provide you with two VM images for SecretStroll project on which we have already installed all the necessary applications and libraries:

  • A VirtualBox image for people using a x86_64 CPU architecture. (i.e. almost all laptops...)
  • A zipped UTM image for people using a ARM 64 CPU architecture. (i.e. Apple Silicon Macs)

If it is not already done, you can install VirtualBox or UTM on your laptop by following the instructions in their respective documentation:

We only provide support for projects running inside the VM and we strongly recommend you to develop inside the VM.

There are two accounts on the VM (user:password):

student:student
root:root

You can set up SSH on the VM and connect from your host or directly use the VM as your development environment.

Setting up SSH to the VM

For VirtualBox

In VirtualBox, you can set up SSH access to the VM by following these steps:

  • Open the settings of your image
  • Go to the "Network" panel
  • Choose "Advanced" and click on the "Port forwarding" button
  • Add a forwarding rule (green "plus" button on the side)
  • In the forwarding rule, leave both IP addresses empty, set Host port to 2222, and Guest port to 22 (the default SSH port)
  • Restart the virtual machine

For UTM

In UTM, you can set up SSH access to the VM by following these steps:

  • Open the settings of your image
  • Go to the "Network" panel
  • Add a new port forward rule (New button on the right of the Port Forward frame)
  • In the forwarding rule, leave both IP addresses empty, set Host Port to 2222, and Guest Port to 22 (the default SSH port)
  • Restart the virtual machine

Once the port forwarding rule is effective, you can connect to your virtual machine via SSH: ssh -p 2222 [email protected]

This is how you copy files TO the VM: scp -P 2222 <path_to_copy_from_on_host_OS> [email protected]:<path_to_copy_to_on_guest_OS>

Copy files FROM the VM: scp -P 2222 [email protected]:<path_to_copy_from_on_guest_OS> <path_to_copy_to_on_host_OS>

Code Skeleton

The first step of this project will be to retrieve the skeleton that you will have to use as a base implementation. The most convenient way to do this will be to clone the public repository of this course with git.

git clone https://github.com/spring-epfl/CS-523-public.git cs523

We use Python 3 in this project and all necessary Python components are already installed on the VM and Docker containers. You can find installed libraries in the file requirements.txt.

Feel free to have a look at client.py and server.py to see how the classes and methods are used.

Note: The library petrelicis currently only distributed for Linux systems, if you are not using the VM or a Linux system, you should still be able to test your code by running it within the Docker containers build with the provided configuration.

Collaboration

You can use git to sync your work with your teammates. However, keep in mind that you are not allowed to use public repositories, so make sure that your repository is private.

If you cloned our git repository to retrieve the skeleton as we advised, you can replace the remote URL to your own git repository

cd cs523
git remote set-url origin [email protected]:<your GitHub user ID>/<your private repo>

Files in this repository

This repository contains the skeleton code for Parts 1 and 3:

  • credential.py—Source code that you have to complete.
  • stroll.py—Source code that you have to complete.
  • client.py—Client CLI calling classes and methods defined in stroll.py.
  • server.py—Server CLI calling classes and methods defined in stroll.py.
  • serialization.py—Extends the library jsonpickle to serialize python objects.
  • fingerprinting.py—skeleton for Part 3.
  • requirements.txt—Required Python libraries.
  • docker-compose.yamldocker compose configuration describing how to run the Docker containers.
  • docker/—Directory containing Docker configurations for running the client and the server.
  • tor/—Intentionally empty folder needed to run a Tor server.
  • fingerprint.db—Database containing POI information for Part 3.

The directory privacy_evaluation contains files for the part 2.

Server and client deployment

The server and client code deployment is handled by Docker and our skeleton. In this section, we introduce our Docker infrastructure and how to use it. Then, we provide a step-by-step guide of running the client and server.

Working with the Docker infrastructure

Before launching the infrastructure, ensure the tor directory in the project's directory has the correct permissions.

student@cs523:~$ cd cs523/secretstroll/
student@cs523:~/cs523/secretstroll$ chmod 777 tor
student@cs523:~/cs523/secretstroll$ ls -ld tor
drwxrwxrwx 2 student student    4096 mar 24 15:31 tor

The server and the client run in a Docker infrastructure composed of 2 containers, and a virtual network.

Before setting up the Docker infrastructure for the first time, you must first build the images which will be used to run the client and server containers. To do so, run the following command in the directory which contains the file docker-compose.yml:

docker compose build

To set up the Docker infrastructure, run the following command in the directory containing the file docker-compose.yml:

docker compose up -d

When you stop working with the infrastructure, remember to shut it down by running the following command in the secretstroll directory containing the file docker-compose.yml:

docker compose down

Note: If you forget to shut down the Docker infrastructure, e.g., before shutting down your computer, you might end up with stopped Docker containers preventing the creation of the new ones when you to re-launch the infrastructure the next time. This can be fixed by removing the network bridge with docker compose down and destroying the stopped Docker containers with docker container prune -f.

Accessing the data

The code in the secretstroll directory is shared between your VM and the Docker containers, so modifications you make in your VM will also appear in containers. Feel free to read the file docker-compose.yml to see how it is done.

If you need to transfer some data between your VM and your host machine, you can set up SSH access and use the scp command as detailed before.

Another option for people who use VirtualBox is to have shared directories between the VM and your host. For this feature to work correctly you need to have VirtualBox's Guest Additions installed on the VM. We have already installed Guest Additions on the VM we provided for this course, but you might have to update it to work with your version of VirtualBox, in which case, please refer to their documentation.

Note also that you will need to use Tor in this project (see section below), and that Tor is quite sensitive to its directories' permissions. As it is often not possible to map directly the permission between the host and guest when sharing some files, be careful to not run your project directly from the shared directory as incorrect permission given to the tor directory of your project can prevent Tor from starting.

Tor integration

Integrating Tor into your project should be seamless. The Docker configuration we provide is designed to run Tor in the background, and the code is designed to use the Tor if requested with no effort on your part.

If your project works if used normally, but fails when using Tor, you can check if its log file in the Docker container gives a clue to what is happening:

cat /var/log/service/tor/current

If you still do not know what causes the problem or do not know how to correct it, call an assistant.

Server

It is easier to run the commands in a Docker container by opening a shell, and then running the commands inside this shell.

To execute a shell in the container in which the server is to be launched, run the following command:

docker exec -it cs523-server /bin/bash

In this container, the root directory of the project is mounted on /server.

cd /server

The server has two subcommands: gen-ca and run. gen-ca generates the public and secret keys, and run runs the server. The server and its subcommands have a help option, which you can access using the -h argument.

Key generation example:

python3 server.py setup -S restaurant -S bar -S sushi

usage: server.py setup [-h] [-p PUB] [-s SEC] -S SUBSCRIPTIONS

optional arguments:
  -h, --help            show this help message and exit
  -p PUB, --pub PUB     Name of the file in which to write the public key.
                        (default: key.pub)
  -s SEC, --sec SEC     Name of the file in which to write the secret key.
                        (default: key.sec)
  -S SUBSCRIPTIONS, --subscriptions SUBSCRIPTIONS
                        Subscriptions recognized by the server.

Server run example:

python3 server.py run

usage: server.py run [-h] [-D DATABASE] [-p PUB] [-s SEC]

optional arguments:
  -h, --help            show this help message and exit
  -D DATABASE, --database DATABASE
                        Path to the PoI database.
  -p PUB, --pub PUB     Name of the file containing the public key.
  -s SEC, --sec SEC     Name of the file containing the secret key.

In the Part 3 of the project, the server is expected to be accessible as a Tor hidden service. The server's Docker container configures Tor to create a hidden service and redirects the traffic to the Python server. The server serves local and hidden service requests simultaneously by default.

The server also contains a database, fingerprint.db. This is used in Part 3. The database has a POI table that contains records for each POI. The server returns the list of POIs associated with a queried cell ID, and information about each POI in the list. You must not modify the database.

Client

To execute a shell in the client container, run the following command:

docker exec -it cs523-client /bin/bash

In this container, the root directory of the project is mounted on /client.

cd /client

The client has four subcommands: get-pk, register, loc, and grid. As for the server, the client and its subcommands have a help option, which you can access using the -h argument.

Use get-pk to retrieve the public key from the server:

python3 client.py get-pk

usage: client.py get-pk [-h] [-o OUT] [-t]

optional arguments:
  -h, --help         show this help message and exit
  -o OUT, --out OUT  Name of the file in which to write the public key.
                     (default: key-client.pub)
  -t, --tor          Use Tor to connect to the server.

Use register to register an account on the serve:

python3 client.py register -u your_name -S restaurant -S bar

usage: client.py register [-h] [-p PUB] -u USER [-o OUT] -S SUBSCRIPTIONS [-t]

optional arguments:
  -h, --help            show this help message and exit
  -p PUB, --pub PUB     Name of the file from which to read the public key.
                        (default: key-client.pub)
  -u USER, --user USER  User name.
  -o OUT, --out OUT     Name of the file in which to write the attribute-based
                        credential. (default: anon.cred)
  -S SUBSCRIPTIONS, --subscriptions SUBSCRIPTIONS
                        Subscriptions to register.
  -t, --tor             Use Tor to connect to the server.

Use loc and grid commands to retrieve information about points of interests using lat/lon location (Part 1) and cell identifier (Part 3), respectively:

python3 client.py loc 46.52345 6.57890 -T restaurant -T bar

usage: client.py loc [-h] [-p PUB] [-c CREDENTIAL] -T TYPES [-t] lat lon

positional arguments:
  lat                   Latitude.
  lon                   Longitude.

optional arguments:
  -h, --help            show this help message and exit
  -p PUB, --pub PUB     Name of the file from which to read the public key.
                        (default: key-client.pub)
  -c CREDENTIAL, --credential CREDENTIAL
                        Name of the file from which to read the attribute-
                        based credential. (default: anon.cred)
  -T TYPES, --types TYPES
                        Types of services to request.
  -t, --tor             Use Tor to connect to the server.

Warning: The database only contains points of interest with latitude in range [46.5, 46.57] and longitude in range [6.55, 6.65] (Lausanne area). You can make queries outside these values, but you will not find anything interesting.

python3 client.py grid 42 -T restaurant

usage: client.py grid [-h] [-p PUB] [-c CREDENTIAL] [-T TYPES] [-t] cell_id

positional arguments:
  cell_id               Cell identifier.

optional arguments:
  -h, --help            show this help message and exit
  -p PUB, --pub PUB     Name of the file from which to read the public key.
                        (default: key-client.pub)
  -c CREDENTIAL, --credential CREDENTIAL
                        Name of the file from which to read the attribute-
                        based credential. (default: anon.cred)
  -T TYPES, --types TYPES
                        Types of services to request.
  -t, --tor             Use Tor to connect to the server.

A sample run of Part 1

Here we show a typical run of the system for Part 1.

Initialization:

Open a shell

$ cd cs523/secretstroll
$ docker compose build
$ docker compose up -d

Server side:

Open a shell

$ cd cs523/secretstroll
$ docker exec -it cs523-server /bin/bash
(server) $ cd /server
(server) $ python3 server.py setup -s key.sec -p key.pub -S restaurant -S bar -S dojo
(server) $ python3 server.py run -D fingerprint.db -s key.sec -p key.pub

Client side:

Open a shell
$ cd cs523/secretstroll
$ docker exec -it cs523-client /bin/bash
(client) $ cd /client
(client) $ python3 client.py get-pk
(client) $ python3 client.py register -u your_name -S restaurant -S bar -S dojo
(client) $ python3 client.py loc 46.52345 6.57890 -T restaurant -T bar

Close everything down at the end of the experiment:

$ docker compose down

A sample run of Part 3

Here we provide a typical run of the system for Part 3:

Initialization:

Open a shell
$ cd cs523/secretstroll
$ docker compose build
$ docker compose up -d

Server side:

You should have already generated the keys in Part 1, so you do not need to repeat that step.

Open a shell
$ cd cs523/secretstroll
$ docker exec -it cs523-server /bin/bash
(server) $ cd /server
(server) $ python3 server.py run

Client side:

You should have already performed the registration in Part 1, so you do not need to the repeat the step. Use the grid parameter to query for a particular cell. Set the reveal argument (-r) to an empty value. Set the -t argument to use Tor. The example run below queries the server for cell ID = 42.

Open a shell
$ cd cs523/secretstroll
$ docker exec -it cs523-client /bin/bash
(client) $ cd /client
(client) $ python3 client.py grid 42 -T restaurant -t

Close everything down at the end of the experiment:

$ docker compose down