0
0
mirror of https://github.com/keepassxreboot/keepassxc.git synced 2024-09-19 20:02:18 +02:00

Fix Botan 3 build (#9388)

* SymmetricCipher: Fix Botan 3 build

Botan commit 819cf8fe6278a19b8266f449228f02fc28a4f784 changed
Botan::Cipher_Dir to be a scoped enumeration, so the users
must be adapted.

This change causes no issues with Botan 2 because normal
enumeration values can also be referred to the same way
scoped enumeration values are accessed.

* Auto detect Botan3

* AsyncTask: Do not use `std::result_of`

`std::result_of` was deprecated in C++17 and then it was
subsequently removed in C++20. One could use `std::invoke_result_t`,
but let Qt figure out the return type instead.

* Collapse Botan2 and Botan3 find package into one

* Update COPYING

---------

Co-authored-by: Jonathan White <support@dmapps.us>
This commit is contained in:
Barnabás Pőcze 2023-05-07 14:48:58 +02:00 committed by GitHub
parent cf819e0a3f
commit 16b3d32ca5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 94 additions and 259 deletions

View File

@ -61,7 +61,6 @@ if(UNIX AND NOT APPLE)
option(WITH_XC_FDOSECRETS "Implement freedesktop.org Secret Storage Spec server side API." OFF)
endif()
option(WITH_XC_DOCS "Enable building of documentation" ON)
option(KPXC_DEV_BOTAN3 "Build against Botan3" OFF)
set(WITH_XC_X11 ON CACHE BOOL "Enable building with X11 deps")
@ -204,6 +203,16 @@ if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14.0")
check_pie_supported()
endif()
# Find Botan early since the version affects subsequent compiler options
find_package(Botan REQUIRED)
if(BOTAN_VERSION VERSION_GREATER_EQUAL "3.0.0")
set(WITH_XC_BOTAN3 TRUE)
elseif(BOTAN_VERSION VERSION_LESS "2.11.0")
# Check for minimum Botan version
message(FATAL_ERROR "Botan 2.11.0 or higher is required")
endif()
include_directories(SYSTEM ${BOTAN_INCLUDE_DIR})
# Create position independent code for shared libraries and executables
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
@ -300,7 +309,7 @@ if(CMAKE_BUILD_TYPE_LOWER STREQUAL "debug")
check_add_gcc_compiler_flag("-Wshadow-local")
add_gcc_compiler_flags("-Werror")
# This is needed since compiling aginst Botan3 requires compiling against C++20
if(KPXC_DEV_BOTAN3)
if(WITH_XC_BOTAN3)
add_gcc_compiler_cxxflags("-Wno-error=deprecated-enum-enum-conversion -Wno-error=deprecated")
endif()
endif()
@ -348,7 +357,7 @@ if(UNIX AND NOT APPLE)
endif()
set(CMAKE_C_STANDARD 99)
if(KPXC_DEV_BOTAN3)
if(WITH_XC_BOTAN3)
set(CMAKE_CXX_STANDARD 20)
else()
set(CMAKE_CXX_STANDARD 17)
@ -538,26 +547,6 @@ endif()
# Make sure we don't enable asserts there.
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_NONE QT_NO_DEBUG)
if(KPXC_DEV_BOTAN3)
# Find Botan3
find_package(Botan3 REQUIRED)
if(BOTAN3_VERSION VERSION_LESS "3.0.0")
message(FATAL_ERROR "Botan3 3.0.0 or higher is required")
endif()
set(BOTAN_VERSION "${BOTAN3_VERSION}")
set(BOTAN_INCLUDE_DIR "${BOTAN3_INCLUDE_DIR}")
set(BOTAN_LIBRARIES "${BOTAN3_LIBRARIES}")
else()
# Find Botan2
find_package(Botan2 REQUIRED)
if(BOTAN2_VERSION VERSION_LESS "2.11.0")
message(FATAL_ERROR "Botan2 2.11.0 or higher is required")
endif()
set(BOTAN_VERSION "${BOTAN2_VERSION}")
set(BOTAN_INCLUDE_DIR "${BOTAN2_INCLUDE_DIR}")
set(BOTAN_LIBRARIES "${BOTAN2_LIBRARIES}")
endif()
include_directories(SYSTEM ${BOTAN_INCLUDE_DIR})
# Find Argon2 -- Botan 2.18 and below does not support threaded Argon2
find_library(ARGON2_LIBRARIES NAMES argon2)
find_path(ARGON2_INCLUDE_DIR NAMES argon2.h PATH_SUFFIXES local/include)

