if (NOT EVENT__DISABLE_MBEDTLS)
add_event_library(event_mbedtls
- LIBRARIES event_core_shared ${MBEDTLS_LIBRARIES}
+ INNER_LIBRARIES event_core
+ OUTER_INCLUDES ${MBEDTLS_INCLUDE_DIR}
+ LIBRARIES ${MBEDTLS_LIBRARIES}
SOURCES ${SRC_MBEDTLS})
endif()
${LIB_APPS}
${LIB_PLATFORM})
- if (${ssl})
- target_link_libraries(${name} event_openssl)
+ if (TARGET ${ssl})
+ target_link_libraries(${name} ${ssl})
if(WIN32)
target_link_libraries(${name} crypt32)
endif()
endif()
if (NOT EVENT__DISABLE_OPENSSL)
- add_sample_prog(ON https-client
+ add_sample_prog(event_openssl https-client
sample/https-client.c
sample/openssl_hostname_validation.c
sample/hostcheck.c)
- add_sample_prog(ON le-proxy
+ add_sample_prog(event_openssl le-proxy
sample/le-proxy.c)
- add_sample_prog(ON becat sample/becat.c ${WIN32_GETOPT})
+ add_sample_prog(event_openssl becat sample/becat.c ${WIN32_GETOPT})
+ endif()
+
+ if (NOT EVENT__DISABLE_MBEDTLS)
+ add_sample_prog(event_mbedtls ssl-client-mbedtls
+ sample/ssl-client-mbedtls.c)
endif()
set(SAMPLES_WOPT
endif()
if (NOT EVENT__DISABLE_OPENSSL)
- list(APPEND SRC_REGRESS test/regress_ssl.c)
+ list(APPEND SRC_REGRESS test/regress_openssl.c)
+ endif()
+
+ if (NOT EVENT__DISABLE_MBEDTLS)
+ list(APPEND SRC_REGRESS test/regress_mbedtls.c)
endif()
add_executable(regress ${SRC_REGRESS})
if (NOT EVENT__DISABLE_OPENSSL)
target_link_libraries(regress event_openssl)
endif()
+ if (NOT EVENT__DISABLE_MBEDTLS)
+ target_link_libraries(regress event_mbedtls)
+ endif()
if (CMAKE_USE_PTHREADS_INIT)
target_link_libraries(regress event_pthreads)
endif()
# included from other files.
PLATFORM_DEPENDENT_SRC = \
arc4random.c \
- epoll_sub.c
+ epoll_sub.c \
+ test/regress_ssl.c
CMAKE_FILES = \
cmake/AddCompilerFlags.cmake \
cmake/CodeCoverage.cmake \
cmake/COPYING-CMAKE-SCRIPTS \
cmake/Copyright.txt \
+ cmake/FindMbedTLS.cmake \
cmake/LibeventConfig.cmake.in \
cmake/LibeventConfigVersion.cmake.in \
cmake/Macros.cmake \
#define SSL_ERROR_WANT_WRITE MBEDTLS_ERR_SSL_WANT_WRITE
#define SSL mbedtls_ssl_context
-/*
- * Define an OpenSSL bio that targets a bufferevent.
- */
-
-/* --------------------
- A BIO is an OpenSSL abstraction that handles reading and writing data. The
- library will happily speak SSL over anything that implements a BIO
- interface.
-
- Here we define a BIO implementation that directs its output to a
- bufferevent. We'll want to use this only when none of OpenSSL's built-in
- IO mechanisms work for us.
- -------------------- */
-
-/* every BIO type needs its own integer type value. */
-#define BIO_TYPE_LIBEVENT 57
-/* ???? Arguably, we should set BIO_TYPE_FILTER or BIO_TYPE_SOURCE_SINK on
- * this. */
-
#if 0
static void
print_err(int val)
{
- int err;
- printf("Error was %d\n", val);
-
- while ((err = ERR_get_error())) {
- const char *msg = (const char*)ERR_reason_error_string(err);
- const char *lib = (const char*)ERR_lib_error_string(err);
- const char *func = (const char*)ERR_func_error_string(err);
-
- printf("%s in %s %s\n", msg, lib, func);
- }
+ char buf[1024];
+ mbedtls_strerror(val, buf, sizeof(buf));
+ printf("Error was %d:%s\n", val, buf);
}
#else
#define print_err(v) ((void)0)
int r = 0;
struct evbuffer *input;
- //BIO_clear_retry_flags(b);
- fprintf(stdout, "bio prepare write:\n");
- fwrite(out, 1, outlen, stdout);
-
if (!out)
return 0;
if (!bufev)
input = bufferevent_get_input(bufev);
if (evbuffer_get_length(input) == 0) {
/* If there's no data to read, say so. */
- //BIO_set_retry_read(b);
return MBEDTLS_ERR_SSL_WANT_READ;
} else {
r = evbuffer_remove(input, out, outlen);
}
- fprintf(stderr, "bio read %d bytes\n", r);
return r;
}
-/* Called to write data info the BIO */
+/* Called to write data into the BIO */
static int
bio_bufferevent_write(void *ctx, const unsigned char *in, size_t inlen)
{
struct evbuffer *output;
size_t outlen;
- //BIO_clear_retry_flags(b);
-
if (!bufev)
return MBEDTLS_ERR_NET_INVALID_CONTEXT;
if (bufev->wm_write.high && bufev->wm_write.high <= (outlen+inlen)) {
if (bufev->wm_write.high <= outlen) {
/* If no data can fit, we'll need to retry later. */
- //BIO_set_retry_write(b);
return MBEDTLS_ERR_SSL_WANT_WRITE;
}
inlen = bufev->wm_write.high - outlen;
EVUTIL_ASSERT(inlen > 0);
evbuffer_add(output, in, inlen);
- fprintf(stderr, "bio write %d bytes\n", inlen);
return inlen;
}
/* --------------------
- Now, here's the OpenSSL-based implementation of bufferevent.
-
- The implementation comes in two flavors: one that connects its SSL object
- to an underlying bufferevent using a BIO_bufferevent, and one that has the
- SSL object connect to a socket directly. The latter should generally be
- faster, except on Windows, where your best bet is using a
- bufferevent_async.
+ Now, here's the mbedTLS-based implementation of bufferevent.
- (OpenSSL supports many other BIO types, too. But we can't use any unless
- we have a good way to get notified when they become readable/writable.)
+ The implementation comes in only one flavors, that has the
+ SSL object connect to a socket directly.
-------------------- */
struct bio_data_counts {
/* An underlying bufferevent that we're directing our output to.
If it's NULL, then we're connected to an fd, not an evbuffer. */
struct bufferevent *underlying;
- /* net fd */
- mbedtls_net_context net_ctx;
+ /* net fd */
+ mbedtls_net_context net_ctx;
/* The SSL object doing our encryption. */
SSL *ssl;
static int be_mbedtls_ctrl(struct bufferevent *, enum bufferevent_ctrl_op, union bufferevent_ctrl_data *);
const struct bufferevent_ops bufferevent_ops_mbedtls = {
- "ssl",
+ "mbedtls",
evutil_offsetof(struct bufferevent_mbedtls, bev.bev),
be_mbedtls_enable,
be_mbedtls_disable,
{
int event = BEV_EVENT_ERROR;
//int dirty_shutdown = 0;
- unsigned long err;
- char buf[100] = {};
-
- fprintf(stderr, "when %d error code %d", when, errcode);
+ char buf[100];
if (when & BEV_EVENT_READING && ret == 0)
{
bufferevent_run_eventcb_(&bev_ssl->bev.bev, when | event, 0);
}
-/*static void
-init_bio_counts(struct bufferevent_mbedtls *bev_ssl)
-{
- BIO *rbio, *wbio;
-
- wbio = SSL_get_wbio(bev_ssl->ssl);
- bev_ssl->counts.n_written = wbio ? BIO_number_written(wbio) : 0;
- rbio = SSL_get_rbio(bev_ssl->ssl);
- bev_ssl->counts.n_read = rbio ? BIO_number_read(rbio) : 0;
-}
-
-static inline void
-decrement_buckets(struct bufferevent_mbedtls *bev_ssl)
-{
- unsigned long num_w = BIO_number_written(SSL_get_wbio(bev_ssl->ssl));
- unsigned long num_r = BIO_number_read(SSL_get_rbio(bev_ssl->ssl));
- /* These next two subtractions can wrap around. That's okay. * /
- unsigned long w = num_w - bev_ssl->counts.n_written;
- unsigned long r = num_r - bev_ssl->counts.n_read;
- if (w)
- bufferevent_decrement_write_buckets_(&bev_ssl->bev, w);
- if (r)
- bufferevent_decrement_read_buckets_(&bev_ssl->bev, r);
- bev_ssl->counts.n_written = num_w;
- bev_ssl->counts.n_read = num_r;
-}*/
-
#define OP_MADE_PROGRESS 1
#define OP_BLOCKED 2
#define OP_ERR 4
return OP_ERR | result;
++n_used;
space[i].iov_len = r;
- //decrement_buckets(bev_ssl);
} else {
int err = r;
print_err(err);
return OP_ERR | result;
n_written += r;
bev_ssl->last_write = -1;
- //decrement_buckets(bev_ssl);
} else {
int err = r;
print_err(err);
r = mbedtls_ssl_handshake(bev_ssl->ssl);
break;
}
- //decrement_buckets(bev_ssl);
if (r==0) {
evutil_socket_t fd = event_get_fd(&bev_ssl->bev.bev.ev_read);
}
int
-bufferevent_ssl_renegotiate(struct bufferevent *bev)
+bufferevent_mbedtls_renegotiate(struct bufferevent *bev)
{
struct bufferevent_mbedtls *bev_ssl = upcast(bev);
if (!bev_ssl)
} else {
mbedtls_ssl_set_bio(bev_ssl->ssl, NULL, NULL, NULL, NULL);
bufferevent_free(bev_ssl->underlying);
- bev_ssl->underlying = NULL;
+ /* We still have a reference to it, via our
+ * BIO. So we don't drop this. */
+ // bev_ssl->underlying = NULL;
}
}
} else {
case BUFFEREVENT_SSL_ACCEPTING:
if (bev_ssl->ssl->conf->endpoint != MBEDTLS_SSL_IS_SERVER)
return -1;
- //SSL_set_accept_state(bev_ssl->ssl);
if (set_handshake_callbacks(bev_ssl, fd) < 0)
return -1;
break;
case BUFFEREVENT_SSL_CONNECTING:
if (bev_ssl->ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT)
return -1;
- //SSL_set_connect_state(bev_ssl->ssl);
if (set_handshake_callbacks(bev_ssl, fd) < 0)
return -1;
break;
&bufferevent_ops_mbedtls, tmp_options) < 0)
goto err;
- /* Don't explode if we decide to realloc a chunk we're writing from in
- * the output buffer. */
- //SSL_set_mode(ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
-
bev_ssl->underlying = underlying;
bev_ssl->ssl = ssl;
bev_ssl->old_state = state;
bev_ssl->last_write = -1;
- //init_bio_counts(bev_ssl);
-
fd = be_mbedtls_auto_fd(bev_ssl, fd);
if (be_mbedtls_set_fd(bev_ssl, state, fd))
goto err;
return bufferevent_mbedtls_new_impl(
base, NULL, fd, ssl, state, options);
-err:
- if (options & BEV_OPT_CLOSE_ON_FREE)
- mbedtls_ssl_free(ssl);
- return NULL;
}
int
include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(mbedTLS
+find_package_handle_standard_args(MbedTLS
FOUND_VAR MBEDTLS_FOUND
REQUIRED_VARS
MBEDTLS_INCLUDE_DIR
AC_ARG_ENABLE(openssl,
AS_HELP_STRING(--disable-openssl, disable support for openssl encryption),
[], [enable_openssl=yes])
+AC_ARG_ENABLE(mbedtls,
+ AS_HELP_STRING(--disable-mbedtls, disable support for mbedtls encryption),
+ [], [enable_mbedtls=yes])
AC_ARG_ENABLE(debug-mode,
AS_HELP_STRING(--disable-debug-mode, disable support for running in debug mode),
[], [enable_debug_mode=yes])
AC_SYS_LARGEFILE
LIBEVENT_OPENSSL
+LIBEVENT_MBEDTLS
dnl Checks for header files.
AC_CHECK_HEADERS([ \
[Define if libevent should build without support for a debug mode])
fi
-dnl check if we should enable verbose debugging
+dnl check if we should enable verbose debugging
if test x$enable_verbose_debug = xyes; then
CFLAGS="$CFLAGS -DUSE_DEBUG"
fi
dnl check if we have and should use OpenSSL
AM_CONDITIONAL(OPENSSL, [test "$enable_openssl" != "no" && test "$have_openssl" = "yes"])
+# check if we have and should use mbedtls
+AM_CONDITIONAL(MBEDTLS, [test "$enable_mbedtls" != "no" && test "$have_mbedtls" = "yes"])
+
dnl enable some warnings by default
AX_CHECK_COMPILE_FLAG([-Wall], [CFLAGS="$CFLAGS -Wall"],[],[-Werror])
AM_CONDITIONAL([ENABLE_DOXYGEN], [test "$DX_FLAG_doc" = "1"])
AM_CONDITIONAL([ENABLE_DOXYGEN_MAN], [test "$DX_FLAG_man" = "1"])
-AC_CONFIG_FILES( [libevent.pc libevent_openssl.pc libevent_pthreads.pc libevent_core.pc libevent_extra.pc] )
+AC_CONFIG_FILES( [libevent.pc libevent_mbedtls.pc libevent_openssl.pc libevent_pthreads.pc libevent_core.pc libevent_extra.pc] )
AC_OUTPUT(Makefile)
/* Define if the system has openssl */
#cmakedefine EVENT__HAVE_OPENSSL 1
+/* Define if the system has mbedtls */
+#cmakedefine EVENT__HAVE_MBEDTLS 1
+
/* Define to 1 if you have the `pipe' function. */
#cmakedefine EVENT__HAVE_PIPE 1
/** Tells a bufferevent to begin SSL renegotiation. */
EVENT2_EXPORT_SYMBOL
-int bufferevent_ssl_renegotiate(struct bufferevent *bev);
+int bufferevent_mbedtls_renegotiate(struct bufferevent *bev);
/** Return the most recent OpenSSL error reported on an SSL bufferevent. */
EVENT2_EXPORT_SYMBOL
defined(event_extra_shared_EXPORTS) || \
defined(event_core_shared_EXPORTS) || \
defined(event_pthreads_shared_EXPORTS) || \
- defined(event_openssl_shared_EXPORTS)
+ defined(event_openssl_shared_EXPORTS) || \
+ defined(event_mbedtls_shared_EXPORTS)
# if defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550)
# define EVENT2_EXPORT_SYMBOL __global
save_LIBS="$LIBS"
LIBS=""
MBEDTLS_LIBS=""
- for lib in mbedtls ; do
- # clear cache
- unset ac_cv_search_mbedtls_ssl_init
- AC_SEARCH_LIBS([mbedtls_ssl_init], [mbedtls ],
- [have_mbedtls=yes
- MBEDTLS_LIBS="$LIBS -l$lib -lmbedcrypto -lmbedx509 $EV_LIB_GDI $EV_LIB_WS32 $MBEDTLS_LIBADD"],
- [have_mbedtls=no],
- [-l$lib $EV_LIB_GDI $EV_LIB_WS32 $MBEDTLS_LIBADD])
- LIBS="$save_LIBS"
- test "$have_mbedtls" = "yes" && break
- done
- ;;
+ # clear cache
+ unset ac_cv_search_mbedtls_ssl_init
+ AC_SEARCH_LIBS([mbedtls_ssl_init], [mbedtls],
+ [have_mbedtls=yes
+ MBEDTLS_LIBS="$LIBS -lmbedtls -lmbedcrypto -lmbedx509 $EV_LIB_GDI $EV_LIB_WS32"],
+ [have_mbedtls=no],
+ [-lmbedtls -lmbedcrypto -lmbedx509 $EV_LIB_GDI $EV_LIB_WS32])
+ LIBS="$save_LIBS"
+ test "$have_mbedtls" = "yes" && break
esac
CPPFLAGS_SAVE=$CPPFLAGS
CPPFLAGS="$CPPFLAGS $MBEDTLS_INCS"
sample/openssl_hostname_validation.h
endif
+if MBEDTLS
+SAMPLES += sample/ssl-client-mbedtls
+sample_ssl_client_mbedtls_SOURCES = sample/ssl-client-mbedtls.c
+sample_ssl_client_mbedtls_LDADD = libevent.la libevent_mbedtls.la $(MBEDTLS_LIBS) $(MBEDTLS_LIBADD)
+sample_ssl_client_mbedtls_CPPFLAGS = $(AM_CPPFLAGS) $(MBEDTLS_INCS)
+endif
+
if BUILD_SAMPLES
noinst_PROGRAMS += $(SAMPLES)
endif
--- /dev/null
+/*
+ * SSL client demonstration program
+ *
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#include "mbedtls/config.h"
+#include "mbedtls/platform.h"
+
+#include "mbedtls/net_sockets.h"
+#include "mbedtls/debug.h"
+#include "mbedtls/ssl.h"
+#include "mbedtls/entropy.h"
+#include "mbedtls/ctr_drbg.h"
+#include "mbedtls/error.h"
+#include "mbedtls/certs.h"
+
+#include <string.h>
+
+#include <event2/event.h>
+#include <event2/dns.h>
+#include <event2/bufferevent.h>
+#include <event2/bufferevent_ssl.h>
+#include <event2/util.h>
+
+#define SERVER_PORT "443"
+#define SERVER_NAME "amazon.com"
+#define GET_REQUEST "GET / HTTP/1.0\r\n\r\n"
+
+#define DEBUG_LEVEL 1
+
+static void
+my_debug(void *ctx, int level, const char *file, int line, const char *str)
+{
+ ((void)level);
+
+ mbedtls_fprintf((FILE *)ctx, "%s:%04d: %s", file, line, str);
+ fflush((FILE *)ctx);
+}
+
+static void
+writecb(struct bufferevent *bev, void *arg)
+{
+ fprintf(stderr, "writecb\n");
+}
+
+static void
+readcb(struct bufferevent *bev, void *arg)
+{
+ char buf[1000];
+ size_t r = 0;
+ int i;
+ for (i = 0; i < 10; ++i) {
+ r = bufferevent_read(bev, buf, 800);
+ fprintf(stderr, "readcb %zu\n\n", r);
+ if (r > 1) {
+ fwrite(buf, 1, r, stdout);
+ fwrite("\n", 1, r, stdout);
+ fflush(stdout);
+ }
+ }
+}
+
+static void
+eventcb(struct bufferevent *bev, short what, void *arg)
+{
+ fprintf(stderr, "\n---------------eventcb %d\n", what);
+ if (what & BEV_EVENT_CONNECTED) {
+ const char headers[] = "GET / HTTP/1.1\r\n"
+ "HOST: " SERVER_NAME "\r\n"
+ "User-Agent: curl/7.65.1\r\n"
+ "Connection: Keep-Alive\r\n"
+ "\r\n";
+ bufferevent_write(
+ bev, headers, sizeof(headers) - 1); // without ending '\0'
+ // bufferevent_disable(bev, EV_WRITE);
+ fprintf(stderr, "write request completely\n");
+ } else if (what & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) {
+ fprintf(stderr, "closed\n");
+ bufferevent_free(bev);
+ }
+}
+
+
+int
+main(void)
+{
+ int ret;
+ mbedtls_net_context server_fd;
+ const char *pers = "ssl_client1";
+
+ mbedtls_entropy_context entropy;
+ mbedtls_ctr_drbg_context ctr_drbg;
+ mbedtls_ssl_context ssl;
+ mbedtls_ssl_config conf;
+ mbedtls_x509_crt cacert;
+
+ struct event_base *evbase;
+ struct evdns_base *evdns;
+ struct bufferevent *bev;
+ struct bufferevent *bevf;
+
+#ifdef WIN32
+ WORD wVersionRequested;
+ WSADATA wsaData;
+ int err;
+
+ /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
+ wVersionRequested = MAKEWORD(2, 2);
+
+ err = WSAStartup(wVersionRequested, &wsaData);
+#endif
+
+
+#if defined(MBEDTLS_DEBUG_C)
+ mbedtls_debug_set_threshold(DEBUG_LEVEL);
+#endif
+
+ /*
+ * 0. Initialize the RNG and the session data
+ */
+ mbedtls_net_init(&server_fd);
+ mbedtls_ssl_init(&ssl);
+ mbedtls_ssl_config_init(&conf);
+ mbedtls_x509_crt_init(&cacert);
+ mbedtls_ctr_drbg_init(&ctr_drbg);
+
+ mbedtls_printf("\n . Seeding the random number generator...");
+ fflush(stdout);
+
+ mbedtls_entropy_init(&entropy);
+ if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
+ (const unsigned char *)pers, strlen(pers))) != 0) {
+ mbedtls_printf(" failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret);
+ goto exit;
+ }
+
+ mbedtls_printf(" ok\n");
+
+ /*
+ * 0. Initialize certificates
+ */
+ mbedtls_printf(" . Loading the CA root certificate ...");
+ fflush(stdout);
+
+ ret = mbedtls_x509_crt_parse(&cacert,
+ (const unsigned char *)mbedtls_test_cas_pem, mbedtls_test_cas_pem_len);
+ if (ret < 0) {
+ mbedtls_printf(
+ " failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret);
+ goto exit;
+ }
+
+ mbedtls_printf(" ok (%d skipped)\n", ret);
+
+ /*
+ * 1. Start the connection
+ */
+ mbedtls_printf(" . Connecting to tcp/%s/%s...", SERVER_NAME, SERVER_PORT);
+ fflush(stdout);
+
+ if ((ret = mbedtls_net_connect(&server_fd, SERVER_NAME, SERVER_PORT,
+ MBEDTLS_NET_PROTO_TCP)) != 0) {
+ mbedtls_printf(" failed\n ! mbedtls_net_connect returned %d\n\n", ret);
+ goto exit;
+ }
+
+ mbedtls_printf(" ok\n");
+
+ /*
+ * 2. Setup stuff
+ */
+ mbedtls_printf(" . Setting up the SSL/TLS structure...");
+ fflush(stdout);
+
+ if ((ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT,
+ MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
+ mbedtls_printf(
+ " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret);
+ goto exit;
+ }
+
+ mbedtls_printf(" ok\n");
+
+ /* OPTIONAL is not optimal for security,
+ * but makes interop easier in this simplified example */
+ mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_NONE);
+ mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
+ mbedtls_ssl_conf_dbg(&conf, my_debug, stdout);
+
+ if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
+ mbedtls_printf(" failed\n ! mbedtls_ssl_setup returned %d\n\n", ret);
+ goto exit;
+ }
+
+ if ((ret = mbedtls_ssl_set_hostname(&ssl, SERVER_NAME)) != 0) {
+ mbedtls_printf(
+ " failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret);
+ goto exit;
+ }
+ fflush(stdout);
+
+ event_enable_debug_mode();
+ evbase = event_base_new();
+ evdns = evdns_base_new(evbase, 1);
+ evdns_base_set_option(evdns, "randomize-case:", "0");
+
+ evutil_make_socket_nonblocking(server_fd.fd);
+
+ bev = bufferevent_socket_new(evbase, server_fd.fd, BEV_OPT_CLOSE_ON_FREE);
+ bevf = bufferevent_mbedtls_filter_new(
+ evbase, bev, &ssl, BUFFEREVENT_SSL_CONNECTING, BEV_OPT_CLOSE_ON_FREE);
+ bev = bevf;
+ bufferevent_setcb(bev, readcb, writecb, eventcb, NULL);
+
+ bufferevent_enable(bev, EV_READ);
+
+
+ event_base_loop(evbase, 0);
+ event_base_free(evbase);
+
+
+exit:
+
+#ifdef MBEDTLS_ERROR_C
+ if (ret != 0) {
+ char error_buf[100];
+ mbedtls_strerror(ret, error_buf, 100);
+ mbedtls_printf("Last error was: %d - %s\n\n", ret, error_buf);
+ }
+#endif
+
+ mbedtls_net_free(&server_fd);
+
+ mbedtls_x509_crt_free(&cacert);
+ mbedtls_ssl_free(&ssl);
+ mbedtls_ssl_config_free(&conf);
+ mbedtls_ctr_drbg_free(&ctr_drbg);
+ mbedtls_entropy_free(&entropy);
+
+#if defined(_WIN32)
+ mbedtls_printf(" + Press Enter to exit this program.\n");
+ fflush(stdout);
+ getchar();
+#endif
+
+ return (ret);
+}
+++ /dev/null
-/*
- * SSL client demonstration program
- *
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
- */
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdio.h>
-#include <stdlib.h>
-#define mbedtls_time time
-#define mbedtls_time_t time_t
-#define mbedtls_fprintf fprintf
-#define mbedtls_printf printf
-#endif
-
-#if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_ENTROPY_C) || \
- !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_CLI_C) || \
- !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_RSA_C) || \
- !defined(MBEDTLS_CERTS_C) || !defined(MBEDTLS_PEM_PARSE_C) || \
- !defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_X509_CRT_PARSE_C)
-int main( void )
-{
- mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_ENTROPY_C and/or "
- "MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_CLI_C and/or "
- "MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
- "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C "
- "not defined.\n");
- return( 0 );
-}
-#else
-
-#include "mbedtls/net_sockets.h"
-#include "mbedtls/debug.h"
-#include "mbedtls/ssl.h"
-#include "mbedtls/entropy.h"
-#include "mbedtls/ctr_drbg.h"
-#include "mbedtls/error.h"
-#include "mbedtls/certs.h"
-
-#include <string.h>
-
-#include <event2/event.h>
-#include <event2/bufferevent.h>
-#include <event2/bufferevent_ssl.h>
-#include <event2/util.h>
-
-#define SERVER_PORT "443"
-#define SERVER_NAME "amazon.com"
-#define GET_REQUEST "GET / HTTP/1.0\r\n\r\n"
-
-#define DEBUG_LEVEL 1
-
-static void my_debug( void *ctx, int level,
- const char *file, int line,
- const char *str )
-{
- ((void) level);
-
- mbedtls_fprintf( (FILE *) ctx, "%s:%04d: %s", file, line, str );
- fflush( (FILE *) ctx );
-}
-
-void writecb(struct bufferevent *bev, void *arg)
-{
- fprintf(stderr, "writecb\n");
-}
-
-void readcb(struct bufferevent *bev, void *arg)
-{
- char buf[1000] = {};
- size_t r = 0;
- int i;
- for (i=0; i<10; ++i)
-{
- r = bufferevent_read(bev, buf, 800);
- fprintf(stderr, "readcb %d\n\n", r);
- if (r > 1) {
- fwrite(buf, 1, r, stdout);
- fwrite("\n", 1, r, stdout);
- fflush(stdout);
- }
- }
-}
-
-void eventcb(struct bufferevent *bev, short what, void *arg)
-{
- fprintf(stderr, "\n---------------eventcb %d\n", what);
- if (what & BEV_EVENT_CONNECTED) {
- const char headers[] =
- "GET / HTTP/1.1\r\n"
- "HOST: " SERVER_NAME "\r\n"
- "User-Agent: curl/7.65.1\r\n"
- "Connection: Keep-Alive\r\n"
- "\r\n";
- bufferevent_write(bev, headers, sizeof(headers) - 1); // without ending '\0'
- //bufferevent_disable(bev, EV_WRITE);
- fprintf(stderr, "write request completely\n");
- } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
- fprintf(stderr, "closed\n");
- bufferevent_free(bev);
- }
-}
-
-
-
-int main( void )
-{
- int ret, len;
- mbedtls_net_context server_fd;
- uint32_t flags;
- unsigned char buf[1024];
- const char *pers = "ssl_client1";
-
- mbedtls_entropy_context entropy;
- mbedtls_ctr_drbg_context ctr_drbg;
- mbedtls_ssl_context ssl;
- mbedtls_ssl_config conf;
- mbedtls_x509_crt cacert;
-
- struct event *ev_sigterm;
- struct event_base *evbase;
- struct evdns_base *evdns;
-
-#ifdef WIN32
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
-
- /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
- wVersionRequested = MAKEWORD(2, 2);
-
- err = WSAStartup(wVersionRequested, &wsaData);
-#endif
-
-
-#if defined(MBEDTLS_DEBUG_C)
- mbedtls_debug_set_threshold( DEBUG_LEVEL );
-#endif
-
- /*
- * 0. Initialize the RNG and the session data
- */
- mbedtls_net_init( &server_fd );
- mbedtls_ssl_init( &ssl );
- mbedtls_ssl_config_init( &conf );
- mbedtls_x509_crt_init( &cacert );
- mbedtls_ctr_drbg_init( &ctr_drbg );
-
- mbedtls_printf( "\n . Seeding the random number generator..." );
- fflush( stdout );
-
- mbedtls_entropy_init( &entropy );
- if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
- (const unsigned char *) pers,
- strlen( pers ) ) ) != 0 )
- {
- mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret );
- goto exit;
- }
-
- mbedtls_printf( " ok\n" );
-
- /*
- * 0. Initialize certificates
- */
- mbedtls_printf( " . Loading the CA root certificate ..." );
- fflush( stdout );
-
- ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_cas_pem,
- mbedtls_test_cas_pem_len );
- if( ret < 0 )
- {
- mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret );
- goto exit;
- }
-
- mbedtls_printf( " ok (%d skipped)\n", ret );
-
- /*
- * 1. Start the connection
- */
- mbedtls_printf( " . Connecting to tcp/%s/%s...", SERVER_NAME, SERVER_PORT );
- fflush( stdout );
-
- if( ( ret = mbedtls_net_connect( &server_fd, SERVER_NAME,
- SERVER_PORT, MBEDTLS_NET_PROTO_TCP ) ) != 0 )
- {
- mbedtls_printf( " failed\n ! mbedtls_net_connect returned %d\n\n", ret );
- goto exit;
- }
-
- mbedtls_printf( " ok\n" );
-
- /*
- * 2. Setup stuff
- */
- mbedtls_printf( " . Setting up the SSL/TLS structure..." );
- fflush( stdout );
-
- if( ( ret = mbedtls_ssl_config_defaults( &conf,
- MBEDTLS_SSL_IS_CLIENT,
- MBEDTLS_SSL_TRANSPORT_STREAM,
- MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 )
- {
- mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret );
- goto exit;
- }
-
- mbedtls_printf( " ok\n" );
-
- /* OPTIONAL is not optimal for security,
- * but makes interop easier in this simplified example */
- mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_NONE );
- mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
- mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
- mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
-
- if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
- {
- mbedtls_printf( " failed\n ! mbedtls_ssl_setup returned %d\n\n", ret );
- goto exit;
- }
-
- if( ( ret = mbedtls_ssl_set_hostname( &ssl, SERVER_NAME ) ) != 0 )
- {
- mbedtls_printf( " failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
- goto exit;
- }
- fflush( stdout );
-
- //mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
-
- event_enable_debug_mode();
- evbase = event_base_new();
- evdns = evdns_base_new(evbase, 1);
- evdns_base_set_option(evdns, "randomize-case:", "0");
-
- evutil_make_socket_nonblocking(server_fd.fd);
-
-
-#if 1
-struct bufferevent *bev = bufferevent_socket_new(evbase, server_fd.fd, BEV_OPT_CLOSE_ON_FREE);
-struct bufferevent *bevf = bufferevent_mbedtls_filter_new(
- evbase, bev, &ssl,
- BUFFEREVENT_SSL_CONNECTING, BEV_OPT_CLOSE_ON_FREE);
- bev = bevf;
-#else
-
-struct bufferevent *bev = bufferevent_mbedtls_socket_new(
- evbase, server_fd.fd, &ssl,
- BUFFEREVENT_SSL_CONNECTING, BEV_OPT_CLOSE_ON_FREE);
-#endif
- bufferevent_setcb(bev, readcb, NULL, eventcb, NULL);
-
- bufferevent_enable(bev, EV_READ);
-
-
- event_base_loop(evbase, 0);
- event_base_free(evbase);
-
-
-
-exit:
-
-#ifdef MBEDTLS_ERROR_C
- if( ret != 0 )
- {
- char error_buf[100];
- mbedtls_strerror( ret, error_buf, 100 );
- mbedtls_printf("Last error was: %d - %s\n\n", ret, error_buf );
- }
-#endif
-
- mbedtls_net_free( &server_fd );
-
- mbedtls_x509_crt_free( &cacert );
- mbedtls_ssl_free( &ssl );
- mbedtls_ssl_config_free( &conf );
- mbedtls_ctr_drbg_free( &ctr_drbg );
- mbedtls_entropy_free( &entropy );
-
-#if defined(_WIN32)
- mbedtls_printf( " + Press Enter to exit this program.\n" );
- fflush( stdout ); getchar();
-#endif
-
- return( ret );
-}
-#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C &&
- MBEDTLS_SSL_CLI_C && MBEDTLS_NET_C && MBEDTLS_RSA_C &&
- MBEDTLS_CERTS_C && MBEDTLS_PEM_PARSE_C && MBEDTLS_CTR_DRBG_C &&
- MBEDTLS_X509_CRT_PARSE_C */
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <event2/bufferevent_ssl.h>
+#elif defined(EVENT_EXPORT_TEST_COMPONENT_MBEDTLS)
+#include <mbedtls/ssl.h>
+#include <event2/bufferevent_ssl.h>
#endif
#if defined(EVENT_EXPORT_TEST_COMPONENT_EXTRA)
SSL_free(ssl);
return r;
}
+#elif defined(EVENT_EXPORT_TEST_COMPONENT_MBEDTLS)
+static int
+test()
+{
+ struct event_base *base = NULL;
+ mbedtls_ssl_config *conf = NULL;
+ mbedtls_ssl_context *ssl = NULL;
+ struct bufferevent *bev;
+ int r = 1;
+
+ base = event_base_new();
+ if (!base) {
+ goto error;
+ }
+
+ conf = malloc(sizeof(*conf));
+ if (!conf) {
+ goto error;
+ }
+ mbedtls_ssl_config_init(conf);
+
+ ssl = malloc(sizeof(*ssl));
+ if (!ssl) {
+ goto error;
+ }
+ mbedtls_ssl_init(ssl);
+ mbedtls_ssl_setup(ssl, conf);
+
+ bev = bufferevent_mbedtls_socket_new(base, -1, ssl,
+ BUFFEREVENT_SSL_CONNECTING,
+ BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS);
+ if (bev == NULL) {
+ goto error;
+ }
+ r = 0;
+error:
+ if (base)
+ event_base_free(base);
+ if (ssl) {
+ mbedtls_ssl_free(ssl);
+ free(ssl);
+ }
+ if (conf) {
+ mbedtls_ssl_config_free(conf);
+ free(conf);
+ }
+ return r;
+}
#else
static int
test()
testcase("core", "core", 0)
testcase("extra", "extra", 0)
testcase("openssl", "openssl", 0)
+ testcase("mbedtls", "mbedtls", 0)
testcase("", "", 0)
testcase("extra", "core", 0)
testcase("openssl", "core", 0)
+ testcase("mbedtls", "core", 0)
testcase("core", "extra", 1)
testcase("core", "openssl", 1)
testcase("extra", "openssl", 1)
testcase("openssl", "extra", 1)
+ testcase("core", "mbedtls", 1)
+ testcase("extra", "mbedtls", 1)
+ testcase("mbedtls", "extra", 1)
if platform.system() != "Windows":
testcase("pthreads", "pthreads", 0)
testcase("pthreads", "core", 0)
testcase("pthreads", "extra", 1)
testcase("pthreads", "openssl", 1)
testcase("openssl", "pthreads", 1)
+ testcase("pthreads", "mbedtls", 1)
+ testcase("mbedtls", "pthreads", 1)
def config_restore():
test_regress_LDFLAGS = $(PTHREAD_CFLAGS)
if OPENSSL
-test_regress_SOURCES += test/regress_ssl.c
+test_regress_SOURCES += test/regress_openssl.c
test_regress_CPPFLAGS += $(OPENSSL_INCS)
test_regress_LDADD += libevent_openssl.la $(OPENSSL_LIBS) ${OPENSSL_LIBADD}
endif
+if MBEDTLS
+test_regress_SOURCES += test/regress_mbedtls.c
+test_regress_CPPFLAGS += $(MBEDTLS_INCS)
+test_regress_LDADD += libevent_mbedtls.la $(MBEDTLS_LIBS)
+endif
+
test_bench_SOURCES = test/bench.c
test_bench_LDADD = $(LIBEVENT_GC_SECTIONS) libevent.la
test_bench_cascade_SOURCES = test/bench_cascade.c
extern struct testcase_t minheap_testcases[];
extern struct testcase_t iocp_testcases[];
extern struct testcase_t ssl_testcases[];
+extern struct testcase_t mbedtls_testcases[];
extern struct testcase_t listener_testcases[];
extern struct testcase_t listener_iocp_testcases[];
extern struct testcase_t thread_testcases[];
#endif
#ifdef EVENT__HAVE_OPENSSL
{ "ssl/", ssl_testcases },
+#endif
+#ifdef EVENT__HAVE_MBEDTLS
+ { "mbedtls/", mbedtls_testcases },
#endif
END_OF_GROUPS
};
--- /dev/null
+/*
+ * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/** For event_debug() usage/coverage */
+#define EVENT_VISIBILITY_WANT_DLLIMPORT
+
+#include "event2/util.h"
+#include <mbedtls/ssl.h>
+#include <mbedtls/entropy.h>
+#include <mbedtls/ctr_drbg.h>
+#include <mbedtls/debug.h>
+#include "regress.h"
+#include "tinytest.h"
+
+#define TESTCASES_NAME mbedtls_testcases
+
+#ifdef OPENSSL_VERSION_NUMBER
+#undef OPENSSL_VERSION_NUMBER
+#endif
+#define OPENSSL_VERSION_NUMBER 0
+#define SSL_IS_CLIENT MBEDTLS_SSL_IS_CLIENT
+#define SSL_IS_SERVER MBEDTLS_SSL_IS_SERVER
+
+#define get_ssl_ctx get_mbedtls_config
+
+#define SSL_renegotiate mbedtls_ssl_renegotiate
+#define SSL_get_peer_certificate mbedtls_ssl_get_peer_cert
+#define SSL_new mbedtls_ssl_new
+#define SSL_use_certificate(a, b) \
+ do { \
+ } while (0);
+#define SSL_use_PrivateKey(a, b) \
+ do { \
+ } while (0);
+#define X509_free(x) \
+ do { \
+ } while (0);
+
+#define X509 const mbedtls_x509_crt
+#define SSL mbedtls_ssl_context
+
+#define bufferevent_ssl_get_ssl bufferevent_mbedtls_get_ssl
+#define bufferevent_ssl_set_allow_dirty_shutdown \
+ bufferevent_mbedtls_set_allow_dirty_shutdown
+#define bufferevent_ssl_socket_new bufferevent_mbedtls_socket_new
+#define bufferevent_ssl_filter_new bufferevent_mbedtls_filter_new
+
+struct rwcount;
+static void BIO_setup(SSL *ssl, struct rwcount *rw);
+static mbedtls_ssl_config *get_mbedtls_config(int endpoint);
+static mbedtls_ssl_context *mbedtls_ssl_new(mbedtls_ssl_config *config);
+static void *mbedtls_test_setup(const struct testcase_t *testcase);
+static int mbedtls_test_cleanup(const struct testcase_t *testcase, void *ptr);
+static const struct testcase_setup_t ssl_setup = {
+ mbedtls_test_setup, mbedtls_test_cleanup};
+#include "regress_ssl.c"
+static mbedtls_ssl_config *the_mbedtls_conf[2] = {NULL, NULL};
+static mbedtls_ssl_context *the_mbedtls_ctx[1024] = {NULL};
+static int the_mbedtls_ctx_count = 0;
+static mbedtls_entropy_context entropy;
+static mbedtls_ctr_drbg_context ctr_drbg;
+static mbedtls_x509_crt *the_cert;
+static mbedtls_pk_context *the_key;
+
+static void
+mbedtls_debug(
+ void *userdata, int level, const char *file, int line, const char *str)
+{
+ int loglen = strlen(str);
+ if (str[loglen - 1] == '\n')
+ loglen--;
+ event_debug(("[mbedtls][%s][%d][%s][%d]%.*s", (char *)userdata, level, file,
+ line, loglen, str));
+}
+
+static mbedtls_pk_context *
+mbedtls_getkey(void)
+{
+ int ret = 0;
+ mbedtls_pk_context *pk = malloc(sizeof(mbedtls_pk_context));
+ tt_assert(pk);
+ mbedtls_pk_init(pk);
+ ret = mbedtls_pk_parse_key(
+ pk, (const unsigned char *)KEY, sizeof(KEY), NULL, 0);
+ tt_assert(ret == 0);
+ return pk;
+end:
+ if (pk) {
+ mbedtls_pk_free(pk);
+ free(pk);
+ }
+ return NULL;
+}
+
+static void
+create_tm_from_unix_epoch(struct tm *cur_p, const time_t t)
+{
+#ifdef _WIN32
+ struct tm *tmp = gmtime(&t);
+ if (!tmp) {
+ fprintf(stderr, "gmtime: %s (%i)", strerror(errno), (int)t);
+ exit(1);
+ }
+ *cur_p = *tmp;
+#else
+ gmtime_r(&t, cur_p);
+#endif
+}
+
+static mbedtls_x509_crt *
+mbedtls_getcert(mbedtls_pk_context *pk)
+{
+ const char *name = "commonName=example.com";
+ time_t now = time(NULL);
+ char now_string[32] = "";
+ char not_before[32] = "";
+ char not_after[32] = "";
+ unsigned char certbuf[8192];
+ struct tm tm;
+ mbedtls_x509_crt *crt = NULL;
+ int ret = 0;
+
+ mbedtls_mpi serial;
+ mbedtls_x509write_cert write_cert;
+
+ snprintf(now_string, sizeof(now_string), "%lld", (long long)now);
+
+ create_tm_from_unix_epoch(&tm, now);
+ strftime(not_before, sizeof(not_before), "%Y%m%d%H%M%S", &tm);
+ now += 3600;
+ create_tm_from_unix_epoch(&tm, now);
+ strftime(not_after, sizeof(not_after), "%Y%m%d%H%M%S", &tm);
+
+ mbedtls_x509write_crt_init(&write_cert);
+ mbedtls_x509write_crt_set_version(&write_cert, 2);
+
+ mbedtls_mpi_init(&serial);
+ ret = mbedtls_mpi_read_string(&serial, 10, now_string);
+ tt_assert(ret == 0);
+ ret = mbedtls_x509write_crt_set_serial(&write_cert, &serial);
+ tt_assert(ret == 0);
+ mbedtls_mpi_free(&serial);
+
+ ret = mbedtls_x509write_crt_set_subject_name(&write_cert, name);
+ tt_assert(ret == 0);
+ ret = mbedtls_x509write_crt_set_issuer_name(&write_cert, name);
+ tt_assert(ret == 0);
+
+ mbedtls_x509write_crt_set_md_alg(&write_cert, MBEDTLS_MD_SHA256);
+
+ ret =
+ mbedtls_x509write_crt_set_validity(&write_cert, not_before, not_after);
+ tt_assert(ret == 0);
+ mbedtls_x509write_crt_set_issuer_key(&write_cert, pk);
+ mbedtls_x509write_crt_set_subject_key(&write_cert, pk);
+
+ ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
+ (const unsigned char *)name, strlen(name));
+ tt_assert(ret == 0);
+ ret = mbedtls_x509write_crt_pem(&write_cert, certbuf, sizeof(certbuf),
+ mbedtls_ctr_drbg_random, &ctr_drbg);
+ tt_assert(ret == 0);
+ mbedtls_x509write_crt_free(&write_cert);
+
+ crt = malloc(sizeof(mbedtls_x509_crt));
+ tt_assert(crt);
+ mbedtls_x509_crt_init(crt);
+ ret = mbedtls_x509_crt_parse(crt, certbuf, strlen((char *)certbuf) + 1);
+ tt_assert(ret == 0);
+ return crt;
+end:
+ if (crt) {
+ mbedtls_x509_crt_free(crt);
+ free(crt);
+ }
+ return NULL;
+}
+
+static mbedtls_ssl_config *
+get_mbedtls_config(int endpoint)
+{
+ if (the_mbedtls_conf[endpoint])
+ return the_mbedtls_conf[endpoint];
+ the_mbedtls_conf[endpoint] = malloc(sizeof(mbedtls_ssl_config));
+ if (!the_mbedtls_conf[endpoint])
+ return NULL;
+ mbedtls_ssl_config_init(the_mbedtls_conf[endpoint]);
+ mbedtls_ssl_conf_renegotiation(
+ the_mbedtls_conf[endpoint], MBEDTLS_SSL_RENEGOTIATION_ENABLED);
+ mbedtls_ssl_conf_dbg(the_mbedtls_conf[endpoint], mbedtls_debug,
+ (void *)(endpoint == MBEDTLS_SSL_IS_SERVER ? "server" : "client"));
+ mbedtls_ssl_config_defaults(the_mbedtls_conf[endpoint], endpoint,
+ MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
+ mbedtls_ssl_conf_rng(
+ the_mbedtls_conf[endpoint], mbedtls_ctr_drbg_random, &ctr_drbg);
+ if (disable_tls_11_and_12) {
+ mbedtls_ssl_conf_max_version(the_mbedtls_conf[endpoint],
+ MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1);
+ }
+ if (endpoint == MBEDTLS_SSL_IS_SERVER) {
+ mbedtls_ssl_conf_own_cert(
+ the_mbedtls_conf[endpoint], the_cert, the_key);
+ } else { /* MBEDTLS_SSL_IS_CLIENT */
+ mbedtls_ssl_conf_ca_chain(the_mbedtls_conf[endpoint], the_cert, NULL);
+ }
+ return the_mbedtls_conf[endpoint];
+}
+
+static void
+init_mbedtls(void)
+{
+ mbedtls_debug_set_threshold(5);
+}
+
+static void *
+mbedtls_test_setup(const struct testcase_t *testcase)
+{
+ init_mbedtls();
+
+ mbedtls_entropy_init(&entropy);
+ mbedtls_ctr_drbg_init(&ctr_drbg);
+ mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
+ (const unsigned char *)"libevent", sizeof("libevent"));
+
+ the_key = mbedtls_getkey();
+ EVUTIL_ASSERT(the_key);
+
+ the_cert = mbedtls_getcert(the_key);
+ EVUTIL_ASSERT(the_cert);
+
+ disable_tls_11_and_12 = 0;
+
+ return basic_test_setup(testcase);
+}
+static int
+mbedtls_test_cleanup(const struct testcase_t *testcase, void *ptr)
+{
+ int i;
+ int ret = basic_test_cleanup(testcase, ptr);
+ if (!ret) {
+ return ret;
+ }
+
+ test_is_done = 0;
+ n_connected = 0;
+ got_close = 0;
+ got_error = 0;
+ got_timeout = 0;
+ renegotiate_at = -1;
+ stop_when_connected = 0;
+ pending_connect_events = 0;
+ exit_base = NULL;
+
+ mbedtls_x509_crt_free(the_cert);
+ free(the_cert);
+ mbedtls_pk_free(the_key);
+ free(the_key);
+
+ for (i = 0; i < the_mbedtls_ctx_count; i++) {
+ mbedtls_ssl_free(the_mbedtls_ctx[i]);
+ }
+ if (the_mbedtls_conf[0]) {
+ mbedtls_ssl_config_free(the_mbedtls_conf[0]);
+ free(the_mbedtls_conf[0]);
+ the_mbedtls_conf[0] = NULL;
+ }
+ if (the_mbedtls_conf[1]) {
+ mbedtls_ssl_config_free(the_mbedtls_conf[1]);
+ free(the_mbedtls_conf[1]);
+ the_mbedtls_conf[1] = NULL;
+ }
+
+ return 1;
+}
+
+static mbedtls_ssl_context *
+mbedtls_ssl_new(mbedtls_ssl_config *config)
+{
+ mbedtls_ssl_context *ssl = malloc(sizeof(*ssl));
+ mbedtls_ssl_init(ssl);
+ mbedtls_ssl_setup(ssl, config);
+ the_mbedtls_ctx[the_mbedtls_ctx_count++] = ssl;
+ return ssl;
+}
+
+static int
+bio_rwcount_read(void *ctx, unsigned char *out, size_t outlen)
+{
+ struct rwcount *rw = ctx;
+ ev_ssize_t ret = recv(rw->fd, out, outlen, 0);
+ ++rw->read;
+ if (ret == -1 && EVUTIL_ERR_RW_RETRIABLE(EVUTIL_SOCKET_ERROR())) {
+ return MBEDTLS_ERR_SSL_WANT_READ;
+ }
+ return ret;
+}
+static int
+bio_rwcount_write(void *ctx, const unsigned char *in, size_t inlen)
+{
+ struct rwcount *rw = ctx;
+ ev_ssize_t ret = send(rw->fd, in, inlen, 0);
+ ++rw->write;
+ if (ret == -1 && EVUTIL_ERR_RW_RETRIABLE(EVUTIL_SOCKET_ERROR())) {
+ return MBEDTLS_ERR_SSL_WANT_WRITE;
+ }
+ return ret;
+}
+static void
+BIO_setup(SSL *ssl, struct rwcount *rw)
+{
+ mbedtls_ssl_set_bio(ssl, rw, bio_rwcount_write, bio_rwcount_read,
+ NULL);
+}
--- /dev/null
+/*
+ * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "event2/util.h"
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include "openssl-compat.h"
+#include "regress.h"
+#include "tinytest.h"
+#define TESTCASES_NAME ssl_testcases
+static void *ssl_test_setup(const struct testcase_t *testcase);
+static int ssl_test_cleanup(const struct testcase_t *testcase, void *ptr);
+static const struct testcase_setup_t ssl_setup = {
+ ssl_test_setup, ssl_test_cleanup};
+
+static X509 *the_cert;
+EVP_PKEY *the_key;
+
+#define SSL_IS_CLIENT
+#define SSL_IS_SERVER
+
+#define bufferevent_ssl_get_ssl bufferevent_openssl_get_ssl
+#define bufferevent_ssl_set_allow_dirty_shutdown \
+ bufferevent_openssl_set_allow_dirty_shutdown
+#define bufferevent_ssl_socket_new bufferevent_openssl_socket_new
+#define bufferevent_ssl_filter_new bufferevent_openssl_filter_new
+
+struct rwcount;
+static void BIO_setup(SSL *ssl, struct rwcount *rw);
+#include "regress_ssl.c"
+
+EVP_PKEY *
+ssl_getkey(void)
+{
+ EVP_PKEY *key;
+ BIO *bio;
+
+ /* new read-only BIO backed by KEY. */
+ bio = BIO_new_mem_buf((char *)KEY, -1);
+ tt_assert(bio);
+
+ key = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
+ BIO_free(bio);
+ tt_assert(key);
+
+ return key;
+end:
+ return NULL;
+}
+
+X509 *
+ssl_getcert(EVP_PKEY *key)
+{
+ /* Dummy code to make a quick-and-dirty valid certificate with
+ OpenSSL. Don't copy this code into your own program! It does a
+ number of things in a stupid and insecure way. */
+ X509 *x509 = NULL;
+ X509_NAME *name = NULL;
+ int nid;
+ time_t now = time(NULL);
+
+ tt_assert(key);
+
+ x509 = X509_new();
+ tt_assert(x509);
+ tt_assert(0 != X509_set_version(x509, 2));
+ tt_assert(0 != ASN1_INTEGER_set(X509_get_serialNumber(x509), (long)now));
+
+ name = X509_NAME_new();
+ tt_assert(name);
+ nid = OBJ_txt2nid("commonName");
+ tt_assert(NID_undef != nid);
+ tt_assert(0 != X509_NAME_add_entry_by_NID(name, nid, MBSTRING_ASC,
+ (unsigned char *)"example.com", -1, -1, 0));
+
+ X509_set_subject_name(x509, name);
+ X509_set_issuer_name(x509, name);
+ X509_NAME_free(name);
+
+ X509_time_adj(X509_getm_notBefore(x509), 0, &now);
+ now += 3600;
+ X509_time_adj(X509_getm_notAfter(x509), 0, &now);
+ X509_set_pubkey(x509, key);
+ tt_assert(0 != X509_sign(x509, key, EVP_sha1()));
+
+ return x509;
+end:
+ X509_free(x509);
+ X509_NAME_free(name);
+ return NULL;
+}
+
+static SSL_CTX *the_ssl_ctx = NULL;
+
+SSL_CTX *
+get_ssl_ctx(void)
+{
+ if (the_ssl_ctx)
+ return the_ssl_ctx;
+ the_ssl_ctx = SSL_CTX_new(SSLv23_method());
+ if (!the_ssl_ctx)
+ return NULL;
+ if (disable_tls_11_and_12) {
+#ifdef SSL_OP_NO_TLSv1_2
+ SSL_CTX_set_options(the_ssl_ctx, SSL_OP_NO_TLSv1_2);
+#endif
+#ifdef SSL_OP_NO_TLSv1_1
+ SSL_CTX_set_options(the_ssl_ctx, SSL_OP_NO_TLSv1_1);
+#endif
+ }
+ return the_ssl_ctx;
+}
+
+void
+init_ssl(void)
+{
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
+ (defined(LIBRESSL_VERSION_NUMBER) && \
+ LIBRESSL_VERSION_NUMBER < 0x20700000L)
+ SSL_library_init();
+ ERR_load_crypto_strings();
+ SSL_load_error_strings();
+ OpenSSL_add_all_algorithms();
+ if (SSLeay() != OPENSSL_VERSION_NUMBER) {
+ TT_DECLARE("WARN", ("Version mismatch for openssl: compiled with %lx "
+ "but running with %lx",
+ (unsigned long)OPENSSL_VERSION_NUMBER,
+ (unsigned long)SSLeay()));
+ }
+#endif
+}
+
+static void *
+ssl_test_setup(const struct testcase_t *testcase)
+{
+ init_ssl();
+
+ the_key = ssl_getkey();
+ EVUTIL_ASSERT(the_key);
+
+ the_cert = ssl_getcert(the_key);
+ EVUTIL_ASSERT(the_cert);
+
+ disable_tls_11_and_12 = 0;
+
+ return basic_test_setup(testcase);
+}
+static int
+ssl_test_cleanup(const struct testcase_t *testcase, void *ptr)
+{
+ int ret = basic_test_cleanup(testcase, ptr);
+ if (!ret) {
+ return ret;
+ }
+
+ test_is_done = 0;
+ n_connected = 0;
+ got_close = 0;
+ got_error = 0;
+ got_timeout = 0;
+ renegotiate_at = -1;
+ stop_when_connected = 0;
+ pending_connect_events = 0;
+ exit_base = NULL;
+
+ X509_free(the_cert);
+ EVP_PKEY_free(the_key);
+
+ SSL_CTX_free(the_ssl_ctx);
+ the_ssl_ctx = NULL;
+
+ return 1;
+}
+
+static int
+bio_rwcount_new(BIO *b)
+{
+ BIO_set_init(b, 0);
+ BIO_set_data(b, NULL);
+ return 1;
+}
+static int
+bio_rwcount_free(BIO *b)
+{
+ TT_BLATHER(("bio_rwcount_free: %p", b));
+ if (!b)
+ return 0;
+ if (BIO_get_shutdown(b)) {
+ BIO_set_init(b, 0);
+ BIO_set_data(b, NULL);
+ }
+ return 1;
+}
+static int
+bio_rwcount_read(BIO *b, char *out, int outlen)
+{
+ struct rwcount *rw = BIO_get_data(b);
+ ev_ssize_t ret = recv(rw->fd, out, outlen, 0);
+ ++rw->read;
+ if (ret == -1 && EVUTIL_ERR_RW_RETRIABLE(EVUTIL_SOCKET_ERROR())) {
+ BIO_set_retry_read(b);
+ }
+ return ret;
+}
+static int
+bio_rwcount_write(BIO *b, const char *in, int inlen)
+{
+ struct rwcount *rw = BIO_get_data(b);
+ ev_ssize_t ret = send(rw->fd, in, inlen, 0);
+ ++rw->write;
+ if (ret == -1 && EVUTIL_ERR_RW_RETRIABLE(EVUTIL_SOCKET_ERROR())) {
+ BIO_set_retry_write(b);
+ }
+ return ret;
+}
+static long
+bio_rwcount_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ struct rwcount *rw = BIO_get_data(b);
+ long ret = 0;
+ switch (cmd) {
+ case BIO_C_GET_FD:
+ ret = rw->fd;
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret = BIO_get_shutdown(b);
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ BIO_set_shutdown(b, (int)num);
+ break;
+ case BIO_CTRL_PENDING:
+ ret = 0;
+ break;
+ case BIO_CTRL_WPENDING:
+ ret = 0;
+ break;
+ case BIO_CTRL_DUP:
+ case BIO_CTRL_FLUSH:
+ ret = 1;
+ break;
+ }
+ return ret;
+}
+static int
+bio_rwcount_puts(BIO *b, const char *s)
+{
+ return bio_rwcount_write(b, s, strlen(s));
+}
+#define BIO_TYPE_LIBEVENT_RWCOUNT 0xff1
+static BIO_METHOD *methods_rwcount;
+
+static BIO_METHOD *
+BIO_s_rwcount(void)
+{
+ if (methods_rwcount == NULL) {
+ methods_rwcount = BIO_meth_new(BIO_TYPE_LIBEVENT_RWCOUNT, "rwcount");
+ if (methods_rwcount == NULL)
+ return NULL;
+ BIO_meth_set_write(methods_rwcount, bio_rwcount_write);
+ BIO_meth_set_read(methods_rwcount, bio_rwcount_read);
+ BIO_meth_set_puts(methods_rwcount, bio_rwcount_puts);
+ BIO_meth_set_ctrl(methods_rwcount, bio_rwcount_ctrl);
+ BIO_meth_set_create(methods_rwcount, bio_rwcount_new);
+ BIO_meth_set_destroy(methods_rwcount, bio_rwcount_free);
+ }
+ return methods_rwcount;
+}
+static BIO *
+BIO_new_rwcount(int close_flag)
+{
+ BIO *result;
+ if (!(result = BIO_new(BIO_s_rwcount())))
+ return NULL;
+ BIO_set_init(result, 1);
+ BIO_set_data(result, NULL);
+ BIO_set_shutdown(result, !!close_flag);
+ return result;
+}
+static void
+BIO_setup(SSL *ssl, struct rwcount *rw)
+{
+ BIO *bio;
+ bio = BIO_new_rwcount(0);
+ tt_assert(bio);
+ BIO_set_data(bio, rw);
+ SSL_set_bio(ssl, bio, bio);
+end:
+ return;
+}
#include <netinet/in.h>
#endif
-#include "event2/util.h"
#include "event2/event.h"
#include "event2/bufferevent_ssl.h"
#include "event2/bufferevent_struct.h"
#include "event2/buffer.h"
#include "event2/listener.h"
-#include "regress.h"
#include "tinytest.h"
#include "tinytest_macros.h"
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include "openssl-compat.h"
-
#include <string.h>
#ifdef _WIN32
#include <io.h>
"lhdEOj7mAgHwGwwVZWOgs9Lq6vfztnSuhqjha1daESY6kDscPIQ=\n"
"-----END RSA PRIVATE KEY-----\n";
-EVP_PKEY *
-ssl_getkey(void)
-{
- EVP_PKEY *key;
- BIO *bio;
-
- /* new read-only BIO backed by KEY. */
- bio = BIO_new_mem_buf((char*)KEY, -1);
- tt_assert(bio);
-
- key = PEM_read_bio_PrivateKey(bio,NULL,NULL,NULL);
- BIO_free(bio);
- tt_assert(key);
-
- return key;
-end:
- return NULL;
-}
-
-X509 *
-ssl_getcert(EVP_PKEY *key)
-{
- /* Dummy code to make a quick-and-dirty valid certificate with
- OpenSSL. Don't copy this code into your own program! It does a
- number of things in a stupid and insecure way. */
- X509 *x509 = NULL;
- X509_NAME *name = NULL;
- int nid;
- time_t now = time(NULL);
-
- tt_assert(key);
-
- x509 = X509_new();
- tt_assert(x509);
- tt_assert(0 != X509_set_version(x509, 2));
- tt_assert(0 != ASN1_INTEGER_set(X509_get_serialNumber(x509),
- (long)now));
-
- name = X509_NAME_new();
- tt_assert(name);
- nid = OBJ_txt2nid("commonName");
- tt_assert(NID_undef != nid);
- tt_assert(0 != X509_NAME_add_entry_by_NID(
- name, nid, MBSTRING_ASC, (unsigned char*)"example.com",
- -1, -1, 0));
-
- X509_set_subject_name(x509, name);
- X509_set_issuer_name(x509, name);
- X509_NAME_free(name);
-
- X509_time_adj(X509_getm_notBefore(x509), 0, &now);
- now += 3600;
- X509_time_adj(X509_getm_notAfter(x509), 0, &now);
- X509_set_pubkey(x509, key);
- tt_assert(0 != X509_sign(x509, key, EVP_sha1()));
-
- return x509;
-end:
- X509_free(x509);
- X509_NAME_free(name);
- return NULL;
-}
-
static int disable_tls_11_and_12 = 0;
-static SSL_CTX *the_ssl_ctx = NULL;
-
-SSL_CTX *
-get_ssl_ctx(void)
-{
- if (the_ssl_ctx)
- return the_ssl_ctx;
- the_ssl_ctx = SSL_CTX_new(SSLv23_method());
- if (!the_ssl_ctx)
- return NULL;
- if (disable_tls_11_and_12) {
-#ifdef SSL_OP_NO_TLSv1_2
- SSL_CTX_set_options(the_ssl_ctx, SSL_OP_NO_TLSv1_2);
-#endif
-#ifdef SSL_OP_NO_TLSv1_1
- SSL_CTX_set_options(the_ssl_ctx, SSL_OP_NO_TLSv1_1);
-#endif
- }
- return the_ssl_ctx;
-}
-
static int test_is_done;
static int n_connected;
static int got_close;
static int stop_when_connected;
static int pending_connect_events;
static struct event_base *exit_base;
-static X509 *the_cert;
-EVP_PKEY *the_key;
-
-void
-init_ssl(void)
-{
-#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
- (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
- SSL_library_init();
- ERR_load_crypto_strings();
- SSL_load_error_strings();
- OpenSSL_add_all_algorithms();
- if (SSLeay() != OPENSSL_VERSION_NUMBER) {
- TT_DECLARE("WARN",
- ("Version mismatch for openssl: compiled with %lx but running with %lx",
- (unsigned long)OPENSSL_VERSION_NUMBER, (unsigned long)SSLeay()));
- }
-#endif
-}
-
-static void *
-ssl_test_setup(const struct testcase_t *testcase)
-{
- init_ssl();
-
- the_key = ssl_getkey();
- EVUTIL_ASSERT(the_key);
-
- the_cert = ssl_getcert(the_key);
- EVUTIL_ASSERT(the_cert);
-
- disable_tls_11_and_12 = 0;
-
- return basic_test_setup(testcase);
-}
-static int
-ssl_test_cleanup(const struct testcase_t *testcase, void *ptr)
-{
- int ret = basic_test_cleanup(testcase, ptr);
- if (!ret) {
- return ret;
- }
-
- test_is_done = 0;
- n_connected = 0;
- got_close = 0;
- got_error = 0;
- got_timeout = 0;
- renegotiate_at = -1;
- stop_when_connected = 0;
- pending_connect_events = 0;
- exit_base = NULL;
-
- X509_free(the_cert);
- EVP_PKEY_free(the_key);
-
- SSL_CTX_free(the_ssl_ctx);
- the_ssl_ctx = NULL;
-
- return 1;
-}
-const struct testcase_setup_t ssl_setup = {
- ssl_test_setup, ssl_test_cleanup
-};
/* ====================
};
static void
-bufferevent_openssl_check_fd(struct bufferevent *bev, int filter)
+bufferevent_ssl_check_fd(struct bufferevent *bev, int filter)
{
tt_fd_op(bufferevent_getfd(bev), !=, EVUTIL_INVALID_SOCKET);
tt_fd_op(bufferevent_setfd(bev, EVUTIL_INVALID_SOCKET), ==, 0);
;
}
static void
-bufferevent_openssl_check_freed(struct bufferevent *bev)
+bufferevent_ssl_check_freed(struct bufferevent *bev)
{
tt_int_op(event_pending(&bev->ev_read, EVLIST_ALL, NULL), ==, 0);
tt_int_op(event_pending(&bev->ev_write, EVLIST_ALL, NULL), ==, 0);
return;
}
if ((type & REGRESS_OPENSSL_CLIENT) && n == renegotiate_at) {
- SSL_renegotiate(bufferevent_openssl_get_ssl(bev));
+ SSL_renegotiate(bufferevent_ssl_get_ssl(bev));
}
++n;
evbuffer_add_printf(bufferevent_get_output(bev),
"%d\n", n);
TT_BLATHER(("Done reading; now writing."));
bufferevent_enable(bev, EV_WRITE);
- bufferevent_disable(bev, EV_READ);
+ // we shouldn't disable EV_READ here, otherwise we wouldn't got close cb
+ // bufferevent_disable(bev, EV_READ);
}
static void
if (what & BEV_EVENT_CONNECTED) {
SSL *ssl;
++n_connected;
- ssl = bufferevent_openssl_get_ssl(bev);
+ ssl = bufferevent_ssl_get_ssl(bev);
tt_assert(ssl);
peer_cert = SSL_get_peer_certificate(ssl);
if (type & REGRESS_OPENSSL_SERVER) {
TT_BLATHER(("Got a good EOF"));
++got_close;
if (type & REGRESS_OPENSSL_FD) {
- bufferevent_openssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER);
+ bufferevent_ssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER);
}
if (type & REGRESS_OPENSSL_FREED) {
- bufferevent_openssl_check_freed(bev);
+ bufferevent_ssl_check_freed(bev);
}
bufferevent_free(bev);
} else if (what & BEV_EVENT_ERROR) {
TT_BLATHER(("Got an error."));
++got_error;
if (type & REGRESS_OPENSSL_FD) {
- bufferevent_openssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER);
+ bufferevent_ssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER);
}
if (type & REGRESS_OPENSSL_FREED) {
- bufferevent_openssl_check_freed(bev);
+ bufferevent_ssl_check_freed(bev);
}
bufferevent_free(bev);
} else if (what & BEV_EVENT_TIMEOUT) {
TT_BLATHER(("Got timeout."));
++got_timeout;
if (type & REGRESS_OPENSSL_FD) {
- bufferevent_openssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER);
+ bufferevent_ssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER);
}
if (type & REGRESS_OPENSSL_FREED) {
- bufferevent_openssl_check_freed(bev);
+ bufferevent_ssl_check_freed(bev);
}
bufferevent_free(bev);
}
int state2 = is_open ? BUFFEREVENT_SSL_OPEN :BUFFEREVENT_SSL_ACCEPTING;
int dirty_shutdown = type & REGRESS_OPENSSL_DIRTY_SHUTDOWN;
if (fd_pair) {
- *bev1_out = bufferevent_openssl_socket_new(
+ *bev1_out = bufferevent_ssl_socket_new(
base, fd_pair[0], ssl1, state1, flags);
- *bev2_out = bufferevent_openssl_socket_new(
+ *bev2_out = bufferevent_ssl_socket_new(
base, fd_pair[1], ssl2, state2, flags);
} else {
- *bev1_out = bufferevent_openssl_filter_new(
+ *bev1_out = bufferevent_ssl_filter_new(
base, underlying_pair[0], ssl1, state1, flags);
- *bev2_out = bufferevent_openssl_filter_new(
+ *bev2_out = bufferevent_ssl_filter_new(
base, underlying_pair[1], ssl2, state2, flags);
}
bufferevent_setcb(*bev2_out, respond_to_number, done_writing_cb,
eventcb, (void*)(REGRESS_OPENSSL_SERVER | (long)type));
- bufferevent_openssl_set_allow_dirty_shutdown(*bev1_out, dirty_shutdown);
- bufferevent_openssl_set_allow_dirty_shutdown(*bev2_out, dirty_shutdown);
+ bufferevent_ssl_set_allow_dirty_shutdown(*bev1_out, dirty_shutdown);
+ bufferevent_ssl_set_allow_dirty_shutdown(*bev2_out, dirty_shutdown);
}
static void
renegotiate_at = 600;
}
- ssl1 = SSL_new(get_ssl_ctx());
- ssl2 = SSL_new(get_ssl_ctx());
+ ssl1 = SSL_new(get_ssl_ctx(SSL_IS_CLIENT));
+ ssl2 = SSL_new(get_ssl_ctx(SSL_IS_SERVER));
SSL_use_certificate(ssl2, the_cert);
SSL_use_PrivateKey(ssl2, the_key);
struct basic_test_data *data = arg;
struct bufferevent *bev;
enum regress_openssl_type type;
- SSL *ssl = SSL_new(get_ssl_ctx());
+ SSL *ssl = SSL_new(get_ssl_ctx(SSL_IS_SERVER));
type = (enum regress_openssl_type)data->setup_data;
SSL_use_certificate(ssl, the_cert);
SSL_use_PrivateKey(ssl, the_key);
- bev = bufferevent_openssl_socket_new(
+ bev = bufferevent_ssl_socket_new(
data->base, fd, ssl, BUFFEREVENT_SSL_ACCEPTING,
BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS);
tt_assert(bev);
size_t read;
size_t write;
};
-static int
-bio_rwcount_new(BIO *b)
-{
- BIO_set_init(b, 0);
- BIO_set_data(b, NULL);
- return 1;
-}
-static int
-bio_rwcount_free(BIO *b)
-{
- TT_BLATHER(("bio_rwcount_free: %p", b));
- if (!b)
- return 0;
- if (BIO_get_shutdown(b)) {
- BIO_set_init(b, 0);
- BIO_set_data(b, NULL);
- }
- return 1;
-}
-static int
-bio_rwcount_read(BIO *b, char *out, int outlen)
-{
- struct rwcount *rw = BIO_get_data(b);
- ev_ssize_t ret = recv(rw->fd, out, outlen, 0);
- ++rw->read;
- if (ret == -1 && EVUTIL_ERR_RW_RETRIABLE(EVUTIL_SOCKET_ERROR())) {
- BIO_set_retry_read(b);
- }
- return ret;
-}
-static int
-bio_rwcount_write(BIO *b, const char *in, int inlen)
-{
- struct rwcount *rw = BIO_get_data(b);
- ev_ssize_t ret = send(rw->fd, in, inlen, 0);
- ++rw->write;
- if (ret == -1 && EVUTIL_ERR_RW_RETRIABLE(EVUTIL_SOCKET_ERROR())) {
- BIO_set_retry_write(b);
- }
- return ret;
-}
-static long
-bio_rwcount_ctrl(BIO *b, int cmd, long num, void *ptr)
-{
- struct rwcount *rw = BIO_get_data(b);
- long ret = 0;
- switch (cmd) {
- case BIO_C_GET_FD:
- ret = rw->fd;
- break;
- case BIO_CTRL_GET_CLOSE:
- ret = BIO_get_shutdown(b);
- break;
- case BIO_CTRL_SET_CLOSE:
- BIO_set_shutdown(b, (int)num);
- break;
- case BIO_CTRL_PENDING:
- ret = 0;
- break;
- case BIO_CTRL_WPENDING:
- ret = 0;
- break;
- case BIO_CTRL_DUP:
- case BIO_CTRL_FLUSH:
- ret = 1;
- break;
- }
- return ret;
-}
-static int
-bio_rwcount_puts(BIO *b, const char *s)
-{
- return bio_rwcount_write(b, s, strlen(s));
-}
-#define BIO_TYPE_LIBEVENT_RWCOUNT 0xff1
-static BIO_METHOD *methods_rwcount;
-
-static BIO_METHOD *
-BIO_s_rwcount(void)
-{
- if (methods_rwcount == NULL) {
- methods_rwcount = BIO_meth_new(BIO_TYPE_LIBEVENT_RWCOUNT, "rwcount");
- if (methods_rwcount == NULL)
- return NULL;
- BIO_meth_set_write(methods_rwcount, bio_rwcount_write);
- BIO_meth_set_read(methods_rwcount, bio_rwcount_read);
- BIO_meth_set_puts(methods_rwcount, bio_rwcount_puts);
- BIO_meth_set_ctrl(methods_rwcount, bio_rwcount_ctrl);
- BIO_meth_set_create(methods_rwcount, bio_rwcount_new);
- BIO_meth_set_destroy(methods_rwcount, bio_rwcount_free);
- }
- return methods_rwcount;
-}
-static BIO *
-BIO_new_rwcount(int close_flag)
-{
- BIO *result;
- if (!(result = BIO_new(BIO_s_rwcount())))
- return NULL;
- BIO_set_init(result, 1);
- BIO_set_data(result, NULL);
- BIO_set_shutdown(result, !!close_flag);
- return result;
-}
static void
regress_bufferevent_openssl_connect(void *arg)
tt_assert(listener);
tt_assert(evconnlistener_get_fd(listener) >= 0);
- ssl = SSL_new(get_ssl_ctx());
+ ssl = SSL_new(get_ssl_ctx(SSL_IS_CLIENT));
tt_assert(ssl);
- bev = bufferevent_openssl_socket_new(
+ bev = bufferevent_ssl_socket_new(
data->base, -1, ssl,
BUFFEREVENT_SSL_CONNECTING,
BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS);
/* Possible only when we have fd, since be_openssl can and will overwrite
* bio otherwise before */
if (type & REGRESS_OPENSSL_SLEEP) {
- BIO *bio;
-
rw.fd = bufferevent_getfd(bev);
- bio = BIO_new_rwcount(0);
- tt_assert(bio);
- BIO_set_data(bio, &rw);
- SSL_set_bio(ssl, bio, bio);
+ BIO_setup(ssl, &rw);
}
evbuffer_add_printf(bufferevent_get_output(bev), "1\n");
bufferevent_enable(bev, EV_READ|EV_WRITE);
struct wm_context *ctx = arg;
struct bufferevent *bev;
struct event_base *base = evconnlistener_get_base(listener);
- SSL *ssl = SSL_new(get_ssl_ctx());
+ SSL *ssl = SSL_new(get_ssl_ctx(SSL_IS_SERVER));
SSL_use_certificate(ssl, the_cert);
SSL_use_PrivateKey(ssl, the_key);
- bev = bufferevent_openssl_socket_new(
+ bev = bufferevent_ssl_socket_new(
base, fd, ssl, BUFFEREVENT_SSL_ACCEPTING, ctx->flags);
TT_BLATHER(("wm_transfer-%s(%p): accept",
tt_assert(listener);
tt_assert(evconnlistener_get_fd(listener) >= 0);
- ssl = SSL_new(get_ssl_ctx());
+ ssl = SSL_new(get_ssl_ctx(SSL_IS_CLIENT));
tt_assert(ssl);
if (type & REGRESS_OPENSSL_FILTER) {
bev = bufferevent_socket_new(data->base, -1, client.flags);
tt_assert(bev);
- bev = bufferevent_openssl_filter_new(
+ bev = bufferevent_ssl_filter_new(
base, bev, ssl, BUFFEREVENT_SSL_CONNECTING, client.flags);
} else {
- bev = bufferevent_openssl_socket_new(
+ bev = bufferevent_ssl_socket_new(
data->base, -1, ssl,
BUFFEREVENT_SSL_CONNECTING,
client.flags);
event_base_loop(base, EVLOOP_ONCE);
}
-struct testcase_t ssl_testcases[] = {
+struct testcase_t TESTCASES_NAME[] = {
#define T(a) ((void *)(a))
{ "bufferevent_socketpair", regress_bufferevent_openssl,
TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_SOCKETPAIR) },
{ "bufferevent_socketpair_timeout_freed_fd", regress_bufferevent_openssl,
TT_ISOLATED, &ssl_setup,
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_TIMEOUT | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) },
-
{ "bufferevent_connect", regress_bufferevent_openssl_connect,
TT_FORK|TT_NEED_BASE, &ssl_setup, NULL },
{ "bufferevent_connect_sleep", regress_bufferevent_openssl_connect,
TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_OPENSSL_SLEEP) },
-
{ "bufferevent_wm", regress_bufferevent_openssl_wm,
TT_FORK|TT_NEED_BASE, &ssl_setup, NULL },
{ "bufferevent_wm_filter", regress_bufferevent_openssl_wm,