PUSHTLS(2) PUSHTLS(2)
NAME
pushtls, tlsClient, tlsServer, initThumbprints,
freeThumbprints, okThumbprint, okCertificate, readcert,
readcertchain - attach TLS1 or SSL3 encryption to a
communication channel
SYNOPSIS
#include <u.h>
#include <libc.h>
int pushtls(int fd, char *hashalg, char *encalg,
int isclient, char *secret, char *dir)
#include <mp.h>
#include <libsec.h>
int tlsClient(int fd, TLSconn *conn)
int tlsServer(int fd, TLSconn *conn)
uchar *readcert(char *filename, int *pcertlen)
PEMchain *readcertchain(char *filename)
Thumbprint *initThumbprints(char *ok, char *crl, char *tag)
void freeThumbprints(Thumbprint *table)
int okThumbprint(uchar *hash, int len, Thumbprint *table)
int okCertificate(uchar *cert, int len, Thumbprint *table)
DESCRIPTION
Transport Layer Security (TLS) comprises a record layer pro-
tocol, doing message digesting and encrypting in the kernel,
and a handshake protocol, doing initial authentication and
secret creation at user level and then starting a data chan-
nel in the record protocol. TLS is nearly the same as SSL
3.0, and the software should interoperate with implementa-
tions of either standard.
To use just the record layer, as described in tls(3), call
pushtls to open the record layer device, connect to the com-
munications channel fd, and start up encryption and message
authentication as specified in hashalg, encalg, and secret.
These parameters must have been arranged at the two ends of
the conversation by other means. For example, hashalg could
be sha1, encalg could be rc4_128, and secret could be the
base-64 encoding of two (client-to-server and server-to-
client) 20-byte digest keys and two corresponding 16-byte
Page 1 Plan 9 (printed 10/28/25)
PUSHTLS(2) PUSHTLS(2)
encryption keys. Pushtls returns a file descriptor for the
TLS data channel. Anything written to this descriptor will
get encrypted and authenticated and then written to the file
descriptor, fd. Pushtls, tlsClient and tlsServer close the
original file descriptor on success. If dir is non-zero,
the path name of the connection directory is copied into
dir. This path name is guaranteed to be less than 40 bytes
long.
Certificates
Alternatively, call tlsClient to speak the full handshake
protocol, negotiate the algorithms and secrets, and return a
new data file descriptor for the data channel. Conn points
to a (caller-allocated) struct:
typedef struct TLSconn {
char dir[40]; /* OUT connection directory */
uchar *cert; /* IN/OUT certificate */
uchar *sessionID; /* IN/OUT session ID */
uchar *psk; /* opt IN pre-shared key */
int certlen, sessionIDlen, psklen;
int (*trace)(char*fmt, ...);
PEMChain *chain;
char *sessionType; /* opt IN session type */
uchar *sessionKey; /* opt IN/OUT session key */
int sessionKeylen; /* opt IN session key length */
char *sessionConst; /* opt IN session constant */
char *serverName; /* opt IN server name */
char *pskID; /* opt IN pre-shared key ID */
} TLSconn;
defined in libsec.h. On input, the caller can provide
options such as cert, the local certificate, and sessionID,
used by a client to resume a previously negotiated security
association. On output, the connection directory is set, as
with listen (see dial(2)). The input cert is freed and a
freshly allocated copy of the remote's certificate is
returned in conn, to be checked by the caller according to
its needs. One way to check the remote certificate is to
use initThumbprints and freeThumbprints which allocate and
free, respectively, a table of hashes from files of known
trusted and revoked certificates. okThumbprint confirms
that a particular hash is in the table.
TlsClient will optionally compute a session key for use by
higher-level protocols. To compute a session key, the
caller must set sessionType to a known session type;
sessionKeylen to the desired key length; sessionKey to a
buffer of length sessionKeylen; and sessionConst to the
desired salting constant. The only supported session type
is ttls, as used by 802.1x.
Page 2 Plan 9 (printed 10/28/25)
PUSHTLS(2) PUSHTLS(2)
TlsServer executes the server side of the handshake. The
caller must initialize conn->cert, usually by calling
readcert to read and decode the PEM-encoded certificate from
filename, return a pointer to malloced storage containing
the certificate, and store its length through pcertlen. The
private key corresponding to cert.pem should have been pre-
viously loaded into factotum. (See rsa(8) for more about
key generation.)
Readcertchain will read a PEM-encoded chain of certificates
from filename and return a pointer to a linked list of
malloced PEMChain structures, defined in libsec.h:
typedef struct PEMChain PEMChain;
struct PEMChain {
PEMChain*next;
uchar *pem;
int pemlen;
};
By setting
conn->chain = readcertchain("intermediate-certs.pem");
the server can present extra certificate evidence to estab-
lish the chain of trust to a root authority known to the
client.
Conn is not required for the ongoing conversation and may be
freed by the application whenever convenient.
EXAMPLES
Start the client half of TLS and check the remote certifi-
cate:
conn = (TLSconn*)mallocz(sizeof *conn, 1);
fd = tlsClient(fd, conn);
if(!okCertificate(conn->cert, conn->certlen, table))
sysfatal("suspect server: %r");
Run the server side:
fd = accept(lcfd, ldir);
conn = (TLSconn*)mallocz(sizeof *conn, 1);
conn->cert = readcert("cert.pem", &conn->certlen);
fd = tlsServer(fd, conn);
FILES
/sys/lib/tls thumbprints of trusted services
/sys/lib/ssl PEM certificate files
SOURCE
Page 3 Plan 9 (printed 10/28/25)
PUSHTLS(2) PUSHTLS(2)
/sys/src/libc/9sys/pushtls.c
/sys/src/libsec/port
SEE ALSO
dial(2), tls(3), factotum(4), thumbprint(6)
DIAGNOSTICS
Return -1 on failure.
BUGS
Note that pushtls, tlsClient and tlsServer do not close the
original file descriptor on failure, only on success.
The sessionID and cert pointers in the TLSconn structure
have to be freed by the caller.
Note that in the TLS protocol sessionID itself is public;
it is used as a pointer to secrets stored in factotum.
Page 4 Plan 9 (printed 10/28/25)