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 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 tls(3), call
          pushtls to open the record layer device, connect to the com-
          munications 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 written to the file

     Page 1                       Plan 9            (printed 12/21/24)

     PUSHTLS(2)                                             PUSHTLS(2)

          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, 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 associa-
          tion.  On output, the connection 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 par-
          ticular 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; sessionKey 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 pre-
          viously loaded into factotum.  (See rsa(8) for more about
          key generation.)

     Page 2                       Plan 9            (printed 12/21/24)

     PUSHTLS(2)                                             PUSHTLS(2)

          Readcertchain will read a PEM-encoded chain of certificates
          from filename and return a pointer to a linked list of
          malloced PEMChain structures, 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 estab-
          lish 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 certifi-
          cate:

               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");

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

     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)

     Page 3                       Plan 9            (printed 12/21/24)

     PUSHTLS(2)                                             PUSHTLS(2)

     DIAGNOSTICS
          Return -1 on failure.

     BUGS
          Client certificates and client sessionIDs are not yet imple-
          mented.

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

     Page 4                       Plan 9            (printed 12/21/24)