mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-13 11:40:33 +00:00
[TAS-247][FEAT][Kroot] enable hotstart with last known Kroot
* Kroot is now saved into binary file if successfuly verified. * on startup, file is checked first. * This should enable a much quicker TTFAF
This commit is contained in:
parent
ffb456d058
commit
06e0c4b63a
@ -60,22 +60,26 @@ namespace wht = std;
|
||||
#endif
|
||||
|
||||
|
||||
osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath, const std::string& merkleFilePath)
|
||||
osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath, const std::string& merkleFilePath, const std::string& rootKeyFilePath)
|
||||
{
|
||||
return osnma_msg_receiver_sptr(new osnma_msg_receiver(pemFilePath, merkleFilePath));
|
||||
return osnma_msg_receiver_sptr(new osnma_msg_receiver(pemFilePath, merkleFilePath, rootKeyFilePath));
|
||||
}
|
||||
|
||||
|
||||
osnma_msg_receiver::osnma_msg_receiver(
|
||||
const std::string& crtFilePath,
|
||||
const std::string& merkleFilePath) : gr::block("osnma_msg_receiver",
|
||||
osnma_msg_receiver::osnma_msg_receiver(const std::string& crtFilePath, const std::string& merkleFilePath, const std::string& rootKeyFilePath) : gr::block("osnma_msg_receiver",
|
||||
gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(0, 0, 0))
|
||||
{
|
||||
d_dsm_reader = std::make_unique<OSNMA_DSM_Reader>();
|
||||
d_crypto = std::make_unique<Gnss_Crypto>(crtFilePath, merkleFilePath);
|
||||
d_crypto = std::make_unique<Gnss_Crypto>(crtFilePath, merkleFilePath, rootKeyFilePath);
|
||||
d_helper = std::make_unique<Osnma_Helper>();
|
||||
d_nav_data_manager = std::make_unique<OSNMA_nav_data_Manager>();
|
||||
|
||||
if(d_crypto->have_root_key()){
|
||||
d_kroot = d_crypto->get_root_key();
|
||||
d_kroot_verified = true;
|
||||
}
|
||||
|
||||
// register OSNMA input message port from telemetry blocks
|
||||
this->message_port_register_in(pmt::mp("OSNMA_from_TLM"));
|
||||
// register OSNMA output message port to PVT block
|
||||
@ -126,7 +130,7 @@ void osnma_msg_receiver::msg_handler_osnma(const pmt::pmt_t& msg)
|
||||
uint32_t PRNa = std::get<0>(*inav_data);
|
||||
std::string nav_data = std::get<1>(*inav_data);
|
||||
uint32_t TOW = std::get<2>(*inav_data);
|
||||
d_nav_data_manager->add_navigation_data(nav_data, PRNa,TOW);
|
||||
d_nav_data_manager->add_navigation_data(nav_data, PRNa, TOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -490,6 +494,10 @@ void osnma_msg_receiver::process_dsm_message(const std::vector<uint8_t>& dsm_msg
|
||||
LOG(INFO) << "Galileo OSNMA: NMA Status is " << d_dsm_reader->get_nmas_status(d_osnma_data.d_nma_header.nmas) << ", "
|
||||
<< "Chain in force is " << static_cast<uint32_t>(d_osnma_data.d_nma_header.cid) << ", "
|
||||
<< "Chain and Public Key Status is " << d_dsm_reader->get_cpks_status(d_osnma_data.d_nma_header.cpks);
|
||||
// Save Kroot into a permanent storage
|
||||
d_crypto->store_root_key(ROOTKEYFILE_DEFAULT);
|
||||
d_kroot = d_osnma_data.d_dsm_kroot_message.kroot;
|
||||
d_crypto->set_root_key(d_kroot);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -50,7 +50,7 @@ class osnma_msg_receiver;
|
||||
|
||||
using osnma_msg_receiver_sptr = gnss_shared_ptr<osnma_msg_receiver>;
|
||||
|
||||
osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath, const std::string& merkleFilePath);
|
||||
osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath, const std::string& merkleFilePath, const std::string& rootKeyFilePath);
|
||||
|
||||
/*!
|
||||
* \brief GNU Radio block that receives asynchronous OSNMA messages
|
||||
@ -63,8 +63,8 @@ class osnma_msg_receiver : public gr::block
|
||||
public:
|
||||
~osnma_msg_receiver() = default; //!< Default destructor
|
||||
private:
|
||||
friend osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath, const std::string& merkleFilePath);
|
||||
osnma_msg_receiver(const std::string& crtFilePath, const std::string& merkleFilePath);
|
||||
friend osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath, const std::string& merkleFilePath, const std::string& rootKeyFilePath);
|
||||
osnma_msg_receiver(const std::string& crtFilePath, const std::string& merkleFilePath, const std::string& rootKeyFilePath);
|
||||
|
||||
void msg_handler_osnma(const pmt::pmt_t& msg);
|
||||
void process_osnma_message(const std::shared_ptr<OSNMA_msg>& osnma_msg);
|
||||
@ -100,6 +100,7 @@ private:
|
||||
std::map<uint32_t, std::vector<uint8_t>> d_tesla_keys; // tesla keys over time, sorted by TOW
|
||||
std::multimap<uint32_t, Tag> d_tags_awaiting_verify; // container with tags to verify from arbitrary SVIDs, sorted by TOW
|
||||
|
||||
std::vector<uint8_t> d_kroot; // last available stored root key
|
||||
std::vector<uint8_t> d_tags_to_verify{0, 4, 12};
|
||||
std::vector<MACK_message> d_macks_awaiting_MACSEQ_verification;
|
||||
|
||||
@ -110,7 +111,7 @@ private:
|
||||
|
||||
std::unique_ptr<OSNMA_DSM_Reader> d_dsm_reader; // osnma parameters parser
|
||||
std::unique_ptr<Gnss_Crypto> d_crypto; // access to cryptographic functions
|
||||
std::unique_ptr<Osnma_Helper> d_helper;
|
||||
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
|
||||
|
||||
OSNMA_data d_osnma_data{};
|
||||
|
@ -126,7 +126,8 @@ void GNSSFlowgraph::init()
|
||||
enable_osnma_rx_ = true;
|
||||
const auto certFilePath = configuration_->property("GNSS-SDR.osnma_public_key", CRTFILE_DEFAULT);
|
||||
const auto merKleTreePath = configuration_->property("GNSS-SDR.osnma_merkletree", MERKLEFILE_DEFAULT);
|
||||
osnma_rx_ = osnma_msg_receiver_make(certFilePath, merKleTreePath);
|
||||
const auto rootKeyPath = configuration_->property("GNSS-SDR.osnma_root_key", ROOTKEYFILE_DEFAULT);
|
||||
osnma_rx_ = osnma_msg_receiver_make(certFilePath, merKleTreePath, rootKeyPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -163,6 +163,7 @@ const std::unordered_map<std::string, uint16_t> OSNMA_TABLE_15 = {
|
||||
const std::string PEMFILE_STORED("./OSNMA_PublicKey.pem");
|
||||
const std::string CRTFILE_DEFAULT("../data/OSNMA_PublicKey_20240115100000_newPKID_1.crt");
|
||||
const std::string MERKLEFILE_DEFAULT("../data/OSNMA_MerkleTree_20240115100000_newPKID_1.xml");
|
||||
const std::string ROOTKEYFILE_DEFAULT("../data/OSNMA_RootKey.bin");
|
||||
|
||||
class Mack_lookup
|
||||
{
|
||||
|
@ -75,7 +75,7 @@ Gnss_Crypto::Gnss_Crypto()
|
||||
}
|
||||
|
||||
|
||||
Gnss_Crypto::Gnss_Crypto(const std::string& certFilePath, const std::string& merkleTreePath)
|
||||
Gnss_Crypto::Gnss_Crypto(const std::string& certFilePath, const std::string& merkleTreePath, const std::string& rootKeyFilePath)
|
||||
{
|
||||
#if USE_GNUTLS_FALLBACK
|
||||
gnutls_global_init();
|
||||
@ -100,6 +100,7 @@ Gnss_Crypto::Gnss_Crypto(const std::string& certFilePath, const std::string& mer
|
||||
}
|
||||
}
|
||||
read_merkle_xml(merkleTreePath);
|
||||
read_root_key(rootKeyFilePath);
|
||||
}
|
||||
|
||||
|
||||
@ -122,7 +123,10 @@ Gnss_Crypto::~Gnss_Crypto()
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool Gnss_Crypto::have_root_key() const
|
||||
{
|
||||
return !d_kroot.empty();
|
||||
}
|
||||
bool Gnss_Crypto::have_public_key() const
|
||||
{
|
||||
#if USE_GNUTLS_FALLBACK
|
||||
@ -196,6 +200,22 @@ bool Gnss_Crypto::store_public_key(const std::string& pubKeyFilePath) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Gnss_Crypto::store_root_key(const std::string& rootKeyFilePath) const
|
||||
{
|
||||
if (!have_root_key())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
std::ofstream file(rootKeyFilePath, std::ios::binary | std::ios::out);
|
||||
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
file.write(reinterpret_cast<const char*>(d_kroot.data()), d_kroot.size());
|
||||
|
||||
return file.good();
|
||||
}
|
||||
|
||||
bool Gnss_Crypto::verify_signature_ecdsa_p256(const std::vector<uint8_t>& message, const std::vector<uint8_t>& signature) const
|
||||
{
|
||||
@ -845,6 +865,10 @@ std::vector<uint8_t> Gnss_Crypto::get_merkle_root() const
|
||||
return d_x_4_0;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Gnss_Crypto::get_root_key() const
|
||||
{
|
||||
return d_kroot;
|
||||
}
|
||||
|
||||
void Gnss_Crypto::set_public_key(const std::vector<uint8_t>& publicKey)
|
||||
{
|
||||
@ -899,12 +923,15 @@ void Gnss_Crypto::set_public_key(const std::vector<uint8_t>& publicKey)
|
||||
DLOG(INFO) << "OSNMA Public Key successfully set up.";
|
||||
}
|
||||
|
||||
|
||||
void Gnss_Crypto::set_merkle_root(const std::vector<uint8_t>& v)
|
||||
{
|
||||
d_x_4_0 = v;
|
||||
}
|
||||
|
||||
void Gnss_Crypto::set_root_key(const std::vector<uint8_t>& root_key)
|
||||
{
|
||||
d_kroot = root_key;
|
||||
}
|
||||
|
||||
void Gnss_Crypto::read_merkle_xml(const std::string& merkleFilePath)
|
||||
{
|
||||
@ -1145,6 +1172,40 @@ bool Gnss_Crypto::readPublicKeyFromCRT(const std::string& crtFilePath)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reads the TESLA root key from a file and stores it.
|
||||
* \param rootKeyFilePath The file path of the TESLA root key.
|
||||
* \return True if the root key was successfully read and stored, false otherwise.
|
||||
*/
|
||||
bool Gnss_Crypto::read_root_key(const std::string& rootKeyFilePath)
|
||||
{
|
||||
std::ifstream file(rootKeyFilePath, std::ios::binary | std::ios::in);
|
||||
|
||||
if (!file) {
|
||||
LOG(WARNING) << "Unable to open file: " << rootKeyFilePath;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Determine file size
|
||||
file.seekg(0, std::ios::end);
|
||||
std::streamsize size = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
||||
if (size == 0) {
|
||||
LOG(WARNING) << "File is empty: " << rootKeyFilePath;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Resize the vector and read file
|
||||
d_kroot.resize(size);
|
||||
if (!file.read(reinterpret_cast<char*>(d_kroot.data()), size)) {
|
||||
LOG(WARNING) << "Failed to read the file: " << rootKeyFilePath;
|
||||
return false;
|
||||
}
|
||||
std::cout << "OSNMA TESLA Root Key successfully read from file " << rootKeyFilePath << std::endl;
|
||||
LOG(INFO) << "OSNMA TESLA Root Key successfully read from file " << rootKeyFilePath;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Gnss_Crypto::convert_raw_to_der_ecdsa(const std::vector<uint8_t>& raw_signature, std::vector<uint8_t>& der_signature) const
|
||||
{
|
||||
|
@ -48,15 +48,22 @@ public:
|
||||
* and a XML file for the Merkle Tree root.
|
||||
* Files can be downloaded by registering at https://www.gsc-europa.eu/
|
||||
*/
|
||||
Gnss_Crypto(const std::string& certFilePath, const std::string& merkleTreePath);
|
||||
Gnss_Crypto(const std::string& certFilePath, const std::string& merkleTreePath, const std::string& rootKeyFilePath);
|
||||
~Gnss_Crypto(); //!< Default destructor
|
||||
|
||||
bool have_root_key() const; //!< Returns true if the TESLA root key is already loaded
|
||||
bool have_public_key() const; //!< Returns true if the ECDSA Public Key is already loaded
|
||||
|
||||
/*!
|
||||
* Stores the ECDSA Public Key in a .pem file, which is read in a following run if the .crt file is not found
|
||||
*/
|
||||
bool store_public_key(const std::string& pubKeyFilePath) const;
|
||||
/*!
|
||||
* Stores the TESLA root key in a plaintext file, which is read in a following run for a faster TTFAF.
|
||||
* @param kroot TESLA root key
|
||||
* @return true if successful
|
||||
*/
|
||||
bool store_root_key(const std::string& rootKeyFilePath) const;
|
||||
|
||||
bool verify_signature_ecdsa_p256(const std::vector<uint8_t>& message, const std::vector<uint8_t>& signature) const; //!< Verify ECDSA-P256 signature (message in plain hex, signature in raw format)
|
||||
bool verify_signature_ecdsa_p521(const std::vector<uint8_t>& message, const std::vector<uint8_t>& signature) const; //!< Verify ECDSA-P521 signature (message in plain hex, signature in raw format)
|
||||
@ -68,13 +75,15 @@ public:
|
||||
|
||||
std::vector<uint8_t> get_public_key() const; //!< Gets the ECDSA Public Key in PEM format
|
||||
std::vector<uint8_t> get_merkle_root() const; //!< Gets the Merkle Tree root node (\f$ x_{4,0} \f$)
|
||||
std::vector<uint8_t> get_root_key() const; //!< Gets the TESLA root key in binary format
|
||||
|
||||
void set_public_key(const std::vector<uint8_t>& publickey); //!< Sets the ECDSA Public Key (publickey in PEM format)
|
||||
void set_merkle_root(const std::vector<uint8_t>& v); //!< Sets the Merkle Tree root node x(\f$ x_{4,0} \f$)
|
||||
|
||||
void set_root_key(const std::vector<uint8_t>& root_key); //!< Sets the TESLA root key
|
||||
private:
|
||||
void read_merkle_xml(const std::string& merkleFilePath);
|
||||
void readPublicKeyFromPEM(const std::string& pemFilePath);
|
||||
bool read_root_key(const std::string& rootKeyFilePath);
|
||||
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;
|
||||
std::vector<uint8_t> convert_from_hex_str(const std::string& input) const;
|
||||
@ -91,6 +100,7 @@ private:
|
||||
#endif
|
||||
#endif
|
||||
std::vector<uint8_t> d_x_4_0;
|
||||
std::vector<uint8_t> d_kroot;
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <chrono>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include "Galileo_OSNMA.h"
|
||||
|
||||
#if USE_GLOG_AND_GFLAGS
|
||||
#include <glog/logging.h> // for LOG
|
||||
@ -76,7 +77,8 @@ protected:
|
||||
// std::string merkleFilePath = "/home/cgm/CLionProjects/osnma/data/OSNMA_MerkleTree_20230803105953_newPKID_1.xml";
|
||||
std::string crtFilePath = "/home/cgm/CLionProjects/osnma/data/OSNMA_PublicKey_20230720113300_newPKID_2.crt"; // conf. 2
|
||||
std::string merkleFilePath = "/home/cgm/CLionProjects/osnma/data/OSNMA_MerkleTree_20230720113300_newPKID_2.xml";
|
||||
osnma = osnma_msg_receiver_make(crtFilePath, merkleFilePath);
|
||||
std::string rootKeyFilePath = ROOTKEYFILE_DEFAULT;
|
||||
osnma = osnma_msg_receiver_make(crtFilePath, merkleFilePath, ROOTKEYFILE_DEFAULT);
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user