Nut TLS

From Nutwiki
Jump to: navigation, search

This is a first attempt to describe how to test the new Nut/OS TLS implementation.

Note: Currently only the server side of TLS 1.2 is implemented.
TLS 1.2 is the most recent (August 2008) version of Transport Layer Security.
Although the standard is released a few years ago, Browser developers started
implementing it just quite recently, so it is not wide spread.

Our implementation was tested with:

  • GnuTLS
  • IE 8(?)
  • Opera 12.02 (Linux & Windows)
Note: The current implementation is quite slow (it takes about 11.7 seconds on the AT91SAM7X) to do
the RSA computations for the handshake. So be a little bit patient with the connection process.
Note: This only works for ARM Controllers, AVR are (currently) not supported (the note above may be a reason why).

In Opera and IE you have to explicitly enable TLS 1.2 in the security settings (usually under "advanced settings" or similar).

You also have to install the recent version of arm-crypto-lib (from Das Labor) (link to the instruction will be inserted when instructions are written).

To build and test the Test-Server (from 'tls' in the application directory) you may follow the following instructions.

Note: The instructions are currently for GNU/Linux systems only. They might work with Windows or Mac OS X but it is not tested.
The develop/testing machine runs on a current ArchLinux installation.

Prepare

We will create a special directory for our experiments, let us call it nuttls_test_space

mkdir nuttls_test_space
cd nuttls_test_space

Here we create two more directorys, one for nutos and one for the crypto library

mkdir nut cryptolib

Build Crypto-Lib

Step 1 - get the source

cd cryptolib
git clone git://das-labor.org/users/bg/arm-crypto-lib .

This may take some time (it has to download ~260MiB of data).

Step 2 - configure

Normally there should be nothing to configure. But you should check that the build options defined in Makefile_sys_conf.inc and Makefile_arm7tdmi_conf.inc match the build options for Nut/OS (especially the ABI).

Step 3 - build

It should be as easy as running:

make -f Makefile_arm7tdmi lib

You should now have a library (bin/arm7tdmi_generic/lib/libcrypto.a).

Step 4 - install

First you have to install the library. Therefore copy the file bin/arm7tdmi_generic/lib/libcrypto.a into the library directory of your toolchain (for example /usr/arm-elf/lib/ on my system) and change the permissions so that your user can read it.

sudo cp bin/arm7tdmi_generic/lib/libcrypto.a /usr/arm-elf/lib/ <br>
chmod 664 /usr/arm-elf/lib/libcrypto.a

Next you have to install the header-files. You can use the script install_headers.sh but have to adjust the PREFIX variable (line 3) to match the header directory of your toolchain.

sudo sh install_headers.sh


Build Nut/OS and Testserver

Step 1 - get the source

Then we check out the current nuttls-development-tree

cd nut <br>
svn co https://ethernut.svn.sourceforge.net/svnroot/ethernut/branches/devnut_tls .

Step 2 - configure the source

If you have not installed nutconf or qnutconf before you should do it now. [[1]] may shows you how.

So we are still in our nut directory (you should avoid to confuse it with the nut directory we just got with our check-out).

nutconf

Will start the graphical configuration interface. It will ask you for your configuration file and you should select the one matching your board (current tests run on an AT91SAM7X-EK, if you are lucky enough to have this board you may directly select tls_at91sam7x-ek.conf).

You should at least adjust the Main Thread Stack Size to 2048 bytes (the RSA computation takes a lot of stack).

Nut/OS Components -> RTOS Kernel -> Multithreading -> Main Thread Stack Size -> 2048

You may adjust other items, like your compiler, libc, ...

For our purposes we set the nut build directory to nut_build and the application (sample) directory to nut_app in the "Settings Menu" ( Edit -> Settings).

Now you have to build Nut/OS:

Build -> Build Nut/OS

And create the app directory:

Build -> Create Sample Directory

Step 3 - build the TLS Test-Server

cd nut_app/tls <br>
make

You now should have working binaries. You may be able to use

make burn

to flash your binary to your board. This did not work for me, so if you have an AT91SAM7X-EK you may instead run

sh flash.sh

Testing the Test-Server

