(tls) Experimental TLS server support with mbedtls (windows) + process cert tlsoption (client + server)

This commit is contained in:
Benjamin Sergeant 2019-12-18 11:51:02 -08:00
parent 237ede56aa
commit 4e1888ac19
5 changed files with 65 additions and 9 deletions

View File

@ -1,6 +1,10 @@
# Changelog # Changelog
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## [7.5.7] - 2019-12-18
(tls) Experimental TLS server support with mbedtls (windows) + process cert tlsoption (client + server)
## [7.5.6] - 2019-12-18 ## [7.5.6] - 2019-12-18
(tls servers) Make it clear that apple ssl and mbedtls backends do not support SSL in server mode (tls servers) Make it clear that apple ssl and mbedtls backends do not support SSL in server mode

View File

@ -38,9 +38,10 @@ namespace ix
mbedtls_ctr_drbg_init(&_ctr_drbg); mbedtls_ctr_drbg_init(&_ctr_drbg);
mbedtls_entropy_init(&_entropy); mbedtls_entropy_init(&_entropy);
mbedtls_x509_crt_init(&_cacert); mbedtls_x509_crt_init(&_cacert);
mbedtls_x509_crt_init(&_cert);
} }
bool SocketMbedTLS::init(const std::string& host, std::string& errMsg) bool SocketMbedTLS::init(const std::string& host, bool isClient, std::string& errMsg)
{ {
initMBedTLS(); initMBedTLS();
std::lock_guard<std::mutex> lock(_mutex); std::lock_guard<std::mutex> lock(_mutex);
@ -58,7 +59,8 @@ namespace ix
} }
if (mbedtls_ssl_config_defaults(&_conf, if (mbedtls_ssl_config_defaults(&_conf,
MBEDTLS_SSL_IS_CLIENT, (isClient) ? MBEDTLS_SSL_IS_CLIENT
: MBEDTLS_SSL_IS_SERVER,
MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT) != 0) MBEDTLS_SSL_PRESET_DEFAULT) != 0)
{ {
@ -68,6 +70,15 @@ namespace ix
mbedtls_ssl_conf_rng(&_conf, mbedtls_ctr_drbg_random, &_ctr_drbg); mbedtls_ssl_conf_rng(&_conf, mbedtls_ctr_drbg_random, &_ctr_drbg);
if (_tlsOptions.hasCertAndKey())
{
if (mbedtls_x509_crt_parse_file(&_cacert, _tlsOptions.certFile.c_str()) < 0)
{
errMsg = "Cannot parse cert file '" + _tlsOptions.certFile + "'";
return false;
}
}
if (_tlsOptions.isPeerVerifyDisabled()) if (_tlsOptions.isPeerVerifyDisabled())
{ {
mbedtls_ssl_conf_authmode(&_conf, MBEDTLS_SSL_VERIFY_NONE); mbedtls_ssl_conf_authmode(&_conf, MBEDTLS_SSL_VERIFY_NONE);
@ -96,7 +107,7 @@ namespace ix
return false; return false;
} }
if (mbedtls_ssl_set_hostname(&_ssl, host.c_str()) != 0) if (!host.empty() && mbedtls_ssl_set_hostname(&_ssl, host.c_str()) != 0)
{ {
errMsg = "SNI setup failed"; errMsg = "SNI setup failed";
return false; return false;
@ -107,10 +118,48 @@ namespace ix
bool SocketMbedTLS::accept(std::string& errMsg) bool SocketMbedTLS::accept(std::string& errMsg)
{ {
errMsg = "TLS not supported yet in server mode with mbedtls backend"; bool isClient = false;
bool initialized = init(std::string(), isClient, errMsg);
if (!initialized)
{
close();
return false; return false;
} }
mbedtls_ssl_set_bio(&_ssl, &_sockfd, mbedtls_net_send, mbedtls_net_recv, NULL);
int res;
do
{
std::lock_guard<std::mutex> lock(_mutex);
res = mbedtls_ssl_handshake(&_ssl);
} while (res == MBEDTLS_ERR_SSL_WANT_READ || res == MBEDTLS_ERR_SSL_WANT_WRITE);
if (res != 0)
{
char buf[256];
mbedtls_strerror(res, buf, sizeof(buf));
errMsg = "error in handshake : ";
errMsg += buf;
if (res == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED)
{
char verifyBuf[512];
uint32_t flags = mbedtls_ssl_get_verify_result(&_ssl);
mbedtls_x509_crt_verify_info(verifyBuf, sizeof(verifyBuf), " ! ", flags);
errMsg += " : ";
errMsg += verifyBuf;
}
close();
return false;
}
return true;
}
bool SocketMbedTLS::connect(const std::string& host, bool SocketMbedTLS::connect(const std::string& host,
int port, int port,
std::string& errMsg, std::string& errMsg,
@ -122,7 +171,8 @@ namespace ix
if (_sockfd == -1) return false; if (_sockfd == -1) return false;
} }
bool initialized = init(host, errMsg); bool isClient = true;
bool initialized = init(host, isClient, errMsg);
if (!initialized) if (!initialized)
{ {
close(); close();
@ -162,6 +212,7 @@ namespace ix
mbedtls_ctr_drbg_free(&_ctr_drbg); mbedtls_ctr_drbg_free(&_ctr_drbg);
mbedtls_entropy_free(&_entropy); mbedtls_entropy_free(&_entropy);
mbedtls_x509_crt_free(&_cacert); mbedtls_x509_crt_free(&_cacert);
mbedtls_x509_crt_free(&_cert);
Socket::close(); Socket::close();
} }

View File

@ -44,11 +44,12 @@ namespace ix
mbedtls_entropy_context _entropy; mbedtls_entropy_context _entropy;
mbedtls_ctr_drbg_context _ctr_drbg; mbedtls_ctr_drbg_context _ctr_drbg;
mbedtls_x509_crt _cacert; mbedtls_x509_crt _cacert;
mbedtls_x509_crt _cert;
std::mutex _mutex; std::mutex _mutex;
SocketTLSOptions _tlsOptions; SocketTLSOptions _tlsOptions;
bool init(const std::string& host, std::string& errMsg); bool init(const std::string& host, bool isClient, std::string& errMsg);
void initMBedTLS(); void initMBedTLS();
}; };

View File

@ -6,4 +6,4 @@
#pragma once #pragma once
#define IX_WEBSOCKET_VERSION "7.5.6" #define IX_WEBSOCKET_VERSION "7.5.7"

View File

@ -53,7 +53,7 @@ done
# Start a receiver # Start a receiver
mkdir -p /tmp/ws_test/receive mkdir -p /tmp/ws_test/receive
cd /tmp/ws_test/receive cd /tmp/ws_test/receive
ws receive "${protocol}127.0.0.1:8090" ${delay} --pidfile /tmp/ws_test/pidfile.receive ${server_tls} & ws receive "${protocol}127.0.0.1:8090" ${delay} --pidfile /tmp/ws_test/pidfile.receive ${client_tls} &
mkdir -p /tmp/ws_test/send mkdir -p /tmp/ws_test/send
cd /tmp/ws_test/send cd /tmp/ws_test/send