ASSL(3)                   OpenBSD Programmer's Manual                  ASSL(3)

NAME
     assl - agglomerated SSL

SYNOPSIS
     #include <assl.h>

     void
     assl_initialize(void);

     struct assl_context *
     assl_alloc_context(enum assl_method method, int flags);

     void
     assl_set_cert_flags(int flags);

     int
     assl_load_file_certs(struct assl_context *ctx, char *ca, char *cert, char
     *key);

     int
     assl_connect(struct assl_context *ctx, char *host, char *port, int
     flags);

     int
     assl_serve(char *host, char *port, int flags, void (*callback)(int sock),
     void (*intr_cb)(void));

     int
     assl_accept(struct assl_context *ctx, int sock);

     ssize_t
     assl_read(struct assl_context *ctx, void *buf, size_t nbytes);

     ssize_t
     assl_write(struct assl_context *ctx, void *buf, size_t nbytes);

     ssize_t
     assl_gets(struct assl_context *ctx, char *buf, int size);

     ssize_t
     assl_puts(struct assl_context *ctx, char *buf, int send_nul);

     int
     assl_poll(struct assl_context *ctx, int mseconds, short event, short
     *revents);

     int
     assl_close(struct assl_context *ctx);

     void
     assl_fatalx(char *errstr);

DESCRIPTION
     assl_initialize() prepares the library for first use.  This function must
     be called before any other function is called.

     assl_alloc_context() allocates an assl context.  A context contains all
     SSL/TLS connection specific details.  The method parameter indicates what
     SSL/TLS type and version to use for the context.  Possible method values
     are:
           ASSL_M_SSLV2         SSL V2 client or server connection.
           ASSL_M_SSLV2_CLIENT  SSL V2 client connection.
           ASSL_M_SSLV2_SERVER  SSL V2 server connection.
           ASSL_M_SSLV3         SSL V3 client or server connection.
           ASSL_M_SSLV3_CLIENT  SSL V3 client connection.
           ASSL_M_SSLV3_SERVER  SSL V3 server connection.
           ASSL_M_TLSV1         TLS V1 client or server connection.
           ASSL_M_TLSV1_CLIENT  TLS V1 client connection.
           ASSL_M_TLSV1_SERVER  TLS V1 server connection.
           ASSL_M_ALL           Any version of a client or server connection.
           ASSL_M_ALL_CLIENT    Any version of a client connection.
           ASSL_M_ALL_SERVER    Any version of a server connection.

     If flags is set to ASSL_F_CHILD then assl_fatalx() will halt execution
     using _exit(2) instead of exit(3) per fork(2) requirement.  This flag
     shall be set for all forked contexts.

     If flags is set to ASSL_F_DONT_VERIFY then the library will not perform
     peer certificate verification.  This is to accommodate clients that don't
     wish to use certificates.  Using this flag will result in less secure
     code and should therefore be used with caution.

     The function will return NULL to indicate failure.

     assl_set_cert_flags() sets global flags for certificate verification.  If
     ASSL_GF_IGNORE_SELF_SIGNED is set than the library will ignore self
     signed certificates.  If ASSL_GF_IGNORE_EXPIRED is set than the library
     will ignore expired certificates.  This function should be only called
     once, right after assl_initialize.  Note that due to OpenSSL limitations
     these flags can not be set per assl_context.

     assl_load_file_certs() loads all required keys and certificates to
     authenticate a client or server.  cert and key contain the certificate
     and key required to authenticate the calling machine to the remote
     machine.  ca contains the Certificate Authority certificate.  All files
     must be provided in PEM format.  The cert is validated against the key.
     Providing a CA is required.  The function returns a non-zero value to
     indicate failure.

     assl_connect() tries to establish an SSL/TLS connection to a host and
     port.  The function returns a non-zero value to indicate failure.  More
     precisely, 1 for libc failures and -1 for openssl(1) failures.  The
     caller is responsible for calling assl_close() to unwind the context.  If
     flags is set to ASSL_F_NONBLOCK then the socket will be set up as non-
     blocking.

     assl_serve() is a blocking function that sets up a listening socket that
     waits for incoming connections on host and port.  Once an incoming
     connection is detected it will call callback with the appropriate socket.
     It is the responsibility of the callback function to either fork and set
     up a context.  Both host and port can be NULL.  In the host case the
     server will listen on all possible IP addresses and in the port case the
     server will listen on port 4433.  The flags parameter is a bitwise field
     and can be set to:
           ASSL_F_NONBLOCK      Set the socket to non-block.
           ASSL_F_CLOSE_SOCKET  Close the socket upon return from the
                                callback.  This is to facilitate forking
                                applications.
     To make assl_serve() exit set the global variable assl_stop_serving to
     true and interrupt the underlying poll(2) function.  If intr_cb is non-
     NULL it will be called when the underlying functions are interrupted with
     EINTR.

     assl_accept() is the equivalent of the accept(2) function with the added
     SSL/TLS handshake and certificate validation functionality.  This
     function should be called from the callback to assl_serve() after a
     context has been allocated in said function.  The function returns a non-
     zero value to indicate failure.

     assl_read() will read nbytes into buf from the ctx socket.  In blocking
     mode the function will not return until nbytes have been read or an error
     condition occurred.  In non-blocking mode the function will return -1 and
     errno = EAGAIN to indicate that there was no data ready to read.  All
     other errors simply return -1.  Upon success the function returns the
     number of bytes read.  If the connection has been terminated the function
     will return 0.

     assl_write() will write nbytes from buf to the ctx socket.  In blocking
     mode the function will not return until nbytes have been written or an
     error condition occurred.  In non-blocking mode the function will return
     -1 and errno = EAGAIN to indicate that data could not be written
     immediately.  All other errors simply return -1.  Upon success the
     function returns the number of bytes written.  If the connection has been
     terminated the function will return 0.

     assl_gets() reads at most size - 1 from the given context.  Reading stops
     when a newline character is found.  In non-blocking mode the function
     will return -1 and errno = EAGAIN to indicate that data could not be read
     immediately.  All other errors simply return -1.  Upon success the
     function returns the number of bytes read.  If the connection has been
     terminated the function will return 0.

     assl_puts() writes the NUL terminated string pointed at in buf to the
     context.  If the send_nul flag is set then the NUL character is written
     to the context as well.  In non-blocking mode the function will return -1
     and errno = EAGAIN to indicate that data could not be written
     immediately.  All other errors simply return -1.  Upon success the
     function returns the number of bytes written.  If the connection has been
     terminated the function will return 0.

     assl_poll() polls the socket in ctx for up to mseconds milliseconds for
     event to occur.  An mseconds timeout of 0 will return immediately and
     INFTIM will block indefinitely.  If revents is not NULL it returns the
     revents field from the pollfd structure as returned by the poll(2)
     command.  assl_poll() returns 0 to indicate a timeout condition, -1 for
     error conditions and 1 for success.  The return value of 1 really is the
     number of file descriptors that are ready and this mimics the poll(2)
     semantics.

     assl_close() function terminates all connections and unwinds all
     resources, including context memory.  Do not use the context pointer
     after calling this function.  It is recommended to set the context
     pointer to NULL after this call.

     assl_fatalx() prints errstr and exits.  If the library is compiled with
     ASSL_NO_FANCY_ERRORS then it will not record the calling stack.  The
     error handling code is not thread or re-entrant safe.  It was written to
     accommodate finite state machines instead.

