\section{Implementation details}

\subsection{Certificate formats}

The ITTC system uses the Secure Socket Layer (SSL) to authenticate and
encrypt all communication.
The administrator issues a certificate to each entity (client, share
server, and administrative utility) in the system, which must be in a
recognized format.
The CN (Common Name) field in each certificate contains a string
%(see Table~\ref{tab:cnstring}) 
that allows other parties to identify it as described in the following table:

%\begin{table}[ht]
\begin{center}
\begin{tabular}{|c|c|} \hline
Entity & ID String \\ \hline
Client & {\tt [CLIENT $n$]} \\
Share Server & {\tt [SERVER $n$]} \\
Administrator & {\tt [ADMIN $n$]} \\ \hline
\end{tabular}
%\caption{Certificate CN format}
%\label{tab:cnstring}
\end{center}
%\end{table}

When establishing an SSL-secured connection, both peers must send their
certificates to establish mutual authentication.
Each peer verifies the certificate it receives and then parses it to extract
the identifying string to ensure that the peer is authentic.
If a certificate is not sent, if verification fails, or if the
identity string does not match what was sent in the protocol,
the connection fails.

\subsection{Sequence numbers}  \label{seqnum}

Although client and server certificates thwart direct network snooping and
impersonation attacks against the servers, the ITTC threat model requires
the system to tolerate and resist successful attacks against individual
clients and servers as well.
If an attacker, for example, obtains the private key and certificate of
a legitimate client, he could use it to obtain access to any shared keys
that the client had access to.
To limit the amount of damage under these circumstances, ITTC uses
sequence numbers in the connection protocols to detect such compromises
after the fact.
Each client and server keeps a count of how many times it has been accessed
by each other entity in the system, and all connections involve an exchange
of sequence numbers to verify synchronization.
An attacker who uses a stolen key and certificate will cause the sequence
number at each server to be incremented without a corresponding change in
the sequence number at the ``victim'' client's system.
The next time that client attempts to access a server, the mismatch will
be detected.

The actual multi-step sequence number exchange proceeds as follows.
Assume that both client and server are currently synchronized at
sequence number $n$ initially:

\begin{enumerate}
\item The server sends $n$ to the client and sets its own sequence
	number to $n + 1$.
\item The client expects $n$.  It sends $n + 1$ back
	to the server.  It sets its own sequence number to $n + 1$.
	(In this step, the client also accepts $n + 1$ from the server.
	If this happens, it sends $n + 2$ back to the server and sets
	its own sequence number to $n + 2$.  The rest of the protocol
	proceeds with the client adding one to all its sequence numbers.)
\item The server expects $n + 1$.  It sends $n + 2$ back
	to the client.  It sets its own sequence number to $n + 2$.
\item The client expects $n + 2$.  It sets its own sequence number to
	$n + 2$.
\end{enumerate}

When the protocol completes successfully, both client and server hold
sequence number $n + 2$.  The advantage this protocol has over a simpler
single-increment protocol is that it distinguishes between ordinary
network failure and a genuine security breach.  In a single-increment
protocol, it is possible for a network failure to cause one party to
increment its sequence number while the other does not.  The off-by-one
discrepancy in the sequence numbers would be interpreted as a security
breach during subsequent interactions between these two parties.  This
double-increment protocol, on the other hand, increments sequence numbers
by two for each successful interaction, while ensuring that the server's
sequence number never drifts by more than one relative to the client's
number.  A network failure would result in at most an off-by-one
discrepancy, which would then be resolved in step two of the protocol.  A
real security breach would cause the numbers to differ by two or more,
presumably triggering a legitimate alarm.

\subsection{Interface to TLB}

\label{sec:tlbapi}
To access the underlying ITTC functionality, client programs link against
the TLB code and call functions in its external interface.
Since it is possible to perform all the standard RSA cryptographic
operations (encrypt, decrypt, sign, verify) with an ITTC-style RSA key,
existing applications can be rewritten to use these keys by replacing
conventional RSA calls with calls to TLB functions.

This approach has some drawbacks, most notably that it requires effort to
go through each application to find RSA cryptographic calls and replace
them with their ITTC counterparts.
Fortunately, the design of SSLeay allows us to implement the TLB interface
more elegantly.
In SSLeay, RSA keys (type {\tt RSA *}) contain not only the data
corresponding to the keys ($N$, $e$, $d$, etc.) but also pointers to
functions that perform the four basic RSA operations.
This form of polymorphism allows us to reduce the entire TLB interface
to a single function call:
\begin{verbatim}
	RSA *ITTC_load_RSA_key(char *ittckeyfile);
\end{verbatim}
This function returns an RSA object whose ``function table'' points
to functions that perform ITTC-style decryption and signing
(encryption and signature verification are handled just like an
ordinary RSA key).
Modifying an application to handle ITTC-style keys is now a matter of
changing only one piece of code, namely the code that loads RSA
keys.
Once the key is loaded in this manner, application code cannot
distinguish an RSA object obtained through ITTC from a conventional
RSA key, and no other code needs to be modified.

