diff --git a/.gitmodules b/.gitmodules index 3bebe8ac..eeeaa0d6 100755 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,3 @@ [submodule "trantor"] path = trantor - url = https://github.com/an-tao/trantor.git - + url = https://github.com/an-tao/trantor.git \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 44063629..b884f646 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -505,20 +505,6 @@ endif (BUILD_TESTING) find_package(ZLIB REQUIRED) target_link_libraries(${PROJECT_NAME} PRIVATE ZLIB::ZLIB) -find_package(OpenSSL) -if (OpenSSL_FOUND) - target_link_libraries(${PROJECT_NAME} PRIVATE OpenSSL::SSL OpenSSL::Crypto) -else (OpenSSL_FOUND) - set(DROGON_SOURCES - ${DROGON_SOURCES} - lib/src/ssl_funcs/Md5.cc - lib/src/ssl_funcs/Sha1.cc) - set(private_headers - ${private_headers} - lib/src/ssl_funcs/Md5.h - lib/src/ssl_funcs/Sha1.h) -endif (OpenSSL_FOUND) - execute_process(COMMAND "git" rev-parse HEAD WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" OUTPUT_VARIABLE GIT_SHA1 diff --git a/config.example.json b/config.example.json index 8c98b3da..38d43a6e 100644 --- a/config.example.json +++ b/config.example.json @@ -5,8 +5,8 @@ //ssl:The global SSL settings. "key" and "cert" are the path to the SSL key and certificate. While // "conf" is an array of 1 or 2-element tuples that supplies file style options for `SSL_CONF_cmd`. "ssl": { - "cert": "../../trantor/trantor/tests/server.pem", - "key": "../../trantor/trantor/tests/server.pem", + "cert": "../../trantor/trantor/tests/server.crt", + "key": "../../trantor/trantor/tests/server.key", "conf": [ //["Options", "-SessionTicket"], //["Options", "Compression"] diff --git a/drogon_ctl/templates/config.csp b/drogon_ctl/templates/config.csp index b5429950..1e520c8d 100644 --- a/drogon_ctl/templates/config.csp +++ b/drogon_ctl/templates/config.csp @@ -5,8 +5,8 @@ //ssl:The global SSL settings. "key" and "cert" are the path to the SSL key and certificate. While // "conf" is an array of 1 or 2-element tuples that supplies file style options for `SSL_CONF_cmd`. "ssl": { - "cert": "../../trantor/trantor/tests/server.pem", - "key": "../../trantor/trantor/tests/server.pem", + "cert": "../../trantor/trantor/tests/server.crt", + "key": "../../trantor/trantor/tests/server.key", "conf": [ //["Options", "-SessionTicket"], //["Options", "Compression"] diff --git a/drogon_ctl/version.cc b/drogon_ctl/version.cc index 0deb27cb..bdba5c90 100644 --- a/drogon_ctl/version.cc +++ b/drogon_ctl/version.cc @@ -15,7 +15,9 @@ #include "version.h" #include #include +#include #include +#include #include using namespace drogon_ctl; @@ -30,6 +32,8 @@ static const char banner[] = void version::handleCommand(std::vector ¶meters) { + const auto tlsBackend = trantor::utils::tlsBackend(); + const bool tlsSupported = drogon::utils::supportsTls(); std::cout << banner << std::endl; std::cout << "A utility for drogon" << std::endl; std::cout << "Version: " << DROGON_VERSION << std::endl; @@ -43,11 +47,7 @@ void version::handleCommand(std::vector ¶meters) << (LIBPQ_SUPPORTS_BATCH_MODE ? "yes)\n" : "no)\n") << " mariadb: " << (USE_MYSQL ? "yes\n" : "no\n") << " sqlite3: " << (USE_SQLITE3 ? "yes\n" : "no\n"); -#ifdef OpenSSL_FOUND - std::cout << " openssl: yes\n"; -#else - std::cout << " openssl: no\n"; -#endif + std::cout << " ssl/tls backend: " << tlsBackend << "\n"; #ifdef USE_BROTLI std::cout << " brotli: yes\n"; #else diff --git a/examples/simple_reverse_proxy/config.json b/examples/simple_reverse_proxy/config.json index dbf7aeda..6aa7a1ff 100644 --- a/examples/simple_reverse_proxy/config.json +++ b/examples/simple_reverse_proxy/config.json @@ -4,8 +4,8 @@ /* //ssl: The global ssl files setting "ssl": { - "cert": "../../trantor/trantor/tests/server.pem", - "key": "../../trantor/trantor/tests/server.pem" + "cert": "../../trantor/trantor/tests/server.crt", + "key": "../../trantor/trantor/tests/server.key" },*/ "listeners": [{ //address: Ip address,0.0.0.0 by default diff --git a/lib/inc/drogon/HttpRequest.h b/lib/inc/drogon/HttpRequest.h index 8a85e5e5..80dccb38 100644 --- a/lib/inc/drogon/HttpRequest.h +++ b/lib/inc/drogon/HttpRequest.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -341,6 +342,13 @@ class DROGON_EXPORT HttpRequest return creationDate(); } + // Return the peer certificate (if any) + virtual const trantor::CertificatePtr &peerCertificate() const = 0; + const trantor::CertificatePtr &getPeerCertificate() const + { + return peerCertificate(); + } + /// Get the Json object of the request /** * The content type of the request must be 'application/json', diff --git a/lib/inc/drogon/HttpResponse.h b/lib/inc/drogon/HttpResponse.h index 6d4ecccb..4e203cc7 100644 --- a/lib/inc/drogon/HttpResponse.h +++ b/lib/inc/drogon/HttpResponse.h @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -336,6 +337,16 @@ class DROGON_EXPORT HttpResponse */ virtual void setPassThrough(bool flag) = 0; + /** + * @brief Get the certificate of the peer, if any. + * @return The certificate of the peer. nullptr is none. + */ + virtual const trantor::CertificatePtr &peerCertificate() const = 0; + const trantor::CertificatePtr &getPeerCertificate() const + { + return peerCertificate(); + } + /* The following methods are a series of factory methods that help users * create response objects. */ diff --git a/lib/inc/drogon/HttpTypes.h b/lib/inc/drogon/HttpTypes.h index 27769593..58fb8d8b 100644 --- a/lib/inc/drogon/HttpTypes.h +++ b/lib/inc/drogon/HttpTypes.h @@ -160,6 +160,7 @@ enum class ReqResult Timeout, HandshakeError, InvalidCertificate, + EncryptionFailure, }; enum class WebSocketMessageType @@ -190,6 +191,8 @@ inline string_view to_string_view(drogon::ReqResult result) return "Handshake error"; case ReqResult::InvalidCertificate: return "Invalid certificate"; + case ReqResult::EncryptionFailure: + return "Unrecoverable encryption failure"; default: return "Unknown error"; } diff --git a/lib/inc/drogon/utils/Utilities.h b/lib/inc/drogon/utils/Utilities.h index 952877e0..bcbd0759 100644 --- a/lib/inc/drogon/utils/Utilities.h +++ b/lib/inc/drogon/utils/Utilities.h @@ -134,6 +134,30 @@ inline std::string getMd5(const std::string &originalString) return getMd5(originalString.data(), originalString.length()); } +DROGON_EXPORT std::string getSha1(const char *data, const size_t dataLen); +inline std::string getSha1(const std::string &originalString) +{ + return getSha1(originalString.data(), originalString.length()); +} + +DROGON_EXPORT std::string getSha256(const char *data, const size_t dataLen); +inline std::string getSha256(const std::string &originalString) +{ + return getSha256(originalString.data(), originalString.length()); +} + +DROGON_EXPORT std::string getSha3(const char *data, const size_t dataLen); +inline std::string getSha3(const std::string &originalString) +{ + return getSha3(originalString.data(), originalString.length()); +} + +DROGON_EXPORT std::string getBlake2b(const char *data, const size_t dataLen); +inline std::string getBlake2b(const std::string &originalString) +{ + return getBlake2b(originalString.data(), originalString.length()); +} + /// Commpress or decompress data using gzip lib. /** * @param data the input data @@ -300,12 +324,18 @@ DROGON_EXPORT void replaceAll(std::string &s, * @param size number of bytes to generate * * @return true if generation is successfull. False otherwise - * - * @note DO NOT abuse this function. Especially if Drogon is built without - * OpenSSL. Entropy running low is a real issue. */ DROGON_EXPORT bool secureRandomBytes(void *ptr, size_t size); +/** + * @brief Generates cryptographically secure random string. + * + * @param size number of characters to generate + * + * @return the random string + */ +DROGON_EXPORT std::string secureRandomString(size_t size); + template typename std::enable_if::value, T>::type fromString(const std::string &p) noexcept(false) @@ -409,6 +439,8 @@ inline bool fromString(const std::string &p) noexcept(false) throw std::runtime_error("Can't convert from string '" + p + "' to bool"); } +DROGON_EXPORT bool supportsTls() noexcept; + namespace internal { DROGON_EXPORT extern const size_t fixedRandomNumber; diff --git a/lib/src/HttpAppFrameworkImpl.h b/lib/src/HttpAppFrameworkImpl.h index 4e57b05d..966a2304 100644 --- a/lib/src/HttpAppFrameworkImpl.h +++ b/lib/src/HttpAppFrameworkImpl.h @@ -545,10 +545,7 @@ class HttpAppFrameworkImpl final : public HttpAppFramework bool supportSSL() const override { -#ifdef OpenSSL_FOUND - return true; -#endif - return false; + return trantor::utils::tlsBackend() != "None"; } size_t getCurrentThreadIndex() const override diff --git a/lib/src/HttpClientImpl.cc b/lib/src/HttpClientImpl.cc index c627a6dc..162beb04 100644 --- a/lib/src/HttpClientImpl.cc +++ b/lib/src/HttpClientImpl.cc @@ -37,19 +37,20 @@ void HttpClientImpl::createTcpClient() tcpClientPtr_ = std::make_shared(loop_, serverAddr_, "httpClient"); -#ifdef OpenSSL_FOUND - if (useSSL_) + if (useSSL_ && utils::supportsTls()) { LOG_TRACE << "useOldTLS=" << useOldTLS_; LOG_TRACE << "domain=" << domain_; - tcpClientPtr_->enableSSL(useOldTLS_, - validateCert_, - domain_, - sslConfCmds_, - clientCertPath_, - clientKeyPath_); + auto policy = trantor::TLSPolicy::defaultClientPolicy(); + policy->setUseOldTLS(useOldTLS_) + .setValidate(validateCert_) + .setHostname(domain_) + .setConfCmds(sslConfCmds_) + .setCertPath(clientCertPath_) + .setKeyPath(clientKeyPath_); + tcpClientPtr_->enableSSL(std::move(policy)); } -#endif + auto thisPtr = shared_from_this(); std::weak_ptr weakPtr = thisPtr; @@ -126,6 +127,8 @@ void HttpClientImpl::createTcpClient() thisPtr->onError(ReqResult::HandshakeError); else if (err == trantor::SSLError::kSSLInvalidCertificate) thisPtr->onError(ReqResult::InvalidCertificate); + else if (err == trantor::SSLError::kSSLProtocolError) + thisPtr->onError(ReqResult::EncryptionFailure); else { LOG_FATAL << "Invalid value for SSLError"; @@ -159,12 +162,12 @@ HttpClientImpl::HttpClientImpl(trantor::EventLoop *loop, lowerHost.end(), lowerHost.begin(), [](unsigned char c) { return tolower(c); }); - if (lowerHost.find("https://") != std::string::npos) + if (lowerHost.find("https://") == 0) { useSSL_ = true; lowerHost = lowerHost.substr(8); } - else if (lowerHost.find("http://") != std::string::npos) + else if (lowerHost.find("http://") == 0) { useSSL_ = false; lowerHost = lowerHost.substr(7); @@ -621,6 +624,7 @@ void HttpClientImpl::onRecvMessage(const trantor::TcpConnectionPtr &connPtr, if (responseParser->gotAll()) { auto resp = responseParser->responseImpl(); + resp->setPeerCertificate(connPtr->peerCertificate()); responseParser->reset(); bytesReceived_ += (msgSize - msg->readableBytes()); msgSize = msg->readableBytes(); diff --git a/lib/src/HttpFileImpl.cc b/lib/src/HttpFileImpl.cc index 0c9811c2..28722a80 100644 --- a/lib/src/HttpFileImpl.cc +++ b/lib/src/HttpFileImpl.cc @@ -128,6 +128,16 @@ std::string HttpFileImpl::getMd5() const noexcept return utils::getMd5(fileContent_.data(), fileContent_.size()); } +std::string HttpFileImpl::getSha256() const noexcept +{ + return utils::getSha256(fileContent_.data(), fileContent_.size()); +} + +std::string HttpFileImpl::getSha3() const noexcept +{ + return utils::getSha3(fileContent_.data(), fileContent_.size()); +} + const std::string &HttpFile::getFileName() const noexcept { return implPtr_->getFileName(); diff --git a/lib/src/HttpFileImpl.h b/lib/src/HttpFileImpl.h index 500bf5c9..b3c2e11a 100644 --- a/lib/src/HttpFileImpl.h +++ b/lib/src/HttpFileImpl.h @@ -116,8 +116,12 @@ class HttpFileImpl return parseFileType(getFileExtension()); } - /// Return the md5 string of the file + /// Return md5 hash of the file std::string getMd5() const noexcept; + // Return sha1 hash of the file + std::string getSha256() const noexcept; + // Return sha512 hash of the file + std::string getSha3() const noexcept; // int saveTo(const std::string &pathAndFileName) const; int saveTo(const filesystem::path &pathAndFileName) const noexcept; void setRequest(const HttpRequestPtr &req) noexcept diff --git a/lib/src/HttpRequestImpl.h b/lib/src/HttpRequestImpl.h index e054c28b..235ab301 100644 --- a/lib/src/HttpRequestImpl.h +++ b/lib/src/HttpRequestImpl.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -74,6 +75,7 @@ class HttpRequestImpl : public HttpRequest contentTypeString_.clear(); keepAlive_ = true; jsonParsingErrorPtr_.reset(); + peerCertificate_.reset(); } trantor::EventLoop *getLoop() { @@ -231,6 +233,11 @@ class HttpRequestImpl : public HttpRequest return creationDate_; } + const trantor::CertificatePtr &peerCertificate() const override + { + return peerCertificate_; + } + void setCreationDate(const trantor::Date &date) { creationDate_ = date; @@ -246,6 +253,11 @@ class HttpRequestImpl : public HttpRequest local_ = local; } + void setPeerCertificate(const trantor::CertificatePtr &cert) + { + peerCertificate_ = cert; + } + void addHeader(const char *start, const char *colon, const char *end); void removeHeader(std::string key) override @@ -561,6 +573,7 @@ class HttpRequestImpl : public HttpRequest trantor::InetAddress peer_; trantor::InetAddress local_; trantor::Date creationDate_; + trantor::CertificatePtr peerCertificate_; std::unique_ptr cacheFilePtr_; mutable std::unique_ptr jsonParsingErrorPtr_; std::unique_ptr expectPtr_; diff --git a/lib/src/HttpResponseImpl.h b/lib/src/HttpResponseImpl.h index 870b2678..2ffd5571 100644 --- a/lib/src/HttpResponseImpl.h +++ b/lib/src/HttpResponseImpl.h @@ -316,6 +316,14 @@ class DROGON_EXPORT HttpResponseImpl : public HttpResponse { return sendfileRange_; } + const trantor::CertificatePtr &peerCertificate() const override + { + return peerCertificate_; + } + void setPeerCertificate(const trantor::CertificatePtr &cert) + { + peerCertificate_ = cert; + } void setSendfile(const std::string &filename) { sendfileName_ = filename; @@ -472,6 +480,7 @@ class DROGON_EXPORT HttpResponseImpl : public HttpResponse mutable std::shared_ptr jsonPtr_; std::shared_ptr fullHeaderString_; + trantor::CertificatePtr peerCertificate_; mutable std::shared_ptr httpString_; mutable size_t datePos_{static_cast(-1)}; mutable int64_t httpStringDate_{-1}; diff --git a/lib/src/HttpServer.cc b/lib/src/HttpServer.cc index 9f67dc4a..0a0b7901 100644 --- a/lib/src/HttpServer.cc +++ b/lib/src/HttpServer.cc @@ -179,6 +179,7 @@ void HttpServer::onMessage(const TcpConnectionPtr &conn, MsgBuffer *buf) req->setLocalAddr(conn->localAddr()); req->setCreationDate(trantor::Date::date()); req->setSecure(conn->isSSLConnection()); + req->setPeerCertificate(conn->peerCertificate()); if (requestParser->firstReq() && isWebSocket(req)) { auto wsConn = std::make_shared(conn); @@ -505,29 +506,29 @@ static std::size_t chunkingCallback( // Alternative code if there are client softwares that do not support chunk // size with leading zeroes // auto nHeaderLen = - //#ifdef _WIN32 + // #ifdef _WIN32 // sprintf_s(pBuffer, // nHeaderSize, "%llx\r", // nDataSize); - //#else + // #else // sprintf(pBuffer, "%lx\r", // nDataSize); - //#endif + // #endif // pBuffer[nHeaderLen++] = '\n'; // if (nHeaderLen < nHeaderSize) // smaller that what was reserved -> // move data - //#ifdef _WIN32 + // #ifdef _WIN32 // memmove_s(pBuffer + // nHeaderLen, // nSize - nHeaderLen, // pBuffer + // nHeaderSize, // nDataSize + 2); - //#else + // #else // memmove(pBuffer + nHeaderLen, // pBuffer + nHeaderSize, // nDataSize + 2); - //#endif + // #endif // return nHeaderLen + nDataSize + 2; } diff --git a/lib/src/HttpServer.h b/lib/src/HttpServer.h index a1d18745..8b17506e 100644 --- a/lib/src/HttpServer.h +++ b/lib/src/HttpServer.h @@ -85,13 +85,21 @@ class HttpServer : trantor::NonCopyable void start(); void stop(); - void enableSSL( + [[deprecated("Use enableSSL(SSLPolicy) instead")]] void enableSSL( const std::string &certPath, const std::string &keyPath, bool useOldTLS, const std::vector> &sslConfCmds) { - server_.enableSSL(certPath, keyPath, useOldTLS, sslConfCmds); + auto policy = + trantor::TLSPolicy::defaultServerPolicy(certPath, keyPath); + policy->setConfCmds(sslConfCmds).setUseOldTLS(useOldTLS); + server_.enableSSL(std::move(policy)); + } + + void enableSSL(trantor::TLSPolicyPtr policy) + { + server_.enableSSL(std::move(policy)); } const trantor::InetAddress &address() const diff --git a/lib/src/ListenerManager.cc b/lib/src/ListenerManager.cc index 60ad3038..be2bfd35 100644 --- a/lib/src/ListenerManager.cc +++ b/lib/src/ListenerManager.cc @@ -58,12 +58,8 @@ void ListenerManager::addListener( bool useOldTLS, const std::vector> &sslConfCmds) { -#ifndef OpenSSL_FOUND - if (useSSL) - { + if (useSSL && !utils::supportsTls()) LOG_ERROR << "Can't use SSL without OpenSSL found in your system"; - } -#endif listeners_.emplace_back( ip, port, useSSL, certFile, keyFile, useOldTLS, sslConfCmds); } @@ -83,15 +79,9 @@ void ListenerManager::createListeners( const WebSocketNewAsyncCallback &webSocketCallback, const ConnectionCallback &connectionCallback, size_t connectionTimeout, -#ifdef OpenSSL_FOUND const std::string &globalCertFile, const std::string &globalKeyFile, const std::vector> &sslConfCmds, -#else - const std::string & /*globalCertFile*/, - const std::string & /*globalKeyFile*/, - const std::vector> & /*sslConfCmds*/, -#endif const std::vector &ioLoops, const std::vector> &syncAdvices, @@ -132,9 +122,8 @@ void ListenerManager::createListeners( syncAdvices, preSendingAdvices); - if (listener.useSSL_) + if (listener.useSSL_ && utils::supportsTls()) { -#ifdef OpenSSL_FOUND auto cert = listener.certFile_; auto key = listener.keyFile_; if (cert.empty()) @@ -152,8 +141,10 @@ void ListenerManager::createListeners( std::copy(listener.sslConfCmds_.begin(), listener.sslConfCmds_.end(), std::back_inserter(cmds)); - serverPtr->enableSSL(cert, key, listener.useOldTLS_, cmds); -#endif + auto policy = + trantor::TLSPolicy::defaultServerPolicy(cert, key); + policy->setConfCmds(cmds).setUseOldTLS(listener.useOldTLS_); + serverPtr->enableSSL(std::move(policy)); } serverPtr->setHttpAsyncCallback(httpCallback); serverPtr->setNewWebsocketCallback(webSocketCallback); @@ -179,9 +170,8 @@ void ListenerManager::createListeners( "drogon", syncAdvices, preSendingAdvices); - if (listener.useSSL_) + if (listener.useSSL_ && utils::supportsTls()) { -#ifdef OpenSSL_FOUND auto cert = listener.certFile_; auto key = listener.keyFile_; if (cert.empty()) @@ -196,11 +186,10 @@ void ListenerManager::createListeners( exit(1); } auto cmds = sslConfCmds; - std::copy(listener.sslConfCmds_.begin(), - listener.sslConfCmds_.end(), - std::back_inserter(cmds)); - serverPtr->enableSSL(cert, key, listener.useOldTLS_, cmds); -#endif + auto policy = + trantor::TLSPolicy::defaultServerPolicy(cert, key); + policy->setConfCmds(cmds).setUseOldTLS(listener.useOldTLS_); + serverPtr->enableSSL(std::move(policy)); } serverPtr->setIoLoops(ioLoops); serverPtr->setHttpAsyncCallback(httpCallback); diff --git a/lib/src/Utilities.cc b/lib/src/Utilities.cc index 7dbc1b0c..56f08ba6 100644 --- a/lib/src/Utilities.cc +++ b/lib/src/Utilities.cc @@ -15,13 +15,8 @@ #include #include "filesystem.h" #include +#include #include -#ifdef OpenSSL_FOUND -#include -#include -#else -#include "ssl_funcs/Md5.h" -#endif #ifdef USE_BROTLI #include #include @@ -30,26 +25,23 @@ #include #include #include -#include #else #include #include #endif #include -#include -#include #include -#include #include -#include +#include #include #include +#include +#include #include #include #include #include #include -#include #include #ifdef _WIN32 @@ -1144,27 +1136,27 @@ std::string brotliDecompress(const char * /*data*/, const size_t /*ndata*/) std::string getMd5(const char *data, const size_t dataLen) { -#if defined(OpenSSL_FOUND) && OPENSSL_VERSION_MAJOR < 3 - MD5_CTX c; - unsigned char md5[16] = {0}; - MD5_Init(&c); - MD5_Update(&c, data, dataLen); - MD5_Final(md5, &c); - return utils::binaryStringToHex(md5, 16); -#elif defined(OpenSSL_FOUND) - unsigned char md5[16] = {0}; - const EVP_MD *md = EVP_get_digestbyname("md5"); - assert(md != nullptr); + return trantor::utils::toHexString(trantor::utils::md5(data, dataLen)); +} - EVP_MD_CTX *mdctx = EVP_MD_CTX_new(); - EVP_DigestInit_ex2(mdctx, md, NULL); - EVP_DigestUpdate(mdctx, data, dataLen); - EVP_DigestFinal_ex(mdctx, md5, NULL); - EVP_MD_CTX_free(mdctx); - return utils::binaryStringToHex(md5, 16); -#else - return Md5Encode::encode(data, dataLen); -#endif +std::string getSha1(const char *data, const size_t dataLen) +{ + return trantor::utils::toHexString(trantor::utils::sha1(data, dataLen)); +} + +std::string getSha256(const char *data, const size_t dataLen) +{ + return trantor::utils::toHexString(trantor::utils::sha256(data, dataLen)); +} + +std::string getSha3(const char *data, const size_t dataLen) +{ + return trantor::utils::toHexString(trantor::utils::sha3(data, dataLen)); +} + +std::string getBlake2b(const char *data, const size_t dataLen) +{ + return trantor::utils::toHexString(trantor::utils::blake2b(data, dataLen)); } void replaceAll(std::string &s, const std::string &from, const std::string &to) @@ -1177,48 +1169,50 @@ void replaceAll(std::string &s, const std::string &from, const std::string &to) } } -/** - * @brief Generates `size` random bytes from the systems random source and - * stores them into `ptr`. - */ -static bool systemRandomBytes(void *ptr, size_t size) +bool supportsTls() noexcept { -#if defined(__BSD__) || defined(__APPLE__) - arc4random_buf(ptr, size); - return true; -#elif defined(__linux__) && \ - ((defined(__GLIBC__) && \ - (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25)))) - return getentropy(ptr, size) != -1; -#elif defined(_WIN32) // Windows - return RtlGenRandom(ptr, (ULONG)size); -#elif defined(__unix__) || defined(__HAIKU__) - // fallback to /dev/urandom for other/old UNIX - thread_local std::unique_ptr > fptr( - fopen("/dev/urandom", "rb"), [](FILE *ptr) { - if (ptr != nullptr) - fclose(ptr); - }); - if (fptr == nullptr) - { - LOG_FATAL << "Failed to open /dev/urandom for randomness"; - abort(); - } - if (fread(ptr, 1, size, fptr.get()) != 0) - return true; -#endif - return false; + return trantor::utils::tlsBackend() != "None"; } bool secureRandomBytes(void *ptr, size_t size) { -#ifdef OpenSSL_FOUND - if (RAND_bytes((unsigned char *)ptr, (int)size) == 0) - return true; -#endif - if (systemRandomBytes(ptr, size)) - return true; - return false; + return trantor::utils::secureRandomBytes(ptr, size); +} + +std::string secureRandomString(size_t size) +{ + if (size == 0) + return std::string(); + + std::string ret(size, 0); + const string_view chars = + "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "+-"; + assert(chars.size() == 64); + + trantor::utils::Hash256 hash; + // batch up to 32 bytes of random data for efficiency. Calling + // secureRandomBytes can be expensive. + auto randByte = [&hash]() { + static size_t i = 0; + if (i == 0) + { + bool ok = trantor::utils::secureRandomBytes(&hash, sizeof(hash)); + if (!ok) + throw std::runtime_error( + "Failed to generate random bytes for secureRandomString"); + } + unsigned char *hashBytes = reinterpret_cast(&hash); + auto ret = hashBytes[i]; + i = (i + 1) % sizeof(hash); + return ret; + }; + + for (size_t i = 0; i < size; ++i) + ret[i] = chars[randByte() % 64]; + return ret; } namespace internal diff --git a/lib/src/WebSocketClientImpl.cc b/lib/src/WebSocketClientImpl.cc index 4c73998b..2d52c8bd 100644 --- a/lib/src/WebSocketClientImpl.cc +++ b/lib/src/WebSocketClientImpl.cc @@ -22,11 +22,7 @@ #include #include #include -#ifdef OpenSSL_FOUND -#include -#else -#include "ssl_funcs/Sha1.h" -#endif +#include using namespace drogon; using namespace trantor; @@ -55,7 +51,11 @@ void WebSocketClientImpl::createTcpClient() std::make_shared(loop_, serverAddr_, "httpClient"); if (useSSL_) { - tcpClientPtr_->enableSSL(useOldTLS_, validateCert_, domain_); + auto policy = trantor::TLSPolicy::defaultClientPolicy(); + policy->setUseOldTLS(useOldTLS_) + .setValidate(validateCert_) + .setHostname(domain_); + tcpClientPtr_->enableSSL(std::move(policy)); } auto thisPtr = shared_from_this(); std::weak_ptr weakPtr = thisPtr; @@ -130,11 +130,11 @@ void WebSocketClientImpl::connectToServerInLoop() auto wsKey = wsKey_; wsKey.append("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); - unsigned char accKey[SHA_DIGEST_LENGTH]; - SHA1(reinterpret_cast(wsKey.c_str()), - wsKey.length(), - accKey); - wsAccept_ = utils::base64Encode(accKey, SHA_DIGEST_LENGTH); + unsigned char accKey[20]; + static_assert(sizeof(accKey) == sizeof(trantor::utils::Hash160)); + auto sha1 = trantor::utils::sha1(wsKey); + memcpy(accKey, &sha1, sizeof(sha1)); + wsAccept_ = utils::base64Encode(accKey, 20); upgradeRequest_->addHeader("Sec-WebSocket-Key", wsKey_); // upgradeRequest_->addHeader("Sec-WebSocket-Version","13"); diff --git a/lib/src/WebsocketControllersRouter.cc b/lib/src/WebsocketControllersRouter.cc index e56fd92f..67a75cc5 100644 --- a/lib/src/WebsocketControllersRouter.cc +++ b/lib/src/WebsocketControllersRouter.cc @@ -21,11 +21,7 @@ #include #include #include -#ifdef OpenSSL_FOUND -#include -#else -#include "ssl_funcs/Sha1.h" -#endif +#include using namespace drogon; void WebsocketControllersRouter::registerWebSocketController( @@ -338,11 +334,10 @@ void WebsocketControllersRouter::doControllerHandler( const WebSocketConnectionImplPtr &wsConnPtr) { wsKey.append("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); - unsigned char accKey[SHA_DIGEST_LENGTH]; - SHA1(reinterpret_cast(wsKey.c_str()), - wsKey.length(), - accKey); - auto base64Key = utils::base64Encode(accKey, SHA_DIGEST_LENGTH); + unsigned char accKey[20]; + auto sha1 = trantor::utils::sha1(wsKey.c_str(), wsKey.length()); + memcpy(accKey, &sha1, sizeof(sha1)); + auto base64Key = utils::base64Encode(accKey, sizeof(accKey)); auto resp = HttpResponse::newHttpResponse(); resp->setStatusCode(k101SwitchingProtocols); resp->addHeader("Upgrade", "websocket"); diff --git a/lib/src/ssl_funcs/Md5.cc b/lib/src/ssl_funcs/Md5.cc deleted file mode 100644 index 318a9c82..00000000 --- a/lib/src/ssl_funcs/Md5.cc +++ /dev/null @@ -1,351 +0,0 @@ -/** - * - * Md5.cc - * An Tao - * - * Copyright 2018, An Tao. All rights reserved. - * https://github.com/an-tao/drogon - * Use of this source code is governed by a MIT license - * that can be found in the License file. - * - * Drogon - * - */ - -#include "Md5.h" -#include -#include - -const uint32_t Md5Encode::kA = 0x67452301; -const uint32_t Md5Encode::kB = 0xefcdab89; -const uint32_t Md5Encode::kC = 0x98badcfe; -const uint32_t Md5Encode::kD = 0x10325476; - -const uint64_t Md5Encode::tiNumInteger = 4294967296; - -// function: CycleMoveLeft -// @param srcNum: the number to be moved left -// @param bitNumToMove: the number of bit of moving -// @return result after moving -uint32_t Md5Encode::cycleMoveLeft(uint32_t srcNum, int bitNumToMove) -{ - uint32_t srcNum1 = srcNum; - uint32_t srcNum2 = srcNum; - if (0 >= bitNumToMove) - { - return srcNum; - } - return ((srcNum1 << bitNumToMove) | (srcNum2 >> (32 - bitNumToMove))); -} - -// function: FillData -// @param inDataPtr: input data -// @param dataByteLen: length of input data -// @param outDataPtr: output data -// return : length of output data -uint32_t Md5Encode::fillData(const char *inDataPtr, - int dataByteLen, - char **outDataPtr) -{ - int bitNum = dataByteLen * BIT_OF_BYTE; - // int grop_num = bitNum / BIT_OF_GROUP; - int modBitNum = bitNum % BIT_OF_GROUP; - int bitNeedFill = 0; - if (modBitNum >= (BIT_OF_GROUP - SRC_DATA_LEN)) - { - bitNeedFill = (BIT_OF_GROUP - modBitNum); - bitNeedFill += (BIT_OF_GROUP - SRC_DATA_LEN); - } - else - { - bitNeedFill = (BIT_OF_GROUP - SRC_DATA_LEN) - modBitNum; - } - int allBit = bitNum + bitNeedFill; - if (0 < bitNeedFill) - { - *outDataPtr = - new char[allBit / BIT_OF_BYTE + SRC_DATA_LEN / BIT_OF_BYTE]; - memset(*outDataPtr, - 0, - allBit / BIT_OF_BYTE + SRC_DATA_LEN / BIT_OF_BYTE); - // copy data - memcpy(*outDataPtr, inDataPtr, dataByteLen); - // fill rest data - unsigned char *tmp = reinterpret_cast(*outDataPtr); - tmp += dataByteLen; - // fill 1 and 0 - *tmp = 0x80; - // fill origin data len - unsigned long long *originNum = - (unsigned long long *)((*outDataPtr) + ((allBit / BIT_OF_BYTE))); - *originNum = dataByteLen * BIT_OF_BYTE; - } - return (allBit / BIT_OF_BYTE + SRC_DATA_LEN / BIT_OF_BYTE); -} - -void Md5Encode::roundF(char *data512Ptr, ParamDynamic ¶m) -{ - uint32_t *M = reinterpret_cast(data512Ptr); - int s[] = {7, 12, 17, 22}; - for (int i = 0; i < 16; ++i) - { - uint64_t ti = tiNumInteger * fabs(sin(i + 1)); - if (i % 4 == 0) - { - FF(param.ua_, param.ub_, param.uc_, param.ud_, M[i], s[i % 4], ti); - } - else if (i % 4 == 1) - { - FF(param.ud_, param.ua_, param.ub_, param.uc_, M[i], s[i % 4], ti); - } - else if (i % 4 == 2) - { - FF(param.uc_, param.ud_, param.ua_, param.ub_, M[i], s[i % 4], ti); - } - else if (i % 4 == 3) - { - FF(param.ub_, param.uc_, param.ud_, param.ua_, M[i], s[i % 4], ti); - } - } -} - -void Md5Encode::roundG(char *data512Ptr, ParamDynamic ¶m) -{ - uint32_t *M = reinterpret_cast(data512Ptr); - int s[] = {5, 9, 14, 20}; - for (int i = 0; i < 16; ++i) - { - auto sss = sin(i + 1 + 16); - uint64_t ti = tiNumInteger * fabs(sss); - int index = (i * 5 + 1) % 16; - if (i % 4 == 0) - { - GG(param.ua_, - param.ub_, - param.uc_, - param.ud_, - M[index], - s[i % 4], - ti); - } - else if (i % 4 == 1) - { - GG(param.ud_, - param.ua_, - param.ub_, - param.uc_, - M[index], - s[i % 4], - ti); - } - else if (i % 4 == 2) - { - GG(param.uc_, - param.ud_, - param.ua_, - param.ub_, - M[index], - s[i % 4], - ti); - } - else if (i % 4 == 3) - { - GG(param.ub_, - param.uc_, - param.ud_, - param.ua_, - M[index], - s[i % 4], - ti); - } - } -} - -void Md5Encode::roundH(char *data512Ptr, ParamDynamic ¶m) -{ - uint32_t *M = reinterpret_cast(data512Ptr); - int s[] = {4, 11, 16, 23}; - for (int i = 0; i < 16; ++i) - { - uint64_t ti = tiNumInteger * fabs(sin(i + 1 + 32)); - int index = (i * 3 + 5) % 16; - if (i % 4 == 0) - { - HH(param.ua_, - param.ub_, - param.uc_, - param.ud_, - M[index], - s[i % 4], - ti); - } - else if (i % 4 == 1) - { - HH(param.ud_, - param.ua_, - param.ub_, - param.uc_, - M[index], - s[i % 4], - ti); - } - else if (i % 4 == 2) - { - HH(param.uc_, - param.ud_, - param.ua_, - param.ub_, - M[index], - s[i % 4], - ti); - } - else if (i % 4 == 3) - { - HH(param.ub_, - param.uc_, - param.ud_, - param.ua_, - M[index], - s[i % 4], - ti); - } - } -} - -void Md5Encode::roundI(char *data512Ptr, ParamDynamic ¶m) -{ - uint32_t *M = reinterpret_cast(data512Ptr); - int s[] = {6, 10, 15, 21}; - for (int i = 0; i < 16; ++i) - { - uint64_t ti = tiNumInteger * fabs(sin(i + 1 + 48)); - int index = (i * 7 + 0) % 16; - if (i % 4 == 0) - { - II(param.ua_, - param.ub_, - param.uc_, - param.ud_, - M[index], - s[i % 4], - ti); - } - else if (i % 4 == 1) - { - II(param.ud_, - param.ua_, - param.ub_, - param.uc_, - M[index], - s[i % 4], - ti); - } - else if (i % 4 == 2) - { - II(param.uc_, - param.ud_, - param.ua_, - param.ub_, - M[index], - s[i % 4], - ti); - } - else if (i % 4 == 3) - { - II(param.ub_, - param.uc_, - param.ud_, - param.ua_, - M[index], - s[i % 4], - ti); - } - } -} - -void Md5Encode::rotationCalculate(char *data512Ptr, ParamDynamic ¶m) -{ - if (nullptr == data512Ptr) - { - return; - } - roundF(data512Ptr, param); - roundG(data512Ptr, param); - roundH(data512Ptr, param); - roundI(data512Ptr, param); - param.ua_ = param.va_last_ + param.ua_; - param.ub_ = param.vb_last_ + param.ub_; - param.uc_ = param.vc_last_ + param.uc_; - param.ud_ = param.vd_last_ + param.ud_; - - param.va_last_ = param.ua_; - param.vb_last_ = param.ub_; - param.vc_last_ = param.uc_; - param.vd_last_ = param.ud_; -} - -// Convert to hex format string -std::string Md5Encode::getHexStr(uint32_t numStr) -{ - std::string hexstr = ""; - char szch[] = {'0', - '1', - '2', - '3', - '4', - '5', - '6', - '7', - '8', - '9', - 'A', - 'B', - 'C', - 'D', - 'E', - 'F'}; - unsigned char *tmptr = (unsigned char *)&numStr; - int len = sizeof(numStr); - for (int i = 0; i < len; ++i) - { - unsigned char ch = tmptr[i] & 0xF0; - ch = ch >> 4; - hexstr.append(1, szch[ch]); - ch = tmptr[i] & 0x0F; - hexstr.append(1, szch[ch]); - } - return hexstr; -} - -// function: Encode -// @param srcInfo: the string to be encoded. -// return : the string after encoding -std::string Md5Encode::encode(const char *data, const size_t dataLen) -{ - ParamDynamic param; - param.ua_ = kA; - param.ub_ = kB; - param.uc_ = kC; - param.ud_ = kD; - param.va_last_ = kA; - param.vb_last_ = kB; - param.vc_last_ = kC; - param.vd_last_ = kD; - - std::string result; - char *outDataPtr = nullptr; - int totalByte = fillData(data, dataLen, &outDataPtr); - - for (int i = 0; i < totalByte / (BIT_OF_GROUP / BIT_OF_BYTE); ++i) - { - char *dataBitOfGroup = outDataPtr; - dataBitOfGroup += i * (BIT_OF_GROUP / BIT_OF_BYTE); - rotationCalculate(dataBitOfGroup, param); - } - delete[] outDataPtr, outDataPtr = nullptr; - result.append(getHexStr(param.ua_)); - result.append(getHexStr(param.ub_)); - result.append(getHexStr(param.uc_)); - result.append(getHexStr(param.ud_)); - return result; -} diff --git a/lib/src/ssl_funcs/Md5.h b/lib/src/ssl_funcs/Md5.h deleted file mode 100644 index c9b04a51..00000000 --- a/lib/src/ssl_funcs/Md5.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -******************************************************* -* brief: md5 encryption -* author: Monkey.Knight -******************************************************* -*/ - -/** - * - * Md5.h - * An Tao - * - * Copyright 2018, An Tao. All rights reserved. - * https://github.com/an-tao/drogon - * Use of this source code is governed by a MIT license - * that can be found in the License file. - * - * Drogon - * - */ - -#pragma once - -#include -#include - -#define BIT_OF_BYTE 8 -#define BIT_OF_GROUP 512 -#define SRC_DATA_LEN 64 - -#define DEF_F(X, Y, Z) ((((X) & (Y)) | ((~X) & (Z)))) -#define DEF_G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z))) -#define DEF_H(X, Y, Z) ((X) ^ (Y) ^ (Z)) -#define DEF_I(X, Y, Z) ((Y) ^ ((X) | (~Z))) - -#define FF(a, b, c, d, Mj, s, ti) \ - (a = b + cycleMoveLeft((a + DEF_F(b, c, d) + Mj + ti), s)) -#define GG(a, b, c, d, Mj, s, ti) \ - (a = b + cycleMoveLeft((a + DEF_G(b, c, d) + Mj + ti), s)) -#define HH(a, b, c, d, Mj, s, ti) \ - (a = b + cycleMoveLeft((a + DEF_H(b, c, d) + Mj + ti), s)) -#define II(a, b, c, d, Mj, s, ti) \ - (a = b + cycleMoveLeft((a + DEF_I(b, c, d) + Mj + ti), s)) - -class Md5Encode -{ - public: - struct ParamDynamic - { - uint32_t ua_; - uint32_t ub_; - uint32_t uc_; - uint32_t ud_; - uint32_t va_last_; - uint32_t vb_last_; - uint32_t vc_last_; - uint32_t vd_last_; - }; - - public: - static std::string encode(const char *data, const size_t dataLen); - - protected: - static uint32_t cycleMoveLeft(uint32_t srcNum, int bitNumToMove); - static void roundF(char *data512Ptr, ParamDynamic ¶m); - static void roundG(char *data512Ptr, ParamDynamic ¶m); - static void roundH(char *data512Ptr, ParamDynamic ¶m); - static void roundI(char *data512Ptr, ParamDynamic ¶m); - static void rotationCalculate(char *data512Ptr, ParamDynamic ¶m); - static std::string getHexStr(uint32_t numStr); - static uint32_t fillData(const char *inDataPtr, - int dataByteLen, - char **outDataPtr); - - private: - static const uint32_t kA; - static const uint32_t kB; - static const uint32_t kC; - static const uint32_t kD; - static const uint64_t tiNumInteger; -}; diff --git a/lib/src/ssl_funcs/Sha1.cc b/lib/src/ssl_funcs/Sha1.cc deleted file mode 100644 index a6c9eef5..00000000 --- a/lib/src/ssl_funcs/Sha1.cc +++ /dev/null @@ -1,159 +0,0 @@ -/** - * - * Sha1.cc - * An Tao - * - * Copyright 2018, An Tao. All rights reserved. - * https://github.com/an-tao/drogon - * Use of this source code is governed by a MIT license - * that can be found in the License file. - * - * Drogon - * - */ - -#include "Sha1.h" -#include - -static inline unsigned int fromBigEndian(unsigned int v) -{ - return ((v & 0xff) << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | - ((v & 0xff000000) >> 24); -} - -static void writeBigEndian64(unsigned char *p, unsigned int v) -{ - memset(p, 0, 8); - memcpy(p, &v, 4); - int i = 0; - for (i = 0; i < 4; ++i) - { - unsigned char t = p[i]; - p[i] = p[7 - i]; - p[7 - i] = t; - } -} - -static inline unsigned int leftRoll(unsigned int v, int n) -{ - return (v << n) | (v >> (32 - n)); -} - -unsigned char *SHA1(const unsigned char *dataIn, - size_t dataLen, - unsigned char *dataOut) -{ - unsigned char *pbytes = (unsigned char *)dataIn; - unsigned int nbyte = (unsigned int)dataLen; - - static unsigned int words[80]; - unsigned int H[5] = { - 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0}; - unsigned int f, k, temp, bitlen[2], word; - unsigned int i, j, index, p1, p2, maxlen; - unsigned char spec[4] = {0}; - i = nbyte % 4; - - p1 = nbyte - i; - spec[i] = 1 << 7; - while (i--) - { - spec[i] = pbytes[p1 + i]; - } - - maxlen = (nbyte + 1) % 64; - if (maxlen <= 56) - { - maxlen = (nbyte + 1) - maxlen + 64; - } - else - { - maxlen = (nbyte + 1) - maxlen + 128; - } - p2 = maxlen - 8; - writeBigEndian64((unsigned char *)bitlen, nbyte * 8); - - for (j = 0; j < maxlen; j += 64) - { - unsigned int a, b, c, d, e; - a = H[0]; - b = H[1]; - c = H[2]; - d = H[3]; - e = H[4]; - for (i = 0; i < 80; ++i) - { - if (i < 16) - { - index = j + (i << 2); - if (index < p1) - { - word = *((unsigned int *)(pbytes + index)); - } - else if (index == p1) - { - word = *(unsigned int *)spec; - } - else if (index < p2) - { - word = 0; - } - else - { - word = (index < maxlen - 4) ? bitlen[0] : bitlen[1]; - } - words[i] = fromBigEndian(word); - } - else - { - words[i] = leftRoll(words[i - 3] ^ words[i - 8] ^ - words[i - 14] ^ words[i - 16], - 1); - } - if (i < 20) - { - f = (b & c) | ((~b) & d); - k = 0x5A827999; - } - else if (i < 40) - { - f = b ^ c ^ d; - k = 0x6ED9EBA1; - } - else if (i < 60) - { - f = (b & c) | (b & d) | (c & d); - k = 0x8F1BBCDC; - } - else - { - f = b ^ c ^ d; - k = 0xCA62C1D6; - } - temp = leftRoll(a, 5) + f + e + k + words[i]; - e = d; - d = c; - c = leftRoll(b, 30); - b = a; - a = temp; - } - H[0] += a; - H[1] += b; - H[2] += c; - H[3] += d; - H[4] += e; - } - int ct = 0; - for (i = 0; i < 5; ++i) - { - unsigned char buf[4] = {0}; - memcpy(buf, &(H[i]), 4); - for (int r = 3; r >= 0; r--) - { - dataOut[ct] = buf[r]; - ++ct; - } - } - - return dataOut; -} diff --git a/lib/src/ssl_funcs/Sha1.h b/lib/src/ssl_funcs/Sha1.h deleted file mode 100644 index 8fe1ab37..00000000 --- a/lib/src/ssl_funcs/Sha1.h +++ /dev/null @@ -1,23 +0,0 @@ -/** - * - * Sha1.h - * An Tao - * - * Copyright 2018, An Tao. All rights reserved. - * https://github.com/an-tao/drogon - * Use of this source code is governed by a MIT license - * that can be found in the License file. - * - * Drogon - * - */ - -#pragma once - -#include - -#define SHA_DIGEST_LENGTH 20 - -unsigned char *SHA1(const unsigned char *dataIn, - size_t dataLen, - unsigned char *dataOut); diff --git a/lib/tests/CMakeLists.txt b/lib/tests/CMakeLists.txt index dc0ab3eb..62a2240c 100644 --- a/lib/tests/CMakeLists.txt +++ b/lib/tests/CMakeLists.txt @@ -17,7 +17,6 @@ set(UNITTEST_SOURCES unittests/OStringStreamTest.cc unittests/PubSubServiceUnittest.cc unittests/Sha1Test.cc - ../src/ssl_funcs/Sha1.cc unittests/FileTypeTest.cc unittests/DrObjectTest.cc unittests/HttpFullDateTest.cc @@ -99,7 +98,8 @@ if (BUILD_CTL) ${CMAKE_CURRENT_SOURCE_DIR}/integration_test/server/test.md ${CMAKE_CURRENT_SOURCE_DIR}/integration_test/server/index.html.gz ${CMAKE_CURRENT_SOURCE_DIR}/integration_test/server/中文.txt - ${PROJECT_SOURCE_DIR}/trantor/trantor/tests/server.pem + ${PROJECT_SOURCE_DIR}/trantor/trantor/tests/server.crt + ${PROJECT_SOURCE_DIR}/trantor/trantor/tests/server.key $) add_custom_command( TARGET integration_test_server POST_BUILD diff --git a/lib/tests/integration_test/client/main.cc b/lib/tests/integration_test/client/main.cc index e2b51051..722b56de 100644 --- a/lib/tests/integration_test/client/main.cc +++ b/lib/tests/integration_test/client/main.cc @@ -49,9 +49,10 @@ void doTest(const HttpClientPtr &client, std::shared_ptr TEST_CTX) req->setMethod(drogon::Get); req->setPath("/"); std::promise waitCookie; + bool haveCert = false; auto f = waitCookie.get_future(); client->sendRequest(req, - [client, &waitCookie, TEST_CTX]( + [client, &waitCookie, &haveCert, TEST_CTX]( ReqResult result, const HttpResponsePtr &resp) { REQUIRE(result == ReqResult::Ok); @@ -61,8 +62,11 @@ void doTest(const HttpClientPtr &client, std::shared_ptr TEST_CTX) sessionID = id; client->addCookie(id); waitCookie.set_value(1); + + haveCert = resp->peerCertificate() != nullptr; }); f.get(); + CHECK(haveCert == client->secure()); } else client->addCookie(sessionID); @@ -1067,7 +1071,7 @@ void doTest(const HttpClientPtr &client, std::shared_ptr TEST_CTX) } catch (const std::exception &e) { - FAIL("Unexpected exception, what()" + std::string(e.what())); + FAIL("Unexpected exception, what(): " + std::string(e.what())); } // Test Coroutine exception @@ -1080,7 +1084,7 @@ void doTest(const HttpClientPtr &client, std::shared_ptr TEST_CTX) } catch (const std::exception &e) { - FAIL("Unexpected exception, what()" + std::string(e.what())); + FAIL("Unexpected exception, what(): " + std::string(e.what())); } // Test Coroutine exception with co_return @@ -1093,7 +1097,7 @@ void doTest(const HttpClientPtr &client, std::shared_ptr TEST_CTX) } catch (const std::exception &e) { - FAIL("Unexpected exception, what()" + std::string(e.what())); + FAIL("Unexpected exception, what(): " + std::string(e.what())); } // Test coroutine filter @@ -1110,7 +1114,7 @@ void doTest(const HttpClientPtr &client, std::shared_ptr TEST_CTX) } catch (const std::exception &e) { - FAIL("Unexpected exception, what()" + std::string(e.what())); + FAIL("Unexpected exception, what(): " + std::string(e.what())); } // Test coroutine handler with parameters @@ -1124,7 +1128,7 @@ void doTest(const HttpClientPtr &client, std::shared_ptr TEST_CTX) } catch (const std::exception &e) { - FAIL("Unexpected exception, what()" + std::string(e.what())); + FAIL("Unexpected exception, what(): " + std::string(e.what())); } try { @@ -1136,7 +1140,7 @@ void doTest(const HttpClientPtr &client, std::shared_ptr TEST_CTX) } catch (const std::exception &e) { - FAIL("Unexpected exception, what()" + std::string(e.what())); + FAIL("Unexpected exception, what(): " + std::string(e.what())); } }); #endif diff --git a/lib/tests/integration_test/server/main.cc b/lib/tests/integration_test/server/main.cc index 5225e5bc..8dac7157 100644 --- a/lib/tests/integration_test/server/main.cc +++ b/lib/tests/integration_test/server/main.cc @@ -158,7 +158,7 @@ int main() if (app().supportSSL()) { drogon::app() - .setSSLFiles("server.pem", "server.pem") + .setSSLFiles("server.crt", "server.key") .addListener("0.0.0.0", 8849, true); } // Class function example diff --git a/lib/tests/main_CookieSameSite.cc b/lib/tests/main_CookieSameSite.cc index 43f76198..8b87a33d 100644 --- a/lib/tests/main_CookieSameSite.cc +++ b/lib/tests/main_CookieSameSite.cc @@ -60,7 +60,7 @@ int main(int argc, char **argv) std::thread thr([&]() { app() - .setSSLFiles("server.pem", "server.pem") + .setSSLFiles("server.crt", "server.key") .addListener("0.0.0.0", 8855, true) .enableSession(); app().getLoop()->queueInLoop([&p1]() { p1.set_value(); }); diff --git a/lib/tests/unittests/Sha1Test.cc b/lib/tests/unittests/Sha1Test.cc index a49016f2..36dbb361 100644 --- a/lib/tests/unittests/Sha1Test.cc +++ b/lib/tests/unittests/Sha1Test.cc @@ -1,17 +1,12 @@ -#include "../../lib/src/ssl_funcs/Sha1.h" +#include #include #include DROGON_TEST(SHA1Test) { - unsigned char in[] = + char in[] = "1234567890123456789012345678901234567890123456789012345" "678901234567890123456789012345678901234567890"; - unsigned char out[SHA_DIGEST_LENGTH] = {0}; - SHA1(in, strlen((const char *)in), out); - std::string outStr; - outStr.resize(SHA_DIGEST_LENGTH * 2); - for (int i = 0; i < SHA_DIGEST_LENGTH; ++i) - sprintf((char *)(outStr.data() + i * 2), "%02x", out[i]); - CHECK(outStr == "fecfd28bbc9345891a66d7c1b8ff46e60192d284"); + auto str = drogon::utils::getSha1(in, strlen((const char *)in)); + CHECK(str == "FECFD28BBC9345891A66D7C1B8FF46E60192D284"); } \ No newline at end of file diff --git a/trantor b/trantor index b5709ef4..8e224d11 160000 --- a/trantor +++ b/trantor @@ -1 +1 @@ -Subproject commit b5709ef4d43fa18b6d23090bbc54975fd1974c3d +Subproject commit 8e224d11b2bd6966e435cf5b75fe99973663cb1b