Skip to content
This repository has been archived by the owner on Jun 30, 2021. It is now read-only.

Commit

Permalink
sslutil API updates [documentation / parsers / x-hdr helpers]
Browse files Browse the repository at this point in the history
- htp_sslutil_verify2opts() : helper function to convert a string to
  the proper SSL_VERIFY_* flags (on / off / optional)

- htp_sslutil_add_xheaders() : helper function to populate a headers
  context with X-SSL type headers:

  the last argument `flags` is an OR'd mask of what X-Header to include:
    * HTP_SSLUTILS_XHDR_SUBJ: `X-SSL-Subject`
    * HTP_SSLUTILS_XHDR_ISSR: `X-SSL-Issuer`
    * HTP_SSLUTILS_XHDR_NBFR: `X-SSL-Notbefore`
    * HTP_SSLUTILS_XHDR_NAFR: `X-SSL-Notafter`
    * HTP_SSLUTILS_XHDR_SERL: `X-SSL-Serial`
    * HTP_SSLUTILS_XHDR_CIPH: `X-SSL-Cipher`
    * HTP_SSLUTILS_XHDR_CERT: `X-SSL-Certificate`
    * HTP_SSLUTILS_XHDR_SHA1: `X-SSL-SHA1`

- Added doxygen documentation for all ssutil functions

- Renamed example_https.c to example_https_server.c
  • Loading branch information
NathanFrench committed Dec 18, 2017
1 parent e5a3bdf commit 22207ad
Show file tree
Hide file tree
Showing 4 changed files with 233 additions and 73 deletions.
6 changes: 3 additions & 3 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ if (NOT EVHTP_DISABLE_SSL)

configure_file(https/bin/generate.sh.in https/bin/generate.sh @ONLY)

add_executable(example_https EXCLUDE_FROM_ALL https/example_https.c)
target_link_libraries(example_https evhtp ${LIBEVHTP_EXTERNAL_LIBS} ${SYS_LIBS})
add_executable(example_https_server EXCLUDE_FROM_ALL https/example_https_server.c)
target_link_libraries(example_https_server evhtp ${LIBEVHTP_EXTERNAL_LIBS} ${SYS_LIBS})

add_dependencies(examples example_https)
add_dependencies(examples example_https_server)
endif()

add_dependencies(examples example_chunked example_pause example_vhost test_extensive test_basic test_vhost test_client test_query test_perf)
Original file line number Diff line number Diff line change
Expand Up @@ -15,75 +15,6 @@
#ifndef EVHTP_DISABLE_SSL
#include "evhtp/sslutils.h"

static void
ssl__add_x_headers_(evhtp_headers_t * headers, evhtp_ssl_t * ssl) {
unsigned char * subj_str = NULL;
unsigned char * issr_str = NULL;
unsigned char * nbf_str = NULL;
unsigned char * naf_str = NULL;
unsigned char * ser_str = NULL;
unsigned char * cip_str = NULL;
unsigned char * sha1_str = NULL;
unsigned char * cert_str = NULL;

if ((subj_str = htp_sslutil_subject_tostr(ssl))) {
evhtp_headers_add_header(
headers,
evhtp_header_new("X-SSL-Subject", subj_str, 0, 1));
}

if ((issr_str = htp_sslutil_issuer_tostr(ssl))) {
evhtp_headers_add_header(
headers,
evhtp_header_new("X-SSL-Issuer", issr_str, 0, 1));
}

if ((nbf_str = htp_sslutil_notbefore_tostr(ssl))) {
evhtp_headers_add_header(
headers,
evhtp_header_new("X-SSL-Notbefore", nbf_str, 0, 1));
}

if ((naf_str = htp_sslutil_notafter_tostr(ssl))) {
evhtp_headers_add_header(
headers,
evhtp_header_new("X-SSL-Notafter", naf_str, 0, 1));
}

if ((ser_str = htp_sslutil_serial_tostr(ssl))) {
evhtp_headers_add_header(
headers,
evhtp_header_new("X-SSL-Serial", ser_str, 0, 1));
}

if ((cip_str = htp_sslutil_cipher_tostr(ssl))) {
evhtp_headers_add_header(
headers,
evhtp_header_new("X-SSL-Cipher", cip_str, 0, 1));
}

if ((sha1_str = htp_sslutil_sha1_tostr(ssl))) {
evhtp_headers_add_header(
headers,
evhtp_header_new("X-SSL-Sha1", sha1_str, 0, 1));
}

if ((cert_str = htp_sslutil_cert_tostr(ssl))) {
evhtp_headers_add_header(
headers,
evhtp_header_new("X-SSL-Certificate", cert_str, 0, 1));
}

free(subj_str);
free(issr_str);
free(nbf_str);
free(naf_str);
free(ser_str);
free(cip_str);
free(sha1_str);
free(cert_str);
} /* ssl__add_x_headers_ */

