OpenSSL/Error handling

Most OpenSSL functions return 1 on success, and something other than 1 on failure. The failure result is often 0, but some functions like ssl_connect() may also return -1 on errors, so it is safest to compare against 1 for success, rather than against 0 for failure.

When an error occurs, more detailed information is stored in the "error queue" (occasionally also referred to as the "error stack" or "error state"), which can contain more than one error code (to record a cascade of errors). The error queue is thread-local (although it is implemented with OpenSSL's home-grown thread local state mechanism, rather than using the OS's mechanism for thread local state).

The simplest thing you can do with the error queue is to print the entire queue. This can be done with ERR_print_errors_fp to print the error queue to a FILE *, or ERR_print_errors to print the error queue to a BIO. Both of these functions empty the error queue after printing it.

Here is an example of how to use a memory BIO to print the error queue to a malloc-allocated string:

char *ossl_err_as_string (void)
{ BIO *bio = BIO_new (BIO_s_mem ());
  ERR_print_errors (bio);
  char *buf = NULL;
  size_t len = BIO_get_mem_data (bio, &buf);
  char *ret = (char *) calloc (1, 1 + len);
  if (ret)
    memcpy (ret, buf, len);
  BIO_free (bio);
  return ret;

On the other hand, printing the error stack to standard error is as simple as:

ERR_print_errors_fp (stderr);

TODO: explain more fine-grained ways of extracting individual error codes from the error queue, and interpreting them