]> granicus.if.org Git - libevent/commitdiff
fix build system and add test and cleanup code
authorokhowang(王沛文) <okhowang@tencent.com>
Thu, 28 May 2020 09:14:46 +0000 (17:14 +0800)
committerAzat Khuzhin <azat@libevent.org>
Wed, 22 Jul 2020 19:53:23 +0000 (22:53 +0300)
20 files changed:
CMakeLists.txt
Makefile.am
bufferevent_mbedtls.c
cmake/FindMbedTLS.cmake
configure.ac
event-config.h.cmake
include/event2/bufferevent_ssl.h
include/event2/visibility.h
m4/libevent_mbedtls.m4
sample/include.am
sample/ssl-client-mbedtls.c [new file with mode: 0644]
sample/ssl_client1.c [deleted file]
test-export/test-export.c
test-export/test-export.py
test/include.am
test/regress.h
test/regress_main.c
test/regress_mbedtls.c [new file with mode: 0644]
test/regress_openssl.c [new file with mode: 0644]
test/regress_ssl.c

index f3072aa4425c3322aaba769143c6cf842f2fcbaa..90052916b97c4488f5659458b13bef52cc92d58f 100644 (file)
@@ -991,7 +991,9 @@ endif()
 
 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()
 
@@ -1038,8 +1040,8 @@ macro(add_sample_prog ssl name)
                           ${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()
@@ -1062,13 +1064,18 @@ if (NOT EVENT__DISABLE_SAMPLES)
     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
@@ -1180,7 +1187,11 @@ if (NOT EVENT__DISABLE_TESTS)
             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})
@@ -1193,6 +1204,9 @@ if (NOT EVENT__DISABLE_TESTS)
             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()
index 61d4ff8144c4dbbdea8f4ce909d0139095a21520..a004e898ed6a2468404f72ce9812056ed5b55989 100644 (file)
@@ -101,7 +101,8 @@ LIBEVENT_PKGCONFIG=libevent.pc libevent_core.pc libevent_extra.pc
 # included from other files.
 PLATFORM_DEPENDENT_SRC = \
        arc4random.c \
-       epoll_sub.c
+       epoll_sub.c \
+       test/regress_ssl.c
 
 CMAKE_FILES = \
        cmake/AddCompilerFlags.cmake \
@@ -116,6 +117,7 @@ CMAKE_FILES = \
        cmake/CodeCoverage.cmake \
        cmake/COPYING-CMAKE-SCRIPTS \
        cmake/Copyright.txt \
+       cmake/FindMbedTLS.cmake \
        cmake/LibeventConfig.cmake.in \
        cmake/LibeventConfigVersion.cmake.in \
        cmake/Macros.cmake \
index 22f0b7b145cb99ff287c17a7284ac79b26210e51..5dc95f4755d601260e3a5540db15a43b6c5ced0b 100644 (file)
 #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)
@@ -117,10 +91,6 @@ bio_bufferevent_read(void *ctx, unsigned char *out, size_t outlen)
        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)