16
COPYING
View File

@ -27,28 +27,24 @@ Copyright: 2010-2012, Felix Geyer <debfx@fobos.de>
2000-2008, Tom Sato <VEF00200@nifty.ne.jp>
2013, Laszlo Papp <lpapp@kde.org>
2013, David Faure <faure@kde.org>
2016-2020, KeePassXC Team <team@keepassxc.org>
2016-2023, KeePassXC Team <team@keepassxc.org>
License: GPL-2 or GPL-3
Comment: The "KeePassXC Team" in every copyright notice is formed by the following people:
- droidmonkey
- phoerious
- TheZ3ro <io@thezero.org>
- varjolintu
- hifi
- louib
- weslly
Every other contributor is listed on https://github.com/keepassxreboot/keepassxc/graphs/contributors
Files: cmake/CodeCoverage.cmake
Copyright: 2012 - 2015, Lars Bilke
License: BSD-3-clause
Files: cmake/FindYubiKey.cmake
Copyright: 2014 Kyle Manna <kyle@kylemanna.com>
License: GPL-2 or GPL-3
Files: cmake/FindBotan2.cmake
Copyright: 2018 Ribose Inc.
License: BSD-2-clause
Files: cmake/FindBotan.cmake
Copyright: none
License: LGPL-2.1
Files: cmake/GenerateProductVersion.cmake
Copyright: 2015 halex2005 <akharlov@gmail.com>

65
cmake/FindBotan.cmake Normal file
View File

@ -0,0 +1,65 @@
# - Find botan
# Find the botan cryptographic library
#
# This module defines the following variables:
# BOTAN_FOUND - True if library and include directory are found
# If set to TRUE, the following are also defined:
# BOTAN_INCLUDE_DIRS - The directory where to find the header file
# BOTAN_LIBRARIES - Where to find the library files
#
# This file is in the public domain (https://github.com/vistle/vistle/blob/master/cmake/Modules/FindBOTAN.cmake)
include(FindPackageHandleStandardArgs)
set(BOTAN_VERSIONS botan-3 botan-2)
set(BOTAN_NAMES botan-3 botan-2 botan)
set(BOTAN_NAMES_DEBUG botand-3 botand-2 botand botan)
find_path(
BOTAN_INCLUDE_DIR
NAMES botan/build.h
PATH_SUFFIXES ${BOTAN_VERSIONS}
DOC "The Botan include directory")
if(BOTAN_INCLUDE_DIR)
file(READ "${BOTAN_INCLUDE_DIR}/botan/build.h" build)
string(REGEX MATCH "BOTAN_VERSION_MAJOR ([0-9]*)" _ ${build})
set(BOTAN_VERSION_MAJOR ${CMAKE_MATCH_1})
string(REGEX MATCH "BOTAN_VERSION_MINOR ([0-9]*)" _ ${build})
set(BOTAN_VERSION_MINOR ${CMAKE_MATCH_1})
string(REGEX MATCH "BOTAN_VERSION_PATCH ([0-9]*)" _ ${build})
set(BOTAN_VERSION_PATCH ${CMAKE_MATCH_1})
set(BOTAN_VERSION "${BOTAN_VERSION_MAJOR}.${BOTAN_VERSION_MINOR}.${BOTAN_VERSION_PATCH}")
endif()
find_library(
BOTAN_LIBRARY
NAMES ${BOTAN_NAMES}
PATH_SUFFIXES release/lib lib
DOC "The Botan (release) library")
if(MSVC)
find_library(
BOTAN_LIBRARY_DEBUG
NAMES ${BOTAN_NAMES_DEBUG}
PATH_SUFFIXES debug/lib lib
DOC "The Botan debug library")
find_package_handle_standard_args(
Botan
REQUIRED_VARS BOTAN_LIBRARY BOTAN_LIBRARY_DEBUG BOTAN_INCLUDE_DIR
VERSION_VAR BOTAN_VERSION)
else()
find_package_handle_standard_args(
Botan
REQUIRED_VARS BOTAN_LIBRARY BOTAN_INCLUDE_DIR
VERSION_VAR BOTAN_VERSION)
endif()
if(BOTAN_FOUND)
set(BOTAN_INCLUDE_DIRS ${BOTAN_INCLUDE_DIR})
if(MSVC)
set(BOTAN_LIBRARIES optimized ${BOTAN_LIBRARY} debug ${BOTAN_LIBRARY_DEBUG})
else()
set(BOTAN_LIBRARIES ${BOTAN_LIBRARY})
endif()
endif()
mark_as_advanced(BOTAN_INCLUDE_DIR BOTAN_LIBRARY BOTAN_LIBRARY_DEBUG)

