diff --git a/ixwebsocket/IXHttpClient.cpp b/ixwebsocket/IXHttpClient.cpp index 58bdd166..2695f673 100644 --- a/ixwebsocket/IXHttpClient.cpp +++ b/ixwebsocket/IXHttpClient.cpp @@ -43,6 +43,11 @@ namespace ix _thread.join(); } + void HttpClient::setTLSOptions(const SocketTLSOptions& tlsOptions) + { + _tlsOptions = tlsOptions; + } + HttpRequestArgsPtr HttpClient::createRequest(const std::string& url, const std::string& verb) { auto request = std::make_shared(); @@ -142,8 +147,7 @@ namespace ix bool tls = protocol == "https"; std::string errorMsg; - SocketTLSOptions tlsOptions; - _socket = createSocket(tls, errorMsg, tlsOptions); + _socket = createSocket(tls, errorMsg, _tlsOptions); if (!_socket) { diff --git a/ixwebsocket/IXHttpClient.h b/ixwebsocket/IXHttpClient.h index b1b711bf..efbbac5a 100644 --- a/ixwebsocket/IXHttpClient.h +++ b/ixwebsocket/IXHttpClient.h @@ -9,6 +9,7 @@ #include "IXHttp.h" #include "IXSocket.h" #include "IXWebSocketHttpHeaders.h" +#include "IXSocketTLSOptions.h" #include #include #include @@ -58,6 +59,9 @@ namespace ix bool performRequest(HttpRequestArgsPtr request, const OnResponseCallback& onResponseCallback); + // TLS + void setTLSOptions(const SocketTLSOptions& tlsOptions); + std::string serializeHttpParameters(const HttpParameters& httpParameters); std::string urlEncode(const std::string& value); @@ -86,5 +90,7 @@ namespace ix std::shared_ptr _socket; std::mutex _mutex; // to protect accessing the _socket (only one socket per client) + + SocketTLSOptions _tlsOptions; }; } // namespace ix diff --git a/ixwebsocket/IXSocketMbedTLS.cpp b/ixwebsocket/IXSocketMbedTLS.cpp index 25f23797..6b1d95e1 100644 --- a/ixwebsocket/IXSocketMbedTLS.cpp +++ b/ixwebsocket/IXSocketMbedTLS.cpp @@ -17,8 +17,9 @@ namespace ix { - SocketMbedTLS::SocketMbedTLS(const SocketTLSOptions& tlsOptions) - : _tlsOptions(tlsOptions) + SocketMbedTLS::SocketMbedTLS(const SocketTLSOptions& tlsOptions, int fd) + : Socket(fd) + , _tlsOptions(tlsOptions) { initMBedTLS(); } @@ -36,6 +37,7 @@ namespace ix mbedtls_ssl_config_init(&_conf); mbedtls_ctr_drbg_init(&_ctr_drbg); mbedtls_entropy_init(&_entropy); + mbedtls_x509_crt_init(&_cacert); } bool SocketMbedTLS::init(const std::string& host, std::string& errMsg) @@ -66,8 +68,27 @@ namespace ix mbedtls_ssl_conf_rng(&_conf, mbedtls_ctr_drbg_random, &_ctr_drbg); - // FIXME: cert verification is disabled - mbedtls_ssl_conf_authmode(&_conf, MBEDTLS_SSL_VERIFY_NONE); + if (_tlsOptions.isPeerVerifyDisabled()) + { + mbedtls_ssl_conf_authmode(&_conf, MBEDTLS_SSL_VERIFY_NONE); + } + else + { + mbedtls_ssl_conf_ca_chain(&_conf, &_cacert, NULL); + + // FIXME: should we call mbedtls_ssl_conf_verify ? + + if (_tlsOptions.isUsingSystemDefaults()) + { + ; // FIXME + } + else if (mbedtls_x509_crt_parse_file(&_cacert, _tlsOptions.caFile.c_str()) < 0) + { + errMsg = "Cannot parse CA file '" + _tlsOptions.caFile + "'"; + return false; + } + mbedtls_ssl_conf_authmode(&_conf, MBEDTLS_SSL_VERIFY_REQUIRED); + } if (mbedtls_ssl_setup(&_ssl, &_conf) != 0) { @@ -134,6 +155,7 @@ namespace ix mbedtls_ssl_config_free(&_conf); mbedtls_ctr_drbg_free(&_ctr_drbg); mbedtls_entropy_free(&_entropy); + mbedtls_x509_crt_free(&_cacert); Socket::close(); } diff --git a/ixwebsocket/IXSocketMbedTLS.h b/ixwebsocket/IXSocketMbedTLS.h index fc318806..68fb36b4 100644 --- a/ixwebsocket/IXSocketMbedTLS.h +++ b/ixwebsocket/IXSocketMbedTLS.h @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include namespace ix @@ -21,7 +23,7 @@ namespace ix class SocketMbedTLS final : public Socket { public: - SocketMbedTLS(const SocketTLSOptions& tlsOptions); + SocketMbedTLS(const SocketTLSOptions& tlsOptions, int fd = -1); ~SocketMbedTLS(); virtual bool connect(const std::string& host, @@ -39,6 +41,7 @@ namespace ix mbedtls_ssl_config _conf; mbedtls_entropy_context _entropy; mbedtls_ctr_drbg_context _ctr_drbg; + mbedtls_x509_crt _cacert; std::mutex _mutex; SocketTLSOptions _tlsOptions; diff --git a/ixwebsocket/IXSocketOpenSSL.cpp b/ixwebsocket/IXSocketOpenSSL.cpp index 9d91d2e0..db55081c 100644 --- a/ixwebsocket/IXSocketOpenSSL.cpp +++ b/ixwebsocket/IXSocketOpenSSL.cpp @@ -280,6 +280,7 @@ namespace ix auto sslErr = ERR_get_error(); errMsg = "OpenSSL failed - SSL_CTX_default_verify_paths loading failed: "; errMsg += ERR_error_string(sslErr, nullptr); + return false; } } else if (SSL_CTX_load_verify_locations( @@ -289,6 +290,7 @@ namespace ix errMsg = "OpenSSL failed - SSL_CTX_load_verify_locations(\"" + _tlsOptions.caFile + "\") failed: "; errMsg += ERR_error_string(sslErr, nullptr); + return false; } SSL_CTX_set_verify(_ssl_context, diff --git a/ixwebsocket/IXSocketTLSOptions.cpp b/ixwebsocket/IXSocketTLSOptions.cpp index 671a3e4f..50e5e600 100644 --- a/ixwebsocket/IXSocketTLSOptions.cpp +++ b/ixwebsocket/IXSocketTLSOptions.cpp @@ -17,10 +17,6 @@ namespace ix bool SocketTLSOptions::isValid() const { -#ifndef IXWEBSOCKET_USE_TLS - _errMsg = "To use TLS features the library must be compiled with USE_TLS"; - return false; -#endif if (!_validated) { if (!certFile.empty() && !std::ifstream(certFile)) diff --git a/ixwebsocket/IXWebSocket.h b/ixwebsocket/IXWebSocket.h index 41dadaaf..e647a966 100644 --- a/ixwebsocket/IXWebSocket.h +++ b/ixwebsocket/IXWebSocket.h @@ -10,9 +10,7 @@ #pragma once #include "IXProgressCallback.h" -#ifdef IXWEBSOCKET_USE_TLS #include "IXSocketTLSOptions.h" -#endif #include "IXWebSocketCloseConstants.h" #include "IXWebSocketErrorInfo.h" #include "IXWebSocketHttpHeaders.h" diff --git a/makefile b/makefile index 53d85681..9cbf2418 100644 --- a/makefile +++ b/makefile @@ -68,7 +68,11 @@ test: (cd test ; python2.7 run.py -r) test_openssl: - mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_OPEN_SSL=1 -DUSE_WS=1 -DUSE_TEST=1 .. ; make -j 4) + mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_OPEN_SSL=1 -DUSE_TEST=1 .. ; make -j 4) + (cd test ; python2.7 run.py -r) + +test_mbedtls: + mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_MBED_TLS=1 -DUSE_TEST=1 .. ; make -j 4) (cd test ; python2.7 run.py -r) ws_test: ws diff --git a/ws/ws_http_client.cpp b/ws/ws_http_client.cpp index 409c9fb1..3f1403ed 100644 --- a/ws/ws_http_client.cpp +++ b/ws/ws_http_client.cpp @@ -98,6 +98,8 @@ namespace ix const ix::SocketTLSOptions& tlsOptions) { HttpClient httpClient; + httpClient.setTLSOptions(tlsOptions); + auto args = httpClient.createRequest(); args->extraHeaders = parseHeaders(headersData); args->connectTimeout = connectTimeout;