T-110.5211 Cryptosystems (4 cr)

Assignment instructions


Introduction

This page contains all the necessary information to implement the course assignment. There is quite a lot of text, but please read through the page before starting the assignment to avoid common pitfalls. If you get stuck with the assignment, we welcome questions to the course e-mail address, but please read this page and the Assignment FAQ before sending e-mail.

The cryptosystems course assignment consists of two almost independent parts: (1) a simplified crypto library, and (2) a simplified TLS 1.0 (SSL 3.1) client which uses the crypto library for cryptographic operations

The assignment structure mimics the way real world cryptographic software is written: one typically uses an existing crypto library which provides basic crypto computation primitives. Cryptographic primitives need to be fast, secure, and small, which makes their implementation difficult and worth making into a shared library

Crypto library

The simplified crypto library used in the assignment is structured as follows. The crypto.CryptoUtil class provides static methods for creating instances of various cryptographic primitives. The Java interface definitions for these primitives is given in crypto.interfaces.*. When creating an instance of a cryptographic primitive, the CryptoUtil class attempts to use your implementation first if it exists (in crypto.implementations.*); if not, it uses the reference implementation (in crypto.reference.*) instead. By removing the class files of your implementations (which are initially non-working) you can make the crypto library fall back to the working reference implementations. For (almost) every primitive there is a corresponding test class (in crypto.tests) which tests the current implementation and provides some feedback of the module test that fails in case the primitive seems faulty.

As the course progresses, you're asked to implement various primitives as weekly assignments. If you fail to implement some primitives, you can use the reference implementations for those primitives you failed to implement and move on (simply remove the .class file of your implementation and ensure that the corresponding .class file of the reference implementation is intact; CryptoUtil will then use the reference automatically). The test classes (test vectors) should help you implement and test each primitive at a time. However, after implementing a primitive, you should also run the HTTPS client (see below) to ensure that your newly implemented primitive also works in the full application and not just the test classes.

Note that debugging faulty cryptographic primitives can be a very time consuming effort. If a primitive does not work, it is often difficult to figure out why: the result is simply incorrect but it's difficult to see where something went wrong inside your code.

HTTPS client

The second part of the assignment is a simplified HTTPS (HTTP-over-TLS) client, i.e. a client program which retrieves a web page from a web server and uses TLS 1.0 (SSL 3.1) to encrypt traffic. The client uses our simplified cryptographic library for all cryptographic computation and interoperates with an actual HTTPS server. The main "driver" class of the client is tlsclient.HttpsClient, which uses the CryptoUtil class for crypto computations. TLS related functionality is implemented in other classes in the tlsclient package.

However, the HTTPS client is missing some TLS-specific cryptographic parts. First, it's missing some TLS specific cryptographic primitives, that will be implemented as part of our crypto library. Second, it's missing some protocol specific cryptographic logic, in particular, handling of signature verification, certificate trust, and some handshake verification values. The HTTPS client works even without these bits but is susceptible to man-in-the-middle attacks because no actual trust is achieved for the server end. In the last assignments you are asked to complete some of this functionality to provide some trust in the server.

To help with the assignment, you should get acquainted with the TLS protocol (specified in RFC 2246); the specification will be covered in the lectures, but be prepared to peek into the specification for details. Although the framework contains large portions of the TLS protocol data manipulation code, it doesn't hurt to read through the specification (and the code), at least once.

The client implementation is very minimal. The intent is to have a client that will interoperate with a TLS 1.0 compliant server, without implementing all required features of RFC 2246. The client is incomplete in at least the following ways:

  • The client does not implement the mandatory ciphersuite in RFC 2246 (TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA), but uses TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA instead.
  • The client does not support the TLS alert protocol fully, but bails out with an exception instead.
  • The client does not support rekeying, i.e. it does not respond to a "hello request" sent by the server.

Even with these limitations, the client is a useful example of a real world cryptosystem implementation.

Deliverables and requirements

Each weekly exercise is returned by emailing a complete copy of the project files in a single zip file named deliverable-x-your_student_id.zip (i.e. first return would be deliverable-1-12345A.zip, second deliverable-2-12345A.zip etc) to the t-110.5210@tml.hut.fi with the subject "T-110.5210 exercise deliverable". You can leave the message body empty. You should get an acknowledgment from course staff; if you do not get one in a couple of days, get in touch.

