Wednesday, June 6, 2012

New SSL certificates for tomatoUSB and tomato

Problem: Google Chrome under MacOS (after Apple's 10.7.4) update will not connect (https://) to tomatoUSB admin page

Solution: generate a new 1024 bit self-signed certificate for your tomatoUSB router

Hints thanks to the following links:
http://tomatousb.org/forum/t-274362
http://tomatousb.org/tut:use-ssl-certificate-for-wan-admin
and the tomato source code (follow the source in httpd.c which launches 'gencert.sh').

Read the links above and ensure you are comfortable with that is needed to be done. The information below is only an addendum to those steps to help and is not intended to replace those instructions.

The file, /usr/sbin/gencert.sh has the steps needed to generate a new self-signed certificate. The problem with the script is that it generates an rsa 512-bit key which Apple's update flags as a weak key.

Before following the instructions contained within the links above, I was motivated to use 'openssl' and the specific command line arguments used by tomatoUSB without trying to guess just what flags I should/could use to make the proper certificates and keys. So using the commands in 'gencert.sh':

log on to your tomatoUSB router (ssh root@192.168.1.1)
cd /tmp
mkdir new
cd new
sed 's/rsa:512/rsa:1024/g' \
    < /usr/sbin/gencert.sh \
    > ./gencert.sh
chmod 755 ./gencert.sh
# see code below about generating a serial number
export _serial=433691111918831033
./gencert.sh ${_serial}
This will put two new files in /etc (cert.pem and key.pem). You can check the results by issuing the commands:
openssl x509 -text -in /etc/cert.pem
openssl rsa  -text -in /etc/key.pem
Now you can follow the remaining instructions shown in the links above

Result: Chrome will now connect (again) to https://192.168.... (admin interface)

Ahh... the code to generate the serial number. You can compile and run this code on any machine with a good GNU C compiler. This was inspired from the code in httpd.c from the tomato source code. Warning: i was lazy, there is absolutely no error checking in this code.

#include <stdio.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>

main()
{
  unsigned long long sn;
  int f = open("/dev/urandom", 0);
  read (f, &sn, sizeof(sn));
  printf ("%llu\n", sn & 0x7FFFFFFFFFFFFFFFUL);
}