diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 78169a38..eb2446c0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,7 +53,7 @@ jobs: gcc-openssl-master: runs-on: ubuntu-latest - if: ${{ github.event_name == 'schedule' }} + if: ${{ github.event_name == 'schedule' || github.event_name == 'pull_request' }} env: OPENSSL_BRANCH: master steps: @@ -65,7 +65,7 @@ jobs: macos-openssl-master: runs-on: macos-latest - if: ${{ github.event_name == 'schedule' }} + if: ${{ github.event_name == 'schedule' || github.event_name == 'pull_request' }} env: OPENSSL_BRANCH: master USE_RPATH: @@ -78,7 +78,7 @@ jobs: gcc-asan-openssl-master: runs-on: ubuntu-latest - if: ${{ github.event_name == 'schedule' }} + if: ${{ github.event_name == 'schedule' || github.event_name == 'pull_request' }} env: OPENSSL_BRANCH: master ASAN: -DASAN=1 @@ -91,7 +91,7 @@ jobs: macos-asan-openssl-master: runs-on: macos-latest - if: ${{ github.event_name == 'schedule' }} + if: ${{ github.event_name == 'schedule' || github.event_name == 'pull_request' }} env: OPENSSL_BRANCH: master ASAN: -DASAN=1 diff --git a/CMakeLists.txt b/CMakeLists.txt index 60552abf..63d9efeb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,32 @@ include(CheckCSourceRuns) enable_testing() -find_package(OpenSSL 3.4 REQUIRED) +find_package(OpenSSL 3.0 REQUIRED) + +# Detect if OpenSSL supports Engine API +include(CheckCSourceCompiles) +check_c_source_compiles(" + #include + #ifdef OPENSSL_NO_ENGINE + #error Engine API not available + #endif + int main(void) { return 0; } +" HAVE_ENGINE_API) + +# Options for building engine and provider +option(GOST_ENGINE_ENABLE "Enable GOST engine build" ${HAVE_ENGINE_API}) +option(GOST_PROVIDER_ENABLE "Enable GOST provider build" ON) + +if(GOST_ENGINE_ENABLE AND NOT HAVE_ENGINE_API) + message(FATAL_ERROR "Engine API is not available in this OpenSSL version. Set GOST_ENGINE_ENABLE=OFF to build provider only.") +endif() + +if(NOT GOST_ENGINE_ENABLE AND NOT GOST_PROVIDER_ENABLE) + message(FATAL_ERROR "At least one of GOST_ENGINE_ENABLE or GOST_PROVIDER_ENABLE must be ON") +endif() + +message(STATUS "GOST Engine build: ${GOST_ENGINE_ENABLE}") +message(STATUS "GOST Provider build: ${GOST_PROVIDER_ENABLE}") if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to 'RelWithDebInfo' as none was specified.") @@ -110,13 +135,15 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${OUTPUT_DIRECTORY}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_DIRECTORY}) # Remove when https://gitlab.kitware.com/cmake/cmake/issues/18525 is addressed -set(OPENSSL_ENGINES_DIR "" CACHE PATH "OpenSSL Engines Directory") -if ("${OPENSSL_ENGINES_DIR}" STREQUAL "") - include(FindPkgConfig) - pkg_get_variable(OPENSSL_ENGINES_DIR libcrypto enginesdir) - if ("${OPENSSL_ENGINES_DIR}" STREQUAL "") - message( FATAL_ERROR "Unable to discover the OpenSSL engines directory. Provide the path using -DOPENSSL_ENGINES_DIR" ) - endif() +if(GOST_ENGINE_ENABLE) + set(OPENSSL_ENGINES_DIR "" CACHE PATH "OpenSSL Engines Directory") + if ("${OPENSSL_ENGINES_DIR}" STREQUAL "") + include(FindPkgConfig) + pkg_get_variable(OPENSSL_ENGINES_DIR libcrypto enginesdir) + if ("${OPENSSL_ENGINES_DIR}" STREQUAL "") + message( FATAL_ERROR "Unable to discover the OpenSSL engines directory. Provide the path using -DOPENSSL_ENGINES_DIR" ) + endif() + endif() endif() set(GOST_89_SOURCE_FILES @@ -244,66 +271,82 @@ set(TEST_ENVIRONMENT_PROVIDER add_executable(test_digest test_digest.c) target_link_libraries(test_digest OpenSSL::Crypto) -add_test(NAME digest-with-engine COMMAND test_digest) -set_tests_properties(digest-with-engine - PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}") -add_test(NAME digest-with-provider COMMAND test_digest) -set_tests_properties(digest-with-provider - PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_PROVIDER}") +if(GOST_ENGINE_ENABLE) + add_test(NAME digest-with-engine COMMAND test_digest) + set_tests_properties(digest-with-engine + PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}") +endif() +if(GOST_PROVIDER_ENABLE) + add_test(NAME digest-with-provider COMMAND test_digest) + set_tests_properties(digest-with-provider + PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_PROVIDER}") +endif() add_executable(test_ciphers test_ciphers.c) target_link_libraries(test_ciphers OpenSSL::Crypto) -add_test(NAME ciphers-with-engine COMMAND test_ciphers) -set_tests_properties(ciphers-with-engine - PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}") -add_test(NAME ciphers-with-provider COMMAND test_ciphers) -set_tests_properties(ciphers-with-provider - PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_PROVIDER}") +if(GOST_ENGINE_ENABLE) + add_test(NAME ciphers-with-engine COMMAND test_ciphers) + set_tests_properties(ciphers-with-engine + PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}") +endif() +if(GOST_PROVIDER_ENABLE) + add_test(NAME ciphers-with-provider COMMAND test_ciphers) + set_tests_properties(ciphers-with-provider + PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_PROVIDER}") +endif() # test_curves is an internals testing program, it doesn't need a test env -add_executable(test_ecdhe test_ecdhe.c) -target_link_libraries(test_ecdhe gost_core gost_err) -add_test(NAME ecdhe COMMAND test_ecdhe) -set_tests_properties(ecdhe - PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}") +if(GOST_ENGINE_ENABLE) + add_executable(test_ecdhe test_ecdhe.c) + target_link_libraries(test_ecdhe gost_core gost_err) + add_test(NAME ecdhe COMMAND test_ecdhe) + set_tests_properties(ecdhe + PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}") +endif() add_executable(test_curves test_curves.c) target_link_libraries(test_curves gost_core gost_err) add_test(NAME curves COMMAND test_curves) -add_executable(test_params test_params.c) -target_link_libraries(test_params OpenSSL::Crypto) -add_test(NAME parameters-with-engine COMMAND test_params) -set_tests_properties(parameters-with-engine - PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}") - -add_executable(test_derive test_derive.c) -target_link_libraries(test_derive OpenSSL::Crypto) -add_test(NAME derive-with-engine COMMAND test_derive) -set_tests_properties(derive-with-engine - PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}") - -add_executable(test_sign test_sign.c) -target_link_libraries(test_sign OpenSSL::Crypto) -add_test(NAME sign/verify-with-engine COMMAND test_sign) -set_tests_properties(sign/verify-with-engine - PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}") - -add_executable(test_tls test_tls.c) -target_link_libraries(test_tls OpenSSL::SSL) -add_test(NAME TLS-with-engine COMMAND test_tls) -set_tests_properties(TLS-with-engine - PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}") +if(GOST_ENGINE_ENABLE) + add_executable(test_params test_params.c) + target_link_libraries(test_params OpenSSL::Crypto) + add_test(NAME parameters-with-engine COMMAND test_params) + set_tests_properties(parameters-with-engine + PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}") + + add_executable(test_derive test_derive.c) + target_link_libraries(test_derive OpenSSL::Crypto) + add_test(NAME derive-with-engine COMMAND test_derive) + set_tests_properties(derive-with-engine + PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}") + + add_executable(test_sign test_sign.c) + target_link_libraries(test_sign OpenSSL::Crypto) + add_test(NAME sign/verify-with-engine COMMAND test_sign) + set_tests_properties(sign/verify-with-engine + PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}") + + add_executable(test_tls test_tls.c) + target_link_libraries(test_tls OpenSSL::SSL) + add_test(NAME TLS-with-engine COMMAND test_tls) + set_tests_properties(TLS-with-engine + PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}") +endif() add_executable(test_context test_context.c) target_link_libraries(test_context OpenSSL::Crypto) -add_test(NAME context-with-engine COMMAND test_context) -set_tests_properties(context-with-engine - PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}") -add_test(NAME context-with-provider COMMAND test_context) -set_tests_properties(context-with-provider - PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_PROVIDER}") +if(GOST_ENGINE_ENABLE) + add_test(NAME context-with-engine COMMAND test_context) + set_tests_properties(context-with-engine + PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}") +endif() +if(GOST_PROVIDER_ENABLE) + add_test(NAME context-with-provider COMMAND test_context) + set_tests_properties(context-with-provider + PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_PROVIDER}") +endif() # test_keyexpimp is an internals testing program, it doesn't need a test env add_executable(test_keyexpimp test_keyexpimp.c) @@ -319,19 +362,25 @@ add_test(NAME gost89 COMMAND test_gost89) if(TLS13_PATCHED_OPENSSL) add_executable(test_mgm test_mgm.c) target_link_libraries(test_mgm OpenSSL::Crypto) - add_test(NAME mgm-with-engine COMMAND test_mgm) - set_tests_properties(mgm-with-engine - PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}") - add_test(NAME mgm-with-provider COMMAND test_mgm) - set_tests_properties(mgm-with-provider - PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_PROVIDER}") + if(GOST_ENGINE_ENABLE) + add_test(NAME mgm-with-engine COMMAND test_mgm) + set_tests_properties(mgm-with-engine + PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}") + endif() + if(GOST_PROVIDER_ENABLE) + add_test(NAME mgm-with-provider COMMAND test_mgm) + set_tests_properties(mgm-with-provider + PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_PROVIDER}") + endif() set_property(TARGET test_mgm APPEND PROPERTY COMPILE_DEFINITIONS ENGINE_DIR="${OUTPUT_DIRECTORY}") - add_executable(test_tls13handshake test_tls13handshake.c) - target_link_libraries(test_tls13handshake OpenSSL::Crypto OpenSSL::SSL) - add_test(NAME test-tls13handshake-with-provider COMMAND test_tls13handshake) - set_tests_properties(test-tls13handshake-with-provider - PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_PROVIDER}") + if(GOST_PROVIDER_ENABLE) + add_executable(test_tls13handshake test_tls13handshake.c) + target_link_libraries(test_tls13handshake OpenSSL::Crypto OpenSSL::SSL) + add_test(NAME test-tls13handshake-with-provider COMMAND test_tls13handshake) + set_tests_properties(test-tls13handshake-with-provider + PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_PROVIDER}") + endif() endif() if(NOT SKIP_PERL_TESTS) @@ -339,12 +388,16 @@ if(NOT SKIP_PERL_TESTS) ERROR_QUIET RESULT_VARIABLE MISSING_TEST2_V0) find_program(HAVE_PROVE NAMES prove) if(NOT MISSING_TEST2_V0 AND HAVE_PROVE) - add_test(NAME engine - COMMAND prove --merge -PWrapOpenSSL ${CMAKE_CURRENT_SOURCE_DIR}/test :: engine) - set_tests_properties(engine PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}") - add_test(NAME provider - COMMAND prove --merge -PWrapOpenSSL ${CMAKE_CURRENT_SOURCE_DIR}/test :: provider) - set_tests_properties(provider PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_PROVIDER}") + if(GOST_ENGINE_ENABLE) + add_test(NAME engine + COMMAND prove --merge -PWrapOpenSSL ${CMAKE_CURRENT_SOURCE_DIR}/test :: engine) + set_tests_properties(engine PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}") + endif() + if(GOST_PROVIDER_ENABLE) + add_test(NAME provider + COMMAND prove --merge -PWrapOpenSSL ${CMAKE_CURRENT_SOURCE_DIR}/test :: provider) + set_tests_properties(provider PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_PROVIDER}") + endif() else() message(STATUS "No Test2::V0 perl module (engine and provider tests skipped)") endif() @@ -360,15 +413,19 @@ set(BINARY_TESTS_TARGETS test_digest test_ciphers test_curves + test_context + test_keyexpimp + test_gost89 + ) +if(GOST_ENGINE_ENABLE) + list(APPEND BINARY_TESTS_TARGETS test_ecdhe test_params test_derive test_sign - test_context - test_keyexpimp - test_gost89 test_tls ) +endif() set_property(TARGET ${BINARY_TESTS_TARGETS} APPEND PROPERTY COMPILE_DEFINITIONS ENGINE_DIR="${OUTPUT_DIRECTORY}") add_library(gost_core STATIC ${GOST_LIB_SOURCE_FILES}) @@ -378,47 +435,54 @@ add_library(gost_err STATIC ${GOST_ERR_SOURCE_FILES}) set_target_properties(gost_err PROPERTIES POSITION_INDEPENDENT_CODE ON) target_link_libraries(gost_err PRIVATE OpenSSL::Crypto) -# The GOST engine in module form -add_library(gost_engine MODULE ${GOST_ENGINE_SOURCE_FILES}) -# Set the suffix explicitly to adapt to OpenSSL's idea of what a -# module suffix should be -set_target_properties(gost_engine PROPERTIES - PREFIX "" OUTPUT_NAME "gost" SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}) -target_link_libraries(gost_engine PRIVATE gost_core gost_err) - -if (NOT MSVC) -# The GOST engine in library form -add_library(lib_gost_engine SHARED ${GOST_ENGINE_SOURCE_FILES}) -set_target_properties(lib_gost_engine PROPERTIES - COMPILE_DEFINITIONS "BUILDING_ENGINE_AS_LIBRARY" - PUBLIC_HEADER gost-engine.h - OUTPUT_NAME "gost") -target_link_libraries(lib_gost_engine PRIVATE gost_core gost_err) -endif() - -# The GOST provider uses this -add_subdirectory(libprov) - -# The GOST provider in module form -add_library(gost_prov MODULE - ${GOST_PROV_SOURCE_FILES} ${GOST_ENGINE_SOURCE_FILES} - ) -set_target_properties(gost_prov PROPERTIES - PREFIX "" OUTPUT_NAME "gostprov" SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX} - COMPILE_DEFINITIONS "BUILDING_GOST_PROVIDER;OPENSSL_NO_DYNAMIC_ENGINE" - ) -target_link_libraries(gost_prov PRIVATE gost_core libprov) - -if (NOT MSVC) -# The GOST provider in library form -add_library(lib_gost_prov SHARED - ${GOST_PROV_SOURCE_FILES} ${GOST_ENGINE_SOURCE_FILES} - ) -set_target_properties(lib_gost_prov PROPERTIES - OUTPUT_NAME "gostprov" - COMPILE_DEFINITIONS "BUILDING_GOST_PROVIDER;BUILDING_PROVIDER_AS_LIBRARY;OPENSSL_NO_DYNAMIC_ENGINE" - ) -target_link_libraries(lib_gost_prov PRIVATE gost_core libprov) +if(GOST_ENGINE_ENABLE) + # The GOST engine in module form + add_library(gost_engine MODULE ${GOST_ENGINE_SOURCE_FILES}) + # Set the suffix explicitly to adapt to OpenSSL's idea of what a + # module suffix should be + set_target_properties(gost_engine PROPERTIES + PREFIX "" OUTPUT_NAME "gost" SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}) + target_link_libraries(gost_engine PRIVATE gost_core gost_err) + + if (NOT MSVC) + # The GOST engine in library form + add_library(lib_gost_engine SHARED ${GOST_ENGINE_SOURCE_FILES}) + set_target_properties(lib_gost_engine PROPERTIES + COMPILE_DEFINITIONS "BUILDING_ENGINE_AS_LIBRARY" + PUBLIC_HEADER gost-engine.h + OUTPUT_NAME "gost") + target_link_libraries(lib_gost_engine PRIVATE gost_core gost_err) + endif() +endif() + +if(GOST_PROVIDER_ENABLE) + # The GOST provider uses this + if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/libprov/CMakeLists.txt") + message(FATAL_ERROR "libprov submodule not found. Run 'git submodule update --init' to initialize it, or set GOST_PROVIDER_ENABLE=OFF to build without provider support.") + endif() + add_subdirectory(libprov) + + # The GOST provider in module form + add_library(gost_prov MODULE + ${GOST_PROV_SOURCE_FILES} ${GOST_ENGINE_SOURCE_FILES} + ) + set_target_properties(gost_prov PROPERTIES + PREFIX "" OUTPUT_NAME "gostprov" SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX} + COMPILE_DEFINITIONS "BUILDING_GOST_PROVIDER;OPENSSL_NO_DYNAMIC_ENGINE" + ) + target_link_libraries(gost_prov PRIVATE gost_core libprov) + + if (NOT MSVC) + # The GOST provider in library form + add_library(lib_gost_prov SHARED + ${GOST_PROV_SOURCE_FILES} ${GOST_ENGINE_SOURCE_FILES} + ) + set_target_properties(lib_gost_prov PROPERTIES + OUTPUT_NAME "gostprov" + COMPILE_DEFINITIONS "BUILDING_GOST_PROVIDER;BUILDING_PROVIDER_AS_LIBRARY;OPENSSL_NO_DYNAMIC_ENGINE" + ) + target_link_libraries(lib_gost_prov PRIVATE gost_core libprov) + endif() endif() set(GOST_SUM_SOURCE_FILES @@ -440,25 +504,29 @@ add_custom_target(tags COMMAND ctags -R . ${OPENSSL_ROOT_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) -add_custom_target(tcl_tests_provider - COMMAND OPENSSL_LIBCRYPTO=${OPENSSL_CRYPTO_LIBRARY} - OPENSSL_APP=${OPENSSL_PROGRAM} - TESTSRC=${CMAKE_SOURCE_DIR}/tcl_tests - TESTDIR=${CMAKE_BINARY_DIR}/tcl_tests_provider - OPENSSL_MODULES_DIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - OPENSSL_CONF=${CMAKE_SOURCE_DIR}/tcl_tests/openssl-gost-provider.cnf - sh ./runtest.sh - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tcl_tests) - -add_custom_target(tcl_tests_engine - COMMAND OPENSSL_LIBCRYPTO=${OPENSSL_CRYPTO_LIBRARY} - OPENSSL_APP=${OPENSSL_PROGRAM} - TESTSRC=${CMAKE_SOURCE_DIR}/tcl_tests - TESTDIR=${CMAKE_BINARY_DIR}/tcl_tests - ENGINE_DIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - OPENSSL_CONF=${CMAKE_SOURCE_DIR}/tcl_tests/openssl-gost-engine.cnf - sh ./runtest.sh - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tcl_tests) +if(GOST_PROVIDER_ENABLE) + add_custom_target(tcl_tests_provider + COMMAND OPENSSL_LIBCRYPTO=${OPENSSL_CRYPTO_LIBRARY} + OPENSSL_APP=${OPENSSL_PROGRAM} + TESTSRC=${CMAKE_SOURCE_DIR}/tcl_tests + TESTDIR=${CMAKE_BINARY_DIR}/tcl_tests_provider + OPENSSL_MODULES_DIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + OPENSSL_CONF=${CMAKE_SOURCE_DIR}/tcl_tests/openssl-gost-provider.cnf + sh ./runtest.sh + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tcl_tests) +endif() + +if(GOST_ENGINE_ENABLE) + add_custom_target(tcl_tests_engine + COMMAND OPENSSL_LIBCRYPTO=${OPENSSL_CRYPTO_LIBRARY} + OPENSSL_APP=${OPENSSL_PROGRAM} + TESTSRC=${CMAKE_SOURCE_DIR}/tcl_tests + TESTDIR=${CMAKE_BINARY_DIR}/tcl_tests + ENGINE_DIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + OPENSSL_CONF=${CMAKE_SOURCE_DIR}/tcl_tests/openssl-gost-engine.cnf + sh ./runtest.sh + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tcl_tests) +endif() add_executable(test_tlstree test_tlstree.c) target_link_libraries(test_tlstree PUBLIC OpenSSL::Crypto) @@ -468,27 +536,44 @@ install(TARGETS gostsum gost12sum RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES gostsum.1 gost12sum.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) # install engine and provider in module form -install(TARGETS gost_engine EXPORT GostEngineConfig - LIBRARY DESTINATION ${OPENSSL_ENGINES_DIR} - RUNTIME DESTINATION ${OPENSSL_ENGINES_DIR}) -install(TARGETS gost_prov EXPORT GostProviderConfig - LIBRARY DESTINATION ${OPENSSL_MODULES_DIR} - RUNTIME DESTINATION ${OPENSSL_MODULES_DIR}) -if (NOT MSVC) -# install engine and provider in library form -install(TARGETS lib_gost_engine EXPORT GostEngineConfig - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) -install(TARGETS lib_gost_prov EXPORT GostProviderConfig - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) +if(GOST_ENGINE_ENABLE) + install(TARGETS gost_engine EXPORT GostEngineConfig + LIBRARY DESTINATION ${OPENSSL_ENGINES_DIR} + RUNTIME DESTINATION ${OPENSSL_ENGINES_DIR}) + if (NOT MSVC) + # install engine in library form + install(TARGETS lib_gost_engine EXPORT GostEngineConfig + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) + endif() +endif() + +if(GOST_PROVIDER_ENABLE) + install(TARGETS gost_prov EXPORT GostProviderConfig + LIBRARY DESTINATION ${OPENSSL_MODULES_DIR} + RUNTIME DESTINATION ${OPENSSL_MODULES_DIR}) + if (NOT MSVC) + # install provider in library form + install(TARGETS lib_gost_prov EXPORT GostProviderConfig + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) + endif() endif() if (MSVC) install(FILES $ $ - EXPORT GostEngineConfig DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL) - install(FILES $ - EXPORT GostEngineConfig DESTINATION ${OPENSSL_ENGINES_DIR} OPTIONAL) - install(FILES $ - EXPORT GostProviderConfig DESTINATION ${OPENSSL_MODULES_DIR} OPTIONAL) -endif() -install(EXPORT GostEngineConfig DESTINATION share/cmake/GostEngine) -install(EXPORT GostProviderConfig DESTINATION share/cmake/GostProvider) + DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL) + if(GOST_ENGINE_ENABLE) + install(FILES $ + EXPORT GostEngineConfig DESTINATION ${OPENSSL_ENGINES_DIR} OPTIONAL) + endif() + if(GOST_PROVIDER_ENABLE) + install(FILES $ + EXPORT GostProviderConfig DESTINATION ${OPENSSL_MODULES_DIR} OPTIONAL) + endif() +endif() + +if(GOST_ENGINE_ENABLE) + install(EXPORT GostEngineConfig DESTINATION share/cmake/GostEngine) +endif() +if(GOST_PROVIDER_ENABLE) + install(EXPORT GostProviderConfig DESTINATION share/cmake/GostProvider) +endif() diff --git a/INSTALL.md b/INSTALL.md index 9d3fa5f9..ee59243e 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -4,9 +4,9 @@ Building and Installation How to Build ------------ -To build and install OpenSSL GOST Engine, you will need +To build and install OpenSSL GOST Engine and/or Provider, you will need -* OpenSSL 3.0 development version +* OpenSSL 3.0 or later development version * an ANSI C compiler * CMake (3.0 or newer, 3.18 recommended) @@ -24,6 +24,38 @@ Instead of `Release` you can use `Debug`, `RelWithDebInfo` or `MinSizeRel` confi See [cmake docs](https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html) for details. You will find built binaries in `../bin` directory. +Build Options +------------- + +The build system provides two CMake options to control what gets built: + +* `GOST_ENGINE_ENABLE` - Build the GOST engine (default: ON when Engine API is available, OFF otherwise) +* `GOST_PROVIDER_ENABLE` - Build the GOST provider (default: ON) + +### Building for OpenSSL 4.x + +OpenSSL 4.x removed the Engine API. To build for OpenSSL 4.x, disable the engine: + + $ cmake -DCMAKE_BUILD_TYPE=Release -DGOST_ENGINE_ENABLE=OFF .. + $ cmake --build . --config Release + +### Building only the Engine (OpenSSL 3.x) + +If you only want to build the engine: + + $ cmake -DCMAKE_BUILD_TYPE=Release -DGOST_PROVIDER_ENABLE=OFF .. + $ cmake --build . --config Release + +### Building both Engine and Provider (OpenSSL 3.x) + +By default, both are built when using OpenSSL 3.x: + + $ cmake -DCMAKE_BUILD_TYPE=Release .. + $ cmake --build . --config Release + +Custom OpenSSL Installation +--------------------------- + If you want to build against a specific OpenSSL instance (you will need it if you have more than one OpenSSL instance for example), you can use the `cmake` variable `OPENSSL_ROOT_DIR` to specify absolute path of the desirable OpenSSL @@ -35,6 +67,9 @@ Building against OpenSSL 3.0 requires openssl detection module (FindOpenSSL.cmake) from CMake 3.18 or higher. More earlier versions may have problems with it. +Visual Studio +------------- + If you use Visual Studio, you can also set `CMAKE_INSTALL_PREFIX` variable to set install path, like this: diff --git a/README.md b/README.md index 0a128151..cab62eb4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A reference implementation of the Russian GOST crypto algorithms for OpenSSL -Compatibility: OpenSSL 3.0 +Compatibility: OpenSSL 3.0 and later License: same as the corresponding version of OpenSSL. @@ -12,6 +12,38 @@ Some useful links: https://www.altlinux.org/OSS-GOST-Crypto DO NOT TRY BUILDING MASTER BRANCH AGAINST openssl 1.1.1! Use 1_1_1 branch instead! +## Building for OpenSSL 3.x + +By default, both the GOST engine and provider are built. You can control this using CMake options: + +- `GOST_ENGINE_ENABLE` - Build the GOST engine (default: ON for OpenSSL 3.x, OFF for OpenSSL 4.x) +- `GOST_PROVIDER_ENABLE` - Build the GOST provider (default: ON) + +### Building both Engine and Provider (OpenSSL 3.x) + +```bash +cmake -DCMAKE_BUILD_TYPE=Release .. +cmake --build . --config Release +``` + +### Building only the Provider (for OpenSSL 4.x compatibility) + +Since OpenSSL 4.x removed the Engine API, use this configuration: + +```bash +cmake -DCMAKE_BUILD_TYPE=Release -DGOST_ENGINE_ENABLE=OFF .. +cmake --build . --config Release +``` + +### Building only the Engine (OpenSSL 3.x) + +```bash +cmake -DCMAKE_BUILD_TYPE=Release -DGOST_PROVIDER_ENABLE=OFF .. +cmake --build . --config Release +``` + +The build system will automatically detect if the Engine API is available in your OpenSSL version. + # provider A reference implementation in the same spirit as the engine, specified diff --git a/gost_lcl.h b/gost_lcl.h index e11f4437..9bdeb554 100644 --- a/gost_lcl.h +++ b/gost_lcl.h @@ -15,7 +15,9 @@ # include # include # include -# include +# ifndef OPENSSL_NO_ENGINE +# include +# endif # include # include # include "gost89.h" @@ -42,9 +44,11 @@ EVP_CTRL_SET_TLSTREE_PARAMS definition in OpenSSL is expected." # define GOST_PARAM_PBE_PARAMS 1 # define GOST_PARAM_PK_FORMAT 2 # define GOST_PARAM_MAX 3 -# define GOST_CTRL_CRYPT_PARAMS (ENGINE_CMD_BASE+GOST_PARAM_CRYPT_PARAMS) -# define GOST_CTRL_PBE_PARAMS (ENGINE_CMD_BASE+GOST_PARAM_PBE_PARAMS) -# define GOST_CTRL_PK_FORMAT (ENGINE_CMD_BASE+GOST_PARAM_PK_FORMAT) +# ifndef OPENSSL_NO_ENGINE +# define GOST_CTRL_CRYPT_PARAMS (ENGINE_CMD_BASE+GOST_PARAM_CRYPT_PARAMS) +# define GOST_CTRL_PBE_PARAMS (ENGINE_CMD_BASE+GOST_PARAM_PBE_PARAMS) +# define GOST_CTRL_PK_FORMAT (ENGINE_CMD_BASE+GOST_PARAM_PK_FORMAT) +# endif typedef struct R3410_ec { int nid; @@ -63,8 +67,10 @@ extern R3410_ec_params R3410_2001_paramset[], void free_cached_groups(void); +# ifndef OPENSSL_NO_ENGINE extern const ENGINE_CMD_DEFN gost_cmds[]; int gost_control_func(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); +# endif const char *get_gost_engine_param(int param); int gost_set_default_param(int param, const char *value); void gost_param_free(void); @@ -72,7 +78,9 @@ void gost_param_free(void); /* method registration */ int register_ameth_gost(int nid, EVP_PKEY_ASN1_METHOD **ameth, const char *pemstr, const char *info); +# ifndef OPENSSL_NO_ENGINE int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags); +# endif /* Gost-specific pmeth control-function parameters */ /* For GOST R34.10 parameters */ diff --git a/gost_pmeth.c b/gost_pmeth.c index 8f8c057d..4a77c3f4 100644 --- a/gost_pmeth.c +++ b/gost_pmeth.c @@ -19,6 +19,8 @@ #include "gost_lcl.h" #include "e_gost_err.h" +#ifndef OPENSSL_NO_ENGINE + #define ossl3_const #ifdef OPENSSL_VERSION_MAJOR #undef ossl3_const @@ -1270,3 +1272,4 @@ int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags) return 1; } +#endif /* OPENSSL_NO_ENGINE */ diff --git a/test_ciphers.c b/test_ciphers.c index 60384988..bc0cca35 100644 --- a/test_ciphers.c +++ b/test_ciphers.c @@ -10,7 +10,9 @@ # include # pragma warning(pop) #endif -#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif #include #include #include @@ -505,6 +507,7 @@ static int test_stream(const EVP_CIPHER *type, const char *name, return ret; } +#ifndef OPENSSL_NO_ENGINE int engine_is_available(const char *name) { ENGINE *e = ENGINE_get_first(); @@ -517,6 +520,7 @@ int engine_is_available(const char *name) ENGINE_free(e); return 0; } +#endif void warn_if_untested(const EVP_CIPHER *ciph, void *provider) { @@ -535,6 +539,7 @@ void warn_if_untested(const EVP_CIPHER *ciph, void *provider) void warn_all_untested(void) { +#ifndef OPENSSL_NO_ENGINE if (engine_is_available("gost")) { ENGINE *eng; @@ -551,6 +556,7 @@ void warn_all_untested(void) ENGINE_finish(eng); ENGINE_free(eng); } +#endif if (OSSL_PROVIDER_available(NULL, "gostprov")) { OSSL_PROVIDER *prov; diff --git a/test_digest.c b/test_digest.c index 38cc2ebd..3801d4d9 100644 --- a/test_digest.c +++ b/test_digest.c @@ -13,7 +13,9 @@ # pragma warning(pop) #endif #include -#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif #include #include #include @@ -944,6 +946,7 @@ static int do_synthetic_test(const struct hash_testvec *tv) return 0; } +#ifndef OPENSSL_NO_ENGINE int engine_is_available(const char *name) { ENGINE *e = ENGINE_get_first(); @@ -956,6 +959,7 @@ int engine_is_available(const char *name) ENGINE_free(e); return e != NULL; } +#endif void warn_if_untested(const EVP_MD *dgst, void *provider) { @@ -974,6 +978,7 @@ void warn_if_untested(const EVP_MD *dgst, void *provider) void warn_all_untested(void) { +#ifndef OPENSSL_NO_ENGINE if (engine_is_available("gost")) { ENGINE *eng; @@ -990,6 +995,7 @@ void warn_all_untested(void) ENGINE_finish(eng); ENGINE_free(eng); } +#endif if (OSSL_PROVIDER_available(NULL, "gostprov")) { OSSL_PROVIDER *prov;