Final Project
The final project is an encrypted client/server messaging system. The networking part will be very simple (and you will be given code for that), but it will draw on many of the topics covered in the class, including:
- Certificates and certificate authorities
- Password authentication
- Message encryption
- Input parsing
- Sandboxing
Briefly, users of the system who wish to send messages to other users will contact the server, receive certificates for them, encrypt and digitally sign the messages, and upload them. The server will store those messages for retrieval by the recipients.
System Components
The system will consist of several components. On the server side, there will (conceptually) be one program that will handle all requests. The client side will consist of several programs:
- getcert: A user logs in with a username and password, sends a public key, and receives a certificate. The server must also store this certificate.
- changepw: A user logs in with a username and password, and supplies a new password.
- sendmsg: A user logs in with a client-side certificate, sends a list of recipient names, receives their certificates, encrypts the message to those certificates, digitally signs it, and uploads it.
- recvmsg: A user logs in with a client-side certificate and receives a single encrypted message which is then deleted from the server. The signature on the message is verified and the message is displayed.
All connections to the server must be encrypted with TLS. Users who do not have a certificate or who wish to change their password must use the password for authentication; users with certificates must use them to authenticate.
There are a number things that you should not do, in the interests of keeping this manageable:
- First and foremost, you should not try to implement a GUI. Yes, there are potential security issues there, but you'll spend far too much time on the user interface.
- The server must not be multithreaded; you must assume that only one request will arrive at a time. Note that this is a significant simplification that ignores a significant security risk: race conditions.
- You should not add any commands or functionality, even things that would be desirable in a real system, e.g., a reply command or a list of the pending messages.
- Do not write any code to add users to the system—you will be supplied with a list of usernames, passwords, and hashed passwords.
- Don't try to implement certificate revocation or client-side certificate-caching.
Deliverables
- Obviously, you must deliver source code for all of the programs. The clients and server must be in C or C++ (and a mixture is ok); the test programs may be in any language you wish
- You must turn in a design document. This is the one deliverable for the intermediate project due date, though any changes should be included (and noted) as part of your final project. Design issues include, but are not necessarily limited to:
- Crucial security decisions and their rationale. The most important is how you divide a command into sandboxed and unsandboxed sections, and why. That is, when you decide to split some program into two sections, one with more privileges and one with less, you're going to have to decide what goes where. Justify this decision, and justify the limitations on the unprivileged section.
- Document the file layout
- Explain any file permission decisions
- Explain any other decisions that are important from a security perspective
- You must turn in a test plan and test mechanisms. The test plan is the other deliverable for the intermediate due date; again, you may change and update it for the final submission. This document needs to describe your testing strategy: what you are testing, and why. You must do tests that emulate attacks—but what are the attacks you anticipate, and how will you test for them? Note well that attacks can come from authorized users, i.e., those with passwords and/or certificates, and that plausible attacks go well beyond authentication or certificate issues.
Sandboxing
We will discuss sandboxing in detail in a few weeks; briefly, it's a way to limit the powers of a process. You could limit what files it can open, block its ability to open files or write to them, etc. But sandboxed processes still need to talk to some part of the outside world, or they can't do anything useful. How you split a program is a delicate matter—if the process has many permissions, it's dangerous, but if it has too few, you may have to do risky things in the privileged part.
There are a lot of different ways to do sandboxing on Linux; we'll discuss that in about a month.
OpenSSL
You'll need to use OpenSSL routines. There are many and they're complex. I'll provide guides to the ones you'll need.
Network Protocol
The client and server will use a simplified version of HTTPS to communicate. By using HTTPS, you'll be able to use your browser for some debugging. The details of the simplified protocol will be provided very soon.
Storage
Using Github for a code is strongly encouraged. If you don't know how to use it, now is a good time to learn; it will really pay off for you. Yes, there are crazy, weird things you can do with git—but the simple things are simple, and it's by far the best way for a group to maintain a codebase.
Google Docs is a convenient way to collaborate on writing. If your team uses LaTeX, you can use Github for that, or perhaps Overleaf.com.