static void
http__callback_(evhtp_request_t * req, void * arg) {
evhtp_connection_t * conn;
Expand All @@ -93,7 +24,10 @@ http__callback_(evhtp_request_t * req, void * arg) {
conn = evhtp_request_get_connection(req);
evhtp_assert(conn != NULL);

ssl__add_x_headers_(req->headers_out, conn->ssl);
htp_sslutil_add_xheaders(
req->headers_out,
conn->ssl,
HTP_SSLUTILS_XHDR_ALL);

return evhtp_send_reply(req, EVHTP_RES_OK);
}
Expand Down
150 changes: 150 additions & 0 deletions include/evhtp/sslutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,167 @@
extern "C" {
#endif

/**
* @defgroup htp_sslutils SSL utility functions
*/

/**
* @brief converts the client certificate DNAME information (CN=<cert>, OU=.....)
* @ingroup htp_sslutils
*
* @param ssl the client SSL context
*
* @return heap allocated str representation, NULL on error.
*/
EVHTP_EXPORT unsigned char * htp_sslutil_subject_tostr(evhtp_ssl_t * ssl);


/**
* @brief converts the DN (issuer of cert from the client)
* @ingroup htp_sslutils
*
* @param ssl client SSL context
*
* @return heap allocated str representation, NULL on error
*/
EVHTP_EXPORT unsigned char * htp_sslutil_issuer_tostr(evhtp_ssl_t * ssl);


/**
* @brief converts the `notbefore` date of the cert from the client
* @ingroup htp_sslutils
*
* @param ssl client SSL context
*
* @return heap allocated str (YYMMDDhhmmss) of the notbefore, NULL on error.
*/
EVHTP_EXPORT unsigned char * htp_sslutil_notbefore_tostr(evhtp_ssl_t * ssl);


/**
* @brief converts the `notafter` date of the cert from the client
* @ingroup htp_sslutils
*
* @param ssl ssl client SSL context
*
* @return heap allocated str (YYMMDDhhmmss) of notafter, NULL on error.
*/
EVHTP_EXPORT unsigned char * htp_sslutil_notafter_tostr(evhtp_ssl_t * ssl);


/**
* @brief converts the SHA1 digest in str from the client
* @ingroup htp_sslutils
*
* @param ssl SSL context from client
*
* @return NULL on error
*/
EVHTP_EXPORT unsigned char * htp_sslutil_sha1_tostr(evhtp_ssl_t * ssl);

/**
* @brief convert serial number to string
* @ingroup htp_sslutils
*
* @param ssl SSL context from client
*
* @return NULL on error
*/
EVHTP_EXPORT unsigned char * htp_sslutil_serial_tostr(evhtp_ssl_t * ssl);

/**
* @brief convert the used for this SSL context
* @ingroup htp_sslutils
*
* @param ssl SSL context
*
* @return heap allocated cipher str, NULL on error
*/
EVHTP_EXPORT unsigned char * htp_sslutil_cipher_tostr(evhtp_ssl_t * ssl);

/**
* @brief convert the client cert into a multiline string
* @ingroup htp_sslutils
*
* @param ssl client SSL context
*
* @return heap allocated string, NULL on error
*/
EVHTP_EXPORT unsigned char * htp_sslutil_cert_tostr(evhtp_ssl_t * ssl);


/**
* @brief convert X509 extentions to string
* @ingroup htp_sslutils
*
* @param ssl SSL context
* @param oid
*
* @return
*/
EVHTP_EXPORT unsigned char * htp_sslutil_x509_ext_tostr(evhtp_ssl_t * ssl, const char * oid);


/**
* @brief convert a string to the proper verify opts
* @ingroup htp_sslutils
*
* @param opts_str ("on" / "optional" / "off" )
* where:
* "on" : client must present a valid cert (otherwise rejected)
* "off" : no client cert required at all
* "optional" : client MAY present a valid certificate (but not rejected)
*
* @note if `opts_str` is NULL, defaults to "off"
*
* @return OR'd mask SSL_VERIFY_* flags, -1 on error
*/
EVHTP_EXPORT int htp_sslutil_verify2opts(const char * opts_str);

/*
* @ingroup htp_sslutils
* @ {
*/
#define HTP_SSLUTILS_XHDR_SUBJ (1 << 0)
#define HTP_SSLUTILS_XHDR_ISSR (1 << 1)
#define HTP_SSLUTILS_XHDR_NBFR (1 << 2)
#define HTP_SSLUTILS_XHDR_NAFR (1 << 3)
#define HTP_SSLUTILS_XHDR_SERL (1 << 4)
#define HTP_SSLUTILS_XHDR_SHA1 (1 << 5)
#define HTP_SSLUTILS_XHDR_CERT (1 << 6)
#define HTP_SSLUTILS_XHDR_CIPH (1 << 7)
#define HTP_SSLUTILS_XHDR_ALL \
HTP_SSLUTILS_XHDR_SUBJ \
| HTP_SSLUTILS_XHDR_ISSR \
| HTP_SSLUTILS_XHDR_NBFR \
| HTP_SSLUTILS_XHDR_NAFR \
| HTP_SSLUTILS_XHDR_SERL \
| HTP_SSLUTILS_XHDR_SHA1 \
| HTP_SSLUTILS_XHDR_CERT \
| HTP_SSLUTILS_XHDR_CIPH
/** @} */

/**
* @brief add SSL-type X-Header flags to an evhtp_headers_t context
* @ingroup htp_sslutils
*
* @param hdrs headers structure to append into
* @param ssl the SSL context
* HTP_SSLUTILS_XHDR_SUBJ: `X-SSL-Subject`
* HTP_SSLUTILS_XHDR_ISSR: `X-SSL-Issuer`
* HTP_SSLUTILS_XHDR_NBFR: `X-SSL-Notbefore`
* HTP_SSLUTILS_XHDR_NAFR: `X-SSL-Notafter`
* HTP_SSLUTILS_XHDR_SERL: `X-SSL-Serial`
* HTP_SSLUTILS_XHDR_CIPH: `X-SSL-Cipher`
* HTP_SSLUTILS_XHDR_CERT: `X-SSL-Certificate`
* HTP_SSLUTILS_XHDR_SHA1: `X-SSL-SHA1`
*
* @param flags flags (See XHDR defines above)
*
* @return 0 on success, -1 on error
*/
EVHTP_EXPORT int htp_sslutil_add_xheaders(evhtp_headers_t * hdrs, evhtp_ssl_t * ssl, short flags);

#ifdef __cplusplus
}
#endif
Expand Down
76 changes: 76 additions & 0 deletions sslutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -426,3 +426,79 @@ htp_sslutil_x509_ext_tostr(evhtp_ssl_t * ssl, const char * oid) {

return ext_str;
} /* htp_sslutil_x509_ext_tostr */

int
htp_sslutil_verify2opts(const char * opts_str) {
if (!opts_str || !strcasecmp(opts_str, "off")) {
return SSL_VERIFY_NONE;
}

if (!strcasecmp(opts_str, "optional")) {
return SSL_VERIFY_PEER;
}

if (!strcasecmp(opts_str, "on")) {
return SSL_VERIFY_PEER
| SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
}

return -1;
}

int
htp_sslutil_add_xheaders(evhtp_headers_t * hdrs, evhtp_ssl_t * ssl, short flags) {
int i;

if (!hdrs || !ssl) {
return -1;
}

struct {
const char * hdr_str;
short flag;
unsigned char * (* convfn)(evhtp_ssl_t *);
} ssl_x_hdrs_[] = {
{ "X-SSL-Subject", HTP_SSLUTILS_XHDR_SUBJ, htp_sslutil_subject_tostr },
{ "X-SSL-Issuer", HTP_SSLUTILS_XHDR_ISSR, htp_sslutil_issuer_tostr },
{ "X-SSL-Notbefore", HTP_SSLUTILS_XHDR_NBFR, htp_sslutil_notbefore_tostr },
{ "X-SSL-Notafter", HTP_SSLUTILS_XHDR_NAFR, htp_sslutil_notafter_tostr },
{ "X-SSL-Serial", HTP_SSLUTILS_XHDR_SERL, htp_sslutil_serial_tostr },
{ "X-SSL-Cipher", HTP_SSLUTILS_XHDR_CIPH, htp_sslutil_cipher_tostr },
{ "X-SSL-Certificate", HTP_SSLUTILS_XHDR_CERT, htp_sslutil_cert_tostr },
{ "X-SSL-SHA1", HTP_SSLUTILS_XHDR_SHA1, htp_sslutil_sha1_tostr },
{ NULL, 0, NULL }
};

/* remove all of the current x- headers if present */
evhtp_kv_rm_and_free(hdrs, evhtp_kvs_find_kv(hdrs, "X-SSL-Subject"));
evhtp_kv_rm_and_free(hdrs, evhtp_kvs_find_kv(hdrs, "X-SSL-Issuer"));
evhtp_kv_rm_and_free(hdrs, evhtp_kvs_find_kv(hdrs, "X-SSL-Notbefore"));
evhtp_kv_rm_and_free(hdrs, evhtp_kvs_find_kv(hdrs, "X-SSL-Notafter"));
evhtp_kv_rm_and_free(hdrs, evhtp_kvs_find_kv(hdrs, "X-SSL-Serial"));
evhtp_kv_rm_and_free(hdrs, evhtp_kvs_find_kv(hdrs, "X-SSL-Cipher"));
evhtp_kv_rm_and_free(hdrs, evhtp_kvs_find_kv(hdrs, "X-SSL-Certificate"));

if (flags == 0) {
return 0;
}

/* iterate over our ssl_x_hdrs_ struct array, compare the flags,
* and if a xhdr flag is set, run the proper *_tostr function and
* append it to the `hdrs` passed to this function.
*/
for (i = 0; ssl_x_hdrs_[i].hdr_str; i++) {
char * o_str = NULL;

if (flags & ssl_x_hdrs_[i].flag) {
if ((o_str = (ssl_x_hdrs_[i].convfn)(ssl))) {
evhtp_headers_add_header(
hdrs,
evhtp_header_new(ssl_x_hdrs_[i].hdr_str, o_str, 0, 1));

evhtp_safe_free(o_str, free);
}
}
}

return 0;
} /* htp_sslutil_add_xheaders */

0 comments on commit 22207ad

Please sign in to comment.