Name

ne_ssl_set_verify — register an SSL certificate verification callback

Synopsis

#include <ne_session.h>

typedef int (*ne_ssl_verify_fn)(void *userdata, int failures, const ne_ssl_certificate *cert);

void ne_ssl_set_verify(ne_session *session, ne_ssl_verify_fn verify_fn, void *userdata);

Description

To enable manual SSL certificate verification, a callback can be registered using ne_ssl_set_verify. If such a callback is not registered, when a connection is established to an SSL server which does not present a certificate signed by a trusted CA (see ne_ssl_load_ca), or if the certificate presented is invalid in some way, the connection will fail.

When the callback is invoked, the failures parameter gives a bitmask indicating in what way the automatic certificate verification failed. The value is equal to the bit-wise OR of one or more of the following constants (and is guaranteed to be non-zero):

NE_SSL_NOTYETVALID

The certificate is not yet valid.

NE_SSL_EXPIRED

The certificate has expired.

NE_SSL_CNMISMATCH

The hostname used for the session does not match the hostname to which the certificate was issued: this could mean that the connection has been intercepted.

NE_SSL_UNKNOWNCA

The Certificate Authority which signed the certificate is not trusted.

The cert parameter passed to the callback describes the certificate which was presented by the server, see ne_ssl_certificate for more details. The certificate object given is only valid until the callback returns.

Return value

The verification callback must return zero to indicate that the certificate should be trusted; and non-zero otherwise (in which case, the connection will fail).

Examples

Manual certificate verification:

static int
my_verify(void *userdata, int failures, const ne_ssl_certificate *cert)
{
   /* leak the return values of ne_ssl_readable_dname for simplicity! */
   printf("Issuer: %s\n", ne_ssl_readable_dname(cert->issuer);
   printf("Subject: %s\n", ne_ssl_readable_dname(cert->subject);
   if (failures & NE_SSL_CNMISMATCH) {
      printf("Server certificate was issued to `%s'; "
             "connection may have been intercepted!\n",
             cert->subject->commonName);
   }
   if (failures & NE_SSL_EXPIRED) {
      printf("Server certificate expired on %s!", cert->until);
   }
   /* ... check for other failures ... */
   if (prompt_user())
      return 1; /* fail verification */
   else
      return 0; /* trust certificate */
}

int
main(...)
{
    ne_session *sess = ne_session_create("https", "some.host.name", 443);
    ne_ssl_set_verify(sess, my_verify, NULL);
    ...
}

See also

ne_ssl_certificate, ne_ssl_load_ca, ne_ssl_dname, ne_ssl_readable_dname