TLS daemon with PKCS #11 backend
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



The tlspool package concentrates TLS usage by client and server applications.
It gets passed a file descriptor of a socket, initiates TLS over it, and
then makes a callback with authenticated local/remote identities in a
request for an additional file descriptor for the plaintext side.  This
approach makes it straightforward to add TLS support to network software,
and the central location of the TLS Pool makes it easy to enforce consistent
rules for authentication and authorization rules.

Current development

The actual daemon design is part of the plans of,
which aims to improve everyone's Internet quality through distribution of
more protocols and facilities with strong encryption and privacy.  The
full stretch of this project is documented on
The practical/project side of this project is called, and the
website for the TLS Pool can be found at

We are currently at a state where the daemon and a small stub library for
applications are working for certificate authentication using X.509 certs
and/or OpenPGP keys.  We have built-in initial support for a few upcoming
authentication approaches, namely Secure Remote Passwords and our own
work on TLS-KDH,

Please see the TODO file for work that has not yet been completed.

Using the library API

The core logic used here is (client shown, server is similar):

	#include <tlspool/starttls.h>
	plainfd = -1;
	if (-1 == starttls_client (fd, &tlsparams, &plainfd, NULL)) {
		if (plainfd >= 0) {
			close (plainfd);
			plainfd = -1;
		...error reporting...
	} else {
		...continue to use plainfd...

The daemon will cover TCP, UDP and SCTP over IPv4 and IPv6.  Asynchronous
versions of these calls are possible by directly talking to the UNIX domain
socket of the API.  The library routines above are only simple interfaces
to these socket interactions.

Unlike with common libraries, the identity forms (X.509 certificates,
OpenPGP keys, Kerberos tickets, ...) are not made available to the
application.  What is provided, are authenticated identities contained
in the tlsparams structure after this call.

The importance of PKCS #11

The key material used by this daemon will be accessed over PKCS #11.  Compromise
will require multi-layered attacks to key material: the material is protected
by a secure key store of choice, in hardware or software, and even the PIN
for using the private keys without seeing them is stored in a separate
program, namely the TLS Pool.  Specifically, the PIN and key material are
not available to user agents such as a PHP-enabled web server which may
be running outdated software.

Aside from the improved key protection and the ability to choose a security
level by choosing the PKCS #11 implementation accordingly, it is useful to
have a central location for key storage; this simplifies maintenance tasks,
such as certificate renewals and (PIN encrypted) secret key backup.

One last advantage of using PKCS #11 is that this enables a form where
USB token manufacturers can provide a tool that functions as a HTTP proxy,
and that establishes secure connections to selected parties with an OpenPGP
key and no further infrastructure.  End users can plugin their token to
get secured access, and remove it to stop further secure web connections.
Note that this principle can easily be extended to other protocols that
can work through a proxy.

Note that it is expressly not the task of the TLS Pool to manage the
objects stored behind the PKCS #11 API.  This is expressly left to
external tools that manage certificates and keys on behalf of the
application area covered.  All the TLS Pool does is read tokens, looking
for usable keys to authenticate its identities to the Internet, both over
X.509 and over OpenPGP.

One final, and hardly recognised use of having a central TLS Pool and
potentially centralised PKCS #11 repositories is the ability to monitor
the network traffic for intrusion attempts.  To be able to do this in
the presence of encrypted connections, the ability to decrypt the
traffic must be offered to sniffers like Snort.  The decryption usually
involves manual input of certificates and private keys, which is no
longer necessary with PKCS #11 with remote access to the API in place.
So, large-scale organisations could setup a networked HSM and use it
both for production use and for feeding the intrusion detectors.

The use of Central Configuration

It is common for TLS applications to have locally defined settings for
things like cipher suites, keys, methods of authentication supported, and
much more.  Given the complexity of TLS and the application-specific
format of configuration, the result is not ideal:

  - Applications need to concern themselves with security issues.  In most
    cases, the ability to externalise these concerns is desirable for the
    application programmer, system administrator and security officer.

  - When changes are necessary, many applications need to be reconfigured,
    each in their own format.  This is a problem when such changes are
    needed as a result of security disclosures.

  - Not all applications cover the full range of features that TLS can
    offer.  This means that security policies are constrained to the
    lowest common denominator.

The TLS Pool resolves this situation by not interfacing with the application
about security settings.  All security settings are made out-of-band, and
can be set in the same way for all applications at once; variations are
supported per service, but even then the grammar is consistent.

Configuration information for the TLS Pool is stored in simple key-value
databases, whose contents may be modified without taking the TLS Pool
offline.  The databases can be managed from the commandline, over a
web-based API or from a central configuration in LDAP, using the sister
project SteamWorks, documented on -- there
is a SteamWorks Pulley plugin for TLS Pool configuration.

Additional Rules: RADIUS

TODO: Can RADIUS handle user@domain for both the user and the realm?

Local environments may have their own added requirements to authentication,
authorization and also pursue their own accounting of TLS connections.  The
common approach to these mechansims is RADIUS, which can independently
handle these three types of request.  RADIUS is designed as a fast local
protocol, and it can be rerouted with FreeRADIUS and resolved with scripts
or programs in just about any programming language.

Any AAA facilities are stacked on top of the minimum requirements offered
by the TLS Pool, that is the identities of the peers can be assumed to
have been established (or perhaps be established in parallel) while the
authentication and authorization is requested.  Note that accounting
will always wait for completion of the identity check, to avoid charging
to an innocent account.

Note that RADIUS combines authentication and authorization into one accept
phase, which is supposed to do both.  This means that in practice most
people will declare RADIUS for either authentication or authorization.
This is not a requirement though; the functions can be setup and, due to
lack of expressiveness in the protocol, split over different servers.

Accounting is not usually applied immediately when a TLS connection is
setup; this is barely useful information.  Instead, the TLS Pool is able
to receive accounting requests over the same API as it uses for the
authentication and authorization requests, and it can pass requests on
to the accounting functions of a RADIUS service.

Accounting in the style of the TLS Pool comes down to counting ticks or
time; a series of values is supplied to both the start and end that is
being accounted:

  - an identifier for the kind of thing being accounted;
  - an identifier for the instance being accounted;
  - a local and remote identity of a user@domain or of a domain.

For each of these, information is collected to support accounting:

  - the identifier for the kind of thing being accounted;
  - the identifier for the instance being accounted;
  - the local and remote identity of a user@domain or of a domain;
  - a timestamp for the start and, if present, the end of a period;
  - a final count representing the number of items being accounted.

Windows Porting

The TLS Pool makes heavy use of UNIX domain sockets, and specifically their
ability to pass a file descriptor between processes using `SOL_SOCKET` and
`SCM_RIGHTS`.  For Windows, another approach is provisioned:

TODO: This needs to be tried and built into the code base!

  - The TLS Pool offers its services through a NamedPipe
  - Waiting can be done with I/O Completion Ports
  - File descriptor passing may be ported to random-name-passing for a NamedPipe
  - This would require NamedPipe access being available only to the TLS Pool
  - Alternatively, we could use CreatePipe and DuplicateHandle