How we built a PKI and a TSA and got them certified in 6 months
Part 4: Time Stamping Authority

Dani Jimenez
Signaturit Tech Blog
8 min readFeb 28, 2019

[Part 1, Part 2, Part 3]

We got to the final monster! The one that will make us battle the most. But don’t worry, we’ll find some good weapons along the way…

What do we have to build exactly?

In Part 1 of this blog post we already talked about how a Timestamping Authority works.
But, is there some standard that specifies the communication protocol?

There is!

There’s an RFC, more precisely RFC 3161 Internet X.509 Public Key Infrastructure: Time-Stamp Protocol (TSP), which specifies the protocol and data structures to use when communicating with a TSA.

Data structures, including time stamp requests and responses are specified as ASN.1 encoded messages, which is a type of encoding widely used in cryptography.

Implementing all the ASN.1 data structures specified in the RFC would have taken us some time…

Fortunately for us, the guys from the Legion of Bouncy Castle Inc. have got us covered. They provide a wide variety of cryptographic APIs and tools, including one which implements all data structures related with time stamping complying with RFC 3161.

Bouncy Castle libraries are provided for Java and C# programming languages. Because I had way more experience in Java and I know the language has a pretty good Cryptographic API with the JCA/JCE, this was the chosen option.

So we already have:

  • In/Out service interface specifications
  • Data structures
  • Programming language

Let’s keep going…

Infrastructure

As any other application, our TSA has to communicate with a list of external services including in this case the database and the Hardware Security Module (HSM).

We will focus on the communication with the HSM and how that’s performed from the application logic all the way to the hardware device deployed in the data center.

Our application is written in Java, therefore cryptographic operations rely on the Java Cryptographic Api (JCA).

The way the JCA works is it relies on Java Cryptographic Providers. A provider is an implementation of the JCA spec. One provider might not implement every method specified in the JCA.

For example the SunEC provider will implement cryptographic operations related to Elliptic Curve Cryptography.

oracle.com

Out of these Java Cryptographic Providers there’s one which is a special case. It’s the Java SunPKCS11 provider.

First of all, what is PKCS#11?

PKCS#11, also kown as “Cryptoki”, is an application programming interface to communicate with cryptographic tokens in order to manage keys and perform cryptographic operations. It’s a very common interface to comply with for Hardware Security Modules and Smart cards.

So, in this case, the SunPKCS11 provider does not implement any JCA operation itself, instead it acts as a wrapper loading a third party PKCS#11 library implementation.

As we said in part 2 of this blog post, the HSM that we purchased was provided with a PKCS#11 library, that is the HSM manufacturer’s implementation of the PKCS#11 interface. This way we can use the Java JCA along with the SunPKCS11 provider to load the library provided by the HSM vendor in order to communicate with the HSM.

Here is the whole picture:

If you read part 2 of this blog post, you might be thinking…

- But wait, didn’t the HSM vendor provide a JCA Provider implementation already? So why not use that directly instead of using an added abstraction layer with the PKCS#11 interface?

You’re right, but here is why…

In Signaturit we have different environments:

  • Develop, which can be the developer’s own computer when implementing a new functionality for the TSA, or even when modifying a service that has to interact with the TSA.
  • QA environment, where most of the testing is done.
  • Sandbox, which is a sort of pre-production environment using same infrastructure as PROD but different data.
  • Production, the environment that the end users get to interact with.

It would be a bad decision to use the HSM for every environment, plus, making the HSM available from each one of these environments would not be a savvy decision in terms of security.

So, how can we “mock” the Hardware Security Module so a developer can interact with it or with the TSA without having direct connection with the hardware?

There are different options to do this. For example we could have switched between the HSM’s JCA provider and one of Java’s default, or even implemented our own mock JCA provider.

Our decision was to stick with PKCS#11 interface, as it’s an industry standard, and depending on the environment load the HSM vendor’s PKCS#11 implementation library, or the mock version.

But where do we find a “mock” implementation version of the PKCS#11 interface? Do we implement it ourselves?

Luckily, the guys from Open DNSSEC had already solved our path. They developed a software based PKCS#11 implementation which is called SoftHSM.

With this we could switch from the software based implementation to the hardware solution dynamically loading one library or another.

Deployment

Our application is a Java 8 application using Spring Boot framework.