View File

@ -1,106 +0,0 @@
# Copyright (c) 2018 Ribose Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#.rst:
# FindBotan2
# -----------
#
# Find the botan-2 library.
#
# IMPORTED Targets
# ^^^^^^^^^^^^^^^^
#
# This module defines :prop_tgt:`IMPORTED` targets:
#
# ``Botan2::Botan2``
# The botan-2 library, if found.
#
# Result variables
# ^^^^^^^^^^^^^^^^
#
# This module defines the following variables:
#
# ::
#
# BOTAN2_FOUND - true if the headers and library were found
# BOTAN2_INCLUDE_DIRS - where to find headers
# BOTAN2_LIBRARIES - list of libraries to link
# BOTAN2_VERSION - library version that was found, if any
# find the headers
find_path(BOTAN2_INCLUDE_DIR
NAMES botan/version.h
PATH_SUFFIXES botan-2
)
# find the library
find_library(BOTAN2_LIBRARY NAMES botan-2 libbotan-2 botan)
# determine the version
if(BOTAN2_INCLUDE_DIR AND EXISTS "${BOTAN2_INCLUDE_DIR}/botan/build.h")
file(STRINGS "${BOTAN2_INCLUDE_DIR}/botan/build.h" botan2_version_str
REGEX "^#define[\t ]+(BOTAN_VERSION_[A-Z]+)[\t ]+[0-9]+")
string(REGEX REPLACE ".*#define[\t ]+BOTAN_VERSION_MAJOR[\t ]+([0-9]+).*"
"\\1" _botan2_version_major "${botan2_version_str}")
string(REGEX REPLACE ".*#define[\t ]+BOTAN_VERSION_MINOR[\t ]+([0-9]+).*"
"\\1" _botan2_version_minor "${botan2_version_str}")
string(REGEX REPLACE ".*#define[\t ]+BOTAN_VERSION_PATCH[\t ]+([0-9]+).*"
"\\1" _botan2_version_patch "${botan2_version_str}")
set(BOTAN2_VERSION "${_botan2_version_major}.${_botan2_version_minor}.${_botan2_version_patch}"
CACHE INTERNAL "The version of Botan which was detected")
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Botan2
REQUIRED_VARS BOTAN2_LIBRARY BOTAN2_INCLUDE_DIR
VERSION_VAR BOTAN2_VERSION
)
if(BOTAN2_FOUND)
set(BOTAN2_INCLUDE_DIRS ${BOTAN2_INCLUDE_DIR} ${PC_BOTAN2_INCLUDE_DIRS})
set(BOTAN2_LIBRARIES ${BOTAN2_LIBRARY})
endif()
if(BOTAN2_FOUND AND NOT TARGET Botan2::Botan2)
# create the new library target
add_library(Botan2::Botan2 UNKNOWN IMPORTED)
# set the required include dirs for the target
if(BOTAN2_INCLUDE_DIRS)
set_target_properties(Botan2::Botan2
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${BOTAN2_INCLUDE_DIRS}"
)
endif()
# set the required libraries for the target
if(EXISTS "${BOTAN2_LIBRARY}")
set_target_properties(Botan2::Botan2
PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${BOTAN2_LIBRARY}"
)
endif()
endif()
mark_as_advanced(BOTAN2_INCLUDE_DIR BOTAN2_LIBRARY)

