This is a proof of concept implementation of NTS in Python
This code is based on Daniel Franke's hackathon code which implemented parts of the NTS protocol:
Quick and dirty implementation of Network Time Security for the IETF 101 hackathon. Public domain.
Christer Weinigel email@example.com made some fixes the implementation and added a NTSKE server, a NTS/UDP server and a NTS/UDP client.
This implementation has been tested with Martin Langer's NTS implementation which can be found here:
Ubuntu 18.04. Ubuntu 16.04 does not work due to the openssl libraries being too old. Intall the following packages:
apt-get install git gcc binutils cmake libssl-dev python3-cffi
Clone the repository:
Testing the Python implementation
I've tested this implementation on Ubuntu 18.04. The scripts require Python 3.6, even though they are written to be compatible with Python 2.7. I haven't figured out why Python 2.7 doesn't work yet.
Warning: don't remove the assert sys.version_info == 3 from the files. It might seem like it's working, but the SSL.Connection will return corrupt data with some NTS servers.
Change directory to the top of the nts-poc-python tree:
Check out Daniel Fox Franke's libaes_siv implementation and build it:
git clone https://github.com/dfoxfranke/libaes_siv.git cd libaes_siv cmake . make
To start the NTSKE server, open a terminal and run:
The server uses server.ini for its configuration. The default is for the NTSKE server to listen on TCP port 4446. The master keys are stored in the directory "master_keys". If no master key exists, the NTSKE server will create a new master key.
To start the NTP/UDP server, open a terminal and run:
The server uses the file "server.ini" for its configuration. The default is for the NTSKE server to listen on TCP port 4123.
Run the NTSKE client to talk to the NTSKE server and save the results to the file "client.ini" and not perform certicate verification (-v).
python3 ntske-client.py -v localhost 4446
Run the NTS client to talk to the NTS server and get a timestamped packet back.
If you want to talk to a different NTS server than the one specified in client.ini you can specify the NTS server on the command line:
python nts-client.py host port
If you want to rotate the master key, run server_helper.py:
This will create a new key in the master_keys directory which will be read by ntske-server.py or nts-server.py on the next request.
Testing with Martin Langer's NTS implementation
As a hack to test compatibility, I've modified Martin's NTSKE server so that it saves the master keys it is using to disk in the same format as the python NTSKE implementation does. The Python implementation uses the same cookie format as Martin's implementation, that is, the one recommended in the NTS draft with a 16 byte nonce.
First of all, Martin Langer's NTS implementation requires more recent versions of cmake, openssl and boost than are available on Ubuntu 18.04, so you will have to build them yourself.
Download and build cmake-3.13.3 and install it under /opt:
wget https://github.com/Kitware/CMake/releases/download/v3.13.3/cmake-3.13.3.tar.gz tar xvfz cmake-3.13.3.tar.gz cd cmake-3.13.3 ./bootstrap --prefix=/opt/cmake-3.13.3 make -j8 make install cd ..
Download and build openssl-1.1.1a and install it under /opt:
wget https://www.openssl.org/source/openssl-1.1.1a.tar.gz tar xvfz openssl-1.1.1a.tar.gz ./config --prefix=/opt/openssl-1.1.1a make -j8 make install cd ..
Download and build boost-1.69 and install it under /opt:
wget https://dl.bintray.com/boostorg/release/1.69.0/source/boost_1_69_0.tar.gz tar xvfz boost_1_69_0.tar.gz cd boost_1_69_0 ./bootstrap.sh --prefix=/opt/boost-1.69 ./b2 install -j8 cd ..
Building Martin Langer's NTS
Clone the modified version of the ntp project:
git clone --recursive https://gitlab.com/wingel/ntp.git
Build the modified version of the ntp project:
cd ntp mkdir -p build cd build /opt/cmake-3.13.3/bin/cmake -DBOOST_ROOT=/opt/boost-1.69 -DOPENSSL_ROOT_DIR=/opt/openssl-1.1.1a ../src make
Running Martin Langer's NTS
To test this, open a terminal, clear out the master_keys generated by the Python implementaton and then run Martin's implementation:
rm -rf master_keys; ./ntp/build/ntp
Martin's implementation will use the configuration in the "config" directory which is right now set to use TCP port 4443 for NTSKE and UDP port 4123 for NTS.
To ask for cookies from Martin's NTSKE server, run:
python3 ntske-client.py localhost 4443 rootCaBundle.pem
since Martin's implementation does not send a NTPv4 Port Negotiation record, port 123 will be stored in "client.ini", so to talk to Martin's NTPv4 server, run the following command:
./nts-client.py localhost 4123
if you are running nts-server.py, you can talk to it using:
./nts-client.py localhost 4126
You can also talk to the Python NTSKE server as described above and those cookies will also work with with both server implementations.