From 2174ff7dd6e856f0bc2dccdbdf346d1decc6cf26 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 22 Feb 2013 09:54:35 +0800 Subject: [PATCH] move ssl cipher list from compiletime to context creation time option More flexible this way... NULL for the new member means use the ssl library default set of ciphers, so as long as your info struct is zerod by bss or memset, you don't need to do anything about this change unless you want to set the cipher list. Signed-off-by: Andy Green --- README.build | 9 --------- README.coding | 15 +++++++++++++++ changelog | 6 ++++++ lib/libwebsockets.c | 12 ++++++++---- lib/libwebsockets.h | 4 ++++ libwebsockets-api-doc.html | 7 ++++++- 6 files changed, 39 insertions(+), 14 deletions(-) diff --git a/README.build b/README.build index 2787bde..64d98cf 100644 --- a/README.build +++ b/README.build @@ -165,15 +165,6 @@ for later protocol versions... unlikely - AWAITING_TIMEOUT default 5: after this many seconds without a response, the server will hang up on the client - - CIPHERS_LIST_STRING default "DEFAULT": SSL Cipher selection. It's advisable -to tweak the ciphers allowed to be negotiated on secure connections for -performance reasons, otherwise a slow algorithm may be selected by the two -endpoints and the server could expend most of its time just encrypting and -decrypting data, severely limiting the amount of messages it will be able to -handle per second. For example:: - - "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL" - - SYSTEM_RANDOM_FILEPATH default "/dev/urandom": if your random device differs you can set it here diff --git a/README.coding b/README.coding index bb093fb..0231d03 100644 --- a/README.coding +++ b/README.coding @@ -209,3 +209,18 @@ Note that BSDs don't support keepalive time / probes / inteveral per-socket like Linux does. On those systems you can enable keepalive by a nonzero value in ka_time, but the systemwide kernel settings for the time / probes/ interval are used, regardless of what nonzero value is in ka_time. + +Optimizing SSL connections +-------------------------- + +There's a member ssl_cipher_list in the lws_context_creation_info struct +which allows the user code to restrict the possible cipher selection at +context-creation time. + +You might want to look into that to stop the ssl peers selecting a ciher which +is too computationally expensive. To use it, point it to a string like + +"RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL" + +if left NULL, then the "DEFAULT" set of ciphers are all possible to select. + diff --git a/changelog b/changelog index 9b76f08..97c0f64 100644 --- a/changelog +++ b/changelog @@ -10,6 +10,10 @@ User api additions and get a LWS_CALLBACK_HTTP_WRITEABLE callback, the same way you can regulate writes with a websocket protocol connection. + - A new member in the context creation parameter struct "ssl_cipher_list" is + added, replacing CIPHERS_LIST_STRING. NULL means use the ssl library + default list of ciphers. + User api changes ---------------- @@ -27,6 +31,8 @@ User api removal were using it to get user_space, you need to adapt your code to only use user_space inside the user callback. + - CIPHERS_LIST_STRING is removed + v1.21-chrome26-firefox18 ======================== diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index 337582d..7414fe7 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -1657,7 +1657,8 @@ libwebsocket_create_context(struct lws_context_creation_info *info) #endif lwsl_info(" SPEC_LATEST_SUPPORTED: %u\n", SPEC_LATEST_SUPPORTED); lwsl_info(" AWAITING_TIMEOUT: %u\n", AWAITING_TIMEOUT); - lwsl_info(" CIPHERS_LIST_STRING: '%s'\n", CIPHERS_LIST_STRING); + if (info->ssl_cipher_list) + lwsl_info(" SSL ciphers: '%s'\n", info->ssl_cipher_list); lwsl_info(" SYSTEM_RANDOM_FILEPATH: '%s'\n", SYSTEM_RANDOM_FILEPATH); lwsl_info(" LWS_MAX_ZLIB_CONN_BUFFER: %u\n", LWS_MAX_ZLIB_CONN_BUFFER); @@ -1877,7 +1878,9 @@ libwebsocket_create_context(struct lws_context_creation_info *info) SSL_CTX_set_options(context->ssl_ctx, SSL_OP_NO_COMPRESSION); #endif SSL_CTX_set_options(context->ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); - SSL_CTX_set_cipher_list(context->ssl_ctx, CIPHERS_LIST_STRING); + if (info->ssl_cipher_list) + SSL_CTX_set_cipher_list(context->ssl_ctx, + info->ssl_cipher_list); #ifndef LWS_NO_CLIENT @@ -1908,8 +1911,9 @@ libwebsocket_create_context(struct lws_context_creation_info *info) #endif SSL_CTX_set_options(context->ssl_client_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); - SSL_CTX_set_cipher_list(context->ssl_client_ctx, - CIPHERS_LIST_STRING); + if (info->ssl_cipher_list) + SSL_CTX_set_cipher_list(context->ssl_client_ctx, + info->ssl_cipher_list); /* openssl init for cert verification (for client sockets) */ if (!info->ssl_ca_filepath) { diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index b7f43fc..28e649c 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -759,6 +759,9 @@ struct libwebsocket_extension { * @ssl_private_key_filepath: filepath to private key if wanting SSL mode, * else ignored * @ssl_ca_filepath: CA certificate filepath or NULL + * @ssl_cipher_list: List of valid ciphers to use (eg, + * "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL" + * or you can leave it as NULL to get "DEFAULT" * @gid: group id to change to after setting listen socket, or -1. * @uid: user id to change to after setting listen socket, or -1. * @options: 0, or LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK @@ -781,6 +784,7 @@ struct lws_context_creation_info { const char *ssl_cert_filepath; const char *ssl_private_key_filepath; const char *ssl_ca_filepath; + const char *ssl_cipher_list; int gid; int uid; unsigned int options; diff --git a/libwebsockets-api-doc.html b/libwebsockets-api-doc.html index 42a37b0..a38145c 100644 --- a/libwebsockets-api-doc.html +++ b/libwebsockets-api-doc.html @@ -637,7 +637,7 @@ and servers get LWS_CALLBACK_SERVER_WRITEABLE. called when a client connects to the server at network level; the connection is accepted but then passed to this callback to decide whether to hang up immediately -or not, based on the client IP. user contains the connection +or not, based on the client IP. in contains the connection socket's descriptor. Return non-zero to terminate the connection before sending or receiving anything. Because this happens immediately after the network connection @@ -969,6 +969,7 @@ all sessions, etc, if it wants     const char * ssl_cert_filepath;
    const char * ssl_private_key_filepath;
    const char * ssl_ca_filepath;
+    const char * ssl_cipher_list;
    int gid;
    int uid;
    unsigned int options;
@@ -1004,6 +1005,10 @@ server cert from, otherwise NULL for unencrypted else ignored
ssl_ca_filepath
CA certificate filepath or NULL +
ssl_cipher_list +
List of valid ciphers to use (eg, +"RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL" +or you can leave it as NULL to get "DEFAULT"
gid
group id to change to after setting listen socket, or -1.
uid -- 2.7.4