TH PUSHTLS 2
SH NAME
pushtls, tlsClient, tlsServer, initThumbprints, freeThumbprints, okThumbprint, okCertificate, readcert, readcertchain \- attach TLS1 or SSL3 encryption to a communication channel
SH SYNOPSIS
B #include <u.h>
br
B #include <libc.h>
PP
nf
B
int pushtls(int fd, char *hashalg, char *encalg,
B
int isclient, char *secret, char *dir)
PP
nf
B #include <mp.h>
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, char *tag)
PP
B
void freeThumbprints(Thumbprint *table)
PP
B
int okThumbprint(uchar *hash, int len, Thumbprint *table)
PP
B
int okCertificate(uchar *cert, int len, Thumbprint *table)
SH DESCRIPTION
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
IR tls (3),
call
I pushtls
to open the record layer device, connect to the communications channel
IR fd ,
and start up encryption and message authentication as specified
in
IR hashalg ,
IR encalg ,
and
IR secret .
These parameters must have been arranged at the two ends of the
conversation by other means.
For example,
I hashalg
could be
BR sha1 ,
I encalg
could be
BR rc4_128 ,
and
I 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.
I 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,
IR fd .
I Pushtls ,
IR tlsClient
and
IR tlsServer
close the original file descriptor on success.
If
I dir
is non-zero, the path name of the connection directory is copied into
IR dir .
This path name is guaranteed to be less than 40 bytes long.
SS Certificates
\" and other horseshit
Alternatively, call
I tlsClient
to speak the full handshake protocol,
negotiate the algorithms and secrets,
and return a new data file descriptor for the data channel.
I Conn
points to a (caller-allocated) struct:
IP
EX
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;
EE
PP
defined in
IR libsec.h .
On input, the caller can provide options such as
IR cert ,
the local certificate, and
IR sessionID ,
used by a client to resume a previously negotiated security association.
On output, the connection directory is set, as with
B listen
(see
IR dial (2)).
The input
I cert
is freed and a freshly allocated copy of the remote's certificate
is returned in
IR conn ,
to be checked by the caller
according to its needs.
One way to check the remote certificate is to use
I initThumbprints
and
I freeThumbprints
which allocate and free, respectively, a table of hashes
from files of known trusted and revoked certificates.
I okThumbprint
confirms that a particular hash is in the table.
PP
I TlsClient
will optionally compute a session key for use
by higher-level protocols.
To compute a session key, the caller must set
I sessionType
to a known session type;
I sessionKeylen
to the desired key length;
I sessionKey
to a buffer of length
IR sessionKeylen ;
and
I sessionConst
to the desired salting constant.
The only supported session type is
BR ttls ,
as used by 802.1x.
PP
I TlsServer
executes the server side of the handshake.
The caller must initialize
IB conn ->cert \fR,
usually by calling
I readcert
to read and decode the PEM-encoded certificate from
IR filename ,
return a pointer to
IR malloc ed
storage containing the certificate,
and store its length through
IR pcertlen .
The private key corresponding to
I cert.pem
should have been previously loaded into factotum.
(See
IR rsa (8)
for more about key generation.)
PP
I Readcertchain
will read a PEM-encoded chain of certificates from
I filename
and return a pointer to a linked list of
IR malloc ed
B PEMChain
structures, defined in
IR libsec.h :
IP
EX
typedef struct PEMChain PEMChain;
struct PEMChain {
PEMChain*next;
uchar *pem;
int pemlen;
};
EE
LP
By setting
IP
EX
conn->chain = readcertchain("intermediate-certs.pem");
EE
LP
the server can present extra certificate evidence
to establish the chain of trust to a root authority
known to the client.
PP
I Conn
is not required for the ongoing conversation and may
be freed by the application whenever convenient.
SH EXAMPLES
Start the client half of TLS and check the remote certificate:
IP
EX
conn = (TLSconn*)mallocz(sizeof *conn, 1);
fd = tlsClient(fd, conn);
if(!okCertificate(conn->cert, conn->certlen, table))
sysfatal("suspect server: %r");
\fI...application begins...\fP
EE
PP
Run the server side:
IP
EX
fd = accept(lcfd, ldir);
conn = (TLSconn*)mallocz(sizeof *conn, 1);
conn->cert = readcert("cert.pem", &conn->certlen);
fd = tlsServer(fd, conn);
\fI...application begins...\fP
EE
SH FILES
TF /sys/lib/tls
TP
B /sys/lib/tls
thumbprints of trusted services
TP
B /sys/lib/ssl
PEM certificate files
SH SOURCE
B /sys/src/libc/9sys/pushtls.c
br
B /sys/src/libsec/port
SH "SEE ALSO"
IR dial (2),
IR tls (3),
IR factotum (4),
IR thumbprint (6)
SH DIAGNOSTICS
Return \-1 on failure.
SH BUGS
Client certificates and client sessionIDs are not yet
implemented.
PP
Note that
IR pushtls ,
IR tlsClient
and
IR tlsServer
do not close the original file descriptor on failure,
only on success.
PP
The
IR sessionID
and
IR cert
pointers in the
IR TLSconn
structure have to be freed by the caller.
PP
Note that in the TLS protocol
I sessionID
itself is public; it is used as a pointer to
secrets stored in
IR factotum .