From 27940ecdd136c247a7daf78f30642bbf816648ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 21 Mar 2017 11:32:05 +0100 Subject: Backport the master FindBOTAN.cmake, to find botan 2.0 as well ref #3245 --- louloulibs/cmake/Modules/FindBOTAN.cmake | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/louloulibs/cmake/Modules/FindBOTAN.cmake b/louloulibs/cmake/Modules/FindBOTAN.cmake index a12bd35..13d2de4 100644 --- a/louloulibs/cmake/Modules/FindBOTAN.cmake +++ b/louloulibs/cmake/Modules/FindBOTAN.cmake @@ -15,21 +15,29 @@ # # This file is in the public domain -find_path(BOTAN_INCLUDE_DIRS NAMES botan/botan.h - PATH_SUFFIXES botan-1.11 - DOC "The botan include directory") +include(FindPkgConfig) -find_library(BOTAN_LIBRARIES NAMES botan botan-1.11 - DOC "The botan library") +pkg_check_modules(BOTAN botan-2) +pkg_check_modules(BOTAN botan-1.11) -# Use some standard module to handle the QUIETLY and REQUIRED arguments, and -# set BOTAN_FOUND to TRUE if these two variables are set. -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(BOTAN REQUIRED_VARS BOTAN_LIBRARIES BOTAN_INCLUDE_DIRS) +if(NOT BOTAN_FOUND) + find_path(BOTAN_INCLUDE_DIRS NAMES botan/botan.h + PATH_SUFFIXES botan-2 botan-1.11 + DOC "The botan include directory") -if(BOTAN_FOUND) - set(BOTAN_LIBRARY ${BOTAN_LIBRARIES}) - set(BOTAN_INCLUDE_DIR ${BOTAN_INCLUDE_DIRS}) + find_library(BOTAN_LIBRARIES NAMES botan botan-2 botan-1.11 + DOC "The botan library") + + # Use some standard module to handle the QUIETLY and REQUIRED arguments, and + # set BOTAN_FOUND to TRUE if these two variables are set. + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(BOTAN REQUIRED_VARS BOTAN_LIBRARIES BOTAN_INCLUDE_DIRS) + + if(BOTAN_FOUND) + set(BOTAN_LIBRARY ${BOTAN_LIBRARIES} CACHE INTERNAL "") + set(BOTAN_INCLUDE_DIR ${BOTAN_INCLUDE_DIRS} CACHE INTERNAL "") + set(BOTAN_FOUND ${BOTAN_FOUND} CACHE INTERNAL "") + endif() endif() mark_as_advanced(BOTAN_INCLUDE_DIRS BOTAN_LIBRARIES) -- cgit v1.2.3 From 395297e488cee2d19eb75f5a42102f1f5daa3a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 2 Dec 2016 16:50:28 +0100 Subject: Use the new botan 1.11.32 Tls::Client API (but stay compatible with older ones) ref #3245 --- louloulibs/network/tcp_socket_handler.cpp | 20 ++++++++++++-------- louloulibs/network/tcp_socket_handler.hpp | 30 ++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/louloulibs/network/tcp_socket_handler.cpp b/louloulibs/network/tcp_socket_handler.cpp index 1dddde5..d509a63 100644 --- a/louloulibs/network/tcp_socket_handler.cpp +++ b/louloulibs/network/tcp_socket_handler.cpp @@ -419,10 +419,14 @@ void TCPSocketHandler::start_tls() { Botan::TLS::Server_Information server_info(this->address, "irc", std::stoul(this->port)); this->tls = std::make_unique( - std::bind(&TCPSocketHandler::tls_output_fn, this, ph::_1, ph::_2), - std::bind(&TCPSocketHandler::tls_data_cb, this, ph::_1, ph::_2), - std::bind(&TCPSocketHandler::tls_alert_cb, this, ph::_1, ph::_2, ph::_3), - std::bind(&TCPSocketHandler::tls_handshake_cb, this, ph::_1), +# if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,32) + *this, +# else + [this](const Botan::byte* data, size_t size) { this->tls_emit_data(data, size); }, + [this](const Botan::byte* data, size_t size) { this->tls_record_received(0, data, size); }, + [this](Botan::TLS::Alert alert, const Botan::byte*, size_t) { this->tls_alert(alert); }, + [this](const Botan::TLS::Session& session) { return this->tls_session_established(session); }, +# endif session_manager, this->credential_manager, policy, rng, server_info, Botan::TLS::Protocol_Version::latest_tls_version()); } @@ -475,7 +479,7 @@ void TCPSocketHandler::tls_send(std::string&& data) std::make_move_iterator(data.end())); } -void TCPSocketHandler::tls_data_cb(const Botan::byte* data, size_t size) +void TCPSocketHandler::tls_record_received(uint64_t, const Botan::byte *data, size_t size) { this->in_buf += std::string(reinterpret_cast(data), size); @@ -483,17 +487,17 @@ void TCPSocketHandler::tls_data_cb(const Botan::byte* data, size_t size) this->parse_in_buffer(size); } -void TCPSocketHandler::tls_output_fn(const Botan::byte* data, size_t size) +void TCPSocketHandler::tls_emit_data(const Botan::byte *data, size_t size) { this->raw_send(std::string(reinterpret_cast(data), size)); } -void TCPSocketHandler::tls_alert_cb(Botan::TLS::Alert alert, const Botan::byte*, size_t) +void TCPSocketHandler::tls_alert(Botan::TLS::Alert alert) { log_debug("tls_alert: ", alert.type_string()); } -bool TCPSocketHandler::tls_handshake_cb(const Botan::TLS::Session& session) +bool TCPSocketHandler::tls_session_established(const Botan::TLS::Session& session) { log_debug("Handshake with ", session.server_info().hostname(), " complete.", " Version: ", session.version().to_string(), diff --git a/louloulibs/network/tcp_socket_handler.hpp b/louloulibs/network/tcp_socket_handler.hpp index 20a3e5a..40532f0 100644 --- a/louloulibs/network/tcp_socket_handler.hpp +++ b/louloulibs/network/tcp_socket_handler.hpp @@ -19,6 +19,25 @@ #include #include +#ifdef BOTAN_FOUND +class BiboumiTLSPolicy: public Botan::TLS::Policy +{ +public: +# if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,33) + bool use_ecc_point_compression() const override + { + return true; + } +# endif +}; + +# if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,32) +# define BOTAN_TLS_CALLBACKS_OVERRIDE override final +# else +# define BOTAN_TLS_CALLBACKS_OVERRIDE +# endif +#endif + /** * An interface, with a series of callbacks that should be implemented in * subclasses that deal with a socket. These callbacks are called on various events @@ -26,6 +45,9 @@ * (select/poll/epoll etc) */ class TCPSocketHandler: public SocketHandler +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,32) + ,public Botan::TLS::Callbacks +#endif { protected: ~TCPSocketHandler(); @@ -158,22 +180,22 @@ private: * Called by the tls object that some data has been decrypt. We call * parse_in_buffer() to handle that unencrypted data. */ - void tls_data_cb(const Botan::byte* data, size_t size); + void tls_record_received(uint64_t rec_no, const Botan::byte* data, size_t size) BOTAN_TLS_CALLBACKS_OVERRIDE; /** * Called by the tls object to indicate that some data has been encrypted * and is now ready to be sent on the socket as is. */ - void tls_output_fn(const Botan::byte* data, size_t size); + void tls_emit_data(const Botan::byte* data, size_t size) BOTAN_TLS_CALLBACKS_OVERRIDE; /** * Called by the tls object to indicate that a TLS alert has been * received. We don’t use it, we just log some message, at the moment. */ - void tls_alert_cb(Botan::TLS::Alert alert, const Botan::byte*, size_t); + void tls_alert(Botan::TLS::Alert alert) BOTAN_TLS_CALLBACKS_OVERRIDE; /** * Called by the tls object at the end of the TLS handshake. We don't do * anything here appart from logging the TLS session information. */ - bool tls_handshake_cb(const Botan::TLS::Session& session); + bool tls_session_established(const Botan::TLS::Session& session) BOTAN_TLS_CALLBACKS_OVERRIDE; /** * Called whenever the tls session goes from inactive to active. This * means that the handshake has just been successfully done, and we can -- cgit v1.2.3 From cb79fc1b3d492af60404b5be1c0cb1c8c8065801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sun, 4 Dec 2016 22:17:37 +0100 Subject: Update the verify_certificate_chain code to work with botan >= 1.11.34 as well ref #3245 --- louloulibs/network/credentials_manager.cpp | 35 +++++++++++++++++++++++------- louloulibs/network/credentials_manager.hpp | 15 +++++++++++++ louloulibs/network/tcp_socket_handler.cpp | 25 +++++++++++++++++++++ louloulibs/network/tcp_socket_handler.hpp | 9 ++++++++ 4 files changed, 76 insertions(+), 8 deletions(-) diff --git a/louloulibs/network/credentials_manager.cpp b/louloulibs/network/credentials_manager.cpp index ed04d24..289307b 100644 --- a/louloulibs/network/credentials_manager.cpp +++ b/louloulibs/network/credentials_manager.cpp @@ -37,6 +37,28 @@ void BasicCredentialsManager::set_trusted_fingerprint(const std::string& fingerp this->trusted_fingerprint = fingerprint; } +const std::string& BasicCredentialsManager::get_trusted_fingerprint() const +{ + return this->trusted_fingerprint; +} + +void check_tls_certificate(const std::vector& certs, + const std::string& hostname, const std::string& trusted_fingerprint, + std::exception_ptr exc) +{ + + if (!trusted_fingerprint.empty() && !certs.empty() && + trusted_fingerprint == certs[0].fingerprint() && + certs[0].matches_dns_name(hostname)) + // We trust the certificate, based on the trusted fingerprint and + // the fact that the hostname matches + return; + + if (exc) + std::rethrow_exception(exc); +} + +#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,34) void BasicCredentialsManager::verify_certificate_chain(const std::string& type, const std::string& purported_hostname, const std::vector& certs) @@ -50,17 +72,14 @@ void BasicCredentialsManager::verify_certificate_chain(const std::string& type, catch (const std::exception& tls_exception) { log_warning("TLS certificate check failed: ", tls_exception.what()); - if (!this->trusted_fingerprint.empty() && !certs.empty() && - this->trusted_fingerprint == certs[0].fingerprint() && - certs[0].matches_dns_name(purported_hostname)) - // We trust the certificate, based on the trusted fingerprint and - // the fact that the hostname matches - return; - + std::exception_ptr exception_ptr{}; if (this->socket_handler->abort_on_invalid_cert()) - throw; + exception_ptr = std::current_exception(); + + check_tls_certificate(certs, purported_hostname, this->trusted_fingerprint, exception_ptr); } } +#endif bool BasicCredentialsManager::try_to_open_one_ca_bundle(const std::vector& paths) { diff --git a/louloulibs/network/credentials_manager.hpp b/louloulibs/network/credentials_manager.hpp index 7557372..29ee024 100644 --- a/louloulibs/network/credentials_manager.hpp +++ b/louloulibs/network/credentials_manager.hpp @@ -9,6 +9,18 @@ class TCPSocketHandler; +/** + * If the given cert isn’t valid, based on the given hostname + * and fingerprint, then throws the exception if it’s non-empty. + * + * Must be called after the standard (from Botan) way of + * checking the certificate, if we want to also accept certificates based + * on a trusted fingerprint. + */ +void check_tls_certificate(const std::vector& certs, + const std::string& hostname, const std::string& trusted_fingerprint, + std::exception_ptr exc); + class BasicCredentialsManager: public Botan::Credentials_Manager { public: @@ -19,12 +31,15 @@ public: BasicCredentialsManager& operator=(const BasicCredentialsManager&) = delete; BasicCredentialsManager& operator=(BasicCredentialsManager&&) = delete; +#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,34) void verify_certificate_chain(const std::string& type, const std::string& purported_hostname, const std::vector&) override final; +#endif std::vector trusted_certificate_authorities(const std::string& type, const std::string& context) override final; void set_trusted_fingerprint(const std::string& fingerprint); + const std::string& get_trusted_fingerprint() const; private: const TCPSocketHandler* const socket_handler; diff --git a/louloulibs/network/tcp_socket_handler.cpp b/louloulibs/network/tcp_socket_handler.cpp index d509a63..d9ec226 100644 --- a/louloulibs/network/tcp_socket_handler.cpp +++ b/louloulibs/network/tcp_socket_handler.cpp @@ -509,6 +509,31 @@ bool TCPSocketHandler::tls_session_established(const Botan::TLS::Session& sessio return true; } +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,34) +void TCPSocketHandler::tls_verify_cert_chain(const std::vector& cert_chain, + const std::vector>& ocsp_responses, + const std::vector& trusted_roots, + Botan::Usage_Type usage, const std::string& hostname, + const Botan::TLS::Policy& policy) +{ + log_debug("Checking remote certificate for hostname ", hostname); + try + { + Botan::TLS::Callbacks::tls_verify_cert_chain(cert_chain, ocsp_responses, trusted_roots, usage, hostname, policy); + log_debug("Certificate is valid"); + } + catch (const std::exception& tls_exception) + { + log_warning("TLS certificate check failed: ", tls_exception.what()); + std::exception_ptr exception_ptr{}; + if (this->abort_on_invalid_cert()) + exception_ptr = std::current_exception(); + + check_tls_certificate(cert_chain, hostname, this->credential_manager.get_trusted_fingerprint(), exception_ptr); + } +} +#endif + void TCPSocketHandler::on_tls_activated() { this->send_data({}); diff --git a/louloulibs/network/tcp_socket_handler.hpp b/louloulibs/network/tcp_socket_handler.hpp index 40532f0..8baa1d1 100644 --- a/louloulibs/network/tcp_socket_handler.hpp +++ b/louloulibs/network/tcp_socket_handler.hpp @@ -196,6 +196,15 @@ private: * anything here appart from logging the TLS session information. */ bool tls_session_established(const Botan::TLS::Session& session) BOTAN_TLS_CALLBACKS_OVERRIDE; + +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,34) + void tls_verify_cert_chain(const std::vector& cert_chain, + const std::vector>& ocsp_responses, + const std::vector& trusted_roots, + Botan::Usage_Type usage, + const std::string& hostname, + const Botan::TLS::Policy& policy) BOTAN_TLS_CALLBACKS_OVERRIDE; +#endif /** * Called whenever the tls session goes from inactive to active. This * means that the handshake has just been successfully done, and we can -- cgit v1.2.3 From 6605f8b5e57068aa6430bba0cccfaf9f9e5fbd1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 21 Mar 2017 11:34:48 +0100 Subject: Update changelog for 4.1 release --- CHANGELOG.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a896e68..349a9c3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,8 @@ +Version 4.1 - 2017-03-21 +======================== + + - Works with biboumi 2.x, as well as biboumi 1.11.x + Version 4.0 - 2016-11-09 ======================== -- cgit v1.2.3 From 5f158b4d91e9a93cf7cf6b30dde6ca3cd0052ec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 21 Mar 2017 11:49:21 +0100 Subject: Update the ci to use the latest image, and remove deprecated jobs --- .gitlab-ci.yml | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cd32742..e36ea0e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -29,7 +29,7 @@ variables: tags: - docker -image: biboumi-test-fedora:latest +image: docker.louiz.org/biboumi-test-fedora:latest build:1: variables: @@ -72,7 +72,7 @@ build:6: build:rpm: stage: build - image: biboumi-test-fedora:latest + image: docker.louiz.org/biboumi-test-fedora:latest tags: - docker script: @@ -104,33 +104,21 @@ build:rpm: test:debian: stage: test - image: biboumi-test-debian:latest + image: docker.louiz.org/biboumi-test-debian:latest tags: - docker <<: *basic_test test:fedora: stage: test - image: biboumi-test-fedora:latest + image: docker.louiz.org/biboumi-test-fedora:latest tags: - docker <<: *basic_test -test:openbsd: - variables: - COMPILER: "g++" - SYSTEMD: "-DWITHOUT_SYSTEMD=1" - stage: test - script: - - cmake .. -DCMAKE_CXX_COMPILER=${COMPILER} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} ${BOTAN} ${CARES} ${SYSTEMD} ${LIBIDN} ${LITESQL} - - make biboumi - - make check - tags: - - openbsd - test:coverity: stage: test - image: biboumi-test-fedora:latest + image: docker.louiz.org/biboumi-test-fedora:latest allow_failure: true when: manual script: @@ -139,13 +127,3 @@ test:coverity: - cov-build --dir cov-int make biboumi test_suite -j$(nproc || echo 1) - tar czvf biboumi_coverity.tgz cov-int - curl --form token=$COVERITY_TOKEN --form email=louiz@louiz.org --form file=@biboumi_coverity.tgz --form version="$(git rev-parse --short HEAD)" --form description="Automatic submission by gitlab-ci" https://scan.coverity.com/builds?project=louiz%2Fbiboumi - -test:sonar-qube: - stage: test - image: biboumi-test-fedora:latest - script: - - cmake .. - - ~/sonar-scanner/bin/build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir ./bw-outputs make biboumi test_suite - - cd .. - - ~/sonar-scanner/bin/sonar-scanner -Dsonar.host.url=https://sonarqube.com -Dsonar.login=$SONAR_LOGIN -Dsonar.language=cpp -Dsonar.cfamily.build-wrapper-output=build/bw-outputs -Dsonar.sourceEncoding=UTF-8 -Dsonar.sources=src/,louloulibs/,tests/ -Dsonar.projectKey=biboumi -Dsonar.projectName=Biboumi -Dsonar.projectVersion=3.0 - -- cgit v1.2.3 From 8ce6759eae618cb1109bd5dea70c3eb17f733445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 21 Mar 2017 15:04:45 +0100 Subject: Add missing botan/version.h includes --- louloulibs/network/credentials_manager.hpp | 1 + louloulibs/network/tcp_socket_handler.hpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/louloulibs/network/credentials_manager.hpp b/louloulibs/network/credentials_manager.hpp index 29ee024..9f42782 100644 --- a/louloulibs/network/credentials_manager.hpp +++ b/louloulibs/network/credentials_manager.hpp @@ -6,6 +6,7 @@ #include #include +#include class TCPSocketHandler; diff --git a/louloulibs/network/tcp_socket_handler.hpp b/louloulibs/network/tcp_socket_handler.hpp index 8baa1d1..4c1df64 100644 --- a/louloulibs/network/tcp_socket_handler.hpp +++ b/louloulibs/network/tcp_socket_handler.hpp @@ -20,6 +20,8 @@ #include #ifdef BOTAN_FOUND +#include + class BiboumiTLSPolicy: public Botan::TLS::Policy { public: -- cgit v1.2.3 From abb9c08828561be1c4463c5eaf8be62d0065eec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 21 Mar 2017 15:12:02 +0100 Subject: Add a missing ifndef BOTAN --- louloulibs/network/tcp_socket_handler.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/louloulibs/network/tcp_socket_handler.hpp b/louloulibs/network/tcp_socket_handler.hpp index 4c1df64..c850f43 100644 --- a/louloulibs/network/tcp_socket_handler.hpp +++ b/louloulibs/network/tcp_socket_handler.hpp @@ -47,8 +47,10 @@ public: * (select/poll/epoll etc) */ class TCPSocketHandler: public SocketHandler -#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,32) +#ifdef BOTAN_FOUND +# if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,32) ,public Botan::TLS::Callbacks +# endif #endif { protected: -- cgit v1.2.3 From 1fe2b1566a1bb14fb74794d53a5db9cca68c98ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 21 Mar 2017 16:46:51 +0100 Subject: Release version 4.1 --- CMakeLists.txt | 2 +- packaging/biboumi.spec.cmake | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2301123..9575cbd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.0) project(biboumi) set(${PROJECT_NAME}_VERSION_MAJOR 4) -set(${PROJECT_NAME}_VERSION_MINOR 0) +set(${PROJECT_NAME}_VERSION_MINOR 1) set(${PROJECT_NAME}_VERSION_SUFFIX "") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -pedantic -Wall -Wextra") diff --git a/packaging/biboumi.spec.cmake b/packaging/biboumi.spec.cmake index 0747d34..c180180 100644 --- a/packaging/biboumi.spec.cmake +++ b/packaging/biboumi.spec.cmake @@ -59,6 +59,9 @@ make check %{?_smp_mflags} %changelog +* Tue Mar 21 2017 Le Coz Florent - 4.1-1 +- Update to 4.1 sources: compatibility with botan 2.0 + * Wed Nov 9 2016 Le Coz Florent - 4.0-1 - Update to 4.0 sources -- cgit v1.2.3