C语言 C中的x509证书验证

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2756553/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:21:07  来源:igfitidea点击:

x509 certificate verification in C

copenssl

提问by openssid

I do have certificates in DER and PEM format, my goal is to retrieve the fields of Issuer and Subject and verify the certificate with the CA public key and simultaneously verify CA certificate with the root public key. I am able to retrieve all the details of issuer and subject but unable to verify the certificate.
The API used:

我确实有 DER 和 PEM 格式的证书,我的目标是检索 Issuer 和 Subject 的字段并使用 CA 公钥验证证书,同时使用根公钥验证 CA 证书。我能够检索颁发者和主题的所有详细信息,但无法验证证书。
使用的 API:

x509 = d2i_X509_fp (fp, &x509); //READING DER Format
x509 = PEM_read_X509 (fp, &x509, NULL, NULL); //READING PEM Format
//to retrieve the Subject:
X509_NAME_oneline(X509_get_subject_name(x509), subject, sizeof (subject));
//to retrieve the Issuer:
X509_NAME_oneline(X509_get_issuer_name(x509), issuer, sizeof (issuer));

//To store the CA public key (in unsigned char *key) that will be used to verify the 
//certificate (in my case always sha1WithRSAEncryption):
RSA *x = X509_get_pubkey(x509)->pkey.rsa;
bn = x->n;
//extracts the bytes from public key & convert into unsigned char buffer
buf_len = (size_t) BN_num_bytes (bn);
stored_CA_pubKey = (unsigned char *)malloc (buf_len);
i_n = BN_bn2bin (bn, (unsigned char *)stored_CA_pubKey);
if (i_n != buf_len)
  LOG(ERROR," : key error\n");
if (key[0] & 0x80)
  LOG(DEBUG, "00\n");

stored_CA_pubKeyLen = EVP_PKEY_size(X509_get_pubkey(x509));

For Verification I went through different approaches but I am unable to verify:

对于验证,我采用了不同的方法,但无法验证:

a)

一种)

i_x509_verify = X509_verify(cert_x509, ca_pubkey);

b)

b)

/* verify the signature */
int iRet1, iRet2, iReason;
iRet1 = EVP_VerifyInit(&md_ctx, EVP_sha1());
iRet2 = EVP_VerifyUpdate(&md_ctx, cert_code, cert_code_len);
rv = EVP_VerifyFinal(&md_ctx, (const unsigned char *)stored_CA_pubKey,
     stored_CA_pubKeyLen, cert_pubkey);

NOTE : cert_code and stored_CA_pubKey are unsigned char buffers.

注意:cert_code 和 stored_CA_pubKey 是无符号字符缓冲区。

回答by pHagi

I use following code for verifying a certificate

我使用以下代码来验证证书

init CertStore:

初始化证书存储:

X509_STORE* m_store = X509_STORE_new();
X509_LOOKUP* m_lookup = X509_STORE_add_lookup(m_store,X509_LOOKUP_file());    
X509_STORE_load_locations(m_store, "CAFile.pem", NULL);
X509_STORE_set_default_paths(m_store);
X509_LOOKUP_load_file(m_lookup,"CAFile.pem",X509_FILETYPE_PEM)
// alternative lookup by hashdir
// X509_LOOKUP* m_lookup=X509_STORE_add_lookup(m_store,X509_LOOKUP_hash_dir());

VerifyCert:

验证证书:

X509_STORE_CTX *storeCtx = X509_STORE_CTX_new();
X509_STORE_CTX_init(storeCtx,m_store,cert,NULL);
X509_STORE_CTX_set_flags(storeCtx, X509_V_FLAG_CB_ISSUER_CHECK);
if (X509_verify_cert(storeCtx) == 1)
{
  printf("success");
}
else
{
  printf("Verificatione rror: %s",X509_verify_cert_error_string(storeCtx->error));
}
X509_STORE_CTX_free(storeCtx);

you also need to cleanup m_store

你还需要清理 m_store

if(m_store != NULL)
{
   X509_STORE_free(m_store);
   m_store = NULL;
}

回答by John

Take a look at my self-answered question: https://stackoverflow.com/questions/3412032/openssl-c-how-do-you-verify-a-public-key-was-issued-by-your-private-cait goes a long way to doing what you need.

看看我的自我回答问题:https: //stackoverflow.com/questions/3412032/openssl-c-how-do-you-verify-a-public-key-was-issued-by-your-private- ca做你需要的事情还有很长的路要走。

回答by openssid

X509_STORE* m_store = NULL;

X509_LOOKUP *m_lookup = NULL;
X509_STORE_CTX *storeCtx = NULL;
m_store = X509_STORE_new();
if(NULL == m_store) goto exit;
m_lookup = X509_STORE_add_lookup(m_store, X509_LOOKUP_file());
if(NULL == m_lookup) goto exit;
X509_STORE_load_locations(m_store, CA_CERT_PATH, NULL);
X509_STORE_set_default_paths(m_store);
X509_LOOKUP_load_file(m_lookup,CA_CERT_PATH, X509_FILETYPE_ASN1);
m_lookup = X509_STORE_add_lookup(m_store, X509_LOOKUP_hash_dir());
if(NULL == m_lookup) goto exit;
storeCtx = X509_STORE_CTX_new();
if(NULL == storeCtx) goto exit;
X509_STORE_CTX_init(storeCtx,m_store,cer_x509,NULL);
X509_STORE_CTX_set_flags(storeCtx, /*X509_V_FLAG_CHECK_SS_SIGNATURE*/0x4000);
if (X509_verify_cert(storeCtx) == 1)
{
printf("success\n");
}
else
{
printf("Verification error: %s\n",X509_verify_cert_error_string(storeCtx->error));
}
exit:
    if(NULL != storeCtx) X509_STORE_CTX_free(storeCtx);
    if(m_store != NULL)
    {
        X509_STORE_free(m_store);
        m_store = NULL;
    }

After Doing this also I am unable to verify Self signed certificate

这样做后,我也无法验证自签名证书