diff --git a/src/libnopoll.def b/src/libnopoll.def index e95901c..08d34ba 100644 --- a/src/libnopoll.def +++ b/src/libnopoll.def @@ -83,6 +83,7 @@ nopoll_conn_opts_set_extra_headers nopoll_conn_opts_set_interface nopoll_conn_opts_set_reuse nopoll_conn_opts_set_ssl_certs +nopoll_conn_opts_set_ssl_crl nopoll_conn_opts_set_ssl_protocol nopoll_conn_opts_skip_origin_check nopoll_conn_opts_ssl_peer_verify diff --git a/src/nopoll_conn.c b/src/nopoll_conn.c index 16e35e7..1af6b4c 100644 --- a/src/nopoll_conn.c +++ b/src/nopoll_conn.c @@ -714,6 +714,8 @@ int __nopoll_conn_ssl_verify_callback (int ok, X509_STORE_CTX * store) { nopoll_bool __nopoll_conn_set_ssl_client_options (noPollCtx * ctx, noPollConn * conn, noPollConnOpts * options) { + X509_LOOKUP *lookup; + nopoll_log (ctx, NOPOLL_LEVEL_DEBUG, "Checking to establish SSL options (%p)", options); if (options && options->ca_certificate) { @@ -775,6 +777,19 @@ nopoll_bool __nopoll_conn_set_ssl_client_options (noPollCtx * ctx, noPollConn * SSL_CTX_set_verify_depth (conn->ssl_ctx, 10); } /* end if */ + if (options && options->crl) { + /* Code and comments shamelessly borrowed from cURL */ + /* tell OpenSSL where to find CRL file that is used to check certificate revocation */ + lookup = X509_STORE_add_lookup(SSL_CTX_get_cert_store(conn->ssl_ctx), X509_LOOKUP_file()); + if (!lookup || (!X509_load_crl_file(lookup, options->crl, X509_FILETYPE_PEM))) { + nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "Error loading CRL (%s)", options->crl); + return nopoll_false; + } + /* Everything is fine. */ + X509_STORE_set_flags(SSL_CTX_get_cert_store(conn->ssl_ctx), X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); + nopoll_log (ctx, NOPOLL_LEVEL_DEBUG, "Successfully set CRL: %s", options->crl); + } /* end if */ + return nopoll_true; } diff --git a/src/nopoll_conn_opts.c b/src/nopoll_conn_opts.c index d1b90ad..82a21bb 100644 --- a/src/nopoll_conn_opts.c +++ b/src/nopoll_conn_opts.c @@ -151,6 +151,31 @@ nopoll_bool nopoll_conn_opts_set_ssl_certs (noPollConnOpts * opts, } /** + * @brief Set CRL on a particular options object that can be used for + * a client and a listener connection. + * + * @param opts The connection options where these settings will be + * applied. + * + * @param crl The CRL to use on the connection. + * + * @return nopoll_true in the case the CRL provided is reachable. + */ +nopoll_bool nopoll_conn_opts_set_ssl_crl (noPollConnOpts * opts, const char * crl) +{ + if (opts == NULL) + return nopoll_false; + + /* store certificate settings */ + opts->crl = nopoll_strdup (crl); + if (opts->crl) + if (access (opts->crl, R_OK) != 0) + return nopoll_false; + + return nopoll_true; +} + +/** * @brief Allows to disable peer ssl certificate verification. This is * not recommended for production enviroment. This affects in a * different manner to a listener connection and a client connection. @@ -404,6 +429,7 @@ void __nopoll_conn_opts_free_common (noPollConnOpts * opts) nopoll_free (opts->private_key); nopoll_free (opts->chain_certificate); nopoll_free (opts->ca_certificate); + nopoll_free (opts->crl); /* cookie */ nopoll_free (opts->cookie); diff --git a/src/nopoll_conn_opts.h b/src/nopoll_conn_opts.h index 4ca9fd1..f1d65b9 100644 --- a/src/nopoll_conn_opts.h +++ b/src/nopoll_conn_opts.h @@ -52,6 +52,8 @@ nopoll_bool nopoll_conn_opts_set_ssl_certs (noPollConnOpts * opts, const char * chain_certificate, const char * ca_certificate); +nopoll_bool nopoll_conn_opts_set_ssl_crl (noPollConnOpts * opts, const char * crl); + void nopoll_conn_opts_ssl_peer_verify (noPollConnOpts * opts, nopoll_bool verify); void nopoll_conn_opts_set_cookie (noPollConnOpts * opts, const char * cookie_content); diff --git a/src/nopoll_private.h b/src/nopoll_private.h index 44aebaf..a879884 100644 --- a/src/nopoll_private.h +++ b/src/nopoll_private.h @@ -397,6 +397,7 @@ struct _noPollConnOpts { char * private_key; char * chain_certificate; char * ca_certificate; + char * crl; nopoll_bool disable_ssl_verify;