EXAMPLES
     The following code fragment illustrates the client case:

           #include "assl.h"

           int
           main(int argc, char *argv[])
           {
                   struct assl_context     *c;

                   assl_initialize();

                   c = assl_alloc_context(ASSL_M_TLSV1_CLIENT, 0);
                   if (c == NULL)
                           assl_fatalx("assl_alloc_context");

                   if (assl_load_file_certs(c, "../ca/ca.crt",
                       "client/client.crt", "client/private/client.key"))
                           assl_fatalx("assl_load_certs");

                   if (assl_connect(c, "localhost", ASSL_DEFAULT_PORT,
                       ASSL_F_BLOCK))
                           assl_fatalx("assl_connect");

                   return (0);
           }

     The following code fragment illustrates the server case:

           #include "assl.h"

           void                    serve_callback(int);

           void
           serve_callback(int s)
           {
                   struct assl_context     *c;

                   c = assl_alloc_context(ASSL_M_TLSV1_SERVER, 0);
                   if (c == NULL)
                           assl_fatalx("assl_alloc_context");

                   if (assl_load_file_certs(c, "../ca/ca.crt",
                       "server/server.crt", "server/private/server.key"))
                           assl_fatalx("assl_load_file_certs");

                   if (assl_accept(c, s))
                           assl_fatalx("assl_accept");

                   errx(1, "do something!");
           }

           int
           main(int argc, char *argv[])
           {
                   assl_initialize();

                   assl_serve(NULL, ASSL_DEFAULT_PORT,
                       ASSL_F_BLOCK, serve_callback);

                   return (0);
           }

DON'T SEE ALSO
     openssl(1)

HISTORY

     assl was written by Marco Peereboom <marco@peereboom.us> in order to hide
     the awful OpenSSL API.  It strives to reuse openssl(1) APIs and provide a
     much simpler and sane interface for programmers that are interested in
     writing applications that require the SSL/TLS protocol for secure
     communications.

     Once the API solidifies, individual functions can be replaced with code
     that does not rely on openssl(1)

OpenBSD 4.7                      June 22, 2010                     OpenBSD 4.7