#
# libwebsockets - small server side websockets and web server implementation
#
# Copyright (C) 2010 - 2026 Andy Green <andy@warmcat.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
#
# This converts everything about the tls support into
#
# - entries on SOURCES (modifications set back in PARENT_SCOPE)
# - entries on LIB_LIST (modifications set back in PARENT_SCOPE)
# - include_directories()
# - Api build-time discovery results set in PARENT_SCOPE
#
# Everything else is handled privately here.

include_directories(.)

# Allow the user to use the old CyaSSL options/library in stead of wolfSSL
if (LWS_WITH_CYASSL AND LWS_WITH_WOLFSSL)
	message(FATAL_ERROR "LWS_WITH_CYASSL and LWS_WITH_WOLFSSL are mutually exclusive!")
endif()

if (LWS_WITH_CYASSL)
	# Copy CyaSSL options to the wolfSSL options
	set(LWS_WITH_WOLFSSL ${LWS_WITH_CYASSL} CACHE BOOL "Use wolfSSL/CyaSSL instead of OpenSSL" FORCE PARENT_SCOPE)
	set(LWS_WOLFSSL_LIBRARIES ${LWS_CYASSL_LIBRARIES} CACHE PATH "Path to wolfSSL/CyaSSL libraries" FORCE PARENT_SCOPE)
	set(LWS_WOLFSSL_INCLUDE_DIRS ${LWS_CYASSL_INCLUDE_DIRS} CACHE PATH "Path to wolfSSL/CyaSSL header files" FORCE PARENT_SCOPE)
endif()

if (LWS_WITH_OPENHITLS)
	find_package(OpenHITLS)
	if (OPENHITLS_UNSUPPORTED_PLATFORM)
		message(FATAL_ERROR "OpenHITLS is not supported on this platform.")
	elseif (NOT OPENHITLS_FOUND)
		message(FATAL_ERROR "OpenHITLS is selected but not available. Set OPENHITLS_LIBRARIES and OPENHITLS_INCLUDE_DIRS.")
	endif()
	set(LWS_WITH_TLS 1 PARENT_SCOPE)
endif()

set(LWS_OPENSSL_LIBRARIES CACHE PATH "Path to the OpenSSL library" )
set(LWS_OPENSSL_INCLUDE_DIRS CACHE PATH "Path to the OpenSSL include directory" )
set(LWS_WOLFSSL_LIBRARIES CACHE PATH "Path to the wolfSSL library" )
set(LWS_WOLFSSL_INCLUDE_DIRS CACHE PATH "Path to the wolfSSL include directory" )


# BoringSSL and AWS-LC support modern GenHash APIs now

if (LWS_WITH_SSL AND NOT LWS_WITH_WOLFSSL AND NOT LWS_WITH_MBEDTLS AND NOT LWS_WITH_SCHANNEL AND NOT LWS_WITH_OPENHITLS)
	if ("${LWS_OPENSSL_LIBRARIES}" STREQUAL "" OR "${LWS_OPENSSL_INCLUDE_DIRS}" STREQUAL "")
	else()
		if (NOT LWS_PLAT_FREERTOS)
			set(OPENSSL_LIBRARIES ${LWS_OPENSSL_LIBRARIES})
		endif()
		set(OPENSSL_INCLUDE_DIRS ${LWS_OPENSSL_INCLUDE_DIRS})
		set(OPENSSL_FOUND 1)
	endif()
endif()

if (LWS_WITH_SSL AND LWS_WITH_WOLFSSL)
	if ("${LWS_WOLFSSL_LIBRARIES}" STREQUAL "" OR "${LWS_WOLFSSL_INCLUDE_DIRS}" STREQUAL "")
		include (FindPkgConfig)
		PKG_SEARCH_MODULE(LWS_WOLFSSL wolfssl)

		if (NOT LWS_WOLFSSL_FOUND)
			if (LWS_WITH_CYASSL)
				message(FATAL_ERROR "You must set LWS_CYASSL_LIBRARIES and LWS_CYASSL_INCLUDE_DIRS when LWS_WITH_CYASSL is turned on.")
			else()
				message(FATAL_ERROR "You must set LWS_WOLFSSL_LIBRARIES and LWS_WOLFSSL_INCLUDE_DIRS when LWS_WITH_WOLFSSL is turned on.")
			endif()
		else()
			set(WOLFSSL_LIBRARIES ${LWS_WOLFSSL_LIBRARIES})
			set(WOLFSSL_INCLUDE_DIRS ${LWS_WOLFSSL_INCLUDE_DIRS})
			set(WOLFSSL_FOUND 1)
		endif()
	else()
		set(WOLFSSL_LIBRARIES ${LWS_WOLFSSL_LIBRARIES})
		set(WOLFSSL_INCLUDE_DIRS ${LWS_WOLFSSL_INCLUDE_DIRS})
		set(WOLFSSL_FOUND 1)
	endif()
	set(USE_WOLFSSL 1)
	set(USE_WOLFSSL 1 PARENT_SCOPE)
	set(LWS_WITH_TLS 1 PARENT_SCOPE)
	if (LWS_WITH_CYASSL)
		set(USE_OLD_CYASSL 1)
	endif()
endif()

if (LWS_SSL_CLIENT_USE_OS_CA_CERTS)
	set(LWS_SSL_CLIENT_USE_OS_CA_CERTS 1 PARENT_SCOPE)
endif()

if (LWS_WITH_MBEDTLS)
	add_subdirectory(mbedtls)
	include_directories(${_CMAKE_INC_LIST})
endif()

if (LWS_WITH_GNUTLS)
	add_subdirectory(gnutls)
	include_directories(${_CMAKE_INC_LIST})
	if (GNUTLS_INCLUDE_DIRS)
		set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} "${GNUTLS_INCLUDE_DIRS}")
		set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} PARENT_SCOPE)
	endif()
endif()

if (LWS_WITH_BEARSSL)
	if (LWS_WITH_DTLS)
		message(FATAL_ERROR "BearSSL does not support DTLS. Please disable LWS_WITH_DTLS (and features that imply it, like LWS_WITH_WEBRTC) or choose a different TLS backend.")
	endif()
	add_subdirectory(bearssl)
	include_directories(${_CMAKE_INC_LIST})
endif()

