I am writing a C++ code using openssl api's to perform the following function
openssl dgst -sha256 -verify public_key.pem -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -signature signature.sig sw-description
Following is the C++ Code I have attempted
#include <openssl/core_names.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/types.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <iomanip>
bool verify_signature(const std::string& signature_file, const std::string& public_key_file, const std::string& data_file)
{
// Read the signature file
std::ifstream sig_file(signature_file, std::ios::binary);
if (!sig_file.is_open()) {
std::cerr << "Failed to open signature file: " << signature_file << std::endl;
return false;
}
std::vector<unsigned char> signature((std::istreambuf_iterator<char>(sig_file)), std::istreambuf_iterator<char>());
sig_file.close();
BIO* publicKeyBio = BIO_new_file(public_key_file.c_str(), "rb");
if (!publicKeyBio) {
perror("Failed to open public key file");
return false;
}
EVP_PKEY* pkey = PEM_read_bio_PUBKEY(publicKeyBio, nullptr, nullptr, nullptr);
if (!pkey) {
ERR_print_errors_fp(stderr);
std::cout<<"22";
return false;
}
// Read the data file
std::ifstream data_file_stream(data_file, std::ios::binary);
if (!data_file_stream.is_open()) {
std::cerr << "Failed to open data file: " << data_file << std::endl;
return false;
}
std::vector<unsigned char> data((std::istreambuf_iterator<char>(data_file_stream)), std::istreambuf_iterator<char>());
data_file_stream.close();
// Create a digest of the data using SHA-256
EVP_MD_CTX* md_ctx = EVP_MD_CTX_new();
if (!md_ctx) {
std::cerr << "Failed to create message digest context" << std::endl;
return false;
}
if (EVP_DigestInit_ex(md_ctx, EVP_sha256(), nullptr) != 1) {
std::cerr << "Failed to initialize message digest context" << std::endl;
EVP_MD_CTX_free(md_ctx);
return false;
}
if (EVP_DigestUpdate(md_ctx, data.data(), data.size()) != 1) {
std::cerr << "Failed to update message digest" << std::endl;
EVP_MD_CTX_free(md_ctx);
return false;
}
unsigned char digest[EVP_MAX_MD_SIZE];
unsigned int digest_len;
if (EVP_DigestFinal_ex(md_ctx, digest, &digest_len) != 1) {
std::cerr << "Failed to finalize message digest" << std::endl;
EVP_MD_CTX_free(md_ctx);
return false;
}
EVP_MD_CTX_free(md_ctx);
// Verify the signature using the public key and PSS padding scheme
EVP_MD_CTX* verify_ctx = EVP_MD_CTX_new();
if (!verify_ctx) {
std::cerr << "Failed to create signature verification context" << std::endl;
EVP_PKEY_free(pkey);
return false;
}
if (EVP_DigestVerifyInit(verify_ctx, nullptr, EVP_sha256(), nullptr, pkey) != 1) {
std::cerr << "Failed to initialize signature verification context" << std::endl;
EVP_MD_CTX_free(verify_ctx);
EVP_PKEY_free(pkey);
return false;
}
if (EVP_PKEY_CTX_set_rsa_padding(EVP_MD_CTX_pkey_ctx(verify_ctx), RSA_PKCS1_PSS_PADDING) <= 0) {
std::cerr << "Failed to set RSA-PSS padding in signature verification context" << std::endl;
EVP_MD_CTX_free(verify_ctx);
EVP_PKEY_free(pkey);
return false;
}
if (EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_MD_CTX_pkey_ctx(verify_ctx), -1) <= 0) {
std::cerr << "Failed to set RSA-PSS salt length in signature verification context" << std::endl;
EVP_MD_CTX_free(verify_ctx);
EVP_PKEY_free(pkey);
return false;
}
if (EVP_DigestVerifyUpdate(verify_ctx, digest, digest_len) != 1) {
ERR_print_errors_fp(stderr);
EVP_MD_CTX_free(verify_ctx);
EVP_PKEY_free(pkey);
return false;
}
// Verify the signature
if(EVP_DigestVerifyFinal(verify_ctx, signature.data(), signature.size()) != 1)
{
ERR_print_errors_fp(stderr);
std::cerr << "Signature verification failed" << std::endl;
EVP_MD_CTX_free(verify_ctx);
EVP_PKEY_free(pkey);
return false;
}
EVP_MD_CTX_free(verify_ctx);
EVP_PKEY_free(pkey);
std::cout << "Signature verification succeeded" << std::endl;
return true;
}
int main()
{
std::string signature_file = "signature_direct.sig";
std::string public_key_file = "public_key.pem";
std::string data_file = "sw.swu";
if (!verify_signature(signature_file, public_key_file, data_file)) {
std::cerr << "Signature verification failed" << std::endl;
return 1;
}
return 0;
}
`
On running the openssl command above, the signature verification is OK, however on using the same files in the C++ code, the signature verification fails.
Can somebody please help, where am I wrong in the code?
Aucun commentaire:
Enregistrer un commentaire