From 80a7068ec8560cdd817016a70ff08248a2547e3b Mon Sep 17 00:00:00 2001
From: ABruines <alexander.bruines@gmail.com>
Date: Sun, 9 Aug 2015 22:56:32 +0200
Subject: [PATCH] Allow using CyaSSL in stead of wolfSSL

---
 CMakeLists.txt              | 35 ++++++++++++++++++++++++++++++-----
 README.build.md             | 23 +++++++++++++++++------
 cross-openwrt-makefile      |  8 +++++++-
 lib/client.c                | 21 +++++++++++++++++++--
 lib/libwebsockets.h         |  4 ++++
 lib/private-libwebsockets.h |  5 +++++
 lib/ssl.c                   | 10 +++++++++-
 lws_config.h.in             |  6 +++++-
 8 files changed, 96 insertions(+), 16 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 270478f5..cfb14169 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -45,6 +45,7 @@ endif()
 option(LWS_WITH_STATIC "Build the static version of the library" ON)
 option(LWS_WITH_SHARED "Build the shared version of the library" ON)
 option(LWS_WITH_SSL "Include SSL support (default OpenSSL, wolfSSL if LWS_USE_WOLFSSL is set)" ON)
+option(LWS_USE_CYASSL "Use CyaSSL replacement for OpenSSL. When settings this, you also need to specify LWS_CYASSL_LIBRARIES and LWS_CYASSL_INCLUDE_DIRS" OFF)
 option(LWS_USE_WOLFSSL "Use wolfSSL replacement for OpenSSL. When settings this, you also need to specify LWS_WOLFSSL_LIBRARIES and LWS_WOLFSSL_INCLUDE_DIRS" OFF)
 option(LWS_WITH_ZLIB "Include zlib support (required for extensions)" ON)
 option(LWS_WITH_LIBEV "Compile with support for libev" OFF)
