mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-01-31 11:19:18 +00:00
Introducing the crypto bro
This commit is contained in:
parent
d351049eb2
commit
972ead3cae
@ -102,45 +102,6 @@ target_link_libraries(core_libs
|
|||||||
Pugixml::pugixml
|
Pugixml::pugixml
|
||||||
)
|
)
|
||||||
|
|
||||||
if(OPENSSL_FOUND)
|
|
||||||
if(TARGET OpenSSL::SSL)
|
|
||||||
target_link_libraries(core_libs
|
|
||||||
PRIVATE
|
|
||||||
OpenSSL::SSL
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
target_link_libraries(core_libs
|
|
||||||
PRIVATE
|
|
||||||
${OPENSSL_LIBRARIES}
|
|
||||||
)
|
|
||||||
target_include_directories(core_libs
|
|
||||||
PRIVATE
|
|
||||||
${OPENSSL_INCLUDE_DIR}
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
if(OPENSSL_VERSION)
|
|
||||||
if(OPENSSL_VERSION VERSION_GREATER "3.0.0")
|
|
||||||
target_compile_definitions(core_libs PRIVATE -DUSE_OPENSSL_3=1)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
target_link_libraries(core_libs
|
|
||||||
PRIVATE
|
|
||||||
${GNUTLS_LIBRARIES}
|
|
||||||
${GNUTLS_OPENSSL_LIBRARY}
|
|
||||||
)
|
|
||||||
target_include_directories(core_libs
|
|
||||||
PRIVATE
|
|
||||||
${GNUTLS_INCLUDE_DIR}
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(OPENSSL_FOUND)
|
|
||||||
target_compile_definitions(core_libs PRIVATE -DUSE_OPENSSL_FALLBACK=1)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_GENERIC_LAMBDAS AND NOT GNURADIO_USES_STD_POINTERS)
|
if(USE_GENERIC_LAMBDAS AND NOT GNURADIO_USES_STD_POINTERS)
|
||||||
target_link_libraries(core_libs PUBLIC Boost::headers)
|
target_link_libraries(core_libs PUBLIC Boost::headers)
|
||||||
else()
|
else()
|
||||||
|
@ -19,18 +19,15 @@
|
|||||||
|
|
||||||
#include "osnma_msg_receiver.h"
|
#include "osnma_msg_receiver.h"
|
||||||
#include "Galileo_OSNMA.h"
|
#include "Galileo_OSNMA.h"
|
||||||
|
#include "gnss_crypto.h"
|
||||||
#include "osnma_dsm_reader.h" // for OSNMA_DSM_Reader
|
#include "osnma_dsm_reader.h" // for OSNMA_DSM_Reader
|
||||||
#include <glog/logging.h> // for DLOG
|
#include <glog/logging.h> // for DLOG
|
||||||
#include <gnuradio/io_signature.h> // for gr::io_signature::make
|
#include <gnuradio/io_signature.h> // for gr::io_signature::make
|
||||||
#include <bitset>
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iterator>
|
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <string>
|
|
||||||
#include <typeinfo> // for typeid
|
#include <typeinfo> // for typeid
|
||||||
|
|
||||||
#if HAS_GENERIC_LAMBDA
|
#if HAS_GENERIC_LAMBDA
|
||||||
@ -46,32 +43,20 @@ namespace wht = boost;
|
|||||||
namespace wht = std;
|
namespace wht = std;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if USE_OPENSSL_FALLBACK
|
|
||||||
#include <openssl/cmac.h>
|
|
||||||
#include <openssl/hmac.h>
|
|
||||||
#if USE_OPENSSL_3
|
|
||||||
#include <openssl/evp.h>
|
|
||||||
#define OPENSSL_ENGINE NULL
|
|
||||||
#else
|
|
||||||
#include <openssl/sha.h>
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#include <gnutls/crypto.h>
|
|
||||||
#include <gnutls/gnutls.h>
|
|
||||||
#include <gnutls/x509.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
osnma_msg_receiver_sptr osnma_msg_receiver_make()
|
osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath)
|
||||||
{
|
{
|
||||||
return osnma_msg_receiver_sptr(new osnma_msg_receiver());
|
return osnma_msg_receiver_sptr(new osnma_msg_receiver(pemFilePath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
osnma_msg_receiver::osnma_msg_receiver() : gr::block("osnma_msg_receiver",
|
osnma_msg_receiver::osnma_msg_receiver(
|
||||||
|
const std::string& pemFilePath) : gr::block("osnma_msg_receiver",
|
||||||
gr::io_signature::make(0, 0, 0),
|
gr::io_signature::make(0, 0, 0),
|
||||||
gr::io_signature::make(0, 0, 0))
|
gr::io_signature::make(0, 0, 0))
|
||||||
{
|
{
|
||||||
d_dsm_reader = std::make_unique<OSNMA_DSM_Reader>();
|
d_dsm_reader = std::make_unique<OSNMA_DSM_Reader>();
|
||||||
|
d_crypto = std::make_unique<Gnss_Crypto>(pemFilePath);
|
||||||
// register OSNMA input message port from telemetry blocks
|
// register OSNMA input message port from telemetry blocks
|
||||||
this->message_port_register_in(pmt::mp("OSNMA_from_TLM"));
|
this->message_port_register_in(pmt::mp("OSNMA_from_TLM"));
|
||||||
// register OSNMA output message port to PVT block
|
// register OSNMA output message port to PVT block
|
||||||
@ -291,11 +276,11 @@ void osnma_msg_receiver::process_dsm_message(const std::vector<uint8_t>& dsm_msg
|
|||||||
std::vector<uint8_t> hash;
|
std::vector<uint8_t> hash;
|
||||||
if (d_osnma_data.d_dsm_kroot_message.hf == 0) // Table 8.
|
if (d_osnma_data.d_dsm_kroot_message.hf == 0) // Table 8.
|
||||||
{
|
{
|
||||||
hash = computeSHA256(MSG);
|
hash = d_crypto->computeSHA256(MSG);
|
||||||
}
|
}
|
||||||
else if (d_osnma_data.d_dsm_kroot_message.hf == 2)
|
else if (d_osnma_data.d_dsm_kroot_message.hf == 2)
|
||||||
{
|
{
|
||||||
hash = computeSHA3_256(MSG);
|
hash = d_crypto->computeSHA3_256(MSG);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -585,275 +570,3 @@ void osnma_msg_receiver::read_mack_key()
|
|||||||
void osnma_msg_receiver::read_mack_padding()
|
void osnma_msg_receiver::read_mack_padding()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<uint8_t> osnma_msg_receiver::computeSHA256(const std::vector<uint8_t>& input)
|
|
||||||
{
|
|
||||||
std::vector<uint8_t> output(32); // SHA256 hash size
|
|
||||||
#if USE_OPENSSL_FALLBACK
|
|
||||||
#if USE_OPENSSL_3
|
|
||||||
// unsigned char mdVal[EVP_MAX_MD_SIZE];
|
|
||||||
// unsigned char* md;
|
|
||||||
unsigned int mdLen;
|
|
||||||
EVP_MD_CTX* mdCtx = EVP_MD_CTX_new();
|
|
||||||
if (!EVP_DigestInit_ex(mdCtx, EVP_sha256(), OPENSSL_ENGINE))
|
|
||||||
{
|
|
||||||
LOG(WARNING) << "OSNMA SHA-256: Message digest initialization failed.";
|
|
||||||
EVP_MD_CTX_free(mdCtx);
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
if (!EVP_DigestUpdate(mdCtx, input.data(), input.size()))
|
|
||||||
{
|
|
||||||
LOG(WARNING) << "OSNMA SHA-256: Message digest update failed.";
|
|
||||||
EVP_MD_CTX_free(mdCtx);
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
if (!EVP_DigestFinal_ex(mdCtx, output.data(), &mdLen))
|
|
||||||
{
|
|
||||||
LOG(WARNING) << "OSNMA SHA-256: Message digest finalization failed.";
|
|
||||||
EVP_MD_CTX_free(mdCtx);
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
EVP_MD_CTX_free(mdCtx);
|
|
||||||
// md = mdVal;
|
|
||||||
#else
|
|
||||||
SHA256_CTX sha256Context;
|
|
||||||
SHA256_Init(&sha256Context);
|
|
||||||
SHA256_Update(&sha256Context, input.data(), input.size());
|
|
||||||
SHA256_Final(output.data(), &sha256Context);
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
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
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<uint8_t> osnma_msg_receiver::computeSHA3_256(const std::vector<uint8_t>& input)
|
|
||||||
{
|
|
||||||
std::vector<uint8_t> output(32); // SHA256 hash size
|
|
||||||
#if USE_OPENSSL_FALLBACK
|
|
||||||
#if USE_OPENSSL_3
|
|
||||||
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 < 3.0
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
std::vector<uint8_t> output_aux(32);
|
|
||||||
gnutls_hash_hd_t hashHandle;
|
|
||||||
gnutls_hash_init(&hashHandle, GNUTLS_DIG_SHA3_256);
|
|
||||||
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
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<uint8_t> osnma_msg_receiver::computeHMAC_SHA_256(const std::vector<uint8_t>& key, const std::vector<uint8_t>& input)
|
|
||||||
{
|
|
||||||
std::vector<uint8_t> output(32);
|
|
||||||
#if USE_OPENSSL_FALLBACK
|
|
||||||
#if USE_OPENSSL_3
|
|
||||||
std::vector<uint8_t> hmac(EVP_MAX_MD_SIZE);
|
|
||||||
|
|
||||||
// Create HMAC-SHA256 context
|
|
||||||
EVP_MD_CTX* ctx = EVP_MD_CTX_new();
|
|
||||||
EVP_PKEY* pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, nullptr, key.data(), key.size());
|
|
||||||
|
|
||||||
// Initialize HMAC-SHA256 context
|
|
||||||
EVP_DigestSignInit(ctx, nullptr, EVP_sha256(), nullptr, pkey);
|
|
||||||
|
|
||||||
// Compute HMAC-SHA256
|
|
||||||
EVP_DigestSignUpdate(ctx, input.data(), input.size());
|
|
||||||
size_t macLength;
|
|
||||||
EVP_DigestSignFinal(ctx, hmac.data(), &macLength);
|
|
||||||
|
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
EVP_MD_CTX_free(ctx);
|
|
||||||
|
|
||||||
hmac.resize(macLength);
|
|
||||||
output = hmac;
|
|
||||||
#else
|
|
||||||
std::vector<uint8_t> hmac(32);
|
|
||||||
// Create HMAC context
|
|
||||||
HMAC_CTX* ctx = HMAC_CTX_new();
|
|
||||||
HMAC_Init_ex(ctx, key.data(), key.size(), EVP_sha256(), nullptr);
|
|
||||||
|
|
||||||
// Update HMAC context with the message
|
|
||||||
HMAC_Update(ctx, input.data(), input.size());
|
|
||||||
|
|
||||||
// Finalize HMAC computation
|
|
||||||
unsigned int hmacLen;
|
|
||||||
HMAC_Final(ctx, hmac.data(), &hmacLen);
|
|
||||||
|
|
||||||
// Clean up HMAC context
|
|
||||||
HMAC_CTX_free(ctx);
|
|
||||||
|
|
||||||
// Resize the HMAC vector to the actual length
|
|
||||||
hmac.resize(hmacLen);
|
|
||||||
|
|
||||||
output = hmac;
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
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
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<uint8_t> osnma_msg_receiver::computeCMAC_AES(const std::vector<uint8_t>& key, const std::vector<uint8_t>& input)
|
|
||||||
{
|
|
||||||
std::vector<uint8_t> output(16);
|
|
||||||
#if USE_OPENSSL_FALLBACK
|
|
||||||
#if USE_OPENSSL_3
|
|
||||||
std::vector<uint8_t> mac(EVP_MAX_MD_SIZE); // CMAC-AES output size
|
|
||||||
|
|
||||||
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
|
|
||||||
|
|
||||||
// Initialize CMAC-AES context
|
|
||||||
EVP_CIPHER_CTX* cmacCtx = EVP_CIPHER_CTX_new();
|
|
||||||
EVP_CMAC_CTX* cmac = EVP_CMAC_CTX_new();
|
|
||||||
|
|
||||||
EVP_CIPHER_CTX_reset(ctx);
|
|
||||||
EVP_CMAC_CTX_reset(cmac);
|
|
||||||
|
|
||||||
// Set AES-128 CMAC cipher and key
|
|
||||||
EVP_CMAC_init(cmac, key.data(), key.size(), EVP_aes_128_cbc(), nullptr);
|
|
||||||
|
|
||||||
// Compute CMAC-AES
|
|
||||||
EVP_CMAC_update(cmac, input.data(), input.size());
|
|
||||||
size_t macLength;
|
|
||||||
EVP_CMAC_final(cmac, mac.data(), &macLength);
|
|
||||||
|
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
|
||||||
EVP_CMAC_CTX_free(cmac);
|
|
||||||
|
|
||||||
mac.resize(macLength);
|
|
||||||
output = mac;
|
|
||||||
#else
|
|
||||||
std::vector<uint8_t> mac(CMAC_DIGEST_LENGTH); // CMAC-AES output size
|
|
||||||
|
|
||||||
// Create CMAC context
|
|
||||||
CMAC_CTX* cmacCtx = CMAC_CTX_new();
|
|
||||||
CMAC_Init(cmacCtx, key.data(), key.size(), EVP_aes_128_cbc(), nullptr);
|
|
||||||
|
|
||||||
// Compute CMAC-AES
|
|
||||||
CMAC_Update(cmacCtx, input.data(), input.size());
|
|
||||||
CMAC_Final(cmacCtx, mac.data(), nullptr);
|
|
||||||
|
|
||||||
// Clean up CMAC context
|
|
||||||
CMAC_CTX_free(cmacCtx);
|
|
||||||
|
|
||||||
output = mac;
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
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
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
// bool signature(const std::vector<uint8_t>& publicKey, const std::vector<uint8_t>& digest, std::vector<uint8_t>& signature)
|
|
||||||
// {
|
|
||||||
// bool success = false;
|
|
||||||
// #if USE_OPENSSL_FALLBACK
|
|
||||||
// #else
|
|
||||||
// gnutls_global_init();
|
|
||||||
// int result = gnutls_pubkey_verify_data(publicKey.data(), GNUTLS_SIGN_ECDSA_SHA256, digest.data, digest.size(), signature.data(), signature.size());
|
|
||||||
// success = (result == GNUTLS_E_SUCCESS);
|
|
||||||
// gnutls_global_deinit();
|
|
||||||
// #endif
|
|
||||||
// return success;
|
|
||||||
// }
|
|
||||||
// bool verifyDigitalSignature(const unsigned char* signature, size_t signatureSize, const unsigned char* message, size_t messageSize, gnutls_pubkey_t publicKey)
|
|
||||||
// {
|
|
||||||
// int verificationStatus = gnutls_pubkey_verify_data(publicKey, GNUTLS_DIG_SHA256, 0, message, messageSize, signature, signatureSize);
|
|
||||||
// return verificationStatus == 0;
|
|
||||||
|
|
||||||
std::vector<uint8_t> osnma_msg_receiver::readPublicKeyFromPEM(const std::string& filePath)
|
|
||||||
{
|
|
||||||
std::vector<uint8_t> publicKey;
|
|
||||||
#if USE_OPENSSL_FALLBACK
|
|
||||||
#if USE_OPENSSL_3
|
|
||||||
#else
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
// Open the .pem file
|
|
||||||
std::ifstream file(filePath);
|
|
||||||
if (!file)
|
|
||||||
{
|
|
||||||
std::cerr << "Failed to open the file: " << filePath << std::endl;
|
|
||||||
return publicKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the contents of the .pem file into a string
|
|
||||||
std::string pemContents((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
|
||||||
|
|
||||||
gnutls_x509_crt_t cert;
|
|
||||||
gnutls_x509_crt_init(&cert);
|
|
||||||
|
|
||||||
// Import the certificate from the PEM file
|
|
||||||
gnutls_datum_t pemData;
|
|
||||||
pemData.data = reinterpret_cast<unsigned char*>(const_cast<char*>(pemContents.data()));
|
|
||||||
pemData.size = pemContents.size();
|
|
||||||
int ret = gnutls_x509_crt_import(cert, &pemData, GNUTLS_X509_FMT_PEM);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
std::cerr << "Failed to import certificate from PEM file" << std::endl;
|
|
||||||
gnutls_x509_crt_deinit(cert);
|
|
||||||
return publicKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Export the public key data
|
|
||||||
size_t pubkey_data_size = 0;
|
|
||||||
ret = gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, nullptr, &pubkey_data_size);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
std::cerr << "Failed to export public key data" << std::endl;
|
|
||||||
gnutls_x509_crt_deinit(cert);
|
|
||||||
return publicKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
publicKey.resize(pubkey_data_size);
|
|
||||||
ret = gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, publicKey.data(), &pubkey_data_size);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
std::cerr << "Failed to export public key data" << std::endl;
|
|
||||||
gnutls_x509_crt_deinit(cert);
|
|
||||||
return publicKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
gnutls_x509_crt_deinit(cert);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
return publicKey;
|
|
||||||
}
|
|
@ -27,6 +27,7 @@
|
|||||||
#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 <memory> // for std::shared_ptr
|
#include <memory> // for std::shared_ptr
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
/** \addtogroup Core
|
/** \addtogroup Core
|
||||||
@ -35,11 +36,12 @@
|
|||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
class OSNMA_DSM_Reader;
|
class OSNMA_DSM_Reader;
|
||||||
|
class Gnss_Crypto;
|
||||||
class osnma_msg_receiver;
|
class osnma_msg_receiver;
|
||||||
|
|
||||||
using osnma_msg_receiver_sptr = gnss_shared_ptr<osnma_msg_receiver>;
|
using osnma_msg_receiver_sptr = gnss_shared_ptr<osnma_msg_receiver>;
|
||||||
|
|
||||||
osnma_msg_receiver_sptr osnma_msg_receiver_make();
|
osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief GNU Radio block that receives asynchronous OSNMA messages
|
* \brief GNU Radio block that receives asynchronous OSNMA messages
|
||||||
@ -53,8 +55,8 @@ public:
|
|||||||
~osnma_msg_receiver() = default; //!< Default destructor
|
~osnma_msg_receiver() = default; //!< Default destructor
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend osnma_msg_receiver_sptr osnma_msg_receiver_make();
|
friend osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath);
|
||||||
osnma_msg_receiver();
|
osnma_msg_receiver(const std::string& pemFilePath);
|
||||||
|
|
||||||
void msg_handler_osnma(const pmt::pmt_t& msg);
|
void msg_handler_osnma(const pmt::pmt_t& msg);
|
||||||
void process_osnma_message(const std::shared_ptr<OSNMA_msg>& osnma_msg);
|
void process_osnma_message(const std::shared_ptr<OSNMA_msg>& osnma_msg);
|
||||||
@ -69,13 +71,8 @@ private:
|
|||||||
void read_mack_key();
|
void read_mack_key();
|
||||||
void read_mack_padding();
|
void read_mack_padding();
|
||||||
|
|
||||||
std::vector<uint8_t> computeSHA256(const std::vector<uint8_t>& input);
|
|
||||||
std::vector<uint8_t> computeSHA3_256(const std::vector<uint8_t>& input);
|
|
||||||
std::vector<uint8_t> computeHMAC_SHA_256(const std::vector<uint8_t>& key, const std::vector<uint8_t>& input);
|
|
||||||
std::vector<uint8_t> computeCMAC_AES(const std::vector<uint8_t>& key, const std::vector<uint8_t>& input);
|
|
||||||
std::vector<uint8_t> readPublicKeyFromPEM(const std::string& filePath);
|
|
||||||
|
|
||||||
std::unique_ptr<OSNMA_DSM_Reader> d_dsm_reader;
|
std::unique_ptr<OSNMA_DSM_Reader> d_dsm_reader;
|
||||||
|
std::unique_ptr<Gnss_Crypto> d_crypto;
|
||||||
|
|
||||||
std::array<std::array<uint8_t, 256>, 16> d_dsm_message{};
|
std::array<std::array<uint8_t, 256>, 16> d_dsm_message{};
|
||||||
std::array<std::array<uint8_t, 16>, 16> d_dsm_id_received{};
|
std::array<std::array<uint8_t, 16>, 16> d_dsm_id_received{};
|
||||||
|
@ -118,7 +118,9 @@ void GNSSFlowgraph::init()
|
|||||||
if (configuration_->property("Channels_1B.count", 0) > 0)
|
if (configuration_->property("Channels_1B.count", 0) > 0)
|
||||||
{
|
{
|
||||||
enable_osnma_rx_ = true;
|
enable_osnma_rx_ = true;
|
||||||
osnma_rx_ = osnma_msg_receiver_make();
|
const std::string pemfile_default("./OSNMA_PublicKey_20210920133026.pem");
|
||||||
|
auto pemFilePath = configuration_->property("GNSS-SDR.OSNMA_pem", pemfile_default);
|
||||||
|
osnma_rx_ = osnma_msg_receiver_make(pemFilePath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
set(SYSTEM_PARAMETERS_SOURCES
|
set(SYSTEM_PARAMETERS_SOURCES
|
||||||
gnss_almanac.cc
|
gnss_almanac.cc
|
||||||
|
gnss_crypto.cc
|
||||||
gnss_ephemeris.cc
|
gnss_ephemeris.cc
|
||||||
gnss_satellite.cc
|
gnss_satellite.cc
|
||||||
gnss_signal.cc
|
gnss_signal.cc
|
||||||
@ -34,6 +35,7 @@ set(SYSTEM_PARAMETERS_SOURCES
|
|||||||
|
|
||||||
set(SYSTEM_PARAMETERS_HEADERS
|
set(SYSTEM_PARAMETERS_HEADERS
|
||||||
gnss_almanac.h
|
gnss_almanac.h
|
||||||
|
gnss_crypto.h
|
||||||
gnss_ephemeris.h
|
gnss_ephemeris.h
|
||||||
gnss_satellite.h
|
gnss_satellite.h
|
||||||
gnss_signal.h
|
gnss_signal.h
|
||||||
@ -130,6 +132,42 @@ target_include_directories(core_system_parameters
|
|||||||
${GNSSSDR_SOURCE_DIR}/src/algorithms/libs
|
${GNSSSDR_SOURCE_DIR}/src/algorithms/libs
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(OPENSSL_FOUND)
|
||||||
|
if(TARGET OpenSSL::SSL)
|
||||||
|
target_link_libraries(core_system_parameters
|
||||||
|
PRIVATE
|
||||||
|
OpenSSL::SSL
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
target_link_libraries(core_system_parameters
|
||||||
|
PRIVATE
|
||||||
|
${OPENSSL_LIBRARIES}
|
||||||
|
)
|
||||||
|
target_include_directories(core_system_parameters
|
||||||
|
PRIVATE
|
||||||
|
${OPENSSL_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
if(OPENSSL_VERSION)
|
||||||
|
if(OPENSSL_VERSION VERSION_GREATER "3.0.0")
|
||||||
|
target_compile_definitions(core_system_parameters PRIVATE -DUSE_OPENSSL_3=1)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
target_link_libraries(core_system_parameters
|
||||||
|
PRIVATE
|
||||||
|
${GNUTLS_LIBRARIES}
|
||||||
|
${GNUTLS_OPENSSL_LIBRARY}
|
||||||
|
)
|
||||||
|
target_include_directories(core_system_parameters
|
||||||
|
PRIVATE
|
||||||
|
${GNUTLS_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
if(OPENSSL_FOUND)
|
||||||
|
target_compile_definitions(core_system_parameters PRIVATE -DUSE_OPENSSL_FALLBACK=1)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(ENABLE_CLANG_TIDY)
|
if(ENABLE_CLANG_TIDY)
|
||||||
if(CLANG_TIDY_EXE)
|
if(CLANG_TIDY_EXE)
|
||||||
set_target_properties(core_system_parameters
|
set_target_properties(core_system_parameters
|
||||||
|
400
src/core/system_parameters/gnss_crypto.cc
Normal file
400
src/core/system_parameters/gnss_crypto.cc
Normal file
@ -0,0 +1,400 @@
|
|||||||
|
/*!
|
||||||
|
* \file gnss_crypto.cc
|
||||||
|
* \brief Class for computing cryptografic functions
|
||||||
|
* \author Carles Fernandez, 2023. cfernandez(at)cttc.es
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||||
|
* This file is part of GNSS-SDR.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors)
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gnss_crypto.h"
|
||||||
|
#include <cstddef>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
#if USE_OPENSSL_FALLBACK
|
||||||
|
#include <openssl/cmac.h>
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
#if USE_OPENSSL_3
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#define OPENSSL_ENGINE NULL
|
||||||
|
#else
|
||||||
|
#include <openssl/rsa.h>
|
||||||
|
#include <openssl/sha.h>
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#include <gnutls/crypto.h>
|
||||||
|
#include <gnutls/gnutls.h>
|
||||||
|
#include <gnutls/x509.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Gnss_Crypto::Gnss_Crypto(const std::string& filePath)
|
||||||
|
{
|
||||||
|
d_PublicKey = readPublicKeyFromPEM(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<uint8_t> Gnss_Crypto::computeSHA256(const std::vector<uint8_t>& input)
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> output(32); // SHA256 hash size
|
||||||
|
#if USE_OPENSSL_FALLBACK
|
||||||
|
#if USE_OPENSSL_3
|
||||||
|
unsigned int mdLen;
|
||||||
|
EVP_MD_CTX* mdCtx = EVP_MD_CTX_new();
|
||||||
|
if (!EVP_DigestInit_ex(mdCtx, EVP_sha256(), OPENSSL_ENGINE))
|
||||||
|
{
|
||||||
|
// LOG(WARNING) << "OSNMA SHA-256: Message digest initialization failed.";
|
||||||
|
EVP_MD_CTX_free(mdCtx);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
if (!EVP_DigestUpdate(mdCtx, input.data(), input.size()))
|
||||||
|
{
|
||||||
|
// LOG(WARNING) << "OSNMA SHA-256: Message digest update failed.";
|
||||||
|
EVP_MD_CTX_free(mdCtx);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
if (!EVP_DigestFinal_ex(mdCtx, output.data(), &mdLen))
|
||||||
|
{
|
||||||
|
// LOG(WARNING) << "OSNMA SHA-256: Message digest finalization failed.";
|
||||||
|
EVP_MD_CTX_free(mdCtx);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
EVP_MD_CTX_free(mdCtx);
|
||||||
|
#else
|
||||||
|
SHA256_CTX sha256Context;
|
||||||
|
SHA256_Init(&sha256Context);
|
||||||
|
SHA256_Update(&sha256Context, input.data(), input.size());
|
||||||
|
SHA256_Final(output.data(), &sha256Context);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
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
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<uint8_t> Gnss_Crypto::computeSHA3_256(const std::vector<uint8_t>& input)
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> output(32); // SHA256 hash size
|
||||||
|
#if USE_OPENSSL_FALLBACK
|
||||||
|
#if USE_OPENSSL_3
|
||||||
|
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 < 3.0
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
std::vector<uint8_t> output_aux(32);
|
||||||
|
gnutls_hash_hd_t hashHandle;
|
||||||
|
gnutls_hash_init(&hashHandle, GNUTLS_DIG_SHA3_256);
|
||||||
|
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
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<uint8_t> Gnss_Crypto::computeHMAC_SHA_256(const std::vector<uint8_t>& key, const std::vector<uint8_t>& input)
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> output(32);
|
||||||
|
#if USE_OPENSSL_FALLBACK
|
||||||
|
#if USE_OPENSSL_3
|
||||||
|
std::vector<uint8_t> hmac(EVP_MAX_MD_SIZE);
|
||||||
|
|
||||||
|
// Create HMAC-SHA256 context
|
||||||
|
EVP_MD_CTX* ctx = EVP_MD_CTX_new();
|
||||||
|
EVP_PKEY* pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, nullptr, key.data(), key.size());
|
||||||
|
|
||||||
|
// Initialize HMAC-SHA256 context
|
||||||
|
EVP_DigestSignInit(ctx, nullptr, EVP_sha256(), nullptr, pkey);
|
||||||
|
|
||||||
|
// Compute HMAC-SHA256
|
||||||
|
EVP_DigestSignUpdate(ctx, input.data(), input.size());
|
||||||
|
size_t macLength;
|
||||||
|
EVP_DigestSignFinal(ctx, hmac.data(), &macLength);
|
||||||
|
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
|
EVP_MD_CTX_free(ctx);
|
||||||
|
|
||||||
|
hmac.resize(macLength);
|
||||||
|
output = hmac;
|
||||||
|
#else
|
||||||
|
std::vector<uint8_t> hmac(32);
|
||||||
|
// Create HMAC context
|
||||||
|
HMAC_CTX* ctx = HMAC_CTX_new();
|
||||||
|
HMAC_Init_ex(ctx, key.data(), key.size(), EVP_sha256(), nullptr);
|
||||||
|
|
||||||
|
// Update HMAC context with the message
|
||||||
|
HMAC_Update(ctx, input.data(), input.size());
|
||||||
|
|
||||||
|
// Finalize HMAC computation
|
||||||
|
unsigned int hmacLen;
|
||||||
|
HMAC_Final(ctx, hmac.data(), &hmacLen);
|
||||||
|
|
||||||
|
// Clean up HMAC context
|
||||||
|
HMAC_CTX_free(ctx);
|
||||||
|
|
||||||
|
// Resize the HMAC vector to the actual length
|
||||||
|
hmac.resize(hmacLen);
|
||||||
|
|
||||||
|
output = hmac;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
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
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<uint8_t> Gnss_Crypto::computeCMAC_AES(const std::vector<uint8_t>& key, const std::vector<uint8_t>& input)
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> output(16);
|
||||||
|
#if USE_OPENSSL_FALLBACK
|
||||||
|
#if USE_OPENSSL_3
|
||||||
|
std::vector<uint8_t> mac(EVP_MAX_MD_SIZE); // CMAC-AES output size
|
||||||
|
|
||||||
|
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
|
||||||
|
EVP_MAC* cmac = EVP_MAC_fetch(NULL, "CMAC-AES", NULL);
|
||||||
|
|
||||||
|
EVP_MAC_CTX* cmacCtx = EVP_MAC_CTX_new(cmac);
|
||||||
|
|
||||||
|
OSSL_PARAM params[4];
|
||||||
|
params[0] = OSSL_PARAM_construct_utf8_string("key", (char*)key.data(), key.size());
|
||||||
|
params[1] = OSSL_PARAM_construct_octet_string("iv", NULL, 0); // Set IV to NULL
|
||||||
|
params[2] = OSSL_PARAM_construct_octet_string("aad", NULL, 0); // Set AAD to NULL
|
||||||
|
params[3] = OSSL_PARAM_construct_end();
|
||||||
|
|
||||||
|
// Set AES-128 CMAC cipher and key
|
||||||
|
EVP_MAC_init(cmacCtx, nullptr, 0, params);
|
||||||
|
|
||||||
|
// Compute CMAC-AES
|
||||||
|
EVP_MAC_update(cmacCtx, input.data(), input.size());
|
||||||
|
size_t macLength = mac.size();
|
||||||
|
size_t outputLength = 16;
|
||||||
|
|
||||||
|
EVP_MAC_final(cmacCtx, mac.data(), &macLength, outputLength);
|
||||||
|
|
||||||
|
EVP_MAC_free(cmac);
|
||||||
|
EVP_MAC_CTX_free(cmacCtx);
|
||||||
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
|
|
||||||
|
mac.resize(macLength);
|
||||||
|
output = mac;
|
||||||
|
#else
|
||||||
|
std::vector<uint8_t> mac(16); // CMAC-AES output size
|
||||||
|
|
||||||
|
// Create CMAC context
|
||||||
|
CMAC_CTX* cmacCtx = CMAC_CTX_new();
|
||||||
|
CMAC_Init(cmacCtx, key.data(), key.size(), EVP_aes_128_cbc(), nullptr);
|
||||||
|
|
||||||
|
// Compute CMAC-AES
|
||||||
|
CMAC_Update(cmacCtx, input.data(), input.size());
|
||||||
|
CMAC_Final(cmacCtx, mac.data(), nullptr);
|
||||||
|
|
||||||
|
// Clean up CMAC context
|
||||||
|
CMAC_CTX_free(cmacCtx);
|
||||||
|
|
||||||
|
output = mac;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
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
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<uint8_t> Gnss_Crypto::readPublicKeyFromPEM(const std::string& filePath)
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> publicKey;
|
||||||
|
// Open the .pem file
|
||||||
|
std::ifstream pemFile(filePath);
|
||||||
|
if (!pemFile)
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to open the file: " << filePath << std::endl;
|
||||||
|
return publicKey;
|
||||||
|
}
|
||||||
|
#if USE_OPENSSL_FALLBACK
|
||||||
|
#if USE_OPENSSL_3
|
||||||
|
// Read the contents of the file into a string
|
||||||
|
std::string pemContent((std::istreambuf_iterator<char>(pemFile)), std::istreambuf_iterator<char>());
|
||||||
|
|
||||||
|
// Create a BIO object from the string data
|
||||||
|
BIO* bio = BIO_new_mem_buf(pemContent.c_str(), pemContent.length());
|
||||||
|
if (!bio)
|
||||||
|
{
|
||||||
|
// Handle BIO creation error
|
||||||
|
pemFile.close();
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the PEM data from the BIO
|
||||||
|
EVP_PKEY* evpKey = PEM_read_bio_PUBKEY(bio, nullptr, nullptr, nullptr);
|
||||||
|
if (!evpKey)
|
||||||
|
{
|
||||||
|
// Handle PEM reading error
|
||||||
|
BIO_free(bio);
|
||||||
|
pemFile.close();
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a memory BIO to write the public key data
|
||||||
|
BIO* memBio = BIO_new(BIO_s_mem());
|
||||||
|
if (!memBio)
|
||||||
|
{
|
||||||
|
// Handle memory BIO creation error
|
||||||
|
EVP_PKEY_free(evpKey);
|
||||||
|
BIO_free(bio);
|
||||||
|
pemFile.close();
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the public key to the memory BIO
|
||||||
|
int result = PEM_write_bio_PUBKEY(memBio, evpKey);
|
||||||
|
if (result != 1)
|
||||||
|
{
|
||||||
|
// Handle public key writing error
|
||||||
|
BIO_free(memBio);
|
||||||
|
EVP_PKEY_free(evpKey);
|
||||||
|
BIO_free(bio);
|
||||||
|
pemFile.close();
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the pointer to the memory BIO data and its length
|
||||||
|
char* bioData;
|
||||||
|
long bioDataLength = BIO_get_mem_data(memBio, &bioData);
|
||||||
|
|
||||||
|
// Copy the public key data to the vector
|
||||||
|
publicKey.assign(bioData, bioData + bioDataLength);
|
||||||
|
|
||||||
|
// Free resources
|
||||||
|
BIO_free(memBio);
|
||||||
|
EVP_PKEY_free(evpKey);
|
||||||
|
BIO_free(bio);
|
||||||
|
pemFile.close();
|
||||||
|
#else
|
||||||
|
// Read the PEM file contents into a string
|
||||||
|
std::string pemContents((std::istreambuf_iterator<char>(pemFile)), std::istreambuf_iterator<char>());
|
||||||
|
|
||||||
|
// Create a BIO object to hold the PEM data
|
||||||
|
BIO* bio = BIO_new_mem_buf(pemContents.c_str(), -1);
|
||||||
|
|
||||||
|
// Load the public key from the BIO
|
||||||
|
RSA* rsa = PEM_read_bio_RSA_PUBKEY(bio, nullptr, nullptr, nullptr);
|
||||||
|
BIO_free(bio);
|
||||||
|
|
||||||
|
if (rsa == nullptr)
|
||||||
|
{
|
||||||
|
// Handle error reading public key
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the RSA modulus and convert it to a vector of uint8_t
|
||||||
|
const BIGNUM* rsaModulus = nullptr;
|
||||||
|
RSA_get0_key(rsa, &rsaModulus, nullptr, nullptr);
|
||||||
|
|
||||||
|
BN_bn2bin(rsaModulus, publicKey.data());
|
||||||
|
|
||||||
|
// Clean up the RSA object
|
||||||
|
RSA_free(rsa);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
// Read the contents of the .pem file into a string
|
||||||
|
std::string pemContents((std::istreambuf_iterator<char>(pemFile)), std::istreambuf_iterator<char>());
|
||||||
|
|
||||||
|
gnutls_x509_crt_t cert;
|
||||||
|
gnutls_x509_crt_init(&cert);
|
||||||
|
|
||||||
|
// Import the certificate from the PEM file
|
||||||
|
gnutls_datum_t pemData;
|
||||||
|
pemData.data = reinterpret_cast<unsigned char*>(const_cast<char*>(pemContents.data()));
|
||||||
|
pemData.size = pemContents.size();
|
||||||
|
int ret = gnutls_x509_crt_import(cert, &pemData, GNUTLS_X509_FMT_PEM);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to import certificate from PEM file" << std::endl;
|
||||||
|
gnutls_x509_crt_deinit(cert);
|
||||||
|
return publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export the public key data
|
||||||
|
size_t pubkey_data_size = 0;
|
||||||
|
ret = gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, nullptr, &pubkey_data_size);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to export public key data" << std::endl;
|
||||||
|
gnutls_x509_crt_deinit(cert);
|
||||||
|
return publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
publicKey.resize(pubkey_data_size);
|
||||||
|
ret = gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, publicKey.data(), &pubkey_data_size);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to export public key data" << std::endl;
|
||||||
|
gnutls_x509_crt_deinit(cert);
|
||||||
|
return publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
gnutls_x509_crt_deinit(cert);
|
||||||
|
#endif
|
||||||
|
return publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// // bool signature(const std::vector<uint8_t>& publicKey, const std::vector<uint8_t>& digest, std::vector<uint8_t>& signature)
|
||||||
|
// // {
|
||||||
|
// // bool success = false;
|
||||||
|
// // #if USE_OPENSSL_FALLBACK
|
||||||
|
// // #else
|
||||||
|
// // gnutls_global_init();
|
||||||
|
// // int result = gnutls_pubkey_verify_data(publicKey.data(), GNUTLS_SIGN_ECDSA_SHA256, digest.data, digest.size(), signature.data(), signature.size());
|
||||||
|
// // success = (result == GNUTLS_E_SUCCESS);
|
||||||
|
// // gnutls_global_deinit();
|
||||||
|
// // #endif
|
||||||
|
// // return success;
|
||||||
|
// // }
|
||||||
|
// // bool verifyDigitalSignature(const unsigned char* signature, size_t signatureSize, const unsigned char* message, size_t messageSize, gnutls_pubkey_t publicKey)
|
||||||
|
// // {
|
||||||
|
// // int verificationStatus = gnutls_pubkey_verify_data(publicKey, GNUTLS_DIG_SHA256, 0, message, messageSize, signature, signatureSize);
|
||||||
|
// // return verificationStatus == 0;
|
49
src/core/system_parameters/gnss_crypto.h
Normal file
49
src/core/system_parameters/gnss_crypto.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*!
|
||||||
|
* \file gnss_crypto.h
|
||||||
|
* \brief Class for computing cryptografic functions
|
||||||
|
* \author Carles Fernandez, 2023. cfernandez(at)cttc.es
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||||
|
* This file is part of GNSS-SDR.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors)
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GNSS_SDR_GNSS_CRYPTO_H
|
||||||
|
#define GNSS_SDR_GNSS_CRYPTO_H
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
/** \addtogroup Core
|
||||||
|
* \{ */
|
||||||
|
/** \addtogroup System_Parameters
|
||||||
|
* \{ */
|
||||||
|
|
||||||
|
|
||||||
|
class Gnss_Crypto
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Gnss_Crypto() = default;
|
||||||
|
Gnss_Crypto(const std::string& filePath);
|
||||||
|
std::vector<uint8_t> computeSHA256(const std::vector<uint8_t>& input);
|
||||||
|
std::vector<uint8_t> computeSHA3_256(const std::vector<uint8_t>& input);
|
||||||
|
std::vector<uint8_t> computeHMAC_SHA_256(const std::vector<uint8_t>& key, const std::vector<uint8_t>& input);
|
||||||
|
std::vector<uint8_t> computeCMAC_AES(const std::vector<uint8_t>& key, const std::vector<uint8_t>& input);
|
||||||
|
std::vector<uint8_t> readPublicKeyFromPEM(const std::string& filePath);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<uint8_t> d_PublicKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \} */
|
||||||
|
/** \} */
|
||||||
|
#endif // GNSS_SDR_GNSS_CRYPTO_H
|
Loading…
Reference in New Issue
Block a user