# The base dir where the test-apps look for the SSL certs.
set(LWS_OPENSSL_CLIENT_CERTS ../share CACHE PATH "Server SSL certificate directory")
if (WIN32)
	set(LWS_OPENSSL_CLIENT_CERTS . CACHE PATH "Client SSL certificate directory" PARENT_SCOPE)
else()
	set(LWS_OPENSSL_CLIENT_CERTS /etc/pki/tls/certs/ CACHE PATH "Client SSL certificate directory")
endif()

if (LWS_WITH_SSL)
	list(APPEND SOURCES
		tls/tls.c)
	if (LWS_WITH_NETWORK)
		list(APPEND SOURCES
			tls/tls-network.c)
	endif()
	if (LWS_WITH_TLS_SESSIONS)
		list(APPEND SOURCES
			tls/tls-sessions.c)
	endif()
	if (LWS_WITH_TLS_JIT_TRUST)
		list(APPEND SOURCES
			tls/tls-jit-trust.c)
	endif()
	
	if (LWS_WITH_MBEDTLS)
		set(CMAKE_REQUIRED_INCLUDES_TEMP ${CMAKE_REQUIRED_INCLUDES})
		set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${MBEDTLS_INCLUDE_DIRS})
		set(CMAKE_REQUIRED_LIBRARIES_TEMP ${CMAKE_REQUIRED_LIBRARIES})
		set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${MBEDTLS_LIBRARIES})
		CHECK_C_SOURCE_COMPILES("#include <mbedtls/ssl.h>\nint main(void) { void *v = (void *)mbedtls_ssl_set_export_keys_cb; return !!v; }\n" LWS_HAVE_mbedtls_ssl_set_export_keys_cb)
		CHECK_C_SOURCE_COMPILES("#include <mbedtls/ssl.h>\nint main(void) { void *v = (void *)mbedtls_ssl_conf_export_keys_cb; return !!v; }\n" LWS_HAVE_mbedtls_ssl_conf_export_keys_cb)
		CHECK_C_SOURCE_COMPILES("#include <mbedtls/ssl.h>\nint main(void) { void *v = (void *)mbedtls_ssl_set_quic_transport_ops; return !!v; }\n" LWS_HAVE_mbedtls_ssl_set_quic_transport_ops)
		set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES_TEMP})
		set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_TEMP})

		if (LWS_ROLE_QUIC AND NOT LWS_HAVE_mbedtls_ssl_set_export_keys_cb)
			message(WARNING "MbedTLS version too old for QUIC; disabling QUIC and HTTP3")
			set(LWS_ROLE_QUIC 0)
			set(LWS_WITH_HTTP3 0)
			set(LWS_ROLE_H3 0)
			set(LWS_ROLE_WT 0)
			set(LWS_ROLE_QUIC 0 PARENT_SCOPE)
			set(LWS_WITH_HTTP3 0 PARENT_SCOPE)
			set(LWS_ROLE_H3 0 PARENT_SCOPE)
			set(LWS_ROLE_WT 0 PARENT_SCOPE)
		endif()

		if (LWS_ROLE_QUIC AND NOT LWS_HAVE_mbedtls_ssl_set_quic_transport_ops)
			message(FATAL_ERROR "LWS_ROLE_QUIC (HTTP/3) requires mbedtls to be patched with QUIC support. Standard upstream mbedtls doesn't support quic.  See https://libwebsockets.org/git/mbedtls/log?h=development")
		endif()

		list(APPEND SOURCES
			tls/mbedtls/mbedtls-tls.c
			tls/mbedtls/mbedtls-extensions.c
			tls/mbedtls/mbedtls-x509.c)
		if (LWS_ROLE_QUIC AND LWS_WITH_NETWORK)
			list(APPEND SOURCES tls/mbedtls/mbedtls-quic.c)
		endif()
		if (LWS_WITH_NETWORK)
			list(APPEND SOURCES
				tls/mbedtls/mbedtls-ssl.c)
		endif()
		if (LWS_WITH_NETWORK)
			if (LWS_WITH_DTLS)
				list(APPEND SOURCES
					tls/mbedtls/lws-gendtls.c)
			endif()
		endif()
		if (LWS_WITH_TLS_JIT_TRUST)
			list(APPEND SOURCES
				tls/mbedtls/mbedtls-extensions.c)
		endif()
		if (LWS_WITH_TLS_SESSIONS)
			list(APPEND SOURCES
				tls/mbedtls/mbedtls-session.c)
		endif()
		if (LWS_WITH_GENCRYPTO)
			list(APPEND SOURCES
				tls/mbedtls/lws-genhash.c
				tls/mbedtls/lws-genrsa.c
				tls/mbedtls/lws-genaes.c
				tls/lws-genec-common.c
				tls/mbedtls/lws-genec.c
				tls/mbedtls/lws-gencrypto.c)
		endif()
	elseif (LWS_WITH_SCHANNEL)
		list(APPEND SOURCES
			tls/schannel/schannel-tls.c
			tls/schannel/schannel-session.c
			tls/schannel/schannel-x509.c)
		if (LWS_WITH_NETWORK)
			list(APPEND SOURCES tls/schannel/schannel-ssl.c)
		endif()
		if (LWS_ROLE_QUIC AND LWS_WITH_NETWORK)
			list(APPEND SOURCES tls/schannel/schannel-quic.c)
		endif()
		list(APPEND LIB_LIST "ncrypt" "bcrypt" "crypt32" "secur32")
		if (LWS_WITH_GENCRYPTO)
			list(APPEND SOURCES
				tls/schannel/lws-genhash.c
				tls/schannel/lws-genrsa.c
				tls/schannel/lws-genaes.c
				tls/lws-genec-common.c
				tls/schannel/lws-genec.c)
		endif()
		if (LWS_WITH_DTLS)
			list(APPEND SOURCES
				tls/schannel/lws-gendtls.c)
		endif()
	elseif (LWS_WITH_OPENHITLS)
		list(APPEND SOURCES
			tls/openhitls/openhitls-tls.c
			tls/openhitls/openhitls-session.c
			tls/openhitls/openhitls-ssl.c
			tls/openhitls/openhitls-x509.c)
		if (NOT LWS_WITHOUT_SERVER)
			list(APPEND SOURCES
				tls/openhitls/openhitls-server.c)
		endif()
		if (NOT LWS_WITHOUT_CLIENT)
			list(APPEND SOURCES
				tls/openhitls/openhitls-client.c)
		endif()
		if (LWS_WITH_GENCRYPTO)
			list(APPEND SOURCES
				tls/openhitls/lws-genhash.c
				tls/openhitls/lws-genrsa.c
				tls/openhitls/lws-genaes.c
				tls/lws-genec-common.c
				tls/openhitls/lws-genec.c
				tls/openhitls/lws-gencrypto.c)
		endif()
		if (LWS_WITH_NETWORK AND LWS_WITH_DTLS)
			list(APPEND SOURCES
				tls/openhitls/lws-gendtls.c)
		endif()
	elseif (LWS_WITH_GNUTLS)
		list(APPEND SOURCES
			tls/gnutls/gnutls-tls.c
			tls/gnutls/gnutls-x509.c)
		if (LWS_ROLE_QUIC AND LWS_WITH_NETWORK)
			list(APPEND SOURCES tls/gnutls/gnutls-quic.c)
		endif()
		if (LWS_WITH_NETWORK)
			list(APPEND SOURCES
				tls/gnutls/gnutls-ssl.c)
		endif()
		if (LWS_WITH_TLS_SESSIONS)
			list(APPEND SOURCES
				tls/gnutls/gnutls-session.c)
		endif()
		if (LWS_WITH_GENCRYPTO)
			list(APPEND SOURCES
				tls/gnutls/lws-genhash.c
				tls/gnutls/lws-genrsa.c
				tls/gnutls/lws-genaes.c
				tls/lws-genec-common.c
				tls/gnutls/lws-genec.c)
			if (LWS_WITH_DTLS)
				list(APPEND SOURCES
					tls/gnutls/lws-gendtls.c)
			endif()
		endif()
	elseif (LWS_WITH_BEARSSL)
		list(APPEND SOURCES
			tls/bearssl/bearssl-x509.c)
		if (LWS_WITH_NETWORK)
			list(APPEND SOURCES tls/bearssl/bearssl-ssl.c)
		endif()
		if (LWS_WITH_TLS_SESSIONS)
			list(APPEND SOURCES
				tls/bearssl/bearssl-session.c)
		endif()
		if (LWS_WITH_GENCRYPTO)
			list(APPEND SOURCES
				tls/bearssl/bearssl-crypto.c
				tls/lws-genec-common.c)
		endif()
		if (LWS_WITH_DTLS)
			list(APPEND SOURCES
				tls/bearssl/bearssl-dtls.c)
		endif()
	else()
		list(APPEND SOURCES
			tls/openssl/openssl-tls.c
			tls/openssl/openssl-x509.c)
		if (LWS_ROLE_QUIC AND LWS_WITH_NETWORK)
			list(APPEND SOURCES tls/openssl/openssl-quic.c)
		endif()
		if (LWS_WITH_NETWORK)
			list(APPEND SOURCES
				tls/openssl/openssl-ssl.c)
		endif()
		if (LWS_WITH_NETWORK)
			if (LWS_WITH_DTLS)
				list(APPEND SOURCES
					tls/openssl/lws-gendtls.c)
			endif()
		endif()
		if (LWS_WITH_TLS_SESSIONS)
			list(APPEND SOURCES
				tls/openssl/openssl-session.c)
		endif()
		if (LWS_WITH_GENCRYPTO)
			list(APPEND SOURCES
				tls/openssl/lws-genhash.c
				tls/openssl/lws-genrsa.c
				tls/openssl/lws-genaes.c
				tls/lws-genec-common.c
				tls/openssl/lws-genec.c
				tls/openssl/lws-gencrypto.c)
		endif()
	endif()
		
	if (NOT LWS_WITHOUT_SERVER)
		list(APPEND SOURCES
			tls/tls-server.c)
		if (LWS_WITH_MBEDTLS)
			list(APPEND SOURCES
				tls/mbedtls/mbedtls-server.c)
		elseif (LWS_WITH_BEARSSL)
			list(APPEND SOURCES
				tls/bearssl/bearssl-server.c)
		elseif(NOT LWS_WITH_SCHANNEL AND NOT LWS_WITH_GNUTLS AND NOT LWS_WITH_OPENHITLS)
			list(APPEND SOURCES
				tls/openssl/openssl-server.c)
		endif()
	endif()
	if (NOT LWS_WITHOUT_CLIENT)
		list(APPEND SOURCES
			tls/tls-client.c)
		if (LWS_WITH_MBEDTLS)
			list(APPEND SOURCES
				tls/mbedtls/mbedtls-client.c)
		elseif (LWS_WITH_BEARSSL)
			list(APPEND SOURCES
				tls/bearssl/bearssl-client.c)
		elseif(NOT LWS_WITH_SCHANNEL AND NOT LWS_WITH_GNUTLS AND NOT LWS_WITH_OPENHITLS)
			list(APPEND SOURCES
				tls/openssl/openssl-client.c)
		endif()
		
	endif()
