pushtls, tlsClient, tlsServer, initThumbprints, freeThumbprints, okThumbprint, readcert, readcertchain \- attach TLS1 or SSL3 encryption to a communication channel
.SHSYNOPSIS
.B#include<u.h>
.br
.B#include<libc.h>
.PP
.B
int pushtls(int fd, char *hashalg, char *encalg,
.br
.B
int isclient, char *secret, char *dir)
.PP
.B#include<mp.h>
.br
.B#include<libsec.h>
.PP
.B
int tlsClient(int fd, TLSconn *conn)
.PP
.B
int tlsServer(int fd, TLSconn *conn)
.PP
.B
uchar *readcert(char *filename, int *pcertlen)
.PP
.B
PEMchain *readcertchain(char *filename)
.PP
.B
Thumbprint* initThumbprints(char *ok, char *crl)
.PP
.B
void freeThumbprints(Thumbprint *table)
.PP
.B
int okThumbprint(uchar *hash, Thumbprint *table)
.SHDESCRIPTION
Transport Layer Security (TLS) comprises a record layer protocol,
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 channel in the record protocol.
TLS is nearly the same as SSL 3.0, and the software should interoperate
with implementations of either standard.
.PP
To use just the record layer, as described in Plan 9's
\fItls\fR(3),
call
.Ipushtls
to open the record layer device, connect to the communications channel
.IRfd,
and start up encryption and message authentication as specified
in
.IRhashalg,
.IRencalg,
and
.IRsecret.
These parameters must have been arranged at the two ends of the
conversation by other means.
For example,
.Ihashalg
could be
.BRsha1,
.Iencalg
could be
.BRrc4_128,
and
.Isecret
could be the base-64 encoding of two (client-to-server and server-to-client)
20-byte digest keys and two corresponding 16-byte encryption keys.
.IPushtls
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,
.IRfd.
If
.Idir
is non-zero, the path name of the connection directory is copied into
.IRdir.
This path name is guaranteed to be less than 40 bytes long.
.PP
Alternatively, call
.ItlsClient
to speak the full handshake protocol,
negotiate the algorithms and secrets,
and return a new data file descriptor for the data channel.
.IConn
points to a (caller-allocated) struct
.EX
typedef struct TLSconn{
char dir[40]; // OUT connection directory
uchar *cert; // IN/OUT certificate
uchar *sessionID; // IN/OUT sessionID
int certlen, sessionIDlen;
void (*trace)(char*fmt, ...);
PEMChain *chain;
} TLSconn;
.EE
defined in
.IRtls.h.
On input, the caller can provide options such as
.IRcert,
the local certificate, and
.IRsessionID,
used by a client to resume a previously negotiated security association.
On output, the connection directory is set, as with
.Blisten
(see
.IRdial(3)).
The input
.Icert
is freed and a freshly allocated copy of the remote's certificate
is returned in
.IRconn,
to be checked by the caller
according to its needs. One mechanism is supplied by
.IinitThumbprints
and
.IfreeThumbprints
which allocate and free, respectively, a table of hashes
from files of known trusted and revoked certificates.
.IokThumbprint
confirms that a particular hash is in the table, as computed by
.PP
.EX
uchar hash[SHA1dlen];
conn = (TLSconn*)mallocz(sizeof *conn, 1);
fd = tlsClient(fd, conn);
sha1(conn->cert, conn->certlen, hash, nil);
if(!okThumbprint(hash,table))
exits("suspect server");
...application begins...
.EE
.PP
Call
.ItlsServer
to perform the corresponding function on the server side: