1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-04-25 12:13:13 +00:00

Merge branch 'osnma-cesare-fix5' of https://github.com/carlesfernandez/gnss-sdr into carlesfernandez-osnma-cesare-fix5

This commit is contained in:
cesaaargm 2024-07-02 13:54:34 +02:00
commit adb3b455ea
15 changed files with 565 additions and 419 deletions

View File

@ -2196,99 +2196,9 @@ endif()
################################################################################ ################################################################################
# GnuTLS - https://www.gnutls.org/ # OpenSSL https://www.openssl.org/ or GnuTLS - https://www.gnutls.org/
################################################################################ ################################################################################
find_package(GnuTLS) include(GnssSdrCrypto)
set_package_properties(GnuTLS PROPERTIES
URL "https://www.gnutls.org/"
PURPOSE "Used for the SUPL protocol implementation."
TYPE REQUIRED
)
if(GnuTLS_FOUND AND GNUTLS_VERSION_STRING)
set_package_properties(GnuTLS PROPERTIES
DESCRIPTION "Transport Layer Security Library (found: v${GNUTLS_VERSION_STRING})"
)
else()
set_package_properties(GnuTLS PROPERTIES
DESCRIPTION "Transport Layer Security Library"
)
endif()
find_library(GNUTLS_OPENSSL_LIBRARY
NAMES gnutls-openssl libgnutls-openssl.so.27
PATHS
/usr/lib
/usr/lib64
/usr/lib/x86_64-linux-gnu
/usr/lib/aarch64-linux-gnu
/usr/lib/arm-linux-gnueabihf
/usr/lib/arm-linux-gnueabi
/usr/lib/i386-linux-gnu
/usr/lib/alpha-linux-gnu
/usr/lib/hppa-linux-gnu
/usr/lib/i386-gnu
/usr/lib/i686-gnu
/usr/lib/i686-linux-gnu
/usr/lib/x86_64-kfreebsd-gnu
/usr/lib/i686-kfreebsd-gnu
/usr/lib/m68k-linux-gnu
/usr/lib/mips-linux-gnu
/usr/lib/mips64el-linux-gnuabi64
/usr/lib/mipsel-linux-gnu
/usr/lib/powerpc-linux-gnu
/usr/lib/powerpc-linux-gnuspe
/usr/lib/powerpc64-linux-gnu
/usr/lib/powerpc64le-linux-gnu
/usr/lib/s390x-linux-gnu
/usr/lib/riscv64-linux-gnu
/usr/lib/sparc64-linux-gnu
/usr/lib/x86_64-linux-gnux32
/usr/lib/sh4-linux-gnu
/usr/lib/loongarch64-linux-gnu
/usr/local/lib
/usr/local/lib64
/opt/local/lib
)
#if(NOT GNUTLS_OPENSSL_LIBRARY)
if(GNUTLS_OPENSSL_LIBRARY)
if(GnuTLS_FOUND)
message(STATUS " But it was not built with openssl compatibility.")
endif()
message(STATUS " Looking for OpenSSL instead...")
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(OPENSSL_ROOT_DIR /usr/local/opt/openssl) # Trick for Homebrew
endif()
find_package(OpenSSL)
set_package_properties(OpenSSL PROPERTIES
URL "https://www.openssl.org"
DESCRIPTION "Cryptography and SSL/TLS Toolkit (found: v${OPENSSL_VERSION})"
PURPOSE "Used for the SUPL protocol implementation."
TYPE REQUIRED
)
message("OPENSSL_FOUND: " ${OPENSSL_FOUND})
if(OPENSSL_FOUND)
set_package_properties(GnuTLS PROPERTIES
PURPOSE "Not found, but OpenSSL can replace it."
)
set(GNUTLS_INCLUDE_DIR ${OPENSSL_INCLUDE_DIR})
set(GNUTLS_LIBRARIES "")
set(GNUTLS_OPENSSL_LIBRARY ${OPENSSL_SSL_LIBRARY})
else()
message(" The GnuTLS library with openssl compatibility enabled has not been found.")
message(" You can try to install the required libraries by typing:")
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|kFreeBSD|GNU")
if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
message(" sudo yum install openssl-devel")
else()
message(" sudo apt-get install libgnutls28-dev")
endif()
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
message(" 'sudo port install gnutls', if you are using Macports, or")
message(" 'brew install openssl', if you are using Homebrew.")
endif()
message(FATAL_ERROR "GnuTLS libraries with openssl compatibility are required to build gnss-sdr")
endif()
endif()

View File

