diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 172476ac4..5f071b0b5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -131,14 +131,14 @@ jobs: container: ubuntu:${{ matrix.container }} strategy: matrix: - container: ['20.04', '22.04', '24.04', '24.10'] + container: ['22.04', '24.04', '24.10'] env: DEBIAN_FRONTEND: noninteractive DEBFULLNAME: github-actions DEBEMAIL: github-actions@github.com steps: - name: Install dependencies - run: apt update -qq && apt install --no-install-recommends -y lsb-release build-essential devscripts debhelper lintian pkg-config ${UBUNTU_DEPS} doxygen swig openjdk-11-jdk-headless libpython3-dev python3-setuptools libboost-test-dev + run: apt update -qq && apt install --no-install-recommends -y lsb-release build-essential devscripts debhelper lintian pkg-config ${UBUNTU_DEPS} doxygen swig openjdk-17-jdk-headless libpython3-dev python3-setuptools libboost-test-dev - name: Checkout uses: actions/checkout@v4 - name: Setup changelog @@ -148,7 +148,7 @@ jobs: dch --distribution $(lsb_release -cs) -v ${VERSIONEX} "Release ${VERSIONEX}." - name: Build packages run: | - dpkg-buildpackage -us -uc + JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 dpkg-buildpackage -us -uc mv ../libdigidocpp*.* . - name: Lintian run: lintian *.deb; diff --git a/CMakeLists.txt b/CMakeLists.txt index b1feeca85..81d820414 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,4 @@ -cmake_minimum_required(VERSION 3.16) -if(POLICY CMP0122) - cmake_policy(SET CMP0122 NEW) -endif() +cmake_minimum_required(VERSION 3.22) if(POLICY CMP0167) cmake_policy(SET CMP0167 NEW) endif() @@ -58,29 +55,28 @@ if(APPLE) set(FRAMEWORK_DESTINATION /Library/Frameworks CACHE PATH "Mac OS X Framework install destination") endif() -find_package(OpenSSL 1.1.1 REQUIRED) +find_package(OpenSSL 3.0.0 REQUIRED) find_package(PKCS11) #find_package(PoDoFo) find_package(Threads) find_package(LibXml2 REQUIRED) find_package(ZLIB REQUIRED) find_package(MiniZip 1 QUIET) -add_library(xmlsec INTERFACE) if(UNIX) find_package(PkgConfig) find_package(unofficial-xmlsec QUIET) if(TARGET unofficial::xmlsec::xmlsec1-openssl) - target_link_libraries(xmlsec INTERFACE unofficial::xmlsec::xmlsec1-openssl) + add_library(xmlsec ALIAS unofficial::xmlsec::xmlsec1-openssl) else() pkg_check_modules(XMLSEC1_OPENSSL xmlsec1-openssl REQUIRED IMPORTED_TARGET) - target_link_libraries(xmlsec INTERFACE PkgConfig::XMLSEC1_OPENSSL) + add_library(xmlsec ALIAS PkgConfig::XMLSEC1_OPENSSL) endif() if(NOT APPLE) pkg_check_modules(MINIZIP minizip IMPORTED_TARGET) endif() else() find_package(unofficial-xmlsec REQUIRED) - target_link_libraries(xmlsec INTERFACE unofficial::xmlsec::xmlsec1-openssl) + add_library(xmlsec ALIAS unofficial::xmlsec::xmlsec1-openssl) endif() find_package(SWIG) if(SWIG_FOUND) diff --git a/debian/control b/debian/control index 1142dc8a9..60cd77f13 100644 --- a/debian/control +++ b/debian/control @@ -3,17 +3,18 @@ Section: libs Priority: optional Maintainer: RIA Build-Depends: - debhelper-compat (= 12), + debhelper-compat (= 13), pkg-config, cmake, libxml2-dev, libxmlsec1-dev, doxygen, swig, - java11-sdk-headless, + java17-sdk-headless, libpython3-dev, python3-setuptools -Standards-Version: 4.5.1 +Standards-Version: 4.6.1 +Rules-Requires-Root: no Homepage: https://github.com/open-eid/libdigidocpp Package: libdigidocpp-common @@ -65,10 +66,12 @@ Description: DigiDoc digital signature library tools Package: libdigidocpp-dev Architecture: any +Multi-Arch: same Section: libdevel Depends: libdigidocpp1 (= ${binary:Version}), ${misc:Depends} +Suggests: libdigidocpp-doc Description: DigiDoc digital signature library development files This package contains files necessary for developing applications with the DigiDoc digital signature library. @@ -109,6 +112,7 @@ Description: DigiDoc digital signature python bindings Package: libdigidocpp-doc Architecture: all +Multi-Arch: foreign Section: doc Depends: ${misc:Depends} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 437003ce2..3dc2a7a09 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,5 @@ if(TARGET PkgConfig::MINIZIP) - add_library(minizip INTERFACE) - target_link_libraries(minizip INTERFACE PkgConfig::MINIZIP) + add_library(minizip ALIAS PkgConfig::MINIZIP) else() message(STATUS "MiniZip not found; using bundled copy.") add_library(minizip STATIC minizip/zip.c minizip/unzip.c minizip/ioapi.c $<$:minizip/iowin32.c>) diff --git a/src/SignatureXAdES_B.cpp b/src/SignatureXAdES_B.cpp index 02f473b7d..05fd3d290 100644 --- a/src/SignatureXAdES_B.cpp +++ b/src/SignatureXAdES_B.cpp @@ -23,7 +23,6 @@ #include "Conf.h" #include "DataFile_p.h" #include "crypto/Digest.h" -#include "crypto/OpenSSLHelpers.h" #include "crypto/Signer.h" #include "crypto/X509CertStore.h" #include "crypto/X509Crypto.h" @@ -117,11 +116,7 @@ int initXmlSecCallback() { Exception e(orUnknown(file), line, Log::format("%s:obj=%s:subj=%s:reason=%d - %s", func, orUnknown(errorObject), orUnknown(errorSubject), reason, error_msg)); -#if OPENSSL_VERSION_NUMBER < 0x30000000L - while(unsigned long error = ERR_get_error_line(&ofile, &oline)) -#else while(unsigned long error = ERR_get_error_all(&ofile, &oline, &ofunc, nullptr, nullptr)) -#endif { Exception err(ofile, oline, ERR_error_string(error, nullptr)); #ifndef LIBRESSL_VERSION_NUMBER @@ -142,11 +137,7 @@ int initXmlSecCallback() func, orUnknown(errorObject), orUnknown(errorSubject), reason, error_msg, msg); if(reason == XMLSEC_ERRORS_R_CRYPTO_FAILED) { -#if OPENSSL_VERSION_NUMBER < 0x30000000L - while(unsigned long error = ERR_get_error_line(&ofile, &oline)) -#else while(unsigned long error = ERR_get_error_all(&ofile, &oline, &ofunc, nullptr, nullptr)) -#endif Log::out(Log::WarnType, ofile, unsigned(oline), "%s: %s", ofunc, ERR_error_string(error, nullptr)); } @@ -185,7 +176,7 @@ int initXmlSecCallback() return {}; } - auto *is = dynamic_cast(file)->m_is.get(); + auto *is = static_cast(file)->m_is.get(); is->clear(); is->seekg(0); return is; diff --git a/src/crypto/Connect.cpp b/src/crypto/Connect.cpp index 9271ba3f5..c21a79f6d 100644 --- a/src/crypto/Connect.cpp +++ b/src/crypto/Connect.cpp @@ -33,10 +33,6 @@ #include #include -#ifdef _WIN32 -#include -#endif - #if defined(__aarch64__) || defined(__ARM64__) || defined(_M_ARM64) #define TARGET_ARCH "arm64" #elif defined(__arm__) || defined(_M_ARM) @@ -101,24 +97,10 @@ Connect::Connect(const string &_url, string _method, int _timeout, const vector< BIO_set_nbio(d, _timeout > 0); auto start = chrono::high_resolution_clock::now(); -#if OPENSSL_VERSION_NUMBER < 0x30000000L - while(BIO_do_connect(d) != 1) - { - if(_timeout == 0) - THROW_NETWORKEXCEPTION("Failed to connect to host: '%s'", hostname.c_str()) - if(!BIO_should_retry(d)) - THROW_NETWORKEXCEPTION("Failed to connect to host: '%s'", hostname.c_str()) - auto end = chrono::high_resolution_clock::now(); - if(chrono::duration_cast(end - start).count() >= _timeout) - THROW_NETWORKEXCEPTION("Failed to create connection with host timeout: '%s'", hostname.c_str()) - this_thread::sleep_for(chrono::milliseconds(50)); - } -#else if(timeout > 0 && BIO_do_connect_retry(d, timeout, -1) < 1) THROW_NETWORKEXCEPTION("Failed to create connection with host timeout: '%s'", hostname.c_str()) if(timeout == 0 && BIO_do_connect(d) < 1) THROW_NETWORKEXCEPTION("Failed to create connection with host: '%s'", hostname.c_str()) -#endif if(usessl > 0) { @@ -176,20 +158,6 @@ Connect::Connect(const string &_url, string _method, int _timeout, const vector< } } -#if OPENSSL_VERSION_NUMBER < 0x30000000L - if(_timeout > 0) - { - int fd = BIO_get_fd(d, nullptr); - fd_set confds; - FD_ZERO(&confds); - FD_SET(fd, &confds); - timeval tv { timeout, 0 }; - int read = BIO_should_read(d); - if(select(fd + 1, read ? &confds : nullptr, read ? nullptr : &confds, nullptr, &tv) == -1) - DEBUG("select failed"); - } -#endif - BIO_printf(d, "%s %s HTTP/1.1\r\n", method.c_str(), path.c_str()); addHeader("Connection", "close"); if(port == "80" || port == "443") diff --git a/src/crypto/OCSP.cpp b/src/crypto/OCSP.cpp index c6b9b3e21..cb8467a4a 100644 --- a/src/crypto/OCSP.cpp +++ b/src/crypto/OCSP.cpp @@ -86,7 +86,7 @@ OCSP::OCSP(const X509Cert &cert, const X509Cert &issuer, const std::string &user {"Accept", "application/ocsp-response"}, {"Connection", "Close"}, {"Cache-Control", "no-cache"} - }, i2d(req, i2d_OCSP_REQUEST)); + }, i2d(req)); if(result.isForbidden()) THROW("OCSP service responded - Forbidden"); @@ -179,7 +179,7 @@ X509Cert OCSP::responderCert() const OCSP::operator vector() const { - return i2d(resp, i2d_OCSP_RESPONSE); + return i2d(resp); } /** @@ -199,11 +199,7 @@ void OCSP::verifyResponse(const X509Cert &cert) const sk_X509_push(stack.get(), i.handle()); } auto store = X509CertStore::createStore(X509CertStore::OCSP, tm); -#if OPENSSL_VERSION_NUMBER < 0x30000000L - if(OCSP_basic_verify(basic.get(), stack.get(), store.get(), OCSP_NOCHECKS) != 1) -#else if(OCSP_basic_verify(basic.get(), stack.get(), store.get(), OCSP_NOCHECKS | OCSP_PARTIAL_CHAIN) != 1) -#endif { unsigned long err = ERR_get_error(); if(ERR_GET_LIB(err) == ERR_LIB_OCSP && diff --git a/src/crypto/OpenSSLHelpers.h b/src/crypto/OpenSSLHelpers.h index 3c87757c0..b2ca6252e 100644 --- a/src/crypto/OpenSSLHelpers.h +++ b/src/crypto/OpenSSLHelpers.h @@ -25,38 +25,33 @@ #include -#ifndef RSA_PSS_SALTLEN_DIGEST -#define RSA_PSS_SALTLEN_DIGEST -1 -#endif - namespace digidoc { -#define SCOPE_PTR_FREE(TYPE, DATA, FREE) make_unique_ptr(DATA, FREE) -#define SCOPE_PTR(TYPE, DATA) SCOPE_PTR_FREE(TYPE, DATA, TYPE##_free) -#define SCOPE(TYPE, VAR, DATA) auto VAR = SCOPE_PTR_FREE(TYPE, DATA, TYPE##_free) +#define SCOPE_PTR(TYPE, DATA) make_unique_ptr(DATA, TYPE##_free) +#define SCOPE(TYPE, VAR, DATA) auto VAR = make_unique_ptr(DATA, TYPE##_free) -template +template [[nodiscard]] -inline std::vector i2d(T *obj, Func func) +inline std::vector i2d(T *obj) { std::vector result; if(!obj) return result; - int size = func(obj, nullptr); + int size = F(obj, nullptr); if(size <= 0) return result; result.resize(size_t(size), 0); - if(unsigned char *p = result.data(); func(obj, &p) != size) + if(unsigned char *p = result.data(); F(obj, &p) != size) result.clear(); return result; } -template +template [[nodiscard]] -inline std::vector i2d(const T &obj, Func func) +inline std::vector i2d(const T &obj) { - return i2d(obj.get(), std::forward(func)); + return i2d(obj.get()); } /** @@ -72,11 +67,7 @@ class OpenSSLException : public Exception { Exception e(ERR_lib_error_string(error), 0, ERR_error_string(error, nullptr)); #ifndef LIBRESSL_VERSION_NUMBER - if(ERR_GET_LIB(error) == ERR_R_BIO_LIB && -#if OPENSSL_VERSION_NUMBER < 0x30000000L - ERR_GET_FUNC(error) == BIO_F_BIO_LOOKUP_EX && -#endif - ERR_GET_REASON(error) == ERR_R_SYS_LIB) + if(ERR_GET_LIB(error) == ERR_R_BIO_LIB && ERR_GET_REASON(error) == ERR_R_SYS_LIB) e.setCode(ExceptionCode::HostNotFound); #endif addCause(e); diff --git a/src/crypto/TS.cpp b/src/crypto/TS.cpp index 5dfb3a1b1..08ff3ce10 100644 --- a/src/crypto/TS.cpp +++ b/src/crypto/TS.cpp @@ -92,7 +92,7 @@ TS::TS(const Digest &digest, const std::string &userAgent) {"Accept", "application/timestamp-reply"}, {"Connection", "Close"}, {"Cache-Control", "no-cache"} - }, i2d(req, i2d_TS_REQ)); + }, i2d(req)); if(result.isForbidden()) { @@ -195,14 +195,14 @@ string TS::digestMethod() const vector TS::digestValue() const { if(auto info = tstInfo()) - return i2d(TS_MSG_IMPRINT_get_msg(TS_TST_INFO_get_msg_imprint(info.get())), i2d_ASN1_OCTET_STRING); + return i2d(TS_MSG_IMPRINT_get_msg(TS_TST_INFO_get_msg_imprint(info.get()))); return {}; } vector TS::messageImprint() const { if(auto info = tstInfo()) - return i2d(TS_TST_INFO_get_msg_imprint(info.get()), i2d_TS_MSG_IMPRINT); + return i2d(TS_TST_INFO_get_msg_imprint(info.get())); return {}; } @@ -212,7 +212,7 @@ string TS::serial() const if(!info) return {}; - if(auto bn = SCOPE_PTR_FREE(BIGNUM, ASN1_INTEGER_to_BN(TS_TST_INFO_get_serial(info.get()), nullptr), BN_free)) + if(auto bn = make_unique_ptr(ASN1_INTEGER_to_BN(TS_TST_INFO_get_serial(info.get()), nullptr), BN_free)) { if(auto str = make_unique_ptr(BN_bn2dec(bn.get()), [](char *data) { OPENSSL_free(data); })) return str.get(); @@ -281,7 +281,7 @@ TS::operator vector() const { #ifndef OPENSSL_NO_CMS if(cms) - return i2d(cms, i2d_CMS_ContentInfo); + return i2d(cms); #endif - return i2d(d, i2d_PKCS7); + return i2d(d); } diff --git a/src/crypto/X509Cert.cpp b/src/crypto/X509Cert.cpp index cc66b8f61..75aff5ca8 100644 --- a/src/crypto/X509Cert.cpp +++ b/src/crypto/X509Cert.cpp @@ -27,7 +27,6 @@ #include #include -#include #include using namespace digidoc; @@ -279,7 +278,7 @@ X509Cert::~X509Cert() = default; */ X509Cert::operator std::vector() const { - return i2d(cert, i2d_X509); + return i2d(cert); } /** @@ -299,7 +298,7 @@ string X509Cert::serial() const { if(!cert) return {}; - if(auto bn = SCOPE_PTR_FREE(BIGNUM, ASN1_INTEGER_to_BN(X509_get_serialNumber(cert.get()), nullptr), BN_free)) + if(auto bn = make_unique_ptr(ASN1_INTEGER_to_BN(X509_get_serialNumber(cert.get()), nullptr), BN_free)) { auto openssl_free = [](char *data) { OPENSSL_free(data); }; if(auto str = unique_ptr(BN_bn2dec(bn.get()), openssl_free)) @@ -317,7 +316,7 @@ string X509Cert::serial() const */ string X509Cert::issuerName(const string &obj) const { - return toString(X509_get_issuer_name, obj); + return toString(obj); } /** @@ -421,7 +420,7 @@ vector X509Cert::qcStatements() const */ string X509Cert::subjectName(const string &obj) const { - return toString(X509_get_subject_name, obj); + return toString(obj); } string X509Cert::toOID(ASN1_OBJECT *obj) @@ -434,18 +433,17 @@ string X509Cert::toOID(ASN1_OBJECT *obj) /** * Converts X509_NAME struct to string. * - * @param func X509_NAME struct that is converted to string. * @param obj Optional parameter to get from X509_NAME (default CN). * @return converted value of X509_NAME. * @throws Exception throws exception if conversion failed. */ -template -string X509Cert::toString(Func func, const string &obj) const +template +string X509Cert::toString(const string &obj) const { string str; if(!cert) return str; - X509_NAME* name = func(cert.get()); + X509_NAME* name = Func(cert.get()); if(!name) THROW_OPENSSLEXCEPTION("Failed to convert X.509 certificate subject"); @@ -551,9 +549,7 @@ bool X509Cert::operator ==(const X509Cert &other) const return true; if(!cert || !other.cert) return false; - // Workaround OpenSSL 1.1.1f issues - return vector(*this) == vector(other); - //return X509_cmp(cert.get(), other.cert.get()) == 0 + return X509_cmp(cert.get(), other.cert.get()) == 0; } /** diff --git a/src/crypto/X509Cert.h b/src/crypto/X509Cert.h index eed3bb210..c1b44f341 100644 --- a/src/crypto/X509Cert.h +++ b/src/crypto/X509Cert.h @@ -109,8 +109,8 @@ namespace digidoc private: static std::string toOID(ASN1_OBJECT *obj); - template - std::string toString(Func func, const std::string &obj) const; + template + std::string toString(const std::string &obj) const; std::shared_ptr cert; }; }