View File

@ -1,106 +0,0 @@
# Copyright (c) 2018 Ribose Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#.rst:
# FindBotan3
# -----------
#
# Find the botan-3 library.
#
# IMPORTED Targets
# ^^^^^^^^^^^^^^^^
#
# This module defines :prop_tgt:`IMPORTED` targets:
#
# ``Botan3::Botan3``
# The botan-3 library, if found.
#
# Result variables
# ^^^^^^^^^^^^^^^^
#
# This module defines the following variables:
#
# ::
#
# BOTAN3_FOUND - true if the headers and library were found
# BOTAN3_INCLUDE_DIRS - where to find headers
# BOTAN3_LIBRARIES - list of libraries to link
# BOTAN3_VERSION - library version that was found, if any
# find the headers
find_path(BOTAN3_INCLUDE_DIR
NAMES botan/version.h
PATH_SUFFIXES botan-3
)
# find the library
find_library(BOTAN3_LIBRARY NAMES botan-3 libbotan-3 botan)
# determine the version
if(BOTAN3_INCLUDE_DIR AND EXISTS "${BOTAN3_INCLUDE_DIR}/botan/build.h")
file(STRINGS "${BOTAN3_INCLUDE_DIR}/botan/build.h" botan3_version_str
REGEX "^#define[\t ]+(BOTAN_VERSION_[A-Z]+)[\t ]+[0-9]+")
string(REGEX REPLACE ".*#define[\t ]+BOTAN_VERSION_MAJOR[\t ]+([0-9]+).*"
"\\1" _botan3_version_major "${botan3_version_str}")
string(REGEX REPLACE ".*#define[\t ]+BOTAN_VERSION_MINOR[\t ]+([0-9]+).*"
"\\1" _botan3_version_minor "${botan3_version_str}")
string(REGEX REPLACE ".*#define[\t ]+BOTAN_VERSION_PATCH[\t ]+([0-9]+).*"
"\\1" _botan3_version_patch "${botan3_version_str}")
set(BOTAN3_VERSION "${_botan3_version_major}.${_botan3_version_minor}.${_botan3_version_patch}"
CACHE INTERNAL "The version of Botan which was detected")
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Botan3
REQUIRED_VARS BOTAN3_LIBRARY BOTAN3_INCLUDE_DIR
VERSION_VAR BOTAN3_VERSION
)
if(BOTAN3_FOUND)
set(BOTAN3_INCLUDE_DIRS ${BOTAN3_INCLUDE_DIR} ${PC_BOTAN3_INCLUDE_DIRS})
set(BOTAN3_LIBRARIES ${BOTAN3_LIBRARY})
endif()
if(BOTAN3_FOUND AND NOT TARGET Botan3::Botan3)
# create the new library target
add_library(Botan3::Botan3 UNKNOWN IMPORTED)
# set the required include dirs for the target
if(BOTAN3_INCLUDE_DIRS)
set_target_properties(Botan3::Botan3
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${BOTAN3_INCLUDE_DIRS}"
)
endif()
# set the required libraries for the target
if(EXISTS "${BOTAN3_LIBRARY}")
set_target_properties(Botan3::Botan3
PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${BOTAN3_LIBRARY}"
)
endif()
endif()
mark_as_advanced(BOTAN3_INCLUDE_DIR BOTAN3_LIBRARY)

View File