@ -75,7 +75,7 @@ information about this open-source, software-defined GNSS receiver.
- [Install Armadillo, a C++ linear algebra library](#install-armadillo-a-c-linear-algebra-library) - [Install Armadillo, a C++ linear algebra library](#install-armadillo-a-c-linear-algebra-library)
- [Install Gflags, a commandline flags processing module for C++](#install-gflags-a-commandline-flags-processing-module-for-c) - [Install Gflags, a commandline flags processing module for C++](#install-gflags-a-commandline-flags-processing-module-for-c)
- [Install Glog, a library that implements application-level logging](#install-glog-a-library-that-implements-application-level-logging) - [Install Glog, a library that implements application-level logging](#install-glog-a-library-that-implements-application-level-logging)
- [Install the GnuTLS or OpenSSL libraries](#install-the-gnutls-or-openssl-libraries) - [Install the OpenSSL libraries](#install-the-openssl-libraries)
- [Install Matio, MATLAB MAT file I/O library](#install-matio-matlab-mat-file-io-library) - [Install Matio, MATLAB MAT file I/O library](#install-matio-matlab-mat-file-io-library)
- [Install Protocol Buffers, a portable mechanism for serialization of structured data](#install-protocol-buffers-a-portable-mechanism-for-serialization-of-structured-data) - [Install Protocol Buffers, a portable mechanism for serialization of structured data](#install-protocol-buffers-a-portable-mechanism-for-serialization-of-structured-data)
- [Install Pugixml, a light-weight C++ XML processing library](#install-pugixml-a-light-weight-c-xml-processing-library) - [Install Pugixml, a light-weight C++ XML processing library](#install-pugixml-a-light-weight-c-xml-processing-library)
@ -168,16 +168,19 @@ $ sudo apt-get install build-essential cmake git pkg-config libboost-dev libboos
libboost-system-dev libboost-filesystem-dev libboost-thread-dev libboost-chrono-dev \ libboost-system-dev libboost-filesystem-dev libboost-thread-dev libboost-chrono-dev \
libboost-serialization-dev liblog4cpp5-dev libuhd-dev gnuradio-dev gr-osmosdr \ libboost-serialization-dev liblog4cpp5-dev libuhd-dev gnuradio-dev gr-osmosdr \
libblas-dev liblapack-dev libarmadillo-dev libgflags-dev libgoogle-glog-dev \ libblas-dev liblapack-dev libarmadillo-dev libgflags-dev libgoogle-glog-dev \
libgnutls-openssl-dev libpcap-dev libmatio-dev libpugixml-dev libgtest-dev \ libssl-dev libpcap-dev libmatio-dev libpugixml-dev libgtest-dev \
libprotobuf-dev protobuf-compiler python3-mako libprotobuf-dev libcpu-features-dev protobuf-compiler python3-mako
``` ```
Please note that the required files from `libgtest-dev` were named `googletest` Please note that the required files from `libgtest-dev` were named `googletest`
in Debian 9 "stretch" and Ubuntu 18.04 "bionic", and renamed to `libgtest-dev` in Debian 9 "stretch" and Ubuntu 18.04 "bionic", and renamed to `libgtest-dev`
in Debian 10 "buster" and above. in Debian 10 "buster" and above.
Since Ubuntu 21.04 Hirsute / Debian 11, the package `libcpu-features-dev` is In distributions older than Ubuntu 21.04 Hirsute / Debian 11, the package
also required. `libcpu-features-dev` is not required.
In distributions older than Ubuntu 22.04 Jammy / Debian 12, the package
`libssl-dev` must be replaced by `libgnutls-openssl-dev`.
**Note for Ubuntu 14.04 LTS "trusty" users:** you will need to build from source **Note for Ubuntu 14.04 LTS "trusty" users:** you will need to build from source
and install GNU Radio manually, as explained below, since GNSS-SDR requires and install GNU Radio manually, as explained below, since GNSS-SDR requires
@ -451,20 +454,15 @@ Please note that Glog is replaced by the
[Abseil Logging Library](https://abseil.io/docs/cpp/guides/logging) if Abseil >= [Abseil Logging Library](https://abseil.io/docs/cpp/guides/logging) if Abseil >=
v20240116 is available in your system. v20240116 is available in your system.
#### Install the GnuTLS or OpenSSL libraries #### Install the OpenSSL libraries
``` ```
$ sudo apt-get install libgnutls-openssl-dev # For Debian/Ubuntu/LinuxMint $ sudo apt-get install libssl-dev # For Debian/Ubuntu/LinuxMint
$ sudo yum install openssl-devel # For Fedora/CentOS/RHEL $ sudo yum install openssl-devel # For Fedora/CentOS/RHEL
$ sudo zypper install openssl-devel # For OpenSUSE $ sudo zypper install openssl-devel # For OpenSUSE
$ sudo pacman -S openssl # For Arch Linux $ sudo pacman -S openssl # For Arch Linux
``` ```
In case the [GnuTLS](https://www.gnutls.org/ "GnuTLS's Homepage") library with
openssl extensions package is not available in your GNU/Linux distribution,
GNSS-SDR can also work well with
[OpenSSL](https://www.openssl.org/ "OpenSSL's Homepage").
#### Install [Matio](https://github.com/tbeu/matio "Matio's Homepage"), MATLAB MAT file I/O library #### Install [Matio](https://github.com/tbeu/matio "Matio's Homepage"), MATLAB MAT file I/O library
``` ```
@ -838,7 +836,7 @@ In a terminal, type:
``` ```
$ sudo port selfupdate $ sudo port selfupdate
$ sudo port upgrade outdated $ sudo port upgrade outdated
$ sudo port install armadillo cmake pkgconfig protobuf3-cpp pugixml gnutls $ sudo port install armadillo cmake pkgconfig protobuf3-cpp pugixml openssl3
$ sudo port install gnuradio +uhd +grc +zeromq $ sudo port install gnuradio +uhd +grc +zeromq
$ sudo port install boost matio libad9361-iio libiio $ sudo port install boost matio libad9361-iio libiio
$ sudo port install py311-mako $ sudo port install py311-mako

View File

@ -0,0 +1,194 @@
# GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
# This file is part of GNSS-SDR.
#
# SPDX-FileCopyrightText: 2024 C. Fernandez-Prades cfernandez(at)cttc.es
# SPDX-License-Identifier: BSD-3-Clause
################################################################################
# OpenSSL https://www.openssl.org/
################################################################################
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(OPENSSL_ROOT_DIR /usr/local/opt/openssl) # Trick for Homebrew
endif()
find_package(OpenSSL)
set_package_properties(OpenSSL
PROPERTIES
URL "https://www.openssl.org"
PURPOSE "Used for the OSNMA and SUPL protocol implementations."
TYPE REQUIRED
)
if(OPENSSL_FOUND)
set_package_properties(OpenSSL
PROPERTIES
DESCRIPTION "Cryptography and SSL/TLS Toolkit (found: v${OPENSSL_VERSION})"
)
else()
set_package_properties(OpenSSL
PROPERTIES
DESCRIPTION "OpenSSL has not been found, but GnuTLS with openssl compatibility can replace it"
)
################################################################################
# GnuTLS - https://www.gnutls.org/
################################################################################
find_package(GnuTLS)
set_package_properties(GnuTLS PROPERTIES
URL "https://www.gnutls.org/"
PURPOSE "Used for the OSNMA and SUPL protocol implementations."
TYPE REQUIRED
)
if(GnuTLS_FOUND AND GNUTLS_VERSION_STRING)
set_package_properties(GnuTLS PROPERTIES
DESCRIPTION "Transport Layer Security Library (found: v${GNUTLS_VERSION_STRING})"
)
else()
set_package_properties(GnuTLS PROPERTIES
DESCRIPTION "Transport Layer Security Library"
)
endif()
find_library(GNUTLS_OPENSSL_LIBRARY
NAMES gnutls-openssl libgnutls-openssl.so.27
PATHS
/usr/lib
/usr/lib64
/usr/lib/x86_64-linux-gnu
/usr/lib/aarch64-linux-gnu
/usr/lib/arm-linux-gnueabihf
/usr/lib/arm-linux-gnueabi
/usr/lib/i386-linux-gnu
/usr/lib/alpha-linux-gnu
/usr/lib/hppa-linux-gnu
/usr/lib/i386-gnu
/usr/lib/i686-gnu
/usr/lib/i686-linux-gnu
/usr/lib/x86_64-kfreebsd-gnu
/usr/lib/i686-kfreebsd-gnu
/usr/lib/m68k-linux-gnu
/usr/lib/mips-linux-gnu
/usr/lib/mips64el-linux-gnuabi64
/usr/lib/mipsel-linux-gnu
/usr/lib/powerpc-linux-gnu
/usr/lib/powerpc-linux-gnuspe
/usr/lib/powerpc64-linux-gnu
/usr/lib/powerpc64le-linux-gnu
/usr/lib/s390x-linux-gnu
/usr/lib/riscv64-linux-gnu
/usr/lib/sparc64-linux-gnu
/usr/lib/x86_64-linux-gnux32
/usr/lib/sh4-linux-gnu
/usr/lib/loongarch64-linux-gnu
/usr/local/lib
/usr/local/lib64
/opt/local/lib
)
find_path(GNUTLS_INCLUDE_DIR NAMES gnutls/gnutls.h
PATHS
/usr/include
/usr/local/include
/opt/local/include # default location in Macports
/opt/homebrew/opt/gnutls/include/
${GNUTLS_ROOT_DIR}/include/
)
if(NOT GNUTLS_OPENSSL_LIBRARY)
message(" The GnuTLS library with openssl compatibility enabled has not been found.")
message(" You can try to install the required libraries by typing:")
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|kFreeBSD|GNU")
if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
message(" sudo yum install openssl-devel")
else()
message(" sudo apt-get install libgnutls28-dev")
endif()
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
message(" 'sudo port install openssl3', if you are using Macports, or")
message(" 'brew install openssl', if you are using Homebrew.")
endif()
message(FATAL_ERROR "OpenSSL or the GnuTLS libraries with openssl compatibility are required to build gnss-sdr")
endif()
# Test GnuTLS capabilities
file(READ "${GNUTLS_INCLUDE_DIR}/gnutls/gnutls.h" gnutls_gnutls_file_contents)
if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_SIGN_ECDSA_SHA256")
set(GNUTLS_SIGN_ECDSA_SHA256 TRUE)
endif()
if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_DIG_SHA3_256")
set(GNUTLS_DIG_SHA3_256 TRUE)
endif()
if("${gnutls_gnutls_file_contents}" MATCHES "#define GNUTLS_VERSION_MAJOR 2")
set(GNUTLS_HMAC_INIT_WITH_DIGEST TRUE)
endif()
if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_MAC_AES_CMAC_128")
set(GNUTLS_MAC_AES_CMAC_128 TRUE)
endif()
file(READ "${GNUTLS_INCLUDE_DIR}/gnutls/abstract.h" gnutls_abstract_file_contents)
if("${gnutls_abstract_file_contents}" MATCHES "gnutls_pubkey_export2")
set(GNUTLS_PUBKEY_EXPORT2 TRUE)
endif()
endif()
################################################################################
function(link_to_crypto_dependencies target)
if(OPENSSL_FOUND)
if(TARGET OpenSSL::SSL)
target_link_libraries(${target}
PUBLIC
OpenSSL::SSL
)
if(TARGET OpenSSL::Crypto)
target_link_libraries(${target}
PUBLIC
OpenSSL::Crypto
)
endif()
else()
target_link_libraries(${target}
PUBLIC
${OPENSSL_LIBRARIES}
"${OPENSSL_CRYPTO_LIBRARIES}"
)
target_include_directories(${target}
PUBLIC
${OPENSSL_INCLUDE_DIR}
)
endif()
if(OPENSSL_VERSION)
if(OPENSSL_VERSION VERSION_GREATER "3.0.0")
target_compile_definitions(${target} PUBLIC -DUSE_OPENSSL_3=1)
else()
if(NOT OPENSSL_VERSION VERSION_LESS "1.1.1")
target_compile_definitions(${target} PUBLIC -DUSE_OPENSSL_111=1)
endif()
endif()
else()
endif()
else() # GnuTLS
target_link_libraries(${target}
PUBLIC
${GNUTLS_LIBRARIES}
${GNUTLS_OPENSSL_LIBRARY}
)
target_include_directories(${target}
PUBLIC
${GNUTLS_INCLUDE_DIR}
)
target_compile_definitions(${target} PUBLIC -DUSE_GNUTLS_FALLBACK=1)
if(GNUTLS_SIGN_ECDSA_SHA256)
target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_SIGN_ECDSA_SHA256=1)
endif()
if(GNUTLS_DIG_SHA3_256)
target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_DIG_SHA3_256=1)
endif()
if(GNUTLS_PUBKEY_EXPORT2)
target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_PUBKEY_EXPORT2=1)
endif()
if(GNUTLS_HMAC_INIT_WITH_DIGEST)
target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_HMAC_INIT_WITH_DIGEST=1)
endif()
if(GNUTLS_MAC_AES_CMAC_128)
target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_MAC_AES_CMAC_128=1)
endif()
endif()
endfunction()

View File

@ -55,6 +55,15 @@ All notable changes to GNSS-SDR will be documented in this file.
This change has a downside in maintainability, since the source code becomes This change has a downside in maintainability, since the source code becomes
plagued with preprocessor directives required to maintain compatibility both plagued with preprocessor directives required to maintain compatibility both
with gflags and glog, and with Abseil. with gflags and glog, and with Abseil.
- Historically, GNSS-SDR linked against the GnuTLS library for cryptographic
functions. If GnuTLS was not found, then the building system looked for and
linked against OpenSSL as a fallback. This was due to the OpenSSL 1.x dual
license scheme, which was incompatible with GPL v3.0 license, preventing it
from being a mandatory dependency for GNSS-SDR in most GNU/Linux
distributions. This issue was solved with the release of OpenSSL 3.0.0, which
transitioned to the Apache License 2.0, fully compatible with GPL v3.0.
Accordingly, the GNSS-SDR building system now looks for OpenSSL in the first
place and, if not found, then it looks for GnuTLS as a fallback.
### Improvements in Usability: ### Improvements in Usability:

View File

@ -317,7 +317,7 @@ void osnma_msg_receiver::local_time_verification(const std::shared_ptr<OSNMA_msg
// std::cout << "Galileo OSNMA: d_receiver_time: " << d_receiver_time << std::endl; // std::cout << "Galileo OSNMA: d_receiver_time: " << d_receiver_time << std::endl;
} }
// verify time constraint // verify time constraint
std::time_t delta_T = abs(d_receiver_time - d_GST_SIS); std::time_t delta_T = std::abs(static_cast<int64_t>(d_receiver_time - d_GST_SIS));
if (delta_T <= d_T_L) if (delta_T <= d_T_L)
{ {
d_tags_allowed = tags_to_verify::all; d_tags_allowed = tags_to_verify::all;

View File

@ -46,16 +46,9 @@ if(CMAKE_C_COMPILER_ID MATCHES "Clang|GNU" AND (CMAKE_VERSION VERSION_GREATER "3
target_compile_options(core_libs_supl PUBLIC $<$<COMPILE_LANGUAGE:C>:${MY_C_FLAGS}>) target_compile_options(core_libs_supl PUBLIC $<$<COMPILE_LANGUAGE:C>:${MY_C_FLAGS}>)
endif() endif()
if(OPENSSL_FOUND) # links to the appropriate library and defines
target_compile_definitions(core_libs_supl PUBLIC -DUSE_OPENSSL_FALLBACK=1) # USE_GNUTLS_FALLBACK, USE_OPENSSL_3, or USE_OPENSSL_111 accordingly.
endif() link_to_crypto_dependencies(core_libs_supl)
message("OPENSSL_FOUND: " ${OPENSSL_FOUND})
message("USE_OPENSSL_FALLBACK:" ${USE_OPENSSL_FALLBACK})
target_link_libraries(core_libs_supl
PUBLIC
${GNUTLS_LIBRARIES}
${GNUTLS_OPENSSL_LIBRARY}
)
target_include_directories(core_libs_supl target_include_directories(core_libs_supl
PUBLIC PUBLIC

View File

@ -24,18 +24,18 @@
#define EXPORT #define EXPORT
#endif #endif
// clang-format off // clang-format off
#if USE_OPENSSL_FALLBACK #if USE_GNUTLS_FALLBACK
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#else
#include <gnutls/gnutls.h> #include <gnutls/gnutls.h>
#include <gnutls/compat.h> #include <gnutls/compat.h>
#include <gnutls/crypto.h> #include <gnutls/crypto.h>
#include <gnutls/openssl.h> #include <gnutls/openssl.h>
#include <gnutls/x509.h> #include <gnutls/x509.h>
#else
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#endif #endif
// clang-format on // clang-format on
#include <PDU.h> #include <PDU.h>

View File

@ -121,7 +121,7 @@ void GNSSFlowgraph::init()
galileo_tow_map_ = nullptr; galileo_tow_map_ = nullptr;
} }
if (configuration_->property("Channels_1B.count", 0) > 0) if (configuration_->property("Channels_1B.count", 0) > 0 && configuration_->property("GNSS-SDR.osnma_enable", true))
{ {
enable_osnma_rx_ = true; enable_osnma_rx_ = true;
const auto certFilePath = configuration_->property("GNSS-SDR.osnma_public_key", CRTFILE_DEFAULT); const auto certFilePath = configuration_->property("GNSS-SDR.osnma_public_key", CRTFILE_DEFAULT);

View File

@ -124,7 +124,7 @@ target_link_libraries(core_system_parameters
Boost::date_time Boost::date_time
Boost::serialization Boost::serialization
PRIVATE PRIVATE
Pugixml::pugixml Pugixml::pugixml
) )
if(ENABLE_GLOG_AND_GFLAGS) if(ENABLE_GLOG_AND_GFLAGS)
@ -140,50 +140,9 @@ target_include_directories(core_system_parameters
${GNSSSDR_SOURCE_DIR}/src/algorithms/libs ${GNSSSDR_SOURCE_DIR}/src/algorithms/libs
) )
if(OPENSSL_FOUND) # links to the appropriate library and defines
message("OPENSSL_FOUND: " ${OPENSSL_FOUND}) # USE_GNUTLS_FALLBACK, USE_OPENSSL_3, or USE_OPENSSL_111 accordingly.
if(TARGET OpenSSL::SSL) link_to_crypto_dependencies(core_system_parameters)
target_link_libraries(core_system_parameters
PUBLIC
OpenSSL::SSL
)
else()
target_link_libraries(core_system_parameters
PUBLIC
${OPENSSL_LIBRARIES}
)
target_include_directories(core_system_parameters
PUBLIC
${OPENSSL_INCLUDE_DIR}
)
endif()
if(OPENSSL_VERSION)
message("OPENSSL_VERSION: " ${OPENSSL_VERSION})
if(OPENSSL_VERSION VERSION_GREATER "3.0.0")
target_compile_definitions(core_system_parameters PUBLIC -DUSE_OPENSSL_FALLBACK=1 -DUSE_OPENSSL_3=1)
message("USE_OPENSSL_3: " ${DUSE_OPENSSL_3})
message("USE_OPENSSL_FALLBACK:" ${USE_OPENSSL_FALLBACK})
else()
if(NOT OPENSSL_VERSION VERSION_LESS "1.1.1")
target_compile_definitions(core_system_parameters PRIVATE -DUSE_OPENSSL_FALLBACK=1 -DUSE_OPENSSL_111=1)
endif()
endif()
endif()
else()
target_link_libraries(core_system_parameters
PUBLIC
${GNUTLS_LIBRARIES}
${GNUTLS_OPENSSL_LIBRARY}
)
target_include_directories(core_system_parameters
PUBLIC
${GNUTLS_INCLUDE_DIR}
)
endif()
if(OPENSSL_FOUND)
target_compile_definitions(core_system_parameters PUBLIC -DUSE_OPENSSL_FALLBACK=1)
endif()
if(ENABLE_CLANG_TIDY) if(ENABLE_CLANG_TIDY)
if(CLANG_TIDY_EXE) if(CLANG_TIDY_EXE)

View File

@ -25,7 +25,11 @@
#include <iostream> #include <iostream>
#include <iterator> #include <iterator>
#if USE_OPENSSL_FALLBACK #if USE_GNUTLS_FALLBACK
#include <cstring>
#include <gnutls/crypto.h>
#include <gnutls/x509.h>
#else // OpenSSL
#include <openssl/cmac.h> #include <openssl/cmac.h>
#include <openssl/ecdsa.h> #include <openssl/ecdsa.h>
#include <openssl/hmac.h> #include <openssl/hmac.h>
@ -40,14 +44,9 @@
#include <openssl/param_build.h> #include <openssl/param_build.h>
#include <openssl/params.h> #include <openssl/params.h>
#define OPENSSL_ENGINE nullptr #define OPENSSL_ENGINE nullptr
#else #else // OpenSSL 1.x
#include <openssl/sha.h> #include <openssl/sha.h>
#endif #endif
#else // GnuTLS
#include <cstring>
#include <gnutls/abstract.h>
#include <gnutls/crypto.h>
#include <gnutls/x509.h>
#endif #endif
#if USE_GLOG_AND_GFLAGS #if USE_GLOG_AND_GFLAGS
@ -59,28 +58,38 @@
Gnss_Crypto::Gnss_Crypto() Gnss_Crypto::Gnss_Crypto()
{ {
#if USE_OPENSSL_FALLBACK #if USE_GNUTLS_FALLBACK
gnutls_global_init();
#if !HAVE_GNUTLS_SIGN_ECDSA_SHA256
LOG(WARNING) << "The GnuTLS library version you are linking against is too old for some OSNMA functions."
<< " Please do not trust OSNMA ouputs or upgrade your system to a newer version of GnuTLS or OpenSSL"
<< " and rebuild GNSS-SDR against it.";
#endif
#else // OpenSSL
#if !(USE_OPENSSL_3 || USE_OPENSSL_111) #if !(USE_OPENSSL_3 || USE_OPENSSL_111)
LOG(WARNING) << "The OpenSSL library version you are linking against is too old for some OSNMA functions." LOG(WARNING) << "The OpenSSL library version you are linking against is too old for some OSNMA functions."
<< " Please do not trust OSNMA ouputs or upgrade your system to a newer version of OpenSSL" << " Please do not trust OSNMA ouputs or upgrade your system to a newer version of OpenSSL"
<< " and rebuild GNSS-SDR against it."; << " and rebuild GNSS-SDR against it.";
#endif #endif
#else // GnuTLS
gnutls_global_init();
#endif #endif
} }
Gnss_Crypto::Gnss_Crypto(const std::string& certFilePath, const std::string& merkleTreePath) Gnss_Crypto::Gnss_Crypto(const std::string& certFilePath, const std::string& merkleTreePath)
{ {
#if USE_OPENSSL_FALLBACK #if USE_GNUTLS_FALLBACK
gnutls_global_init();
#if !HAVE_GNUTLS_SIGN_ECDSA_SHA256
LOG(WARNING) << "The GnuTLS library version you are linking against is too old for some OSNMA functions."
<< " Please do not trust OSNMA ouputs or upgrade your system to a newer version of GnuTLS or OpenSSL"
<< " and rebuild GNSS-SDR against it.";
#endif
#else // OpenSSL
#if !(USE_OPENSSL_3 || USE_OPENSSL_111) #if !(USE_OPENSSL_3 || USE_OPENSSL_111)
LOG(WARNING) << "The OpenSSL library version you are linking against is too old for some OSNMA functions." LOG(WARNING) << "The OpenSSL library version you are linking against is too old for some OSNMA functions."
<< " Please do not trust OSNMA ouputs or upgrade your system to a newer version of OpenSSL" << " Please do not trust OSNMA ouputs or upgrade your system to a newer version of OpenSSL"
<< " and rebuild GNSS-SDR against it."; << " and rebuild GNSS-SDR against it.";
#endif #endif
#else // GnuTLS
gnutls_global_init();
#endif #endif
if (!readPublicKeyFromCRT(certFilePath)) if (!readPublicKeyFromCRT(certFilePath))
{ {
@ -92,31 +101,30 @@ Gnss_Crypto::Gnss_Crypto(const std::string& certFilePath, const std::string& mer
Gnss_Crypto::~Gnss_Crypto() Gnss_Crypto::~Gnss_Crypto()
{ {
#if USE_OPENSSL_FALLBACK #if USE_GNUTLS_FALLBACK
#if USE_OPENSSL_3
#else
if (d_PublicKey != nullptr)
{
EC_KEY_free(d_PublicKey);
}
#endif
#else // GnuTLS
if (d_PublicKey != nullptr) if (d_PublicKey != nullptr)
{ {
gnutls_pubkey_deinit(d_PublicKey); gnutls_pubkey_deinit(d_PublicKey);
d_PublicKey = nullptr; d_PublicKey = nullptr;
} }
gnutls_global_deinit(); gnutls_global_deinit();
#else // OpenSSL
#if !USE_OPENSSL_3
if (d_PublicKey != nullptr)
{
EC_KEY_free(d_PublicKey);
}
#endif
#endif #endif
} }
bool Gnss_Crypto::have_public_key() const bool Gnss_Crypto::have_public_key() const
{ {
#if USE_OPENSSL_FALLBACK #if USE_GNUTLS_FALLBACK
return (d_PublicKey != nullptr);
#else // GnuTLS
return (d_PublicKey != gnutls_pubkey_t{}); return (d_PublicKey != gnutls_pubkey_t{});
#else // OpenSSL
return (d_PublicKey != nullptr);
#endif #endif
} }
@ -260,7 +268,15 @@ void Gnss_Crypto::read_merkle_xml(const std::string& merkleFilePath)
std::vector<uint8_t> Gnss_Crypto::computeSHA256(const std::vector<uint8_t>& input) const std::vector<uint8_t> Gnss_Crypto::computeSHA256(const std::vector<uint8_t>& input) const
{ {
std::vector<uint8_t> output(32); // SHA256 hash size std::vector<uint8_t> output(32); // SHA256 hash size
#if USE_OPENSSL_FALLBACK #if USE_GNUTLS_FALLBACK
std::vector<uint8_t> output_aux(32);
gnutls_hash_hd_t hashHandle;
gnutls_hash_init(&hashHandle, GNUTLS_DIG_SHA256);
gnutls_hash(hashHandle, input.data(), input.size());
gnutls_hash_output(hashHandle, output_aux.data());
output = output_aux;
gnutls_hash_deinit(hashHandle, output_aux.data());
#else // OpenSSL
#if USE_OPENSSL_3 #if USE_OPENSSL_3
unsigned int mdLen; unsigned int mdLen;
EVP_MD_CTX* mdCtx = EVP_MD_CTX_new(); EVP_MD_CTX* mdCtx = EVP_MD_CTX_new();
@ -283,20 +299,12 @@ std::vector<uint8_t> Gnss_Crypto::computeSHA256(const std::vector<uint8_t>& inpu
return output; return output;
} }
EVP_MD_CTX_free(mdCtx); EVP_MD_CTX_free(mdCtx);
#else #else // OpenSSL 1.x
SHA256_CTX sha256Context; SHA256_CTX sha256Context;
SHA256_Init(&sha256Context); SHA256_Init(&sha256Context);
SHA256_Update(&sha256Context, input.data(), input.size()); SHA256_Update(&sha256Context, input.data(), input.size());
SHA256_Final(output.data(), &sha256Context); SHA256_Final(output.data(), &sha256Context);
#endif #endif
#else // GnuTLS
std::vector<uint8_t> output_aux(32);
gnutls_hash_hd_t hashHandle;
gnutls_hash_init(&hashHandle, GNUTLS_DIG_SHA256);
gnutls_hash(hashHandle, input.data(), input.size());
gnutls_hash_output(hashHandle, output_aux.data());
output = output_aux;
gnutls_hash_deinit(hashHandle, output_aux.data());
#endif #endif
return output; return output;
} }
@ -305,23 +313,8 @@ std::vector<uint8_t> Gnss_Crypto::computeSHA256(const std::vector<uint8_t>& inpu
std::vector<uint8_t> Gnss_Crypto::computeSHA3_256(const std::vector<uint8_t>& input) const std::vector<uint8_t> Gnss_Crypto::computeSHA3_256(const std::vector<uint8_t>& input) const
{ {
std::vector<uint8_t> output(32); // SHA256 hash size std::vector<uint8_t> output(32); // SHA256 hash size
#if USE_OPENSSL_FALLBACK #if USE_GNUTLS_FALLBACK
#if USE_OPENSSL_3 || USE_OPENSSL_111 #if HAVE_GNUTLS_DIG_SHA3_256
EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
const EVP_MD* md = EVP_sha3_256();
EVP_DigestInit_ex(mdctx, md, nullptr);
EVP_DigestUpdate(mdctx, input.data(), input.size());
EVP_DigestFinal_ex(mdctx, output.data(), nullptr);
EVP_MD_CTX_free(mdctx);
#else
// SHA3-256 not implemented in OpenSSL 1.0, it was introduced in OpenSSL 1.1.1
if (!input.empty())
{
// do nothing
}
#endif
#else // GnuTLS
std::vector<uint8_t> output_aux(32); std::vector<uint8_t> output_aux(32);
gnutls_hash_hd_t hashHandle; gnutls_hash_hd_t hashHandle;
gnutls_hash_init(&hashHandle, GNUTLS_DIG_SHA3_256); gnutls_hash_init(&hashHandle, GNUTLS_DIG_SHA3_256);
@ -329,6 +322,23 @@ std::vector<uint8_t> Gnss_Crypto::computeSHA3_256(const std::vector<uint8_t>& in
gnutls_hash_output(hashHandle, output_aux.data()); gnutls_hash_output(hashHandle, output_aux.data());
output = output_aux; output = output_aux;
gnutls_hash_deinit(hashHandle, output_aux.data()); gnutls_hash_deinit(hashHandle, output_aux.data());
#endif
#else // OpenSSL
#if USE_OPENSSL_3 || USE_OPENSSL_111
EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
const EVP_MD* md = EVP_sha3_256();
EVP_DigestInit_ex(mdctx, md, nullptr);
EVP_DigestUpdate(mdctx, input.data(), input.size());
EVP_DigestFinal_ex(mdctx, output.data(), nullptr);
EVP_MD_CTX_free(mdctx);
#else // OpenSSL 1.x
// SHA3-256 not implemented in OpenSSL 1.0, it was introduced in OpenSSL 1.1.1
if (!input.empty())
{
// do nothing
}
#endif
#endif #endif
return output; return output;
} }
@ -337,7 +347,19 @@ std::vector<uint8_t> Gnss_Crypto::computeSHA3_256(const std::vector<uint8_t>& in
std::vector<uint8_t> Gnss_Crypto::computeHMAC_SHA_256(const std::vector<uint8_t>& key, const std::vector<uint8_t>& input) const std::vector<uint8_t> Gnss_Crypto::computeHMAC_SHA_256(const std::vector<uint8_t>& key, const std::vector<uint8_t>& input) const
{ {
std::vector<uint8_t> output(32); std::vector<uint8_t> output(32);
#if USE_OPENSSL_FALLBACK #if USE_GNUTLS_FALLBACK
std::vector<uint8_t> output_aux(32);
gnutls_hmac_hd_t hmac;
#if HAVE_GNUTLS_HMAC_INIT_WITH_DIGEST
gnutls_hmac_init(&hmac, GNUTLS_DIG_SHA256, key.data(), key.size());
#else
gnutls_hmac_init(&hmac, GNUTLS_MAC_SHA256, key.data(), key.size());
#endif
gnutls_hmac(hmac, input.data(), input.size());
gnutls_hmac_output(hmac, output_aux.data());
output = output_aux;
gnutls_hmac_deinit(hmac, output_aux.data());
#else // OpenSSL
#if USE_OPENSSL_3 #if USE_OPENSSL_3
std::vector<uint8_t> hmac(EVP_MAX_MD_SIZE); std::vector<uint8_t> hmac(EVP_MAX_MD_SIZE);
size_t output_length = 0; size_t output_length = 0;
@ -393,7 +415,7 @@ std::vector<uint8_t> Gnss_Crypto::computeHMAC_SHA_256(const std::vector<uint8_t>
EVP_MAC_free(mac); EVP_MAC_free(mac);
hmac.resize(output_length); hmac.resize(output_length);
output = hmac; output = hmac;
#else #else // OpenSSL 1.x
unsigned int outputLength = EVP_MAX_MD_SIZE; unsigned int outputLength = EVP_MAX_MD_SIZE;
unsigned char* result = HMAC(EVP_sha256(), key.data(), key.size(), input.data(), input.size(), output.data(), &outputLength); unsigned char* result = HMAC(EVP_sha256(), key.data(), key.size(), input.data(), input.size(), output.data(), &outputLength);
if (result == nullptr) if (result == nullptr)
@ -405,14 +427,6 @@ std::vector<uint8_t> Gnss_Crypto::computeHMAC_SHA_256(const std::vector<uint8_t>
// Resize the output vector to the actual length of the HMAC-SHA256 output // Resize the output vector to the actual length of the HMAC-SHA256 output
output.resize(outputLength); output.resize(outputLength);
#endif #endif
#else // GnuTLS
std::vector<uint8_t> output_aux(32);
gnutls_hmac_hd_t hmac;
gnutls_hmac_init(&hmac, GNUTLS_MAC_SHA256, key.data(), key.size());
gnutls_hmac(hmac, input.data(), input.size());
gnutls_hmac_output(hmac, output_aux.data());
output = output_aux;
gnutls_hmac_deinit(hmac, output_aux.data());
#endif #endif
return output; return output;
} }
@ -421,7 +435,43 @@ std::vector<uint8_t> Gnss_Crypto::computeHMAC_SHA_256(const std::vector<uint8_t>
std::vector<uint8_t> Gnss_Crypto::computeCMAC_AES(const std::vector<uint8_t>& key, const std::vector<uint8_t>& input) const std::vector<uint8_t> Gnss_Crypto::computeCMAC_AES(const std::vector<uint8_t>& key, const std::vector<uint8_t>& input) const
{ {
std::vector<uint8_t> output(16); std::vector<uint8_t> output(16);
#if USE_OPENSSL_FALLBACK #if USE_GNUTLS_FALLBACK
#if HAVE_GNUTLS_MAC_AES_CMAC_128
gnutls_hmac_hd_t hmac;
// Initialize the HMAC context with the CMAC algorithm and key
int ret = gnutls_hmac_init(&hmac, GNUTLS_MAC_AES_CMAC_128, key.data(), key.size());
if (ret != GNUTLS_E_SUCCESS)
{
LOG(INFO) << "OSNMA CMAC-AES: gnutls_hmac_init failed: " << gnutls_strerror(ret);
return output;
}
// Update the HMAC context with the input data
ret = gnutls_hmac(hmac, input.data(), input.size());
if (ret != GNUTLS_E_SUCCESS)
{
LOG(INFO) << "OSNMA CMAC-AES: gnutls_hmac failed: " << gnutls_strerror(ret);
gnutls_hmac_deinit(hmac, nullptr);
return output;
}
// Retrieve the HMAC output
gnutls_hmac_output(hmac, output.data());
// Clean up the HMAC context
gnutls_hmac_deinit(hmac, nullptr);
#else
if (!key.empty())
{
// do nothing
}
if (!input.empty())
{
// do nothing
}
#endif
#else // OpenSSL
#if USE_OPENSSL_3 #if USE_OPENSSL_3
std::vector<uint8_t> aux(EVP_MAX_MD_SIZE); // CMAC-AES output size std::vector<uint8_t> aux(EVP_MAX_MD_SIZE); // CMAC-AES output size
size_t output_length = 0; size_t output_length = 0;
@ -479,33 +529,47 @@ std::vector<uint8_t> Gnss_Crypto::computeCMAC_AES(const std::vector<uint8_t>& ke
aux.resize(output_length); aux.resize(output_length);
output = aux; output = aux;
#else #else // OpenSSL 1.x
std::vector<uint8_t> mac(16); // CMAC-AES output size size_t mac_length = 0; // to hold the length of the MAC output
// Create CMAC context // Create CMAC context
CMAC_CTX* cmacCtx = CMAC_CTX_new(); CMAC_CTX* cmacCtx = CMAC_CTX_new();
CMAC_Init(cmacCtx, key.data(), key.size(), EVP_aes_128_cbc(), nullptr); if (!cmacCtx)
{
LOG(INFO) << "OSNMA CMAC-AES: Failed to create CMAC context";
return output;
}
// Compute CMAC-AES // Initialize the CMAC context with the key and cipher
CMAC_Update(cmacCtx, input.data(), input.size()); if (CMAC_Init(cmacCtx, key.data(), key.size(), EVP_aes_128_cbc(), nullptr) != 1)
CMAC_Final(cmacCtx, mac.data(), nullptr); {
LOG(INFO) << "OSNMA CMAC-AES: MAC_Init failed";
CMAC_CTX_free(cmacCtx);
return output;
}
// Compute the CMAC
if (CMAC_Update(cmacCtx, input.data(), input.size()) != 1)
{
LOG(INFO) << "OSNMA CMAC-AES: CMAC_Update failed";
CMAC_CTX_free(cmacCtx);
return output;
}
// Finalize the CMAC computation and retrieve the output
if (CMAC_Final(cmacCtx, output.data(), &mac_length) != 1)
{
LOG(INFO) << "OSNMA CMAC-AES: CMAC_Final failed";
CMAC_CTX_free(cmacCtx);
return output;
}
// Clean up CMAC context // Clean up CMAC context
CMAC_CTX_free(cmacCtx); CMAC_CTX_free(cmacCtx);
output = mac; // Ensure the output vector is properly sized according to the actual MAC length
output.resize(mac_length);
#endif #endif
#else // GnuTLS
gnutls_cipher_hd_t cipher;
std::vector<uint8_t> mac(16);
std::vector<uint8_t> message = input;
gnutls_datum_t key_data = {const_cast<uint8_t*>(key.data()), static_cast<unsigned int>(key.size())};
gnutls_cipher_init(&cipher, GNUTLS_CIPHER_AES_128_CBC, &key_data, nullptr);
gnutls_cipher_set_iv(cipher, nullptr, 16); // Set IV to zero
gnutls_cipher_encrypt(cipher, message.data(), message.size()); // Encrypt the message with AES-128
gnutls_cipher_tag(cipher, mac.data(), mac.size()); // Get the CMAC-AES tag
output = mac;
gnutls_cipher_deinit(cipher);
#endif #endif
return output; return output;
} }
@ -526,29 +590,9 @@ void Gnss_Crypto::readPublicKeyFromPEM(const std::string& pemFilePath)
return; return;
} }
std::string pemContent((std::istreambuf_iterator<char>(pemFile)), std::istreambuf_iterator<char>()); std::string pemContent((std::istreambuf_iterator<char>(pemFile)), std::istreambuf_iterator<char>());
#if USE_OPENSSL_FALLBACK #if USE_GNUTLS_FALLBACK
// Create a BIO object from the string data
BIO* bio = BIO_new_mem_buf(pemContent.c_str(), pemContent.length());
if (!bio)
{
std::cerr << "OpenSSL: error creating a BIO object with data read from file " << pemFilePath << ". Aborting import" << std::endl;
return;
}
#if USE_OPENSSL_3
d_PublicKey = PEM_read_bio_PUBKEY(bio, nullptr, nullptr, nullptr);
#else
d_PublicKey = PEM_read_bio_EC_PUBKEY(bio, nullptr, nullptr, nullptr);
#endif
BIO_free(bio);
if (d_PublicKey == nullptr)
{
std::cerr << "OpenSSL: error reading the OSNMA Public Key from file " << pemFilePath << ". Aborting import" << std::endl;
LOG(INFO) << "OpenSSL: error reading the OSNMA Public Key from file " << pemFilePath << ". Aborting import";
return;
}
#else // GnuTLS
// Import the PEM data // Import the PEM data
gnutls_datum_t pemDatum = {const_cast<unsigned char*>(reinterpret_cast<unsigned char*>(pemContent.data())), static_cast<unsigned int>(pemContent.size())}; gnutls_datum_t pemDatum = {const_cast<unsigned char*>(reinterpret_cast<unsigned char*>(const_cast<char*>(pemContent.data()))), static_cast<unsigned int>(pemContent.size())};
gnutls_pubkey_t pubkey; gnutls_pubkey_t pubkey;
gnutls_pubkey_init(&pubkey); gnutls_pubkey_init(&pubkey);
@ -566,6 +610,26 @@ void Gnss_Crypto::readPublicKeyFromPEM(const std::string& pemFilePath)
pubkey_copy(pubkey, &d_PublicKey); pubkey_copy(pubkey, &d_PublicKey);
gnutls_pubkey_deinit(pubkey); gnutls_pubkey_deinit(pubkey);
#else // OpenSSL
// Create a BIO object from the string data
BIO* bio = BIO_new_mem_buf(const_cast<char*>(pemContent.c_str()), pemContent.length());
if (!bio)
{
std::cerr << "OpenSSL: error creating a BIO object with data read from file " << pemFilePath << ". Aborting import" << std::endl;
return;
}
#if USE_OPENSSL_3
d_PublicKey = PEM_read_bio_PUBKEY(bio, nullptr, nullptr, nullptr);
#else // OpenSSL 1.x
d_PublicKey = PEM_read_bio_EC_PUBKEY(bio, nullptr, nullptr, nullptr);
#endif
BIO_free(bio);
if (d_PublicKey == nullptr)
{
std::cerr << "OpenSSL: error reading the OSNMA Public Key from file " << pemFilePath << ". Aborting import" << std::endl;
LOG(INFO) << "OpenSSL: error reading the OSNMA Public Key from file " << pemFilePath << ". Aborting import";
return;
}
#endif #endif
std::cout << "OSNMA Public key successfully read from file " << pemFilePath << std::endl; std::cout << "OSNMA Public key successfully read from file " << pemFilePath << std::endl;
LOG(INFO) << "OSNMA Public key successfully read from file " << pemFilePath; LOG(INFO) << "OSNMA Public key successfully read from file " << pemFilePath;
@ -574,57 +638,7 @@ void Gnss_Crypto::readPublicKeyFromPEM(const std::string& pemFilePath)
bool Gnss_Crypto::readPublicKeyFromCRT(const std::string& crtFilePath) bool Gnss_Crypto::readPublicKeyFromCRT(const std::string& crtFilePath)
{ {
#if USE_OPENSSL_FALLBACK #if USE_GNUTLS_FALLBACK
// Open the .crt file
std::ifstream crtFile(crtFilePath, std::ios::binary);
if (!crtFile.is_open())
{
std::cerr << "Unable to open file: " << crtFilePath << std::endl;
return false;
}
// Read certificate
std::vector<char> buffer((std::istreambuf_iterator<char>(crtFile)), std::istreambuf_iterator<char>());
BIO* bio = BIO_new_mem_buf(buffer.data(), buffer.size());
if (!bio)
{
std::cerr << "Unable to create BIO for file: " << crtFilePath << std::endl;
return false;
}
X509* cert = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr);
if (!cert)
{
std::cerr << "Unable to read certificate from file: " << crtFilePath << std::endl;
BIO_free(bio);
return false;
}
// Read the public key from the certificate
EVP_PKEY* pubkey = X509_get_pubkey(cert);
#if USE_OPENSSL_3
if (!pubkey)
{
std::cerr << "Failed to extract the public key" << std::endl;
X509_free(cert);
return false;
}
pubkey_copy(pubkey, &d_PublicKey);
EVP_PKEY_free(pubkey);
#else
EC_KEY* ec_pubkey = EVP_PKEY_get1_EC_KEY(pubkey);
EVP_PKEY_free(pubkey);
if (!ec_pubkey)
{
std::cerr << "Failed to extract the public key" << std::endl;
X509_free(cert);
return false;
}
pubkey_copy(ec_pubkey, &d_PublicKey);
EC_KEY_free(ec_pubkey);
#endif
BIO_free(bio);
X509_free(cert);
#else // GnuTLS
// Open the .crt file // Open the .crt file
std::ifstream crtFile(crtFilePath, std::ios::binary); std::ifstream crtFile(crtFilePath, std::ios::binary);
if (!crtFile.is_open()) if (!crtFile.is_open())
@ -664,6 +678,56 @@ bool Gnss_Crypto::readPublicKeyFromCRT(const std::string& crtFilePath)
pubkey_copy(pubkey, &d_PublicKey); pubkey_copy(pubkey, &d_PublicKey);
gnutls_x509_crt_deinit(cert); gnutls_x509_crt_deinit(cert);
gnutls_pubkey_deinit(pubkey); gnutls_pubkey_deinit(pubkey);
#else // OpenSSL
// Open the .crt file
std::ifstream crtFile(crtFilePath, std::ios::binary);
if (!crtFile.is_open())
{
std::cerr << "Unable to open file: " << crtFilePath << std::endl;
return false;
}
// Read certificate
std::vector<char> buffer((std::istreambuf_iterator<char>(crtFile)), std::istreambuf_iterator<char>());
BIO* bio = BIO_new_mem_buf(buffer.data(), buffer.size());
if (!bio)
{
std::cerr << "Unable to create BIO for file: " << crtFilePath << std::endl;
return false;
}
X509* cert = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr);
if (!cert)
{
std::cerr << "Unable to read certificate from file: " << crtFilePath << std::endl;
BIO_free(bio);
return false;
}
// Read the public key from the certificate
EVP_PKEY* pubkey = X509_get_pubkey(cert);
#if USE_OPENSSL_3
if (!pubkey)
{
std::cerr << "Failed to extract the public key" << std::endl;
X509_free(cert);
return false;
}
pubkey_copy(pubkey, &d_PublicKey);
EVP_PKEY_free(pubkey);
#else // OpenSSL 1.x
EC_KEY* ec_pubkey = EVP_PKEY_get1_EC_KEY(pubkey);
EVP_PKEY_free(pubkey);
if (!ec_pubkey)
{
std::cerr << "Failed to extract the public key" << std::endl;
X509_free(cert);
return false;
}
pubkey_copy(ec_pubkey, &d_PublicKey);
EC_KEY_free(ec_pubkey);
#endif
BIO_free(bio);
X509_free(cert);
#endif #endif
std::cout << "OSNMA Public key successfully read from file " << crtFilePath << std::endl; std::cout << "OSNMA Public key successfully read from file " << crtFilePath << std::endl;
LOG(INFO) << "OSNMA Public key successfully read from file " << crtFilePath; LOG(INFO) << "OSNMA Public key successfully read from file " << crtFilePath;
@ -680,7 +744,34 @@ bool Gnss_Crypto::verify_signature(const std::vector<uint8_t>& message, const st
return false; return false;
} }
bool success = false; bool success = false;
#if USE_OPENSSL_FALLBACK #if USE_GNUTLS_FALLBACK
#if HAVE_GNUTLS_SIGN_ECDSA_SHA256
// Convert signature to DER format
std::vector<uint8_t> der_sig;
if (!convert_raw_to_der_ecdsa(signature, der_sig))
{
std::cerr << "Failed to convert raw ECDSA signature to DER format" << std::endl;
return false;
}
// Prepare the digest datum
gnutls_datum_t digest_data = {const_cast<unsigned char*>(digest.data()), static_cast<unsigned int>(digest.size())};
gnutls_datum_t der_sig_data = {der_sig.data(), static_cast<unsigned int>(der_sig.size())};
// Verify the DER-encoded signature
int ret = gnutls_pubkey_verify_hash2(d_PublicKey, GNUTLS_SIGN_ECDSA_SHA256, 0, &digest_data, &der_sig_data);
success = (ret >= 0);
if (success)
{
LOG(INFO) << "GnuTLS: OSNMA signature authenticated successfully";
}
else
{
std::cerr << "GnuTLS: OSNMA message authentication failed: " << gnutls_strerror(ret) << std::endl;
LOG(WARNING) << "GnuTLS: OSNMA message authentication failed: " << gnutls_strerror(ret);
}
#endif
#else // OpenSSL
#if USE_OPENSSL_3 #if USE_OPENSSL_3
EVP_PKEY_CTX* ctx; EVP_PKEY_CTX* ctx;
ctx = EVP_PKEY_CTX_new(d_PublicKey, nullptr); ctx = EVP_PKEY_CTX_new(d_PublicKey, nullptr);
@ -753,7 +844,7 @@ bool Gnss_Crypto::verify_signature(const std::vector<uint8_t>& message, const st
std::cerr << "OpenSSL: OSNMA message authentication failed: " << err << std::endl; std::cerr << "OpenSSL: OSNMA message authentication failed: " << err << std::endl;
LOG(WARNING) << "OpenSSL: OSNMA message authentication failed: " << err; LOG(WARNING) << "OpenSSL: OSNMA message authentication failed: " << err;
} }
#else #else // OpenSSL 1.x
std::vector<uint8_t> der_sig; std::vector<uint8_t> der_sig;
if (!convert_raw_to_der_ecdsa(signature, der_sig)) if (!convert_raw_to_der_ecdsa(signature, der_sig))
{ {
@ -777,31 +868,6 @@ bool Gnss_Crypto::verify_signature(const std::vector<uint8_t>& message, const st
LOG(WARNING) << "OpenSSL: OSNMA message authentication failed"; LOG(WARNING) << "OpenSSL: OSNMA message authentication failed";
} }
#endif #endif
#else // GnuTLS
// Convert signature to DER format
std::vector<uint8_t> der_sig;
if (!convert_raw_to_der_ecdsa(signature, der_sig))
{
std::cerr << "Failed to convert raw ECDSA signature to DER format" << std::endl;
return false;
}
// Prepare the digest datum
gnutls_datum_t digest_data = {const_cast<unsigned char*>(digest.data()), static_cast<unsigned int>(digest.size())};
gnutls_datum_t der_sig_data = {der_sig.data(), static_cast<unsigned int>(der_sig.size())};
// Verify the DER-encoded signature
int ret = gnutls_pubkey_verify_hash2(d_PublicKey, GNUTLS_SIGN_ECDSA_SHA256, 0, &digest_data, &der_sig_data);
success = (ret >= 0);
if (success)
{
LOG(INFO) << "GnuTLS: OSNMA signature authenticated successfully";
}
else
{
std::cerr << "GnuTLS: OSNMA message authentication failed: " << gnutls_strerror(ret) << std::endl;
LOG(WARNING) << "GnuTLS: OSNMA message authentication failed: " << gnutls_strerror(ret);
}
#endif #endif
return success; return success;
} }
@ -845,10 +911,24 @@ std::vector<uint8_t> Gnss_Crypto::getMerkleRoot(const std::vector<std::vector<ui
void Gnss_Crypto::set_public_key(const std::vector<uint8_t>& publicKey) void Gnss_Crypto::set_public_key(const std::vector<uint8_t>& publicKey)
{ {
#if USE_OPENSSL_FALLBACK #if USE_GNUTLS_FALLBACK
gnutls_pubkey_t pubkey;
gnutls_datum_t pemDatum = {const_cast<unsigned char*>(publicKey.data()), static_cast<unsigned int>(publicKey.size())};
gnutls_pubkey_init(&pubkey);
int ret = gnutls_pubkey_import(pubkey, &pemDatum, GNUTLS_X509_FMT_PEM);
if (ret != GNUTLS_E_SUCCESS)
{
gnutls_pubkey_deinit(pubkey);
std::cerr << "GnuTLS: error setting the public key" << std::endl;
std::cerr << "GnuTLS error: " << gnutls_strerror(ret) << std::endl;
return;
}
pubkey_copy(pubkey, &d_PublicKey);
gnutls_pubkey_deinit(pubkey);
#else // OpenSSL
BIO* bio = nullptr; BIO* bio = nullptr;
EVP_PKEY* pkey = nullptr; EVP_PKEY* pkey = nullptr;
bio = BIO_new_mem_buf(publicKey.data(), publicKey.size()); bio = BIO_new_mem_buf(const_cast<uint8_t*>(publicKey.data()), publicKey.size());
if (!bio) if (!bio)
{ {
std::cerr << "Failed to create BIO for key \n"; std::cerr << "Failed to create BIO for key \n";
@ -876,22 +956,8 @@ void Gnss_Crypto::set_public_key(const std::vector<uint8_t>& publicKey)
return; return;
} }
EC_KEY_free(ec_pkey); EC_KEY_free(ec_pkey);
#endif #endif // OpenSSL 1.x
EVP_PKEY_free(pkey); EVP_PKEY_free(pkey);
#else // GnuTLS
gnutls_pubkey_t pubkey;
gnutls_datum_t pemDatum = {const_cast<unsigned char*>(publicKey.data()), static_cast<unsigned int>(publicKey.size())};
gnutls_pubkey_init(&pubkey);
int ret = gnutls_pubkey_import(pubkey, &pemDatum, GNUTLS_X509_FMT_PEM);
if (ret != GNUTLS_E_SUCCESS)
{
gnutls_pubkey_deinit(pubkey);
std::cerr << "GnuTLS: error setting the public key" << std::endl;
std::cerr << "GnuTLS error: " << gnutls_strerror(ret) << std::endl;
return;
}
pubkey_copy(pubkey, &d_PublicKey);
gnutls_pubkey_deinit(pubkey);
#endif #endif
LOG(INFO) << "OSNMA Public Key successfully set up."; LOG(INFO) << "OSNMA Public Key successfully set up.";
} }
@ -945,7 +1011,45 @@ bool Gnss_Crypto::convert_raw_to_der_ecdsa(const std::vector<uint8_t>& raw_signa
} }
#if USE_OPENSSL_FALLBACK #if USE_GNUTLS_FALLBACK // GnuTLS-specific functions
bool Gnss_Crypto::pubkey_copy(gnutls_pubkey_t src, gnutls_pubkey_t* dest)
{
gnutls_datum_t key_datum;
// Export the public key from src to memory
#if HAVE_GNUTLS_PUBKEY_EXPORT2
int ret = gnutls_pubkey_export2(src, GNUTLS_X509_FMT_PEM, &key_datum);
#else
size_t output_stata_size;
int ret = gnutls_pubkey_export(src, GNUTLS_X509_FMT_PEM, &key_datum, &output_stata_size);
#endif
if (ret < 0)
{
gnutls_free(key_datum.data);
return false;
}
// Initialize dest
ret = gnutls_pubkey_init(dest);
if (ret < 0)
{
gnutls_free(key_datum.data);
return false;
}
// Import the public key data from key_datum to dest
ret = gnutls_pubkey_import(*dest, &key_datum, GNUTLS_X509_FMT_PEM);
gnutls_free(key_datum.data);
if (ret < 0)
{
gnutls_pubkey_deinit(*dest);
return false;
}
return true;
}
#else // OpenSSL
#if USE_OPENSSL_3 #if USE_OPENSSL_3
bool Gnss_Crypto::pubkey_copy(EVP_PKEY* src, EVP_PKEY** dest) bool Gnss_Crypto::pubkey_copy(EVP_PKEY* src, EVP_PKEY** dest)
{ {
@ -1036,41 +1140,5 @@ bool Gnss_Crypto::pubkey_copy(EC_KEY* src, EC_KEY** dest)
return true; return true;
} }
#endif #endif
#else // GnuTLS-specific functions
bool Gnss_Crypto::pubkey_copy(gnutls_pubkey_t src, gnutls_pubkey_t* dest)
{
gnutls_datum_t key_datum;
// Export the public key from src to memory
int ret = gnutls_pubkey_export2(src, GNUTLS_X509_FMT_PEM, &key_datum);
if (ret < 0)
{
gnutls_free(key_datum.data);
return false;
}
// Initialize dest
ret = gnutls_pubkey_init(dest);
if (ret < 0)
{
gnutls_free(key_datum.data);
return false;
}
// Import the public key data from key_datum to dest
ret = gnutls_pubkey_import(*dest, &key_datum, GNUTLS_X509_FMT_PEM);
gnutls_free(key_datum.data);
if (ret < 0)
{
gnutls_pubkey_deinit(*dest);
return false;
}
return true;
}
#endif #endif

View File

@ -22,10 +22,11 @@
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <vector> #include <vector>
#if USE_OPENSSL_FALLBACK #if USE_GNUTLS_FALLBACK
#include <openssl/ec.h> #include <gnutls/abstract.h>
#else
#include <gnutls/gnutls.h> #include <gnutls/gnutls.h>
#else // OpenSSL
#include <openssl/ec.h>
#endif #endif
/** \addtogroup Core /** \addtogroup Core
@ -60,7 +61,10 @@ private:
bool readPublicKeyFromCRT(const std::string& crtFilePath); bool readPublicKeyFromCRT(const std::string& crtFilePath);
bool convert_raw_to_der_ecdsa(const std::vector<uint8_t>& raw_signature, std::vector<uint8_t>& der_signature) const; bool convert_raw_to_der_ecdsa(const std::vector<uint8_t>& raw_signature, std::vector<uint8_t>& der_signature) const;
std::vector<uint8_t> convert_from_hex_str(const std::string& input) const; std::vector<uint8_t> convert_from_hex_str(const std::string& input) const;
#if USE_OPENSSL_FALLBACK #if USE_GNUTLS_FALLBACK
bool pubkey_copy(gnutls_pubkey_t src, gnutls_pubkey_t* dest);
gnutls_pubkey_t d_PublicKey{};
#else // OpenSSL
#if USE_OPENSSL_3 #if USE_OPENSSL_3
bool pubkey_copy(EVP_PKEY* src, EVP_PKEY** dest); bool pubkey_copy(EVP_PKEY* src, EVP_PKEY** dest);
EVP_PKEY* d_PublicKey{}; EVP_PKEY* d_PublicKey{};
@ -68,9 +72,6 @@ private:
bool pubkey_copy(EC_KEY* src, EC_KEY** dest); bool pubkey_copy(EC_KEY* src, EC_KEY** dest);
EC_KEY* d_PublicKey = nullptr; EC_KEY* d_PublicKey = nullptr;
#endif #endif
#else // GnuTLS
bool pubkey_copy(gnutls_pubkey_t src, gnutls_pubkey_t* dest);
gnutls_pubkey_t d_PublicKey{};
#endif #endif
std::vector<uint8_t> d_x_4_0; std::vector<uint8_t> d_x_4_0;
std::vector<uint8_t> d_x_3_1; std::vector<uint8_t> d_x_3_1;
@ -82,4 +83,5 @@ private:
/** \} */ /** \} */
/** \} */ /** \} */
#endif // GNSS_SDR_GNSS_CRYPTO_H #endif // GNSS_SDR_GNSS_CRYPTO_H

View File

@ -18,6 +18,7 @@
#include <bitset> #include <bitset>
#include <iomanip> #include <iomanip>
#include <ios> #include <ios>
#include <sstream>
uint32_t Osnma_Helper::compute_gst(uint32_t WN, uint32_t TOW) const uint32_t Osnma_Helper::compute_gst(uint32_t WN, uint32_t TOW) const
{ {

View File

@ -1367,6 +1367,9 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA)
GTest::GTest GTest::GTest
GTest::Main GTest::Main
core_libs core_libs
Gnuradio::blocks
Gnuradio::runtime
Gnuradio::filter # workaround for old systems
) )
if(ENABLE_GLOG_AND_GFLAGS) if(ENABLE_GLOG_AND_GFLAGS)
target_link_libraries(osnma_msg_receiver_test PRIVATE Gflags::gflags Glog::glog) target_link_libraries(osnma_msg_receiver_test PRIVATE Gflags::gflags Glog::glog)

View File

@ -104,10 +104,15 @@ macro(add_benchmark)
) )
endmacro() endmacro()
set(EXTRA_BENCHMARK_DEPENDENCIES "")
if(ENABLE_GLOG_AND_GFLAGS)
set(EXTRA_BENCHMARK_DEPENDENCIES "Gflags::gflags;Glog::glog")
endif()
add_benchmark(benchmark_copy) add_benchmark(benchmark_copy)
add_benchmark(benchmark_preamble core_system_parameters) add_benchmark(benchmark_preamble core_system_parameters ${EXTRA_BENCHMARK_DEPENDENCIES})
add_benchmark(benchmark_detector core_system_parameters) add_benchmark(benchmark_detector core_system_parameters ${EXTRA_BENCHMARK_DEPENDENCIES})
add_benchmark(benchmark_reed_solomon core_system_parameters) add_benchmark(benchmark_reed_solomon core_system_parameters ${EXTRA_BENCHMARK_DEPENDENCIES})
add_benchmark(benchmark_atan2 Gnuradio::runtime) add_benchmark(benchmark_atan2 Gnuradio::runtime)
if(has_std_plus_void) if(has_std_plus_void)

View File

@ -1,11 +1,15 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <bitset> #include <bitset>
#include <filesystem> #include <chrono>
#include <fstream> #include <fstream>
#include <logging.h>
#include <osnma_msg_receiver.h> #include <osnma_msg_receiver.h>
#include <vector> #include <vector>
#if USE_GLOG_AND_GFLAGS
#include <glog/logging.h> // for LOG
#else
#include <absl/log/log.h>
#endif
struct TestVector struct TestVector
{ {