endif()

set(SOURCES ${SOURCES} PARENT_SCOPE)

#
# OpenSSL
#
if (LWS_WITH_SSL)
	message("Compiling with SSL support")
	set(chose_ssl 0)
	if (LWS_WITH_WOLFSSL)
		# Use wolfSSL as OpenSSL replacement.
		# TODO: Add a find_package command for this also.
		message("wolfSSL include dir: ${WOLFSSL_INCLUDE_DIRS}")
		message("wolfSSL libraries: ${WOLFSSL_LIBRARIES}")

		# Additional to the root directory we need to include
		# the wolfssl/ subdirectory which contains the OpenSSL
		# compatibility layer headers.

		if (LWS_WITH_CYASSL)
			foreach(inc ${WOLFSSL_INCLUDE_DIRS})
				set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIRS} ${inc} ${inc}/cyassl)
				set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} "${inc}" "${inc}/cyassl")
				set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} PARENT_SCOPE)
			endforeach()
		else()
			foreach(inc ${WOLFSSL_INCLUDE_DIRS})
				set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIRS} ${inc} ${inc}/wolfssl)
				set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} "${inc}" "${inc}/wolfssl")
				set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} PARENT_SCOPE)
			endforeach()
		endif()
		set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${OPENSSL_INCLUDE_DIRS})
		set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} PARENT_SCOPE)
		set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIRS} PARENT_SCOPE)
		set(VARIA wolfSSL_)

		list(INSERT LIB_LIST 0 "${WOLFSSL_LIBRARIES}")
		message("LIB_LIST ${LIB_LIST}")
		set(chose_ssl 1)
	endif()

	if (LWS_WITH_MBEDTLS AND DEFINED MBEDTLS_INCLUDE_DIRS AND DEFINED MBEDTLS_LIBRARIES)
		message("MBEDTLS include dir: ${MBEDTLS_INCLUDE_DIRS}")
		message("MBEDTLS libraries: ${MBEDTLS_LIBRARIES}")

		foreach(inc ${MBEDTLS_INCLUDE_DIRS})
				set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} "${inc}" "${inc}/mbedtls")
				set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} PARENT_SCOPE)
		endforeach()

		list(INSERT LIB_LIST 0 "${MBEDTLS_LIBRARIES}")
	endif()

	if (LWS_WITH_BEARSSL AND DEFINED LWS_BEARSSL_INCLUDE_DIRS AND DEFINED LWS_BEARSSL_LIBRARIES)
		message("BEARSSL include dir: ${LWS_BEARSSL_INCLUDE_DIRS}")
		message("BEARSSL libraries: ${LWS_BEARSSL_LIBRARIES}")

		foreach(inc ${LWS_BEARSSL_INCLUDE_DIRS})
				set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} "${inc}")
				set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} PARENT_SCOPE)
		endforeach()

		list(INSERT LIB_LIST 0 "${LWS_BEARSSL_LIBRARIES}")
	endif()
	
	if (LWS_WITH_MBEDTLS)
		set(chose_ssl 1)
	endif()

	if (LWS_WITH_OPENHITLS)
		message("OpenHITLS include dir: ${OPENHITLS_INCLUDE_DIRS}")
		message("OpenHITLS libraries: ${OPENHITLS_LIBRARIES}")
		if (OPENHITLS_INCLUDE_DIRS)
			set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} "${OPENHITLS_INCLUDE_DIRS}")
			# Add the subdirectories that openHiTLS headers need
			if (EXISTS "${OPENHITLS_INCLUDE_DIRS}/bsl")
				set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} "${OPENHITLS_INCLUDE_DIRS}/bsl")
			endif()
			if (EXISTS "${OPENHITLS_INCLUDE_DIRS}/crypto")
				set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} "${OPENHITLS_INCLUDE_DIRS}/crypto")
			endif()
			if (EXISTS "${OPENHITLS_INCLUDE_DIRS}/pki")
				set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} "${OPENHITLS_INCLUDE_DIRS}/pki")
			endif()
			if (EXISTS "${OPENHITLS_INCLUDE_DIRS}/tls")
				set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} "${OPENHITLS_INCLUDE_DIRS}/tls")
			endif()
			if (EXISTS "${OPENHITLS_INCLUDE_DIRS}/auth")
				set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} "${OPENHITLS_INCLUDE_DIRS}/auth")
			endif()
			set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} PARENT_SCOPE)
			# Also add to compiler include path for this build
			include_directories("${OPENHITLS_INCLUDE_DIRS}")
			if (EXISTS "${OPENHITLS_INCLUDE_DIRS}/bsl")
				include_directories("${OPENHITLS_INCLUDE_DIRS}/bsl")
			endif()
			if (EXISTS "${OPENHITLS_INCLUDE_DIRS}/crypto")
				include_directories("${OPENHITLS_INCLUDE_DIRS}/crypto")
			endif()
			if (EXISTS "${OPENHITLS_INCLUDE_DIRS}/pki")
				include_directories("${OPENHITLS_INCLUDE_DIRS}/pki")
			endif()
			if (EXISTS "${OPENHITLS_INCLUDE_DIRS}/tls")
				include_directories("${OPENHITLS_INCLUDE_DIRS}/tls")
			endif()
			if (EXISTS "${OPENHITLS_INCLUDE_DIRS}/auth")
				include_directories("${OPENHITLS_INCLUDE_DIRS}/auth")
			endif()
		endif()
		if (NOT LWS_PLAT_FREERTOS)
			list(INSERT LIB_LIST 0 ${OPENHITLS_LIBRARIES})
		endif()
		set(LWS_WITH_TLS_KEYLOG 1 PARENT_SCOPE)
		set(chose_ssl 1)
	endif()

	if (LWS_WITH_SCHANNEL OR LWS_WITH_GNUTLS OR LWS_WITH_BEARSSL)
		set(chose_ssl 1)
	endif()

	if (NOT chose_ssl)
		if (OPENSSL_FOUND AND "${OPENSSL_INCLUDE_DIRS}" STREQUAL "")
			set(OPENSSL_INCLUDE_DIRS "${OPENSSL_INCLUDE_DIR}")
		endif()

		if (NOT OPENSSL_FOUND AND NOT LWS_WITH_BORINGSSL AND NOT LWS_WITH_AWSLC)
			# TODO: Add support for STATIC also.
			if (NOT LWS_PLAT_FREERTOS)
				find_package(PkgConfig QUIET)
				pkg_check_modules(PC_OPENSSL openssl QUIET)
				find_package(OpenSSL)
				if (NOT OPENSSL_FOUND)
					message(FATAL_ERROR "OpenSSL development packages (e.g., libssl-dev or openssl-devel) not found! \\nIf you want to use OpenSSL, please install them.\\nIf you installed GnuTLS instead, you must explicitly enable it by adding -DLWS_WITH_GNUTLS=1 to your cmake line.\\nYou can also disable SSL completely with -DLWS_WITH_SSL=0.")
				endif()
				if (NOT OPENSSL_FOUND AND PC_OPENSSL_FOUND)
					list(APPEND OPENSSL_LIBRARIES ${PC_OPENSSL_LINK_LIBRARIES})
				endif()
				set(OPENSSL_LIBRARIES ${OPENSSL_LIBRARIES} PARENT_SCOPE)
			endif()
			set(OPENSSL_INCLUDE_DIRS "${OPENSSL_INCLUDE_DIR}")
		endif()

		message("OpenSSL include dir: ${OPENSSL_INCLUDE_DIRS}")
		if (NOT LWS_PLAT_FREERTOS)
			message("OpenSSL libraries: ${OPENSSL_LIBRARIES}")
		endif()

		if (OPENSSL_INCLUDE_DIRS)
			set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} "${OPENSSL_INCLUDE_DIRS}")
			set(LWS_PUBLIC_INCLUDES ${LWS_PUBLIC_INCLUDES} PARENT_SCOPE)
		endif()
		if (NOT LWS_PLAT_FREERTOS AND OPENSSL_LIBRARIES)
			list(INSERT LIB_LIST 0 ${OPENSSL_LIBRARIES})
		endif()

		if (NOT LWS_WITH_MBEDTLS AND NOT LWS_WITH_OPENHITLS)
			# older (0.98) Openssl lacks this
			set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${OPENSSL_INCLUDE_DIRS} PARENT_SCOPE)
			set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${OPENSSL_INCLUDE_DIRS})
			check_include_file(openssl/ecdh.h LWS_HAVE_OPENSSL_ECDH_H)

			if (LWS_SSL_SERVER_WITH_ECDH_CERT AND NOT LWS_HAVE_OPENSSL_ECDH_H)
				message(FATAL_ERROR "Missing openssl/ecdh.h, so cannot use LWS_SSL_SERVER_WITH_ECDH_CERT")
			endif()
		else()
			unset(LWS_HAVE_OPENSSL_ECDH_H PARENT_SCOPE)
		endif()

		if (LWS_WITH_BORINGSSL OR LWS_WITH_AWSLC)
			if (LWS_WITH_BORINGSSL)
				list(APPEND LIB_LIST "stdc++")
			endif()
			list(APPEND LIB_LIST "pthread")
		endif()
	endif()

