Add testapps support for client certs and CRLs
AG: plumb into cmake to avoid travis mac blowing up
This commit is contained in:
parent
44182452c8
commit
ddd9bfaaac
6 changed files with 156 additions and 12 deletions
|
@ -384,6 +384,7 @@ SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
|
|||
SET(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${LWS_INSTALL_LIB_DIR}${LIB_SUFFIX}")
|
||||
|
||||
include(CheckFunctionExists)
|
||||
include(CheckSymbolExists)
|
||||
include(CheckIncludeFile)
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckLibraryExists)
|
||||
|
@ -463,15 +464,6 @@ if (NOT LWS_HAVE_REALLOC)
|
|||
set(realloc rpl_realloc)
|
||||
endif()
|
||||
|
||||
# Generate the lws_config.h that includes all the public compilation settings.
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/lws_config.h.in"
|
||||
"${PROJECT_BINARY_DIR}/lws_config.h")
|
||||
|
||||
# Generate the lws_config.h that includes all the private compilation settings.
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/lws_config_private.h.in"
|
||||
"${PROJECT_BINARY_DIR}/lws_config_private.h")
|
||||
|
||||
if (MSVC)
|
||||
# Turn off stupid microsoft security warnings.
|
||||
|
@ -864,6 +856,22 @@ foreach (lib ${LWS_LIBRARIES})
|
|||
target_link_libraries(${lib} ${LIB_LIST})
|
||||
endforeach()
|
||||
|
||||
set (temp ${CMAKE_REQUIRED_LIBRARIES})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${LIB_LIST})
|
||||
CHECK_FUNCTION_EXISTS(SSL_CTX_set1_param LWS_HAVE_SSL_CTX_set1_param)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${temp})
|
||||
# Generate the lws_config.h that includes all the public compilation settings.
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/lws_config.h.in"
|
||||
"${PROJECT_BINARY_DIR}/lws_config.h")
|
||||
|
||||
# Generate the lws_config.h that includes all the private compilation settings.
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/lws_config_private.h.in"
|
||||
"${PROJECT_BINARY_DIR}/lws_config_private.h")
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Test applications
|
||||
#
|
||||
|
@ -1450,6 +1458,7 @@ message(" LWS_SSL_SERVER_WITH_ECDH_CERT = ${LWS_SSL_SERVER_WITH_ECDH_CERT}")
|
|||
message(" LWS_MAX_SMP = ${LWS_MAX_SMP}")
|
||||
message(" LWS_WITH_CGI = ${LWS_WITH_CGI}")
|
||||
message(" LWS_HAVE_OPENSSL_ECDH_H = ${LWS_HAVE_OPENSSL_ECDH_H}")
|
||||
message(" LWS_HAVE_SSL_CTX_set1_param = ${LWS_HAVE_SSL_CTX_set1_param}")
|
||||
message(" LWS_WITH_HTTP_PROXY = ${LWS_WITH_HTTP_PROXY}")
|
||||
message(" LIBHUBBUB_LIBRARIES = ${LIBHUBBUB_LIBRARIES}")
|
||||
message(" PLUGINS = ${PLUGINS_LIST}")
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
|
||||
/* SSL server using ECDH certificate */
|
||||
#cmakedefine LWS_SSL_SERVER_WITH_ECDH_CERT
|
||||
#cmakedefine LWS_HAVE_SSL_CTX_set1_param
|
||||
|
||||
/* CGI apis */
|
||||
#cmakedefine LWS_WITH_CGI
|
||||
|
|
|
@ -35,10 +35,17 @@
|
|||
|
||||
#include "../lib/libwebsockets.h"
|
||||
|
||||
#ifdef LWS_OPENSSL_SUPPORT
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
|
||||
static int deny_deflate, deny_mux, longlived, mirror_lifetime;
|
||||
static struct lws *wsi_dumb, *wsi_mirror;
|
||||
static volatile int force_exit;
|
||||
static unsigned int opts;
|
||||
#if defined(LWS_OPENSSL_SUPPORT) && defined(LWS_HAVE_SSL_CTX_set1_param)
|
||||
static char crl_path[1024] = "";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This demo shows how to connect multiple websockets simultaneously to a
|
||||
|
@ -126,6 +133,27 @@ callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
force_exit = 1;
|
||||
break;
|
||||
|
||||
#if defined(LWS_OPENSSL_SUPPORT) && defined(LWS_HAVE_SSL_CTX_set1_param)
|
||||
case LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS:
|
||||
if (crl_path[0]) {
|
||||
/* Enable CRL checking of the server certificate */
|
||||
X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new();
|
||||
X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
|
||||
SSL_CTX_set1_param((SSL_CTX*)user, param);
|
||||
X509_STORE *store = SSL_CTX_get_cert_store((SSL_CTX*)user);
|
||||
X509_LOOKUP *lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
|
||||
int n = X509_load_cert_crl_file(lookup, crl_path, X509_FILETYPE_PEM);
|
||||
X509_VERIFY_PARAM_free(param);
|
||||
if (n != 1) {
|
||||
char errbuf[256];
|
||||
n = ERR_get_error();
|
||||
lwsl_err("LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS: SSL error: %s (%d)\n", ERR_error_string(n, errbuf), n);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -262,6 +290,12 @@ static struct option options[] = {
|
|||
{ "undeflated", no_argument, NULL, 'u' },
|
||||
{ "nomux", no_argument, NULL, 'n' },
|
||||
{ "longlived", no_argument, NULL, 'l' },
|
||||
{ "ssl-cert", required_argument, NULL, 'C' },
|
||||
{ "ssl-key", required_argument, NULL, 'K' },
|
||||
{ "ssl-ca", required_argument, NULL, 'A' },
|
||||
#if defined(LWS_OPENSSL_SUPPORT) && defined(LWS_HAVE_SSL_CTX_set1_param)
|
||||
{ "ssl-crl", required_argument, NULL, 'R' },
|
||||
#endif
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
@ -287,6 +321,9 @@ int main(int argc, char **argv)
|
|||
struct lws_context *context;
|
||||
const char *prot, *p;
|
||||
char path[300];
|
||||
char cert_path[1024] = "";
|
||||
char key_path[1024] = "";
|
||||
char ca_path[1024] = "";
|
||||
|
||||
memset(&info, 0, sizeof info);
|
||||
|
||||
|
@ -297,7 +334,7 @@ int main(int argc, char **argv)
|
|||
goto usage;
|
||||
|
||||
while (n >= 0) {
|
||||
n = getopt_long(argc, argv, "nuv:hsp:d:l", options, NULL);
|
||||
n = getopt_long(argc, argv, "nuv:hsp:d:lC:K:A:", options, NULL);
|
||||
if (n < 0)
|
||||
continue;
|
||||
switch (n) {
|
||||
|
@ -322,6 +359,20 @@ int main(int argc, char **argv)
|
|||
case 'n':
|
||||
deny_mux = 1;
|
||||
break;
|
||||
case 'C':
|
||||
strncpy(cert_path, optarg, sizeof cert_path);
|
||||
break;
|
||||
case 'K':
|
||||
strncpy(key_path, optarg, sizeof key_path);
|
||||
break;
|
||||
case 'A':
|
||||
strncpy(ca_path, optarg, sizeof ca_path);
|
||||
break;
|
||||
#if defined(LWS_OPENSSL_SUPPORT) && defined(LWS_HAVE_SSL_CTX_set1_param)
|
||||
case 'R':
|
||||
strncpy(crl_path, optarg, sizeof crl_path);
|
||||
break;
|
||||
#endif
|
||||
case 'h':
|
||||
goto usage;
|
||||
}
|
||||
|
@ -362,9 +413,30 @@ int main(int argc, char **argv)
|
|||
info.gid = -1;
|
||||
info.uid = -1;
|
||||
|
||||
if (use_ssl)
|
||||
if (use_ssl) {
|
||||
info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
|
||||
|
||||
/*
|
||||
* If the server wants us to present a valid SSL client certificate
|
||||
* then we can set it up here.
|
||||
*/
|
||||
|
||||
if (cert_path[0])
|
||||
info.ssl_cert_filepath = cert_path;
|
||||
if (key_path[0])
|
||||
info.ssl_private_key_filepath = key_path;
|
||||
|
||||
/*
|
||||
* A CA cert and CRL can be used to validate the cert send by the server
|
||||
*/
|
||||
if (ca_path[0])
|
||||
info.ssl_ca_filepath = ca_path;
|
||||
#if defined(LWS_OPENSSL_SUPPORT) && defined(LWS_HAVE_SSL_CTX_set1_param)
|
||||
else if (crl_path[0])
|
||||
lwsl_notice("WARNING, providing a CRL requires a CA cert!\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
context = lws_create_context(&info);
|
||||
if (context == NULL) {
|
||||
fprintf(stderr, "Creating libwebsocket context failed\n");
|
||||
|
|
|
@ -34,6 +34,15 @@
|
|||
* using this protocol, including the sender
|
||||
*/
|
||||
|
||||
#ifdef LWS_OPENSSL_SUPPORT
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
|
||||
#if defined(LWS_OPENSSL_SUPPORT) && defined(LWS_HAVE_SSL_CTX_set1_param)
|
||||
/* location of the certificate revocation list */
|
||||
char crl_path[1024] = "";
|
||||
#endif
|
||||
|
||||
extern int debug_level;
|
||||
|
||||
enum demo_protocols {
|
||||
|
@ -620,6 +629,39 @@ bail:
|
|||
|
||||
break;
|
||||
|
||||
#if defined(LWS_OPENSSL_SUPPORT)
|
||||
case LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION:
|
||||
/* Verify the client certificate */
|
||||
if (!len || (SSL_get_verify_result((SSL*)in) != X509_V_OK)) {
|
||||
int err = X509_STORE_CTX_get_error((X509_STORE_CTX*)user);
|
||||
int depth = X509_STORE_CTX_get_error_depth((X509_STORE_CTX*)user);
|
||||
const char* msg = X509_verify_cert_error_string(err);
|
||||
lwsl_err("LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION: SSL error: %s (%d), depth: %d\n", msg, err, depth);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
#if defined(LWS_HAVE_SSL_CTX_set1_param)
|
||||
case LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS:
|
||||
if (crl_path[0]) {
|
||||
/* Enable CRL checking */
|
||||
X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new();
|
||||
X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
|
||||
SSL_CTX_set1_param((SSL_CTX*)user, param);
|
||||
X509_STORE *store = SSL_CTX_get_cert_store((SSL_CTX*)user);
|
||||
X509_LOOKUP *lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
|
||||
n = X509_load_cert_crl_file(lookup, crl_path, X509_FILETYPE_PEM);
|
||||
X509_VERIFY_PARAM_free(param);
|
||||
if (n != 1) {
|
||||
char errbuf[256];
|
||||
n = ERR_get_error();
|
||||
lwsl_err("LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS: SSL error: %s (%d)\n", ERR_error_string(n, errbuf), n);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -165,6 +165,12 @@ static struct option options[] = {
|
|||
{ "ssl-cert", required_argument, NULL, 'C' },
|
||||
{ "ssl-key", required_argument, NULL, 'K' },
|
||||
{ "ssl-ca", required_argument, NULL, 'A' },
|
||||
#if defined(LWS_OPENSSL_SUPPORT)
|
||||
{ "ssl-verify-client", no_argument, NULL, 'v' },
|
||||
#if defined(LWS_HAVE_SSL_CTX_set1_param)
|
||||
{ "ssl-crl", required_argument, NULL, 'R' },
|
||||
#endif
|
||||
#endif
|
||||
{ "libev", no_argument, NULL, 'e' },
|
||||
#ifndef LWS_NO_DAEMONIZE
|
||||
{ "daemonize", no_argument, NULL, 'D' },
|
||||
|
@ -201,7 +207,7 @@ int main(int argc, char **argv)
|
|||
info.port = 7681;
|
||||
|
||||
while (n >= 0) {
|
||||
n = getopt_long(argc, argv, "eci:hsap:d:Dr:C:K:A:u:g:", options, NULL);
|
||||
n = getopt_long(argc, argv, "eci:hsap:d:Dr:C:K:A:R:vu:g:", options, NULL);
|
||||
if (n < 0)
|
||||
continue;
|
||||
switch (n) {
|
||||
|
@ -258,6 +264,17 @@ int main(int argc, char **argv)
|
|||
case 'A':
|
||||
strncpy(ca_path, optarg, sizeof ca_path);
|
||||
break;
|
||||
#if defined(LWS_OPENSSL_SUPPORT)
|
||||
case 'v':
|
||||
use_ssl = 1;
|
||||
opts |= LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT;
|
||||
break;
|
||||
#if defined(LWS_HAVE_SSL_CTX_set1_param)
|
||||
case 'R':
|
||||
strncpy(crl_path, optarg, sizeof crl_path);
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
case 'h':
|
||||
fprintf(stderr, "Usage: test-server "
|
||||
"[--port=<p>] [--ssl] "
|
||||
|
|
|
@ -57,6 +57,9 @@ extern int count_pollfds;
|
|||
extern volatile int force_exit;
|
||||
extern struct lws_context *context;
|
||||
extern char *resource_path;
|
||||
#if defined(LWS_OPENSSL_SUPPORT) && defined(LWS_HAVE_SSL_CTX_set1_param)
|
||||
extern char crl_path[1024];
|
||||
#endif
|
||||
|
||||
extern void test_server_lock(int care);
|
||||
extern void test_server_unlock(int care);
|
||||
|
|
Loading…
Add table
Reference in a new issue