123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- .TH PUSHTLS 2
- .SH NAME
- pushtls, tlsClient, tlsServer, initThumbprints, freeThumbprints, okThumbprint, 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)
- .PP
- .B
- void freeThumbprints(Thumbprint *table)
- .PP
- .B
- int okThumbprint(uchar *hash, 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 .
- 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 */
- 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;
- .EE
- .PP
- defined in
- .IR tls.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 tls.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
- 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");
- \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 in the TLS protocol
- .I sessionID
- itself is public; it is used as a pointer to
- secrets stored in
- .IR factotum .
|