endif(LWS_WITH_SSL)

if (DEFINED OPENSSL_INCLUDE_DIRS)
	set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
endif()
if (DEFINED LIB_LIST)
	set(CMAKE_REQUIRED_LIBRARIES ${LIB_LIST})
endif()
if(UNIX AND (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang"))
  check_c_source_compiles("int main() { long long x = 0; __atomic_fetch_add(&x, 1, __ATOMIC_SEQ_CST); return 0; }" HAVE_WORKING_ATOMIC_64)
  if(HAVE_WORKING_ATOMIC_64)
    set(LWS_ATOMIC_LIB "")
  else()
    set(LWS_ATOMIC_LIB atomic)
  endif()
endif()
if (UNIX AND NOT (${CMAKE_SYSTEM_NAME} MATCHES "QNX"))
	set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${CMAKE_DL_LIBS} ${LWS_ATOMIC_LIB})
endif()
if ((CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) AND NOT ((${CMAKE_SYSTEM_NAME} MATCHES "QNX") OR PC_OPENSSL_FOUND))
	set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} pthread)
endif()

if (NOT VARIA)
	set(VARIA "")
endif()

if (NOT LWS_WITH_SCHANNEL AND NOT LWS_WITH_OPENHITLS)

CHECK_FUNCTION_EXISTS(${VARIA}SSL_CTX_set1_param LWS_HAVE_SSL_CTX_set1_param PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}SSL_set_info_callback LWS_HAVE_SSL_SET_INFO_CALLBACK PARENT_SCOPE)