If you remember, we needed a middleware software provided by the HSM vendor to perform the ultimate communication with the HSM through the network. This middleware had to be installed over an O.S, so,because we’re using AWS, that pretty much imposed us to use Docker containers (no lambda function implementation possible).

More precisely we’re using Docker containers with EC2 instances and ECS orchestrator.

The communication between our application and the HSM placed in the data center is performed through a VPN established from the AWS VPC and our network deployed in the data center.

Time synchronization

Time synchronization is a critical aspect for a Time Stamping Authority. Remember that a time stamp is performed applying a digital signature to some data (usually a hash of the original data) along with a time reference.

This time reference must come from a trusted source. For some documents a time deviation for the moment on which they were signed can be critical.

So how do we make sure our time reference is correct?

We use Network Time Protocol (NTP). NTP is a protocol for clock synchronization between computers.

I won’t go too deep into NTP details because it’s a pretty complex subject itself and we could write a whole blog post about it, but if you have any questions, for example an explanation of the stratums hierarchy, don’t hesitate to write them in the comment’s section and I’ll do my best to answer them.

As we already mentioned, our application runs in a docker container which is deployed in AWS, so it runs inside an EC2 machine. For each docker container its time is synchronized with the host’s time, that means with the EC2 machine’s time.

What we have done is we have set up a service called chrony in the EC2 machine. This service, chrony, has been configured with a list of trusted NTP servers that are geographically close to Dublin, which is the AWS region we use. If working properly, the service maintains the EC2 machine and Docker containers time synchronized with UTC time within a deviation of milliseconds.

Unfortunately the synchronization for the EC2 host is not enough. The ETSI documents regarding Policy and Security Requirements for Trust Service Providers issuing Time-Stamps states that if a time deviation over one second is detected, the Time Stamping Authority must not issue any time stamp.

So besides the time synchronization performed at the O.S. level, we needed to have a synchronization process performed at the application level, and if a deviation bigger than one second is detected, the TSA service is stopped, no time stamps are issued and an alert is raised to trusted personnel.

Audit generation

The ETSI documentation requires the TSA to generate audit data for certain events.

In the case of the Time Stamping Unit (TSU), which is the ultimate application instance that performs the time stamps, these events are mainly two:

  • Time synchronization event
  • Time Stamp issuance event

The data recorded for a time synchronization event is:

  • id: Auto increment id for the row
  • action: Enum type indicating if the result of the synchronization was correct or incorrect
  • accuracy: The accuracy of the deviation from UTC time calculated during that synchronization event
  • message: “OK” or error message indicating the reason for the incorrect synchronization
  • time: Insert time for the audit registry
  • host: Host name of the machine that performed the synchronization
  • mac: Message Authentication Code for the audit registry (we’ll talk about this in a moment)

The data recorded for a time stamp issuance event is:

  • id: Auto increment id for the row
  • action: Time Stamp request result as defined in RFC 3161 (granted, granted with mods, rejected, waiting, revocation warning, revocation notification)
  • serial: Serial for the issued time stamp
  • timestamp_response: The whole ASN.1 encoded time stamp token
  • time: Insert time for the audit registry
  • host: Host name of the machine that performed the issuance
  • mac: Message Authentication Code for the audit registry

Because time stamps are performed on previously hashed data, there are no privacy considerations regarding the input data included in the time stamp response that’s stored.

Another restriction that the ETSI documentations specifies is that audit registries shall be protected to ensure their integrity.

The way we do that is we use a Message Authentication Code. A MAC function is a “keyed function” that generates a tag from the given input data. That generated tag can be used to verify the input data’s integrity and authenticity.

The key used to generate that MAC is a symmetric key which is stored in the HSM.

Certification

After all the work done and all the decisions taken, it was time to face the audit process to become a Qualified Trust Service Provider issuing Qualified Time Stamps.

Ultimately the audit process was successfully passed and Signaturit was included in the European Union Trusted List.

So that’s it! We finished the last part of the blog post.
Thank you for reading!

About Signaturit

Signaturit is a trust service provider that offers innovative solutions in the field of electronic signatures (eSignatures), certified registered delivery (eDelivery) and electronic identification (EID).

Open Positions

We are always looking for talented people who share our vision and want to join our international team in sunny Barcelona :) Be a SignaBuddy > jobs

--

--