diff --git a/CMakeLists.txt b/CMakeLists.txt index c5f32e10..f876b8e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,6 +73,8 @@ option(LWS_WITHOUT_DAEMONIZE "Don't build the daemonization api" ON) option(LWS_IPV6 "Compile with support for ipv6" OFF) option(LWS_WITH_HTTP2 "Compile with support for http2" OFF) option(LWS_MBED3 "Platform is MBED3" OFF) +option(LWS_SSL_SERVER_WITH_ECDH_CERT "Include SSL server use ECDH certificate" OFF) + if (DEFINED YOTTA_WEBSOCKETS_VERSION_STRING) @@ -253,6 +255,10 @@ if (MINGW) set(CMAKE_C_FLAGS "-D__USE_MINGW_ANSI_STDIO ${CMAKE_C_FLAGS}") endif() +if (LWS_SSL_SERVER_WITH_ECDH_CERT) + set(LWS_SSL_SERVER_WITH_ECDH_CERT 1) +endif() + include_directories("${PROJECT_BINARY_DIR}") include(CheckCSourceCompiles) @@ -1123,6 +1129,7 @@ message(" LWS_USE_LIBEV = ${LWS_USE_LIBEV}") message(" LWS_IPV6 = ${LWS_IPV6}") message(" LWS_WITH_HTTP2 = ${LWS_WITH_HTTP2}") message(" LWS_MBED3 = ${LWS_MBED3}") +message(" LWS_SSL_SERVER_WITH_ECDH_CERT = ${LWS_SSL_SERVER_WITH_ECDH_CERT}") message("---------------------------------------------------------------------") # These will be available to parent projects including libwebsockets using add_subdirectory() diff --git a/README.coding.md b/README.coding.md index c1a703ec..4775cd52 100644 --- a/README.coding.md +++ b/README.coding.md @@ -316,3 +316,19 @@ static inline int The user code can also override or subclass the file operations, to either wrap or replace them. An example is shown in test server. + +ECDH Support +------------ + +ECDH Certs are now supported. Enable the CMake option + +cmake .. -DLWS_SSL_SERVER_WITH_ECDH_CERT=1 + +**and** the info->options flag + +LWS_SERVER_OPTION_SSL_ECD + +to build in support and select it at runtime. + + + diff --git a/changelog b/changelog index e30e46f7..6d883e58 100644 --- a/changelog +++ b/changelog @@ -144,7 +144,7 @@ The browser shows the close code and reason he received websocket connection CLOSED, code: 1001, reason: seeya -3) There's a new context creation time option flag +4) There's a new context creation time option flag LWS_SERVER_OPTION_VALIDATE_UTF8 @@ -152,6 +152,16 @@ if you set it in info->options, then TEXT and CLOSE frames will get checked to confirm that they contain valid UTF-8. If they don't, the connection will get closed by lws. +5) ECDH Certs are now supported. Enable the CMake option + +cmake .. -DLWS_SSL_SERVER_WITH_ECDH_CERT=1 + +**and** the info->options flag + +LWS_SERVER_OPTION_SSL_ECD + +to build in support and select it at runtime. + User api changes ---------------- diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index deb38438..fc4fd024 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -271,6 +271,7 @@ enum lws_context_options { LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS = (1 << 6), LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED = (1 << 7), LWS_SERVER_OPTION_VALIDATE_UTF8 = (1 << 8), + LWS_SERVER_OPTION_SSL_ECDH = (1 << 9), /****** add new things just above ---^ ******/ }; diff --git a/lib/ssl.c b/lib/ssl.c index c154768d..f72b6b5b 100644 --- a/lib/ssl.c +++ b/lib/ssl.c @@ -92,6 +92,12 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info, struct lws wsi; int error; int n; +#ifdef LWS_SSL_SERVER_WITH_ECDH_CERT + int KeyType; + EC_KEY *EC_key = NULL; + X509 *x; + EVP_PKEY *pkey; +#endif if (info->port != CONTEXT_PORT_NO_LISTEN) { @@ -243,6 +249,34 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info, return 1; } +#ifdef LWS_SSL_SERVER_WITH_ECDH_CERT + if (context->options & LWS_SERVER_OPTION_SSL_ECDH) { + lwsl_notice(" Using ECDH certificate support\n"); + + /* Get X509 certificate from ssl context */ + x = sk_X509_value(context->ssl_ctx->extra_certs, 0); + /* Get the public key from certificate */ + pkey = X509_get_pubkey(x); + /* Get the key type */ + KeyType = EVP_PKEY_type(pkey->type); + + if (EVP_PKEY_EC != KeyType) { + lwsl_err("Key type is not EC\n"); + return 1; + } + /* Get the key */ + EC_key = EVP_PKEY_get1_EC_KEY(pkey); + /* Set ECDH parameter */ + if (!EC_key) { + error = ERR_get_error(); + lwsl_err("ECDH key is NULL \n"); + return 1; + } + SSL_CTX_set_tmp_ecdh(context->ssl_ctx, EC_key); + EC_KEY_free(EC_key); + } +#endif + /* * SSL is happy and has a cert it's content with * If we're supporting HTTP2, initialize that diff --git a/lws_config.h.in b/lws_config.h.in index 185cf079..e03c1d5b 100644 --- a/lws_config.h.in +++ b/lws_config.h.in @@ -68,4 +68,7 @@ /* use SHA1() not internal libwebsockets_SHA1 */ #cmakedefine LWS_SHA1_USE_OPENSSL_NAME +/* SSL server using ECDH certificate */ +#cmakedefine LWS_SSL_SERVER_WITH_ECDH_CERT + ${LWS_SIZEOFPTR_CODE}