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

sslutil API updates [documentation / parsers / x-hdr helpers] #67

Merged
merged 1 commit into from
Dec 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 */