First you have to identify which IP-Address is assigned to your board by the DHCP-Server. To get this information you may query your DHCP-Server, or get it from the Debug output from your board (you did connect the UART/RS232 interface to the debug port, didn't you?).

You should see the following output (or at least quite a similar one, since this changes during development):

 
Nut/OS 4.10.0.0
TLS Server Sample 0.1.0
Configure eth0...OK
Run 'gnutls-cli 192.168.192.243 443' to connect to this server
Register UROM file system...OK.

spawning thread: tls_0

Waiting for a tls client...
spawning thread: tls_1

Waiting for a tls client...
spawning thread: tls_2

Waiting for a tls client...
 

Here our address is 192.168.192.243, this will be different on your board.

Now you can add a hostname for this IP-Address to your machines configuration

sudo echo <board-ip> nuttls_test_system >> /etc/hosts

It is now time to connect via TLS. I recommend using the command-line utility from GnuTLS:

gnutls-cli --x509cafile cert/nuttls_test_system.cert nuttls_test_system


 
Now the following should appear on your terminal:
Processed 1 CA certificate(s).
Resolving 'nuttls_test_system'...
Connecting to '192.168.192.243:443'...
- Peer's certificate is trusted
- The hostname in the certificate matches 'nuttls_test_system'.
- Session ID: E4:0E:C7:B0
- Certificate type: X.509
- Got a certificate list of 1 certificates.
- Certificate[0] info:
 - subject `C=DE,O=egnite GmbH,ST=NRW,CN=Daniel Otte', issuer `C=DE,O=egnite GmbH,ST=NRW,CN=Daniel Otte', 
   RSA key 512 bits, signed using RSA-SHA256, activated `  2012-06-18 17:09:27 UTC', 
   expires `2013-06-18 17:09:27 UTC', SHA-1 fingerprint `6ff3f09462e388468f96eaef941baf95c169be83'
	Public Key Id:
		4b16eff5669cf1ed071cc55eb3e52953fc23c5e6
	Public key's random art:
		+--[ RSA  512]----+
		|              o. |
		|               B=|
		|        .     =+B|
		|         o   +.E+|
		|        S . ..=..|
		|       o o . oo+.|
		|        . .   *.o|
		|             o ..|
		|                o|
		+-----------------+ 

- Version: TLS1.2
- Key Exchange: RSA
- Cipher: AES-128-CBC
- MAC: SHA256
- Compression: NULL
- Handshake was completed 

- Simple Client Mode:
 

You have now opened a direct connection to the board (it a little bit like telnet). You can now start an HTTP-Request (note the blank line afte the GET ... line)

GET / HTTP

The Server should respond with

 
HTTP/1.1 200 Ok
Server: Ethernut 4.10.0.0
Content-Type: text/html
Content-Length: 59
Connection: close

<html>
<head></head>
<body>
<h1>Works</h1> 
</body>
</html>
 

And then it should close the connection.

Generating your own certificate

For this steps you currently need a working C-Compiler (gcc is used in the examples) and a working ruby environment.

You may be interested in getting your own certificate on the board. There are many good tutorials how to set up a PKI so we will not go to much into detail here. So for now we assume you have a RSA certificate in DER form and a matching key in text form as shown in the example below (created with certtool from gnuTLS):

 
Public Key Info:
        Public Key Algorithm: RSA
        Key Security Level: Low

modulus:
        00:c4:04:46:32:2b:18:eb:56:d4:01:7a:4e:db:b7:
        50:05:34:65:64:07:26:86:b8:d0:2b:d9:d5:3d:35:
        d8:4e:77:f8:6b:21:9a:be:a5:6f:4c:ef:82:1c:58:
        36:7a:f1:ba:81:1e:32:8c:d4:5c:dc:df:6e:13:b6:
        dc:d9:49:0a:25:
public exponent:
        01:00:01:
private exponent:
        00:c2:a4:0f:e4:3f:41:66:67:78:eb:e2:bc:ad:96:
        b0:c2:0a:4e:67:ee:65:c6:3f:7c:8f:1e:a6:8d:3a:
        8b:89:15:fd:8d:11:aa:f8:ad:a7:cf:5c:c7:86:11:
        83:cc:f8:37:16:14:a5:3e:53:8b:ce:c4:42:46:bf:
        7f:b0:11:d7:bd:
prime1:
        00:c4:97:6d:6a:04:19:0c:69:b0:16:63:74:73:d2:
        cf:21:2c:00:47:6e:4c:88:a0:8b:d6:69:25:e2:82:
        00:ce:db:
prime2:
        00:ff:40:60:d2:35:bb:a0:18:fa:2a:aa:65:bc:d5:
        35:65:fb:c0:f6:20:4b:33:65:a2:97:43:d7:04:7b:
        e6:5a:ff:
coefficient:
        00:9a:2b:48:98:ac:76:06:a4:05:f6:c6:ec:0f:70:
        c8:47:44:98:0f:1f:ec:26:61:f7:04:2c:7f:2d:55:
        b6:ce:67:
exp1:
        54:c6:4b:fb:6c:9a:f4:9c:5a:bf:bc:d1:89:e4:bd:
        47:3b:b7:3f:16:54:50:92:92:da:b9:eb:09:5b:30:
        48:03:
exp2:
        31:8c:9b:be:f2:b3:53:66:c5:d9:56:6e:9d:73:7e:
        04:28:14:d3:32:7d:a6:a2:8a:27:77:01:dc:5a:f8:
        e2:9d:

...
 

The next step is compiling the cert-merge tool in the directory cert:

cd cert
gcc -o cert-merge cert-merge.c

You are now able to create new certificate-binary-blobs. If nuttls_test_system.cert.der is your DER-certificate you can use

./cert-merge nuttls_test_system.cert.tls nuttls_test_system.cert.der

to create a binary blob for the nutTLS system. To include this blob you may like to create an elf-file like this:

 arm-elf-objcopy --rename-section .data=.rodata,alloc,load,readonly,data,contents \
                 -I binary -O elf32-littlearm nuttls_test_system.cert.tls \
                 nuttls_test_system.cert.tls.elf

Now you should have nuttls_test_system.cert.tls.elf ready for linking into your project. If you changed the input file name for the elf-file you should adjust the Macros CERT_BLOB_START, CERT_BLOB_END and CERT_BLOB_SIZE in tls_handshake.c as they are based on the file name.

What is left is inclusion of the key. The key is transformed into C-source-code by convert-key.rb. convert-key.rb is a ruby script which transforms a RSA key given in the text form shown above into C-code. If your key file is named nuttls_test_system.key, you may use the following command:

ruby convert-key.rb nuttls_test_system.key > server.key.c

If you copy both new created files (nuttls_test_system.cert.tls.elf and server.key.c) in the projects directory and recreate the project:

make clean all

You should have a working binary with your certificate.