diff options
37 files changed, 1088 insertions, 496 deletions
diff --git a/deps/openssl/CMakeLists.txt b/deps/openssl/CMakeLists.txt index bc69bbfa47..a72459cd73 100644 --- a/deps/openssl/CMakeLists.txt +++ b/deps/openssl/CMakeLists.txt @@ -14,14 +14,11 @@ # (further support will be needed, this is a preliminary release!) set(OPENSSL_EXPECTED_VERSION 1.0.0) -find_package(OpenSSL REQUIRED) +find_package(OpenSSL REQUIRED COMPONENTS Crypto SSL) add_library(openssl INTERFACE) target_link_libraries(openssl INTERFACE - ${OPENSSL_LIBRARIES}) - -target_include_directories(openssl - INTERFACE - ${OPENSSL_INCLUDE_DIR})
\ No newline at end of file + OpenSSL::Crypto + OpenSSL::SSL)
\ No newline at end of file diff --git a/src/cmake/macros/FindOpenSSL.cmake b/src/cmake/macros/FindOpenSSL.cmake index 4d46e5edd6..f40a591f9a 100644 --- a/src/cmake/macros/FindOpenSSL.cmake +++ b/src/cmake/macros/FindOpenSSL.cmake @@ -1,75 +1,195 @@ -# - Try to find the OpenSSL encryption library -# Once done this will define -# -# OPENSSL_ROOT_DIR - Set this variable to the root installation of OpenSSL -# -# Read-Only variables: -# OPENSSL_FOUND - system has the OpenSSL library -# OPENSSL_INCLUDE_DIR - the OpenSSL include directory -# OPENSSL_LIBRARIES - The libraries needed to use OpenSSL - -#============================================================================= -# Copyright 2006-2009 Kitware, Inc. -# Copyright 2006 Alexander Neundorf <neundorf@kde.org> -# Copyright 2009-2010 Mathieu Malaterre <mathieu.malaterre@gmail.com> -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distributed this file outside of CMake, substitute the full -# License text for the above reference.) - -# http://www.slproweb.com/products/Win32OpenSSL.html - -SET(_OPENSSL_ROOT_HINTS - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;Inno Setup: App Path]" - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;Inno Setup: App Path]" - "$ENV{OPENSSL_ROOT_DIR}" - "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}" - ) +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. -IF(PLATFORM EQUAL 64) - SET(_OPENSSL_ROOT_PATHS - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;InstallLocation]" - "C:/OpenSSL-Win64/" - "C:/OpenSSL/" - "C:/Program Files/OpenSSL-Win64/" - ) -ELSE() - SET(_OPENSSL_ROOT_PATHS - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;InstallLocation]" - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;InstallLocation]" - "C:/OpenSSL/" - "C:/Program Files/OpenSSL/" - ) -ENDIF() +#[=======================================================================[.rst: +FindOpenSSL +----------- + +Find the OpenSSL encryption library. + +Optional COMPONENTS +^^^^^^^^^^^^^^^^^^^ + +This module supports two optional COMPONENTS: ``Crypto`` and ``SSL``. Both +components have associated imported targets, as described below. + +Imported Targets +^^^^^^^^^^^^^^^^ + +This module defines the following :prop_tgt:`IMPORTED` targets: + +``OpenSSL::SSL`` + The OpenSSL ``ssl`` library, if found. +``OpenSSL::Crypto`` + The OpenSSL ``crypto`` library, if found. +``OpenSSL::applink`` + The OpenSSL ``applink`` components that might be need to be compiled into + projects under MSVC. This target is available only if found OpenSSL version + is not less than 0.9.8. By linking this target the above OpenSSL targets can + be linked even if the project has different MSVC runtime configurations with + the above OpenSSL targets. This target has no effect on platforms other than + MSVC. + +NOTE: Due to how ``INTERFACE_SOURCES`` are consumed by the consuming target, +unless you certainly know what you are doing, it is always preferred to link +``OpenSSL::applink`` target as ``PRIVATE`` and to make sure that this target is +linked at most once for the whole dependency graph of any library or +executable: + +.. code-block:: cmake + + target_link_libraries(myTarget PRIVATE OpenSSL::applink) + +Otherwise you would probably encounter unexpected random problems when building +and linking, as both the ISO C and the ISO C++ standard claims almost nothing +about what a link process should be. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables in your project: + +``OPENSSL_FOUND`` + System has the OpenSSL library. If no components are requested it only + requires the crypto library. +``OPENSSL_INCLUDE_DIR`` + The OpenSSL include directory. +``OPENSSL_CRYPTO_LIBRARY`` + The OpenSSL crypto library. +``OPENSSL_CRYPTO_LIBRARIES`` + The OpenSSL crypto library and its dependencies. +``OPENSSL_SSL_LIBRARY`` + The OpenSSL SSL library. +``OPENSSL_SSL_LIBRARIES`` + The OpenSSL SSL library and its dependencies. +``OPENSSL_LIBRARIES`` + All OpenSSL libraries and their dependencies. +``OPENSSL_VERSION`` + This is set to ``$major.$minor.$revision$patch`` (e.g. ``0.9.8s``). +``OPENSSL_APPLINK_SOURCE`` + The sources in the target ``OpenSSL::applink`` that is mentioned above. This + variable shall always be undefined if found openssl version is less than + 0.9.8 or if platform is not MSVC. + +Hints +^^^^^ + +Set ``OPENSSL_ROOT_DIR`` to the root directory of an OpenSSL installation. +Set ``OPENSSL_USE_STATIC_LIBS`` to ``TRUE`` to look for static libraries. +Set ``OPENSSL_MSVC_STATIC_RT`` set ``TRUE`` to choose the MT version of the lib. +#]=======================================================================] + +set(OPENSSL_EXPECTED_VERSION "1.0") + +macro(_OpenSSL_test_and_find_dependencies ssl_library crypto_library) + if((CMAKE_SYSTEM_NAME STREQUAL "Linux") AND + (("${ssl_library}" MATCHES "\\${CMAKE_STATIC_LIBRARY_SUFFIX}$") OR + ("${crypto_library}" MATCHES "\\${CMAKE_STATIC_LIBRARY_SUFFIX}$"))) + set(_OpenSSL_has_dependencies TRUE) + find_package(Threads) + else() + set(_OpenSSL_has_dependencies FALSE) + endif() +endmacro() + +function(_OpenSSL_add_dependencies libraries_var) + if(CMAKE_THREAD_LIBS_INIT) + list(APPEND ${libraries_var} ${CMAKE_THREAD_LIBS_INIT}) + endif() + list(APPEND ${libraries_var} ${CMAKE_DL_LIBS}) + set(${libraries_var} ${${libraries_var}} PARENT_SCOPE) +endfunction() + +function(_OpenSSL_target_add_dependencies target) + if(_OpenSSL_has_dependencies) + set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES Threads::Threads ) + set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${CMAKE_DL_LIBS} ) + endif() +endfunction() + +if (UNIX) + find_package(PkgConfig QUIET) + pkg_check_modules(_OPENSSL QUIET openssl) +endif () -FIND_PATH(OPENSSL_ROOT_DIR +# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES +if(OPENSSL_USE_STATIC_LIBS) + set(_openssl_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + if(WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .a ) + endif() +endif() + +if (WIN32) + # http://www.slproweb.com/products/Win32OpenSSL.html + set(_OPENSSL_MSI_INSTALL_GUID "") + if(PLATFORM EQUAL 64) + set(_OPENSSL_MSI_INSTALL_GUID "117551DB-A110-4BBD-BB05-CFE0BCB3ED31") + set(_OPENSSL_ROOT_HINTS + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;Inno Setup: App Path]" + ${OPENSSL_ROOT_DIR} + ENV OPENSSL_ROOT_DIR + ) + file(TO_CMAKE_PATH "$ENV{PROGRAMFILES}" _programfiles) + set(_OPENSSL_ROOT_PATHS + "${_programfiles}/OpenSSL" + "${_programfiles}/OpenSSL-Win64" + "C:/OpenSSL/" + "C:/OpenSSL-Win64/" + ) + else() + set(_OPENSSL_MSI_INSTALL_GUID "A1EEC576-43B9-4E75-9E02-03DA542D2A38") + set(_OPENSSL_ROOT_HINTS + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;Inno Setup: App Path]" + ${OPENSSL_ROOT_DIR} + ENV OPENSSL_ROOT_DIR + ) + file(TO_CMAKE_PATH "$ENV{PROGRAMFILES}" _programfiles) + set(_OPENSSL_ROOT_PATHS + "${_programfiles}/OpenSSL" + "${_programfiles}/OpenSSL-Win32" + "C:/OpenSSL/" + "C:/OpenSSL-Win32/" + ) + endif() + unset(_programfiles) + # If OpenSSL was installed using .msi package instead of .exe, Inno Setup registry values are not written to Uninstall\OpenSSL + # but because it is only a shim around Inno Setup it does write the location of uninstaller which we can use to determine path + get_filename_component(_OPENSSL_MSI_INSTALL_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Inno Setup MSIs\\${_OPENSSL_MSI_INSTALL_GUID};]" DIRECTORY) + if(NOT _OPENSSL_MSI_INSTALL_PATH STREQUAL "/") + list(INSERT _OPENSSL_ROOT_HINTS 0 ${_OPENSSL_MSI_INSTALL_PATH}) + endif() +else () + set(_OPENSSL_ROOT_HINTS + ${OPENSSL_ROOT_DIR} + ENV OPENSSL_ROOT_DIR + ) +endif () + +set(_OPENSSL_ROOT_HINTS_AND_PATHS + HINTS ${_OPENSSL_ROOT_HINTS} + PATHS ${_OPENSSL_ROOT_PATHS} + ) + +find_path(OPENSSL_INCLUDE_DIR NAMES - include/openssl/ssl.h + openssl/ssl.h + ${_OPENSSL_ROOT_HINTS_AND_PATHS} HINTS - ${_OPENSSL_ROOT_HINTS} - PATHS - ${_OPENSSL_ROOT_PATHS} -) -MARK_AS_ADVANCED(OPENSSL_ROOT_DIR) - -# Re-use the previous path: -FIND_PATH(OPENSSL_INCLUDE_DIR openssl/ssl.h - ${OPENSSL_ROOT_DIR}/include + ${_OPENSSL_INCLUDEDIR} + ${_OPENSSL_INCLUDE_DIRS} + PATH_SUFFIXES + include ) -IF(WIN32 AND NOT CYGWIN) - # MINGW should go here too - IF(MSVC) +if(WIN32 AND NOT CYGWIN) + if(MSVC) # /MD and /MDd are the standard values - if someone wants to use # others, the libnames have to change here too # use also ssl and ssleay32 in debug as fallback for openssl < 0.9.8b - # TODO: handle /MT and static lib + # enable OPENSSL_MSVC_STATIC_RT to get the libs build /MT (Multithreaded no-DLL) # In Visual C++ naming convention each of these four kinds of Windows libraries has it's standard suffix: # * MD for dynamic-release # * MDd for dynamic-debug @@ -77,119 +197,475 @@ IF(WIN32 AND NOT CYGWIN) # * MTd for static-debug # Implementation details: - # We are using the libraries located in the VC subdir instead of the parent directory eventhough : + # We are using the libraries located in the VC subdir instead of the parent directory even though : # libeay32MD.lib is identical to ../libeay32.lib, and # ssleay32MD.lib is identical to ../ssleay32.lib + # enable OPENSSL_USE_STATIC_LIBS to use the static libs located in lib/VC/static - # In 1.1 version of OpenSSL we have other names of libs: libcrypto32MTd.lib and libssl32MTd.lib + if (OPENSSL_MSVC_STATIC_RT) + set(_OPENSSL_MSVC_RT_MODE "MT") + else () + set(_OPENSSL_MSVC_RT_MODE "MD") + endif () + + # Since OpenSSL 1.1, lib names are like libcrypto32MTd.lib and libssl32MTd.lib if( "${CMAKE_SIZEOF_VOID_P}" STREQUAL "8" ) set(_OPENSSL_MSVC_ARCH_SUFFIX "64") else() set(_OPENSSL_MSVC_ARCH_SUFFIX "32") endif() - FIND_LIBRARY(LIB_EAY_DEBUG + if(OPENSSL_USE_STATIC_LIBS) + set(_OPENSSL_STATIC_SUFFIX + "_static" + ) + set(_OPENSSL_PATH_SUFFIXES + "lib/VC/static" + "VC/static" + "lib" + ) + else() + set(_OPENSSL_STATIC_SUFFIX + "" + ) + set(_OPENSSL_PATH_SUFFIXES + "lib/VC" + "VC" + "lib" + ) + endif () + + find_library(LIB_EAY_DEBUG NAMES - libcrypto${_OPENSSL_MSVC_ARCH_SUFFIX}MDd libcrypto libeay32MDd libeay32 - PATHS - ${OPENSSL_ROOT_DIR}/lib/VC - ${OPENSSL_ROOT_DIR}/debug/lib + # When OpenSSL is built with default options, the static library name is suffixed with "_static". + # Looking the "libcrypto_static.lib" with a higher priority than "libcrypto.lib" which is the + # import library of "libcrypto.dll". + libcrypto${_OPENSSL_STATIC_SUFFIX}${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE}d + libcrypto${_OPENSSL_STATIC_SUFFIX}${_OPENSSL_MSVC_RT_MODE}d + libcrypto${_OPENSSL_STATIC_SUFFIX}d + libeay32${_OPENSSL_STATIC_SUFFIX}${_OPENSSL_MSVC_RT_MODE}d + libeay32${_OPENSSL_STATIC_SUFFIX}d + crypto${_OPENSSL_STATIC_SUFFIX}d + # When OpenSSL is built with the "-static" option, only the static build is produced, + # and it is not suffixed with "_static". + libcrypto${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE}d + libcrypto${_OPENSSL_MSVC_RT_MODE}d + libcryptod + libeay32${_OPENSSL_MSVC_RT_MODE}d + libeay32d + cryptod + NAMES_PER_DIR + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + ${_OPENSSL_PATH_SUFFIXES} ) - FIND_LIBRARY(LIB_EAY_RELEASE + find_library(LIB_EAY_RELEASE NAMES - libcrypto${_OPENSSL_MSVC_ARCH_SUFFIX}MD libcrypto libeay32MD libeay32 - PATHS - ${OPENSSL_ROOT_DIR}/lib/VC - ${OPENSSL_ROOT_DIR}/lib + # When OpenSSL is built with default options, the static library name is suffixed with "_static". + # Looking the "libcrypto_static.lib" with a higher priority than "libcrypto.lib" which is the + # import library of "libcrypto.dll". + libcrypto${_OPENSSL_STATIC_SUFFIX}${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE} + libcrypto${_OPENSSL_STATIC_SUFFIX}${_OPENSSL_MSVC_RT_MODE} + libcrypto${_OPENSSL_STATIC_SUFFIX} + libeay32${_OPENSSL_STATIC_SUFFIX}${_OPENSSL_MSVC_RT_MODE} + libeay32${_OPENSSL_STATIC_SUFFIX} + crypto${_OPENSSL_STATIC_SUFFIX} + # When OpenSSL is built with the "-static" option, only the static build is produced, + # and it is not suffixed with "_static". + libcrypto${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE} + libcrypto${_OPENSSL_MSVC_RT_MODE} + libcrypto + libeay32${_OPENSSL_MSVC_RT_MODE} + libeay32 + crypto + NAMES_PER_DIR + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + ${_OPENSSL_PATH_SUFFIXES} ) - FIND_LIBRARY(SSL_EAY_DEBUG + find_library(SSL_EAY_DEBUG NAMES - libssl${_OPENSSL_MSVC_ARCH_SUFFIX}MDd libssl ssleay32MDd ssleay32 ssl - PATHS - ${OPENSSL_ROOT_DIR}/lib/VC - ${OPENSSL_ROOT_DIR}/debug/lib + # When OpenSSL is built with default options, the static library name is suffixed with "_static". + # Looking the "libssl_static.lib" with a higher priority than "libssl.lib" which is the + # import library of "libssl.dll". + libssl${_OPENSSL_STATIC_SUFFIX}${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE}d + libssl${_OPENSSL_STATIC_SUFFIX}${_OPENSSL_MSVC_RT_MODE}d + libssl${_OPENSSL_STATIC_SUFFIX}d + ssleay32${_OPENSSL_STATIC_SUFFIX}${_OPENSSL_MSVC_RT_MODE}d + ssleay32${_OPENSSL_STATIC_SUFFIX}d + ssl${_OPENSSL_STATIC_SUFFIX}d + # When OpenSSL is built with the "-static" option, only the static build is produced, + # and it is not suffixed with "_static". + libssl${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE}d + libssl${_OPENSSL_MSVC_RT_MODE}d + libssld + ssleay32${_OPENSSL_MSVC_RT_MODE}d + ssleay32d + ssld + NAMES_PER_DIR + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + ${_OPENSSL_PATH_SUFFIXES} ) - FIND_LIBRARY(SSL_EAY_RELEASE + find_library(SSL_EAY_RELEASE NAMES - libssl${_OPENSSL_MSVC_ARCH_SUFFIX}MD libssl ssleay32MD ssleay32 ssl - PATHS - ${OPENSSL_ROOT_DIR}/lib/VC - ${OPENSSL_ROOT_DIR}/lib + # When OpenSSL is built with default options, the static library name is suffixed with "_static". + # Looking the "libssl_static.lib" with a higher priority than "libssl.lib" which is the + # import library of "libssl.dll". + libssl${_OPENSSL_STATIC_SUFFIX}${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE} + libssl${_OPENSSL_STATIC_SUFFIX}${_OPENSSL_MSVC_RT_MODE} + libssl${_OPENSSL_STATIC_SUFFIX} + ssleay32${_OPENSSL_STATIC_SUFFIX}${_OPENSSL_MSVC_RT_MODE} + ssleay32${_OPENSSL_STATIC_SUFFIX} + ssl${_OPENSSL_STATIC_SUFFIX} + # When OpenSSL is built with the "-static" option, only the static build is produced, + # and it is not suffixed with "_static". + libssl${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE} + libssl${_OPENSSL_MSVC_RT_MODE} + libssl + ssleay32${_OPENSSL_MSVC_RT_MODE} + ssleay32 + ssl + NAMES_PER_DIR + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + ${_OPENSSL_PATH_SUFFIXES} ) - if( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE ) - set( OPENSSL_LIBRARIES - optimized ${SSL_EAY_RELEASE} ${LIB_EAY_RELEASE} - debug ${SSL_EAY_DEBUG} ${LIB_EAY_DEBUG} - ) - else() - set( OPENSSL_LIBRARIES - ${SSL_EAY_RELEASE} - ${LIB_EAY_RELEASE} - ) - endif() + set(LIB_EAY_LIBRARY_DEBUG "${LIB_EAY_DEBUG}") + set(LIB_EAY_LIBRARY_RELEASE "${LIB_EAY_RELEASE}") + set(SSL_EAY_LIBRARY_DEBUG "${SSL_EAY_DEBUG}") + set(SSL_EAY_LIBRARY_RELEASE "${SSL_EAY_RELEASE}") - MARK_AS_ADVANCED(SSL_EAY_DEBUG SSL_EAY_RELEASE LIB_EAY_DEBUG LIB_EAY_RELEASE) - ELSEIF(MINGW) + include(SelectLibraryConfigurations) + select_library_configurations(LIB_EAY) + select_library_configurations(SSL_EAY) - # same player, for MingW - FIND_LIBRARY(LIB_EAY + mark_as_advanced(LIB_EAY_LIBRARY_DEBUG LIB_EAY_LIBRARY_RELEASE + SSL_EAY_LIBRARY_DEBUG SSL_EAY_LIBRARY_RELEASE) + set(OPENSSL_SSL_LIBRARY ${SSL_EAY_LIBRARY} ) + set(OPENSSL_CRYPTO_LIBRARY ${LIB_EAY_LIBRARY} ) + elseif(MINGW) + # same player, for MinGW + set(LIB_EAY_NAMES crypto libeay32) + set(SSL_EAY_NAMES ssl ssleay32) + find_library(LIB_EAY NAMES - libeay32 - PATHS - ${OPENSSL_ROOT_DIR}/lib/MinGW + ${LIB_EAY_NAMES} + NAMES_PER_DIR + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + "lib/MinGW" + "lib" ) - FIND_LIBRARY(SSL_EAY NAMES + find_library(SSL_EAY NAMES - ssleay32 - PATHS - ${OPENSSL_ROOT_DIR}/lib/MinGW + ${SSL_EAY_NAMES} + NAMES_PER_DIR + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + "lib/MinGW" + "lib" ) - MARK_AS_ADVANCED(SSL_EAY LIB_EAY) - - set( OPENSSL_LIBRARIES - ${SSL_EAY} - ${LIB_EAY} - ) - ELSE(MSVC) + mark_as_advanced(SSL_EAY LIB_EAY) + set(OPENSSL_SSL_LIBRARY ${SSL_EAY} ) + set(OPENSSL_CRYPTO_LIBRARY ${LIB_EAY} ) + unset(LIB_EAY_NAMES) + unset(SSL_EAY_NAMES) + else() # Not sure what to pick for -say- intel, let's use the toplevel ones and hope someone report issues: - FIND_LIBRARY(LIB_EAY + find_library(LIB_EAY NAMES + libcrypto libeay32 - PATHS - ${OPENSSL_ROOT_DIR}/lib - ${OPENSSL_ROOT_DIR}/lib/VC + NAMES_PER_DIR + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + HINTS + ${_OPENSSL_LIBDIR} + PATH_SUFFIXES + lib ) - FIND_LIBRARY(SSL_EAY + find_library(SSL_EAY NAMES + libssl ssleay32 - PATHS - ${OPENSSL_ROOT_DIR}/lib - ${OPENSSL_ROOT_DIR}/lib/VC + NAMES_PER_DIR + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + HINTS + ${_OPENSSL_LIBDIR} + PATH_SUFFIXES + lib ) - MARK_AS_ADVANCED(SSL_EAY LIB_EAY) - SET( OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} ) - ENDIF(MSVC) -ELSE(WIN32 AND NOT CYGWIN) - FIND_LIBRARY(OPENSSL_SSL_LIBRARIES NAMES ssl ssleay32 ssleay32MD) - FIND_LIBRARY(OPENSSL_CRYPTO_LIBRARIES NAMES crypto) - MARK_AS_ADVANCED(OPENSSL_CRYPTO_LIBRARIES OPENSSL_SSL_LIBRARIES) + mark_as_advanced(SSL_EAY LIB_EAY) + set(OPENSSL_SSL_LIBRARY ${SSL_EAY} ) + set(OPENSSL_CRYPTO_LIBRARY ${LIB_EAY} ) + endif() +else() + + find_library(OPENSSL_SSL_LIBRARY + NAMES + ssl + ssleay32 + ssleay32MD + NAMES_PER_DIR + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + HINTS + ${_OPENSSL_LIBDIR} + ${_OPENSSL_LIBRARY_DIRS} + PATH_SUFFIXES + lib + ) + + find_library(OPENSSL_CRYPTO_LIBRARY + NAMES + crypto + NAMES_PER_DIR + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + HINTS + ${_OPENSSL_LIBDIR} + ${_OPENSSL_LIBRARY_DIRS} + PATH_SUFFIXES + lib + ) + + mark_as_advanced(OPENSSL_CRYPTO_LIBRARY OPENSSL_SSL_LIBRARY) - SET(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARIES}) +endif() -ENDIF(WIN32 AND NOT CYGWIN) +set(OPENSSL_SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY}) +set(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY}) +set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARIES} ) +_OpenSSL_test_and_find_dependencies("${OPENSSL_SSL_LIBRARY}" "${OPENSSL_CRYPTO_LIBRARY}") +if(_OpenSSL_has_dependencies) + _OpenSSL_add_dependencies( OPENSSL_SSL_LIBRARIES ) + _OpenSSL_add_dependencies( OPENSSL_CRYPTO_LIBRARIES ) + _OpenSSL_add_dependencies( OPENSSL_LIBRARIES ) +endif() + +function(from_hex HEX DEC) + string(TOUPPER "${HEX}" HEX) + set(_res 0) + string(LENGTH "${HEX}" _strlen) + + while (_strlen GREATER 0) + math(EXPR _res "${_res} * 16") + string(SUBSTRING "${HEX}" 0 1 NIBBLE) + string(SUBSTRING "${HEX}" 1 -1 HEX) + if (NIBBLE STREQUAL "A") + math(EXPR _res "${_res} + 10") + elseif (NIBBLE STREQUAL "B") + math(EXPR _res "${_res} + 11") + elseif (NIBBLE STREQUAL "C") + math(EXPR _res "${_res} + 12") + elseif (NIBBLE STREQUAL "D") + math(EXPR _res "${_res} + 13") + elseif (NIBBLE STREQUAL "E") + math(EXPR _res "${_res} + 14") + elseif (NIBBLE STREQUAL "F") + math(EXPR _res "${_res} + 15") + else() + math(EXPR _res "${_res} + ${NIBBLE}") + endif() + + string(LENGTH "${HEX}" _strlen) + endwhile() + + set(${DEC} ${_res} PARENT_SCOPE) +endfunction() + +if(OPENSSL_INCLUDE_DIR AND EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h") + file(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h" openssl_version_str + REGEX "^#[\t ]*define[\t ]+OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])+.*") + + if(openssl_version_str) + # The version number is encoded as 0xMNNFFPPS: major minor fix patch status + # The status gives if this is a developer or prerelease and is ignored here. + # Major, minor, and fix directly translate into the version numbers shown in + # the string. The patch field translates to the single character suffix that + # indicates the bug fix state, which 00 -> nothing, 01 -> a, 02 -> b and so + # on. + + string(REGEX REPLACE "^.*OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F]).*$" + "\\1;\\2;\\3;\\4;\\5" OPENSSL_VERSION_LIST "${openssl_version_str}") + list(GET OPENSSL_VERSION_LIST 0 OPENSSL_VERSION_MAJOR) + list(GET OPENSSL_VERSION_LIST 1 OPENSSL_VERSION_MINOR) + from_hex("${OPENSSL_VERSION_MINOR}" OPENSSL_VERSION_MINOR) + list(GET OPENSSL_VERSION_LIST 2 OPENSSL_VERSION_FIX) + from_hex("${OPENSSL_VERSION_FIX}" OPENSSL_VERSION_FIX) + list(GET OPENSSL_VERSION_LIST 3 OPENSSL_VERSION_PATCH) + + if (NOT OPENSSL_VERSION_PATCH STREQUAL "00") + from_hex("${OPENSSL_VERSION_PATCH}" _tmp) + # 96 is the ASCII code of 'a' minus 1 + math(EXPR OPENSSL_VERSION_PATCH_ASCII "${_tmp} + 96") + unset(_tmp) + # Once anyone knows how OpenSSL would call the patch versions beyond 'z' + # this should be updated to handle that, too. This has not happened yet + # so it is simply ignored here for now. + string(ASCII "${OPENSSL_VERSION_PATCH_ASCII}" OPENSSL_VERSION_PATCH_STRING) + endif () + + set(OPENSSL_VERSION "${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MINOR}.${OPENSSL_VERSION_FIX}${OPENSSL_VERSION_PATCH_STRING}") + else () + # Since OpenSSL 3.0.0, the new version format is MAJOR.MINOR.PATCH and + # a new OPENSSL_VERSION_STR macro contains exactly that + file(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h" OPENSSL_VERSION_STR + REGEX "^#[\t ]*define[\t ]+OPENSSL_VERSION_STR[\t ]+\"([0-9])+\\.([0-9])+\\.([0-9])+\".*") + string(REGEX REPLACE "^.*OPENSSL_VERSION_STR[\t ]+\"([0-9]+\\.[0-9]+\\.[0-9]+)\".*$" + "\\1" OPENSSL_VERSION_STR "${OPENSSL_VERSION_STR}") + + set(OPENSSL_VERSION "${OPENSSL_VERSION_STR}") + + unset(OPENSSL_VERSION_STR) + endif () +endif () + +foreach(_comp IN LISTS OpenSSL_FIND_COMPONENTS) + if(_comp STREQUAL "Crypto") + if(EXISTS "${OPENSSL_INCLUDE_DIR}" AND + (EXISTS "${OPENSSL_CRYPTO_LIBRARY}" OR + EXISTS "${LIB_EAY_LIBRARY_DEBUG}" OR + EXISTS "${LIB_EAY_LIBRARY_RELEASE}") + ) + set(OpenSSL_${_comp}_FOUND TRUE) + else() + set(OpenSSL_${_comp}_FOUND FALSE) + endif() + elseif(_comp STREQUAL "SSL") + if(EXISTS "${OPENSSL_INCLUDE_DIR}" AND + (EXISTS "${OPENSSL_SSL_LIBRARY}" OR + EXISTS "${SSL_EAY_LIBRARY_DEBUG}" OR + EXISTS "${SSL_EAY_LIBRARY_RELEASE}") + ) + set(OpenSSL_${_comp}_FOUND TRUE) + else() + set(OpenSSL_${_comp}_FOUND FALSE) + endif() + else() + message(WARNING "${_comp} is not a valid OpenSSL component") + set(OpenSSL_${_comp}_FOUND FALSE) + endif() +endforeach() +unset(_comp) include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(OpenSSL DEFAULT_MSG - OPENSSL_LIBRARIES - OPENSSL_INCLUDE_DIR +find_package_handle_standard_args(OpenSSL + REQUIRED_VARS + OPENSSL_CRYPTO_LIBRARY + OPENSSL_INCLUDE_DIR + VERSION_VAR + OPENSSL_VERSION + HANDLE_COMPONENTS + FAIL_MESSAGE + "Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR" ) -MARK_AS_ADVANCED(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES) +mark_as_advanced(OPENSSL_INCLUDE_DIR) + +if(OPENSSL_FOUND) + message(STATUS "Found OpenSSL library: ${OPENSSL_LIBRARIES}") + message(STATUS "Found OpenSSL headers: ${OPENSSL_INCLUDE_DIR}") + include(EnsureVersion) + ENSURE_VERSION("${OPENSSL_EXPECTED_VERSION}" "${OPENSSL_VERSION}" OPENSSL_VERSION_OK) + if(NOT OPENSSL_VERSION_OK) + message(FATAL_ERROR "TrinityCore needs OpenSSL version ${OPENSSL_EXPECTED_VERSION} but found too new version ${OPENSSL_VERSION}. TrinityCore needs OpenSSL 1.0.x or 1.1.x to work properly. If you still have problems please install OpenSSL 1.0.x if you still have problems search on forum for TCE00022") + endif() + + if(NOT TARGET OpenSSL::Crypto AND + (EXISTS "${OPENSSL_CRYPTO_LIBRARY}" OR + EXISTS "${LIB_EAY_LIBRARY_DEBUG}" OR + EXISTS "${LIB_EAY_LIBRARY_RELEASE}") + ) + add_library(OpenSSL::Crypto UNKNOWN IMPORTED) + set_target_properties(OpenSSL::Crypto PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${OPENSSL_INCLUDE_DIR}") + if(EXISTS "${OPENSSL_CRYPTO_LIBRARY}") + set_target_properties(OpenSSL::Crypto PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${OPENSSL_CRYPTO_LIBRARY}") + endif() + if(EXISTS "${LIB_EAY_LIBRARY_RELEASE}") + set_property(TARGET OpenSSL::Crypto APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(OpenSSL::Crypto PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" + IMPORTED_LOCATION_RELEASE "${LIB_EAY_LIBRARY_RELEASE}") + endif() + if(EXISTS "${LIB_EAY_LIBRARY_DEBUG}") + set_property(TARGET OpenSSL::Crypto APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(OpenSSL::Crypto PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" + IMPORTED_LOCATION_DEBUG "${LIB_EAY_LIBRARY_DEBUG}") + endif() + _OpenSSL_target_add_dependencies(OpenSSL::Crypto) + endif() + + if(NOT TARGET OpenSSL::SSL AND + (EXISTS "${OPENSSL_SSL_LIBRARY}" OR + EXISTS "${SSL_EAY_LIBRARY_DEBUG}" OR + EXISTS "${SSL_EAY_LIBRARY_RELEASE}") + ) + add_library(OpenSSL::SSL UNKNOWN IMPORTED) + set_target_properties(OpenSSL::SSL PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${OPENSSL_INCLUDE_DIR}") + if(EXISTS "${OPENSSL_SSL_LIBRARY}") + set_target_properties(OpenSSL::SSL PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${OPENSSL_SSL_LIBRARY}") + endif() + if(EXISTS "${SSL_EAY_LIBRARY_RELEASE}") + set_property(TARGET OpenSSL::SSL APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(OpenSSL::SSL PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" + IMPORTED_LOCATION_RELEASE "${SSL_EAY_LIBRARY_RELEASE}") + endif() + if(EXISTS "${SSL_EAY_LIBRARY_DEBUG}") + set_property(TARGET OpenSSL::SSL APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(OpenSSL::SSL PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" + IMPORTED_LOCATION_DEBUG "${SSL_EAY_LIBRARY_DEBUG}") + endif() + if(TARGET OpenSSL::Crypto) + set_target_properties(OpenSSL::SSL PROPERTIES + INTERFACE_LINK_LIBRARIES OpenSSL::Crypto) + endif() + _OpenSSL_target_add_dependencies(OpenSSL::SSL) + endif() + + if("${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_FIX}" VERSION_GREATER_EQUAL "0.9.8") + if(MSVC) + if(EXISTS "${OPENSSL_INCLUDE_DIR}") + set(_OPENSSL_applink_paths PATHS ${OPENSSL_INCLUDE_DIR}) + endif() + find_file(OPENSSL_APPLINK_SOURCE + NAMES + openssl/applink.c + ${_OPENSSL_applink_paths} + NO_DEFAULT_PATH) + if(OPENSSL_APPLINK_SOURCE) + set(_OPENSSL_applink_interface_srcs ${OPENSSL_APPLINK_SOURCE}) + endif() + endif() + if(NOT TARGET OpenSSL::applink) + add_library(OpenSSL::applink INTERFACE IMPORTED) + set_property(TARGET OpenSSL::applink APPEND + PROPERTY INTERFACE_SOURCES + ${_OPENSSL_applink_interface_srcs}) + endif() + endif() +endif() + +# Restore the original find library ordering +if(OPENSSL_USE_STATIC_LIBS) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${_openssl_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) +endif() diff --git a/src/common/Cryptography/AES.cpp b/src/common/Cryptography/AES.cpp index 3087af2e23..31e0847005 100644 --- a/src/common/Cryptography/AES.cpp +++ b/src/common/Cryptography/AES.cpp @@ -1,6 +1,18 @@ /* - * Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 - * Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore> + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "AES.h" @@ -30,34 +42,24 @@ bool Acore::Crypto::AES::Process(IV const& iv, uint8* data, size_t length, Tag& ASSERT(length <= static_cast<size_t>(std::numeric_limits<int>::max())); int len = static_cast<int>(length); if (!EVP_CipherInit_ex(_ctx, nullptr, nullptr, nullptr, iv.data(), -1)) - { return false; - } int outLen; if (!EVP_CipherUpdate(_ctx, data, &outLen, data, len)) - { return false; - } len -= outLen; if (!_encrypting && !EVP_CIPHER_CTX_ctrl(_ctx, EVP_CTRL_GCM_SET_TAG, sizeof(tag), tag)) - { return false; - } if (!EVP_CipherFinal_ex(_ctx, data + outLen, &outLen)) - { return false; - } ASSERT(len == outLen); if (_encrypting && !EVP_CIPHER_CTX_ctrl(_ctx, EVP_CTRL_GCM_GET_TAG, sizeof(tag), tag)) - { return false; - } return true; } diff --git a/src/common/Cryptography/AES.h b/src/common/Cryptography/AES.h index 1c0466aa77..c73aeebea2 100644 --- a/src/common/Cryptography/AES.h +++ b/src/common/Cryptography/AES.h @@ -1,10 +1,22 @@ /* - * Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 - * Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore> + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef Warhead_AES_h__ -#define Warhead_AES_h__ +#ifndef Azeroth_AES_h__ +#define Azeroth_AES_h__ #include "Define.h" #include <array> @@ -36,4 +48,4 @@ namespace Acore::Crypto }; } -#endif // Warhead_AES_h__ +#endif // Azeroth_AES_h__ diff --git a/src/common/Cryptography/ARC4.cpp b/src/common/Cryptography/ARC4.cpp index 4356deae01..90535f7477 100644 --- a/src/common/Cryptography/ARC4.cpp +++ b/src/common/Cryptography/ARC4.cpp @@ -18,17 +18,26 @@ #include "ARC4.h" #include "Errors.h" -Acore::Crypto::ARC4::ARC4() - : _ctx(EVP_CIPHER_CTX_new()) +Acore::Crypto::ARC4::ARC4() : _ctx(EVP_CIPHER_CTX_new()) { +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + _cipher = EVP_CIPHER_fetch(nullptr, "RC4", nullptr); +#else + EVP_CIPHER const* _cipher = EVP_rc4(); +#endif + EVP_CIPHER_CTX_init(_ctx); - int result = EVP_EncryptInit_ex(_ctx, EVP_rc4(), nullptr, nullptr, nullptr); + int result = EVP_EncryptInit_ex(_ctx, _cipher, nullptr, nullptr, nullptr); ASSERT(result == 1); } Acore::Crypto::ARC4::~ARC4() { EVP_CIPHER_CTX_free(_ctx); + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_CIPHER_free(_cipher); +#endif } void Acore::Crypto::ARC4::Init(uint8 const* seed, size_t len) diff --git a/src/common/Cryptography/ARC4.h b/src/common/Cryptography/ARC4.h index eb20966279..f598589a29 100644 --- a/src/common/Cryptography/ARC4.h +++ b/src/common/Cryptography/ARC4.h @@ -24,20 +24,25 @@ namespace Acore::Crypto { - class ARC4 + class AC_COMMON_API ARC4 { public: ARC4(); ~ARC4(); void Init(uint8 const* seed, size_t len); + template <typename Container> void Init(Container const& c) { Init(std::data(c), std::size(c)); } void UpdateData(uint8* data, size_t len); + template <typename Container> void UpdateData(Container& c) { UpdateData(std::data(c), std::size(c)); } private: +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_CIPHER* _cipher; +#endif EVP_CIPHER_CTX* _ctx; }; } diff --git a/src/common/Cryptography/Argon2.cpp b/src/common/Cryptography/Argon2.cpp index 3d839646ae..ead8449cbf 100644 --- a/src/common/Cryptography/Argon2.cpp +++ b/src/common/Cryptography/Argon2.cpp @@ -1,6 +1,18 @@ /* - * Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 - * Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore> + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "Argon2.h" @@ -20,9 +32,7 @@ ); if (status == ARGON2_OK) - { return std::string(buf); - } return {}; } diff --git a/src/common/Cryptography/Argon2.h b/src/common/Cryptography/Argon2.h index 4a3bcf2398..b2f3ed968e 100644 --- a/src/common/Cryptography/Argon2.h +++ b/src/common/Cryptography/Argon2.h @@ -1,15 +1,25 @@ /* - * Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 - * Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore> + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef WARHEAD_ARGON2_H -#define WARHEAD_ARGON2_H +#ifndef AC_ARGON2_H +#define AC_ARGON2_H #include "BigNumber.h" -#include "Define.h" #include "Optional.h" -#include <string> namespace Acore::Crypto { diff --git a/src/common/Cryptography/Authentication/AuthCrypt.cpp b/src/common/Cryptography/Authentication/AuthCrypt.cpp index 791c7bcf65..21115ed155 100644 --- a/src/common/Cryptography/Authentication/AuthCrypt.cpp +++ b/src/common/Cryptography/Authentication/AuthCrypt.cpp @@ -19,19 +19,16 @@ #include "Errors.h" #include "HMAC.h" -AuthCrypt::AuthCrypt() : _initialized(false) -{ -} - void AuthCrypt::Init(SessionKey const& K) { uint8 ServerEncryptionKey[] = { 0xCC, 0x98, 0xAE, 0x04, 0xE8, 0x97, 0xEA, 0xCA, 0x12, 0xDD, 0xC0, 0x93, 0x42, 0x91, 0x53, 0x57 }; _serverEncrypt.Init(Acore::Crypto::HMAC_SHA1::GetDigestOf(ServerEncryptionKey, K)); + uint8 ServerDecryptionKey[] = { 0xC2, 0xB3, 0x72, 0x3C, 0xC6, 0xAE, 0xD9, 0xB5, 0x34, 0x3C, 0x53, 0xEE, 0x2F, 0x43, 0x67, 0xCE }; _clientDecrypt.Init(Acore::Crypto::HMAC_SHA1::GetDigestOf(ServerDecryptionKey, K)); // Drop first 1024 bytes, as WoW uses ARC4-drop1024. - std::array<uint8, 1024> syncBuf; + std::array<uint8, 1024> syncBuf{}; _serverEncrypt.UpdateData(syncBuf); _clientDecrypt.UpdateData(syncBuf); diff --git a/src/common/Cryptography/Authentication/AuthCrypt.h b/src/common/Cryptography/Authentication/AuthCrypt.h index c89079ddb4..88239a9e36 100644 --- a/src/common/Cryptography/Authentication/AuthCrypt.h +++ b/src/common/Cryptography/Authentication/AuthCrypt.h @@ -20,12 +20,11 @@ #include "ARC4.h" #include "AuthDefines.h" -#include <array> -class AuthCrypt +class AC_COMMON_API AuthCrypt { public: - AuthCrypt(); + AuthCrypt() = default; void Init(SessionKey const& K); void DecryptRecv(uint8* data, size_t len); @@ -36,6 +35,6 @@ public: private: Acore::Crypto::ARC4 _clientDecrypt; Acore::Crypto::ARC4 _serverEncrypt; - bool _initialized; + bool _initialized{ false }; }; #endif diff --git a/src/common/Cryptography/Authentication/SRP6.cpp b/src/common/Cryptography/Authentication/SRP6.cpp index 0e77c2326e..20e05f5b2b 100644 --- a/src/common/Cryptography/Authentication/SRP6.cpp +++ b/src/common/Cryptography/Authentication/SRP6.cpp @@ -50,8 +50,8 @@ using SRP6 = Acore::Crypto::SRP6; /*static*/ SessionKey SRP6::SHA1Interleave(SRP6::EphemeralKey const& S) { // split S into two buffers - std::array<uint8, EPHEMERAL_KEY_LENGTH/2> buf0, buf1; - for (size_t i = 0; i < EPHEMERAL_KEY_LENGTH/2; ++i) + std::array<uint8, EPHEMERAL_KEY_LENGTH / 2> buf0{}, buf1{}; + for (size_t i = 0; i < EPHEMERAL_KEY_LENGTH / 2; ++i) { buf0[i] = S[2 * i + 0]; buf1[i] = S[2 * i + 1]; @@ -59,8 +59,12 @@ using SRP6 = Acore::Crypto::SRP6; // find position of first nonzero byte size_t p = 0; - while (p < EPHEMERAL_KEY_LENGTH && !S[p]) { ++p; } - if (p & 1) { ++p; } // skip one extra byte if p is odd + while (p < EPHEMERAL_KEY_LENGTH && !S[p]) + ++p; + + if (p & 1) + ++p; // skip one extra byte if p is odd + p /= 2; // offset into buffers // hash each of the halves, starting at the first nonzero byte @@ -82,14 +86,12 @@ SRP6::SRP6(std::string const& username, Salt const& salt, Verifier const& verifi std::optional<SessionKey> SRP6::VerifyChallengeResponse(EphemeralKey const& A, SHA1::Digest const& clientM) { - ASSERT(!_used); + ASSERT(!_used, "A single SRP6 object must only ever be used to verify ONCE!"); _used = true; BigNumber const _A(A); if ((_A % _N).IsZero()) - { return std::nullopt; - } BigNumber const u(SHA1::GetDigestOf(A, B)); EphemeralKey const S = (_A * (_v.ModExp(u, _N))).ModExp(_b, N).ToByteArray<32>(); @@ -104,11 +106,7 @@ std::optional<SessionKey> SRP6::VerifyChallengeResponse(EphemeralKey const& A, S SHA1::Digest const ourM = SHA1::GetDigestOf(NgHash, _I, s, A, B, K); if (ourM == clientM) - { return K; - } - else - { - return std::nullopt; - } + + return std::nullopt; } diff --git a/src/common/Cryptography/Authentication/SRP6.h b/src/common/Cryptography/Authentication/SRP6.h index 49f7ce6de0..734ef12980 100644 --- a/src/common/Cryptography/Authentication/SRP6.h +++ b/src/common/Cryptography/Authentication/SRP6.h @@ -20,21 +20,20 @@ #include "AuthDefines.h" #include "BigNumber.h" -#include "Common.h" #include "CryptoHash.h" -#include "Define.h" -#include <array> #include <optional> namespace Acore::Crypto { - class SRP6 + class AC_COMMON_API SRP6 { public: static constexpr size_t SALT_LENGTH = 32; using Salt = std::array<uint8, SALT_LENGTH>; + static constexpr size_t VERIFIER_LENGTH = 32; using Verifier = std::array<uint8, VERIFIER_LENGTH>; + static constexpr size_t EPHEMERAL_KEY_LENGTH = 32; using EphemeralKey = std::array<uint8, EPHEMERAL_KEY_LENGTH>; @@ -43,6 +42,7 @@ namespace Acore::Crypto // username + password must be passed through Utf8ToUpperOnlyLatin FIRST! static std::pair<Salt, Verifier> MakeRegistrationData(std::string const& username, std::string const& password); + // username + password must be passed through Utf8ToUpperOnlyLatin FIRST! static bool CheckLogin(std::string const& username, std::string const& password, Salt const& salt, Verifier const& verifier) { diff --git a/src/common/Cryptography/BigNumber.cpp b/src/common/Cryptography/BigNumber.cpp index d557b85141..1cd8d6a199 100644 --- a/src/common/Cryptography/BigNumber.cpp +++ b/src/common/Cryptography/BigNumber.cpp @@ -1,11 +1,25 @@ /* - * Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version. - * Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore> + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Cryptography/BigNumber.h" +#include "BigNumber.h" #include "Errors.h" #include <algorithm> +#include <cstring> +#include <memory> #include <openssl/bn.h> BigNumber::BigNumber() @@ -25,9 +39,7 @@ void BigNumber::SetDword(int32 val) { SetDword(uint32(std::abs(val))); if (val < 0) - { BN_set_negative(_bn, 1); - } } void BigNumber::SetDword(uint32 val) @@ -50,9 +62,7 @@ void BigNumber::SetBinary(uint8 const* bytes, int32 len, bool littleEndian) uint8* array = new uint8[len]; for (int i = 0; i < len; i++) - { array[i] = bytes[len - 1 - i]; - } BN_bin2bn(array, len, _bn); @@ -62,9 +72,7 @@ void BigNumber::SetBinary(uint8 const* bytes, int32 len, bool littleEndian) #endif } else - { BN_bin2bn(bytes, len, _bn); - } } bool BigNumber::SetHexStr(char const* str) @@ -81,9 +89,7 @@ void BigNumber::SetRand(int32 numbits) BigNumber& BigNumber::operator=(BigNumber const& bn) { if (this == &bn) - { return *this; - } BN_copy(_bn, bn._bn); return *this; @@ -103,7 +109,7 @@ BigNumber& BigNumber::operator-=(BigNumber const& bn) BigNumber& BigNumber::operator*=(BigNumber const& bn) { - BN_CTX* bnctx; + BN_CTX *bnctx; bnctx = BN_CTX_new(); BN_mul(_bn, _bn, bn._bn, bnctx); @@ -114,7 +120,7 @@ BigNumber& BigNumber::operator*=(BigNumber const& bn) BigNumber& BigNumber::operator/=(BigNumber const& bn) { - BN_CTX* bnctx; + BN_CTX *bnctx; bnctx = BN_CTX_new(); BN_div(_bn, nullptr, _bn, bn._bn, bnctx); @@ -125,7 +131,7 @@ BigNumber& BigNumber::operator/=(BigNumber const& bn) BigNumber& BigNumber::operator%=(BigNumber const& bn) { - BN_CTX* bnctx; + BN_CTX *bnctx; bnctx = BN_CTX_new(); BN_mod(_bn, _bn, bn._bn, bnctx); @@ -148,7 +154,7 @@ int BigNumber::CompareTo(BigNumber const& bn) const BigNumber BigNumber::Exp(BigNumber const& bn) const { BigNumber ret; - BN_CTX* bnctx; + BN_CTX *bnctx; bnctx = BN_CTX_new(); BN_exp(ret._bn, _bn, bn._bn, bnctx); @@ -160,7 +166,7 @@ BigNumber BigNumber::Exp(BigNumber const& bn) const BigNumber BigNumber::ModExp(BigNumber const& bn1, BigNumber const& bn2) const { BigNumber ret; - BN_CTX* bnctx; + BN_CTX *bnctx; bnctx = BN_CTX_new(); BN_mod_exp(ret._bn, _bn, bn1._bn, bn2._bn, bnctx); @@ -201,17 +207,13 @@ void BigNumber::GetBytes(uint8* buf, size_t bufsize, bool littleEndian) const // If we need more bytes than length of BigNumber set the rest to 0 if (numBytes < bufsize) - { memset((void*)buf, 0, bufsize); - } BN_bn2bin(_bn, buf + (bufsize - numBytes)); // openssl's BN stores data internally in big endian format, reverse if little endian desired if (littleEndian) - { std::reverse(buf, buf + bufsize); - } #else int res = littleEndian ? BN_bn2lebinpad(_bn, buf, bufsize) : BN_bn2binpad(_bn, buf, bufsize); ASSERT(res > 0, "Buffer of size {} is too small to hold bignum with {} bytes.\n", bufsize, BN_num_bytes(_bn)); diff --git a/src/common/Cryptography/BigNumber.h b/src/common/Cryptography/BigNumber.h index d53eb6bacf..259fa92ed2 100644 --- a/src/common/Cryptography/BigNumber.h +++ b/src/common/Cryptography/BigNumber.h @@ -1,6 +1,18 @@ /* - * Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version. - * Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore> + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifndef _AUTH_BIGNUMBER_H @@ -8,7 +20,6 @@ #include "Define.h" #include <array> -#include <memory> #include <string> #include <vector> diff --git a/src/common/Cryptography/CryptoConstants.h b/src/common/Cryptography/CryptoConstants.h index 7ec74483bb..3ba8b55d6a 100644 --- a/src/common/Cryptography/CryptoConstants.h +++ b/src/common/Cryptography/CryptoConstants.h @@ -24,7 +24,8 @@ namespace Acore::Crypto { struct Constants { - static constexpr size_t SHA1_DIGEST_LENGTH_BYTES = 20; + static constexpr size_t MD5_DIGEST_LENGTH_BYTES = 16; + static constexpr size_t SHA1_DIGEST_LENGTH_BYTES = 20; static constexpr size_t SHA256_DIGEST_LENGTH_BYTES = 32; }; } diff --git a/src/common/Cryptography/CryptoGenerics.h b/src/common/Cryptography/CryptoGenerics.h index 4d65699da6..d4b799747c 100644 --- a/src/common/Cryptography/CryptoGenerics.h +++ b/src/common/Cryptography/CryptoGenerics.h @@ -89,6 +89,7 @@ namespace Acore::Crypto { using IV = typename Cipher::IV; using Tag = typename Cipher::Tag; + // extract trailing IV and tag IV iv; Tag tag; diff --git a/src/common/Cryptography/CryptoHash.h b/src/common/Cryptography/CryptoHash.h index e2f38da8d8..1763351bc7 100644 --- a/src/common/Cryptography/CryptoHash.h +++ b/src/common/Cryptography/CryptoHash.h @@ -19,12 +19,12 @@ #define AZEROTHCORE_CRYPTOHASH_H #include "CryptoConstants.h" -#include "Define.h" #include "Errors.h" #include <array> #include <openssl/evp.h> #include <string> #include <string_view> +#include <utility> class BigNumber; @@ -35,10 +35,10 @@ namespace Acore::Impl typedef EVP_MD const* (*HashCreator)(); #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L - static EVP_MD_CTX* MakeCTX() { return EVP_MD_CTX_create(); } + static EVP_MD_CTX* MakeCTX() noexcept { return EVP_MD_CTX_create(); } static void DestroyCTX(EVP_MD_CTX* ctx) { EVP_MD_CTX_destroy(ctx); } #else - static EVP_MD_CTX* MakeCTX() { return EVP_MD_CTX_new(); } + static EVP_MD_CTX* MakeCTX() noexcept { return EVP_MD_CTX_new(); } static void DestroyCTX(EVP_MD_CTX* ctx) { EVP_MD_CTX_free(ctx); } #endif }; @@ -46,74 +46,104 @@ namespace Acore::Impl template <GenericHashImpl::HashCreator HashCreator, size_t DigestLength> class GenericHash { - public: - static constexpr size_t DIGEST_LENGTH = DigestLength; - using Digest = std::array<uint8, DIGEST_LENGTH>; - - static Digest GetDigestOf(uint8 const* data, size_t len) - { - GenericHash hash; - hash.UpdateData(data, len); - hash.Finalize(); - return hash.GetDigest(); - } - - template <typename... Ts> - static auto GetDigestOf(Ts&& ... pack) -> std::enable_if_t < !(std::is_integral_v<std::decay_t<Ts>> || ...), Digest > - { - GenericHash hash; - (hash.UpdateData(std::forward<Ts>(pack)), ...); - hash.Finalize(); - return hash.GetDigest(); - } - - GenericHash() : _ctx(GenericHashImpl::MakeCTX()) - { - int result = EVP_DigestInit_ex(_ctx, HashCreator(), nullptr); - ASSERT(result == 1); - } - - ~GenericHash() - { - if (!_ctx) + public: + static constexpr size_t DIGEST_LENGTH = DigestLength; + using Digest = std::array<uint8, DIGEST_LENGTH>; + + static Digest GetDigestOf(uint8 const* data, size_t len) + { + GenericHash hash; + hash.UpdateData(data, len); + hash.Finalize(); + return hash.GetDigest(); + } + + template <typename... Ts> + static auto GetDigestOf(Ts&&... pack) -> std::enable_if_t<!(std::is_integral_v<std::decay_t<Ts>> || ...), Digest> + { + GenericHash hash; + (hash.UpdateData(std::forward<Ts>(pack)), ...); + hash.Finalize(); + return hash.GetDigest(); + } + + GenericHash() : _ctx(GenericHashImpl::MakeCTX()) + { + int result = EVP_DigestInit_ex(_ctx, HashCreator(), nullptr); + ASSERT(result == 1); + } + + GenericHash(GenericHash const& right) : _ctx(GenericHashImpl::MakeCTX()) + { + *this = right; + } + + GenericHash(GenericHash&& right) noexcept + { + *this = std::move(right); + } + + ~GenericHash() + { + if (!_ctx) + return; + GenericHashImpl::DestroyCTX(_ctx); + _ctx = nullptr; + } + + GenericHash& operator=(GenericHash const& right) { - return; + if (this == &right) + return *this; + + int result = EVP_MD_CTX_copy_ex(_ctx, right._ctx); + ASSERT(result == 1); + _digest = right._digest; + return *this; } - GenericHashImpl::DestroyCTX(_ctx); - _ctx = nullptr; - } - - void UpdateData(uint8 const* data, size_t len) - { - int result = EVP_DigestUpdate(_ctx, data, len); - ASSERT(result == 1); - } - void UpdateData(std::string_view str) { UpdateData(reinterpret_cast<uint8 const*>(str.data()), str.size()); } - void UpdateData(std::string const& str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */ - void UpdateData(char const* str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */ - template <typename Container> - void UpdateData(Container const& c) { UpdateData(std::data(c), std::size(c)); } - - void Finalize() - { - uint32 length; - int result = EVP_DigestFinal_ex(_ctx, _digest.data(), &length); - ASSERT(result == 1); - ASSERT(length == DIGEST_LENGTH); - GenericHashImpl::DestroyCTX(_ctx); - _ctx = nullptr; - } - - Digest const& GetDigest() const { return _digest; } - - private: - EVP_MD_CTX* _ctx; - Digest _digest = { }; + + GenericHash& operator=(GenericHash&& right) noexcept + { + if (this == &right) + return *this; + + _ctx = std::exchange(right._ctx, GenericHashImpl::MakeCTX()); + _digest = std::exchange(right._digest, Digest{}); + return *this; + } + + void UpdateData(uint8 const* data, size_t len) + { + int result = EVP_DigestUpdate(_ctx, data, len); + ASSERT(result == 1); + } + + void UpdateData(std::string_view str) { UpdateData(reinterpret_cast<uint8 const*>(str.data()), str.size()); } + void UpdateData(std::string const& str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */ + void UpdateData(char const* str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */ + + template <typename Container> + void UpdateData(Container const& c) { UpdateData(std::data(c), std::size(c)); } + + void Finalize() + { + uint32 length; + int result = EVP_DigestFinal_ex(_ctx, _digest.data(), &length); + ASSERT(result == 1); + ASSERT(length == DIGEST_LENGTH); + } + + Digest const& GetDigest() const { return _digest; } + + private: + EVP_MD_CTX* _ctx{}; + Digest _digest{}; }; } namespace Acore::Crypto { + using MD5 = Acore::Impl::GenericHash<EVP_md5, Constants::MD5_DIGEST_LENGTH_BYTES>; using SHA1 = Acore::Impl::GenericHash<EVP_sha1, Constants::SHA1_DIGEST_LENGTH_BYTES>; using SHA256 = Acore::Impl::GenericHash<EVP_sha256, Constants::SHA256_DIGEST_LENGTH_BYTES>; } diff --git a/src/common/Cryptography/CryptoRandom.cpp b/src/common/Cryptography/CryptoRandom.cpp index 78aa4af500..35d78f7444 100644 --- a/src/common/Cryptography/CryptoRandom.cpp +++ b/src/common/Cryptography/CryptoRandom.cpp @@ -22,5 +22,5 @@ void Acore::Crypto::GetRandomBytes(uint8* buf, size_t len) { int result = RAND_bytes(buf, len); - ASSERT(result == 1); + ASSERT(result == 1, "Not enough randomness in OpenSSL's entropy pool. What in the world are you running on?"); } diff --git a/src/common/Cryptography/CryptoRandom.h b/src/common/Cryptography/CryptoRandom.h index 726fac5d6f..07f87df00d 100644 --- a/src/common/Cryptography/CryptoRandom.h +++ b/src/common/Cryptography/CryptoRandom.h @@ -23,7 +23,7 @@ namespace Acore::Crypto { - void GetRandomBytes(uint8* buf, size_t len); + AC_COMMON_API void GetRandomBytes(uint8* buf, size_t len); template <typename Container> void GetRandomBytes(Container& c) diff --git a/src/common/Cryptography/HMAC.h b/src/common/Cryptography/HMAC.h index e6e2d7f81f..ebfc1e14ba 100644 --- a/src/common/Cryptography/HMAC.h +++ b/src/common/Cryptography/HMAC.h @@ -19,10 +19,9 @@ #define AZEROTHCORE_HMAC_H #include "CryptoConstants.h" -#include "Define.h" +#include "CryptoHash.h" #include "Errors.h" #include <array> -#include <openssl/hmac.h> #include <string> #include <string_view> @@ -30,96 +29,108 @@ class BigNumber; namespace Acore::Impl { - struct HMACImpl - { - typedef EVP_MD const* (*HashCreator)(); - -#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L - static HMAC_CTX* MakeCTX() - { - HMAC_CTX* ctx = new HMAC_CTX(); - HMAC_CTX_init(ctx); - return ctx; - } - - static void DestroyCTX(HMAC_CTX* ctx) - { - HMAC_CTX_cleanup(ctx); - delete ctx; - } -#else - static HMAC_CTX* MakeCTX() { return HMAC_CTX_new(); } - static void DestroyCTX(HMAC_CTX* ctx) { HMAC_CTX_free(ctx); } -#endif - }; - - template <HMACImpl::HashCreator HashCreator, size_t DigestLength> + template <GenericHashImpl::HashCreator HashCreator, size_t DigestLength> class GenericHMAC { - public: - static constexpr size_t DIGEST_LENGTH = DigestLength; - using Digest = std::array<uint8, DIGEST_LENGTH>; - - template <typename Container> - static Digest GetDigestOf(Container const& seed, uint8 const* data, size_t len) - { - GenericHMAC hash(seed); - hash.UpdateData(data, len); - hash.Finalize(); - return hash.GetDigest(); - } - - template <typename Container, typename... Ts> - static auto GetDigestOf(Container const& seed, Ts&& ... pack) -> std::enable_if_t < !(std::is_integral_v<std::decay_t<Ts>> || ...), Digest > - { - GenericHMAC hash(seed); - (hash.UpdateData(std::forward<Ts>(pack)), ...); - hash.Finalize(); - return hash.GetDigest(); - } - - GenericHMAC(uint8 const* seed, size_t len) : _ctx(HMACImpl::MakeCTX()) - { - int result = HMAC_Init_ex(_ctx, seed, len, HashCreator(), nullptr); - ASSERT(result == 1); - } - template <typename Container> GenericHMAC(Container const& container) : GenericHMAC(std::data(container), std::size(container)) {} - - ~GenericHMAC() - { - if (!_ctx) + public: + static constexpr size_t DIGEST_LENGTH = DigestLength; + using Digest = std::array<uint8, DIGEST_LENGTH>; + + template <typename Container> + static Digest GetDigestOf(Container const& seed, uint8 const* data, size_t len) + { + GenericHMAC hash(seed); + hash.UpdateData(data, len); + hash.Finalize(); + return hash.GetDigest(); + } + + template <typename Container, typename... Ts> + static auto GetDigestOf(Container const& seed, Ts&&... pack) -> std::enable_if_t<!(std::is_integral_v<std::decay_t<Ts>> || ...), Digest> + { + GenericHMAC hash(seed); + (hash.UpdateData(std::forward<Ts>(pack)), ...); + hash.Finalize(); + return hash.GetDigest(); + } + + GenericHMAC(uint8 const* seed, size_t len) : _ctx(GenericHashImpl::MakeCTX()), _key(EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, nullptr, seed, len)) + { + int result = EVP_DigestSignInit(_ctx, nullptr, HashCreator(), nullptr, _key); + ASSERT(result == 1); + } + + template <typename Container> + GenericHMAC(Container const& container) : GenericHMAC(std::data(container), std::size(container)) {} + + GenericHMAC(GenericHMAC const& right) : _ctx(GenericHashImpl::MakeCTX()) { - return; + *this = right; } - HMACImpl::DestroyCTX(_ctx); - _ctx = nullptr; - } - - void UpdateData(uint8 const* data, size_t len) - { - int result = HMAC_Update(_ctx, data, len); - ASSERT(result == 1); - } - void UpdateData(std::string_view str) { UpdateData(reinterpret_cast<uint8 const*>(str.data()), str.size()); } - void UpdateData(std::string const& str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */ - void UpdateData(char const* str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */ - template <typename Container> - void UpdateData(Container const& c) { UpdateData(std::data(c), std::size(c)); } - - void Finalize() - { - uint32 length = 0; - int result = HMAC_Final(_ctx, _digest.data(), &length); - ASSERT(result == 1); - ASSERT(length == DIGEST_LENGTH); - HMACImpl::DestroyCTX(_ctx); - _ctx = nullptr; - } - - Digest const& GetDigest() const { return _digest; } - private: - HMAC_CTX* _ctx; - Digest _digest = { }; + + GenericHMAC(GenericHMAC&& right) noexcept + { + *this = std::move(right); + } + + ~GenericHMAC() + { + GenericHashImpl::DestroyCTX(_ctx); + _ctx = nullptr; + EVP_PKEY_free(_key); + _key = nullptr; + } + + GenericHMAC& operator=(GenericHMAC const& right) + { + if (this == &right) + return *this; + + int result = EVP_MD_CTX_copy_ex(_ctx, right._ctx); + ASSERT(result == 1); + _key = right._key; // EVP_PKEY uses reference counting internally, just copy the pointer + EVP_PKEY_up_ref(_key); // Bump reference count for PKEY, as every instance of this class holds two references to PKEY and destructor decrements it twice + _digest = right._digest; + return *this; + } + + GenericHMAC& operator=(GenericHMAC&& right) noexcept + { + if (this == &right) + return *this; + + _ctx = std::exchange(right._ctx, GenericHashImpl::MakeCTX()); + _key = std::exchange(right._key, EVP_PKEY_new()); + _digest = std::exchange(right._digest, Digest{}); + return *this; + } + + void UpdateData(uint8 const* data, size_t len) + { + int result = EVP_DigestSignUpdate(_ctx, data, len); + ASSERT(result == 1); + } + + void UpdateData(std::string_view str) { UpdateData(reinterpret_cast<uint8 const*>(str.data()), str.size()); } + void UpdateData(std::string const& str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */ + void UpdateData(char const* str) { UpdateData(std::string_view(str)); } /* explicit overload to avoid using the container template */ + + template <typename Container> + void UpdateData(Container const& c) { UpdateData(std::data(c), std::size(c)); } + + void Finalize() + { + size_t length = DIGEST_LENGTH; + int result = EVP_DigestSignFinal(_ctx, _digest.data(), &length); + ASSERT(result == 1); + ASSERT(length == DIGEST_LENGTH); + } + + Digest const& GetDigest() const { return _digest; } + private: + EVP_MD_CTX* _ctx{}; + EVP_PKEY* _key{}; + Digest _digest{}; }; } @@ -128,4 +139,5 @@ namespace Acore::Crypto using HMAC_SHA1 = Acore::Impl::GenericHMAC<EVP_sha1, Constants::SHA1_DIGEST_LENGTH_BYTES>; using HMAC_SHA256 = Acore::Impl::GenericHMAC<EVP_sha256, Constants::SHA256_DIGEST_LENGTH_BYTES>; } + #endif diff --git a/src/common/Cryptography/OpenSSLCrypto.cpp b/src/common/Cryptography/OpenSSLCrypto.cpp index 7bba285bda..ccfe2de5f7 100644 --- a/src/common/Cryptography/OpenSSLCrypto.cpp +++ b/src/common/Cryptography/OpenSSLCrypto.cpp @@ -15,49 +15,90 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <OpenSSLCrypto.h> +#include "OpenSSLCrypto.h" +#include <openssl/crypto.h> #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x1010000fL #include <vector> #include <thread> #include <mutex> + std::vector<std::mutex*> cryptoLocks; + static void lockingCallback(int mode, int type, char const* /*file*/, int /*line*/) { if (mode & CRYPTO_LOCK) - { cryptoLocks[type]->lock(); - } else - { cryptoLocks[type]->unlock(); - } } -static void threadIdCallback(CRYPTO_THREADID* id) + +static void threadIdCallback(CRYPTO_THREADID * id) { (void)id; CRYPTO_THREADID_set_numeric(id, std::hash<std::thread::id>()(std::this_thread::get_id())); } +#elif OPENSSL_VERSION_NUMBER >= 0x30000000L +#include <openssl/provider.h> +OSSL_PROVIDER* LegacyProvider; +OSSL_PROVIDER* DefaultProvider; +#endif + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L && AC_PLATFORM == AC_PLATFORM_WINDOWS +#include <boost/dll/runtime_symbol_info.hpp> +#include <filesystem> + +void SetupLibrariesForWindows() +{ + namespace fs = std::filesystem; + + fs::path programLocation{ boost::dll::program_location().remove_filename().string() }; + fs::path libLegacy{ boost::dll::program_location().remove_filename().string() + "/legacy.dll" }; + + ASSERT(fs::exists(libLegacy), "Not found 'legacy.dll'. Please copy library 'legacy.dll' from OpenSSL default dir to '{}'", programLocation.generic_string()); + OSSL_PROVIDER_set_default_search_path(nullptr, programLocation.generic_string().c_str()); +} +#endif + void OpenSSLCrypto::threadsSetup() { +#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x1010000fL cryptoLocks.resize(CRYPTO_num_locks()); + for (int i = 0 ; i < CRYPTO_num_locks(); ++i) { cryptoLocks[i] = new std::mutex(); } + (void)&threadIdCallback; CRYPTO_THREADID_set_callback(threadIdCallback); + (void)&lockingCallback; CRYPTO_set_locking_callback(lockingCallback); +#elif OPENSSL_VERSION_NUMBER >= 0x30000000L +#if AC_PLATFORM == AC_PLATFORM_WINDOWS + SetupLibrariesForWindows(); +#endif + LegacyProvider = OSSL_PROVIDER_load(nullptr, "legacy"); + DefaultProvider = OSSL_PROVIDER_load(nullptr, "default"); +#endif } + void OpenSSLCrypto::threadsCleanup() { +#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x1010000fL CRYPTO_set_locking_callback(nullptr); CRYPTO_THREADID_set_callback(nullptr); + for (int i = 0 ; i < CRYPTO_num_locks(); ++i) { delete cryptoLocks[i]; } + cryptoLocks.resize(0); -} +#elif OPENSSL_VERSION_NUMBER >= 0x30000000L + OSSL_PROVIDER_unload(LegacyProvider); + OSSL_PROVIDER_unload(DefaultProvider); + OSSL_PROVIDER_set_default_search_path(nullptr, nullptr); #endif +} diff --git a/src/common/Cryptography/OpenSSLCrypto.h b/src/common/Cryptography/OpenSSLCrypto.h index b181f3418d..be68504510 100644 --- a/src/common/Cryptography/OpenSSLCrypto.h +++ b/src/common/Cryptography/OpenSSLCrypto.h @@ -15,11 +15,10 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef OPENSSL_CRYPTO_H_ -#define OPENSSL_CRYPTO_H_ +#ifndef _AC_OPENSSL_CRYPTO_H +#define _AC_OPENSSL_CRYPTO_H #include "Define.h" -#include <openssl/opensslv.h> /** * A group of functions which setup openssl crypto module to work properly in multithreaded enviroment @@ -27,17 +26,11 @@ */ namespace OpenSSLCrypto { - -#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x1010000fL /// Needs to be called before threads using openssl are spawned - void threadsSetup(); - /// Needs to be called after threads using openssl are despawned - void threadsCleanup(); -#else - void threadsSetup() { }; - void threadsCleanup() { }; -#endif + AC_COMMON_API void threadsSetup(); + /// Needs to be called after threads using openssl are despawned + AC_COMMON_API void threadsCleanup(); } #endif diff --git a/src/common/Cryptography/SessionKeyGenerator.h b/src/common/Cryptography/SessionKeyGenerator.h index b66f1014a0..43dca3f235 100644 --- a/src/common/Cryptography/SessionKeyGenerator.h +++ b/src/common/Cryptography/SessionKeyGenerator.h @@ -15,17 +15,18 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "CryptoHash.h" -#include <cstring> - #ifndef AZEROTHCORE_SESSIONKEYGENERATOR_HPP #define AZEROTHCORE_SESSIONKEYGENERATOR_HPP +#include "CryptoHash.h" +#include <cstring> + template <typename Hash> class SessionKeyGenerator { public: - template <typename C> SessionKeyGenerator(C const& buf) : + template <typename C> + SessionKeyGenerator(C const& buf) : o0it(o0.begin()) { uint8 const* data = std::data(buf); @@ -52,9 +53,9 @@ public: } private: - typename Hash::Digest o0 = { }; - typename Hash::Digest o1 = { }; - typename Hash::Digest o2 = { }; + typename Hash::Digest o0{}; + typename Hash::Digest o1{}; + typename Hash::Digest o2{}; typename Hash::Digest::const_iterator o0it; }; diff --git a/src/common/Cryptography/TOTP.cpp b/src/common/Cryptography/TOTP.cpp index 937285bc97..3b132bc46e 100644 --- a/src/common/Cryptography/TOTP.cpp +++ b/src/common/Cryptography/TOTP.cpp @@ -28,11 +28,8 @@ static constexpr uint32 HMAC_RESULT_SIZE = 20; { timestamp /= TOTP_INTERVAL; unsigned char challenge[8]; - for (int i = 8; i--; timestamp >>= 8) - { challenge[i] = timestamp; - } unsigned char digest[HMAC_RESULT_SIZE]; uint32 digestSize = HMAC_RESULT_SIZE; @@ -41,7 +38,6 @@ static constexpr uint32 HMAC_RESULT_SIZE = 20; uint32 offset = digest[19] & 0xF; uint32 truncated = (digest[offset] << 24) | (digest[offset + 1] << 16) | (digest[offset + 2] << 8) | (digest[offset + 3]); truncated &= 0x7FFFFFFF; - return (truncated % 1000000); } diff --git a/src/common/Cryptography/TOTP.h b/src/common/Cryptography/TOTP.h index 6a0e782942..01b2a53bd7 100644 --- a/src/common/Cryptography/TOTP.h +++ b/src/common/Cryptography/TOTP.h @@ -1,6 +1,18 @@ /* - * Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 - * Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore> + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifndef WARHEAD_TOTP_H diff --git a/src/server/apps/authserver/Main.cpp b/src/server/apps/authserver/Main.cpp index b0105d658b..4c110db7aa 100644 --- a/src/server/apps/authserver/Main.cpp +++ b/src/server/apps/authserver/Main.cpp @@ -35,6 +35,7 @@ #include "IoContext.h" #include "Log.h" #include "MySQLThreading.h" +#include "OpenSSLCrypto.h" #include "ProcessPriority.h" #include "RealmList.h" #include "SecretMgr.h" @@ -96,10 +97,14 @@ int main(int argc, char** argv) []() { LOG_INFO("server.authserver", "> Using configuration file {}", sConfigMgr->GetFilename()); - LOG_INFO("server.authserver", "> Using SSL version: {} (library: {})", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); + LOG_INFO("server.authserver", "> Using SSL version: {} (library: {})", OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_VERSION)); LOG_INFO("server.authserver", "> Using Boost version: {}.{}.{}", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); }); + OpenSSLCrypto::threadsSetup(); + + std::shared_ptr<void> opensslHandle(nullptr, [](void*) { OpenSSLCrypto::threadsCleanup(); }); + // authserver PID file creation std::string pidFile = sConfigMgr->GetOption<std::string>("PidFile", ""); if (!pidFile.empty()) diff --git a/src/server/apps/worldserver/Main.cpp b/src/server/apps/worldserver/Main.cpp index 67d97c8324..7578a2af77 100644 --- a/src/server/apps/worldserver/Main.cpp +++ b/src/server/apps/worldserver/Main.cpp @@ -160,7 +160,7 @@ int main(int argc, char** argv) []() { LOG_INFO("server.worldserver", "> Using configuration file {}", sConfigMgr->GetFilename()); - LOG_INFO("server.worldserver", "> Using SSL version: {} (library: {})", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); + LOG_INFO("server.worldserver", "> Using SSL version: {} (library: {})", OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_VERSION)); LOG_INFO("server.worldserver", "> Using Boost version: {}.{}.{}", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); }); diff --git a/src/server/game/Addons/AddonMgr.cpp b/src/server/game/Addons/AddonMgr.cpp index 396babbdae..918b1b5172 100644 --- a/src/server/game/Addons/AddonMgr.cpp +++ b/src/server/game/Addons/AddonMgr.cpp @@ -17,10 +17,10 @@ #include "AddonMgr.h" #include "DatabaseEnv.h" +#include "CryptoHash.h" #include "Log.h" #include "Timer.h" #include <list> -#include <openssl/md5.h> namespace AddonMgr { @@ -66,6 +66,7 @@ namespace AddonMgr oldMSTime = getMSTime(); result = CharacterDatabase.Query("SELECT id, name, version, UNIX_TIMESTAMP(timestamp) FROM banned_addons"); + if (result) { uint32 count2 = 0; @@ -78,14 +79,10 @@ namespace AddonMgr BannedAddon addon{}; addon.Id = fields[0].Get<uint32>() + offset; addon.Timestamp = uint32(fields[3].Get<uint64>()); + addon.NameMD5 = Acore::Crypto::MD5::GetDigestOf(fields[1].Get<std::string>()); + addon.VersionMD5 = Acore::Crypto::MD5::GetDigestOf(fields[2].Get<std::string>()); - std::string name = fields[1].Get<std::string>(); - std::string version = fields[2].Get<std::string>(); - - MD5(reinterpret_cast<uint8 const*>(name.c_str()), name.length(), addon.NameMD5); - MD5(reinterpret_cast<uint8 const*>(version.c_str()), version.length(), addon.VersionMD5); - - m_bannedAddons.push_back(addon); + m_bannedAddons.emplace_back(addon); ++count2; } while (result->NextRow()); diff --git a/src/server/game/Addons/AddonMgr.h b/src/server/game/Addons/AddonMgr.h index 897476a774..d51fb14020 100644 --- a/src/server/game/Addons/AddonMgr.h +++ b/src/server/game/Addons/AddonMgr.h @@ -19,6 +19,7 @@ #define _ADDONMGR_H #include "Define.h" +#include <array> #include <list> #include <string> #include <utility> @@ -49,8 +50,8 @@ struct SavedAddon struct BannedAddon { uint32 Id; - uint8 NameMD5[16]; - uint8 VersionMD5[16]; + std::array<uint8, 16> NameMD5; + std::array<uint8, 16> VersionMD5; uint32 Timestamp; }; diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 2849c953ed..a4453e5e1f 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -1254,8 +1254,8 @@ void WorldSession::SendAddonsInfo() for (AddonMgr::BannedAddonList::const_iterator itr = bannedAddons->begin(); itr != bannedAddons->end(); ++itr) { data << uint32(itr->Id); - data.append(itr->NameMD5, sizeof(itr->NameMD5)); - data.append(itr->VersionMD5, sizeof(itr->VersionMD5)); + data.append(itr->NameMD5); + data.append(itr->VersionMD5); data << uint32(itr->Timestamp); data << uint32(1); // IsBanned } diff --git a/src/server/game/Warden/Modules/WardenModuleMac.h b/src/server/game/Warden/Modules/WardenModuleMac.h index 5285392efc..90ec6651d4 100644 --- a/src/server/game/Warden/Modules/WardenModuleMac.h +++ b/src/server/game/Warden/Modules/WardenModuleMac.h @@ -18,7 +18,9 @@ #ifndef _WARDEN_MODULE_MAC_H #define _WARDEN_MODULE_MAC_H -uint8 Module_0DBBF209A27B1E279A9FEC5C168A15F7_Data[9318] = +#include <array> + +std::array<uint8, 9318> Module_0DBBF209A27B1E279A9FEC5C168A15F7_Data = { 0x07, 0x0C, 0x44, 0xCD, 0xC9, 0xFB, 0x99, 0xBC, 0x7C, 0x77, 0xDC, 0xE8, 0x8D, 0x07, 0xBE, 0x55, 0x37, 0x5C, 0x84, 0x10, 0x23, 0xE1, 0x36, 0x5B, 0xF1, 0xBC, 0x60, 0xF3, 0x68, 0xBA, 0x60, 0x69, @@ -605,7 +607,7 @@ uint8 Module_0DBBF209A27B1E279A9FEC5C168A15F7_Data[9318] = 0x43, 0x82, 0xAA, 0x0C, 0xEE, 0x1B }; -uint8 Module_0DBBF209A27B1E279A9FEC5C168A15F7_Key[16] = +std::array<uint8, 16> Module_0DBBF209A27B1E279A9FEC5C168A15F7_Key = { 0x5B, 0x27, 0x27, 0x01, 0x24, 0x56, 0xB4, 0xD4, 0x2D, 0xD0, 0x96, 0x77, 0x49, 0x51, 0xDC, 0x0A }; diff --git a/src/server/game/Warden/Warden.cpp b/src/server/game/Warden/Warden.cpp index 919b7af22c..8b53a43dd0 100644 --- a/src/server/game/Warden/Warden.cpp +++ b/src/server/game/Warden/Warden.cpp @@ -19,7 +19,7 @@ #include "AccountMgr.h" #include "BanMgr.h" #include "ByteBuffer.h" -#include "Common.h" +#include "CryptoHash.h" #include "Log.h" #include "Opcodes.h" #include "Player.h" @@ -28,7 +28,6 @@ #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" -#include <openssl/sha.h> Warden::Warden() : _session(nullptr), _checkTimer(10000/*10 sec*/), _clientResponseTimer(0), _dataSent(false), _module(nullptr), _initialized(false) @@ -77,11 +76,11 @@ void Warden::RequestModule() LOG_DEBUG("warden", "Request module"); // Create packet structure - WardenModuleUse request; + WardenModuleUse request{}; request.Command = WARDEN_SMSG_MODULE_USE; - memcpy(request.ModuleId, _module->Id, 16); - memcpy(request.ModuleKey, _module->Key, 16); + memcpy(request.ModuleId, _module->Id.data(), 16); + memcpy(request.ModuleKey, _module->Key.data(), 16); request.Size = _module->CompressedSize; EndianConvert(request.Size); @@ -155,30 +154,21 @@ bool Warden::IsValidCheckSum(uint32 checksum, const uint8* data, const uint16 le } } -struct keyData +union keyData { - union - { - struct - { - uint8 bytes[20]; - } bytes; - - struct - { - uint32 ints[5]; - } ints; - }; + std::array<uint8, 20> bytes; + std::array<uint32, 5> ints; }; uint32 Warden::BuildChecksum(const uint8* data, uint32 length) { - keyData hash; - SHA1(data, length, hash.bytes.bytes); + keyData hash{}; + hash.bytes = Acore::Crypto::SHA1::GetDigestOf(data, size_t(length)); uint32 checkSum = 0; + for (uint8 i = 0; i < 5; ++i) { - checkSum = checkSum ^ hash.ints.ints[i]; + checkSum = checkSum ^ hash.ints[i]; } return checkSum; diff --git a/src/server/game/Warden/Warden.h b/src/server/game/Warden/Warden.h index 278ad7a955..db0222c2b5 100644 --- a/src/server/game/Warden/Warden.h +++ b/src/server/game/Warden/Warden.h @@ -91,10 +91,10 @@ struct WardenHashRequest struct ClientWardenModule { - uint8 Id[16]; - uint8 Key[16]; - uint32 CompressedSize; - uint8* CompressedData; + std::array<uint8, 16> Id{}; + std::array<uint8, 16> Key{}; + uint32 CompressedSize{}; + uint8* CompressedData{}; }; class WorldSession; diff --git a/src/server/game/Warden/WardenMac.cpp b/src/server/game/Warden/WardenMac.cpp index 039f17f78a..c10ce9a3b5 100644 --- a/src/server/game/Warden/WardenMac.cpp +++ b/src/server/game/Warden/WardenMac.cpp @@ -25,15 +25,12 @@ #include "WardenModuleMac.h" #include "WorldPacket.h" #include "WorldSession.h" -#include <openssl/md5.h> WardenMac::WardenMac() : Warden() { } -WardenMac::~WardenMac() -{ -} +WardenMac::~WardenMac() = default; void WardenMac::Init(WorldSession* pClient, SessionKey const& K) { @@ -64,29 +61,21 @@ void WardenMac::Init(WorldSession* pClient, SessionKey const& K) _module = GetModuleForClient(); - LOG_DEBUG("warden", "Module Key: {}", Acore::Impl::ByteArrayToHexStr(_module->Key, 16)); - LOG_DEBUG("warden", "Module ID: {}", Acore::Impl::ByteArrayToHexStr(_module->Id, 16)); + LOG_DEBUG("warden", "Module Key: {}", ByteArrayToHexStr(_module->Key)); + LOG_DEBUG("warden", "Module ID: {}", ByteArrayToHexStr(_module->Id)); RequestModule(); } ClientWardenModule* WardenMac::GetModuleForClient() { - ClientWardenModule* mod = new ClientWardenModule; - - uint32 len = sizeof(Module_0DBBF209A27B1E279A9FEC5C168A15F7_Data); + auto mod = new ClientWardenModule; // data assign - mod->CompressedSize = len; - mod->CompressedData = new uint8[len]; - memcpy(mod->CompressedData, Module_0DBBF209A27B1E279A9FEC5C168A15F7_Data, len); - memcpy(mod->Key, Module_0DBBF209A27B1E279A9FEC5C168A15F7_Key, 16); + mod->CompressedSize = Module_0DBBF209A27B1E279A9FEC5C168A15F7_Data.size(); + mod->CompressedData = Module_0DBBF209A27B1E279A9FEC5C168A15F7_Data.data(); // md5 hash - MD5_CTX ctx; - MD5_Init(&ctx); - MD5_Update(&ctx, mod->CompressedData, len); - MD5_Final((uint8*)&mod->Id, &ctx); - + mod->Id = Acore::Crypto::MD5::GetDigestOf(mod->CompressedData, mod->CompressedSize); return mod; } @@ -100,7 +89,7 @@ void WardenMac::RequestHash() LOG_DEBUG("warden", "Request hash"); // Create packet structure - WardenHashRequest Request; + WardenHashRequest Request{}; Request.Command = WARDEN_SMSG_HASH_REQUEST; memcpy(Request.Seed, _seed, 16); @@ -242,7 +231,7 @@ void WardenMac::HandleData(ByteBuffer& buff) sha1.UpdateData((uint8*)&magic, 4); sha1.Finalize(); - std::array<uint8, Acore::Crypto::SHA1::DIGEST_LENGTH> sha1Hash; + Acore::Crypto::SHA1::Digest sha1Hash{}; buff.read(sha1Hash.data(), sha1Hash.size()); if (sha1Hash != sha1.GetDigest()) @@ -251,20 +240,15 @@ void WardenMac::HandleData(ByteBuffer& buff) //found = true; } - MD5_CTX ctx; - MD5_Init(&ctx); - MD5_Update(&ctx, str.c_str(), str.size()); - uint8 ourMD5Hash[16]; - MD5_Final(ourMD5Hash, &ctx); - - uint8 theirsMD5Hash[16]; - buff.read(theirsMD5Hash, 16); + auto ourMD5Hash = Acore::Crypto::MD5::GetDigestOf(str); + Acore::Crypto::MD5::Digest theirsMD5Hash{}; + buff.read(theirsMD5Hash); - if (memcmp(ourMD5Hash, theirsMD5Hash, 16)) + if (ourMD5Hash != theirsMD5Hash) { LOG_DEBUG("warden", "Handle data failed: MD5 hash is wrong!"); //found = true; } - _session->KickPlayer("WardenMac"); + _session->KickPlayer("WardenMac::HandleData"); } diff --git a/src/server/game/Warden/WardenWin.cpp b/src/server/game/Warden/WardenWin.cpp index b3529d9e87..604192c55e 100644 --- a/src/server/game/Warden/WardenWin.cpp +++ b/src/server/game/Warden/WardenWin.cpp @@ -31,7 +31,6 @@ #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" -#include <openssl/md5.h> // GUILD is the shortest string that has no client validation (RAID only sends if in a raid group) static constexpr char _luaEvalPrefix[] = "local S,T,R=SendAddonMessage,function()"; @@ -97,9 +96,7 @@ static WorldIntConfigs GetMaxWardenChecksForType(uint8 type) WardenWin::WardenWin() : Warden(), _serverTicks(0) { } -WardenWin::~WardenWin() -{ -} +WardenWin::~WardenWin() = default; void WardenWin::Init(WorldSession* session, SessionKey const& k) { @@ -121,14 +118,14 @@ void WardenWin::Init(WorldSession* session, SessionKey const& k) _module = GetModuleForClient(); - LOG_DEBUG("warden", "Module Key: {}", Acore::Impl::ByteArrayToHexStr(_module->Key, 16)); - LOG_DEBUG("warden", "Module ID: {}", Acore::Impl::ByteArrayToHexStr(_module->Id, 16)); + LOG_DEBUG("warden", "Module Key: {}", ByteArrayToHexStr(_module->Key)); + LOG_DEBUG("warden", "Module ID: {}", ByteArrayToHexStr(_module->Id)); RequestModule(); } ClientWardenModule* WardenWin::GetModuleForClient() { - ClientWardenModule* mod = new ClientWardenModule; + auto mod = new ClientWardenModule; uint32 length = sizeof(Module.Module); @@ -136,13 +133,10 @@ ClientWardenModule* WardenWin::GetModuleForClient() mod->CompressedSize = length; mod->CompressedData = new uint8[length]; memcpy(mod->CompressedData, Module.Module, length); - memcpy(mod->Key, Module.ModuleKey, 16); + memcpy(mod->Key.data(), Module.ModuleKey, 16); // md5 hash - MD5_CTX ctx; - MD5_Init(&ctx); - MD5_Update(&ctx, mod->CompressedData, length); - MD5_Final((uint8*)&mod->Id, &ctx); + mod->Id = Acore::Crypto::MD5::GetDigestOf(mod->CompressedData, mod->CompressedSize); return mod; } @@ -152,7 +146,7 @@ void WardenWin::InitializeModule() LOG_DEBUG("warden", "Initialize module"); // Create packet structure - WardenInitModuleRequest Request; + WardenInitModuleRequest Request{}; Request.Command1 = WARDEN_SMSG_MODULE_INITIALIZE; Request.Size1 = 20; Request.Unk1 = 1; @@ -209,7 +203,7 @@ void WardenWin::RequestHash() LOG_DEBUG("warden", "Request hash"); // Create packet structure - WardenHashRequest Request; + WardenHashRequest Request{}; Request.Command = WARDEN_SMSG_HASH_REQUEST; memcpy(Request.Seed, _seed, 16); diff --git a/src/server/scripts/Commands/cs_server.cpp b/src/server/scripts/Commands/cs_server.cpp index 2e60148a2a..63c65caab5 100644 --- a/src/server/scripts/Commands/cs_server.cpp +++ b/src/server/scripts/Commands/cs_server.cpp @@ -129,7 +129,7 @@ public: } handler->PSendSysMessage("%s", GitRevision::GetFullVersion()); - handler->PSendSysMessage("Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); + handler->PSendSysMessage("Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_VERSION)); handler->PSendSysMessage("Using Boost version: %i.%i.%i", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); handler->PSendSysMessage("Using MySQL version: %u", MySQL::GetLibraryVersion()); handler->PSendSysMessage("Using CMake version: %s", GitRevision::GetCMakeVersion()); diff --git a/src/tools/dbimport/Main.cpp b/src/tools/dbimport/Main.cpp index 644e80a29e..0f4ddf5ffa 100644 --- a/src/tools/dbimport/Main.cpp +++ b/src/tools/dbimport/Main.cpp @@ -16,13 +16,13 @@ */ #include "Banner.h" -#include "Common.h" #include "Config.h" #include "DatabaseEnv.h" #include "DatabaseLoader.h" #include "IoContext.h" #include "Log.h" #include "MySQLThreading.h" +#include "OpenSSLCrypto.h" #include "Util.h" #include <boost/program_options.hpp> #include <boost/version.hpp> @@ -73,11 +73,15 @@ int main(int argc, char** argv) []() { LOG_INFO("dbimport", "> Using configuration file: {}", sConfigMgr->GetFilename()); - LOG_INFO("dbimport", "> Using SSL version: {} (library: {})", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); + LOG_INFO("dbimport", "> Using SSL version: {} (library: {})", OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_VERSION)); LOG_INFO("dbimport", "> Using Boost version: {}.{}.{}", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); } ); + OpenSSLCrypto::threadsSetup(); + + std::shared_ptr<void> opensslHandle(nullptr, [](void*) { OpenSSLCrypto::threadsCleanup(); }); + // Initialize the database connection if (!StartDB()) return 1; |