@@ -129,17 +99,15 @@ bio_bufferevent_read(void *ctx, unsigned char *out, size_t outlen)
        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)
 {
@@ -147,8 +115,6 @@ 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;
 
@@ -160,7 +126,6 @@ bio_bufferevent_write(void *ctx, const unsigned char *in, size_t inlen)
        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;
@@ -168,22 +133,15 @@ bio_bufferevent_write(void *ctx, const unsigned char *in, size_t inlen)
 
        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 {
@@ -201,8 +159,8 @@ struct bufferevent_mbedtls {
        /* 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;
 
@@ -248,7 +206,7 @@ static int be_mbedtls_flush(struct bufferevent *bufev,
 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,
@@ -407,10 +365,7 @@ conn_closed(struct bufferevent_mbedtls *bev_ssl, int when, int errcode, int ret)
 {
        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)
        { 
@@ -443,33 +398,6 @@ conn_closed(struct bufferevent_mbedtls *bev_ssl, int when, int errcode, int ret)
        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
@@ -507,7 +435,6 @@ do_read(struct bufferevent_mbedtls *bev_ssl, int n_to_read) {
                                        return OP_ERR | result;
                        ++n_used;
                        space[i].iov_len = r;
-                       //decrement_buckets(bev_ssl);
                } else {
                        int err = r;
                        print_err(err);
@@ -584,7 +511,6 @@ do_write(struct bufferevent_mbedtls *bev_ssl, int atmost)
                                        return OP_ERR | result;
                        n_written += r;
                        bev_ssl->last_write = -1;
-                       //decrement_buckets(bev_ssl);
                } else {
                        int err = r;
                        print_err(err);
@@ -924,7 +850,6 @@ do_handshake(struct bufferevent_mbedtls *bev_ssl)
                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);
@@ -1010,7 +935,7 @@ set_handshake_callbacks(struct bufferevent_mbedtls *bev_ssl, evutil_socket_t fd)
 }
 
 int
-bufferevent_ssl_renegotiate(struct bufferevent *bev)
+bufferevent_mbedtls_renegotiate(struct bufferevent *bev)
 {
        struct bufferevent_mbedtls *bev_ssl = upcast(bev);
        if (!bev_ssl)
@@ -1103,7 +1028,9 @@ be_mbedtls_unlink(struct bufferevent *bev)
                        } 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 {
@@ -1169,14 +1096,12 @@ be_mbedtls_set_fd(struct bufferevent_mbedtls *bev_ssl,
        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;
@@ -1256,10 +1181,6 @@ bufferevent_mbedtls_new_impl(struct event_base *base,
                &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;
 
@@ -1277,8 +1198,6 @@ bufferevent_mbedtls_new_impl(struct event_base *base,
        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;
@@ -1340,10 +1259,6 @@ bufferevent_mbedtls_socket_new(struct event_base *base,
        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
index d82baa41985701f5fc104d1b1eb7d79fe5eb13b2..c430269d220ed3b81f5e850e58747a902f346de1 100644 (file)
@@ -124,7 +124,7 @@ endif()
 
 
 include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(mbedTLS
+find_package_handle_standard_args(MbedTLS
                                   FOUND_VAR MBEDTLS_FOUND
                                   REQUIRED_VARS
                                       MBEDTLS_INCLUDE_DIR
index 7caa85a4f8dc6d6a0e9caa2ebe3effe4ad5e1f5c..2599c225078db33705272d0a387a8eddd773f3db 100644 (file)
@@ -60,6 +60,9 @@ AC_ARG_ENABLE(malloc-replacement,
 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])
@@ -179,6 +182,7 @@ AC_SUBST(OPENSSL_LIBADD)
 AC_SYS_LARGEFILE
 
 LIBEVENT_OPENSSL
+LIBEVENT_MBEDTLS
 
 dnl Checks for header files.
 AC_CHECK_HEADERS([ \
@@ -804,7 +808,7 @@ if test x$enable_debug_mode = xno; then
         [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
@@ -812,6 +816,9 @@ 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])
 
@@ -961,5 +968,5 @@ DX_INIT_DOXYGEN([libevent], [${top_srcdir}/Doxyfile], [doxygen])
 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)
index b8f59fefcc5b452761215f7ce3d6003a439732c8..1e7adb1c230a19948d833258eff57162d74985da 100644 (file)
 /* 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
 
index 00e6407110c7474b570568a95bd2c44d01ab6fe0..69fb40b763cda1078f0383f129f5b26f52014d6b 100644 (file)
@@ -194,7 +194,7 @@ bufferevent_mbedtls_get_ssl(struct bufferevent *bufev);
 
 /** 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
index 006bbf06d80f6d4c807c06ce531df33384b78bf1..2b07994a8c5fbfd6c8b00761302d5a29a1a71201 100644 (file)
@@ -33,7 +33,8 @@
     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
index 946a9fdd2af2dbeb72424e78c062cdb343f78eac..4b903b9b08460f8df29b98c2fdd9313c0f39700b 100644 (file)
@@ -11,18 +11,15 @@ case "$enable_mbedtls" in
        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"
index 301787dbcd7d9681187330dcebfaeae24410cee8..19d6a9a6feb4ff3d1ede203c9d328b687a70f8a7 100644 (file)
@@ -40,6 +40,13 @@ noinst_HEADERS += \
        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
diff --git a/sample/ssl-client-mbedtls.c b/sample/ssl-client-mbedtls.c
new file mode 100644 (file)
index 0000000..965913b
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ *  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);
+}
diff --git a/sample/ssl_client1.c b/sample/ssl_client1.c
deleted file mode 100644 (file)
index af8019c..0000000
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- *  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 */
index 9091777554750f2c54bf25b88100201f5bf642e3..3dbeadb55b91d0af136fd019d70f44a96b2438ae 100644 (file)
@@ -9,6 +9,9 @@
 #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)
@@ -90,6 +93,54 @@ error:
                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()
index d71e5dbaa194c0ceb4abf1ec9f0eefeb5f238114..a6def1ca9249d001f5ae1b8876d7d474b0e31601 100644 (file)
@@ -88,13 +88,18 @@ def test_group():
     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)
@@ -103,6 +108,8 @@ def test_group():
         testcase("pthreads", "extra", 1)
         testcase("pthreads", "openssl", 1)
         testcase("openssl", "pthreads", 1)
+        testcase("pthreads", "mbedtls", 1)
+        testcase("mbedtls", "pthreads", 1)
 
 
 def config_restore():
index 50e9cdbd9f87030b8fcbda4dd5c9cd36c67446a3..8ec8d5348fe56cef24686ffc606e335983ee8454 100644 (file)
@@ -149,11 +149,17 @@ test_regress_CPPFLAGS = $(AM_CPPFLAGS) $(PTHREAD_CFLAGS) $(ZLIB_CFLAGS) -Itest
 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
index 55a2fddb9ba573bbce7dfbc8429cf484b2769cbd..3596571527942c8eb57b13415483d6114ff923f6 100644 (file)
@@ -50,6 +50,7 @@ extern struct testcase_t edgetriggered_testcases[];
 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[];
index 2951e3d42310bbea93427be66113fbc75385e647..359459384e8509b69de96a7a041d693e75e1c7fc 100644 (file)
@@ -452,6 +452,9 @@ struct testgroup_t testgroups[] = {
 #endif
 #ifdef EVENT__HAVE_OPENSSL
        { "ssl/", ssl_testcases },
+#endif
+#ifdef EVENT__HAVE_MBEDTLS
+       { "mbedtls/", mbedtls_testcases },
 #endif
        END_OF_GROUPS
 };
diff --git a/test/regress_mbedtls.c b/test/regress_mbedtls.c
new file mode 100644 (file)
index 0000000..44434fe
--- /dev/null
@@ -0,0 +1,335 @@
+/*
+ * 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);
+}
diff --git a/test/regress_openssl.c b/test/regress_openssl.c
new file mode 100644 (file)
index 0000000..1a0ddd0
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * 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;
+}
index 37dc334dcafa30aae2001440e89b04be8ab306f6..b5c37b808edfd9154a844e3900a979000029caa7 100644 (file)
 #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>
@@ -98,91 +92,7 @@ static const char KEY[] =
     "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;
@@ -192,70 +102,6 @@ static int renegotiate_at = -1;
 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
-};
 
 
 /* ====================
@@ -285,7 +131,7 @@ enum regress_openssl_type
 };
 
 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);
@@ -299,7 +145,7 @@ end:
        ;
 }
 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);
@@ -339,14 +185,15 @@ respond_to_number(struct bufferevent *bev, void *ctx)
                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
@@ -372,7 +219,7 @@ eventcb(struct bufferevent *bev, short what, void *ctx)
        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) {
@@ -391,30 +238,30 @@ eventcb(struct bufferevent *bev, short what, void *ctx)
                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);
        }
@@ -434,14 +281,14 @@ open_ssl_bufevs(struct bufferevent **bev1_out, struct bufferevent **bev2_out,
        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);
 
        }
@@ -450,8 +297,8 @@ open_ssl_bufevs(struct bufferevent **bev1_out, struct bufferevent **bev2_out,
        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
@@ -478,8 +325,8 @@ regress_bufferevent_openssl(void *arg)
                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);
@@ -581,14 +428,14 @@ acceptcb(struct evconnlistener *listener, evutil_socket_t fd,
        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);
@@ -618,110 +465,6 @@ struct rwcount
        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)
@@ -755,10 +498,10 @@ 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);
@@ -777,13 +520,8 @@ regress_bufferevent_openssl_connect(void *arg)
        /* 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);
@@ -859,12 +597,12 @@ wm_acceptcb(struct evconnlistener *listener, evutil_socket_t fd,
        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",
@@ -940,16 +678,16 @@ regress_bufferevent_openssl_wm(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);
 
        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);
@@ -988,7 +726,7 @@ end:
                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) },
@@ -1057,12 +795,10 @@ struct testcase_t ssl_testcases[] = {
        { "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,