PUSHTLS(2)PUSHTLS(2)NAME
pushtls, tlsClient, tlsServer, initThumbprints, freeThumbprints,
okThumbprint, 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)
void freeThumbprints(Thumbprint *table)
int okThumbprint(uchar *hash, Thumbprint *table)
DESCRIPTION
Transport Layer Security (TLS) comprises a record layer protocol, doing
message digesting and encrypting in the kernel, and a handshake proto‐
col, 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 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 communications 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 encryption keys. Pushtls
returns a file descriptor for the TLS data channel. Anything written
to this descriptor will get encrypted and authenticated and then writ‐
ten to the file descriptor, fd. If dir is non-zero, the path name of
the connection directory is copied into dir. This path name is guaran‐
teed 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 */
int certlen, sessionIDlen;
void (*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 */
} TLSconn;
defined in tls.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 connec‐
tion 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; ses‐
sionKey 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.
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
previously loaded into factotum. (See rsa(8) for more about key gener‐
ation.)
Readcertchain will read a PEM-encoded chain of certificates from file‐
name and return a pointer to a linked list of malloced PEMChain struc‐
tures, defined in tls.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 establish 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 certificate:
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...
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);
...application begins...
FILES
/sys/lib/tls
thumbprints of trusted services
/sys/lib/ssl
PEM certificate files
SOURCE
/sys/src/libc/9sys/pushtls.c
/sys/src/libsec/port
SEE ALSOdial(2), tls(3), factotum(4), thumbprint(6)DIAGNOSTICS
Return -1 on failure.
BUGS
Client certificates and client sessionIDs are not yet implemented.
Note that in the TLS protocol sessionID itself is public; it is used
as a pointer to secrets stored in factotum.
PUSHTLS(2)