@ -14,7 +14,6 @@
#cmakedefine WITH_XC_AUTOTYPE
#cmakedefine WITH_XC_NETWORKING
#cmakedefine KPXC_DEV_BOTAN3
#cmakedefine WITH_XC_BROWSER
#cmakedefine WITH_XC_YUBIKEY
#cmakedefine WITH_XC_SSHAGENT
@ -23,6 +22,7 @@
#cmakedefine WITH_XC_FDOSECRETS
#cmakedefine WITH_XC_DOCS
#cmakedefine WITH_XC_X11
#cmakedefine WITH_XC_BOTAN3
#cmakedefine KEEPASSXC_BUILD_TYPE "@KEEPASSXC_BUILD_TYPE@"
#cmakedefine KEEPASSXC_BUILD_TYPE_RELEASE

View File

@ -33,12 +33,10 @@ namespace AsyncTask
* @param future future to wait for
* @return async task result
*/
template <typename FunctionObject>
typename std::result_of<FunctionObject()>::type
waitForFuture(QFuture<typename std::result_of<FunctionObject()>::type> future)
template <typename T> T waitForFuture(QFuture<T> future)
{
QEventLoop loop;
QFutureWatcher<typename std::result_of<FunctionObject()>::type> watcher;
QFutureWatcher<T> watcher;
QObject::connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit()));
watcher.setFuture(future);
loop.exec();
@ -51,10 +49,9 @@ namespace AsyncTask
* @param task std::function object to run
* @return async task result
*/
template <typename FunctionObject>
typename std::result_of<FunctionObject()>::type runAndWaitForFuture(FunctionObject task)
template <typename FunctionObject> decltype(auto) runAndWaitForFuture(FunctionObject task)
{
return waitForFuture<FunctionObject>(QtConcurrent::run(task));
return waitForFuture(QtConcurrent::run(task));
}
/**
@ -69,9 +66,8 @@ namespace AsyncTask
template <typename FunctionObject, typename FunctionObject2>
void runThenCallback(FunctionObject task, QObject* context, FunctionObject2 callback)
{
typedef QFutureWatcher<typename std::result_of<FunctionObject()>::type> FutureWatcher;
auto future = QtConcurrent::run(task);
auto watcher = new FutureWatcher(context);
auto watcher = new QFutureWatcher<decltype(future.result())>(context);
QObject::connect(watcher, &QFutureWatcherBase::finished, context, [=]() {
watcher->deleteLater();
callback(future.result());

View File

@ -239,7 +239,7 @@ namespace Crypto
{
bool init()
{
#ifdef KPXC_DEV_BOTAN3
#ifdef WITH_XC_BOTAN3
unsigned int version_major = 3, min_version_minor = 0;
QString versionString = "3.x";
#else

View File

@ -33,7 +33,8 @@ bool SymmetricCipher::init(Mode mode, Direction direction, const QByteArray& key
try {
auto botanMode = modeToString(mode);
auto botanDirection = (direction == SymmetricCipher::Encrypt ? Botan::ENCRYPTION : Botan::DECRYPTION);
auto botanDirection =
(direction == SymmetricCipher::Encrypt ? Botan::Cipher_Dir::ENCRYPTION : Botan::Cipher_Dir::DECRYPTION);
auto cipher = Botan::Cipher_Mode::create_or_throw(botanMode.toStdString(), botanDirection);
m_cipher.reset(cipher.release());

View File

@ -25,7 +25,7 @@
#include <QDebug>
#include <botan/dh.h>
#ifdef KPXC_DEV_BOTAN3
#ifdef WITH_XC_BOTAN3
#include <botan/pubkey.h>
#else
#include <botan/pk_ops.h>
@ -57,7 +57,7 @@ namespace FdoSecrets
try {
Botan::secure_vector<uint8_t> salt(32, '\0');
#ifdef KPXC_DEV_BOTAN3
#ifdef WITH_XC_BOTAN3
Botan::PK_Key_Agreement dhka(*m_privateKey, *randomGen()->getRng(), "HKDF(SHA-256)", "");
auto aesKey = dhka.derive_key(16,
reinterpret_cast<const uint8_t*>(clientPublicKey.constData()),