From bab4388f9efe19e26a8734387038d2cbcb073c53 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 24 Dec 2025 11:52:31 +0000 Subject: [PATCH 1/7] Initial plan From 7fdca3503c8f6818d8b0cc9d5fc770225cd4b0f2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 24 Dec 2025 12:01:02 +0000 Subject: [PATCH 2/7] Add CMake options for conditional Engine/Provider builds - Add GOST_ENGINE_ENABLE and GOST_PROVIDER_ENABLE options - Auto-detect Engine API availability via OPENSSL_NO_ENGINE - Conditionally build engine/provider targets based on options - Wrap ENGINE API usage in test files with #ifndef OPENSSL_NO_ENGINE - Update install targets to be conditional Co-authored-by: chipitsine <2217296+chipitsine@users.noreply.github.com> --- CMakeLists.txt | 388 ++++++++++++++++++++++++++++++------------------- test_ciphers.c | 8 +- test_digest.c | 8 +- 3 files changed, 249 insertions(+), 155 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 60552abf0..6a86af59b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,31 @@ enable_testing() find_package(OpenSSL 3.4 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.") set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build." FORCE) @@ -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,51 @@ 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 + 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 +501,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 +533,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/test_ciphers.c b/test_ciphers.c index 60384988e..bc0cca354 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 38cc2ebd6..3801d4d95 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; From f543b4912574763e8e74acd695a5baad7b113339 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 24 Dec 2025 12:03:41 +0000 Subject: [PATCH 3/7] Update documentation for Engine/Provider build options - Add build instructions for OpenSSL 4.x (provider-only) - Document GOST_ENGINE_ENABLE and GOST_PROVIDER_ENABLE options - Update README.md and INSTALL.md with examples Co-authored-by: chipitsine <2217296+chipitsine@users.noreply.github.com> --- CMakeLists.txt | 2 +- INSTALL.md | 39 +++++++++++++++++++++++++++++++++++++-- README.md | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a86af59b..7a3d7bea8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ include(CheckCSourceRuns) enable_testing() -find_package(OpenSSL 3.4 REQUIRED) +find_package(OpenSSL 3.0 REQUIRED) # Detect if OpenSSL supports Engine API include(CheckCSourceCompiles) diff --git a/INSTALL.md b/INSTALL.md index 9d3fa5f91..ee59243e9 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 0a1281511..cab62eb4d 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 From bb8200938d8e0af49ec7b2f5822eb0b317b10a06 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 24 Dec 2025 12:06:55 +0000 Subject: [PATCH 4/7] Guard ENGINE-specific code in gost_lcl.h for OpenSSL 4.x compatibility - Wrap ENGINE header include with #ifndef OPENSSL_NO_ENGINE - Guard ENGINE_CMD_BASE macros with conditional compilation - Protect ENGINE function declarations - Allows provider code to compile without Engine API Co-authored-by: chipitsine <2217296+chipitsine@users.noreply.github.com> --- gost_lcl.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/gost_lcl.h b/gost_lcl.h index e11f4437f..125242236 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); From 392c3bf6013ac8f58202def22fbec54498e5e55a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 24 Dec 2025 16:56:47 +0000 Subject: [PATCH 5/7] Add clearer error message when libprov submodule is missing Provides helpful guidance to users when the libprov submodule hasn't been initialized, suggesting either to run 'git submodule update --init' or disable provider build with GOST_PROVIDER_ENABLE=OFF. Co-authored-by: chipitsine <2217296+chipitsine@users.noreply.github.com> --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a3d7bea8..63d9efeb2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -457,6 +457,9 @@ 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 From adcbf32e0540f3500012c9201292b76f440896fc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 24 Dec 2025 17:30:02 +0000 Subject: [PATCH 6/7] Enable OpenSSL master branch tests for pull requests Modified CI workflow to run tests against OpenSSL master (development) branch on pull requests in addition to scheduled runs. This enables testing compatibility with upcoming OpenSSL 4.x which removes the Engine API. Tests enabled: - gcc-openssl-master - macos-openssl-master - gcc-asan-openssl-master - macos-asan-openssl-master Co-authored-by: chipitsine <2217296+chipitsine@users.noreply.github.com> --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 78169a387..eb2446c08 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 From b838ba4bf62d5a038206844095c6d09ab78d8876 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 24 Dec 2025 20:30:22 +0000 Subject: [PATCH 7/7] Guard ENGINE-specific code in gost_pmeth.c for OpenSSL 4.x compatibility Wrap ENGINE-specific PKEY method code with #ifndef OPENSSL_NO_ENGINE guards to allow provider-only builds when ENGINE API is unavailable (OpenSSL 4.x). Changes: - Wrapped gost_pmeth.c ENGINE-specific functions with conditional compilation - Guarded register_pmeth_gost() declaration in gost_lcl.h - Enables provider-only build without ENGINE dependencies - Fixes build failures on OpenSSL 4.x where ENGINE API was removed The provider code still requires OpenSSL 3.4+ APIs which is a pre-existing limitation. Co-authored-by: chipitsine <2217296+chipitsine@users.noreply.github.com> --- gost_lcl.h | 2 ++ gost_pmeth.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/gost_lcl.h b/gost_lcl.h index 125242236..9bdeb5544 100644 --- a/gost_lcl.h +++ b/gost_lcl.h @@ -78,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 8f8c057d6..4a77c3f4a 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 */