John Wittrock, Greg Herpel
To build: $ cd src/ $ make
To run the server: $ make runserver
To run a client: $ make runclient host=<HOST>
where is the
IP address of the server. If you do not specify this argument, the
client will default to connecting to localhost.
Note also that you can start multiple clients by simply opening
another terminal in the same src directory and executing make runclient
again.
Some instructions on how to use the program:
The initial window you see will be a login screen. You can either login with an existing account (you may not have one on the machine you're testing on), or you can create a new account by clicking on the button at the top of the window. Note that when you are creating a new account, there is a password strength requirement. If the password you have chosen is too weak, you will be unable to use that password, and you will be asked to enter another, stronger password to use with your account. The password classifier is fairly strict.
Once you've logged in or created a new account, you'll see the user list frame, which holds a list of the people online (likely only you), and a "Create Chat" button. You can create a new chat with this button.
If you open another client and log in as another user, you can invite the second user from the first chat window by typing their name in the text field above the "Invite" button in the chat window, and pressing the "Invite" button. A window from the second client session will then pop up, and you can chat between the users. If you create further chat rooms, you will not be able to see the messages sent in them in any other chat room.
When you close the "user list" window, you'll exit the client, and no more messages of any sort will be sent to you.
Instructions for how to use the chat window:
Typing in the bottom text area and hitting Enter or the "Send" button will send the text you typed to everyone in the chat room.
The text area on the top right of the pane tells you who's in the chat room, excluding yourself. This is dynamically updated when users leave or join the chat.
The text box below the user list is for username arguments to commands. The "Invite", "Kick", "Silence", and "Unsilence" buttons all take this text box as input, so if you want to invite a user to the chat, or kick, silence or unsilence a user already in the chat, you must type their name in the box and the press one of those buttons. Note that only the owner of the chat room can use those buttons.
To encrypt a chat session, simply have the chat owner press the "Encrypt" button. This will calculate a shared encryption key between all users, and all messages sent between the clients will be encryped and MACed with half of the SHA-512 hash of that key (i.e. the MAC key is 256 bits and the AES key is 256 bits). The server will not be able to read or change any of the messages in transit without an exception being thrown on the client.
If a user is added to or leaves the chat, you should re-encrypt the chat session.
- If a user is added, they will be able to send un-encrypted messages to the room, but will not be able to read any of the encrypted messages being sent to the room. They may want to use this capability to ask the owner of the room to have everyone re-calculate the shared key.
- If a user leaves, the owner should have everyone re-calculate the shared key as well, since even though messages will no longer go to or from the user that left, it's just really a good idea.
All of the audit data is appended to log.log, by default.
Listing of classes and how they're used:
Client-side classes:
Client.java - the client-side class that makes a connection to the server and starts everything running.
ClientBufferPusher.java - a class which runs in its own thread, polls (in a blocking fashion) for message from the server, and takes appropriate action, like displaying a message in a chat window, or displaying a chat invitation.
ClientMessageListener.java - The client-side class which actively reads the Socket instance for messages from the server and puts them on the client's message buffer.
GUI_*.java - these classes are all client-side and were initially auto-generated by WindowBuilder Pro, which is a Google tool. We've since added code to them, notably GUI_ChatInterface.java, which is the main chat-box window.
ConferenceKey.java - The class that holds the business logic and instance variables for a particular instance (specific to a chat room) of a shared Burmester-Desmedt key. Handles the actual shared-key computation.
CryptoUtil.java - Utility class for generic hashing, encryption, decryption, and MAC computation and verification. Used client-side, as no encryption or decryption is ever done on the server.
EncryptedMessage.java - Client-wrapper for holding a concatenated byte array containing an encrypted message, and IV for that encryption, and a MAC for that message and IV, and then metadata about how much space the IV and MAC take up.
PasswordClassifier.java - Class which classifies passwords that the user enters as strong or weak.
Server-side classes:
Server.java - The main class for the server, which polls for incoming connections, makes SSL connections, and passes those Socket instances off to an instance of a Chatter created for that connection, and also places that Chatter on the list of Chatters logged in to the system.
Chatter.java - Represents everything that the server needs to know about a particular Chatter (client) who is connected to the system. Holds references to the Socket for that particular chatter, and holds references to instances of ChatterReaders and ChatterWriters which are looking for messages on that Socket or sending messages from the server to the Socket.
ChatterHandler - Basic superclass for ChatterReader and ChatterWriter, used only to enforce their interfaces and reduce code duplication.
ChatterReader - Reads messages from a client on a Socket and passes them off to the BufferPusher for processing.
ChatterWriter - takes messages from the server and writes them to a particular Socket (to a client).
ChatRoom - the server's representation of a chat room. Holds things like who's in the chat, who's been invited, who's silenced, etc. Also holds a representation of the state of the conference keying protocol.
BufferPusher - the server's processing class. Takes all commands and forwards them to the right users, or processes them and takes some action on the server side. Responsible for forwarding messages to chat rooms, and doing things like adding and removing users from chat rooms. Most server-side authorization is done here.
Message - Simply a representation of a message sent to the server. Holds a reference to which Chatter sent the message and any data that the message contained so it can be processed.