From 95e3329f1011779628bd75baf97f99035c7ff3fb Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 1 Jul 2024 01:31:09 +0200 Subject: [PATCH] Fix for old GnuTLS --- cmake/Modules/GnssSdrCrypto.cmake | 37 +++++++++++++++++++ src/core/system_parameters/gnss_crypto.cc | 45 +++++++++++++++++------ src/core/system_parameters/gnss_crypto.h | 1 + 3 files changed, 71 insertions(+), 12 deletions(-) diff --git a/cmake/Modules/GnssSdrCrypto.cmake b/cmake/Modules/GnssSdrCrypto.cmake index 67648d702..a5e383790 100644 --- a/cmake/Modules/GnssSdrCrypto.cmake +++ b/cmake/Modules/GnssSdrCrypto.cmake @@ -82,6 +82,15 @@ else() /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:") @@ -98,6 +107,22 @@ else() 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() + 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() ################################################################################ @@ -147,5 +172,17 @@ function(link_to_crypto_dependencies target) ${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() endif() endfunction() diff --git a/src/core/system_parameters/gnss_crypto.cc b/src/core/system_parameters/gnss_crypto.cc index 322e4acdd..8ad7e55bb 100644 --- a/src/core/system_parameters/gnss_crypto.cc +++ b/src/core/system_parameters/gnss_crypto.cc @@ -27,7 +27,6 @@ #if USE_GNUTLS_FALLBACK #include -#include #include #include #else // OpenSSL @@ -61,6 +60,11 @@ Gnss_Crypto::Gnss_Crypto() { #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) LOG(WARNING) << "The OpenSSL library version you are linking against is too old for some OSNMA functions." @@ -75,6 +79,11 @@ Gnss_Crypto::Gnss_Crypto(const std::string& certFilePath, const std::string& mer { #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) LOG(WARNING) << "The OpenSSL library version you are linking against is too old for some OSNMA functions." @@ -305,6 +314,7 @@ std::vector Gnss_Crypto::computeSHA3_256(const std::vector& in { std::vector output(32); // SHA256 hash size #if USE_GNUTLS_FALLBACK +#if HAVE_GNUTLS_DIG_SHA3_256 std::vector output_aux(32); gnutls_hash_hd_t hashHandle; gnutls_hash_init(&hashHandle, GNUTLS_DIG_SHA3_256); @@ -312,6 +322,7 @@ std::vector Gnss_Crypto::computeSHA3_256(const std::vector& in gnutls_hash_output(hashHandle, output_aux.data()); output = output_aux; 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(); @@ -339,7 +350,11 @@ std::vector Gnss_Crypto::computeHMAC_SHA_256(const std::vector #if USE_GNUTLS_FALLBACK std::vector 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; @@ -421,16 +436,15 @@ std::vector Gnss_Crypto::computeCMAC_AES(const std::vector& ke { std::vector output(16); #if USE_GNUTLS_FALLBACK - gnutls_cipher_hd_t cipher; - std::vector mac(16); - std::vector message = input; - gnutls_datum_t key_data = {const_cast(key.data()), static_cast(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); + // CMAC-AES not implemented in GnuTLS + if (!key.empty()) + { + // do nothing + } + if (!input.empty()) + { + // do nothing + } #else // OpenSSL #if USE_OPENSSL_3 std::vector aux(EVP_MAX_MD_SIZE); // CMAC-AES output size @@ -527,7 +541,7 @@ void Gnss_Crypto::readPublicKeyFromPEM(const std::string& pemFilePath) std::string pemContent((std::istreambuf_iterator(pemFile)), std::istreambuf_iterator()); #if USE_GNUTLS_FALLBACK // Import the PEM data - gnutls_datum_t pemDatum = {const_cast(reinterpret_cast(pemContent.data())), static_cast(pemContent.size())}; + gnutls_datum_t pemDatum = {const_cast(reinterpret_cast(const_cast(pemContent.data()))), static_cast(pemContent.size())}; gnutls_pubkey_t pubkey; gnutls_pubkey_init(&pubkey); @@ -680,6 +694,7 @@ bool Gnss_Crypto::verify_signature(const std::vector& message, const st } bool success = false; #if USE_GNUTLS_FALLBACK +#if HAVE_GNUTLS_SIGN_ECDSA_SHA256 // Convert signature to DER format std::vector der_sig; if (!convert_raw_to_der_ecdsa(signature, der_sig)) @@ -704,6 +719,7 @@ bool Gnss_Crypto::verify_signature(const std::vector& message, const st 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 EVP_PKEY_CTX* ctx; @@ -950,7 +966,12 @@ 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); diff --git a/src/core/system_parameters/gnss_crypto.h b/src/core/system_parameters/gnss_crypto.h index 7e0527750..69df8d45d 100644 --- a/src/core/system_parameters/gnss_crypto.h +++ b/src/core/system_parameters/gnss_crypto.h @@ -23,6 +23,7 @@ #include #include #if USE_GNUTLS_FALLBACK +#include #include #else // OpenSSL #include