read()/write()in TCP, and
recvfrom()/sendto()in UDP. Those functions do not provide secure communications unless the transport layer does so. In this set of lab exercises, you are to write functions to transfer data securely at the API level.
The work is based on the discussion at http://hayageek.com/rsa-encryption-decryption-openssl-c/
In the public/private key scheme for secure data transfer, the communicating parties share their own public key with the other party. When sent from Alice to Bob, the message m is encrypted with Bob's public key B+. The content to be sent becomes B+(m). When Bob receives the message, he decrypts the message using his private key B-. Because of the nature of the public key and private key, B-(B+ (m)) = m. That is, only the party with the proper private key B- can decipher the message.
In practice, key management is critical to the success of secure communication. If a public/private key encryption scheme such as RSA is used, the communicating parties have to exchange the public keys of each party. Because the asymmetric nature, the private key is kept secrete by each party, public key exchanges are less trouble-some today, though challenges do exist. Please read the Wikipedia article on the subject for some general information.
You will practice some of the basic operations of an RSA system in this lab. First you will generate your own public key and private key. You will then use this set of keys to encrypt and decrypt messages over a regular TCP connection. The sending party encrypts the message using the receiving party's public key and sends the data to the receiving party. The receiving party decrypts the received data to retrieve the original message using its private key.
To concentrate on the essential issues, you are given a set of programs that take care of some of the routine operations such as reading key files from local file system, establishing a regular TCP connection, among others. Your tasks are to write the core functions to encrypt and decrypt messages, and to send and receive the encrypted messages. You are also given a program example of direct use of RSA related functions to encrypt and decrypt messages to see how these functions may be used.
Your overall task is to write a few core functions such that the given set of applications
echo-client.c will work properly, exchanging information through secured communications. You will be given some program files that have implemented some of the routine tasks. You will need to understand how these programs work and write the required functions to complete the application.
The following descriptions reflect how I would set up the file structures. You can choose different way of organizing your files and use your own wrapper functions developed in this and other courses.
cp -r ~cs363/Spring16/student/labs/lab11 .
lab11directory, one is named
rsawhich contains a working example, the other is named
rsa-appwhich contains a set of program files with which you will work.
uudecodeto see how one might convert between a binary file and a piece of unique text.)
make ./echo-server [port] server-private.pem server-public.pem & ./echo-client [server-name] [server-port] client-private.pem client-public.pem
cat, or any text editors. Your programs can use these files. But you are asked to generate your own using the following command at the Linux command prompt.
openssl genrsa -out new-server-private.pem 2048
openssl rsa -in new-server-private.pem -outform PEM -pubout -out new-server-public.pem
openssl genrsa -out new-client-private.pem 2048
openssl rsa -in new-client-private.pem -outform PEM -pubout -out new-client-public.pem
Note that the order is import that a private key is generated first, the public key is then generated based on the value of the private key.
exchange_public_key()of which the prototype is given in the header file tcplib-ssl.h. The three parameters for this function are the connected socket, the file name for the key, and an indicator whether this is the sender or receiver. Note that both parties can't read and send the public key in the same order. One has to send first, then receive; while the other has to receive first, then send.
reads(). The prototypes of these two functions are also defined in the file tcplib-ssl.h. These two functions have the identical prototype as their counter part in the Linux file system,
write(). They take the socket as the first parameter, a buffer as the second parameter, and the length as the third parameter. Note that the buffers for writing and reading represent plain text. All the encryption and decryption details should be hiden from the application program. That is, you'd have to implement all the details in the functions writes() and reads(), possibly creating other functions as needed. One obvious and critical issue is that the data may have length longer than what the encryption function allows (e.g., in our case of 2048 byte key, the data can't be longer than 240 or so bytes.) In your implementation of writes() and reads() you'd have to consider this issue. You'd have to break the data in multiple pieces and send them separately. On the receiving side, you'd have to receive these separate pieces, decrypt them and reconstruct the original data before sending it back to the calling function.
When the three required functions are implemented properly, writes(), reads(), and exchange_public_key(), plus possible other functions you choose to implement in support of these three functions, you should be able just to compile the programs and run the server and client programs. Note that the echo-client.c contains two pieces of test messages, one a simple and short hello world, the other is a longer message generated by the function read_long_message(). Test with the simple message first. If it works fine, comment out the simple message, uncomment the longer message and try the program with the longer message, in which case, your writes() and reads() will have to break the message into multiple pieces for encryption and decryption.
Save as a text file a screen capture of compiling the programs, send and receive the simple message, and send and receive the longer message. Name this file screen-capture.txt
Clean up your directory by running the command
make clean, and submit the entire directory to your git repository.
Congratulations! You just finished this lab.