1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-10-30 14:46:23 +00:00

Merge branch 'osnma-cesare' of https://github.com/cesaaargm/osnma into osnma-cesare

This commit is contained in:
Carles Fernandez 2024-08-05 11:37:56 +02:00
commit 41eca41ea8
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
6 changed files with 157 additions and 40 deletions

View File

@ -93,7 +93,6 @@ target_link_libraries(core_libs
core_libs_supl core_libs_supl
core_system_parameters core_system_parameters
pvt_libs pvt_libs
algorithms_libs
PRIVATE PRIVATE
algorithms_libs algorithms_libs
Boost::serialization Boost::serialization

View File

@ -22,9 +22,9 @@
#include "Galileo_OSNMA.h" #include "Galileo_OSNMA.h"
#include "gnss_crypto.h" #include "gnss_crypto.h"
#include "gnss_satellite.h" #include "gnss_satellite.h"
#include "osnma_dsm_reader.h" // for OSNMA_DSM_Reader #include "gnss_sdr_make_unique.h" // for std::make_unique in C++11
#include "osnma_helper.h" #include "osnma_dsm_reader.h" // for OSNMA_DSM_Reader
#include "osnma_nav_data_manager.h" #include "osnma_helper.h" // for Osnma_Helper
#include <gnuradio/io_signature.h> // for gr::io_signature::make #include <gnuradio/io_signature.h> // for gr::io_signature::make
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
@ -237,6 +237,12 @@ void osnma_msg_receiver::msg_handler_osnma(const pmt::pmt_t& msg)
} }
void osnma_msg_receiver::read_merkle_xml(const std::string& merklepath)
{
d_crypto->read_merkle_xml(merklepath);
}
void osnma_msg_receiver::process_osnma_message(const std::shared_ptr<OSNMA_msg>& osnma_msg) void osnma_msg_receiver::process_osnma_message(const std::shared_ptr<OSNMA_msg>& osnma_msg)
{ {
if (d_flag_alert_message && (d_public_key_verified || d_kroot_verified)) if (d_flag_alert_message && (d_public_key_verified || d_kroot_verified))

View File

@ -23,21 +23,20 @@
#define FRIEND_TEST(test_case_name, test_name) \ #define FRIEND_TEST(test_case_name, test_name) \
friend class test_case_name##_##test_name##_Test friend class test_case_name##_##test_name##_Test
#include "galileo_inav_message.h" // for OSNMA_msg #include "galileo_inav_message.h" // for OSNMA_msg
#include "gnss_block_interface.h" // for gnss_shared_ptr #include "gnss_block_interface.h" // for gnss_shared_ptr
#include "gnss_sdr_make_unique.h" // for std::make:unique in C++11 #include "osnma_data.h" // for OSNMA_data structures
#include "osnma_data.h" // for OSNMA_data structures #include "osnma_nav_data_manager.h" // for OSNMA_nav_data_Manager
#include "osnma_nav_data_manager.h" #include <gnuradio/block.h> // for gr::block
#include <gnuradio/block.h> // for gr::block #include <pmt/pmt.h> // for pmt::pmt_t
#include <pmt/pmt.h> // for pmt::pmt_t #include <array> // for std::array
#include <array> // for std::array #include <cstdint> // for uint8_t
#include <cstdint> // for uint8_t #include <ctime> // for std::time_t
#include <ctime> // for std::time_t #include <map> // for std::map, std::multimap
#include <map> // for std::map, std::multimap #include <memory> // for std::shared_ptr
#include <memory> // for std::shared_ptr #include <string> // for std::string
#include <string> // for std::string #include <utility> // for std::pair
#include <utility> // for std::pair #include <vector> // for std::vector
#include <vector> // for std::vector
/** \addtogroup Core /** \addtogroup Core
* \{ */ * \{ */
@ -62,9 +61,10 @@ osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath,
class osnma_msg_receiver : public gr::block class osnma_msg_receiver : public gr::block
{ {
public: public:
~osnma_msg_receiver() = default; //!< Default destructor ~osnma_msg_receiver() = default; //!< Default destructor
std::unique_ptr<Gnss_Crypto> d_crypto; // access to cryptographic functions void msg_handler_osnma(const pmt::pmt_t& msg); //!< For testing purposes
void msg_handler_osnma(const pmt::pmt_t& msg); // GnssCrypto and the message handler are needed by public method within TestVectors fixture void read_merkle_xml(const std::string& merklepath); //!< Public for testing purposes
private: private:
friend osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath, const std::string& merkleFilePath, bool strict_mode); friend osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath, const std::string& merkleFilePath, bool strict_mode);
osnma_msg_receiver(const std::string& crtFilePath, const std::string& merkleFilePath, bool strict_mode); osnma_msg_receiver(const std::string& crtFilePath, const std::string& merkleFilePath, bool strict_mode);
@ -112,6 +112,7 @@ private:
std::array<uint16_t, 16> d_number_of_blocks{}; std::array<uint16_t, 16> d_number_of_blocks{};
std::array<uint8_t, 60> d_mack_message{}; // C: 480 b std::array<uint8_t, 60> d_mack_message{}; // C: 480 b
std::unique_ptr<Gnss_Crypto> d_crypto; // class for cryptographic functions
std::unique_ptr<OSNMA_DSM_Reader> d_dsm_reader; // osnma parameters parser std::unique_ptr<OSNMA_DSM_Reader> d_dsm_reader; // osnma parameters parser
std::unique_ptr<Osnma_Helper> d_helper; // helper class with auxiliary functions std::unique_ptr<Osnma_Helper> d_helper; // helper class with auxiliary functions
std::unique_ptr<OSNMA_nav_data_Manager> d_nav_data_manager; // refactor for holding and processing navigation data std::unique_ptr<OSNMA_nav_data_Manager> d_nav_data_manager; // refactor for holding and processing navigation data

View File

@ -20,6 +20,7 @@
#include "Galileo_OSNMA.h" #include "Galileo_OSNMA.h"
#include <pugixml.hpp> #include <pugixml.hpp>
#include <cstddef> #include <cstddef>
#include <cstring>
#include <fstream> #include <fstream>
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
@ -912,11 +913,14 @@ void Gnss_Crypto::set_public_key(const std::vector<uint8_t>& publicKey)
point = EC_POINT_new(group); point = EC_POINT_new(group);
if (!point) if (!point)
{ {
EC_GROUP_free(group);
return; return;
} }
if (!EC_POINT_oct2point(group, point, publicKey.data(), publicKey.size(), nullptr)) if (!EC_POINT_oct2point(group, point, publicKey.data(), publicKey.size(), nullptr))
{ {
EC_GROUP_free(group);
EC_POINT_free(point);
return; return;
} }
@ -930,11 +934,16 @@ void Gnss_Crypto::set_public_key(const std::vector<uint8_t>& publicKey)
} }
if (!ec_key) if (!ec_key)
{ {
EC_GROUP_free(group);
EC_POINT_free(point);
return; return;
} }
if (!EC_KEY_set_public_key(ec_key, point)) if (!EC_KEY_set_public_key(ec_key, point))
{ {
EC_KEY_free(ec_key);
EC_POINT_free(point);
EC_GROUP_free(group);
return; return;
} }
if (!pubkey_copy(ec_key, &d_PublicKey)) if (!pubkey_copy(ec_key, &d_PublicKey))
@ -1066,6 +1075,7 @@ void Gnss_Crypto::readPublicKeyFromPEM(const std::string& pemFilePath)
{ {
return; return;
} }
d_PublicKeyType = "Unknown";
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_GNUTLS_FALLBACK #if USE_GNUTLS_FALLBACK
// Import the PEM data // Import the PEM data
@ -1085,6 +1095,52 @@ void Gnss_Crypto::readPublicKeyFromPEM(const std::string& pemFilePath)
return; return;
} }
// store the key type - needed for the Kroot in case no DSM-PKR available
gnutls_pk_algorithm_t pk_algorithm;
unsigned int bits;
ret = gnutls_pubkey_get_pk_algorithm(pubkey, &bits);
if (ret < 0)
{
LOG(WARNING) << "GnuTLS: Failed to get public key algorithm from .pem file: " << gnutls_strerror(ret);
gnutls_pubkey_deinit(pubkey);
return;
}
pk_algorithm = static_cast<gnutls_pk_algorithm_t>(ret);
if (pk_algorithm == GNUTLS_PK_ECDSA)
{
gnutls_ecc_curve_t curve;
ret = gnutls_pubkey_export_ecc_raw(pubkey, &curve, nullptr, nullptr);
if (ret < 0)
{
LOG(WARNING) << "GnuTLS: Failed to get EC curve from .pem file: " << gnutls_strerror(ret);
gnutls_pubkey_deinit(pubkey);
return;
}
if (curve == GNUTLS_ECC_CURVE_SECP256R1)
{
d_PublicKeyType = "ECDSA P-256";
}
else if (curve == GNUTLS_ECC_CURVE_SECP521R1)
{
d_PublicKeyType = "ECDSA P-521";
}
else
{
LOG(WARNING) << "GnuTLS: Trying to read unknown EC curve from .pem file";
gnutls_pubkey_deinit(pubkey);
return;
}
}
else
{
LOG(WARNING) << "GnuTLS: Trying to read unknown key type from .pem file";
gnutls_pubkey_deinit(pubkey);
return;
}
pubkey_copy(pubkey, &d_PublicKey); pubkey_copy(pubkey, &d_PublicKey);
gnutls_pubkey_deinit(pubkey); gnutls_pubkey_deinit(pubkey);
#else // OpenSSL #else // OpenSSL
@ -1096,9 +1152,77 @@ void Gnss_Crypto::readPublicKeyFromPEM(const std::string& pemFilePath)
return; return;
} }
#if USE_OPENSSL_3 #if USE_OPENSSL_3
d_PublicKey = PEM_read_bio_PUBKEY(bio, nullptr, nullptr, nullptr); EVP_PKEY* pubkey = nullptr;
pubkey = PEM_read_bio_PUBKEY(bio, nullptr, nullptr, nullptr);
// store the key type - needed for the Kroot in case no DSM-PKR available
// Get the key type
int key_type = EVP_PKEY_base_id(pubkey);
if (key_type == EVP_PKEY_EC)
{
// It's an EC key, now we need to determine the curve
char curve_name[256];
size_t curve_name_len = sizeof(curve_name);
if (EVP_PKEY_get_utf8_string_param(pubkey, OSSL_PKEY_PARAM_GROUP_NAME, curve_name, curve_name_len, &curve_name_len) == 1)
{
if (strcmp(curve_name, "prime256v1") == 0 || strcmp(curve_name, "P-256") == 0)
{
d_PublicKeyType = "ECDSA P-256";
}
else if (strcmp(curve_name, "secp521r1") == 0 || strcmp(curve_name, "P-521") == 0)
{
d_PublicKeyType = "ECDSA P-521";
}
else
{
LOG(WARNING) << "OpenSSL: Trying to read an unknown EC curve from .pem file";
BIO_free(bio);
EVP_PKEY_free(pubkey);
return;
}
}
else
{
LOG(WARNING) << "OpenSSL: Trying to read an unknown EC curve from .pem file";
BIO_free(bio);
EVP_PKEY_free(pubkey);
return;
}
}
else
{
LOG(WARNING) << "OpenSSL: Trying to read an unknown key type from .pem file";
BIO_free(bio);
EVP_PKEY_free(pubkey);
return;
}
pubkey_copy(pubkey, &d_PublicKey);
EVP_PKEY_free(pubkey);
#else // OpenSSL 1.x #else // OpenSSL 1.x
d_PublicKey = PEM_read_bio_EC_PUBKEY(bio, nullptr, nullptr, nullptr); EC_KEY* pubkey = nullptr;
pubkey = PEM_read_bio_EC_PUBKEY(bio, nullptr, nullptr, nullptr);
if (!pubkey)
{
LOG(WARNING) << "OpenSSL: Failed to extract the public key from .pem file";
BIO_free(bio);
return;
}
const EC_GROUP* group = EC_KEY_get0_group(pubkey);
int nid = EC_GROUP_get_curve_name(group);
const char* curve_name = OBJ_nid2sn(nid);
const std::string curve_str(curve_name);
if (curve_str == "prime256v1")
{
d_PublicKeyType = "ECDSA P-256";
}
else if (curve_str == "secp521r1")
{
d_PublicKeyType = "ECDSA P-521";
}
pubkey_copy(pubkey, &d_PublicKey);
EC_KEY_free(pubkey);
#endif #endif
BIO_free(bio); BIO_free(bio);
if (d_PublicKey == nullptr) if (d_PublicKey == nullptr)
@ -1172,20 +1296,8 @@ bool Gnss_Crypto::readPublicKeyFromCRT(const std::string& crtFilePath)
if (pk_algorithm == GNUTLS_PK_ECDSA) if (pk_algorithm == GNUTLS_PK_ECDSA)
{ {
gnutls_datum_t params;
ret = gnutls_pubkey_export_ecc_raw(pubkey, nullptr, &params, nullptr);
if (ret < 0)
{
LOG(WARNING) << "GnuTLS: Failed to export EC parameters: " << gnutls_strerror(ret);
gnutls_pubkey_deinit(pubkey);
gnutls_x509_crt_deinit(cert);
return false;
}
gnutls_ecc_curve_t curve; gnutls_ecc_curve_t curve;
ret = gnutls_ecc_curve_get_id(reinterpret_cast<const char*>(params.data)); ret = gnutls_pubkey_export_ecc_raw(pubkey, &curve, nullptr, nullptr);
gnutls_free(params.data);
if (ret < 0) if (ret < 0)
{ {
LOG(WARNING) << "GnuTLS: Failed to get EC curve: " << gnutls_strerror(ret); LOG(WARNING) << "GnuTLS: Failed to get EC curve: " << gnutls_strerror(ret);
@ -1194,8 +1306,6 @@ bool Gnss_Crypto::readPublicKeyFromCRT(const std::string& crtFilePath)
return false; return false;
} }
curve = static_cast<gnutls_ecc_curve_t>(ret);
if (curve == GNUTLS_ECC_CURVE_SECP256R1) if (curve == GNUTLS_ECC_CURVE_SECP256R1)
{ {
d_PublicKeyType = "ECDSA P-256"; d_PublicKeyType = "ECDSA P-256";

View File

@ -70,6 +70,7 @@ TEST(GnssCryptoTest, VerifyPublicKeyStorage)
auto d_crypto2 = std::make_unique<Gnss_Crypto>(f1, ""); auto d_crypto2 = std::make_unique<Gnss_Crypto>(f1, "");
bool result2 = d_crypto2->store_public_key(f2); bool result2 = d_crypto2->store_public_key(f2);
ASSERT_TRUE(result2); ASSERT_TRUE(result2);
ASSERT_TRUE(d_crypto2->get_public_key_type() == "ECDSA P-256");
std::ifstream t(f1); std::ifstream t(f1);
std::string content_file((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>()); std::string content_file((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());

View File

@ -243,7 +243,7 @@ bool OsnmaTestVectors::feedOsnmaWithTestVectors(osnma_msg_receiver_sptr osnma_ob
if (test_step == 1 && d_flag_NPK == true ){ if (test_step == 1 && d_flag_NPK == true ){
// step 2: this simulates the osnma connecting to the GSC server and downloading the Merkle tree of the next public key // step 2: this simulates the osnma connecting to the GSC server and downloading the Merkle tree of the next public key
osnma_object->d_crypto->read_merkle_xml( osnma_object->read_merkle_xml(
std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/MerkleTree/OSNMA_MerkleTree_20231007081500_PKID_8.xml"); std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/MerkleTree/OSNMA_MerkleTree_20231007081500_PKID_8.xml");
} }