@@ -72,6 +73,17 @@ set(LWS_INSTALL_BIN_DIR       bin CACHE PATH "Installation directory for executa
 set(LWS_INSTALL_INCLUDE_DIR   include CACHE PATH "Installation directory for header files")
 set(LWS_INSTALL_EXAMPLES_DIR  bin CACHE PATH "Installation directory for example files")
 
+# Allow the user to use the old CyaSSL options/library in stead of wolfSSL
+if (LWS_USE_CYASSL AND LWS_USE_WOLFSSL)
+	message(FATAL_ERROR "LWS_USE_CYASSL and LWS_USE_WOLFSSL are mutually exclusive!")
+endif()
+if (LWS_USE_CYASSL)
+	# Copy CyaSSL options to the wolfSSL options
+	set(LWS_USE_WOLFSSL ${LWS_USE_CYASSL} CACHE BOOL "Use wolfSSL/CyaSSL instead of OpenSSL" FORCE)
+	set(LWS_WOLFSSL_LIBRARIES ${LWS_CYASSL_LIBRARIES} CACHE PATH "Path to wolfSSL/CyaSSL libraries" FORCE)
+	set(LWS_WOLFSSL_INCLUDE_DIRS ${LWS_CYASSL_INCLUDE_DIRS} CACHE PATH "Path to wolfSSL/CyaSSL header files" FORCE)
+endif()
+
 if (LWS_WITHOUT_CLIENT AND LWS_WITHOUT_SERVER)
 	message(FATAL_ERROR "Makes no sense to compile without both client or server.")
 endif()
@@ -107,7 +119,11 @@ endif()
 if (LWS_WITH_SSL AND LWS_USE_WOLFSSL)
 	if ("${LWS_WOLFSSL_LIBRARIES}" STREQUAL "" OR "${LWS_WOLFSSL_INCLUDE_DIRS}" STREQUAL "")
 		if (NOT WOLFSSL_FOUND)
-			message(FATAL_ERROR "You must set LWS_WOLFSSL_LIBRARIES and LWS_WOLFSSL_INCLUDE_DIRS when LWS_USE_WOLFSSL is turned on.")
+			if (LWS_USE_CYASSL)
+				message(FATAL_ERROR "You must set LWS_CYASSL_LIBRARIES and LWS_CYASSL_INCLUDE_DIRS when LWS_USE_CYASSL is turned on.")
+			else()
+				message(FATAL_ERROR "You must set LWS_WOLFSSL_LIBRARIES and LWS_WOLFSSL_INCLUDE_DIRS when LWS_USE_WOLFSSL is turned on.")
+			endif()
 		endif()
 	else()
 		set(WOLFSSL_LIBRARIES ${LWS_WOLFSSL_LIBRARIES})
@@ -115,6 +131,9 @@ if (LWS_WITH_SSL AND LWS_USE_WOLFSSL)
 		set(WOLFSSL_FOUND 1)
 	endif()
 	set(USE_WOLFSSL 1)
+	if (LWS_USE_CYASSL)
+		set(USE_OLD_CYASSL 1)
+	endif()
 endif()
 
 if (LWS_WITH_ZLIB AND NOT LWS_USE_BUNDLED_ZLIB)
@@ -525,9 +544,15 @@ if (LWS_WITH_SSL)
 		# Additional to the root directory we need to include
 		# the wolfssl/ subdirectory which contains the OpenSSL
 		# compatability layer headers.
-		foreach(inc ${WOLFSSL_INCLUDE_DIRS})
-			include_directories("${inc}" "${inc}/wolfssl")
-		endforeach()
+		if (LWS_USE_CYASSL)
+			foreach(inc ${WOLFSSL_INCLUDE_DIRS})
+				include_directories("${inc}" "${inc}/cyassl")
+			endforeach()
+		else()
+			foreach(inc ${WOLFSSL_INCLUDE_DIRS})
+				include_directories("${inc}" "${inc}/wolfssl")
+			endforeach()
+		endif()
 
 		list(APPEND LIB_LIST "${WOLFSSL_LIBRARIES}")
 	else()
@@ -933,7 +958,7 @@ message("  Settings:  (For more help do cmake -LH <srcpath>)")
 message("---------------------------------------------------------------------")
 message(" LWS_WITH_SSL = ${LWS_WITH_SSL}  (SSL Support)")
 message(" LWS_SSL_CLIENT_USE_OS_CA_CERTS = ${LWS_SSL_CLIENT_USE_OS_CA_CERTS}")
-message(" LWS_USE_WOLFSSL = ${LWS_USE_WOLFSSL} (wolfSSL replacement for OpenSSL)")
+message(" LWS_USE_WOLFSSL = ${LWS_USE_WOLFSSL} (wolfSSL/CyaSSL replacement for OpenSSL)")
 if (LWS_USE_WOLFSSL)
 	message("   LWS_WOLFSSL_LIBRARIES = ${LWS_WOLFSSL_LIBRARIES}")
 	message("   LWS_WOLFSSL_INCLUDE_DIRS = ${LWS_WOLFSSL_INCLUDE_DIRS}")
diff --git a/README.build.md b/README.build.md
index 10647bbd..5f17235b 100644
--- a/README.build.md
+++ b/README.build.md
@@ -151,9 +151,9 @@ Windows GUI
 On windows CMake comes with a gui application:
 	Start -> Programs -> CMake -> CMake (cmake-gui)
 
-wolfSSL replacement for OpenSSL
-------------------------------
-wolfSSL is a lightweight SSL library targeted at embedded systems:
+wolfSSL/CyaSSL replacement for OpenSSL
+--------------------------------------
+wolfSSL/CyaSSL is a lightweight SSL library targeted at embedded systems:
 https://www.wolfssl.com/wolfSSL/Products-wolfssl.html
 
 It contains a OpenSSL compatability layer which makes it possible to pretty
@@ -163,15 +163,26 @@ much link to it instead of OpenSSL, giving a much smaller footprint.
 this to work.
 
 Compiling libwebsockets with wolfSSL
------------------------------------
+------------------------------------
 
 ```bash
 cmake .. -DLWS_USE_WOLFSSL=1 \
 	 -DLWS_WOLFSSL_INCLUDE_DIRS=/path/to/wolfssl \
-	 -DLWS_WOLFSSL_LIB=/path/to/wolfssl/wolfssl.a ..
+	 -DLWS_WOLFSSL_LIBRARIES=/path/to/wolfssl/wolfssl.a ..
+```
+
+**NOTE**: On windows use the .lib file extension for `LWS_WOLFSSL_LIBRARIES` instead.
+
+Compiling libwebsockets with CyaSSL
+-----------------------------------
+
+```bash
+cmake .. -DLWS_USE_CYASSL=1 \
+	 -DLWS_CYASSL_INCLUDE_DIRS=/path/to/cyassl \
+	 -DLWS_CYASSL_LIBRARIES=/path/to/wolfssl/cyassl.a ..
 ```
 
-**NOTE**: On windows use the .lib file extension for `LWS_WOLFSSL_LIB` instead.
+**NOTE**: On windows use the .lib file extension for `LWS_CYASSL_LIBRARIES` instead.
 
 
 Reproducing HTTP2.0 tests
diff --git a/cross-openwrt-makefile b/cross-openwrt-makefile
index 2298ffb9..25043709 100644
--- a/cross-openwrt-makefile
+++ b/cross-openwrt-makefile
@@ -26,9 +26,15 @@ CMAKE_OPTIONS += -DLWS_WITHOUT_TESTAPPS=$(if $(CONFIG_PACKAGE_libwebsockets-exam
 # for wolfssl, define these in addition to LWS_OPENSSL_SUPPORT and
 # edit package/libs/wolfssl/Makefile to include --enable-opensslextra
 # CMAKE_OPTIONS += -DLWS_USE_WOLFSSL=ON
-# CMAKE_OPTIONS += -DLWS_WOLFSSL_LIB=$(STAGING_DIR)/usr/lib/libwolfssl.so
+# CMAKE_OPTIONS += -DLWS_WOLFSSL_LIBRARIES=$(STAGING_DIR)/usr/lib/libwolfssl.so
 # CMAKE_OPTIONS += -DLWS_WOLFSSL_INCLUDE_DIRS=$(STAGING_DIR)/usr/include
 
+# for cyassl, define these in addition to LWS_OPENSSL_SUPPORT and
+# edit package/libs/wolfssl/Makefile to include --enable-opensslextra
+# CMAKE_OPTIONS += -DLWS_USE_CYASSL=ON
+# CMAKE_OPTIONS += -DLWS_CYASSL_LIBRARIES=$(STAGING_DIR)/usr/lib/libcyassl.so
+# CMAKE_OPTIONS += -DLWS_CYASSL_INCLUDE_DIRS=$(STAGING_DIR)/usr/include
+
 # other options worth noting
 # CMAKE_OPTIONS += -DLWS_WITHOUT_EXTENSIONS=ON
 # CMAKE_OPTIONS += -DLWS_WITHOUT_DAEMONIZE=ON
diff --git a/lib/client.c b/lib/client.c
index bf39b23a..8c9ef915 100644
--- a/lib/client.c
+++ b/lib/client.c
@@ -132,7 +132,7 @@ int lws_client_socket_service(struct libwebsocket_context *context,
 		/* we can retry this... just cook the SSL BIO the first time */
 
 		if (wsi->use_ssl && !wsi->ssl) {
-#if defined(WOLFSSL_SNI_HOST_NAME) || defined(SSL_CTRL_SET_TLSEXT_HOSTNAME)
+#if defined(CYASSL_SNI_HOST_NAME) || defined(WOLFSSL_SNI_HOST_NAME) || defined(SSL_CTRL_SET_TLSEXT_HOSTNAME)
 			const char *hostname = lws_hdr_simple_ptr(wsi,
 						_WSI_TOKEN_CLIENT_PEER_ADDRESS);
 #endif
@@ -147,10 +147,17 @@ int lws_client_socket_service(struct libwebsocket_context *context,
 			 * when establishing connection
 			 */
 #ifdef USE_WOLFSSL
+#ifdef USE_OLD_CYASSL
+#ifdef CYASSL_SNI_HOST_NAME
+			CyaSSL_UseSNI(wsi->ssl, CYASSL_SNI_HOST_NAME,
+				hostname, strlen(hostname));
+#endif
+#else
 #ifdef WOLFSSL_SNI_HOST_NAME
 			wolfSSL_UseSNI(wsi->ssl, WOLFSSL_SNI_HOST_NAME,
 				hostname, strlen(hostname));
 #endif
+#endif
 #else
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
 			SSL_set_tlsext_host_name(wsi->ssl, hostname);
@@ -159,16 +166,22 @@ int lws_client_socket_service(struct libwebsocket_context *context,
 
 #ifdef USE_WOLFSSL
 			/*
-			 * wolfSSL does certificate verification differently
+			 * wolfSSL/CyaSSL does certificate verification differently
 			 * from OpenSSL.
 			 * If we should ignore the certificate, we need to set
 			 * this before SSL_new and SSL_connect is called.
 			 * Otherwise the connect will simply fail with error
 			 * code -155
 			 */
+#ifdef USE_OLD_CYASSL
+			if (wsi->use_ssl == 2)
+				CyaSSL_set_verify(wsi->ssl,
+							SSL_VERIFY_NONE, NULL);
+#else
 			if (wsi->use_ssl == 2)
 				wolfSSL_set_verify(wsi->ssl,
 							SSL_VERIFY_NONE, NULL);
+#endif
 #endif /* USE_WOLFSSL */
 
 			wsi->client_bio =
@@ -176,7 +189,11 @@ int lws_client_socket_service(struct libwebsocket_context *context,
 			SSL_set_bio(wsi->ssl, wsi->client_bio, wsi->client_bio);
 
 #ifdef USE_WOLFSSL
+#ifdef USE_OLD_CYASSL
+			CyaSSL_set_using_nonblock(wsi->ssl, 1);
+#else
 			wolfSSL_set_using_nonblock(wsi->ssl, 1);
+#endif
 #else
 			BIO_set_nbio(wsi->client_bio, 1); /* nonblocking */
 #endif
diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h
index 91a8e5e9..e79b25af 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -92,7 +92,11 @@ extern "C" {
 
 #ifdef LWS_OPENSSL_SUPPORT
 #ifdef USE_WOLFSSL
+#ifdef USE_OLD_CYASSL
+#include <cyassl/openssl/ssl.h>
+#else
 #include <wolfssl/openssl/ssl.h>
+#endif /* not USE_OLD_CYASSL */
 #else
 #include <openssl/ssl.h>
 #endif /* not USE_WOLFSSL */
diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h
index 81499564..a35b9ead 100644
--- a/lib/private-libwebsockets.h
+++ b/lib/private-libwebsockets.h
@@ -150,8 +150,13 @@
 
 #ifdef LWS_OPENSSL_SUPPORT
 #ifdef USE_WOLFSSL
+#ifdef USE_OLD_CYASSL
+#include <cyassl/openssl/ssl.h>
+#include <cyassl/error-ssl.h>
+#else
 #include <wolfssl/openssl/ssl.h>
 #include <wolfssl/error-ssl.h>
+#endif /* not USE_OLD_CYASSL */
 #else
 #include <openssl/ssl.h>
 #include <openssl/evp.h>
diff --git a/lib/ssl.c b/lib/ssl.c
index 0d518545..b8154683 100644
--- a/lib/ssl.c
+++ b/lib/ssl.c
@@ -89,7 +89,11 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info,
 		context->use_ssl = info->ssl_cert_filepath != NULL;
 
 #ifdef USE_WOLFSSL
-		lwsl_notice(" Compiled with WOLFSSL support\n");
+#ifdef USE_OLD_CYASSL
+		lwsl_notice(" Compiled with CyaSSL support\n");
+#else
+		lwsl_notice(" Compiled with wolfSSL support\n");
+#endif
 #else
 		lwsl_notice(" Compiled with OpenSSL support\n");
 #endif
@@ -545,7 +549,11 @@ lws_server_socket_service_ssl(struct libwebsocket_context *context,
 		SSL_set_fd(new_wsi->ssl, accept_fd);
 
 #ifdef USE_WOLFSSL
+#ifdef USE_OLD_CYASSL
+		CyaSSL_set_using_nonblock(new_wsi->ssl, 1);
+#else
 		wolfSSL_set_using_nonblock(new_wsi->ssl, 1);
+#endif
 #else
 		SSL_set_mode(new_wsi->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
 		bio = SSL_get_rbio(new_wsi->ssl);
diff --git a/lws_config.h.in b/lws_config.h.in
index 4d66892f..65c4d0a4 100644
--- a/lws_config.h.in
+++ b/lws_config.h.in
@@ -6,10 +6,14 @@
 	#endif
 #endif
 
-/* Define to 1 to use wolfSSL as a replacement for OpenSSL.
+/* Define to 1 to use wolfSSL/CyaSSL as a replacement for OpenSSL.
  * LWS_OPENSSL_SUPPORT needs to be set also for this to work. */
 #cmakedefine USE_WOLFSSL
 
+/* Also define to 1 (in addition to USE_WOLFSSL) when using the
+  (older) CyaSSL library */
+#cmakedefine USE_OLD_CYASSL
+
 /* The Libwebsocket version */
 #cmakedefine LWS_LIBRARY_VERSION "${LWS_LIBRARY_VERSION}"
 
-- 
GitLab