CHECK_FUNCTION_EXISTS(${VARIA}X509_VERIFY_PARAM_set1_host LWS_HAVE_X509_VERIFY_PARAM_set1_host PARENT_SCOPE)

CHECK_FUNCTION_EXISTS(${VARIA}RSA_set0_key LWS_HAVE_RSA_SET0_KEY PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}X509_get_key_usage LWS_HAVE_X509_get_key_usage PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}SSL_CTX_EVP_PKEY_new_raw_private_key LWS_HAVE_SSL_CTX_EVP_PKEY_new_raw_private_key PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}SSL_CTX_get0_certificate LWS_HAVE_SSL_CTX_get0_certificate PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}SSL_get0_alpn_selected LWS_HAVE_SSL_get0_alpn_selected PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}SSL_set_alpn_protos LWS_HAVE_SSL_set_alpn_protos PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}EVP_aes_128_cfb8 LWS_HAVE_EVP_aes_128_cfb8 PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}EVP_aes_128_cfb128 LWS_HAVE_EVP_aes_128_cfb128 PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}EVP_aes_192_cfb8 LWS_HAVE_EVP_aes_192_cfb8 PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}EVP_aes_192_cfb128 LWS_HAVE_EVP_aes_192_cfb128 PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}EVP_aes_256_cfb8 LWS_HAVE_EVP_aes_256_cfb8 PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}EVP_aes_256_cfb128 LWS_HAVE_EVP_aes_256_cfb128 PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}EVP_aes_128_xts LWS_HAVE_EVP_aes_128_xts PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}EVP_aes_128_ofb LWS_HAVE_EVP_aes_128_ofb PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}EVP_aes_128_ecb LWS_HAVE_EVP_aes_128_ecb PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}EVP_aes_128_ctr LWS_HAVE_EVP_aes_128_ctr PARENT_SCOPE)


CHECK_FUNCTION_EXISTS(${VARIA}EVP_aes_128_xts LWS_HAVE_EVP_aes_128_xts PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}RSA_verify_pss_mgf1 LWS_HAVE_RSA_verify_pss_mgf1 PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}HMAC_CTX_new LWS_HAVE_HMAC_CTX_new PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}SSL_CTX_set_ciphersuites LWS_HAVE_SSL_CTX_set_ciphersuites PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}EVP_PKEY_new_raw_private_key LWS_HAVE_EVP_PKEY_new_raw_private_key PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}SSL_SESSION_set_time LWS_HAVE_SSL_SESSION_set_time PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}SSL_SESSION_up_ref LWS_HAVE_SSL_SESSION_up_ref PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}SSL_CTX_set_keylog_callback LWS_HAVE_SSL_CTX_set_keylog_callback PARENT_SCOPE)


# deprecated in openssl v3
CHECK_FUNCTION_EXISTS(${VARIA}EC_KEY_new_by_curve_name LWS_HAVE_EC_KEY_new_by_curve_name PARENT_SCOPE)

if (LWS_WITH_SSL AND NOT LWS_WITH_MBEDTLS AND NOT LWS_WITH_SCHANNEL AND NOT LWS_WITH_GNUTLS AND NOT LWS_WITH_BEARSSL AND NOT LWS_WITH_OPENHITLS)
	# we don't want to confuse what's in or out of the wrapper with
	# what's in an openssl also installed on the build host
