diff --git a/modules/schat.cpp b/modules/schat.cpp index 5250985e..bc1e6215 100644 --- a/modules/schat.cpp +++ b/modules/schat.cpp @@ -25,6 +25,14 @@ #include #include +#if !defined(OPENSSL_VERSION_NUMBER) || defined(LIBRESSL_VERSION_NUMBER) || \ + OPENSSL_VERSION_NUMBER < 0x10100007 +/* SSL_SESSION was made opaque in OpenSSL 1.1.0, cipher accessor was added 2 +weeks before the public release. +See openssl/openssl@e92813234318635639dba0168c7ef5568757449b. */ +# define SSL_SESSION_get0_cipher(pSession) ((pSession)->cipher) +#endif + using std::pair; using std::stringstream; using std::map; @@ -212,8 +220,11 @@ class CSChat : public CModule { Table.SetCell("Host", pSock->GetRemoteIP()); Table.SetCell("Port", CString(pSock->GetRemotePort())); SSL_SESSION* pSession = pSock->GetSSLSession(); - if (pSession && pSession->cipher && pSession->cipher->name) - Table.SetCell("Cipher", pSession->cipher->name); + Table.SetCell( + "Cipher", + SSL_CIPHER_get_name( + pSession ? SSL_SESSION_get0_cipher(pSession) + : nullptr)); } else { Table.SetCell("Status", "Waiting"); @@ -273,10 +284,11 @@ class CSChat : public CModule { pSock->GetRemoteIP() + ":" + CString(pSock->GetRemotePort())); SSL_SESSION* pSession = pSock->GetSSLSession(); - if (pSession && pSession->cipher && pSession->cipher->name) - Table.SetCell("Cipher", pSession->cipher->name); - else - Table.SetCell("Cipher", "None"); + Table.SetCell( + "Cipher", + SSL_CIPHER_get_name( + pSession ? SSL_SESSION_get0_cipher(pSession) + : nullptr)); } else { Table.SetCell("Type", "Listener"); diff --git a/src/SSLVerifyHost.cpp b/src/SSLVerifyHost.cpp index 51821fdd..f3df4440 100644 --- a/src/SSLVerifyHost.cpp +++ b/src/SSLVerifyHost.cpp @@ -17,6 +17,12 @@ #include #ifdef HAVE_LIBSSL +#if defined(OPENSSL_VERSION_NUMBER) && !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100007 +# define CONST_ASN1_STRING_DATA const /* 1.1.0-pre7: openssl/openssl@17ebf85abda18c3875b1ba6670fe7b393bc1f297 */ +#else +# define ASN1_STRING_get0_data( x ) ASN1_STRING_data( x ) +# define CONST_ASN1_STRING_DATA +#endif #include @@ -300,7 +306,7 @@ static HostnameValidationResult matches_common_name(const char* hostname, int common_name_loc = -1; X509_NAME_ENTRY* common_name_entry = nullptr; ASN1_STRING* common_name_asn1 = nullptr; - char* common_name_str = nullptr; + CONST_ASN1_STRING_DATA char* common_name_str = nullptr; // Find the position of the CN field in the Subject field of the certificate common_name_loc = X509_NAME_get_index_by_NID( @@ -321,7 +327,8 @@ static HostnameValidationResult matches_common_name(const char* hostname, if (common_name_asn1 == nullptr) { return Error; } - common_name_str = (char*)ASN1_STRING_data(common_name_asn1); + common_name_str = + (CONST_ASN1_STRING_DATA char*)ASN1_STRING_get0_data(common_name_asn1); // Make sure there isn't an embedded NUL character in the CN if (ASN1_STRING_length(common_name_asn1) != @@ -367,7 +374,9 @@ static HostnameValidationResult matches_subject_alternative_name( if (current_name->type == GEN_DNS) { // Current name is a DNS name, let's check it - char* dns_name = (char*)ASN1_STRING_data(current_name->d.dNSName); + CONST_ASN1_STRING_DATA char* dns_name = + (CONST_ASN1_STRING_DATA char*)ASN1_STRING_get0_data( + current_name->d.dNSName); // Make sure there isn't an embedded NUL character in the DNS name if (ASN1_STRING_length(current_name->d.dNSName) != diff --git a/src/Utils.cpp b/src/Utils.cpp index 7944658b..68bcf640 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -27,6 +27,7 @@ #include #ifdef HAVE_LIBSSL #include +#include #endif /* HAVE_LIBSSL */ #include #include @@ -64,85 +65,67 @@ constexpr const char* szDefaultDH2048 = "-----END DH PARAMETERS-----\n"; void CUtils::GenerateCert(FILE* pOut, const CString& sHost) { - EVP_PKEY* pKey = nullptr; - X509* pCert = nullptr; - X509_NAME* pName = nullptr; const int days = 365; const int years = 10; unsigned int uSeed = (unsigned int)time(nullptr); int serial = (rand_r(&uSeed) % 9999); - RSA* pRSA = RSA_generate_key(2048, 0x10001, nullptr, nullptr); - if ((pKey = EVP_PKEY_new())) { - if (!EVP_PKEY_assign_RSA(pKey, pRSA)) { - EVP_PKEY_free(pKey); - return; - } + std::unique_ptr pExponent(BN_new(), ::BN_free); + if (!pExponent || !BN_set_word(pExponent.get(), 0x10001)) return; - PEM_write_RSAPrivateKey(pOut, pRSA, nullptr, nullptr, 0, nullptr, - nullptr); + std::unique_ptr pRSA(RSA_new(), ::RSA_free); + if (!pRSA || + !RSA_generate_key_ex(pRSA.get(), 2048, pExponent.get(), nullptr)) + return; - if (!(pCert = X509_new())) { - EVP_PKEY_free(pKey); - return; - } + std::unique_ptr pKey(EVP_PKEY_new(), + ::EVP_PKEY_free); + if (!pKey || !EVP_PKEY_set1_RSA(pKey.get(), pRSA.get())) return; - X509_set_version(pCert, 2); - ASN1_INTEGER_set(X509_get_serialNumber(pCert), serial); - X509_gmtime_adj(X509_get_notBefore(pCert), 0); - X509_gmtime_adj(X509_get_notAfter(pCert), - (long)60 * 60 * 24 * days * years); - X509_set_pubkey(pCert, pKey); + std::unique_ptr pCert(X509_new(), ::X509_free); + if (!pCert) return; - pName = X509_get_subject_name(pCert); + X509_set_version(pCert.get(), 2); + ASN1_INTEGER_set(X509_get_serialNumber(pCert.get()), serial); + X509_gmtime_adj(X509_get_notBefore(pCert.get()), 0); + X509_gmtime_adj(X509_get_notAfter(pCert.get()), + (long)60 * 60 * 24 * days * years); + X509_set_pubkey(pCert.get(), pKey.get()); - const char* pLogName = getenv("LOGNAME"); - const char* pHostName = nullptr; + const char* pLogName = getenv("LOGNAME"); + const char* pHostName = nullptr; - if (!sHost.empty()) { - pHostName = sHost.c_str(); - } + if (!pLogName) pLogName = "Unknown"; - if (!pHostName) { - pHostName = getenv("HOSTNAME"); - } + if (!sHost.empty()) pHostName = sHost.c_str(); - if (!pLogName) { - pLogName = "Unknown"; - } + if (!pHostName) pHostName = getenv("HOSTNAME"); - if (!pHostName) { - pHostName = "host.unknown"; - } + if (!pHostName) pHostName = "host.unknown"; - CString sEmailAddr = pLogName; - sEmailAddr += "@"; - sEmailAddr += pHostName; + CString sEmailAddr = pLogName; + sEmailAddr += "@"; + sEmailAddr += pHostName; - X509_NAME_add_entry_by_txt(pName, "OU", MBSTRING_ASC, - (unsigned char*)pLogName, -1, -1, 0); - X509_NAME_add_entry_by_txt(pName, "CN", MBSTRING_ASC, - (unsigned char*)pHostName, -1, -1, 0); - X509_NAME_add_entry_by_txt(pName, "emailAddress", MBSTRING_ASC, - (unsigned char*)sEmailAddr.c_str(), -1, -1, - 0); + X509_NAME* pName = X509_get_subject_name(pCert.get()); + X509_NAME_add_entry_by_txt(pName, "OU", MBSTRING_ASC, + (unsigned char*)pLogName, -1, -1, 0); + X509_NAME_add_entry_by_txt(pName, "CN", MBSTRING_ASC, + (unsigned char*)pHostName, -1, -1, 0); + X509_NAME_add_entry_by_txt(pName, "emailAddress", MBSTRING_ASC, + (unsigned char*)sEmailAddr.c_str(), -1, -1, 0); - X509_set_subject_name(pCert, pName); - X509_set_issuer_name(pCert, pName); + X509_set_subject_name(pCert.get(), pName); + X509_set_issuer_name(pCert.get(), pName); - if (!X509_sign(pCert, pKey, EVP_sha256())) { - X509_free(pCert); - EVP_PKEY_free(pKey); - return; - } + if (!X509_sign(pCert.get(), pKey.get(), EVP_sha256())) return; - PEM_write_X509(pOut, pCert); - X509_free(pCert); - EVP_PKEY_free(pKey); + PEM_write_RSAPrivateKey(pOut, pRSA.get(), nullptr, nullptr, 0, nullptr, + nullptr); + PEM_write_X509(pOut, pCert.get()); - fprintf(pOut, "%s", szDefaultDH2048); - } + fprintf(pOut, "%s", szDefaultDH2048); } #endif /* HAVE_LIBSSL */ diff --git a/src/main.cpp b/src/main.cpp index f6bf0a76..a52033b7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -19,7 +19,19 @@ #include #include -#if defined(HAVE_LIBSSL) && defined(HAVE_PTHREAD) +#if defined(HAVE_LIBSSL) && defined(HAVE_PTHREAD) && \ + (!defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100004) +/* Starting with version 1.1.0-pre4, OpenSSL has a new threading implementation + that doesn't need locking callbacks. + + "OpenSSL now uses a new threading API. It is no longer necessary to set + locking callbacks to use OpenSSL in a multi-threaded environment. There are + two supported threading models: pthreads and windows threads. It is also + possible to configure OpenSSL at compile time for "no-threads". The old + threading API should no longer be used. The functions have been replaced + with "no-op" compatibility macros." + + See openssl/openssl@2e52e7df518d80188c865ea3f7bb3526d14b0c08. */ #include #include #include