#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/err.h>
#include <string.h>
#include <stdio.h>
#include <openssl/pem.h>
#include <fstream>
#include <openssl/sm3.h>
int main(void)
{
    EVP_MD_CTX *cmd_ctx = EVP_MD_CTX_new();
    EVP_PKEY_CTX* pctx = nullptr;  // Owned by |ctx|.
    const char*  filePath = "/media/arv000/c19ee280-30c9-43bc-a890-05e8c96984bc/00-work/01-bug/证书验证问题/国密SM2服务器根证书V3_client.pem";
    const char*  signature_value_bytes_filePath = "/home/arv000/signature_value_bytes.der";
    const char*  signed_data_filePath = "/home/arv000/signed_data.der";
    const EVP_MD *digest = EVP_sm3();
    // 读取公钥
    FILE* file = fopen(filePath, "rb");
    if(nullptr == file){
          printf("public_key opens is failed ;\r\n");
    }
    EVP_PKEY* public_key = PEM_read_PUBKEY(file, nullptr,nullptr,nullptr);
    if(nullptr == public_key){
         printf("public_key is null ;\r\n");
    }
    fclose(file);
    
    // 读取签名内容
    FILE* file2 = fopen(signature_value_bytes_filePath, "rb");
     // 获取文件大小
    fseek(file2, 0, SEEK_END);
    long signature_value_bytes_length = ftell(file2);
    fseek(file2, 0, SEEK_SET);
     char* signature_value_bytes = (char*)malloc(signature_value_bytes_length);
     memset(signature_value_bytes,0,signature_value_bytes_length);
     fread(signature_value_bytes, 1, signature_value_bytes_length, file2);
     fclose(file2);
    // 读取签名值内容

     FILE* file3 = fopen(signed_data_filePath, "rb");
     // 获取文件大小
    fseek(file3, 0, SEEK_END);
    long signed_data_length = ftell(file3);
    fseek(file3, 0, SEEK_SET);
     char* signed_data = (char*)malloc(signed_data_length);
     memset(signed_data,0,signed_data_length);
     fread(signed_data, 1, signed_data_length, file3);
     fclose(file3);
 

  if (!EVP_DigestVerifyInit(cmd_ctx, &pctx, digest, nullptr, public_key))
  {
     printf("EVP_DigestVerifyInit failed ;\r\n");
     return false;
  }
   

  if (!EVP_DigestVerifyUpdate(cmd_ctx, signed_data,
                              signed_data_length)) {
    printf("EVP_DigestVerifyUpdate failed ;\r\n");                           
    return false;
  }
  
  bool ret =
      1 == EVP_DigestVerifyFinal(cmd_ctx, reinterpret_cast<const unsigned char*>(signature_value_bytes),
                                 signature_value_bytes_length);

    printf("ret = %d ;\r\n",ret);
    return 0;
}