CHECK_C_SOURCE_COMPILES("#include <openssl/ssl.h>\nint main(void) { STACK_OF(X509) *c = NULL; SSL_CTX *ctx = NULL; return (int)SSL_CTX_get_extra_chain_certs_only(ctx, &c); }\n" LWS_HAVE_SSL_EXTRA_CHAIN_CERTS)
CHECK_C_SOURCE_COMPILES("#include <openssl/ssl.h>\nint main(void) { EVP_MD_CTX *md_ctx = NULL; EVP_MD_CTX_free(md_ctx); return 0; }\n" LWS_HAVE_EVP_MD_CTX_free)
CHECK_C_SOURCE_COMPILES("#include <openssl/ssl.h>\nint main(void) { OPENSSL_STACK *x = NULL; return !x; } \n" LWS_HAVE_OPENSSL_STACK)
CHECK_C_SOURCE_COMPILES("#include <openssl/ssl.h>\nint main(void) { SSL_CTX *ctx = NULL; return SSL_CTX_set_ecdh_auto(ctx, 1); }\n" LWS_HAVE_SSL_CTX_SET_ECDH_AUTO)
CHECK_C_SOURCE_COMPILES("#include <openssl/ssl.h>\nint main(void) { SSL *ssl = NULL; return (int)SSL_set_tlsext_host_name(ssl, \"hello\"); }\n" LWS_HAVE_SSL_set_tlsext_host_name)

set(LWS_HAVE_SSL_set_tlsext_host_name 1 CACHE BOOL "" FORCE)
set(LWS_HAVE_SSL_EXTRA_CHAIN_CERTS ${LWS_HAVE_SSL_EXTRA_CHAIN_CERTS} PARENT_SCOPE)
set(LWS_HAVE_EVP_MD_CTX_free ${LWS_HAVE_EVP_MD_CTX_free} PARENT_SCOPE)
set(LWS_HAVE_SSL_CTX_SET_ECDH_AUTO ${LWS_HAVE_SSL_CTX_SET_ECDH_AUTO} PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}ECDSA_SIG_set0 LWS_HAVE_ECDSA_SIG_set0 PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}BN_bn2binpad LWS_HAVE_BN_bn2binpad PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}EVP_aes_128_wrap LWS_HAVE_EVP_aes_128_wrap PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}EC_POINT_get_affine_coordinates LWS_HAVE_EC_POINT_get_affine_coordinates PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}SSL_CTX_load_verify_file LWS_HAVE_SSL_CTX_load_verify_file PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}SSL_CTX_load_verify_dir LWS_HAVE_SSL_CTX_load_verify_dir PARENT_SCOPE)

CHECK_C_SOURCE_COMPILES("#include <openssl/ssl.h>\nint main(void) { SSL_set_quic_method(NULL, NULL); return 0; }\n" LWS_HAVE_SSL_SET_QUIC_METHOD)
if (LWS_ROLE_QUIC AND NOT LWS_HAVE_SSL_SET_QUIC_METHOD AND NOT LWS_WITH_BORINGSSL AND NOT LWS_WITH_AWSLC AND NOT LWS_WITH_GNUTLS AND NOT LWS_WITH_WOLFSSL)
	message(FATAL_ERROR "LWS_ROLE_QUIC (HTTP/3) requires BoringSSL, GnuTLS, WolfSSL, or the quictls fork of OpenSSL. Standard upstream OpenSSL is not supported because it lacks SSL_set_quic_method.")
endif()

endif()
endif()

if (LWS_HAVE_SSL_CTX_set_keylog_callback)
	set(LWS_WITH_TLS_KEYLOG 1 PARENT_SCOPE)
endif()

