mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-12 19:20:32 +00:00
Fix ECDSA signature verification when linking againts OpenSSL 1.0
This commit is contained in:
parent
23bb5c85c5
commit
cae618b450
@ -305,7 +305,11 @@ std::vector<uint8_t> Gnss_Crypto::computeSHA3_256(const std::vector<uint8_t>& in
|
||||
EVP_DigestFinal_ex(mdctx, output.data(), nullptr);
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
#else
|
||||
// SHA3-256 not implemented in OpenSSL < 3.0
|
||||
// SHA3-256 not implemented in OpenSSL 1.0, it was introduced in OpenSSL 1.1.1
|
||||
if (!input.empty())
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
#endif
|
||||
#else // GnuTLS
|
||||
std::vector<uint8_t> output_aux(32);
|
||||
@ -384,8 +388,8 @@ std::vector<uint8_t> Gnss_Crypto::computeHMAC_SHA_256(const std::vector<uint8_t>
|
||||
unsigned char* result = HMAC(EVP_sha256(), key.data(), key.size(), input.data(), input.size(), output.data(), &outputLength);
|
||||
if (result == nullptr)
|
||||
{
|
||||
LOG(WARNING) << "OSNMA HMAC_SHA_256 computation failed to compute HMAC-SHA256";
|
||||
return output;
|
||||
LOG(WARNING) << "OSNMA HMAC_SHA_256 computation failed to compute HMAC-SHA256";
|
||||
return output;
|
||||
}
|
||||
|
||||
// Resize the output vector to the actual length of the HMAC-SHA256 output
|
||||
@ -740,7 +744,13 @@ bool Gnss_Crypto::verify_signature(const std::vector<uint8_t>& message, const st
|
||||
LOG(WARNING) << "OpenSSL: OSNMA message authentication failed: " << err;
|
||||
}
|
||||
#else
|
||||
int verification = ECDSA_verify(0, digest.data(), SHA256_DIGEST_LENGTH, signature.data(), static_cast<int>(signature.size()), d_PublicKey);
|
||||
std::vector<uint8_t> 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;
|
||||
}
|
||||
int verification = ECDSA_verify(0, digest.data(), SHA256_DIGEST_LENGTH, der_sig.data(), static_cast<int>(der_sig.size()), d_PublicKey);
|
||||
if (verification == 1)
|
||||
{
|
||||
success = true;
|
||||
@ -749,6 +759,7 @@ bool Gnss_Crypto::verify_signature(const std::vector<uint8_t>& message, const st
|
||||
else if (verification == 0)
|
||||
{
|
||||
std::cerr << "OpenSSL: invalid signature found when verifying message" << std::endl;
|
||||
LOG(WARNING) << "OpenSSL: invalid signature found when verifying message";
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -876,6 +887,54 @@ void Gnss_Crypto::set_public_key(const std::vector<uint8_t>& publicKey)
|
||||
}
|
||||
|
||||
|
||||
bool Gnss_Crypto::convert_raw_to_der_ecdsa(const std::vector<uint8_t>& raw_signature, std::vector<uint8_t>& der_signature) const
|
||||
{
|
||||
if (raw_signature.size() % 2 != 0)
|
||||
{
|
||||
std::cerr << "Invalid raw ECDSA signature size" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t half_size = raw_signature.size() / 2;
|
||||
std::vector<uint8_t> raw_r(raw_signature.begin(), raw_signature.begin() + half_size);
|
||||
std::vector<uint8_t> raw_s(raw_signature.begin() + half_size, raw_signature.end());
|
||||
|
||||
auto encode_asn1_integer = [](const std::vector<uint8_t>& value) -> std::vector<uint8_t> {
|
||||
std::vector<uint8_t> 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<uint8_t> der_r = encode_asn1_integer(raw_r);
|
||||
std::vector<uint8_t> 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<uint8_t>(total_length));
|
||||
|
||||
der_signature.insert(der_signature.end(), der_r.begin(), der_r.end());
|
||||
der_signature.insert(der_signature.end(), der_s.begin(), der_s.end());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#if USE_OPENSSL_FALLBACK
|
||||
#if USE_OPENSSL_3
|
||||
bool Gnss_Crypto::pubkey_copy(EVP_PKEY* src, EVP_PKEY** dest)
|
||||
@ -972,54 +1031,6 @@ bool Gnss_Crypto::pubkey_copy(EC_KEY* src, EC_KEY** dest)
|
||||
|
||||
#else // GnuTLS-specific functions
|
||||
|
||||
bool Gnss_Crypto::convert_raw_to_der_ecdsa(const std::vector<uint8_t>& raw_signature, std::vector<uint8_t>& der_signature) const
|
||||
{
|
||||
if (raw_signature.size() % 2 != 0)
|
||||
{
|
||||
std::cerr << "Invalid raw ECDSA signature size" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t half_size = raw_signature.size() / 2;
|
||||
std::vector<uint8_t> raw_r(raw_signature.begin(), raw_signature.begin() + half_size);
|
||||
std::vector<uint8_t> raw_s(raw_signature.begin() + half_size, raw_signature.end());
|
||||
|
||||
auto encode_asn1_integer = [](const std::vector<uint8_t>& value) -> std::vector<uint8_t> {
|
||||
std::vector<uint8_t> 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<uint8_t> der_r = encode_asn1_integer(raw_r);
|
||||
std::vector<uint8_t> 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<uint8_t>(total_length));
|
||||
|
||||
der_signature.insert(der_signature.end(), der_r.begin(), der_r.end());
|
||||
der_signature.insert(der_signature.end(), der_s.begin(), der_s.end());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Gnss_Crypto::pubkey_copy(gnutls_pubkey_t src, gnutls_pubkey_t* dest)
|
||||
{
|
||||
gnutls_datum_t key_datum;
|
||||
|
@ -58,19 +58,19 @@ private:
|
||||
void read_merkle_xml(const std::string& merkleFilePath);
|
||||
void readPublicKeyFromPEM(const std::string& pemFilePath);
|
||||
bool readPublicKeyFromCRT(const std::string& crtFilePath);
|
||||
bool convert_raw_to_der_ecdsa(const std::vector<uint8_t>& raw_signature, std::vector<uint8_t>& der_signature) const;
|
||||
std::vector<uint8_t> convert_from_hex_str(const std::string& input) const;
|
||||
#if USE_OPENSSL_FALLBACK
|
||||
#if USE_OPENSSL_3
|
||||
bool pubkey_copy(EVP_PKEY* src, EVP_PKEY** dest);
|
||||
EVP_PKEY* d_PublicKey{};
|
||||
#else
|
||||
#else // OpenSSL 1.x
|
||||
bool pubkey_copy(EC_KEY* src, EC_KEY** dest);
|
||||
EC_KEY* d_PublicKey = nullptr;
|
||||
#endif
|
||||
#else // GnuTLS
|
||||
gnutls_pubkey_t d_PublicKey{};
|
||||
bool convert_raw_to_der_ecdsa(const std::vector<uint8_t>& raw_signature, std::vector<uint8_t>& der_signature) const;
|
||||
bool pubkey_copy(gnutls_pubkey_t src, gnutls_pubkey_t* dest);
|
||||
gnutls_pubkey_t d_PublicKey{};
|
||||
#endif
|
||||
std::vector<uint8_t> d_x_4_0;
|
||||
std::vector<uint8_t> d_x_3_1;
|
||||
|
Loading…
Reference in New Issue
Block a user