1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-10-30 22:56:22 +00:00

Add work on OSNMA receiver

This commit is contained in:
Carles Fernandez 2023-06-12 10:02:52 +02:00
parent e75bdeb5f6
commit bece57d226
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
2 changed files with 74 additions and 87 deletions

View File

@ -43,10 +43,6 @@
Gnss_Crypto::Gnss_Crypto(const std::string& filePath) Gnss_Crypto::Gnss_Crypto(const std::string& filePath)
{ {
#if USE_OPENSSL_FALLBACK
#else
gnutls_global_init();
#endif
readPublicKeyFromPEM(filePath); readPublicKeyFromPEM(filePath);
} }
@ -54,10 +50,13 @@ Gnss_Crypto::Gnss_Crypto(const std::string& filePath)
Gnss_Crypto::~Gnss_Crypto() Gnss_Crypto::~Gnss_Crypto()
{ {
#if USE_OPENSSL_FALLBACK #if USE_OPENSSL_FALLBACK
#if USE_OPENSSL_3
#else
if (d_PublicKey != nullptr) if (d_PublicKey != nullptr)
{ {
EC_KEY_free(d_PublicKey); EC_KEY_free(d_PublicKey);
} }
#endif
#else #else
if (d_PublicKey != nullptr) if (d_PublicKey != nullptr)
{ {
@ -300,52 +299,6 @@ void Gnss_Crypto::readPublicKeyFromPEM(const std::string& filePath)
std::cerr << "OpenSSL: error creating a BIO object with data read from file " << filePath << ". Aborting import" << std::endl; std::cerr << "OpenSSL: error creating a BIO object with data read from file " << filePath << ". Aborting import" << std::endl;
return; return;
} }
#if USE_OPENSSL_3
// Read the PEM data from the BIO object
EVP_PKEY* evpKey = PEM_read_bio_PUBKEY(bio, nullptr, nullptr, nullptr);
BIO_free(bio);
if (!evpKey)
{
std::cerr << "OpenSSL: error reading the Public Key from file " << filePath << ". Aborting import" << std::endl;
return;
}
// Check if the public key is an EC key
if (EVP_PKEY_base_id(evpKey) != EVP_PKEY_EC)
{
std::cerr << "OpenSSL: Public key imported from file " << filePath << " is not an EC key. Aborting import" << std::endl;
EVP_PKEY_free(evpKey);
return;
}
// Get the EC key from the EVP_PKEY object
d_PublicKey = EVP_PKEY_get1_EC_KEY(evpKey);
EVP_PKEY_free(evpKey);
if (d_PublicKey == nullptr)
{
std::cout << "OpenSSL: Failed to get the EC key from file " << filePath << ". Aborting import" << std::endl;
return;
}
// Get the EC group from the EC key
const EC_GROUP* ecGroup = EC_KEY_get0_group(d_PublicKey);
if (ecGroup == nullptr)
{
std::cout << "OpenSSL: Failed to extract the EC group from file " << filePath << ". Aborting import" << std::endl;
EC_KEY_free(d_PublicKey);
return;
}
// Check if it is ECDSA P-256
if (EC_GROUP_get_curve_name(ecGroup) != NID_X9_62_prime256v1)
{
std::cerr << "Invalid curve name in file " << filePath << ". Expected P-256. Aborting import" << std::endl;
EC_KEY_free(d_PublicKey);
return;
}
#else
// Load the public key from the BIO // Load the public key from the BIO
d_PublicKey = PEM_read_bio_EC_PUBKEY(bio, nullptr, nullptr, nullptr); d_PublicKey = PEM_read_bio_EC_PUBKEY(bio, nullptr, nullptr, nullptr);
BIO_free(bio); BIO_free(bio);
@ -354,8 +307,8 @@ void Gnss_Crypto::readPublicKeyFromPEM(const std::string& filePath)
std::cerr << "OpenSSL: error reading the Public Key from file " << filePath << ". Aborting import" << std::endl; std::cerr << "OpenSSL: error reading the Public Key from file " << filePath << ". Aborting import" << std::endl;
return; return;
} }
#endif
#else #else
gnutls_global_init();
gnutls_pubkey_t pubKey; gnutls_pubkey_t pubKey;
gnutls_pubkey_init(&pubKey); gnutls_pubkey_init(&pubKey);
d_PublicKey = &pubKey; d_PublicKey = &pubKey;
@ -370,44 +323,73 @@ void Gnss_Crypto::readPublicKeyFromPEM(const std::string& filePath)
gnutls_pubkey_deinit(*d_PublicKey); gnutls_pubkey_deinit(*d_PublicKey);
return; return;
} }
gnutls_pubkey_deinit(pubKey);
#endif #endif
std::cout << "Public key successfully read from file " << filePath << std::endl; std::cout << "Public key successfully read from file " << filePath << std::endl;
} }
// bool verify_signature(const std::vector<uint8_t>& message, const std::vector<uint8_t>& signature) bool Gnss_Crypto::verify_signature(const std::vector<uint8_t>& message, const std::vector<uint8_t>& signature)
// { {
// bool success = false; bool success = false;
// #if USE_OPENSSL_FALLBACK #if USE_OPENSSL_FALLBACK
/** Verifies that the given signature is valid ECDSA signature #if USE_OPENSSL_3
* of the supplied hash value using the specified public key. EVP_PKEY_CTX* ctx;
* \param type this parameter is ignored ctx = EVP_PKEY_CTX_new(d_PublicKey, NULL /* no engine */);
* \param dgst pointer to the hash value bool do_operation = true;
* \param dgstlen length of the hash value if (!ctx)
* \param sig pointer to the DER encoded signature {
* \param siglen length of the DER encoded signature do_operation = false;
* \param eckey EC_KEY object containing a public EC key }
* \return 1 if the signature is valid, 0 if the signature is invalid if (EVP_PKEY_verify_init(ctx) <= 0)
* and -1 on error {
*/ do_operation = false;
// int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, const unsigned char *sig, int siglen, EC_KEY *eckey);) }
// int verification = ECDSA_verify(0, digest, SHA256_DIGEST_LENGTH, signature, signature_len, key_pair_obj); if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0)
// #else {
// gnutls_global_init(); do_operation = false;
// int result = gnutls_pubkey_verify_data(publicKey.data(), GNUTLS_SIGN_ECDSA_SHA256, digest.data(), digest.size(), signature.data(), signature.size()); }
// success = (result == GNUTLS_E_SUCCESS); int verification = 0;
// gnutls_global_deinit(); if (do_operation)
// pubkey: Holds the public key {
// algo: The signature algorithm used verification = EVP_PKEY_verify(ctx, signature.data(), signature.size(), message.data(), message.size());
// flags: Zero or an OR list of gnutls_certificate_verify_flags }
// data: holds the signed data if (verification == 1)
// signature: contains the signature {
// This function will verify the given signed data, using the parameters from the certificate. success = true;
// gnutls_pubkey_verify_data2 (gnutls_pubkey_t pubkey, gnutls_sign_algorithm_t algo, unsigned int flags, const gnutls_datum_t * data, const gnutls_datum_t * signature) }
// #endif #else
// return success; auto digest = this->computeSHA256(message);
// } int verification = ECDSA_verify(0, digest.data(), SHA256_DIGEST_LENGTH, signature.data(), static_cast<int>(signature.size()), d_PublicKey);
// // bool verifyDigitalSignature(const unsigned char* signature, size_t signatureSize, const unsigned char* message, size_t messageSize, gnutls_pubkey_t publicKey) if (verification == 1)
// // { {
// // int verificationStatus = gnutls_pubkey_verify_data(publicKey, GNUTLS_DIG_SHA256, 0, message, messageSize, signature, signatureSize); success = true;
// // return verificationStatus == 0; }
else if (verification == 0)
{
std::cerr << "OpenSSL: invalid signature found when verifying message" << std::endl;
}
#endif
#else
// Verify the dummy hash using the public key
gnutls_datum_t dummyHash = {nullptr, 0};
int ret2 = gnutls_pubkey_verify_hash2(*d_PublicKey, GNUTLS_SIGN_ECDSA_SHA256, 0, &dummyHash, &dummyHash);
if (ret2 != GNUTLS_E_SUCCESS)
{
std::cout << "GnuTLS: The Public Key is invalid" << std::endl;
}
gnutls_datum_t signature_{};
signature_.data = const_cast<uint8_t*>(signature.data());
signature_.size = signature.size();
gnutls_datum_t data_{};
data_.data = const_cast<uint8_t*>(message.data());
data_.size = message.size();
int ret = gnutls_pubkey_verify_data2(*d_PublicKey, GNUTLS_SIGN_ECDSA_SHA256, 0, &data_, &signature_);
if (ret == GNUTLS_E_SUCCESS)
{
success = true;
}
#endif
return success;
}