if (LWS_WITH_MBEDTLS)
	set(LWS_HAVE_TLS_CLIENT_METHOD 1 PARENT_SCOPE)
	if (NOT LWS_PLAT_FREERTOS)
		# not supported in esp-idf openssl wrapper yet, but is in our version
		set(LWS_HAVE_X509_VERIFY_PARAM_set1_host 1 PARENT_SCOPE)
	endif()

	set(CMAKE_REQUIRED_LIBRARIES ${MBEDTLS_LIBRARIES} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY})
	set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${MBEDTLS_INCLUDE_DIRS})

	if (ESP_PLATFORM)
		# we know we should have things
		set(LWS_HAVE_MBEDTLS_AUTH_KEY_ID 1 CACHE BOOL x)
		set(LWS_HAVE_mbedtls_ssl_conf_alpn_protocols 1 CACHE BOOL x)
		set(LWS_HAVE_mbedtls_ssl_get_alpn_protocol 1 CACHE BOOL x)
		set(LWS_HAVE_mbedtls_ssl_conf_sni 1 CACHE BOOL x)
		set(LWS_HAVE_mbedtls_ssl_conf_ciphersuites 1 CACHE BOOL x)
		set(LWS_HAVE_mbedtls_ssl_session_save 1 CACHE BOOL x)
		set(LWS_HAVE_mbedtls_ssl_set_hs_ca_chain 1 CACHE BOOL x)
		set(LWS_HAVE_mbedtls_ssl_set_hs_own_cert 1 CACHE BOOL x)
		set(LWS_HAVE_mbedtls_ssl_set_hs_authmode 1 CACHE BOOL x)
		set(LWS_HAVE_mbedtls_net_init 1 CACHE BOOL x)
		set(LWS_HAVE_mbedtls_x509_crt_parse_file 1 CACHE BOOL x) # some embedded may lack filesystem
		set(LWS_HAVE_mbedtls_md_setup 1 CACHE BOOL x) # not on xenial 2.2
		set(LWS_HAVE_mbedtls_rsa_complete 1 CACHE BOOL x) # not on xenial 2.2
		set(LWS_HAVE_mbedtls_internal_aes_encrypt 1 CACHE BOOL x) # not on xenial 2.2
		set(LWS_HAVE_mbedtls_ssl_export_keying_material 1 CACHE BOOL x)
	else()
		CHECK_C_SOURCE_COMPILES("#include <mbedtls/x509_crt.h>\nint main(void) { struct mbedtls_x509_crt c; c.authority_key_id.keyIdentifier.tag = MBEDTLS_ASN1_OCTET_STRING; return c.authority_key_id.keyIdentifier.tag; }\n" LWS_HAVE_MBEDTLS_AUTH_KEY_ID)
		CHECK_C_SOURCE_COMPILES("#include <mbedtls/ssl.h>\nint main(void) { void *v = (void *)mbedtls_ssl_set_verify; return !!v; }\n" LWS_HAVE_mbedtls_ssl_set_verify)
		CHECK_C_SOURCE_COMPILES("#include <mbedtls/ssl.h>\nint main(void) { void *v = (void *)mbedtls_ssl_conf_alpn_protocols; return !!v; }\n" LWS_HAVE_mbedtls_ssl_conf_alpn_protocols)

		CHECK_FUNCTION_EXISTS(mbedtls_ssl_get_alpn_protocol LWS_HAVE_mbedtls_ssl_get_alpn_protocol PARENT_SCOPE)
		CHECK_FUNCTION_EXISTS(mbedtls_ssl_conf_sni LWS_HAVE_mbedtls_ssl_conf_sni PARENT_SCOPE)
		CHECK_FUNCTION_EXISTS(mbedtls_ssl_conf_ciphersuites LWS_HAVE_mbedtls_ssl_conf_ciphersuites PARENT_SCOPE)
		CHECK_FUNCTION_EXISTS(mbedtls_ssl_session_save LWS_HAVE_mbedtls_ssl_session_save PARENT_SCOPE)
		CHECK_FUNCTION_EXISTS(mbedtls_ssl_set_hs_ca_chain LWS_HAVE_mbedtls_ssl_set_hs_ca_chain PARENT_SCOPE)
		CHECK_FUNCTION_EXISTS(mbedtls_ssl_set_hs_own_cert LWS_HAVE_mbedtls_ssl_set_hs_own_cert PARENT_SCOPE)
		CHECK_FUNCTION_EXISTS(mbedtls_ssl_set_hs_authmode LWS_HAVE_mbedtls_ssl_set_hs_authmode PARENT_SCOPE)
		CHECK_FUNCTION_EXISTS(mbedtls_net_init LWS_HAVE_mbedtls_net_init PARENT_SCOPE)
		CHECK_FUNCTION_EXISTS(mbedtls_x509_crt_parse_file LWS_HAVE_mbedtls_x509_crt_parse_file PARENT_SCOPE) # some embedded may lack filesystem
		CHECK_FUNCTION_EXISTS(mbedtls_md_setup LWS_HAVE_mbedtls_md_setup PARENT_SCOPE) # not on xenial 2.2
		CHECK_FUNCTION_EXISTS(mbedtls_rsa_complete LWS_HAVE_mbedtls_rsa_complete PARENT_SCOPE) # not on xenial 2.2
		CHECK_FUNCTION_EXISTS(mbedtls_internal_aes_encrypt LWS_HAVE_mbedtls_internal_aes_encrypt PARENT_SCOPE) # not on xenial 2.2
		CHECK_FUNCTION_EXISTS(mbedtls_ssl_export_keying_material LWS_HAVE_mbedtls_ssl_export_keying_material PARENT_SCOPE)
	endif()
elseif (LWS_WITH_OPENHITLS)
	set(LWS_HAVE_TLS_CLIENT_METHOD 0 PARENT_SCOPE)
else()
CHECK_FUNCTION_EXISTS(${VARIA}TLS_client_method LWS_HAVE_TLS_CLIENT_METHOD PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}TLSv1_2_client_method LWS_HAVE_TLSV1_2_CLIENT_METHOD PARENT_SCOPE)
endif()

# Generate self-signed SSL certs for the test-server.

if (LWS_WITH_SSL) # AND NOT LWS_WITH_WOLFSSL)
	message("Searching for OpenSSL executable and dlls")
	find_package(OpenSSLbins)
	if (DEFINED OPENSSL_EXECUTABLE)
		message("OpenSSL executable: ${OPENSSL_EXECUTABLE}")
		
		if (OPENSSL_EXECUTABLE MATCHES "^$")
			set(OPENSSL_EXECUTABLE openssl)
		endif()
	endif()
	if (NOT DEFINED OPENSSL_EXECUTABLE)
		set(OPENSSL_EXECUTABLE openssl)
	endif()

endif()

set(GENCERTS 0)

if (LWS_WITH_SSL AND OPENSSL_EXECUTABLE AND NOT LWS_WITHOUT_TEST_SERVER AND NOT LWS_WITHOUT_SERVER AND NOT LWS_WITHOUT_TESTAPPS)
	set(GENCERTS 1)
endif()
if (LWS_PLAT_FREERTOS AND LWS_WITH_SSL)
	set(GENCERTS 1)