Section~\ref{sec:apps} contains some examples of applications that
used this technique to support ITTC-style shared keys.
This object-oriented method of encapsulating functionality with data
can be carried over to other cryptographic architectures (e.g.
Java's JCA or Microsoft CAPI) that support provider interfaces.

\comment{
\subsection{Configuration file}

ITTC uses a single text file to manage the configuration of both
clients and servers.
This file stores information such as:
\begin{itemize}
\item The IP address and port number for each share server
\item The locations of certificates, private keys, private shares, and
sequence number databases
\item Timeout lengths, threading usage, and other tunable parameters
\end{itemize}

While the ITTC servers themselves are given the name of the ITTC
configuration files upon startup, it is not always convenient or
even possible to do this when integrating ITTC into existing applications.
To handle these situations, ITTC uses an extra level of indirection to
handle shared keys.
The ``public shared key'' mentioned in Section~\ref{sec:keystruct}, which
is normally stored as a PEM-encoded file with a {\tt .pem} extension, is
not the actual shared key that is handed to applications.
Instead, an additional file points to both the public shared key data and
to the configuration file used by that key.
For example, generating a shared key {\tt key1} would result in two files.
{\tt key1.pem} would contain the numeric key parameters, while a second
file named {\tt key1.rsk} would contain entries that pointed to both
{\tt key1.pem} and the configuration file {\tt ittc.conf}, as shown below:
%Table~\ref{tab:rsk}.

%\begin{table}[ht]
\begin{verbatim}
            #include ittc.conf

            Client_ID: 0
            Shared_Key: key1.pem
\end{verbatim}
%\caption{RSA Shared Key Configuration File}
%\label{tab:rsk}
%\end{table}

The {\tt .rsk} file is the private key file given to applications.
The {\tt ITTC\_load\_RSA\_key} API call from Section~\ref{sec:tlbapi}
uses this file to find the configuration file, as well as the client
number and the actual shared key data.
By embedding the configuration information with the RSA shared key
data, this arrangement enables applications to treat the RSA shared
key file the same as a conventional RSA private key.
}

\section{Example applications}

\label{sec:apps}

\subsection{Intrusion tolerant certification authority}

\label{sec:ittcca}
The ITTC-based certificate authority application signs incoming
certificate requests with the appropriate shared private key.
The application itself is based on Eric Young's {\tt ca}
certificate authority program, which is included with SSLeay.
As described in Section~\ref{sec:tlbapi}, adapting the existing
code to handle ITTC keys involved only a minimal change to the
code, as seen in Table~\ref{tab:cacode}.

\begin{table}[ht]
\begin{verbatim}
#ifndef ITTC
  BIO_read_filename(in,keyfile);
  pkey=PEM_read_bio_PrivateKey(in,NULL,NULL);
#else
  pkey=EVP_PKEY_new();
  rsa=ITTC_load_RSA_key(keyfile);
  EVP_PKEY_assign_RSA(pkey,rsa);
#endif
\end{verbatim}
\caption{ITTC Certificate Authority Code Patch}
\label{tab:cacode}
\end{table}

The modified certificate authority ({\tt ittc\_ca}), accepts the same
inputs and command line arguments as the original program.
For example, the command
\begin{verbatim}
ittc_ca -config ca.cnf -in request.req 
    -out newcert.pem -keyfile sharedkey.rsk
\end{verbatim}
verifies the self-signed standard-form certificate request in
{\tt request.req}, signs it with the shared RSA key {\tt sharedkey.rsk},
and writes the PEM-encoded X509 result in {\tt newcert.pem}.  The file
{\tt ca.cnf} is an internal SSLeay config file.

In most applications where an ITTC private key is used, it is necessary
to obtain a signed certificate for the corresponding public key from a
well-known issuer (e.g. when using
ITTC to secure a Web server's private key, see Section~\ref{sec:distweb}).
The {\tt ittc\_req} program generates correctly-formatted, self-signed
certificate requests from ITTC-style shared keys.
The command
\begin{verbatim}
ittc_req -config ca.cnf -new 
      -key sharedkey.rsk -out request.req
\end{verbatim}
compiles a standard-form certificate request for the shared key
{\tt sharedkey.rsk} and applies the shared key once to sign it.
The output ({\tt request.req}) is indistinguishable from a
certificate request generated from a conventional RSA key and
can be sent off to any certificate authority (e.g. Verisign)
to be signed.

\subsection{Distributed web server}

\label{sec:distweb}

In addition to securing the private key for a certificate authority,
ITTC can protect private keys for a Web server.
The technique of Section~\ref{sec:tlbapi} was applied to the source
code for ApacheSSL 1.2.6 to produce an ITTC-enabled secure server.
Since Apache already used SSLeay to handle its public-key cryptography,
the entire extent of our modifications to Apache consisted of the
three lines of C code shown in Table~\ref{tab:apachemod}.

\begin{table}[ht]
\begin{verbatim}
#ifdef ITTC
   pConfig->prsaKey =
           ITTC_load_RSA_key(szPath);
#else
   pConfig->prsaKey=RSA_new();
   PEM_read_RSAPrivateKey(f,
               &pConfig->prsaKey, NULL);
#endif
\end{verbatim}
\caption{ApacheSSL Code Modification for ITTC}
\label{tab:apachemod}
\end{table}

With this change in place, Apache accepts ITTC-style private keys and
treats them as if they were conventional RSA keys.
An administrator simply generates an ITTC shared key, generates a
self-signed certificate request with the {\tt ittc\_req} application
(see Section~\ref{sec:ittcca}), and sends this request to a
recognized certificate authority.
Once the signed certificate is received, Apache is configured to
use the certificate and corresponding key with the following
entries in its configuration file, {\tt httpd.conf}:

\begin{verbatim}
SSLCertificateFile
     /usr/local/httpd/SSLconf/cert.pem
SSLCertificateKeyFile 
     /usr/local/httpd/SSLconf/privatekey.rsk
\end{verbatim}

Once the Web server is started up, it will present the certificate
{\tt cert.pem} to Web browsers and use the ITTC shared key
{\tt privatekey.rsk} to decrypt and/or sign responses.