Deliverables are processed semi-automatically, so please make sure that you follow the correct naming scheme and send the entire content of the crypto2008 directory with your deliverable. You should also make sure that your deliverable does not contain any extra files from for example from Java IDE you may use as we have limited space in our email inboxes.

Here is an example on how to create your deliverable .zip file:

  • Move to the directory under which you have the crypto2008 directory
  • Create the zip file - zip -r deliverable-1-12345A.zip crypto2008
  • Your ZIP should look as follows:
    		$ unzip -t deliverable-1-12345A.zip
    	Archive:  deliverable-1-12345A.zip
    	testing: crypto2008/              OK
    	testing: crypto2008/tlsclient/    OK
    	testing: crypto2008/tlsclient/HttpsClient.java   OK
    	testing: crypto2008/tlsclient/TlsConnectionState.java   OK
    	[...]
    	No errors detected in compressed data of deliverable-1-12345A.zip.
    	

Weekly exercises are individual. You can discuss the problems together with your friends (and we encourage this), but everyone must write their code on their own. If you have difficulties, you can ask the course staff for help after the lectures, or send e-mail to t-110.5210@tml.hut.fi.

Grading

Each deliverable is graded pass/fail. The grade of the whole assignment is then determined by the number of passed deliverables according to following table:

  • 2 or less: 0
  • 3: 1
  • 4: 3
  • 5 or more: 5

What existing code you may use

  • The Java framework provided in the course should contain all necessary external code for your client implementation. You may use basic Java classes, of course, except when they relate to cryptography (unless explicitly allowed).
  • Symmetric cryptography
    • SingleDesEcb.java is the only symmetric encryption primitive you may use. You must implement your 3DES-EDE-CBC on top of this primitive. You explicitly may not use existing DES/3DES implementations provided by Java.
    • Instead of java.security.MessageDigest you should use CryptoUtil to get MD5 and SHA1 instances. If you implement MD5 or SHA1 extra assignments, you of course need to implement them without using existing MD5 or SHA1 primitives from Java.
    • Note that in the extra assignments (Extra 1-3) you must implement the primitives from scratch. i.e. you are NOT allowed to use SingleDesEcb.java or MD5/SHA1 from CryptoUtil.
  • Asymmetric cryptography
    • X.509 parser from java.security.cert.*
    • java.security.interfaces.RSAKey
    • java.security.interfaces.RSAPublicKey
    • java.security.interfaces.RSAPrivateKey
  • Other
    • java.math.BigInteger, except that you may not use the modPow function (use CryptoUtil.getModExpInstance() instead)
  • If you're uncertain, e-mail course staff.

Getting help

You can get help on the course assignment through the course e-mail. Before sending e-mail, please check the following:

  1. This page
  2. The FAQ page
  3. The README and Javadoc files in the project files
  4. The comments in implementation source files

Resources and other information

  • Javadoc documentation in the project .zip file under crypto2008/doc directory (important!)
  • Comments inside project java files (there are also links to external resources in the JavaDoc and in project files).
  • Specifications
    • RFC 2246: TLS 1.0
    • RFC 2104: HMAC
    • Java(TM) 2 Platform, Standard Edition, v1.5.0 API Specification
      • http://java.sun.com/j2se/1.5.0/docs/api/overview-summary.html
      • Look at the following (at least):
        • java.math
          • java.math.BigInteger
        • java.security
          • java.security.MessageDigest
        • java.security.cert
          • java.security.cert.CertificateFactory
          • java.security.cert.X509Certificate
        • java.security.interfaces
          • java.security.interfaces.RSAKey
          • java.security.interfaces.RSAPublicKey
          • java.security.interfaces.RSAPrivateKey
    • PKCS #1 v1.5 (RSA Encryption Standard), used in TLS
  • Java environment at HUT
    • Some Computing Centre machines (e.g. kosh.hut.fi) have Java version 1.4.2, some (e.g. vipunen.hut.fi) have version 1.5.0. The Java framework given to you should work with both versions. (Please report if there are problems). You may use another environment, but your code must work in some Computing Centre Unix machine; otherwise you will have difficulties in the demonstration.
  • Testing against a real server:
    • TLS uses port 443 by default.
    • You can use e.g. www.samivaarala.com/index.html for testing:
      java tlsclient.HttpsClient www.samivaarala.com 443 /index.html testpage.out (followed by CTRL-C when loading is done)