From d41efd2653004abd35d60f5c2d582b8b14eb1b58 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 21 Jun 2024 10:29:20 +0200 Subject: [PATCH 1/8] Really fix signature verification with GnuTLS --- src/core/system_parameters/gnss_crypto.cc | 364 ++++++++-------------- src/core/system_parameters/gnss_crypto.h | 34 +- 2 files changed, 143 insertions(+), 255 deletions(-) diff --git a/src/core/system_parameters/gnss_crypto.cc b/src/core/system_parameters/gnss_crypto.cc index d3cd11380..12d113ae0 100644 --- a/src/core/system_parameters/gnss_crypto.cc +++ b/src/core/system_parameters/gnss_crypto.cc @@ -1,7 +1,8 @@ /*! * \file gnss_crypto.cc - * \brief Class for computing cryptografic functions - * \author Carles Fernandez, 2023. cfernandez(at)cttc.es + * \brief Class for computing cryptographic functions + * \author Carles Fernandez, 2023-2024. cfernandez(at)cttc.es + * Cesare Ghionoiu Martinez, 2023-2024. c.ghionoiu-martinez@tu-braunschweig.de * * * ----------------------------------------------------------------------------- @@ -9,7 +10,7 @@ * 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) + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- @@ -20,9 +21,9 @@ #include #include #include +#include #include #include -#include #if USE_OPENSSL_FALLBACK #include @@ -30,29 +31,27 @@ #include #include #if USE_OPENSSL_3 -#include #include +#include #include #include -#include #include -#include #define OPENSSL_ENGINE nullptr #else #include #endif -#else +#else // GnuTLS +#include #include #include #include -#include #endif Gnss_Crypto::Gnss_Crypto(const std::string& pemFilePath, const std::string& merkleTreePath) { #if USE_OPENSSL_FALLBACK -#else - // gnutls_global_init(); +#else // GnuTLS + gnutls_global_init(); #endif readPublicKeyFromPEM(pemFilePath); read_merkle_xml(merkleTreePath); @@ -69,11 +68,13 @@ Gnss_Crypto::~Gnss_Crypto() EC_KEY_free(d_PublicKey); } #endif -#else // GNU-TLS - if (d_PublicKey != NULL) { +#else // GnuTLS + if (d_PublicKey != NULL) + { gnutls_pubkey_deinit(d_PublicKey); d_PublicKey = NULL; } + gnutls_global_deinit(); #endif } @@ -82,25 +83,12 @@ bool Gnss_Crypto::have_public_key() const { #if USE_OPENSSL_FALLBACK return (d_PublicKey != nullptr); -#else +#else // GnuTLS return (d_PublicKey != gnutls_pubkey_t{}); #endif } -std::string Gnss_Crypto::convert_to_utf8_str(const std::vector& input) const -{ - const char hex[] = "0123456789ABCDEF"; - std::string str(input.size() * 2, '0'); - for (size_t i = 0; i < input.size(); i++) - { - str[(i * 2) + 0] = hex[((input[i] & 0xF0) >> 4)]; - str[(i * 2) + 1] = hex[((input[i] & 0x0F))]; - } - return str; -} - - std::vector Gnss_Crypto::convert_from_hex_str(const std::string& input) const { std::vector result; @@ -236,11 +224,6 @@ void Gnss_Crypto::read_merkle_xml(const std::string& merkleFilePath) } -// void Gnss_Crypto::set_public_key(const std::vector& publickey) -// { -// } - - std::vector Gnss_Crypto::computeSHA256(const std::vector& input) const { std::vector output(32); // SHA256 hash size @@ -273,7 +256,7 @@ std::vector Gnss_Crypto::computeSHA256(const std::vector& inpu SHA256_Update(&sha256Context, input.data(), input.size()); SHA256_Final(output.data(), &sha256Context); #endif -#else +#else // GnuTLS std::vector output_aux(32); gnutls_hash_hd_t hashHandle; gnutls_hash_init(&hashHandle, GNUTLS_DIG_SHA256); @@ -301,7 +284,7 @@ std::vector Gnss_Crypto::computeSHA3_256(const std::vector& in #else // SHA3-256 not implemented in OpenSSL < 3.0 #endif -#else +#else // GnuTLS std::vector output_aux(32); gnutls_hash_hd_t hashHandle; gnutls_hash_init(&hashHandle, GNUTLS_DIG_SHA3_256); @@ -358,7 +341,7 @@ std::vector Gnss_Crypto::computeHMAC_SHA_256(const std::vector hmac.resize(hmacLen); output = hmac; #endif -#else +#else // GnuTLS std::vector output_aux(32); gnutls_hmac_hd_t hmac; gnutls_hmac_init(&hmac, GNUTLS_MAC_SHA256, key.data(), key.size()); @@ -421,7 +404,7 @@ std::vector Gnss_Crypto::computeCMAC_AES(const std::vector& ke output = mac; #endif -#else +#else // GnuTLS gnutls_cipher_hd_t cipher; std::vector mac(16); std::vector message = input; @@ -471,8 +454,7 @@ void Gnss_Crypto::readPublicKeyFromPEM(const std::string& pemFilePath) std::cerr << "OpenSSL: error reading the Public Key from file " << pemFilePath << ". Aborting import" << std::endl; return; } - -#else +#else // GnuTLS // Import the PEM data gnutls_datum_t pemDatum = {const_cast(reinterpret_cast(pemContent.data())), static_cast(pemContent.size())}; gnutls_pubkey_t pubkey; @@ -493,62 +475,21 @@ void Gnss_Crypto::readPublicKeyFromPEM(const std::string& pemFilePath) gnutls_pubkey_deinit(pubkey); #endif std::cout << "Public key successfully read from file " << pemFilePath << std::endl; - //print_pubkey_hex(d_PublicKey); } -bool Gnss_Crypto::verify_signature(const std::vector& message, const std::vector& signature) +bool Gnss_Crypto::verify_signature(const std::vector& message, const std::vector& signature) const { std::vector digest = this->computeSHA256(message); if (!have_public_key()) { - std::cerr << "Galileo OSNMA::Kroot verification error::Public key not available"<< std::endl; + std::cerr << "Galileo OSNMA KROOT verification error: Public key is not available" << std::endl; return false; } bool success = false; #if USE_OPENSSL_FALLBACK -// using low-level API to test function -- it works in unit tests, not in real bytes. -// EVP_MD_CTX *mdctx = NULL; // verification context; a struct that wraps the message to be verified. -// int ret = 0; // error -// -// /* Create the Message Digest Context */ -// if(!(mdctx = EVP_MD_CTX_new())) goto err; // Allocates and returns a digest context. -// -// /* Initialize `key` with a public key */ -// // hashes cnt bytes of data at d into the verification context ctx -// if(1 != EVP_DigestVerifyInit(mdctx, NULL /*TODO null?*/, EVP_sha256(), NULL, d_PublicKey)) goto err; -// -// /* Initialize `key` with a public key */ -// if(1 != EVP_DigestVerifyUpdate(mdctx, message.data(), message.size())) goto err; -// -// -// if( 1 == EVP_DigestVerifyFinal(mdctx, signature.data(), signature.size())) -// { -// return true; -// } -// else -// { -// unsigned long errCode = ERR_get_error(); -// int lib_code = ERR_GET_LIB(errCode); -// char* err = ERR_error_string(errCode, NULL); -// const char* error_string = ERR_error_string(errCode, NULL); -// std::cerr << "OpenSSL: message authentication failed: " << err /*<< -// "from library with code " << lib_code << -// " error string: " << error_string */<< std::endl; -// } -//err: -// if(ret != 1) -// { -// /* Do some error handling */ -// // notify other blocks -// std::cout << "ECDSA_Verify_OSSL()::error " << ret << std::endl; -// -// } - - #if USE_OPENSSL_3 EVP_PKEY_CTX* ctx; - //print_pubkey_hex(d_PublicKey); ctx = EVP_PKEY_CTX_new(d_PublicKey, nullptr); bool do_operation = true; @@ -556,7 +497,7 @@ bool Gnss_Crypto::verify_signature(const std::vector& message, const st { do_operation = false; } - // convert raw signature into DER format, needed for verify_signature + // convert raw signature into DER format size_t half_size = signature.size() / 2; std::vector raw_r(signature.begin(), signature.begin() + half_size); std::vector raw_s(signature.begin() + half_size, signature.end()); @@ -575,12 +516,12 @@ bool Gnss_Crypto::verify_signature(const std::vector& message, const st if (ECDSA_SIG_set0(sig, r, s) != 1) { std::cerr << "Failed to set R and S values in ECDSA_SIG" << std::endl; - ECDSA_SIG_free(sig); // Free the ECDSA_SIG struct as it's no longer needed + ECDSA_SIG_free(sig); // Free the ECDSA_SIG struct as it is no longer needed return false; } std::vector derSignature; - unsigned char *derSig = nullptr; + unsigned char* derSig = nullptr; int derSigLength = i2d_ECDSA_SIG(sig, &derSig); if (derSigLength <= 0) @@ -591,7 +532,6 @@ bool Gnss_Crypto::verify_signature(const std::vector& message, const st derSignature.assign(derSig, derSig + derSigLength); - if (EVP_PKEY_verify_init(ctx) <= 0) { do_operation = false; @@ -616,10 +556,9 @@ bool Gnss_Crypto::verify_signature(const std::vector& message, const st { unsigned long errCode = ERR_get_error(); char* err = ERR_error_string(errCode, NULL); - std::cerr << "OpenSSL: message authentication failed: " << err << std::endl; + std::cerr << "OpenSSL: message authentication failed: " << err << std::endl; } #else - auto digest = this->computeSHA256(message); int verification = ECDSA_verify(0, digest.data(), SHA256_DIGEST_LENGTH, signature.data(), static_cast(signature.size()), d_PublicKey); if (verification == 1) { @@ -635,34 +574,26 @@ bool Gnss_Crypto::verify_signature(const std::vector& message, const st } #endif -#else - // GNU-TLS - gnutls_global_init(); - // debug info gnu-tls remove when not needed anymore! - gnutls_global_set_log_level(9); - gnutls_global_set_log_function(Gnss_Crypto::my_log_func); +#else // GnuTLS + // Convert signature to DER format + std::vector 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; + } - unsigned int bit_size; - if (gnutls_pubkey_get_pk_algorithm(d_PublicKey, &bit_size) != GNUTLS_PK_ECDSA) + // Prepare the digest datum + gnutls_datum_t digest_data = {const_cast(digest.data()), static_cast(digest.size())}; + gnutls_datum_t der_sig_data = {der_sig.data(), static_cast(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) { - std::cerr << "GnuTLS: the Public Key does not contain a ECDSA key. Aborting signature verification" << std::endl; + std::cerr << "GnuTLS: message authentication failed: " << gnutls_strerror(ret) << std::endl; } - gnutls_datum_t signature_{}; - signature_.data = const_cast(signature.data()); - signature_.size = signature.size(); - gnutls_datum_t data_{}; - data_.data = const_cast(message.data()); - data_.size = message.size(); - int ret = gnutls_pubkey_verify_data2(d_PublicKey, GNUTLS_SIGN_ECDSA_SHA256, 0, &data_, &signature_); - if (ret >= 0) - { - success = true; - } - else - { - std::cerr << "GnuTLS error: " << gnutls_strerror(ret) << std::endl; - } - gnutls_global_deinit(); #endif return success; } @@ -707,75 +638,47 @@ std::vector Gnss_Crypto::getMerkleRoot(const std::vector& publicKey) { #if USE_OPENSSL_FALLBACK - BIO *bio = NULL; - EVP_PKEY *pkey = NULL; + BIO* bio = NULL; + EVP_PKEY* pkey = NULL; bio = BIO_new_mem_buf(publicKey.data(), publicKey.size()); - if (!bio) { + if (!bio) + { std::cerr << "Failed to create BIO for key \n"; return; } - pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); - BIO_free(bio); + pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); + BIO_free(bio); - if (!pkey) { - std::cerr << "OpenSSL: error setting the public key " - << ". Aborting import" << std::endl; + if (!pkey) + { + std::cerr << "OpenSSL: error setting the public key." << std::endl; return; } - //print_pubkey_hex(pkey); - - if(!pubkey_copy(pkey, &d_PublicKey)) - return - - EVP_PKEY_free(pkey); -#else -// // GNU-TLS -// gnutls_global_init(); -// -// // debug info gnu-tls remove when not needed anymore! -// gnutls_global_set_log_level(9); -// gnutls_global_set_log_function(Gnss_Crypto::my_log_func); + if (!pubkey_copy(pkey, &d_PublicKey)) + { + return; + } + EVP_PKEY_free(pkey); +#else // GnuTLS gnutls_pubkey_t pubkey; gnutls_datum_t pemDatum = {const_cast(publicKey.data()), static_cast(publicKey.size())}; gnutls_pubkey_init(&pubkey); int ret = gnutls_pubkey_import(pubkey, &pemDatum, GNUTLS_X509_FMT_PEM); - //ret = gnutls_pubkey_import_x509_raw(pubkey, &pemDatum,GNUTLS_X509_FMT_PEM,0); if (ret != GNUTLS_E_SUCCESS) { gnutls_pubkey_deinit(pubkey); - std::cerr << "GnuTLS: error setting the public key " - << ". Aborting import" << std::endl; + std::cerr << "GnuTLS: error setting the public key" << std::endl; std::cerr << "GnuTLS error: " << gnutls_strerror(ret) << std::endl; return; } - // d_PublicKey = pubkey; pubkey_copy(pubkey, &d_PublicKey); -// std::cout << "pubkey: " << std::endl; -// print_pubkey_hex(pubkey); -// std::cout << "d_PublicKey before : " << std::endl; -// print_pubkey_hex(d_PublicKey); gnutls_pubkey_deinit(pubkey); -// std::cout << "d_PublicKey after: " << std::endl; -// print_pubkey_hex(d_PublicKey); - -// gnutls_global_deinit(); #endif - } -std::vector Gnss_Crypto::get_public_key() -{ -#if USE_OPENSSL_FALLBACK - // TODO -#else -// GNU-TLS - // TODO -#endif - return {}; -} #if USE_OPENSSL_FALLBACK bool Gnss_Crypto::pubkey_copy(EVP_PKEY* src, EVP_PKEY** dest) @@ -794,9 +697,6 @@ bool Gnss_Crypto::pubkey_copy(EVP_PKEY* src, EVP_PKEY** dest) return false; } - // Add a null-terminator to the data in the memory buffer - //BIO_write(mem_bio, "\0", 1); - // Read the data from the memory buffer char* bio_data; long data_len = BIO_get_mem_data(mem_bio, &bio_data); @@ -824,95 +724,87 @@ bool Gnss_Crypto::pubkey_copy(EVP_PKEY* src, EVP_PKEY** dest) return true; } -void Gnss_Crypto::print_pubkey_hex(EVP_PKEY* pubkey) + +#else // GnuTLS-specific functions + +bool Gnss_Crypto::convert_raw_to_der_ecdsa(const std::vector& raw_signature, std::vector& der_signature) const { - BIO* mem_bio = BIO_new(BIO_s_mem()); - if (!mem_bio) { - std::cerr << "Failed to create new memory BIO\n"; - return; + if (raw_signature.size() % 2 != 0) + { + std::cerr << "Invalid raw ECDSA signature size" << std::endl; + return false; } - if (!PEM_write_bio_PUBKEY(mem_bio, pubkey)){ - std::cerr << "Failed to write public key to BIO\n"; - BIO_free(mem_bio); - return; + size_t half_size = raw_signature.size() / 2; + std::vector raw_r(raw_signature.begin(), raw_signature.begin() + half_size); + std::vector raw_s(raw_signature.begin() + half_size, raw_signature.end()); + + auto encode_asn1_integer = [](const std::vector& value) -> std::vector { + std::vector result; + result.push_back(0x02); // INTEGER tag + + if (value[0] & 0x80) + { + result.push_back(value.size() + 1); // Length byte + result.push_back(0x00); // Add leading zero byte to ensure positive integer + } + else + { + result.push_back(value.size()); // Length byte + } + + result.insert(result.end(), value.begin(), value.end()); + return result; + }; + + std::vector der_r = encode_asn1_integer(raw_r); + std::vector der_s = encode_asn1_integer(raw_s); + + size_t total_length = der_r.size() + der_s.size(); + der_signature.push_back(0x30); // SEQUENCE tag + if (total_length > 127) + { + der_signature.push_back(0x81); // Long form length } + der_signature.push_back(static_cast(total_length)); - BUF_MEM* mem_ptr; - BIO_get_mem_ptr(mem_bio, &mem_ptr); // Fetch the underlying BUF_MEM structure from the BIO. + der_signature.insert(der_signature.end(), der_r.begin(), der_r.end()); + der_signature.insert(der_signature.end(), der_s.begin(), der_s.end()); - std::stringstream ss; - - // Iterate through each byte in mem_ptr->data and print its hex value. - for (size_t i = 0; i < mem_ptr->length; i++) { - ss << std::hex << std::setw(2) << std::setfill('0') << - static_cast(static_cast(mem_ptr->data[i])); - } - - //std::cout << "Public key in hex format: 0x" << ss.str() << std::endl; - - BIO_free(mem_bio); + return true; } -#else // gnutls-specific functions - void Gnss_Crypto::my_log_func(int level, const char *msg){ - fprintf(stderr, " %s", level, msg);} - bool Gnss_Crypto::pubkey_copy(gnutls_pubkey_t src, gnutls_pubkey_t* dest) - { - gnutls_datum_t key_datum; - int ret; - // Export the public key from src to memory - ret = gnutls_pubkey_export2(src, GNUTLS_X509_FMT_PEM, &key_datum); - if (ret < 0) - { - gnutls_free(key_datum.data); - return false; - } +bool Gnss_Crypto::pubkey_copy(gnutls_pubkey_t src, gnutls_pubkey_t* dest) +{ + gnutls_datum_t key_datum; - // Initialize dest - ret = gnutls_pubkey_init(dest); - if (ret < 0) - { - gnutls_free(key_datum.data); - return false; - } + // 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; + } - // 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); + // Initialize dest + ret = gnutls_pubkey_init(dest); + if (ret < 0) + { + gnutls_free(key_datum.data); + return false; + } - if (ret < 0) - { - gnutls_pubkey_deinit(*dest); - 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); - return true; - } + if (ret < 0) + { + gnutls_pubkey_deinit(*dest); + return false; + } - void Gnss_Crypto::print_pubkey_hex(gnutls_pubkey_t pubkey) - { - gnutls_datum_t key_datum; - int ret; - - // Export the public key from pubkey to memory in DER format - ret = gnutls_pubkey_export2(pubkey, GNUTLS_X509_FMT_PEM, &key_datum); - if (ret < 0) { - std::cerr << "Failed to export public key: " << gnutls_strerror(ret) << std::endl; - return; - } - - std::stringstream ss; - - // Iterate through each byte in key_datum.data and print its hex value - for (unsigned int i = 0; i < key_datum.size; ++i) { - ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(key_datum.data[i]); - } - - std::cout << "Public key in hex format: 0x" << ss.str() << std::endl; - - // Free the memory allocated to key_datum.data - gnutls_free(key_datum.data); - } + return true; +} #endif diff --git a/src/core/system_parameters/gnss_crypto.h b/src/core/system_parameters/gnss_crypto.h index 1191a7ed5..41341d981 100644 --- a/src/core/system_parameters/gnss_crypto.h +++ b/src/core/system_parameters/gnss_crypto.h @@ -1,7 +1,8 @@ /*! * \file gnss_crypto.h - * \brief Class for computing cryptografic functions - * \author Carles Fernandez, 2023. cfernandez(at)cttc.es + * \brief Class for computing cryptographic functions + * \author Carles Fernandez, 2023-2024. cfernandez(at)cttc.es + * Cesare Ghionoiu Martinez, 2023-2024. c.ghionoiu-martinez@tu-braunschweig.de * * * ----------------------------------------------------------------------------- @@ -9,7 +10,7 @@ * 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) + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- @@ -38,40 +39,35 @@ public: Gnss_Crypto() = default; ~Gnss_Crypto(); Gnss_Crypto(const std::string& pemFilePath, const std::string& merkleTreePath); + + void readPublicKeyFromPEM(const std::string& pemFilePath); + void read_merkle_xml(const std::string& merkleFilePath); + void set_public_key(const std::vector& publickey); bool have_public_key() const; - std::string convert_to_utf8_str(const std::vector& input) const; - std::vector convert_from_hex_str(const std::string& input) const; + bool verify_signature(const std::vector& message, const std::vector& signature) const; std::vector computeSHA256(const std::vector& input) const; std::vector computeSHA3_256(const std::vector& input) const; std::vector computeHMAC_SHA_256(const std::vector& key, const std::vector& input) const; std::vector computeCMAC_AES(const std::vector& key, const std::vector& input) const; - - bool verify_signature(const std::vector& message, const std::vector& signature); - void readPublicKeyFromPEM(const std::string& pemFilePath); - void read_merkle_xml(const std::string& merkleFilePath); std::vector getMerkleRoot(const std::vector>& merkle) const; - std::vector getMerkleRoot() const + + inline std::vector getMerkleRoot() const { return d_x_4_0; } - void set_public_key(const std::vector& publickey); - static std::vector get_public_key(); - private: + std::vector convert_from_hex_str(const std::string& input) const; #if USE_OPENSSL_FALLBACK - bool pubkey_copy(EVP_PKEY* src, EVP_PKEY** dest); - void print_pubkey_hex(EVP_PKEY* pubkey); #if USE_OPENSSL_3 EVP_PKEY* d_PublicKey{}; #else EC_KEY* d_PublicKey = nullptr; #endif -#else + bool pubkey_copy(EVP_PKEY* src, EVP_PKEY** dest); +#else // GnuTLS gnutls_pubkey_t d_PublicKey{}; - void set_ecc_key(const std::vector& pK, const std::vector ecP); - static void my_log_func(int level, const char* msg); - void print_pubkey_hex(gnutls_pubkey_t); + bool convert_raw_to_der_ecdsa(const std::vector& raw_signature, std::vector& der_signature) const; bool pubkey_copy(gnutls_pubkey_t src, gnutls_pubkey_t* dest); #endif std::vector d_x_4_0; From bac36b2df513f16a37b15526a24b937e1ce04146 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 23 Jun 2024 09:49:14 +0200 Subject: [PATCH 2/8] Read .crt files instead of .pem files Define the following global configuration parameters: GNSS-SDR.osnma_public_key (string, by default pointing to ../data/OSNMA_PublicKey_20240115100000_newPKID_1.crt) GNSS-SDR.osnma_merkletree (string, by default pointing to ../data/OSNMA_MerkleTree_20240115100000_newPKID_1.xml) Add logging of OSNMA events Clean public API of Gnss_Crypto class --- src/core/receiver/gnss_flowgraph.cc | 6 +- src/core/system_parameters/CMakeLists.txt | 4 +- src/core/system_parameters/Galileo_OSNMA.h | 3 +- src/core/system_parameters/gnss_crypto.cc | 185 ++++++++++++++++----- src/core/system_parameters/gnss_crypto.h | 8 +- 5 files changed, 159 insertions(+), 47 deletions(-) diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index 4b5f71012..acdea9df2 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -124,9 +124,9 @@ void GNSSFlowgraph::init() if (configuration_->property("Channels_1B.count", 0) > 0) { enable_osnma_rx_ = true; - auto pemFilePath = configuration_->property("GNSS-SDR.OSNMA_pem", PEMFILE_DEFAULT); - auto merKleTreePath = configuration_->property("GNSS-SDR.OSNMA_MerkleTree", MERKLEFILE_DEFAULT); - osnma_rx_ = osnma_msg_receiver_make(pemFilePath, merKleTreePath); + 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); } else { diff --git a/src/core/system_parameters/CMakeLists.txt b/src/core/system_parameters/CMakeLists.txt index 518e64264..607c3702a 100644 --- a/src/core/system_parameters/CMakeLists.txt +++ b/src/core/system_parameters/CMakeLists.txt @@ -29,8 +29,9 @@ set(SYSTEM_PARAMETERS_SOURCES glonass_gnav_utc_model.cc glonass_gnav_navigation_message.cc reed_solomon.cc - osnma_dsm_reader.cc osnma_data.cc + osnma_dsm_reader.cc + osnma_helper.cc ) set(SYSTEM_PARAMETERS_HEADERS @@ -96,7 +97,6 @@ set(SYSTEM_PARAMETERS_HEADERS Galileo_OSNMA.h osnma_data.h osnma_dsm_reader.h - osnma_helper.cc osnma_helper.h ) diff --git a/src/core/system_parameters/Galileo_OSNMA.h b/src/core/system_parameters/Galileo_OSNMA.h index e6530b610..bc919c4b3 100644 --- a/src/core/system_parameters/Galileo_OSNMA.h +++ b/src/core/system_parameters/Galileo_OSNMA.h @@ -161,7 +161,8 @@ const std::unordered_map OSNMA_TABLE_15 = { {std::string("SHA-512"), 1056}}; // key: ECDSA Curve and hash function, value: {l_ds_bits} const std::string PEMFILE_DEFAULT("../data/OSNMA_PublicKey_20240115100000_newPKID_1.pem"); -const std::string MERKLEFILE_DEFAULT("./OSNMA_MerkleTree_20210920133026.xml"); +const std::string CRTFILE_DEFAULT("../data/OSNMA_PublicKey_20240115100000_newPKID_1.crt"); +const std::string MERKLEFILE_DEFAULT("../data/OSNMA_MerkleTree_20240115100000_newPKID_1.xml"); class Mack_lookup { diff --git a/src/core/system_parameters/gnss_crypto.cc b/src/core/system_parameters/gnss_crypto.cc index 12d113ae0..e78e29e39 100644 --- a/src/core/system_parameters/gnss_crypto.cc +++ b/src/core/system_parameters/gnss_crypto.cc @@ -30,6 +30,7 @@ #include #include #include +#include #if USE_OPENSSL_3 #include #include @@ -47,13 +48,23 @@ #include #endif -Gnss_Crypto::Gnss_Crypto(const std::string& pemFilePath, const std::string& merkleTreePath) +#if USE_GLOG_AND_GFLAGS +#include // for DLOG +#else +#include +#endif + + +Gnss_Crypto::Gnss_Crypto(const std::string& certFilePath, const std::string& merkleTreePath) { #if USE_OPENSSL_FALLBACK #else // GnuTLS gnutls_global_init(); #endif - readPublicKeyFromPEM(pemFilePath); + if (!readPublicKeyFromCRT(certFilePath)) + { + readPublicKeyFromPEM(PEMFILE_DEFAULT); + } read_merkle_xml(merkleTreePath); } @@ -69,10 +80,10 @@ Gnss_Crypto::~Gnss_Crypto() } #endif #else // GnuTLS - if (d_PublicKey != NULL) + if (d_PublicKey != nullptr) { gnutls_pubkey_deinit(d_PublicKey); - d_PublicKey = NULL; + d_PublicKey = nullptr; } gnutls_global_deinit(); #endif @@ -145,11 +156,11 @@ void Gnss_Crypto::read_merkle_xml(const std::string& merkleFilePath) std::string signalVersion = galHeader.child("signalVersion").text().get(); std::string dataVersion = galHeader.child("dataVersion").text().get(); - std::cout << " Source: " << source.child_value("mission") << " - " << source.child_value("segment") << " - " << source.child_value("element") << std::endl; - std::cout << " Destination: " << destination.child_value("mission") << " - " << destination.child_value("segment") << " - " << destination.child_value("element") << std::endl; - std::cout << " Issue Date: " << issueDate << std::endl; - std::cout << " Signal Version: " << signalVersion << std::endl; - std::cout << " Data Version: " << dataVersion << std::endl; + LOG(INFO) << "OSNMA Merkletree - Source: " << source.child_value("mission") << " - " << source.child_value("segment") << " - " << source.child_value("element"); + LOG(INFO) << "OSNMA Merkletree - Destination: " << destination.child_value("mission") << " - " << destination.child_value("segment") << " - " << destination.child_value("element"); + LOG(INFO) << "OSNMA Merkletree - Issue Date: " << issueDate; + LOG(INFO) << "OSNMA Merkletree - Signal Version: " << signalVersion; + LOG(INFO) << "OSNMA Merkletree - Data Version: " << dataVersion; // Accessing data from the body pugi::xml_node merkleTree = body.child("MerkleTree"); @@ -157,8 +168,8 @@ void Gnss_Crypto::read_merkle_xml(const std::string& merkleFilePath) int n = std::stoi(merkleTree.child_value("N")); std::string hashFunction = merkleTree.child_value("HashFunction"); - std::cout << " N: " << n << std::endl; - std::cout << " Hash Function: " << hashFunction << std::endl; + LOG(INFO) << "OSNMA Merkletree - N: " << n; + LOG(INFO) << "OSNMA Merkletree - Hash Function: " << hashFunction; for (pugi::xml_node publicKey : merkleTree.children("PublicKey")) { @@ -168,21 +179,21 @@ void Gnss_Crypto::read_merkle_xml(const std::string& merkleFilePath) std::string point = publicKey.child_value("point"); std::string pkType = publicKey.child_value("PKType"); - std::cout << " Public Key: " << i << std::endl; - std::cout << " PKID: " << pkid << std::endl; - std::cout << " Length in Bits: " << lengthInBits << std::endl; - std::cout << " Point: " << point << std::endl; - std::cout << " PK Type: " << pkType << std::endl; + LOG(INFO) << "OSNMA Merkletree - Public Key: " << i; + LOG(INFO) << "OSNMA Merkletree - PKID: " << pkid; + LOG(INFO) << "OSNMA Merkletree - Length in Bits: " << lengthInBits; + LOG(INFO) << "OSNMA Merkletree - Point: " << point; + LOG(INFO) << "OSNMA Merkletree - PK Type: " << pkType; } for (pugi::xml_node treeNode : merkleTree.children("TreeNode")) { int j = std::stoi(treeNode.child_value("j")); int i = std::stoi(treeNode.child_value("i")); int lengthInBits = std::stoi(treeNode.child_value("lengthInBits")); - std::cout << " Node length (bits): " << lengthInBits << std::endl; + LOG(INFO) << "OSNMA Merkletree - Node length (bits): " << lengthInBits; std::string x_ji = treeNode.child_value("x_ji"); - std::cout << " Size string (bytes): " << x_ji.size() << std::endl; - std::cout << " m_" << j << "_" << i << " = " << x_ji << std::endl; + LOG(INFO) << "OSNMA Merkletree - Size string (bytes): " << x_ji.size(); + LOG(INFO) << "OSNMA Merkletree - m_" << j << "_" << i << " = " << x_ji; if (j == 4 && i == 0) { d_x_4_0 = convert_from_hex_str(x_ji); @@ -220,7 +231,8 @@ void Gnss_Crypto::read_merkle_xml(const std::string& merkleFilePath) d_x_0_1 = convert_from_hex_str("AA1A8B68E5DB293106B5BC8806F9790E8ACF8DC2D28A6EF6C1AC7233A9813D3F"); return; } - std::cout << "Merkle Tree successfully read from file " << merkleFilePath << std::endl; + std::cout << "OSNMA Merkle Tree successfully read from file " << merkleFilePath << std::endl; + LOG(INFO) << "OSNMA Merkle Tree successfully read from file " << merkleFilePath; } @@ -451,7 +463,8 @@ void Gnss_Crypto::readPublicKeyFromPEM(const std::string& pemFilePath) BIO_free(bio); if (d_PublicKey == nullptr) { - std::cerr << "OpenSSL: error reading the Public Key from file " << pemFilePath << ". Aborting import" << std::endl; + 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 @@ -464,17 +477,105 @@ void Gnss_Crypto::readPublicKeyFromPEM(const std::string& pemFilePath) if (ret != GNUTLS_E_SUCCESS) { gnutls_pubkey_deinit(pubkey); - std::cerr << "GnuTLS: error reading the Public Key from file " + std::cerr << "GnuTLS: error reading the OSNMA Public Key from file " << pemFilePath << ". Aborting import" << std::endl; std::cerr << "GnuTLS error: " << gnutls_strerror(ret) << std::endl; + LOG(INFO) << "GnuTLS: error reading the OSNMA Public Key from file " << pemFilePath << ". Aborting import"; return; } pubkey_copy(pubkey, &d_PublicKey); gnutls_pubkey_deinit(pubkey); #endif - std::cout << "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; +} + + +bool Gnss_Crypto::readPublicKeyFromCRT(const std::string& crtFilePath) +{ +#if USE_OPENSSL_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 buffer((std::istreambuf_iterator(crtFile)), std::istreambuf_iterator()); + 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 (!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); + BIO_free(bio); + X509_free(cert); +#else // GnuTLS + // Open the .crt file + std::ifstream crtFile(crtFilePath, std::ios::binary); + if (!crtFile.is_open()) + { + // CRT file not found + // If it was not the default, maybe it is a configuration error + if (crtFilePath != CRTFILE_DEFAULT) + { + std::cerr << "File " << crtFilePath << " not found" << std::endl; + } + return false; + } + + std::vector buffer((std::istreambuf_iterator(crtFile)), std::istreambuf_iterator()); + + gnutls_x509_crt_t cert; + gnutls_x509_crt_init(&cert); + int ret = gnutls_x509_crt_import(cert, (const gnutls_datum_t*)&buffer, GNUTLS_X509_FMT_PEM); + if (ret < 0) + { + std::cerr << "Failed to import certificate: " << gnutls_strerror(ret) << std::endl; + gnutls_x509_crt_deinit(cert); + return false; + } + + gnutls_pubkey_t pubkey; + gnutls_pubkey_init(&pubkey); + + ret = gnutls_pubkey_import_x509(pubkey, cert, 0); + if (ret < 0) + { + std::cerr << "Failed to import public key: " << gnutls_strerror(ret) << std::endl; + gnutls_pubkey_deinit(pubkey); + gnutls_x509_crt_deinit(cert); + return false; + } + pubkey_copy(pubkey, &d_PublicKey); + gnutls_x509_crt_deinit(cert); + gnutls_pubkey_deinit(pubkey); +#endif + std::cout << "OSNMA Public key successfully read from file " << crtFilePath << std::endl; + LOG(INFO) << "OSNMA Public key successfully read from file " << crtFilePath; + return true; } @@ -551,18 +652,21 @@ bool Gnss_Crypto::verify_signature(const std::vector& message, const st if (verification == 1) { success = true; + LOG(INFO) << "OpenSSL: OSNMA signature authenticated successfully"; } else { unsigned long errCode = ERR_get_error(); - char* err = ERR_error_string(errCode, NULL); - std::cerr << "OpenSSL: message authentication failed: " << err << std::endl; + char* err = ERR_error_string(errCode, nullptr); + std::cerr << "OpenSSL: OSNMA message authentication failed: " << err << std::endl; + LOG(WARNING) << "OpenSSL: OSNMA message authentication failed: " << err; } #else int verification = ECDSA_verify(0, digest.data(), SHA256_DIGEST_LENGTH, signature.data(), static_cast(signature.size()), d_PublicKey); if (verification == 1) { success = true; + LOG(INFO) << "OpenSSL: OSNMA signature authenticated successfully"; } else if (verification == 0) { @@ -570,9 +674,9 @@ bool Gnss_Crypto::verify_signature(const std::vector& message, const st } else { - std::cerr << "OpenSSL: message authentication failed" << std::endl; + std::cerr << "OpenSSL: OSNMA message authentication failed" << std::endl; + LOG(WARNING) << "OpenSSL: OSNMA message authentication failed"; } - #endif #else // GnuTLS // Convert signature to DER format @@ -590,9 +694,14 @@ bool Gnss_Crypto::verify_signature(const std::vector& message, const st // 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) + if (success) { - std::cerr << "GnuTLS: message authentication failed: " << gnutls_strerror(ret) << std::endl; + 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 return success; @@ -638,8 +747,8 @@ std::vector Gnss_Crypto::getMerkleRoot(const std::vector& publicKey) { #if USE_OPENSSL_FALLBACK - BIO* bio = NULL; - EVP_PKEY* pkey = NULL; + BIO* bio = nullptr; + EVP_PKEY* pkey = nullptr; bio = BIO_new_mem_buf(publicKey.data(), publicKey.size()); if (!bio) { @@ -647,12 +756,13 @@ void Gnss_Crypto::set_public_key(const std::vector& publicKey) return; } - pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); + pkey = PEM_read_bio_PUBKEY(bio, nullptr, nullptr, nullptr); BIO_free(bio); if (!pkey) { - std::cerr << "OpenSSL: error setting the public key." << std::endl; + std::cerr << "OpenSSL: error setting the OSNMA public key." << std::endl; + LOG(INFO) << "OpenSSL: error setting the OSNMA public key."; return; } @@ -677,6 +787,7 @@ void Gnss_Crypto::set_public_key(const std::vector& publicKey) pubkey_copy(pubkey, &d_PublicKey); gnutls_pubkey_deinit(pubkey); #endif + LOG(INFO) << "OSNMA Public Key successfully set up."; } @@ -685,7 +796,7 @@ bool Gnss_Crypto::pubkey_copy(EVP_PKEY* src, EVP_PKEY** dest) { // Open a memory buffer BIO* mem_bio = BIO_new(BIO_s_mem()); - if (mem_bio == NULL) + if (mem_bio == nullptr) { return false; } @@ -703,15 +814,15 @@ bool Gnss_Crypto::pubkey_copy(EVP_PKEY* src, EVP_PKEY** dest) // Create a new memory buffer and load the data into it BIO* mem_bio2 = BIO_new_mem_buf(bio_data, data_len); - if (mem_bio2 == NULL) + if (mem_bio2 == nullptr) { BIO_free(mem_bio); return false; } // Read the public key from the new memory buffer - *dest = PEM_read_bio_PUBKEY(mem_bio2, NULL, NULL, NULL); - if (*dest == NULL) + *dest = PEM_read_bio_PUBKEY(mem_bio2, nullptr, nullptr, nullptr); + if (*dest == nullptr) { BIO_free(mem_bio); BIO_free(mem_bio2); diff --git a/src/core/system_parameters/gnss_crypto.h b/src/core/system_parameters/gnss_crypto.h index 41341d981..e8b41fddd 100644 --- a/src/core/system_parameters/gnss_crypto.h +++ b/src/core/system_parameters/gnss_crypto.h @@ -36,12 +36,9 @@ class Gnss_Crypto { public: - Gnss_Crypto() = default; + Gnss_Crypto(const std::string& certFilePath, const std::string& merkleTreePath); ~Gnss_Crypto(); - Gnss_Crypto(const std::string& pemFilePath, const std::string& merkleTreePath); - void readPublicKeyFromPEM(const std::string& pemFilePath); - void read_merkle_xml(const std::string& merkleFilePath); void set_public_key(const std::vector& publickey); bool have_public_key() const; bool verify_signature(const std::vector& message, const std::vector& signature) const; @@ -57,6 +54,9 @@ public: } private: + void read_merkle_xml(const std::string& merkleFilePath); + void readPublicKeyFromPEM(const std::string& pemFilePath); + bool readPublicKeyFromCRT(const std::string& crtFilePath); std::vector convert_from_hex_str(const std::string& input) const; #if USE_OPENSSL_FALLBACK #if USE_OPENSSL_3 From 8dfd341d2c01dec6b41ee2c5fb88296c0a64a9cd Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 23 Jun 2024 11:10:40 +0200 Subject: [PATCH 3/8] Fix tests building --- src/tests/CMakeLists.txt | 54 +-- src/tests/single_test_main.cc | 3 +- src/tests/test_main.cc | 2 +- .../osnma/gnss_crypto_test.cc | 304 ++++++++------- .../osnma/osnma_msg_receiver_test.cc | 362 ++++++++---------- 5 files changed, 322 insertions(+), 403 deletions(-) diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 97bbac838..8de611f5f 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -1344,52 +1344,14 @@ else() endif() endif() -######################################################### gnss_crypto_test - -if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) - set(GNSS_CRYPTO_TEST_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc - ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc) - - if(USE_CMAKE_TARGET_SOURCES) - add_executable(gnss_crypto_test) - target_sources(gnss_crypto_test PRIVATE ${GNSS_CRYPTO_TEST_SOURCES}) - else() - add_executable(gnss_crypto_test ${GNSS_CRYPTO_TEST_SOURCES}) - endif() - - target_link_libraries(gnss_crypto_test - PRIVATE - Boost::thread - GTest::GTest - GTest::Main - core_system_parameters - Pugixml::pugixml - ) - if(ENABLE_GLOG_AND_GFLAGS) - target_link_libraries(gnss_crypto_test PRIVATE Gflags::gflags Glog::glog) - target_compile_definitions(gnss_crypto_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1) - else() - target_link_libraries(gnss_crypto_test PRIVATE absl::flags absl::flags_parse absl::log $ absl::log_initialize) - endif() - - target_include_directories(gnss_crypto_test - PRIVATE - ${GNSSSDR_SOURCE_DIR}/src/core/system_parameters) - - xcode_remove_warning_duplicates(gnss_crypto_test) # TODO - unsure if needed - - add_test(gnss_crypto_test gnss_crypto_test) - - set_property(TEST gnss_crypto_test PROPERTY TIMEOUT 1) -endif() ######################################################### osnma_msg_receiver_test if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) set(OSNMA_MSG_RECEIVER_TEST_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc - ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/osnma/osnma_msg_receiver_test.cc) + ${CMAKE_CURRENT_SOURCE_DIR}/single_test_main.cc + ${CMAKE_CURRENT_SOURCE_DIR}/unit-tests/signal-processing-blocks/osnma/osnma_msg_receiver_test.cc + ) if(USE_CMAKE_TARGET_SOURCES) add_executable(osnma_msg_receiver_test) @@ -1399,7 +1361,8 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) endif() target_link_libraries(osnma_msg_receiver_test - PRIVATE + PRIVATE + gnss_sdr_flags Boost::thread GTest::GTest GTest::Main @@ -1416,11 +1379,12 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA) add_test(osnma_msg_receiver_test osnma_msg_receiver_test) - set_property(TEST osnma_msg_receiver_test PROPERTY TIMEOUT 1) + set_property(TEST osnma_msg_receiver_test PROPERTY TIMEOUT 30) target_include_directories(osnma_msg_receiver_test - PRIVATE - ${GNSSSDR_SOURCE_DIR}/src/core/system_parameters) + PRIVATE + ${GNSSSDR_SOURCE_DIR}/src/core/system_parameters + ) endif() if(ENABLE_BENCHMARKS) diff --git a/src/tests/single_test_main.cc b/src/tests/single_test_main.cc index beece7581..c0a6e1dee 100644 --- a/src/tests/single_test_main.cc +++ b/src/tests/single_test_main.cc @@ -19,6 +19,7 @@ #include "concurrent_map.h" #include "concurrent_queue.h" #include "gps_acq_assist.h" +#include "gnss_sdr_flags.h" #include #include #include @@ -36,7 +37,6 @@ using namespace google; DECLARE_string(log_dir); #endif #else -#include "gnss_sdr_flags.h" #include #include #include @@ -44,7 +44,6 @@ DECLARE_string(log_dir); #include #include #include - class TestLogSink : public absl::LogSink { public: diff --git a/src/tests/test_main.cc b/src/tests/test_main.cc index 8611d44b8..7990ca258 100644 --- a/src/tests/test_main.cc +++ b/src/tests/test_main.cc @@ -113,7 +113,7 @@ private: #include "unit-tests/signal-processing-blocks/adapter/pass_through_test.cc" #include "unit-tests/signal-processing-blocks/libs/item_type_helpers_test.cc" #include "unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc" -#include "unit-tests/signal-processing-blocks/osnma/osnma_msg_receiver_test.cc" +// #include "unit-tests/signal-processing-blocks/osnma/osnma_msg_receiver_test.cc" #include "unit-tests/signal-processing-blocks/pvt/geohash_test.cc" #include "unit-tests/signal-processing-blocks/pvt/nmea_printer_test.cc" #include "unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc" diff --git a/src/tests/unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc b/src/tests/unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc index a72d86998..a80ef055a 100644 --- a/src/tests/unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc @@ -1,192 +1,186 @@ -#include #include "gnss_crypto.h" +#include class GnssCryptoTest : public ::testing::Test { - }; -TEST(GnssCryptoTest, VerifySignature) { - // "../data/OSNMA_PublicKey_20240115100000_newPKID_1.pem" - std::unique_ptr d_crypto = std::make_unique(); - -// RG example - import crt certificate - result: FAIL -std::vector message = {0x82, 0x10, 0x49, 0x22, 0x04, 0xE0, 0x60, 0x61, 0x0B, 0xDF, 0x26, 0xD7, 0x7B, 0x5B, 0xF8, 0xC9, 0xCB, 0xFC, 0xF7, 0x04, 0x22, 0x08, 0x14, 0x75, 0xFD, 0x44, 0x5D, 0xF0, 0xFF}; -std::vector signature = {0xF8, 0xCD, 0x88, 0x29, 0x9F, 0xA4, 0x60, 0x58, 0x00, 0x20, 0x7B, 0xFE, 0xBE, 0xAC, 0x55, 0x02, 0x40, 0x53, 0xF3, 0x0F, 0x7C, 0x69, 0xB3, 0x5C, 0x15, 0xE6, 0x08, 0x00, 0xAC, 0x3B, 0x6F, 0xE3, 0xED, 0x06, 0x39, 0x95, 0x2F, 0x7B, 0x02, 0x8D, 0x86, 0x86, 0x74, 0x45, 0x96, 0x1F, 0xFE, 0x94, 0xFB, 0x22, 0x6B, 0xFF, 0x70, 0x06, 0xE0, 0xC4, 0x51, 0xEE, 0x3F, 0x87, 0x28, 0xC1, 0x77, 0xFB}; -std::vector publicKey { // PEM format - 1000 bits - 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, - - 0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, - 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x41, 0x37, 0x4C, 0x4F, 0x5A, 0x4C, 0x77, 0x67, 0x65, 0x39, 0x32, 0x4C, 0x78, 0x4E, 0x2B, 0x46, 0x6B, 0x59, 0x66, 0x38, 0x74, 0x6F, 0x59, 0x79, 0x44, 0x57, 0x50, 0x2F, 0x0A, 0x6F, 0x4A, 0x46, 0x42, 0x44, 0x38, 0x46, 0x59, 0x2B, 0x37, - 0x64, 0x35, 0x67, 0x4F, 0x71, 0x49, 0x61, 0x45, 0x32, 0x52, 0x6A, 0x50, 0x41, 0x6E, 0x4B, 0x49, 0x36, 0x38, 0x73, 0x2F, 0x4F, 0x4B, 0x2F, 0x48, 0x50, 0x67, 0x6F, 0x4C, 0x6B, 0x4F, 0x32, 0x69, 0x6A, 0x51, 0x38, 0x78, 0x41, 0x5A, 0x79, 0x44, 0x64, 0x50, 0x42, 0x31, 0x64, 0x48, 0x53, 0x51, 0x3D, 0x3D, - - 0x0A, - 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A } ; - - // own ECDSA-P256 key and message generated and signed and verified successfully with openssl -// std::vector message{0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A }; // Hello world con 0x0A al final. Raw message (unhashed) -// std::vector signature{0x30, 0x45, 0x02, 0x21, 0x00, 0xFB, 0xE6, 0x09, 0x74, 0x5C, 0x12, 0xE8, 0x2C, 0x0C, 0xC9, 0x7A, 0x8E, 0x13, 0x88, 0x87, 0xDA, 0xBF, 0x08, 0x43, 0xF8, 0xC8, 0x93, 0x16, 0x5A, -// 0x0F, 0x7A, 0xA4, 0xBF, 0x4A, 0xE1, 0xE1, 0xDB, 0x02, 0x20, 0x6B, 0xCB, 0x2F, 0x80, 0x69, 0xBB, 0xDE, 0xC9, 0x11, 0x1D, 0x51, 0x2B, 0x9F, 0x61, 0xA0, 0xC1, 0x29, 0xD1, 0x0B, -// 0x58, 0x09, 0x82, 0x58, 0xFC, 0x9E, 0x00, 0xC7, 0xEE, 0xA5, 0xB9, 0xB2, 0x56}; // Hello world hashed and then encrypted with PrK - // raw r and s values -// std::vector signature = { -// 0x00, 0xFB, 0xE6, 0x09, 0x74, 0x5C, 0x12, 0xE8, 0x2C, 0x0C, 0xC9, 0x7A, 0x8E, 0x13, 0x88, 0x87, 0xDA, 0xBF, 0x08, 0x43, 0xF8, -// 0xC8, 0x93, 0x16, 0x5A, 0x0F, 0x7A, 0xA4, 0xBF, 0x4A, 0xE1, 0xE1, 0xDB, 0x02, 0x20, 0x6B, 0xCB, 0x2F, 0x80, 0x69, 0xBB, 0xDE, -// 0xC9, 0x11, 0x1D, 0x51, 0x2B, 0x9F, 0x61, 0xA0, 0xC1, 0x29, 0xD1, 0x0B, 0x58, 0x09, 0x82, 0x58, 0xFC, 0x9E, 0x00, 0xC7, 0xEE, -// 0xA5, 0xB9, 0xB2, 0x56 }; - - // std::vector publicKey{// PK associated to the PrK, in der format ---test -// 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4A, 0xF3, -// 0xEE, 0x3A, 0x94, 0x25, 0x25, 0x3D, 0x55, 0xC2, 0x5A, 0xC2, 0x2D, 0xCF, 0x14, 0x4D, 0x39, 0x0D, 0xB1, 0xFC, 0x7F, 0x31, 0x5A, 0x2A, 0x19, 0xAE, 0x4E, 0xD6, 0xCB, 0xA6, 0x59, -// 0xD6, 0x99, 0x7C, 0xE8, 0xBD, 0x1F, 0x43, 0x34, 0x1C, 0x59, 0xD9, 0xD9, 0xCA, 0xC3, 0xEE, 0x58, 0xE5, 0xEA, 0xD3, 0x55, 0x44, 0xEA, 0x89, 0x71, 0x65, 0xD0, 0x92, 0x72, 0xA2, -// 0xC8, 0x3C, 0x87, 0x5D }; -// std::vector publicKey{ // PK associated to the PrK, in pem format -// 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, -// -// 0x4D, 0x46, -// 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, -// 0x44, 0x51, 0x67, 0x41, 0x45, 0x53, 0x76, 0x50, 0x75, 0x4F, 0x70, 0x51, 0x6C, 0x4A, 0x54, 0x31, 0x56, 0x77, 0x6C, 0x72, 0x43, 0x4C, 0x63, 0x38, 0x55, 0x54, 0x54, 0x6B, 0x4E, -// 0x73, 0x66, 0x78, 0x2F, 0x0A, 0x4D, 0x56, 0x6F, 0x71, 0x47, 0x61, 0x35, 0x4F, 0x31, 0x73, 0x75, 0x6D, 0x57, 0x64, 0x61, 0x5A, 0x66, 0x4F, 0x69, 0x39, 0x48, 0x30, 0x4D, 0x30, -// 0x48, 0x46, 0x6E, 0x5A, 0x32, 0x63, 0x72, 0x44, 0x37, 0x6C, 0x6A, 0x6C, 0x36, 0x74, 0x4E, 0x56, 0x52, 0x4F, 0x71, 0x4A, 0x63, 0x57, 0x58, 0x51, 0x6B, 0x6E, 0x4B, 0x69, 0x79, -// 0x44, 0x79, 0x48, 0x58, 0x51, 0x3D, 0x3D, 0x0A, -// -// 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, -// 0x2D, 0x2D, 0x2D, 0x0A }; - - // own key - GnuTLS error: The curve is unsupported... x192 EC unsupported?? - // std::vector message = {0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64 }; // hello world - // std::vector signature = {0x30, 0x34, 0x02, 0x18, 0x4F, 0xAC, 0x9C, 0x5A, 0x44, 0xCF, 0xFD, 0x42, 0x6A, 0x58, 0x97, 0xA4, 0x94, 0x53, 0x2C, 0x79, 0xD1, 0x7B, 0x8B, 0xF9, 0x93, 0x03, 0xA2, 0xAF, 0x02, 0x18, 0x46, 0xF2, 0xF3, 0xCF, 0x9A, 0x23, 0x39, 0xB4, 0x25, 0x11, 0x89, 0x9A, 0x44, 0x7E, 0x2F, 0xB1, 0xE1, 0x58, 0xAF, 0xCE, 0xC1,0xB4, 0xA1, 0x38 }; - // std::vector publicKey = { - // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x45, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, - // 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x49, 0x44, 0x4D, 0x67, 0x41, 0x45, 0x51, 0x55, 0x61, 0x30, 0x6C, 0x38, 0x4D, 0x35, 0x76, 0x50, 0x58, 0x2B, 0x74, 0x4A, 0x76, 0x63, 0x4C, 0x2B, 0x45, 0x45, 0x4C, 0x34, 0x6E, 0x71, 0x79, 0x75, 0x53, 0x43, 0x0A, 0x4D, 0x4E, 0x46, 0x4A, 0x64, 0x43, 0x5A, 0x62, 0x62, 0x58, - // 0x35, 0x70, 0x4D, 0x36, 0x69, 0x4C, 0x52, 0x53, 0x30, 0x43, 0x51, 0x59, 0x45, 0x67, 0x56, 0x47, 0x51, 0x6B, 0x65, 0x75, 0x74, 0x74, 0x35, 0x78, 0x2F, 0x45, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, - // 0x0A }; - // std::vector ecparam = { - // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x45, 0x43, 0x20, 0x50, 0x41, 0x52, 0x41, 0x4D, 0x45, 0x54, 0x45, 0x52, 0x53, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x4D, 0x42, 0x41, 0x67, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, - // 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x45, 0x43, 0x20, 0x50, 0x41, 0x52, 0x41, 0x4D, 0x45, 0x54, 0x45, 0x52, 0x53, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A }; - - d_crypto->set_public_key(publicKey); - bool result = d_crypto->verify_signature(message, signature); - - ASSERT_TRUE(result); - -//TEST(GnssCryptoTest, sha256Test) -//{ -// std::unique_ptr d_crypto; -// -// auto str = "Hello World!"; -// std::vector input (str, str + strlen(str)); -// -// auto expectedOutputStr = "86933b0b147ac4c010266b99004158fa17937db89a03dd7bb2ca5ef7f43c325a"; -// std::vector expectedOutput(expectedOutputStr, expectedOutputStr + strlen(expectedOutputStr)); -// -// std::vector computedOutput = d_crypto->computeSHA256(input); -// -// ASSERT_TRUE(computedOutput == expectedOutput - } - - -TEST(GnssCryptoTest,VerifyPubKeyImport) +TEST(GnssCryptoTest, VerifySignature) { // "../data/OSNMA_PublicKey_20240115100000_newPKID_1.pem" - std::unique_ptr d_crypto = std::make_unique(); + const std::string fake("fake"); + std::unique_ptr d_crypto = std::make_unique(fake, fake); + + // RG example - import crt certificate - result: FAIL + std::vector message = {0x82, 0x10, 0x49, 0x22, 0x04, 0xE0, 0x60, 0x61, 0x0B, 0xDF, 0x26, 0xD7, 0x7B, 0x5B, 0xF8, 0xC9, 0xCB, 0xFC, 0xF7, 0x04, 0x22, 0x08, 0x14, 0x75, 0xFD, 0x44, 0x5D, 0xF0, 0xFF}; + std::vector signature = {0xF8, 0xCD, 0x88, 0x29, 0x9F, 0xA4, 0x60, 0x58, 0x00, 0x20, 0x7B, 0xFE, 0xBE, 0xAC, 0x55, 0x02, 0x40, 0x53, 0xF3, 0x0F, 0x7C, 0x69, 0xB3, 0x5C, 0x15, 0xE6, 0x08, 0x00, 0xAC, 0x3B, 0x6F, 0xE3, 0xED, 0x06, 0x39, 0x95, 0x2F, 0x7B, 0x02, 0x8D, 0x86, 0x86, 0x74, 0x45, 0x96, 0x1F, 0xFE, 0x94, 0xFB, 0x22, 0x6B, 0xFF, 0x70, 0x06, 0xE0, 0xC4, 0x51, 0xEE, 0x3F, 0x87, 0x28, 0xC1, 0x77, 0xFB}; + std::vector publicKey{// PEM format - 1000 bits + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, + 0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, + 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x41, 0x37, 0x4C, 0x4F, 0x5A, 0x4C, 0x77, 0x67, 0x65, 0x39, 0x32, 0x4C, 0x78, 0x4E, 0x2B, 0x46, 0x6B, 0x59, 0x66, 0x38, 0x74, 0x6F, 0x59, 0x79, 0x44, 0x57, 0x50, 0x2F, 0x0A, 0x6F, 0x4A, 0x46, 0x42, 0x44, 0x38, 0x46, 0x59, 0x2B, 0x37, + 0x64, 0x35, 0x67, 0x4F, 0x71, 0x49, 0x61, 0x45, 0x32, 0x52, 0x6A, 0x50, 0x41, 0x6E, 0x4B, 0x49, 0x36, 0x38, 0x73, 0x2F, 0x4F, 0x4B, 0x2F, 0x48, 0x50, 0x67, 0x6F, 0x4C, 0x6B, 0x4F, 0x32, 0x69, 0x6A, 0x51, 0x38, 0x78, 0x41, 0x5A, 0x79, 0x44, 0x64, 0x50, 0x42, 0x31, 0x64, 0x48, 0x53, 0x51, 0x3D, 0x3D, + 0x0A, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A}; + + // own ECDSA-P256 key and message generated and signed and verified successfully with openssl + // std::vector message{0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A }; // Hello world con 0x0A al final. Raw message (unhashed) + // std::vector signature{0x30, 0x45, 0x02, 0x21, 0x00, 0xFB, 0xE6, 0x09, 0x74, 0x5C, 0x12, 0xE8, 0x2C, 0x0C, 0xC9, 0x7A, 0x8E, 0x13, 0x88, 0x87, 0xDA, 0xBF, 0x08, 0x43, 0xF8, 0xC8, 0x93, 0x16, 0x5A, + // 0x0F, 0x7A, 0xA4, 0xBF, 0x4A, 0xE1, 0xE1, 0xDB, 0x02, 0x20, 0x6B, 0xCB, 0x2F, 0x80, 0x69, 0xBB, 0xDE, 0xC9, 0x11, 0x1D, 0x51, 0x2B, 0x9F, 0x61, 0xA0, 0xC1, 0x29, 0xD1, 0x0B, + // 0x58, 0x09, 0x82, 0x58, 0xFC, 0x9E, 0x00, 0xC7, 0xEE, 0xA5, 0xB9, 0xB2, 0x56}; // Hello world hashed and then encrypted with PrK + // raw r and s values + // std::vector signature = { + // 0x00, 0xFB, 0xE6, 0x09, 0x74, 0x5C, 0x12, 0xE8, 0x2C, 0x0C, 0xC9, 0x7A, 0x8E, 0x13, 0x88, 0x87, 0xDA, 0xBF, 0x08, 0x43, 0xF8, + // 0xC8, 0x93, 0x16, 0x5A, 0x0F, 0x7A, 0xA4, 0xBF, 0x4A, 0xE1, 0xE1, 0xDB, 0x02, 0x20, 0x6B, 0xCB, 0x2F, 0x80, 0x69, 0xBB, 0xDE, + // 0xC9, 0x11, 0x1D, 0x51, 0x2B, 0x9F, 0x61, 0xA0, 0xC1, 0x29, 0xD1, 0x0B, 0x58, 0x09, 0x82, 0x58, 0xFC, 0x9E, 0x00, 0xC7, 0xEE, + // 0xA5, 0xB9, 0xB2, 0x56 }; + + // std::vector publicKey{// PK associated to the PrK, in der format ---test + // 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4A, 0xF3, + // 0xEE, 0x3A, 0x94, 0x25, 0x25, 0x3D, 0x55, 0xC2, 0x5A, 0xC2, 0x2D, 0xCF, 0x14, 0x4D, 0x39, 0x0D, 0xB1, 0xFC, 0x7F, 0x31, 0x5A, 0x2A, 0x19, 0xAE, 0x4E, 0xD6, 0xCB, 0xA6, 0x59, + // 0xD6, 0x99, 0x7C, 0xE8, 0xBD, 0x1F, 0x43, 0x34, 0x1C, 0x59, 0xD9, 0xD9, 0xCA, 0xC3, 0xEE, 0x58, 0xE5, 0xEA, 0xD3, 0x55, 0x44, 0xEA, 0x89, 0x71, 0x65, 0xD0, 0x92, 0x72, 0xA2, + // 0xC8, 0x3C, 0x87, 0x5D }; + // std::vector publicKey{ // PK associated to the PrK, in pem format + // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, + // + // 0x4D, 0x46, + // 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, + // 0x44, 0x51, 0x67, 0x41, 0x45, 0x53, 0x76, 0x50, 0x75, 0x4F, 0x70, 0x51, 0x6C, 0x4A, 0x54, 0x31, 0x56, 0x77, 0x6C, 0x72, 0x43, 0x4C, 0x63, 0x38, 0x55, 0x54, 0x54, 0x6B, 0x4E, + // 0x73, 0x66, 0x78, 0x2F, 0x0A, 0x4D, 0x56, 0x6F, 0x71, 0x47, 0x61, 0x35, 0x4F, 0x31, 0x73, 0x75, 0x6D, 0x57, 0x64, 0x61, 0x5A, 0x66, 0x4F, 0x69, 0x39, 0x48, 0x30, 0x4D, 0x30, + // 0x48, 0x46, 0x6E, 0x5A, 0x32, 0x63, 0x72, 0x44, 0x37, 0x6C, 0x6A, 0x6C, 0x36, 0x74, 0x4E, 0x56, 0x52, 0x4F, 0x71, 0x4A, 0x63, 0x57, 0x58, 0x51, 0x6B, 0x6E, 0x4B, 0x69, 0x79, + // 0x44, 0x79, 0x48, 0x58, 0x51, 0x3D, 0x3D, 0x0A, + // + // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, + // 0x2D, 0x2D, 0x2D, 0x0A }; + + // own key - GnuTLS error: The curve is unsupported... x192 EC unsupported?? + // std::vector message = {0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64 }; // hello world + // std::vector signature = {0x30, 0x34, 0x02, 0x18, 0x4F, 0xAC, 0x9C, 0x5A, 0x44, 0xCF, 0xFD, 0x42, 0x6A, 0x58, 0x97, 0xA4, 0x94, 0x53, 0x2C, 0x79, 0xD1, 0x7B, 0x8B, 0xF9, 0x93, 0x03, 0xA2, 0xAF, 0x02, 0x18, 0x46, 0xF2, 0xF3, 0xCF, 0x9A, 0x23, 0x39, 0xB4, 0x25, 0x11, 0x89, 0x9A, 0x44, 0x7E, 0x2F, 0xB1, 0xE1, 0x58, 0xAF, 0xCE, 0xC1,0xB4, 0xA1, 0x38 }; + // std::vector publicKey = { + // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x45, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, + // 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x49, 0x44, 0x4D, 0x67, 0x41, 0x45, 0x51, 0x55, 0x61, 0x30, 0x6C, 0x38, 0x4D, 0x35, 0x76, 0x50, 0x58, 0x2B, 0x74, 0x4A, 0x76, 0x63, 0x4C, 0x2B, 0x45, 0x45, 0x4C, 0x34, 0x6E, 0x71, 0x79, 0x75, 0x53, 0x43, 0x0A, 0x4D, 0x4E, 0x46, 0x4A, 0x64, 0x43, 0x5A, 0x62, 0x62, 0x58, + // 0x35, 0x70, 0x4D, 0x36, 0x69, 0x4C, 0x52, 0x53, 0x30, 0x43, 0x51, 0x59, 0x45, 0x67, 0x56, 0x47, 0x51, 0x6B, 0x65, 0x75, 0x74, 0x74, 0x35, 0x78, 0x2F, 0x45, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + // 0x0A }; + // std::vector ecparam = { + // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x45, 0x43, 0x20, 0x50, 0x41, 0x52, 0x41, 0x4D, 0x45, 0x54, 0x45, 0x52, 0x53, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x4D, 0x42, 0x41, 0x67, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, + // 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x45, 0x43, 0x20, 0x50, 0x41, 0x52, 0x41, 0x4D, 0x45, 0x54, 0x45, 0x52, 0x53, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A }; + + d_crypto->set_public_key(publicKey); + bool result = d_crypto->verify_signature(message, signature); + + ASSERT_TRUE(result); +} +// TEST(GnssCryptoTest, sha256Test) +//{ +// std::unique_ptr d_crypto; +// +// auto str = "Hello World!"; +// std::vector input (str, str + strlen(str)); +// +// auto expectedOutputStr = "86933b0b147ac4c010266b99004158fa17937db89a03dd7bb2ca5ef7f43c325a"; +// std::vector expectedOutput(expectedOutputStr, expectedOutputStr + strlen(expectedOutputStr)); +// +// std::vector computedOutput = d_crypto->computeSHA256(input); +// +// ASSERT_TRUE(computedOutput == expectedOutput + + +TEST(GnssCryptoTest, VerifyPubKeyImport) +{ + // "../data/OSNMA_PublicKey_20240115100000_newPKID_1.pem" + const std::string fake("fake"); + std::unique_ptr d_crypto = std::make_unique(fake, fake); // RG example - key is raw 520 bits example shown - // std::vector publicKey = { // base64 decoding error - // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, - // - // 0x04, 0x03, 0xB2, 0xCE, 0x64, 0xBC, 0x20, 0x7B, 0xDD, 0x8B, 0xC4, 0xDF, 0x85, 0x91, 0x87, 0xFC, - // 0xB6, 0x86, 0x32, 0x0D, 0x63, 0xFF, 0xA0, 0x91, 0x41, 0x0F, 0xC1, 0x58, 0xFB, 0xB7, 0x79, 0x80, - // 0xEA, 0x88, 0x68, 0x4D, 0x91, 0x8C, 0xF0, 0x27, 0x28, 0x8E, 0xBC, 0xB3, 0xF3, 0x8A, 0xFC, 0x73, - // 0xE0, 0xA0, 0xB9, 0x0E, 0xDA, 0x28, 0xD0, 0xF3, 0x10, 0x19, 0xC8, 0x37, 0x4F, 0x07, 0x57, 0x47, 0x49, - // - // 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A - // - // }; + // std::vector publicKey = { // base64 decoding error + // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, + // + // 0x04, 0x03, 0xB2, 0xCE, 0x64, 0xBC, 0x20, 0x7B, 0xDD, 0x8B, 0xC4, 0xDF, 0x85, 0x91, 0x87, 0xFC, + // 0xB6, 0x86, 0x32, 0x0D, 0x63, 0xFF, 0xA0, 0x91, 0x41, 0x0F, 0xC1, 0x58, 0xFB, 0xB7, 0x79, 0x80, + // 0xEA, 0x88, 0x68, 0x4D, 0x91, 0x8C, 0xF0, 0x27, 0x28, 0x8E, 0xBC, 0xB3, 0xF3, 0x8A, 0xFC, 0x73, + // 0xE0, 0xA0, 0xB9, 0x0E, 0xDA, 0x28, 0xD0, 0xF3, 0x10, 0x19, 0xC8, 0x37, 0x4F, 0x07, 0x57, 0x47, 0x49, + // + // 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A + // + // }; // RG example crt exported and convert PK.pem - key is raw 1000 bits ,..., why mismatch!? does key get truncated? - // std::vector publicKey { - // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, - // 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x41, 0x37, 0x4C, 0x4F, 0x5A, 0x4C, 0x77, 0x67, 0x65, 0x39, 0x32, 0x4C, 0x78, 0x4E, 0x2B, 0x46, 0x6B, 0x59, 0x66, 0x38, 0x74, 0x6F, 0x59, 0x79, 0x44, 0x57, 0x50, 0x2F, 0x0A, 0x6F, 0x4A, 0x46, 0x42, 0x44, 0x38, 0x46, 0x59, 0x2B, 0x37, - // 0x64, 0x35, 0x67, 0x4F, 0x71, 0x49, 0x61, 0x45, 0x32, 0x52, 0x6A, 0x50, 0x41, 0x6E, 0x4B, 0x49, 0x36, 0x38, 0x73, 0x2F, 0x4F, 0x4B, 0x2F, 0x48, 0x50, 0x67, 0x6F, 0x4C, 0x6B, 0x4F, 0x32, 0x69, 0x6A, 0x51, 0x38, 0x78, 0x41, 0x5A, 0x79, 0x44, 0x64, 0x50, 0x42, 0x31, 0x64, 0x48, 0x53, 0x51, 0x3D, 0x3D, 0x0A, - // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A } ; + // std::vector publicKey { + // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, + // 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x41, 0x37, 0x4C, 0x4F, 0x5A, 0x4C, 0x77, 0x67, 0x65, 0x39, 0x32, 0x4C, 0x78, 0x4E, 0x2B, 0x46, 0x6B, 0x59, 0x66, 0x38, 0x74, 0x6F, 0x59, 0x79, 0x44, 0x57, 0x50, 0x2F, 0x0A, 0x6F, 0x4A, 0x46, 0x42, 0x44, 0x38, 0x46, 0x59, 0x2B, 0x37, + // 0x64, 0x35, 0x67, 0x4F, 0x71, 0x49, 0x61, 0x45, 0x32, 0x52, 0x6A, 0x50, 0x41, 0x6E, 0x4B, 0x49, 0x36, 0x38, 0x73, 0x2F, 0x4F, 0x4B, 0x2F, 0x48, 0x50, 0x67, 0x6F, 0x4C, 0x6B, 0x4F, 0x32, 0x69, 0x6A, 0x51, 0x38, 0x78, 0x41, 0x5A, 0x79, 0x44, 0x64, 0x50, 0x42, 0x31, 0x64, 0x48, 0x53, 0x51, 0x3D, 0x3D, 0x0A, + // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A } ; // own ECDSA P 256 public key and own message generated (2024-02-19-Own-Key-ECDSA-openssl) - std::vector publicKey{ // PEM + std::vector publicKey{// PEM 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, - 0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x53, 0x76, 0x50, 0x75, 0x4F, 0x70, 0x51, 0x6C, 0x4A, 0x54, 0x31, 0x56, 0x77, 0x6C, 0x72, 0x43, 0x4C, 0x63, 0x38, 0x55, 0x54, 0x54, 0x6B, 0x4E, 0x73, 0x66, 0x78, 0x2F, 0x0A, 0x4D, 0x56, 0x6F, 0x71, 0x47, 0x61, 0x35, 0x4F, 0x31, 0x73, 0x75, 0x6D, 0x57, 0x64, 0x61, 0x5A, 0x66, 0x4F, 0x69, 0x39, 0x48, 0x30, 0x4D, 0x30, 0x48, 0x46, 0x6E, 0x5A, 0x32, 0x63, 0x72, 0x44, 0x37, 0x6C, 0x6A, 0x6C, 0x36, 0x74, 0x4E, 0x56, 0x52, 0x4F, 0x71, 0x4A, 0x63, 0x57, 0x58, 0x51, 0x6B, 0x6E, 0x4B, 0x69, 0x79, 0x44, 0x79, 0x48, 0x58, 0x51, 0x3D, 0x3D, 0x0A, - 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, - 0x2D, 0x2D, 0x2D, 0x0A }; + 0x2D, 0x2D, 0x2D, 0x0A}; d_crypto->set_public_key(publicKey); ASSERT_TRUE(d_crypto->have_public_key()); - - - - - - // std::vector publicKey = { // DER format -// 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, -// 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x41, 0x37, 0x4C, 0x4F, 0x5A, 0x4C, 0x77, 0x67, 0x65, 0x39, 0x32, 0x4C, 0x78, 0x4E, 0x2B, 0x46, 0x6B, 0x59, 0x66, 0x38, 0x74, 0x6F, 0x59, 0x79, 0x44, 0x57, 0x50, 0x2F, 0x0A, 0x6F, 0x4A, 0x46, 0x42, 0x44, 0x38, 0x46, 0x59, 0x2B, 0x37, -// 0x64, 0x35, 0x67, 0x4F, 0x71, 0x49, 0x61, 0x45, 0x32, 0x52, 0x6A, 0x50, 0x41, 0x6E, 0x4B, 0x49, 0x36, 0x38, 0x73, 0x2F, 0x4F, 0x4B, 0x2F, 0x48, 0x50, 0x67, 0x6F, 0x4C, 0x6B, 0x4F, 0x32, 0x69, 0x6A, 0x51, 0x38, 0x78, 0x41, 0x5A, 0x79, 0x44, 0x64, 0x50, 0x42, 0x31, 0x64, 0x48, 0x53, 0x51, 0x3D, 0x3D, 0x0A, -// 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x30, 0x82, 0x02, 0x6C, 0x30, 0x82, 0x02, 0x12, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x47, 0xC4, 0xF1, 0x43, 0xC3, 0xFA, 0x61, 0xA5, 0x29, 0x4E, 0x63, -// 0xD5, 0x57, 0x2B, 0x01, 0x62, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x37, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x05, 0x45, 0x55, 0x53, 0x50, 0x41, 0x31, 0x18, 0x30, -// 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x45, 0x55, 0x53, 0x50, 0x41, 0x20, 0x4F, 0x53, 0x4E, 0x4D, 0x41, 0x20, 0x49, 0x43, 0x41, 0x30, 0x1E, 0x17, 0x0D, 0x32, 0x33, 0x30, 0x37, 0x32, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x30, 0x5A, 0x17, 0x0D, 0x32, 0x35, 0x30, 0x38, 0x30, 0x38, 0x31, 0x31, 0x33, -// 0x33, 0x30, 0x30, 0x5A, 0x30, 0x3A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x05, 0x45, 0x55, 0x53, 0x50, 0x41, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x12, 0x45, 0x55, 0x53, 0x50, 0x41, -// 0x20, 0x4F, 0x53, 0x4E, 0x4D, 0x41, 0x20, 0x45, 0x45, 0x20, 0x50, 0x4B, 0x52, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x03, 0xB2, 0xCE, 0x64, 0xBC, 0x20, 0x7B, 0xDD, 0x8B, 0xC4, 0xDF, -// 0x85, 0x91, 0x87, 0xFC, 0xB6, 0x86, 0x32, 0x0D, 0x63, 0xFF, 0xA0, 0x91, 0x41, 0x0F, 0xC1, 0x58, 0xFB, 0xB7, 0x79, 0x80, 0xEA, 0x88, 0x68, 0x4D, 0x91, 0x8C, 0xF0, 0x27, 0x28, 0x8E, 0xBC, 0xB3, 0xF3, 0x8A, 0xFC, 0x73, 0xE0, 0xA0, 0xB9, 0x0E, 0xDA, 0x28, 0xD0, 0xF3, 0x10, 0x19, 0xC8, 0x37, 0x4F, 0x07, 0x57, -// 0x47, 0x49, 0xA3, 0x81, 0xFC, 0x30, 0x81, 0xF9, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0x6A, 0x22, 0x16, 0x58, 0x9B, 0x23, 0xC9, 0x43, 0x41, 0x3C, 0xB6, 0xF8, 0x9D, 0x93, 0x0F, 0xE0, 0xFE, 0x6A, 0x3C, 0x54, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, -// 0x14, 0x20, 0xC0, 0x54, 0x85, 0xAF, 0x82, 0xAE, 0x96, 0x3C, 0xBC, 0xDF, 0xC1, 0xB9, 0x05, 0xDE, 0xD7, 0x46, 0x72, 0x32, 0xA3, 0x30, 0x63, 0x06, 0x03, 0x55, 0x1D, 0x20, 0x04, 0x5C, 0x30, 0x5A, 0x30, 0x4E, 0x06, 0x0B, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0xD5, 0x11, 0x01, 0x01, 0x01, 0x30, 0x3F, 0x30, 0x3D, -// 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x31, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x67, 0x73, 0x63, 0x2D, 0x65, 0x75, 0x72, 0x6F, 0x70, 0x61, 0x2E, 0x65, 0x75, 0x2F, 0x67, 0x73, 0x63, 0x2D, 0x70, 0x72, 0x6F, 0x64, 0x75, 0x63, 0x74, 0x73, 0x2F, -// 0x4F, 0x53, 0x4E, 0x4D, 0x41, 0x2F, 0x50, 0x4B, 0x49, 0x2F, 0x30, 0x08, 0x06, 0x06, 0x04, 0x00, 0x8F, 0x7A, 0x01, 0x02, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1D, 0x1F, 0x04, 0x3B, 0x30, 0x39, 0x30, 0x37, 0xA0, 0x35, 0xA0, 0x33, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, -// 0x67, 0x73, 0x63, 0x2D, 0x65, 0x75, 0x72, 0x6F, 0x70, 0x61, 0x2E, 0x65, 0x75, 0x2F, 0x67, 0x73, 0x63, 0x2D, 0x70, 0x72, 0x6F, 0x64, 0x75, 0x63, 0x74, 0x73, 0x2F, 0x4F, 0x53, 0x4E, 0x4D, 0x41, 0x2F, 0x50, 0x4B, 0x49, 0x2F, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, 0x02, -// 0x07, 0x80, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x21, 0x00, 0xE9, 0xBB, 0x90, 0x8E, 0xE5, 0x0C, 0xF3, 0xDA, 0x57, 0x71, 0xE3, 0xD0, 0xD2, 0xEA, 0xAC, 0x1B, 0x00, 0xF3, 0x51, 0xE9, 0xD8, 0xBB, 0x0A, 0xB2, 0x4C, 0x8A, 0x65, 0x52, 0x79, -// 0x9F, 0x43, 0xF6, 0x02, 0x20, 0x10, 0x65, 0x2F, 0x6A, 0xF8, 0x26, 0x20, 0x42, 0xFF, 0x09, 0x6B, 0xD0, 0x8D, 0x0B, 0x75, 0x15, 0x24, 0xBF, 0xE4, 0xFE, 0x60, 0xC3, 0x6E, 0x2D, 0x31, 0x32, 0xED, 0x65, 0x6C, 0x5C, 0x8B, 0x14 }; - -// std::vector publicKey= { // PEM format -// 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, -// 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x41, 0x37, 0x4C, 0x4F, 0x5A, 0x4C, 0x77, 0x67, 0x65, 0x39, 0x32, 0x4C, 0x78, 0x4E, 0x2B, 0x46, 0x6B, 0x59, 0x66, 0x38, 0x74, 0x6F, 0x59, 0x79, 0x44, 0x57, 0x50, 0x2F, 0x0A, 0x6F, 0x4A, 0x46, 0x42, 0x44, 0x38, 0x46, 0x59, 0x2B, 0x37, -// 0x64, 0x35, 0x67, 0x4F, 0x71, 0x49, 0x61, 0x45, 0x32, 0x52, 0x6A, 0x50, 0x41, 0x6E, 0x4B, 0x49, 0x36, 0x38, 0x73, 0x2F, 0x4F, 0x4B, 0x2F, 0x48, 0x50, 0x67, 0x6F, 0x4C, 0x6B, 0x4F, 0x32, 0x69, 0x6A, 0x51, 0x38, 0x78, 0x41, 0x5A, 0x79, 0x44, 0x64, 0x50, 0x42, 0x31, 0x64, 0x48, 0x53, 0x51, 0x3D, 0x3D, 0x0A, -// 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A }; + // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, + // 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x41, 0x37, 0x4C, 0x4F, 0x5A, 0x4C, 0x77, 0x67, 0x65, 0x39, 0x32, 0x4C, 0x78, 0x4E, 0x2B, 0x46, 0x6B, 0x59, 0x66, 0x38, 0x74, 0x6F, 0x59, 0x79, 0x44, 0x57, 0x50, 0x2F, 0x0A, 0x6F, 0x4A, 0x46, 0x42, 0x44, 0x38, 0x46, 0x59, 0x2B, 0x37, + // 0x64, 0x35, 0x67, 0x4F, 0x71, 0x49, 0x61, 0x45, 0x32, 0x52, 0x6A, 0x50, 0x41, 0x6E, 0x4B, 0x49, 0x36, 0x38, 0x73, 0x2F, 0x4F, 0x4B, 0x2F, 0x48, 0x50, 0x67, 0x6F, 0x4C, 0x6B, 0x4F, 0x32, 0x69, 0x6A, 0x51, 0x38, 0x78, 0x41, 0x5A, 0x79, 0x44, 0x64, 0x50, 0x42, 0x31, 0x64, 0x48, 0x53, 0x51, 0x3D, 0x3D, 0x0A, + // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x30, 0x82, 0x02, 0x6C, 0x30, 0x82, 0x02, 0x12, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x47, 0xC4, 0xF1, 0x43, 0xC3, 0xFA, 0x61, 0xA5, 0x29, 0x4E, 0x63, + // 0xD5, 0x57, 0x2B, 0x01, 0x62, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x37, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x05, 0x45, 0x55, 0x53, 0x50, 0x41, 0x31, 0x18, 0x30, + // 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x45, 0x55, 0x53, 0x50, 0x41, 0x20, 0x4F, 0x53, 0x4E, 0x4D, 0x41, 0x20, 0x49, 0x43, 0x41, 0x30, 0x1E, 0x17, 0x0D, 0x32, 0x33, 0x30, 0x37, 0x32, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x30, 0x5A, 0x17, 0x0D, 0x32, 0x35, 0x30, 0x38, 0x30, 0x38, 0x31, 0x31, 0x33, + // 0x33, 0x30, 0x30, 0x5A, 0x30, 0x3A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x05, 0x45, 0x55, 0x53, 0x50, 0x41, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x12, 0x45, 0x55, 0x53, 0x50, 0x41, + // 0x20, 0x4F, 0x53, 0x4E, 0x4D, 0x41, 0x20, 0x45, 0x45, 0x20, 0x50, 0x4B, 0x52, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x03, 0xB2, 0xCE, 0x64, 0xBC, 0x20, 0x7B, 0xDD, 0x8B, 0xC4, 0xDF, + // 0x85, 0x91, 0x87, 0xFC, 0xB6, 0x86, 0x32, 0x0D, 0x63, 0xFF, 0xA0, 0x91, 0x41, 0x0F, 0xC1, 0x58, 0xFB, 0xB7, 0x79, 0x80, 0xEA, 0x88, 0x68, 0x4D, 0x91, 0x8C, 0xF0, 0x27, 0x28, 0x8E, 0xBC, 0xB3, 0xF3, 0x8A, 0xFC, 0x73, 0xE0, 0xA0, 0xB9, 0x0E, 0xDA, 0x28, 0xD0, 0xF3, 0x10, 0x19, 0xC8, 0x37, 0x4F, 0x07, 0x57, + // 0x47, 0x49, 0xA3, 0x81, 0xFC, 0x30, 0x81, 0xF9, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0x6A, 0x22, 0x16, 0x58, 0x9B, 0x23, 0xC9, 0x43, 0x41, 0x3C, 0xB6, 0xF8, 0x9D, 0x93, 0x0F, 0xE0, 0xFE, 0x6A, 0x3C, 0x54, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, + // 0x14, 0x20, 0xC0, 0x54, 0x85, 0xAF, 0x82, 0xAE, 0x96, 0x3C, 0xBC, 0xDF, 0xC1, 0xB9, 0x05, 0xDE, 0xD7, 0x46, 0x72, 0x32, 0xA3, 0x30, 0x63, 0x06, 0x03, 0x55, 0x1D, 0x20, 0x04, 0x5C, 0x30, 0x5A, 0x30, 0x4E, 0x06, 0x0B, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0xD5, 0x11, 0x01, 0x01, 0x01, 0x30, 0x3F, 0x30, 0x3D, + // 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x31, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x67, 0x73, 0x63, 0x2D, 0x65, 0x75, 0x72, 0x6F, 0x70, 0x61, 0x2E, 0x65, 0x75, 0x2F, 0x67, 0x73, 0x63, 0x2D, 0x70, 0x72, 0x6F, 0x64, 0x75, 0x63, 0x74, 0x73, 0x2F, + // 0x4F, 0x53, 0x4E, 0x4D, 0x41, 0x2F, 0x50, 0x4B, 0x49, 0x2F, 0x30, 0x08, 0x06, 0x06, 0x04, 0x00, 0x8F, 0x7A, 0x01, 0x02, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1D, 0x1F, 0x04, 0x3B, 0x30, 0x39, 0x30, 0x37, 0xA0, 0x35, 0xA0, 0x33, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, + // 0x67, 0x73, 0x63, 0x2D, 0x65, 0x75, 0x72, 0x6F, 0x70, 0x61, 0x2E, 0x65, 0x75, 0x2F, 0x67, 0x73, 0x63, 0x2D, 0x70, 0x72, 0x6F, 0x64, 0x75, 0x63, 0x74, 0x73, 0x2F, 0x4F, 0x53, 0x4E, 0x4D, 0x41, 0x2F, 0x50, 0x4B, 0x49, 0x2F, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, 0x02, + // 0x07, 0x80, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x21, 0x00, 0xE9, 0xBB, 0x90, 0x8E, 0xE5, 0x0C, 0xF3, 0xDA, 0x57, 0x71, 0xE3, 0xD0, 0xD2, 0xEA, 0xAC, 0x1B, 0x00, 0xF3, 0x51, 0xE9, 0xD8, 0xBB, 0x0A, 0xB2, 0x4C, 0x8A, 0x65, 0x52, 0x79, + // 0x9F, 0x43, 0xF6, 0x02, 0x20, 0x10, 0x65, 0x2F, 0x6A, 0xF8, 0x26, 0x20, 0x42, 0xFF, 0x09, 0x6B, 0xD0, 0x8D, 0x0B, 0x75, 0x15, 0x24, 0xBF, 0xE4, 0xFE, 0x60, 0xC3, 0x6E, 0x2D, 0x31, 0x32, 0xED, 0x65, 0x6C, 0x5C, 0x8B, 0x14 }; + // std::vector publicKey= { // PEM format + // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, + // 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x41, 0x37, 0x4C, 0x4F, 0x5A, 0x4C, 0x77, 0x67, 0x65, 0x39, 0x32, 0x4C, 0x78, 0x4E, 0x2B, 0x46, 0x6B, 0x59, 0x66, 0x38, 0x74, 0x6F, 0x59, 0x79, 0x44, 0x57, 0x50, 0x2F, 0x0A, 0x6F, 0x4A, 0x46, 0x42, 0x44, 0x38, 0x46, 0x59, 0x2B, 0x37, + // 0x64, 0x35, 0x67, 0x4F, 0x71, 0x49, 0x61, 0x45, 0x32, 0x52, 0x6A, 0x50, 0x41, 0x6E, 0x4B, 0x49, 0x36, 0x38, 0x73, 0x2F, 0x4F, 0x4B, 0x2F, 0x48, 0x50, 0x67, 0x6F, 0x4C, 0x6B, 0x4F, 0x32, 0x69, 0x6A, 0x51, 0x38, 0x78, 0x41, 0x5A, 0x79, 0x44, 0x64, 0x50, 0x42, 0x31, 0x64, 0x48, 0x53, 0x51, 0x3D, 0x3D, 0x0A, + // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A }; } + // Unit test for computeHMAC_SHA_256 function. -TEST(GnssCryptoTest, TestComputeHMACSHA256) { // key and message generated with openssl - std::unique_ptr d_crypto = std::make_unique(); +TEST(GnssCryptoTest, TestComputeHMACSHA256) +{ + // key and message generated with openssl + const std::string fake("fake"); + std::unique_ptr d_crypto = std::make_unique(fake, fake); std::vector key = { - 0x24, 0x24, 0x3B, 0x76, 0xF9, 0x14, 0xB1, 0xA7, - 0x7D, 0x48, 0xE7, 0xF1, 0x48, 0x0C, 0xC2, 0x98, - 0xEB, 0x62, 0x3E, 0x95, 0x6B, 0x2B, 0xCE, 0xA3, - 0xB4, 0xD4, 0xDB, 0x31, 0xEE, 0x96, 0xAB, 0xFA }; + 0x24, 0x24, 0x3B, 0x76, 0xF9, 0x14, 0xB1, 0xA7, + 0x7D, 0x48, 0xE7, 0xF1, 0x48, 0x0C, 0xC2, 0x98, + 0xEB, 0x62, 0x3E, 0x95, 0x6B, 0x2B, 0xCE, 0xA3, + 0xB4, 0xD4, 0xDB, 0x31, 0xEE, 0x96, 0xAB, 0xFA}; - std::vector message{0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A }; // Hello world con 0x0A + std::vector message{0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; // Hello world con 0x0A std::vector expected_output = { - 0xC3, 0x51, 0xF6, 0xFD, 0xDD, 0xC9, 0x8B, 0x41, - 0xD6, 0xF4, 0x77, 0x6D, 0xAC, 0xE8, 0xE0, 0x14, - 0xB2, 0x7A, 0xCC, 0x22, 0x00, 0xAA, 0xD2, 0x37, - 0xD0, 0x79, 0x06, 0x12, 0x83, 0x40, 0xB7, 0xA6 }; - + 0xC3, 0x51, 0xF6, 0xFD, 0xDD, 0xC9, 0x8B, 0x41, + 0xD6, 0xF4, 0x77, 0x6D, 0xAC, 0xE8, 0xE0, 0x14, + 0xB2, 0x7A, 0xCC, 0x22, 0x00, 0xAA, 0xD2, 0x37, + 0xD0, 0x79, 0x06, 0x12, 0x83, 0x40, 0xB7, 0xA6}; std::vector output = d_crypto->computeHMAC_SHA_256(key, message); ASSERT_EQ(expected_output, output); - - } -TEST(GnssCryptoTest, TestComputeHMACSHA256_m0) { // key and message generated from RG A.6.5.1 - std::unique_ptr d_crypto = std::make_unique(); - std::vector key = { // RG K4 @ 345690 + +TEST(GnssCryptoTest, TestComputeHMACSHA256_m0) +{ // key and message generated from RG A.6.5.1 + const std::string fake("fake"); + std::unique_ptr d_crypto = std::make_unique(fake, fake); + std::vector key = {// RG K4 @ 345690 0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73}; @@ -207,15 +201,18 @@ TEST(GnssCryptoTest, TestComputeHMACSHA256_m0) { // key and message generated fr ASSERT_EQ(expected_output, output); } -TEST(GnssCryptoTest, TestComputeHMACSHA256_adkd4) { // key and message generated from RG A.6.5.2 - std::unique_ptr d_crypto = std::make_unique(); - std::vector key = { // RG K4 @ 345690 + +TEST(GnssCryptoTest, TestComputeHMACSHA256_adkd4) +{ // key and message generated from RG A.6.5.2 + const std::string fake("fake"); + std::unique_ptr d_crypto = std::make_unique(fake, fake); + std::vector key = {// RG K4 @ 345690 0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73}; std::vector message{ 0x02, 0x02, 0x4E, 0x05, 0x46, 0x3C, 0x03, 0xBF, - 0xFF, 0xFF, 0xFF, 0xC0, 0x00,0x00, 0x44, 0x92, 0x38, + 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x44, 0x92, 0x38, 0x22, 0x78, 0x97, 0xFD, 0xEF, 0xF9, 0x30, 0x40}; std::vector expected_output = { @@ -223,7 +220,6 @@ TEST(GnssCryptoTest, TestComputeHMACSHA256_adkd4) { // key and message generated 0xE6, 0x3F, 0xB7, 0xF4, 0xF5, 0x4D, 0x44, 0xAB, 0xEE, 0x4D, 0xCE, 0xB9, 0x3D, 0xCF, 0x65, 0xCB, 0x3A, 0x5B, 0x81, 0x4A, 0x34, 0xE9}; - std::vector output = d_crypto->computeHMAC_SHA_256(key, message); ASSERT_EQ(expected_output, output); diff --git a/src/tests/unit-tests/signal-processing-blocks/osnma/osnma_msg_receiver_test.cc b/src/tests/unit-tests/signal-processing-blocks/osnma/osnma_msg_receiver_test.cc index 226e8e892..c54d25580 100644 --- a/src/tests/unit-tests/signal-processing-blocks/osnma/osnma_msg_receiver_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/osnma/osnma_msg_receiver_test.cc @@ -2,7 +2,6 @@ #include #include #include -#include #include #include @@ -25,26 +24,26 @@ protected: std::string page_even; OSNMA_msg osnma_msg{}; std::array nma_position_filled; - uint32_t d_GST_SIS{}; // 16 AUG 2023 05 00 01 + uint32_t d_GST_SIS{}; // 16 AUG 2023 05 00 01 uint32_t TOW{}; uint32_t WN{}; - std::tm GST_START_EPOCH = {0, 0, 0, 22, 8 - 1, 1999 - 1900, 0}; // months start with 0 and years since 1900 in std::tm - const uint32_t LEAP_SECONDS = 0;//13 + 5; + std::tm GST_START_EPOCH = {0, 0, 0, 22, 8 - 1, 1999 - 1900, 0}; // months start with 0 and years since 1900 in std::tm + const uint32_t LEAP_SECONDS = 0; // 13 + 5; void set_time(std::tm& input); -// std::string log_name {"CONFIG1-2023-08-23-PKID1-OSNMA"}; - std::string log_name {"CONFIG2-2023-07-27-PKID2-MT2-OSNMA"}; - void initializeGoogleLog(); + // std::string log_name {"CONFIG1-2023-08-23-PKID1-OSNMA"}; + std::string log_name{"CONFIG2-2023-07-27-PKID2-MT2-OSNMA"}; + // void initializeGoogleLog(); void SetUp() override { - flag_CRC_test = false; // TODO what for? + flag_CRC_test = false; // TODO what for? page_even = ""; -// std::tm input_time = {0, 0, 5, 16, 8 - 1, 2023 - 1900, 0}; + // std::tm input_time = {0, 0, 5, 16, 8 - 1, 2023 - 1900, 0}; std::tm input_time = {0, 0, 0, 27, 7 - 1, 2023 - 1900, 0}; set_time(input_time); -// std::string pemFilePath = "/home/cgm/CLionProjects/osnma/data/OSNMA_PublicKey_20230803105952_newPKID_1.pem"; -// std::string merkleFilePath = "/home/cgm/CLionProjects/osnma/data/OSNMA_MerkleTree_20230803105953_newPKID_1.xml"; + // std::string pemFilePath = "/home/cgm/CLionProjects/osnma/data/OSNMA_PublicKey_20230803105952_newPKID_1.pem"; + // std::string merkleFilePath = "/home/cgm/CLionProjects/osnma/data/OSNMA_MerkleTree_20230803105953_newPKID_1.xml"; std::string pemFilePath = "/home/cgm/CLionProjects/osnma/data/OSNMA_PublicKey_20230720113300_newPKID_2.pem"; std::string merkleFilePath = "/home/cgm/CLionProjects/osnma/data/OSNMA_MerkleTree_20230720113300_newPKID_2.xml"; osnma = osnma_msg_receiver_make(pemFilePath, merkleFilePath); @@ -58,121 +57,120 @@ public: }; -TEST_F(OsnmaMsgReceiverTest, TeslaKeyVerification) { +TEST_F(OsnmaMsgReceiverTest, TeslaKeyVerification) +{ // Arrange // ---------- osnma->d_tesla_key_verified = false; - osnma->d_osnma_data.d_dsm_kroot_message.kroot = {0x5B, 0xF8, 0xC9, 0xCB, 0xFC, 0xF7, 0x04, 0x22, 0x08, 0x14, 0x75, 0xFD, 0x44, 0x5D, 0xF0, 0xFF}; // Kroot, TOW 345570 GST_0 - 30 - osnma->d_osnma_data.d_dsm_kroot_message.ks = 4; // TABLE 10 --> 128 bits + osnma->d_osnma_data.d_dsm_kroot_message.kroot = {0x5B, 0xF8, 0xC9, 0xCB, 0xFC, 0xF7, 0x04, 0x22, 0x08, 0x14, 0x75, 0xFD, 0x44, 0x5D, 0xF0, 0xFF}; // Kroot, TOW 345570 GST_0 - 30 + osnma->d_osnma_data.d_dsm_kroot_message.ks = 4; // TABLE 10 --> 128 bits osnma->d_osnma_data.d_dsm_kroot_message.alpha = 0x610BDF26D77B; // local_time_verification would do this operation. TODO - eliminate duplication. osnma->d_GST_SIS = (1248 & 0x00000FFF) << 20 | (345630 & 0x000FFFFF); - osnma->d_GST_0 = ((1248 & 0x00000FFF) << 20 | (345600 & 0x000FFFFF)); // applicable time (GST_Kroot + 30) - osnma->d_receiver_time = osnma->d_GST_0 + 30 * std::floor((osnma->d_GST_SIS - osnma->d_GST_0) / 30); // Eq. 3 R.G.//345630; + osnma->d_GST_0 = ((1248 & 0x00000FFF) << 20 | (345600 & 0x000FFFFF)); // applicable time (GST_Kroot + 30) + osnma->d_receiver_time = osnma->d_GST_0 + 30 * std::floor((osnma->d_GST_SIS - osnma->d_GST_0) / 30); // Eq. 3 R.G.//345630; - osnma->d_tesla_keys.insert((std::pair>(345600,{0xEF, 0xF9, 0x99, 0x04, 0x0E, 0x19, 0xB5, 0x70, 0x83, 0x50, 0x60, 0xBE, 0xBD, 0x23, 0xED, 0x92}))); // K1, not needed, just for reference. - std::vector key = {0x2D, 0xC3, 0xA3, 0xCD, 0xB1, 0x17, 0xFA, 0xAD, 0xB8, 0x3B, 0x5F, 0x0B, 0x6F, 0xEA, 0x88, 0xEB}; // K2 + osnma->d_tesla_keys.insert((std::pair>(345600, {0xEF, 0xF9, 0x99, 0x04, 0x0E, 0x19, 0xB5, 0x70, 0x83, 0x50, 0x60, 0xBE, 0xBD, 0x23, 0xED, 0x92}))); // K1, not needed, just for reference. + std::vector key = {0x2D, 0xC3, 0xA3, 0xCD, 0xB1, 0x17, 0xFA, 0xAD, 0xB8, 0x3B, 0x5F, 0x0B, 0x6F, 0xEA, 0x88, 0xEB}; // K2 uint32_t TOW = 345630; - - - // Act // ---------- bool result = osnma->verify_tesla_key(key, TOW); - - - - // Assert // ---------- ASSERT_TRUE(result); - } + TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) { - initializeGoogleLog(); + // initializeGoogleLog(); // Arrange // ---------- -// std::vector testVectors = readTestVectorsFromFile("/home/cgm/CLionProjects/osnma/data/16_AUG_2023_GST_05_00_01.csv"); + // std::vector testVectors = readTestVectorsFromFile("/home/cgm/CLionProjects/osnma/data/16_AUG_2023_GST_05_00_01.csv"); std::vector testVectors = readTestVectorsFromFile("/home/cgm/CLionProjects/osnma/data/27_JUL_2023_GST_00_00_01.csv"); - if (testVectors.empty()){ + if (testVectors.empty()) + { ASSERT_TRUE(false); } bool end_of_hex_stream{false}; int offset_byte{0}; - int byte_index{0}; // index containing the last byte position of the hex stream that was retrieved. Takes advantage that all TVs have same size - const int SIZE_PAGE_BYTES{240/8}; // total bytes of a page - const int SIZE_SUBFRAME_PAGES{15}; // number of pages of a subframe - const int SIZE_SUBFRAME_BYTES{SIZE_PAGE_BYTES*SIZE_SUBFRAME_PAGES}; // total bytes of a subframe - const int DURATION_SUBFRAME{30}; // duration of a subframe, in seconds + int byte_index{0}; // index containing the last byte position of the hex stream that was retrieved. Takes advantage that all TVs have same size + const int SIZE_PAGE_BYTES{240 / 8}; // total bytes of a page + const int SIZE_SUBFRAME_PAGES{15}; // number of pages of a subframe + const int SIZE_SUBFRAME_BYTES{SIZE_PAGE_BYTES * SIZE_SUBFRAME_PAGES}; // total bytes of a subframe + const int DURATION_SUBFRAME{30}; // duration of a subframe, in seconds const int DUMMY_PAGE{63}; bool flag_dummy_page{false}; - std::cout << "OsnmaTestVectorsSimulation:" << " d_GST_SIS= " << d_GST_SIS - << ", TOW=" << TOW - << ", WN=" << WN << std::endl; - - - + std::cout << "OsnmaTestVectorsSimulation:" + << " d_GST_SIS= " << d_GST_SIS + << ", TOW=" << TOW + << ", WN=" << WN << std::endl; // Act // ---------- // loop over all bytes of data. Note: all TestVectors have same amount of data. - while (end_of_hex_stream == false){ + while (end_of_hex_stream == false) + { // loop over all SVs, extract a subframe - for(const TestVector& tv : testVectors) { // loop over all SVs, extract a subframe - std::cout << "OsnmaTestVectorsSimulation: SVID (PRN_a) "<< tv.svId << std::endl; + for (const TestVector& tv : testVectors) + { // loop over all SVs, extract a subframe + std::cout << "OsnmaTestVectorsSimulation: SVID (PRN_a) " << tv.svId << std::endl; auto osnmaMsg_sptr = std::make_shared(); std::array hkroot{}; std::array mack{}; - byte_index = offset_byte; // reset byte_index to the offset position for the next test vector. Offset is updated at the end of each Subframe (every 30 s or 450 Bytes) - std::map> words; // structure containing and + byte_index = offset_byte; // reset byte_index to the offset position for the next test vector. Offset is updated at the end of each Subframe (every 30 s or 450 Bytes) + std::map> words; // structure containing and - for (int idx = 0; idx < SIZE_SUBFRAME_PAGES; ++idx) // extract all pages of a subframe + for (int idx = 0; idx < SIZE_SUBFRAME_PAGES; ++idx) // extract all pages of a subframe { // extract bytes of complete page (odd+even) -- extract SIZE_PAGE from tv.navBits, starting from byte_index - std::vector page_bytes = extract_page_bytes(tv,byte_index,SIZE_PAGE_BYTES); - if(page_bytes.empty()){ - std::cout<< "OsnmaTestVectorsSimulation: end of TestVectors \n" << "byte_index="< data_k(even_page.substr(2,112)); - std::bitset<16> data_j(odd_page.substr(2,16)); + std::bitset<112> data_k(even_page.substr(2, 112)); + std::bitset<16> data_j(odd_page.substr(2, 16)); std::bitset<112> shifted_data_k = data_k; -// uint8_t word_type = 0; -// for(int i = 0; i < 6; ++i) { -// word_type |= (data_k[104 + i] << i); -// } - uint8_t word_type = static_cast((shifted_data_k >>= 106).to_ulong()); // word type is the first 6 bits of the word - std::cout<< "OsnmaTestVectorsSimulation: received Word "<< static_cast(word_type) << std::endl; - if( (word_type >= 1 && word_type <=5) || word_type == 6 || word_type == 10) + // uint8_t word_type = 0; + // for(int i = 0; i < 6; ++i) { + // word_type |= (data_k[104 + i] << i); + // } + uint8_t word_type = static_cast((shifted_data_k >>= 106).to_ulong()); // word type is the first 6 bits of the word + std::cout << "OsnmaTestVectorsSimulation: received Word " << static_cast(word_type) << std::endl; + if ((word_type >= 1 && word_type <= 5) || word_type == 6 || word_type == 10) { // store raw word std::bitset<128> data_combined(data_k.to_string() + data_j.to_string()); words[word_type] = data_combined; } - if(word_type == DUMMY_PAGE) + if (word_type == DUMMY_PAGE) flag_dummy_page = true; // place it into osnma object. std::bitset<40> osnmaBits(odd_page.substr(18, 40)); @@ -185,12 +183,13 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) byte_index += SIZE_PAGE_BYTES; } - std::cout<< "----------" << std::endl; - if(end_of_hex_stream) + std::cout << "----------" << std::endl; + if (end_of_hex_stream) break; - if(flag_dummy_page){ + if (flag_dummy_page) + { flag_dummy_page = false; - continue; // skip this SV + continue; // skip this SV } // Fill osnma object @@ -198,8 +197,8 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) osnmaMsg_sptr->mack = mack; osnmaMsg_sptr->TOW_sf0 = d_GST_SIS & 0x000FFFFF; - osnmaMsg_sptr->WN_sf0 = (d_GST_SIS & 0xFFF00000) >> 20 ; - osnmaMsg_sptr->PRN = tv.svId; // PRNa + osnmaMsg_sptr->WN_sf0 = (d_GST_SIS & 0xFFF00000) >> 20; + osnmaMsg_sptr->PRN = tv.svId; // PRNa // TODO - refactor this logic, currently it is split @@ -210,14 +209,14 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) if (words.find(i) == words.end()) { ephClockStatusWordsReceived = false; - std::cerr<< "OsnmaTestVectorsSimulation: error parsing words 1->5. " - "Word "<< i << " should be received for each subframe but was not." << std::endl; + std::cerr << "OsnmaTestVectorsSimulation: error parsing words 1->5. " + "Word " + << i << " should be received for each subframe but was not." << std::endl; } } // extract bits as needed by osnma block - if(ephClockStatusWordsReceived) + if (ephClockStatusWordsReceived) { - // Define the starting position and length of bits to extract for each word std::map> extractionParams = { {1, {6, 120}}, @@ -229,15 +228,15 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) }; // Fill NavData bits -- Iterate over the extraction parameters - for (const auto& param : extractionParams) { + for (const auto& param : extractionParams) + { uint8_t wordKey = param.first; uint8_t start = param.second.first; uint8_t length = param.second.second; // Extract the required bits and fill osnma block - osnmaMsg_sptr->EphemerisClockAndStatusData_2 += words[wordKey]. - to_string().substr( - start, length); + osnmaMsg_sptr->EphemerisClockAndStatusData_2 += words[wordKey].to_string().substr( + start, length); } } @@ -245,12 +244,12 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) bool timingWordsReceived = words.find(6) != words.end() && words.find(10) != words.end(); // extract bits as needed by osnma block - if(timingWordsReceived){ + if (timingWordsReceived) + { // Define the starting position and length of bits to extract for each word std::map> extractionParams = { {6, {6, 99}}, - {10, {86, 42}} - }; + {10, {86, 42}}}; // Fill NavData bits -- Iterate over the extraction parameters for (const auto& param : extractionParams) @@ -263,27 +262,26 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) osnmaMsg_sptr->TimingData_2 += words[wordKey].to_string().substr( start, length); } - } // Call the handler, as if it came from telemetry decoder block auto temp_obj = pmt::make_any(osnmaMsg_sptr); - osnma->msg_handler_osnma(temp_obj); // osnma entry point + osnma->msg_handler_osnma(temp_obj); // osnma entry point } - if(!end_of_hex_stream){ - offset_byte = byte_index; // update offset for the next subframe + if (!end_of_hex_stream) + { + offset_byte = byte_index; // update offset for the next subframe d_GST_SIS += DURATION_SUBFRAME; TOW = d_GST_SIS & 0x000FFFFF; - WN = (d_GST_SIS & 0xFFF00000) >> 20 ; - std::cout << "OsnmaTestVectorsSimulation:" << " d_GST_SIS= " << d_GST_SIS + WN = (d_GST_SIS & 0xFFF00000) >> 20; + std::cout << "OsnmaTestVectorsSimulation:" + << " d_GST_SIS= " << d_GST_SIS << ", TOW=" << TOW << ", WN=" << WN << std::endl; } - - } @@ -293,20 +291,24 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) // TODO - create global vars with failed tags and compare to total tags (Tag Id for example) } + std::vector OsnmaMsgReceiverTest::readTestVectorsFromFile(const std::string& filename) { std::ifstream file(filename); std::vector testVectors; - if (!file.is_open()) { - std::cerr<<"Error reading the file \"" << filename <<"\" \n"; + if (!file.is_open()) + { + std::cerr << "Error reading the file \"" << filename << "\" \n"; return testVectors; } std::string line; std::getline(file, line); - if (line != "SVID,NumNavBits,NavBitsHEX\r" ){ - std::cerr<<"Error parsing first line" <<"\n"; - } + if (line != "SVID,NumNavBits,NavBitsHEX\r") + { + std::cerr << "Error parsing first line" + << "\n"; + } while (std::getline(file, line)) { @@ -329,23 +331,27 @@ std::vector OsnmaMsgReceiverTest::readTestVectorsFromFile(const std: return testVectors; } + + std::vector OsnmaMsgReceiverTest::parseNavBits(const std::string& hex) { std::vector bytes; - for (unsigned int i = 0; i < hex.length()-1; i += 2) + for (unsigned int i = 0; i < hex.length() - 1; i += 2) { std::string byteString = hex.substr(i, 2); - uint8_t byte = (uint8_t) strtol(byteString.c_str(), NULL, 16); + uint8_t byte = (uint8_t)strtol(byteString.c_str(), NULL, 16); bytes.push_back(byte); } return bytes; } + + std::string OsnmaMsgReceiverTest::bytes_to_str(const std::vector& bytes) { std::string bit_string; bit_string.reserve(bytes.size() * 8); - for(const auto& byte : bytes) + for (const auto& byte : bytes) { std::bitset<8> bits(byte); bit_string += bits.to_string(); @@ -353,6 +359,7 @@ std::string OsnmaMsgReceiverTest::bytes_to_str(const std::vector& bytes return bit_string; } + /** * @brief Extracts a range of bytes from a TestVector's navBits vector. * @@ -381,6 +388,8 @@ std::vector OsnmaMsgReceiverTest::extract_page_bytes(const TestVector& return extracted_bytes; } + + /** * @brief Sets the time based on the given input. * @@ -404,118 +413,37 @@ void OsnmaMsgReceiverTest::set_time(std::tm& input) uint32_t sec_in_week = 7 * 24 * 60 * 60; uint32_t week_number = duration_sec.count() / sec_in_week; uint32_t time_of_week = duration_sec.count() % sec_in_week; - this->WN = week_number; - this->TOW = time_of_week + LEAP_SECONDS; + this->WN = week_number; + this->TOW = time_of_week + LEAP_SECONDS; // Return the week number and time of week as a pair // TODO: d_GST_SIS or d_receiver_time? doubt // I am assuming that local realisation of receiver is identical to SIS GST time coming from W5 or W0 - this->d_GST_SIS = (this->WN & 0x00000FFF) << 20 | (this->TOW & 0x000FFFFF); - - -} -void OsnmaMsgReceiverTest::initializeGoogleLog() -{ - google::InitGoogleLogging(log_name.c_str()); - FLAGS_minloglevel = 0; // INFO - FLAGS_logtostderr = 0; // add this line - FLAGS_log_dir = "/home/cgm/CLionProjects/osnma/build/src/tests/logs"; - if (FLAGS_log_dir.empty()) - { - std::cout << "Logging will be written at " - << std::filesystem::temp_directory_path() - << '\n' - << "Use gnss-sdr --log_dir=/path/to/log to change that.\n"; - } - else - { - try - { - const std::filesystem::path p(FLAGS_log_dir); - if (!std::filesystem::exists(p)) - { - std::cout << "The path " - << FLAGS_log_dir - << " does not exist, attempting to create it.\n"; - std::error_code ec; - if (!std::filesystem::create_directory(p, ec)) - { - std::cout << "Could not create the " << FLAGS_log_dir << " folder.\n"; - gflags::ShutDownCommandLineFlags(); - throw std::runtime_error("Could not create folder for logs"); - } - } - std::cout << "Logging will be written at " << FLAGS_log_dir << '\n'; - } - catch (const std::exception& e) - { - std::cerr << e.what() << '\n'; - std::cerr << "Could not create the " << FLAGS_log_dir << " folder.\n"; - gflags::ShutDownCommandLineFlags(); - throw; - } - } + this->d_GST_SIS = (this->WN & 0x00000FFF) << 20 | (this->TOW & 0x000FFFFF); } TEST_F(OsnmaMsgReceiverTest, BuildTagMessageM0) { - // Arrange - // ---------- - // m0 - std::vector expected_message = { - 0x02, 0x4E, 0x05, 0x46, 0x3C, 0x01, 0x83, 0xA5, 0x91, 0x05, 0x1D, 0x69, 0x25, 0x80, 0x07, 0x6B, - 0x3E, 0xEA, 0x81, 0x41, 0xBF, 0x03, 0xAD, 0xCB, 0x5A, 0xAD, 0xB2, 0x77, 0xAF, 0x6F, 0xCF, 0x21, - 0xFB, 0x98, 0xFF, 0x7E, 0x83, 0xAF, 0xFC, 0x37, 0x02, 0x03, 0xB0, 0xD8, 0xE1, 0x0E, 0xB1, 0x4D, - 0x11, 0x18, 0xE6, 0xB0, 0xE8, 0x20, 0x01, 0xA0, 0x00, 0xE5, 0x91, 0x00, 0x06, 0xD3, 0x1F, 0x00, - 0x02, 0x68, 0x05, 0x4A, 0x02, 0xC2, 0x26, 0x07, 0xF7, 0xFC, 0x00 - }; - - uint32_t TOW_Tag0 = 345660; - uint32_t TOW_NavData = TOW_Tag0 - 30; - uint32_t TOW_Key_Tag0 = TOW_Tag0 + 30 ; - uint32_t WN = 1248; - uint32_t PRNa = 2; - uint8_t CTR = 1; - - osnma->d_osnma_data.d_dsm_kroot_message.ts = 9; // 40 bit - osnma->d_tesla_keys[TOW_Key_Tag0] = {0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDB, 0xBC, 0x73}; // K4 - osnma->d_osnma_data.d_dsm_kroot_message.mf = 0; - osnma->d_satellite_nav_data[PRNa][TOW_NavData].ephemeris_iono_vector_2 = "000011101001011001000100000101000111010110100100100101100000000000011101101011001111101110101010000001010000011011111100000011101011011100101101011010101011011011001001110111101011110110111111001111001000011111101110011000111111110111111010000011101011111111110000110111000000100000001110110000110110001110000100001110101100010100110100010001000110001110011010110000111010000010000000000001101000000000000011100101100100010000000000000110110100110001111100000000000000100110100000000101010010100000001011000010001001100000011111110111111111000000000"; - osnma->d_osnma_data.d_nma_header.nmas = 0b10; - - MACK_tag_and_info MTI; - MTI.tag = static_cast(0xE37BC4F858); - MTI.tag_info.PRN_d = 0x02; - MTI.tag_info.ADKD = 0x00; - MTI.tag_info.cop = 0x0F; - Tag t0(MTI, TOW_Tag0, WN, PRNa, CTR); - - - - // Act - // ---------- - auto computed_message = osnma->build_message(t0); - - - // Assert - // ---------- - ASSERT_TRUE(computed_message == expected_message); - -} -TEST_F(OsnmaMsgReceiverTest, TagVerification) { // Arrange // ---------- - // Tag0 + // m0 + std::vector expected_message = { + 0x02, 0x4E, 0x05, 0x46, 0x3C, 0x01, 0x83, 0xA5, 0x91, 0x05, 0x1D, 0x69, 0x25, 0x80, 0x07, 0x6B, + 0x3E, 0xEA, 0x81, 0x41, 0xBF, 0x03, 0xAD, 0xCB, 0x5A, 0xAD, 0xB2, 0x77, 0xAF, 0x6F, 0xCF, 0x21, + 0xFB, 0x98, 0xFF, 0x7E, 0x83, 0xAF, 0xFC, 0x37, 0x02, 0x03, 0xB0, 0xD8, 0xE1, 0x0E, 0xB1, 0x4D, + 0x11, 0x18, 0xE6, 0xB0, 0xE8, 0x20, 0x01, 0xA0, 0x00, 0xE5, 0x91, 0x00, 0x06, 0xD3, 0x1F, 0x00, + 0x02, 0x68, 0x05, 0x4A, 0x02, 0xC2, 0x26, 0x07, 0xF7, 0xFC, 0x00}; + uint32_t TOW_Tag0 = 345660; uint32_t TOW_NavData = TOW_Tag0 - 30; - uint32_t TOW_Key_Tag0 = TOW_Tag0 + 30 ; + uint32_t TOW_Key_Tag0 = TOW_Tag0 + 30; uint32_t WN = 1248; uint32_t PRNa = 2; uint8_t CTR = 1; - osnma->d_osnma_data.d_dsm_kroot_message.ts = 9; // 40 bit - osnma->d_tesla_keys[TOW_Key_Tag0] = {0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73}; // K4 + osnma->d_osnma_data.d_dsm_kroot_message.ts = 9; // 40 bit + osnma->d_tesla_keys[TOW_Key_Tag0] = {0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDB, 0xBC, 0x73}; // K4 osnma->d_osnma_data.d_dsm_kroot_message.mf = 0; osnma->d_satellite_nav_data[PRNa][TOW_NavData].ephemeris_iono_vector_2 = "000011101001011001000100000101000111010110100100100101100000000000011101101011001111101110101010000001010000011011111100000011101011011100101101011010101011011011001001110111101011110110111111001111001000011111101110011000111111110111111010000011101011111111110000110111000000100000001110110000110110001110000100001110101100010100110100010001000110001110011010110000111010000010000000000001101000000000000011100101100100010000000000000110110100110001111100000000000000100110100000000101010010100000001011000010001001100000011111110111111111000000000"; osnma->d_osnma_data.d_nma_header.nmas = 0b10; @@ -528,29 +456,62 @@ TEST_F(OsnmaMsgReceiverTest, TagVerification) { Tag t0(MTI, TOW_Tag0, WN, PRNa, CTR); + // Act + // ---------- + auto computed_message = osnma->build_message(t0); + + + // Assert + // ---------- + ASSERT_TRUE(computed_message == expected_message); +} + + +TEST_F(OsnmaMsgReceiverTest, TagVerification) +{ + // Arrange + // ---------- + // Tag0 + uint32_t TOW_Tag0 = 345660; + uint32_t TOW_NavData = TOW_Tag0 - 30; + uint32_t TOW_Key_Tag0 = TOW_Tag0 + 30; + uint32_t WN = 1248; + uint32_t PRNa = 2; + uint8_t CTR = 1; + + osnma->d_osnma_data.d_dsm_kroot_message.ts = 9; // 40 bit + osnma->d_tesla_keys[TOW_Key_Tag0] = {0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73}; // K4 + osnma->d_osnma_data.d_dsm_kroot_message.mf = 0; + osnma->d_satellite_nav_data[PRNa][TOW_NavData].ephemeris_iono_vector_2 = "000011101001011001000100000101000111010110100100100101100000000000011101101011001111101110101010000001010000011011111100000011101011011100101101011010101011011011001001110111101011110110111111001111001000011111101110011000111111110111111010000011101011111111110000110111000000100000001110110000110110001110000100001110101100010100110100010001000110001110011010110000111010000010000000000001101000000000000011100101100100010000000000000110110100110001111100000000000000100110100000000101010010100000001011000010001001100000011111110111111111000000000"; + osnma->d_osnma_data.d_nma_header.nmas = 0b10; + + MACK_tag_and_info MTI; + MTI.tag = static_cast(0xE37BC4F858); + MTI.tag_info.PRN_d = 0x02; + MTI.tag_info.ADKD = 0x00; + MTI.tag_info.cop = 0x0F; + Tag t0(MTI, TOW_Tag0, WN, PRNa, CTR); + // Act // ---------- bool result_tag0 = osnma->verify_tag(t0); - - - // Assert // ---------- - //ASSERT_TRUE(result_tag0); + // ASSERT_TRUE(result_tag0); // Tag3 uint32_t TOW_Tag3 = 345660; uint32_t TOW_NavData_Tag3 = TOW_Tag3 - 30; - uint32_t TOW_Key_Tag3 = TOW_Tag0 + 30 ; + uint32_t TOW_Key_Tag3 = TOW_Tag0 + 30; WN = 1248; PRNa = 2; CTR = 3; - osnma->d_osnma_data.d_dsm_kroot_message.ts = 9; // 40 bit - osnma->d_tesla_keys[TOW_Key_Tag3] = {0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73}; // K4 + osnma->d_osnma_data.d_dsm_kroot_message.ts = 9; // 40 bit + osnma->d_tesla_keys[TOW_Key_Tag3] = {0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73}; // K4 osnma->d_osnma_data.d_dsm_kroot_message.mf = 0; osnma->d_satellite_nav_data[PRNa][TOW_NavData].utc_vector_2 = "111111111111111111111111111111110000000000000000000000010001001001001000" @@ -566,5 +527,4 @@ TEST_F(OsnmaMsgReceiverTest, TagVerification) { bool result_tag3 = osnma->verify_tag(t3); ASSERT_TRUE(result_tag0 && result_tag3); - } From d4cc036cbd7866460b7de00190788286002c7f81 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 23 Jun 2024 12:03:12 +0200 Subject: [PATCH 4/8] Fix HMAC-SHA256 computation with OpenSSL > 3.0 --- src/core/system_parameters/gnss_crypto.cc | 60 ++++++++++++++++++----- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/src/core/system_parameters/gnss_crypto.cc b/src/core/system_parameters/gnss_crypto.cc index e78e29e39..a73907e73 100644 --- a/src/core/system_parameters/gnss_crypto.cc +++ b/src/core/system_parameters/gnss_crypto.cc @@ -34,6 +34,7 @@ #if USE_OPENSSL_3 #include #include +#include #include #include #include @@ -315,23 +316,58 @@ std::vector Gnss_Crypto::computeHMAC_SHA_256(const std::vector #if USE_OPENSSL_FALLBACK #if USE_OPENSSL_3 std::vector hmac(EVP_MAX_MD_SIZE); + size_t output_length = 0; + // Create the context for the HMAC operation + EVP_MAC* mac = EVP_MAC_fetch(nullptr, "HMAC", nullptr); + if (!mac) + { + LOG(WARNING) << "OSNMA HMAC_SHA_256 computation failed to fetch HMAC"; + return output; + } - // 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()); + EVP_MAC_CTX* ctx = EVP_MAC_CTX_new(mac); + if (!ctx) + { + EVP_MAC_free(mac); + LOG(WARNING) << "OSNMA HMAC_SHA_256 computation failed to create HMAC context"; + return output; + } - // Initialize HMAC-SHA256 context - EVP_DigestSignInit(ctx, nullptr, EVP_sha256(), nullptr, pkey); + // Initialize the HMAC context with the key and the SHA-256 algorithm + OSSL_PARAM params[] = { + OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_DIGEST, const_cast("SHA256"), 0), + OSSL_PARAM_construct_end()}; - // Compute HMAC-SHA256 - EVP_DigestSignUpdate(ctx, input.data(), input.size()); - size_t macLength; - EVP_DigestSignFinal(ctx, hmac.data(), &macLength); + if (EVP_MAC_init(ctx, key.data(), key.size(), params) <= 0) + { + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); + LOG(WARNING) << "OSNMA HMAC_SHA_256 computation failed to initialize HMAC context"; + return output; + } - EVP_PKEY_free(pkey); - EVP_MD_CTX_free(ctx); + // Update the HMAC context with the input data + if (EVP_MAC_update(ctx, input.data(), input.size()) <= 0) + { + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); + LOG(WARNING) << "OSNMA HMAC_SHA_256 computation failed to update HMAC context"; + return output; + } - hmac.resize(macLength); + // Finalize the HMAC and retrieve the output + if (EVP_MAC_final(ctx, hmac.data(), &output_length, hmac.size()) <= 0) + { + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); + LOG(WARNING) << "OSNMA HMAC_SHA_256 computation failed to finalize HMAC"; + return output; + } + + // Clean up the HMAC context + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); + hmac.resize(output_length); output = hmac; #else std::vector hmac(32); From 378820e76b654ef583b681d27cfa9230f00dc0bc Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 23 Jun 2024 13:10:38 +0200 Subject: [PATCH 5/8] Add unit test for SHA3-256 hash algorithm --- .../osnma/gnss_crypto_test.cc | 75 +++++-------------- 1 file changed, 18 insertions(+), 57 deletions(-) diff --git a/src/tests/unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc b/src/tests/unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc index a80ef055a..d17ae5e47 100644 --- a/src/tests/unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc @@ -7,7 +7,6 @@ class GnssCryptoTest : public ::testing::Test TEST(GnssCryptoTest, VerifySignature) { - // "../data/OSNMA_PublicKey_20240115100000_newPKID_1.pem" const std::string fake("fake"); std::unique_ptr d_crypto = std::make_unique(fake, fake); @@ -22,66 +21,11 @@ TEST(GnssCryptoTest, VerifySignature) 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A}; - // own ECDSA-P256 key and message generated and signed and verified successfully with openssl - // std::vector message{0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A }; // Hello world con 0x0A al final. Raw message (unhashed) - // std::vector signature{0x30, 0x45, 0x02, 0x21, 0x00, 0xFB, 0xE6, 0x09, 0x74, 0x5C, 0x12, 0xE8, 0x2C, 0x0C, 0xC9, 0x7A, 0x8E, 0x13, 0x88, 0x87, 0xDA, 0xBF, 0x08, 0x43, 0xF8, 0xC8, 0x93, 0x16, 0x5A, - // 0x0F, 0x7A, 0xA4, 0xBF, 0x4A, 0xE1, 0xE1, 0xDB, 0x02, 0x20, 0x6B, 0xCB, 0x2F, 0x80, 0x69, 0xBB, 0xDE, 0xC9, 0x11, 0x1D, 0x51, 0x2B, 0x9F, 0x61, 0xA0, 0xC1, 0x29, 0xD1, 0x0B, - // 0x58, 0x09, 0x82, 0x58, 0xFC, 0x9E, 0x00, 0xC7, 0xEE, 0xA5, 0xB9, 0xB2, 0x56}; // Hello world hashed and then encrypted with PrK - // raw r and s values - // std::vector signature = { - // 0x00, 0xFB, 0xE6, 0x09, 0x74, 0x5C, 0x12, 0xE8, 0x2C, 0x0C, 0xC9, 0x7A, 0x8E, 0x13, 0x88, 0x87, 0xDA, 0xBF, 0x08, 0x43, 0xF8, - // 0xC8, 0x93, 0x16, 0x5A, 0x0F, 0x7A, 0xA4, 0xBF, 0x4A, 0xE1, 0xE1, 0xDB, 0x02, 0x20, 0x6B, 0xCB, 0x2F, 0x80, 0x69, 0xBB, 0xDE, - // 0xC9, 0x11, 0x1D, 0x51, 0x2B, 0x9F, 0x61, 0xA0, 0xC1, 0x29, 0xD1, 0x0B, 0x58, 0x09, 0x82, 0x58, 0xFC, 0x9E, 0x00, 0xC7, 0xEE, - // 0xA5, 0xB9, 0xB2, 0x56 }; - - // std::vector publicKey{// PK associated to the PrK, in der format ---test - // 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4A, 0xF3, - // 0xEE, 0x3A, 0x94, 0x25, 0x25, 0x3D, 0x55, 0xC2, 0x5A, 0xC2, 0x2D, 0xCF, 0x14, 0x4D, 0x39, 0x0D, 0xB1, 0xFC, 0x7F, 0x31, 0x5A, 0x2A, 0x19, 0xAE, 0x4E, 0xD6, 0xCB, 0xA6, 0x59, - // 0xD6, 0x99, 0x7C, 0xE8, 0xBD, 0x1F, 0x43, 0x34, 0x1C, 0x59, 0xD9, 0xD9, 0xCA, 0xC3, 0xEE, 0x58, 0xE5, 0xEA, 0xD3, 0x55, 0x44, 0xEA, 0x89, 0x71, 0x65, 0xD0, 0x92, 0x72, 0xA2, - // 0xC8, 0x3C, 0x87, 0x5D }; - // std::vector publicKey{ // PK associated to the PrK, in pem format - // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, - // - // 0x4D, 0x46, - // 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, - // 0x44, 0x51, 0x67, 0x41, 0x45, 0x53, 0x76, 0x50, 0x75, 0x4F, 0x70, 0x51, 0x6C, 0x4A, 0x54, 0x31, 0x56, 0x77, 0x6C, 0x72, 0x43, 0x4C, 0x63, 0x38, 0x55, 0x54, 0x54, 0x6B, 0x4E, - // 0x73, 0x66, 0x78, 0x2F, 0x0A, 0x4D, 0x56, 0x6F, 0x71, 0x47, 0x61, 0x35, 0x4F, 0x31, 0x73, 0x75, 0x6D, 0x57, 0x64, 0x61, 0x5A, 0x66, 0x4F, 0x69, 0x39, 0x48, 0x30, 0x4D, 0x30, - // 0x48, 0x46, 0x6E, 0x5A, 0x32, 0x63, 0x72, 0x44, 0x37, 0x6C, 0x6A, 0x6C, 0x36, 0x74, 0x4E, 0x56, 0x52, 0x4F, 0x71, 0x4A, 0x63, 0x57, 0x58, 0x51, 0x6B, 0x6E, 0x4B, 0x69, 0x79, - // 0x44, 0x79, 0x48, 0x58, 0x51, 0x3D, 0x3D, 0x0A, - // - // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, - // 0x2D, 0x2D, 0x2D, 0x0A }; - - // own key - GnuTLS error: The curve is unsupported... x192 EC unsupported?? - // std::vector message = {0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64 }; // hello world - // std::vector signature = {0x30, 0x34, 0x02, 0x18, 0x4F, 0xAC, 0x9C, 0x5A, 0x44, 0xCF, 0xFD, 0x42, 0x6A, 0x58, 0x97, 0xA4, 0x94, 0x53, 0x2C, 0x79, 0xD1, 0x7B, 0x8B, 0xF9, 0x93, 0x03, 0xA2, 0xAF, 0x02, 0x18, 0x46, 0xF2, 0xF3, 0xCF, 0x9A, 0x23, 0x39, 0xB4, 0x25, 0x11, 0x89, 0x9A, 0x44, 0x7E, 0x2F, 0xB1, 0xE1, 0x58, 0xAF, 0xCE, 0xC1,0xB4, 0xA1, 0x38 }; - // std::vector publicKey = { - // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x45, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, - // 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x49, 0x44, 0x4D, 0x67, 0x41, 0x45, 0x51, 0x55, 0x61, 0x30, 0x6C, 0x38, 0x4D, 0x35, 0x76, 0x50, 0x58, 0x2B, 0x74, 0x4A, 0x76, 0x63, 0x4C, 0x2B, 0x45, 0x45, 0x4C, 0x34, 0x6E, 0x71, 0x79, 0x75, 0x53, 0x43, 0x0A, 0x4D, 0x4E, 0x46, 0x4A, 0x64, 0x43, 0x5A, 0x62, 0x62, 0x58, - // 0x35, 0x70, 0x4D, 0x36, 0x69, 0x4C, 0x52, 0x53, 0x30, 0x43, 0x51, 0x59, 0x45, 0x67, 0x56, 0x47, 0x51, 0x6B, 0x65, 0x75, 0x74, 0x74, 0x35, 0x78, 0x2F, 0x45, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, - // 0x0A }; - // std::vector ecparam = { - // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x45, 0x43, 0x20, 0x50, 0x41, 0x52, 0x41, 0x4D, 0x45, 0x54, 0x45, 0x52, 0x53, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6B, 0x6A, 0x4F, 0x50, 0x51, 0x4D, 0x42, 0x41, 0x67, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, - // 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x45, 0x43, 0x20, 0x50, 0x41, 0x52, 0x41, 0x4D, 0x45, 0x54, 0x45, 0x52, 0x53, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A }; - d_crypto->set_public_key(publicKey); bool result = d_crypto->verify_signature(message, signature); ASSERT_TRUE(result); } -// TEST(GnssCryptoTest, sha256Test) -//{ -// std::unique_ptr d_crypto; -// -// auto str = "Hello World!"; -// std::vector input (str, str + strlen(str)); -// -// auto expectedOutputStr = "86933b0b147ac4c010266b99004158fa17937db89a03dd7bb2ca5ef7f43c325a"; -// std::vector expectedOutput(expectedOutputStr, expectedOutputStr + strlen(expectedOutputStr)); -// -// std::vector computedOutput = d_crypto->computeSHA256(input); -// -// ASSERT_TRUE(computedOutput == expectedOutput TEST(GnssCryptoTest, VerifyPubKeyImport) @@ -110,7 +54,7 @@ TEST(GnssCryptoTest, VerifyPubKeyImport) // 0x64, 0x35, 0x67, 0x4F, 0x71, 0x49, 0x61, 0x45, 0x32, 0x52, 0x6A, 0x50, 0x41, 0x6E, 0x4B, 0x49, 0x36, 0x38, 0x73, 0x2F, 0x4F, 0x4B, 0x2F, 0x48, 0x50, 0x67, 0x6F, 0x4C, 0x6B, 0x4F, 0x32, 0x69, 0x6A, 0x51, 0x38, 0x78, 0x41, 0x5A, 0x79, 0x44, 0x64, 0x50, 0x42, 0x31, 0x64, 0x48, 0x53, 0x51, 0x3D, 0x3D, 0x0A, // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A } ; // own ECDSA P 256 public key and own message generated (2024-02-19-Own-Key-ECDSA-openssl) - std::vector publicKey{// PEM + std::vector publicKey{ // PEM 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, @@ -225,4 +169,21 @@ TEST(GnssCryptoTest, TestComputeHMACSHA256_adkd4) ASSERT_EQ(expected_output, output); } + +TEST(GnssCryptoTest, TestComputeSHA3_256) +{ + const std::string fake("fake"); + std::unique_ptr d_crypto = std::make_unique(fake, fake); + std::vector message{0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; // Hello world + + std::vector expected_output = { + 0xCC, 0xB8, 0xF9, 0x23, 0x5F, 0x4A, 0x93, 0x2C, 0xA0, 0xAB, + 0xBB, 0x2C, 0x24, 0x36, 0x72, 0x5E, 0x2E, 0x8D, 0xC7, 0x5B, + 0x99, 0xE7, 0xF6, 0xC4, 0x50, 0x5B, 0x2A, 0x93, 0x6E, 0xB6, 0x3B, 0x3F}; + + std::vector output = d_crypto->computeSHA3_256(message); + + ASSERT_EQ(expected_output, output); +} + // TODO extend to HMAC-AES \ No newline at end of file From a704c1004472f2612e30cb82e3a9cf47deec33e6 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 23 Jun 2024 13:34:57 +0200 Subject: [PATCH 6/8] Add SHA_256 unit test --- src/core/system_parameters/gnss_crypto.h | 1 + .../osnma/gnss_crypto_test.cc | 131 +++++++----------- 2 files changed, 51 insertions(+), 81 deletions(-) diff --git a/src/core/system_parameters/gnss_crypto.h b/src/core/system_parameters/gnss_crypto.h index e8b41fddd..24d858f7d 100644 --- a/src/core/system_parameters/gnss_crypto.h +++ b/src/core/system_parameters/gnss_crypto.h @@ -36,6 +36,7 @@ class Gnss_Crypto { public: + Gnss_Crypto() = default; Gnss_Crypto(const std::string& certFilePath, const std::string& merkleTreePath); ~Gnss_Crypto(); diff --git a/src/tests/unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc b/src/tests/unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc index d17ae5e47..95137e21d 100644 --- a/src/tests/unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc @@ -5,15 +5,46 @@ class GnssCryptoTest : public ::testing::Test }; +TEST(GnssCryptoTest, TestComputeSHA_256) +{ + std::unique_ptr d_crypto = std::make_unique(); + std::vector message{0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; // Hello world + + std::vector expected_output = { + 0x18, 0x94, 0xA1, 0x9C, 0x85, 0xBA, 0x15, 0x3A, 0xCB, 0xF7, + 0x43, 0xAC, 0x4E, 0x43, 0xFC, 0x00, 0x4C, 0x89, 0x16, 0x04, 0xB2, + 0x6F, 0x8C, 0x69, 0xE1, 0xE8, 0x3E, 0xA2, 0xAF, 0xC7, 0xC4, 0x8F}; + + std::vector output = d_crypto->computeSHA256(message); + + ASSERT_EQ(expected_output, output); +} + + +TEST(GnssCryptoTest, TestComputeSHA3_256) +{ + std::unique_ptr d_crypto = std::make_unique(); + std::vector message{0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; // Hello world + + std::vector expected_output = { + 0xCC, 0xB8, 0xF9, 0x23, 0x5F, 0x4A, 0x93, 0x2C, 0xA0, 0xAB, + 0xBB, 0x2C, 0x24, 0x36, 0x72, 0x5E, 0x2E, 0x8D, 0xC7, 0x5B, + 0x99, 0xE7, 0xF6, 0xC4, 0x50, 0x5B, 0x2A, 0x93, 0x6E, 0xB6, 0x3B, 0x3F}; + + std::vector output = d_crypto->computeSHA3_256(message); + + ASSERT_EQ(expected_output, output); +} + + TEST(GnssCryptoTest, VerifySignature) { - const std::string fake("fake"); - std::unique_ptr d_crypto = std::make_unique(fake, fake); + std::unique_ptr d_crypto = std::make_unique(); - // RG example - import crt certificate - result: FAIL + // RG example - import crt certificate - result: FAIL std::vector message = {0x82, 0x10, 0x49, 0x22, 0x04, 0xE0, 0x60, 0x61, 0x0B, 0xDF, 0x26, 0xD7, 0x7B, 0x5B, 0xF8, 0xC9, 0xCB, 0xFC, 0xF7, 0x04, 0x22, 0x08, 0x14, 0x75, 0xFD, 0x44, 0x5D, 0xF0, 0xFF}; std::vector signature = {0xF8, 0xCD, 0x88, 0x29, 0x9F, 0xA4, 0x60, 0x58, 0x00, 0x20, 0x7B, 0xFE, 0xBE, 0xAC, 0x55, 0x02, 0x40, 0x53, 0xF3, 0x0F, 0x7C, 0x69, 0xB3, 0x5C, 0x15, 0xE6, 0x08, 0x00, 0xAC, 0x3B, 0x6F, 0xE3, 0xED, 0x06, 0x39, 0x95, 0x2F, 0x7B, 0x02, 0x8D, 0x86, 0x86, 0x74, 0x45, 0x96, 0x1F, 0xFE, 0x94, 0xFB, 0x22, 0x6B, 0xFF, 0x70, 0x06, 0xE0, 0xC4, 0x51, 0xEE, 0x3F, 0x87, 0x28, 0xC1, 0x77, 0xFB}; - std::vector publicKey{// PEM format - 1000 bits + std::vector publicKey{ // PEM format - 1000 bits 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x41, 0x37, 0x4C, 0x4F, 0x5A, 0x4C, 0x77, 0x67, 0x65, 0x39, 0x32, 0x4C, 0x78, 0x4E, 0x2B, 0x46, 0x6B, 0x59, 0x66, 0x38, 0x74, 0x6F, 0x59, 0x79, 0x44, 0x57, 0x50, 0x2F, 0x0A, 0x6F, 0x4A, 0x46, 0x42, 0x44, 0x38, 0x46, 0x59, 0x2B, 0x37, @@ -30,31 +61,9 @@ TEST(GnssCryptoTest, VerifySignature) TEST(GnssCryptoTest, VerifyPubKeyImport) { - // "../data/OSNMA_PublicKey_20240115100000_newPKID_1.pem" - const std::string fake("fake"); - std::unique_ptr d_crypto = std::make_unique(fake, fake); + std::unique_ptr d_crypto = std::make_unique(); - // RG example - key is raw 520 bits example shown - // std::vector publicKey = { // base64 decoding error - // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, - // - // 0x04, 0x03, 0xB2, 0xCE, 0x64, 0xBC, 0x20, 0x7B, 0xDD, 0x8B, 0xC4, 0xDF, 0x85, 0x91, 0x87, 0xFC, - // 0xB6, 0x86, 0x32, 0x0D, 0x63, 0xFF, 0xA0, 0x91, 0x41, 0x0F, 0xC1, 0x58, 0xFB, 0xB7, 0x79, 0x80, - // 0xEA, 0x88, 0x68, 0x4D, 0x91, 0x8C, 0xF0, 0x27, 0x28, 0x8E, 0xBC, 0xB3, 0xF3, 0x8A, 0xFC, 0x73, - // 0xE0, 0xA0, 0xB9, 0x0E, 0xDA, 0x28, 0xD0, 0xF3, 0x10, 0x19, 0xC8, 0x37, 0x4F, 0x07, 0x57, 0x47, 0x49, - // - // 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A - // - // }; - - // RG example crt exported and convert PK.pem - key is raw 1000 bits ,..., why mismatch!? does key get truncated? - // std::vector publicKey { - // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, - // 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x41, 0x37, 0x4C, 0x4F, 0x5A, 0x4C, 0x77, 0x67, 0x65, 0x39, 0x32, 0x4C, 0x78, 0x4E, 0x2B, 0x46, 0x6B, 0x59, 0x66, 0x38, 0x74, 0x6F, 0x59, 0x79, 0x44, 0x57, 0x50, 0x2F, 0x0A, 0x6F, 0x4A, 0x46, 0x42, 0x44, 0x38, 0x46, 0x59, 0x2B, 0x37, - // 0x64, 0x35, 0x67, 0x4F, 0x71, 0x49, 0x61, 0x45, 0x32, 0x52, 0x6A, 0x50, 0x41, 0x6E, 0x4B, 0x49, 0x36, 0x38, 0x73, 0x2F, 0x4F, 0x4B, 0x2F, 0x48, 0x50, 0x67, 0x6F, 0x4C, 0x6B, 0x4F, 0x32, 0x69, 0x6A, 0x51, 0x38, 0x78, 0x41, 0x5A, 0x79, 0x44, 0x64, 0x50, 0x42, 0x31, 0x64, 0x48, 0x53, 0x51, 0x3D, 0x3D, 0x0A, - // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A } ; - // own ECDSA P 256 public key and own message generated (2024-02-19-Own-Key-ECDSA-openssl) - std::vector publicKey{ // PEM + std::vector publicKey{// PEM 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, @@ -68,39 +77,14 @@ TEST(GnssCryptoTest, VerifyPubKeyImport) d_crypto->set_public_key(publicKey); ASSERT_TRUE(d_crypto->have_public_key()); - - // std::vector publicKey = { // DER format - // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, - // 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x41, 0x37, 0x4C, 0x4F, 0x5A, 0x4C, 0x77, 0x67, 0x65, 0x39, 0x32, 0x4C, 0x78, 0x4E, 0x2B, 0x46, 0x6B, 0x59, 0x66, 0x38, 0x74, 0x6F, 0x59, 0x79, 0x44, 0x57, 0x50, 0x2F, 0x0A, 0x6F, 0x4A, 0x46, 0x42, 0x44, 0x38, 0x46, 0x59, 0x2B, 0x37, - // 0x64, 0x35, 0x67, 0x4F, 0x71, 0x49, 0x61, 0x45, 0x32, 0x52, 0x6A, 0x50, 0x41, 0x6E, 0x4B, 0x49, 0x36, 0x38, 0x73, 0x2F, 0x4F, 0x4B, 0x2F, 0x48, 0x50, 0x67, 0x6F, 0x4C, 0x6B, 0x4F, 0x32, 0x69, 0x6A, 0x51, 0x38, 0x78, 0x41, 0x5A, 0x79, 0x44, 0x64, 0x50, 0x42, 0x31, 0x64, 0x48, 0x53, 0x51, 0x3D, 0x3D, 0x0A, - // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x30, 0x82, 0x02, 0x6C, 0x30, 0x82, 0x02, 0x12, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x47, 0xC4, 0xF1, 0x43, 0xC3, 0xFA, 0x61, 0xA5, 0x29, 0x4E, 0x63, - // 0xD5, 0x57, 0x2B, 0x01, 0x62, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x37, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x05, 0x45, 0x55, 0x53, 0x50, 0x41, 0x31, 0x18, 0x30, - // 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x45, 0x55, 0x53, 0x50, 0x41, 0x20, 0x4F, 0x53, 0x4E, 0x4D, 0x41, 0x20, 0x49, 0x43, 0x41, 0x30, 0x1E, 0x17, 0x0D, 0x32, 0x33, 0x30, 0x37, 0x32, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x30, 0x5A, 0x17, 0x0D, 0x32, 0x35, 0x30, 0x38, 0x30, 0x38, 0x31, 0x31, 0x33, - // 0x33, 0x30, 0x30, 0x5A, 0x30, 0x3A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x05, 0x45, 0x55, 0x53, 0x50, 0x41, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x12, 0x45, 0x55, 0x53, 0x50, 0x41, - // 0x20, 0x4F, 0x53, 0x4E, 0x4D, 0x41, 0x20, 0x45, 0x45, 0x20, 0x50, 0x4B, 0x52, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x03, 0xB2, 0xCE, 0x64, 0xBC, 0x20, 0x7B, 0xDD, 0x8B, 0xC4, 0xDF, - // 0x85, 0x91, 0x87, 0xFC, 0xB6, 0x86, 0x32, 0x0D, 0x63, 0xFF, 0xA0, 0x91, 0x41, 0x0F, 0xC1, 0x58, 0xFB, 0xB7, 0x79, 0x80, 0xEA, 0x88, 0x68, 0x4D, 0x91, 0x8C, 0xF0, 0x27, 0x28, 0x8E, 0xBC, 0xB3, 0xF3, 0x8A, 0xFC, 0x73, 0xE0, 0xA0, 0xB9, 0x0E, 0xDA, 0x28, 0xD0, 0xF3, 0x10, 0x19, 0xC8, 0x37, 0x4F, 0x07, 0x57, - // 0x47, 0x49, 0xA3, 0x81, 0xFC, 0x30, 0x81, 0xF9, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0x6A, 0x22, 0x16, 0x58, 0x9B, 0x23, 0xC9, 0x43, 0x41, 0x3C, 0xB6, 0xF8, 0x9D, 0x93, 0x0F, 0xE0, 0xFE, 0x6A, 0x3C, 0x54, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, - // 0x14, 0x20, 0xC0, 0x54, 0x85, 0xAF, 0x82, 0xAE, 0x96, 0x3C, 0xBC, 0xDF, 0xC1, 0xB9, 0x05, 0xDE, 0xD7, 0x46, 0x72, 0x32, 0xA3, 0x30, 0x63, 0x06, 0x03, 0x55, 0x1D, 0x20, 0x04, 0x5C, 0x30, 0x5A, 0x30, 0x4E, 0x06, 0x0B, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0xD5, 0x11, 0x01, 0x01, 0x01, 0x30, 0x3F, 0x30, 0x3D, - // 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x31, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x67, 0x73, 0x63, 0x2D, 0x65, 0x75, 0x72, 0x6F, 0x70, 0x61, 0x2E, 0x65, 0x75, 0x2F, 0x67, 0x73, 0x63, 0x2D, 0x70, 0x72, 0x6F, 0x64, 0x75, 0x63, 0x74, 0x73, 0x2F, - // 0x4F, 0x53, 0x4E, 0x4D, 0x41, 0x2F, 0x50, 0x4B, 0x49, 0x2F, 0x30, 0x08, 0x06, 0x06, 0x04, 0x00, 0x8F, 0x7A, 0x01, 0x02, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1D, 0x1F, 0x04, 0x3B, 0x30, 0x39, 0x30, 0x37, 0xA0, 0x35, 0xA0, 0x33, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, - // 0x67, 0x73, 0x63, 0x2D, 0x65, 0x75, 0x72, 0x6F, 0x70, 0x61, 0x2E, 0x65, 0x75, 0x2F, 0x67, 0x73, 0x63, 0x2D, 0x70, 0x72, 0x6F, 0x64, 0x75, 0x63, 0x74, 0x73, 0x2F, 0x4F, 0x53, 0x4E, 0x4D, 0x41, 0x2F, 0x50, 0x4B, 0x49, 0x2F, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, 0x02, - // 0x07, 0x80, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x21, 0x00, 0xE9, 0xBB, 0x90, 0x8E, 0xE5, 0x0C, 0xF3, 0xDA, 0x57, 0x71, 0xE3, 0xD0, 0xD2, 0xEA, 0xAC, 0x1B, 0x00, 0xF3, 0x51, 0xE9, 0xD8, 0xBB, 0x0A, 0xB2, 0x4C, 0x8A, 0x65, 0x52, 0x79, - // 0x9F, 0x43, 0xF6, 0x02, 0x20, 0x10, 0x65, 0x2F, 0x6A, 0xF8, 0x26, 0x20, 0x42, 0xFF, 0x09, 0x6B, 0xD0, 0x8D, 0x0B, 0x75, 0x15, 0x24, 0xBF, 0xE4, 0xFE, 0x60, 0xC3, 0x6E, 0x2D, 0x31, 0x32, 0xED, 0x65, 0x6C, 0x5C, 0x8B, 0x14 }; - - // std::vector publicKey= { // PEM format - // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, - // 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x41, 0x37, 0x4C, 0x4F, 0x5A, 0x4C, 0x77, 0x67, 0x65, 0x39, 0x32, 0x4C, 0x78, 0x4E, 0x2B, 0x46, 0x6B, 0x59, 0x66, 0x38, 0x74, 0x6F, 0x59, 0x79, 0x44, 0x57, 0x50, 0x2F, 0x0A, 0x6F, 0x4A, 0x46, 0x42, 0x44, 0x38, 0x46, 0x59, 0x2B, 0x37, - // 0x64, 0x35, 0x67, 0x4F, 0x71, 0x49, 0x61, 0x45, 0x32, 0x52, 0x6A, 0x50, 0x41, 0x6E, 0x4B, 0x49, 0x36, 0x38, 0x73, 0x2F, 0x4F, 0x4B, 0x2F, 0x48, 0x50, 0x67, 0x6F, 0x4C, 0x6B, 0x4F, 0x32, 0x69, 0x6A, 0x51, 0x38, 0x78, 0x41, 0x5A, 0x79, 0x44, 0x64, 0x50, 0x42, 0x31, 0x64, 0x48, 0x53, 0x51, 0x3D, 0x3D, 0x0A, - // 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A }; } // Unit test for computeHMAC_SHA_256 function. TEST(GnssCryptoTest, TestComputeHMACSHA256) { - // key and message generated with openssl - const std::string fake("fake"); - std::unique_ptr d_crypto = std::make_unique(fake, fake); + std::unique_ptr d_crypto = std::make_unique(); + std::vector key = { 0x24, 0x24, 0x3B, 0x76, 0xF9, 0x14, 0xB1, 0xA7, 0x7D, 0x48, 0xE7, 0xF1, 0x48, 0x0C, 0xC2, 0x98, @@ -121,14 +105,15 @@ TEST(GnssCryptoTest, TestComputeHMACSHA256) TEST(GnssCryptoTest, TestComputeHMACSHA256_m0) -{ // key and message generated from RG A.6.5.1 - const std::string fake("fake"); - std::unique_ptr d_crypto = std::make_unique(fake, fake); - std::vector key = {// RG K4 @ 345690 +{ + // key and message generated from RG A.6.5.1 + std::unique_ptr d_crypto = std::make_unique(); + + std::vector key = { // RG K4 @ 345690 0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73}; - std::vector message{// m0 + std::vector message{ // m0 0x02, 0x4E, 0x05, 0x46, 0x3C, 0x01, 0x83, 0xA5, 0x91, 0x05, 0x1D, 0x69, 0x25, 0x80, 0x07, 0x6B, 0x3E, 0xEA, 0x81, 0x41, 0xBF, 0x03, 0xAD, 0xCB, 0x5A, 0xAD, 0xB2, 0x77, 0xAF, 0x6F, 0xCF, 0x21, 0xFB, 0x98, 0xFF, 0x7E, 0x83, 0xAF, 0xFC, 0x37, 0x02, 0x03, 0xB0, 0xD8, 0xE1, 0x0E, 0xB1, 0x4D, @@ -147,10 +132,11 @@ TEST(GnssCryptoTest, TestComputeHMACSHA256_m0) TEST(GnssCryptoTest, TestComputeHMACSHA256_adkd4) -{ // key and message generated from RG A.6.5.2 - const std::string fake("fake"); - std::unique_ptr d_crypto = std::make_unique(fake, fake); - std::vector key = {// RG K4 @ 345690 +{ + // key and message generated from RG A.6.5.2 + std::unique_ptr d_crypto = std::make_unique(); + + std::vector key = { // RG K4 @ 345690 0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73}; @@ -169,21 +155,4 @@ TEST(GnssCryptoTest, TestComputeHMACSHA256_adkd4) ASSERT_EQ(expected_output, output); } - -TEST(GnssCryptoTest, TestComputeSHA3_256) -{ - const std::string fake("fake"); - std::unique_ptr d_crypto = std::make_unique(fake, fake); - std::vector message{0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; // Hello world - - std::vector expected_output = { - 0xCC, 0xB8, 0xF9, 0x23, 0x5F, 0x4A, 0x93, 0x2C, 0xA0, 0xAB, - 0xBB, 0x2C, 0x24, 0x36, 0x72, 0x5E, 0x2E, 0x8D, 0xC7, 0x5B, - 0x99, 0xE7, 0xF6, 0xC4, 0x50, 0x5B, 0x2A, 0x93, 0x6E, 0xB6, 0x3B, 0x3F}; - - std::vector output = d_crypto->computeSHA3_256(message); - - ASSERT_EQ(expected_output, output); -} - // TODO extend to HMAC-AES \ No newline at end of file From 8ea75116acbcb9405b63dccdf19f010e20d64d56 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Sun, 23 Jun 2024 13:48:31 +0200 Subject: [PATCH 7/8] Fix intantiation of Gnss_Crypto() with GnuTLS --- src/core/system_parameters/gnss_crypto.cc | 9 +++++++++ src/core/system_parameters/gnss_crypto.h | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/core/system_parameters/gnss_crypto.cc b/src/core/system_parameters/gnss_crypto.cc index a73907e73..06c9d6538 100644 --- a/src/core/system_parameters/gnss_crypto.cc +++ b/src/core/system_parameters/gnss_crypto.cc @@ -56,6 +56,15 @@ #endif +Gnss_Crypto::Gnss_Crypto() +{ +#if USE_OPENSSL_FALLBACK +#else // GnuTLS + gnutls_global_init(); +#endif +} + + Gnss_Crypto::Gnss_Crypto(const std::string& certFilePath, const std::string& merkleTreePath) { #if USE_OPENSSL_FALLBACK diff --git a/src/core/system_parameters/gnss_crypto.h b/src/core/system_parameters/gnss_crypto.h index 24d858f7d..9d60c8a77 100644 --- a/src/core/system_parameters/gnss_crypto.h +++ b/src/core/system_parameters/gnss_crypto.h @@ -36,7 +36,7 @@ class Gnss_Crypto { public: - Gnss_Crypto() = default; + Gnss_Crypto(); Gnss_Crypto(const std::string& certFilePath, const std::string& merkleTreePath); ~Gnss_Crypto(); From 584b95e62e01a44ccc7b4b80bd3f3be15d6c8b92 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 24 Jun 2024 14:01:34 +0200 Subject: [PATCH 8/8] Fix CMAC-AES implementation in OpenSSL>3.0.0. Add unit test --- src/core/system_parameters/gnss_crypto.cc | 70 +++++++++++++------ .../osnma/gnss_crypto_test.cc | 31 ++++++-- 2 files changed, 75 insertions(+), 26 deletions(-) diff --git a/src/core/system_parameters/gnss_crypto.cc b/src/core/system_parameters/gnss_crypto.cc index 06c9d6538..947b8a436 100644 --- a/src/core/system_parameters/gnss_crypto.cc +++ b/src/core/system_parameters/gnss_crypto.cc @@ -38,6 +38,7 @@ #include #include #include +#include #define OPENSSL_ENGINE nullptr #else #include @@ -416,35 +417,62 @@ std::vector Gnss_Crypto::computeCMAC_AES(const std::vector& ke std::vector output(16); #if USE_OPENSSL_FALLBACK #if USE_OPENSSL_3 - std::vector mac(EVP_MAX_MD_SIZE); // CMAC-AES output size + std::vector aux(EVP_MAX_MD_SIZE); // CMAC-AES output size + size_t output_length = 0; - EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); - EVP_MAC* cmac = EVP_MAC_fetch(nullptr, "CMAC-AES", nullptr); + // Create the context for the CMAC operation + EVP_MAC* mac = EVP_MAC_fetch(nullptr, "CMAC", nullptr); + if (!mac) + { + LOG(INFO) << "OSNMA CMAC-AES: Failed to fetch CMAC"; + return output; + } - EVP_MAC_CTX* cmacCtx = EVP_MAC_CTX_new(cmac); + EVP_MAC_CTX* ctx = EVP_MAC_CTX_new(mac); + if (!ctx) + { + LOG(INFO) << "OSNMA CMAC-AES: Failed to create CMAC context"; + return output; + } - 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", nullptr, 0); // Set IV to nullptr - params[2] = OSSL_PARAM_construct_octet_string("aad", nullptr, 0); // Set AAD to nullptr - params[3] = OSSL_PARAM_construct_end(); + // Initialize the CMAC context with the key and the AES algorithm + OSSL_PARAM params[] = { + OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, const_cast("AES-128-CBC"), 0), + OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, const_cast(key.data()), key.size()), + OSSL_PARAM_construct_end()}; - // Set AES-128 CMAC cipher and key - EVP_MAC_init(cmacCtx, nullptr, 0, params); + if (EVP_MAC_init(ctx, nullptr, 0, params) <= 0) + { + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); + LOG(INFO) << "OSNMA CMAC-AES: Failed to initialize CMAC context"; + return output; + } - // Compute CMAC-AES - EVP_MAC_update(cmacCtx, input.data(), input.size()); - size_t macLength = mac.size(); - size_t outputLength = 16; + // Update the CMAC context with the input data + if (EVP_MAC_update(ctx, input.data(), input.size()) <= 0) + { + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); + LOG(INFO) << "OSNMA CMAC-AES: Failed to update CMAC context"; + return output; + } - EVP_MAC_final(cmacCtx, mac.data(), &macLength, outputLength); + // Finalize the CMAC and retrieve the output + if (EVP_MAC_final(ctx, aux.data(), &output_length, aux.size()) <= 0) + { + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); + LOG(INFO) << "OSNMA CMAC-AES: Failed to finalize CMAC"; + return output; + } - EVP_MAC_free(cmac); - EVP_MAC_CTX_free(cmacCtx); - EVP_CIPHER_CTX_free(ctx); + // Clean up the CMAC context + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); - mac.resize(macLength); - output = mac; + aux.resize(output_length); + output = aux; #else std::vector mac(16); // CMAC-AES output size diff --git a/src/tests/unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc b/src/tests/unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc index 95137e21d..87f5afbfa 100644 --- a/src/tests/unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/osnma/gnss_crypto_test.cc @@ -44,7 +44,7 @@ TEST(GnssCryptoTest, VerifySignature) // RG example - import crt certificate - result: FAIL std::vector message = {0x82, 0x10, 0x49, 0x22, 0x04, 0xE0, 0x60, 0x61, 0x0B, 0xDF, 0x26, 0xD7, 0x7B, 0x5B, 0xF8, 0xC9, 0xCB, 0xFC, 0xF7, 0x04, 0x22, 0x08, 0x14, 0x75, 0xFD, 0x44, 0x5D, 0xF0, 0xFF}; std::vector signature = {0xF8, 0xCD, 0x88, 0x29, 0x9F, 0xA4, 0x60, 0x58, 0x00, 0x20, 0x7B, 0xFE, 0xBE, 0xAC, 0x55, 0x02, 0x40, 0x53, 0xF3, 0x0F, 0x7C, 0x69, 0xB3, 0x5C, 0x15, 0xE6, 0x08, 0x00, 0xAC, 0x3B, 0x6F, 0xE3, 0xED, 0x06, 0x39, 0x95, 0x2F, 0x7B, 0x02, 0x8D, 0x86, 0x86, 0x74, 0x45, 0x96, 0x1F, 0xFE, 0x94, 0xFB, 0x22, 0x6B, 0xFF, 0x70, 0x06, 0xE0, 0xC4, 0x51, 0xEE, 0x3F, 0x87, 0x28, 0xC1, 0x77, 0xFB}; - std::vector publicKey{ // PEM format - 1000 bits + std::vector publicKey{// PEM format - 1000 bits 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x41, 0x37, 0x4C, 0x4F, 0x5A, 0x4C, 0x77, 0x67, 0x65, 0x39, 0x32, 0x4C, 0x78, 0x4E, 0x2B, 0x46, 0x6B, 0x59, 0x66, 0x38, 0x74, 0x6F, 0x59, 0x79, 0x44, 0x57, 0x50, 0x2F, 0x0A, 0x6F, 0x4A, 0x46, 0x42, 0x44, 0x38, 0x46, 0x59, 0x2B, 0x37, @@ -109,11 +109,11 @@ TEST(GnssCryptoTest, TestComputeHMACSHA256_m0) // key and message generated from RG A.6.5.1 std::unique_ptr d_crypto = std::make_unique(); - std::vector key = { // RG K4 @ 345690 + std::vector key = {// RG K4 @ 345690 0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73}; - std::vector message{ // m0 + std::vector message{// m0 0x02, 0x4E, 0x05, 0x46, 0x3C, 0x01, 0x83, 0xA5, 0x91, 0x05, 0x1D, 0x69, 0x25, 0x80, 0x07, 0x6B, 0x3E, 0xEA, 0x81, 0x41, 0xBF, 0x03, 0xAD, 0xCB, 0x5A, 0xAD, 0xB2, 0x77, 0xAF, 0x6F, 0xCF, 0x21, 0xFB, 0x98, 0xFF, 0x7E, 0x83, 0xAF, 0xFC, 0x37, 0x02, 0x03, 0xB0, 0xD8, 0xE1, 0x0E, 0xB1, 0x4D, @@ -136,7 +136,7 @@ TEST(GnssCryptoTest, TestComputeHMACSHA256_adkd4) // key and message generated from RG A.6.5.2 std::unique_ptr d_crypto = std::make_unique(); - std::vector key = { // RG K4 @ 345690 + std::vector key = {// RG K4 @ 345690 0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73}; @@ -155,4 +155,25 @@ TEST(GnssCryptoTest, TestComputeHMACSHA256_adkd4) ASSERT_EQ(expected_output, output); } -// TODO extend to HMAC-AES \ No newline at end of file + +TEST(GnssCryptoTest, TestComputeCMAC_AES) +{ + // Tests vectors from https://datatracker.ietf.org/doc/html/rfc4493#appendix-A + std::unique_ptr d_crypto = std::make_unique(); + + std::vector key = { + 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C}; + + std::vector message{ + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A}; + + std::vector expected_output = { + 0x07, 0x0A, 0x16, 0xB4, 0x6B, 0x4D, 0x41, 0x44, + 0xF7, 0x9B, 0xDD, 0x9D, 0xD0, 0x4A, 0x28, 0x7C}; + + std::vector output = d_crypto->computeCMAC_AES(key, message); + + ASSERT_EQ(expected_output, output); +} \ No newline at end of file