You are on page 1of 4

T-110.

5241 Network Security


Exercise 2
Due by 17.11.2013 23:59

READ FIRST:
This exercise is relatively programming-heavy, so you might need to refresh your skills if you havent
been coding for a while. Youre free to discuss any problems you encounter with other students but all
programming work must be done individually.

1. OPENSSL PROGRAMMING IN C OR C++:


In this exercise, you get some hands-on experience with OpenSSL, a popular TLS API. You will write a
short HTTPS client which connects to a remote SSL server, sends an encrypted HTTP request and prints
out the server's response (the web page). In addition, your program verifies that the X.509 certificate
provided by the server is valid and chains to a root certificate you trust.
Your program is invoked as follows: ./ssl <host> <port> where host is the remote host to
contact, and port is typically 443. Use GET / HTTP/1.1 and Connection: close in your HTTP requests.
You must write your program in C or C++. The program must compile and run on modern Linux systems
with a recent OpenSSL library. You must use the OpenSSL API (#include <openssl/ssl.h>) to establish the
secure channel, and for certificate chain verification. You must use the Berkeley sockets API exposed by
the standard socket headers for establishing the initial TCP connection.
If at any point your application encounters a problem that prevents it from fetching the remote web
page successfully and securely, your program must print out a line beginning with Exiting due to error:,
followed by a description of the error. Security problems are considered such fatal errors as well. Your
program should then terminate with the exit code 1 (you don't have to take care of freeing resources).
If your program manages to contact the SSL server, it must process the certificate obtained from the
server. You must let OpenSSL verify its validity, using a certificate storage you specify in the source code.
For each certificate in the certificate chain, or up to the certificate that fails to verify properly, you must
inspect the certificate's subject and issuer name fields. After printing whether OpenSSL thinks this
particular certificate was verified properly, your program prints (see format below) the common name
(CN), organizational name (O) and the organizational unit (OU) for both the subject and the issuer of
each certificate. Not all fields (eg. CN) are always present; in this case, you may omit the line
corresponding to the missing field. Print a separator after processing each certificate. It is allowed to use
the deprecated X509_NAME_get_text_by_NID() call. Tip: install a callback to follow OpenSSL's
verification process.

If OpenSSL accepts the chain, you must further check if the server's certificate's subject's common name
matches the host name given as the command line parameter. You don't have to support wild cards.
Matching failure must cause your program to terminate.
Finally, if everything went right, your program sends out the HTTP request and outputs the web page
sent by the server to stdout. It must then gracefully free all resources and terminate with the exit code
0.
Some example outputs of the model ssl program are listed in 1.2 1.4. Your program should behave
mostly identically. Please choose meaningful error messages, and get one from OpenSSL if possible.
Keep it short: your solution must be a single .c or .cpp file. Some useful links:
http://www.rtfm.com/openssl-examples/part1.pdf
http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html

1.1 DETAILS
OpenSSL needs to know where it loads CA certificates for verification purposes. You must use a search
path (do not use a bundle file). This search path should be set to /etc/ssl/certs in your submission.
With OpenSSL development libraries (libssl-dev in Ubuntu) present, your program must compile with
either:
gcc -std=c99 -Wall -pedantic ssl.c -o ssl -lcrypto -lssl

or
g++ -std=c++98 -Wall -pedantic ssl.cpp -o ssl -lcrypto lssl

You can use your own (virtual) Linux or kosh.aalto.fi for developing and testing your program.

1.2 EXAMPLE OUTPUT: WWW.GOOGLE.COM


$ ./ssl www.google.com 443
Certificate OK: yes
Certificate subject:
- Organization name: Equifax
- Organizational unit: Equifax Secure Certificate Authority
Certificate issuer:
- Organization name: Equifax
- Organizational unit: Equifax Secure Certificate Authority
===
Certificate OK: yes
Certificate subject:
- Common name: GeoTrust Global CA
- Organization name: GeoTrust Inc.
Certificate issuer:
- Organization name: Equifax
- Organizational unit: Equifax Secure Certificate Authority
===
Certificate OK: yes
Certificate subject:
- Common name: Google Internet Authority G2
- Organization name: Google Inc

Certificate issuer:
- Common name: GeoTrust Global CA
- Organization name: GeoTrust Inc.
===
Certificate OK: yes
Certificate subject:
- Common name: www.google.com
- Organization name: Google Inc
Certificate issuer:
- Common name: Google Internet Authority G2
- Organization name: Google Inc
===
HTTP/1.1 302 Found
...

(Google's answer mostly omitted)

1.3 EXAMPLE OUTPUT: PCWEBSHOP.CO.UK


$ ./ssl www.pcwebshop.co.uk 443
Certificate OK: no
Problem: self signed certificate
Certificate subject:
- Common name: Parallels Panel
- Organization name: Parallels
- Organizational unit: Parallels Panel
Certificate issuer:
- Common name: Parallels Panel
- Organization name: Parallels
- Organizational unit: Parallels Panel
===
Exiting due to error: self signed certificate

1.4 EXAMPLE OUTPUT: WWW.ADOM.DE


$ ./ssl www.adom.de 443
Certificate OK: yes
Certificate subject:
- Organization name: Equifax
- Organizational unit: Equifax Secure Certificate Authority
Certificate issuer:
- Organization name: Equifax
- Organizational unit: Equifax Secure Certificate Authority
===
Certificate OK: yes
Certificate subject:
- Common name: GeoTrust Global CA
- Organization name: GeoTrust Inc.
Certificate issuer:
- Organization name: Equifax
- Organizational unit: Equifax Secure Certificate Authority
===
Certificate OK: yes
Certificate subject:
- Common name: RapidSSL CA
- Organization name: GeoTrust, Inc.
Certificate issuer:
- Common name: GeoTrust Global CA

- Organization name: GeoTrust Inc.


===
Certificate OK: no
Problem: Hostname and common name don't match.
Certificate subject:
- Common name: *.powerweb.de
- Organization name: *.powerweb.de
- Organizational unit: GT36308742
Certificate issuer:
- Common name: RapidSSL CA
- Organization name: GeoTrust, Inc.
===
Exiting due to error: Hostname and common name don't match.

2. OPENSSL PROGRAMMING IN A HIGHER LEVEL LANGUAGE:


Write a light-weight version of the first program with a higher level language of your choice. It must also
run on modern Linux, and preferably use OpenSSL in the backend. We are not strict about your choice of
language. Especially Python, Perl, Ruby and even Java and PHP are accepted.
Requirements: command line parameters identical to the previous ssl program. You may use a bundle
file with a list of all CA certificates (often /etc/ssl/certs/ca-certificates.crt). You don't need to dig
certificate details, but instead, simply print the web server's reply and exit. However, if there was a
failure in certificate verification, you must print an error message and exit before sending the HTTP
request.
The idea is to use the higher level abstraction from your language of choice, to access SSL sockets. We're
not strict about it, but your program should ideally be around 20-50 lines only.

SUBMITTING:
Do not submit something you did not write yourself. You may use short pieces of code you found on the
public Internet, but be sure to mark what is your own code and what is not!
Submit a source package (eg. zip, tar, tar.gz) with both the C/C++ program and your higher-levellanguage program to Rubyric before the deadline. Also include a very short report (a couple of
paragraphs) in which you describe the code you wrote and the functionality or lack of functionality it
has.
The submission URL for this exercise is https://rubyric.cs.hut.fi/submit/999.