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