endif()
message(" GENCERTS = ${GENCERTS}")
if (GENCERTS)
	message("Generating SSL Certificates for the test-server...")

	set(TEST_SERVER_SSL_KEY "${PROJECT_BINARY_DIR}/libwebsockets-test-server.key.pem")
	set(TEST_SERVER_SSL_CERT "${PROJECT_BINARY_DIR}/libwebsockets-test-server.pem")

	if (WIN32)
		if (MINGW)
			message("cmd = \"${OPENSSL_EXECUTABLE}\" req -new -newkey rsa:2048 -days 10000 -nodes -x509 -subj \"/C=GB/ST=Erewhon/L=All around/O=libwebsockets-test/CN=localhost\" -keyout \"${TEST_SERVER_SSL_KEY}\" -out \"${TEST_SERVER_SSL_CERT}\"")
			execute_process(
				COMMAND "${OPENSSL_EXECUTABLE}" req -new -newkey rsa:2048 -days 10000 -nodes -x509 -subj "/C=GB/ST=Erewhon/L=All around/O=libwebsockets-test/CN=localhost" -keyout "${TEST_SERVER_SSL_KEY}" -out "${TEST_SERVER_SSL_CERT}"
				RESULT_VARIABLE OPENSSL_RETURN_CODE)
		else()
			file(WRITE "${PROJECT_BINARY_DIR}/openssl_test_server.cnf"
				"[req]\n"
				"distinguished_name=req_distinguished_name\n"
				"prompt=no\n"
				"\n"
				"[req_distinguished_name]\n"
				"C=GB\n"
				"ST=Erewhon\n"
				"L=All around\n"
				"O=libwebsockets-test\n"
				"CN=localhost\n"
				)

			execute_process(
				COMMAND "${OPENSSL_EXECUTABLE}" req -config "${PROJECT_BINARY_DIR}/openssl_test_server.cnf" -new -newkey rsa:2048 -days 10000 -nodes -x509 -keyout "${TEST_SERVER_SSL_KEY}" -out "${TEST_SERVER_SSL_CERT}"
				RESULT_VARIABLE OPENSSL_RETURN_CODE)

			message("\n")
		endif()

		if (OPENSSL_RETURN_CODE)
			message(WARNING "!!! Failed to generate SSL certificate for Test Server using cmd.exe !!!:\nOpenSSL return code = ${OPENSSL_RETURN_CODE}")
		else()
			message("SUCCSESFULLY generated SSL certificate")
		endif()
	else()
               if (CMAKE_HOST_SYSTEM_NAME MATCHES "NetBSD")
                execute_process(
                        COMMAND "${OPENSSL_EXECUTABLE}"
                                req -new -newkey rsa:2048 -days 10000 -nodes -x509 -subj "/O=lws/CN=localhost" -keyout "${TEST_SERVER_SSL_KEY}" -out "${TEST_SERVER_SSL_CERT}"
                        RESULT_VARIABLE OPENSSL_RETURN_CODE
                        #               OUTPUT_QUIET ERROR_QUIET
                        )

               else()
	
		# Unix.
               execute_process(
                       COMMAND printf "GB\\nErewhon\\nAll around\\nlibwebsockets-test\\n\\nlocalhost\\nnone@invalid.org\\n"
                       COMMAND "${OPENSSL_EXECUTABLE}"
                               req -config /etc/ssl/openssl.cnf -new -newkey rsa:2048 -days 10000 -nodes -x509 -keyout "${TEST_SERVER_SSL_KEY}" -out "${TEST_SERVER_SSL_CERT}"
                       RESULT_VARIABLE OPENSSL_RETURN_CODE
                       #               OUTPUT_QUIET ERROR_QUIET
                       )
		endif()

		if (OPENSSL_RETURN_CODE)
			message(WARNING "!!! Failed to generate SSL certificate for Test Server!!!:\nOpenSSL return code = ${OPENSSL_RETURN_CODE}")
		else()
			message("SUCCESSFULLY generated SSL certificate")
		endif()
	endif()

	if (NOT OPENSSL_RETURN_CODE)
		list(APPEND TEST_SERVER_DATA
			"${TEST_SERVER_SSL_KEY}"
			"${TEST_SERVER_SSL_CERT}")
	endif()
endif()

#
# Copy OpenSSL dlls to the output directory on Windows.
# (Otherwise we'll get an error when trying to run)
#
if (MSVC AND LWS_WITH_SSL AND NOT LWS_WITH_WOLFSSL)
	if(OPENSSL_BIN_FOUND)
		message("OpenSSL dlls found:")
		message("  Libeay: ${LIBEAY_BIN}")
		message("  SSLeay: ${SSLEAY_BIN}")

		foreach(TARGET_BIN ${TEST_APP_LIST})
			add_custom_command(TARGET ${TARGET_BIN}
				POST_BUILD
				COMMAND "${CMAKE_COMMAND}" -E copy "${LIBEAY_BIN}" "$<TARGET_FILE_DIR:${TARGET_BIN}>" VERBATIM)
			add_custom_command(TARGET ${TARGET_BIN}
				POST_BUILD
				COMMAND "${CMAKE_COMMAND}" -E copy "${SSLEAY_BIN}" "$<TARGET_FILE_DIR:${TARGET_BIN}>" VERBATIM)

			#
			# Win32: if we are using libuv, also need to copy it in the output dir
			#
			if (MSVC AND LWS_WITH_LIBUV)
				STRING(REPLACE ".lib" ".dll" LIBUV_BIN ${LIBUV_LIBRARIES})
				add_custom_command(TARGET ${TARGET_BIN}
					POST_BUILD
					COMMAND "${CMAKE_COMMAND}" -E copy "${LIBUV_BIN}" "$<TARGET_FILE_DIR:${TARGET_BIN}>" VERBATIM)
			endif()
		endforeach()
	endif()
endif()

	list(APPEND SOURCES
		tls/lws-gencrypto-common.c
		tls/chacha.c
		tls/poly1305.c
		tls/lws-genchacha.c)



#
# Keep explicit parent scope exports at end
#

exports_to_parent_scope()
set(LWS_HAVE_MBEDTLS_NET_SOCKETS ${LWS_HAVE_MBEDTLS_NET_SOCKETS} PARENT_SCOPE)
set(LWS_HAVE_MBEDTLS_SSL_NEW_SESSION_TICKET ${LWS_HAVE_MBEDTLS_SSL_NEW_SESSION_TICKET} PARENT_SCOPE)
set(LWS_HAVE_mbedtls_ssl_conf_alpn_protocols ${LWS_HAVE_mbedtls_ssl_conf_alpn_protocols} PARENT_SCOPE)
set(LWS_HAVE_mbedtls_ssl_conf_ciphersuites ${LWS_HAVE_mbedtls_ssl_conf_ciphersuites} PARENT_SCOPE)
set(LWS_HAVE_mbedtls_ssl_session_save ${LWS_HAVE_mbedtls_ssl_session_save} PARENT_SCOPE)
set(LWS_HAVE_mbedtls_ssl_set_export_keys_cb ${LWS_HAVE_mbedtls_ssl_set_export_keys_cb} PARENT_SCOPE)
set(LWS_HAVE_mbedtls_ssl_conf_export_keys_cb ${LWS_HAVE_mbedtls_ssl_conf_export_keys_cb} PARENT_SCOPE)
set(LWS_HAVE_mbedtls_ssl_set_quic_transport_ops ${LWS_HAVE_mbedtls_ssl_set_quic_transport_ops} PARENT_SCOPE)
set(TEST_SERVER_SSL_KEY "${TEST_SERVER_SSL_KEY}" PARENT_SCOPE)
set(TEST_SERVER_SSL_CERT "${TEST_SERVER_SSL_CERT}" PARENT_SCOPE)
set(TEST_SERVER_DATA ${TEST_SERVER_DATA} PARENT_SCOPE)
set(LWS_DEP_LIB_PATHS ${LWS_DEP_LIB_PATHS} PARENT_SCOPE)

