Assignment 5

Due Friday April 27, 2018 11:59 pm via sakai

Authored by Aditya Geria

OpenSSL Message Board Project

Welcome to the world of encryption, identification, authentication and authorization! In this project you will have the following main goals for understanding:

  • OpenSSL as a tool
  • Key generation using RSA cryptography
  • Encryption of data at rest and in transit
  • Communicating and authenticating with a server as a client program.

Project

To accomplish this, the goal of this project is to design a message board as a set of client-server programs where authentication takes place through a self-signed certificate, user information is stored and transferred securely, and messages cannot be retrieved without interception in clear (plaintext) by adversaries.

The role and functionalities of each part of this project will be further explored in the coming sections.

Further Reading: OpenSSL Cookbook which outlines several helpful tips, defines how SSL works, and lists best practices when using OpenSSL.

Logistics

You may work on this programming assignment with a group of no more than 4 people. Only one group member should submit the assignment and the submission writeup should clearly indicate the names of all group members.

You are free to use any language of your choice. As a recommendation, Python and C are the best places to start with Java as a good alternative.

OpenSSL as a Tool

OpenSSL is an open source command line tool for SSL Encryption and generating certificates. As you learned in class, certificates are highly important for verifying a server’s identity on an otherwise untrusted internet. They associate your identity with your public key and are signed by a certification authority (CA) that asserts this association. For this project, you will use OpenSSL to generate a Self Signed Certificate for your server, which is a certificate that is not verified by a Certificate Authority, but instead signed by yourself.

In order to do this initial step, you will need to use the OpenSSL command line tool. This certificate should be used by your server program in establishing its identity. Every client that connects to the server should verify the server’s identity using the information from this certificate that you generate.

  • On a Mac (Sierra/High Sierra) or Linux: OpenSSL should already be available through Terminal or the Shell. Simply test if its installed using the $ which openssl command. If it returns a path, you have the tool.
    • If, for some reason, you do not have the tool, you may need to install it using Homebrew or another package manager of your choice.
  • On Windows: We recommend you switch to a Linux or Mac based system to perform this step. To gain access to a linux machine, consider the iLab machines that are available to everyone in Hill Center (Rooms 248–254) or through SSH. If you would like to create certificates on Windows, you can check the OpenSSL Wiki for links to distributions on various platforms but please be sure to check that your solution works on Linux.

This article by Digital Ocean outlines how to generate a self-signed certificate. Using these guidelines, generate a certificate using RSA 2048 byte keys and the X.509 standard. Use this certificate to initialize information and identify your sever program. Once you have generated the certificate, you will need to save the .crt and .key files as they contain your keypairs and your certificate. OpenSSL Libraries will need this to pull information about your certificate.

--Generating a certificate--
openssl req \
        -newkey rsa:2048 -nodes -keyout domain.key \
       -x509 -days 365 -out domain.crt

Creating the Server and Client Programs

You will create a pair of programs that emulate a message board functionality. To clarify, a message board is a service where users can post messages to retrieve messages from a group. For example, let’s say we wanted to post to a group about Food with a hot new recipe we just invented. Here is what our server program should allow us to do:

Server Overview

  1. Be able to run on a specified port on some host
    • This information can be provided as command line input, or be defaulted to some value.
  2. Verify the SSL certificate you created, store the data from the certificate
  3. Be able to provide this information to any connecting clients
  4. Store a username-password database as a .txt file.
    • Here, you must keep in mind best practices when storing passwords. Remember that passwords should be Salted and Hashed with a strong hash function (e.g., SHA–256).
    • You should never store raw passwords for verification.
    • Connecting clients should be prompted for their username and password to be authenticated to the server.
    • If a client has no matching username in the table, you must create a new entry by using the provided password as the associated password.
  5. After a client has been authenticated, send the client a list of all groups available.
    • The client should be sent a list of groups between each command received from the client.
  6. Accept commands from the the client until the client disconnects (get → post → get → post → end is allowed):
    • GET takes a group as an argument. Retrieves all messages posted to that group, and a timestamp of when the message was posted (can be UTC for simplicity), and by which user.
    • POST takes a group and a message as an argument. Post a message to some group under your username. If the group does not exist, create it.
    • END ends the session with the server, does not exit the client and should allow you to log back in.
  7. A server should be able to handle multiple clients connecting to it simultaneously (i.e., it should be mulithreaded).
    • A functionality to time out idle clients might be extremely helpful for closing dead socket connections
  8. Messages should persist outside of memory. If the server exits, the messages should not be lost. Consider using a function similar to mmap() in C to persist your database without having to deal with files (you’re welcome to read/write files directly, of course). For any files that you use, use relative pathnames (e.g., not something starting with \ or ~username/. Realize that your programs will be tested by a different user on a different system.
    • When the server restarts, it should read from this data store and retrieve messages and groups.

Client Overview

A client program performs the following functionalities:

  • Have command line argument options to specify the host and port of the server, or default to some setting if no arguments are provided. For example, use localhost for the default host and the same default port numbers on the client and server.
  • Establish a secure connection with the server and authenticate its certificate using an OpenSSL library for your respective language
  • Provide the server with a set of credentials (username and password).
  • Send GET POST END commands to the server, and implement their functionality in a reader-friendly way.

An exchange between the server and client might look like this:

- Server is running on port 5000...
- Server checks its memory store for an existing record of message and groups. If it exists, load the information. Otherwise, create it.
- Server checks the password file if it exists.
* Client c1 connects to server, verifies the certificate is valid
* Client c2 connects to the server, verifies the certificate is valid
* c1 provides username and password, server authenticates by comparing hashes
* c2 is a new user, server appends the login info to the password file
* c1 wants to get all messages from the food group
- Server fetches information from data store, retrieves information and sends it over SSL to c1
* c1 wants to post to the food group "This recipe is great!"
- Server appends the message with a timestamp to the group, and updates the datastore.
* c2 wants to post to a new group "games"
- Server will create the group "games" and append c2's message to "games".
* c2 wants to retrieve all messages from "games"
- Server sends this information to c2 over SSL.
* c1 ends
* c2 ends

Running and Testing

To test your server, you can deploy it on localhost and have it listen on some port (5000, 3000 for example), and have clients connect to it as such. Make sure to keep the deployment port consistent across both the client and server, otherwise the client will not be able to find the server.

Have your client connect to the server, and at the same time, deploy another client to connect to the server (testing multithreaded functionalities). Here are some things to test for before submitting: - Trying to fetch messages from a group that doesn’t exist - Trying to provide an invalid username/password combo - Attempting to submit blank messages or invalid group names - Be careful of using methods that are vulnerable to buffer overflow! - Server’s certificate information does not match the expected information in the client. - Make sure the client cannot control or have access to the password file in any way (this is a Security class).

Submission

You will submit your client and server programs, as well as any demo files we need to run your program. We should be able to compile your program quickly and without errors. Please be sure to provide clear directions in your writeup. Have a friend test the entire compile and run process if you can to validate that you didn’t forget anything.

A short README file is also required (in any file format) to explain the logic of your program, as well as your design choices or if you implemented any special features.

On Sakai, submit all of this as a .tar file. by the above due date.

Be sure to identify all members of your group and have only one member submit the assignment.

Also be sure to observe the posted deadline. Late submissions will not be accepted.