glenda.party
term% ls -F
term% cat index.txt
PUSHTLS(2)                    System Calls Manual                   PUSHTLS(2)



NAME
       pushtls,  tlsClient,  tlsServer,  initThumbprints, freeThumbprints, ok‐
       Thumbprint, 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 re‐
       turns 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.  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, ne‐
       gotiate the algorithms and secrets, and return a new data file descrip‐
       tor 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  re‐
       turned  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.   ok‐
       Thumbprint 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 ALSO
       dial(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)