OpenSSL Familiarization


The purpose of this assignment is to let you familiarize yourself with how to use OpenSSL. You will find the certificate authority part important when you do your final project, so make sure you save your code…


The assignment should be done as a bash shell script. (Other shells are acceptable, too.) This does not require any complex shell programming (though you can do that if you want); it's merely a way to automate a list of commands. To make a shell script easily executable, put


#!/bin/bash


as the first line of the file and then do


chmod +x filename


You can then run the script as you do any other command.


You will spend far more time reading man pages than you will writing code for this assignment. This is actually not abnormal in the real world… A major piece of this assignment is testing for security issues: can you get the other side of the communication to believe a certificate that is for some reason invalid. You will likely have to go beyond the bare minimum functionality I specify in order to do adequate testing.


The minimum things you must do:

  1. Create a certificate authority with an intermediate certificate, using the OpenSSL command line interfaces. Those are all documented, either on your own Linux VM or on the OpenSSL site. For local ones, you strip off the 'openssl' command; thus, for the "ca" command, you'd just type "man ca". The guide at https://jamielinux.com/docs/openssl-certificate-authority/ is excellent—but make sure you understand the options and don't just copy-and-paste the examples. (There's one omission: it doesn't mention the SubjectAltName field, which has to list all domain names.) Also, do not copy anything to any system-related directories like /root/ca, regardless of what that guide says—use a subdirectory of your home directory instead. AGAIN: you will need the CA for the final project, so keep your code around. One simplifying point: you do not have to check for malicious behavior when issuing the certificates. That is, none of the input data has to be presumed to be potentially dishonest. The certificates themselves, however, might be, to cause problems for the remaining components—and creating such certificates is a major part of the assignment.
  2. Use your CA's intermediate certificate to issue the following types of certificates:
    1. A web server certificate
    2. A client certificate
    3. A certificate suitable for others to use when encrypting files to you
    4. A certificate suitable for signing files, including encrypted files
  3. Use the s_server command to run a "web server", i.e., fire it up with the -WWW or -HTTP option; see below for more details. Use it to serve up some .txt files.
  4. Use the s_client command to connect to it and send appropriate Web commands; again, see below. Retrieve the appropriate files and display them. Note that s_client will also print the certificate in PEM format; you can copy-and-paste that into the x509 command.
  5. Document your results. Explain your different test cases and what they were intended to demonstrate.


The deliverables are a set of scripts, configuration files if they're not built by the scripts, and your writeup.


There have been many questions about 2(c) and 2(d): what are those certificates for? That part of the assignment was left over: the assignment was originally more complex and involved encrypting and decrypting files. On reflection, I'm going to leave that part in, but it should be simple, and there are no test cases, just the generated certificates.


Why? Certificates can only be used for certain purposes; this is a field in the certificate itself. A certificate that's suitable for setting up a TLS connection—the types you're generating in 2(a) and 2(b)—cannot be used to sign other certificates. The math works—a modular exponentiation is a modular exponentiation, regardless of your intent—but administratively, such a certificate would be reject if seen as part of a chain going back to the CA.


File encryption and signing certificates are another type. This has to be indicated in the certificate request file; the CA will then put it into the generated certificate, something you can verify with 'openssl x509 -text'.


So: generate certificates suitable for these purposes. Since you're not trying to use them for anything, there are no test cases, but the intent here is to make sure you know how to create them, since you'll have to for the final project.


The ideal way to run this is to have two separate windows logged in to your VM. In one window, run s_server; in the other, run s_client. To do this, you'll have to set up an ssh key pair and use that for logging in; directions are here. If you can't do that or don't want to, run


s_server >server.out 2>&1 &


to run s_server (or the script containing it); you can then run s_client (or the script containing it) in the same window. When you're done with that session, run


kill %1; wait


to terminate the server; you'll then be able to look at its output in the server.out file. There are endless tricks and complexities one can do with the shell, and if you're comfortable with shell programming you may find it easier to use those, but you're not required to and I don't think there's a big advantage to doing so for this assignment. In particular, the CA-related commands take configuration files. You can, if you wish, generate those via complex scripts—but it is completely acceptable to use a set of hand-written files. And yes, it's perfectly fine to generate one basic file and mutate it, by hand or in some automated fashion, to generate the others. 


You will find that there are three phases to this project. The first is understanding the many commands and options you will use. You will definitely need ca, genrsa, req, s_client, s_server, and probably x509. Don't worry about CRLs or OCSP; they're not part of the assignment. (And if there's ever a choice, use PEM format, which I believe is the default anyway.) Yes, there are a lot of concepts and a lot of options, most of which you'll find you can ignore—but you have to learn that first.


The second phase is actually building the basic scripts. Once you understand the commands, this is comparatively simple. I suspect that the total executable content will be at most a couple of dozen commands.


The third and perhaps hardest part is coming up with suitably diabolical test cases. Remember: you have s_client talking to s_server; each is trying to trick the other. You are unlikely to actually trick either s_client or s_server; the goal is to elicit the proper error messages. For example, give one an expired certificate, to get that error. What other errors can you produce?


As always—since buggy code is often insecure code, there will be deductions for any bugs.