PUSHTLS(3)                                             PUSHTLS(3)

          pushtls, tlsClient, tlsServer, initThumbprints,
          freeThumbprints, okThumbprint, readcert, readcertchain -
          attach TLS1 or SSL3 encryption to a communication channel

          #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)

          Transport Layer Security (TLS) comprises a record layer pro-
          tocol, 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 chan-
          nel 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 Plan 9's
          tls(3), call pushtls to open the record layer device, con-
          nect to the communications channel fd, and start up encryp-
          tion 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

     PUSHTLS(3)                                             PUSHTLS(3)

          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

          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 sessionID
                int certlen, sessionIDlen;
                void (*trace)(char*fmt, ...);
                PEMChain *chain;
             } 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 associa-
          tion.  On output, the connection directory is set, as with
          listen (see dial(3)). 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 mechanism is supplied by initThumbprints and
          freeThumbprints which allocate and free, respectively, a
          table of hashes from files of known trusted and revoked cer-
          tificates.  okThumbprint confirms that a particular hash is
          in the table, as computed by

             uchar hash[SHA1dlen];
             conn = (TLSconn*)mallocz(sizeof *conn, 1);
             fd = tlsClient(fd, conn);
             sha1(conn->cert, conn->certlen, hash, nil);
                exits("suspect server");
             ...application begins...

          Call tlsServer to perform the corresponding function on 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...
          The private key corresponding to cert.pem should have been
          previously loaded into factotum.  (See rsa(3) for more about
          key generation.)  By setting
             conn->chain = readcertchain("intermediate-certs.pem");
          the server can present extra certificate evidence to estab-
          lish the chain of trust to a root authority known to the

     PUSHTLS(3)                                             PUSHTLS(3)


          Conn is not required for the ongoing conversation and may be
          freed by the application whenever convenient.

               thumbprints of trusted services

               PEM certificate files


          dial(3), thumbprint(7); Plan 9's factotum(4) and tls(3)

          return -1 on failure.

          Pushtls is not implemented.

          Client certificates and client sessionIDs are not yet imple-

          Note that in the TLS protocol sessionID itself is public;
          it is used as a pointer to secrets stored in factotum.