View File

@ -43,13 +43,18 @@ public:
std::vector<uint8_t> computeSHA3_256(const std::vector<uint8_t>& input) const; std::vector<uint8_t> computeSHA3_256(const std::vector<uint8_t>& input) const;
std::vector<uint8_t> computeHMAC_SHA_256(const std::vector<uint8_t>& key, const std::vector<uint8_t>& input) const; std::vector<uint8_t> computeHMAC_SHA_256(const std::vector<uint8_t>& key, const std::vector<uint8_t>& input) const;
std::vector<uint8_t> computeCMAC_AES(const std::vector<uint8_t>& key, const std::vector<uint8_t>& input) const; std::vector<uint8_t> computeCMAC_AES(const std::vector<uint8_t>& key, const std::vector<uint8_t>& input) const;
bool verify_signature(const std::vector<uint8_t>& message, const std::vector<uint8_t>& signature);
void readPublicKeyFromPEM(const std::string& filePath); void readPublicKeyFromPEM(const std::string& filePath);
// void set_public_key(const std::vector<uint8_t>& publickey); // void set_public_key(const std::vector<uint8_t>& publickey);
private: private:
#if USE_OPENSSL_FALLBACK #if USE_OPENSSL_FALLBACK
#if USE_OPENSSL_3
EVP_PKEY* d_PublicKey;
#else
EC_KEY* d_PublicKey = nullptr; EC_KEY* d_PublicKey = nullptr;
#endif
#else #else
gnutls_pubkey_t* d_PublicKey; gnutls_pubkey_t* d_PublicKey;
#endif #endif