4

我们如何使用 X509_verify()。我有两个证书。第一个证书是签署下一个证书(这是我的证书)的根证书。所以我想检查我的证书是否由根证书在 C++ 中使用 x509_verify() 签名。我的目标是保持代码简单易懂,这样我也可以把它放到网上。

4

3 回答 3

12

X509_verify 的签名是

 int X509_verify(X509 * x509, EVP_PKEY * pkey);

假设您在 root 中有根证书,在 mycert 中有您的证书;

   X509 * root;
   X509 * mycert;

//Get root certificate into root
//Get mycert into mycert.

//Get the public key.
EVP_PKEY * pubkey = X509_get_pubkey(root);

//verify. result less than or 0 means not verified or some error.
int result = X509_verify(mycert, pubkey);

//free the public key.
EVP_PKEY_free(pubkey);

我想这会对你有所帮助。

于 2013-05-10T05:09:10.450 回答
4

I think dbasic and Balamurugan answered how to use it. Here's how to interpret the errors you get from it. I find error handling is much more important than business logic because nearly anyone can copy/paste code that works in a benign environment. How you respond to failures, broken/bad inputs and a hostile environments matter more.

The source code for the function is in <openssl dir>/crypto/x509/x_all.c:

int X509_verify(X509 *a, EVP_PKEY *r)
    {
    return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF),a->sig_alg,
        a->signature,a->cert_info,r));
    }

ASN1_item_verify id defined in <openssl dir>/crypto/asn1/a_verify.c:

int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *alg,
        ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
    {
        ...
    }

The function returns -1 on failure with one of the following error codes:

  • ERR_R_PASSED_NULL_PARAMETER if pkey is NULL
  • ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM if alg is unknown using an OID lookup
  • ASN1_R_WRONG_PUBLIC_KEY_TYPE if the pkey type does not match the pkey->method
  • ERR_R_MALLOC_FAILURE if a buffer allocation fails

The function returns 0 on failure with one of the following error codes:

  • ERR_R_EVP_LIB if EVP_DigestVerifyInit fails
  • ERR_R_EVP_LIB if EVP_DigestVerifyUpdate fails
  • ERR_R_EVP_LIB if EVP_DigestVerifyFinal fails

On success, the function returns 1 (from around line 220):

    ...
    if (EVP_DigestVerifyFinal(&ctx,signature->data,
            (size_t)signature->length) <= 0)
        {
        ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
        ret=0;
        goto err;
        }

    ret=1;

err:
    EVP_MD_CTX_cleanup(&ctx);
    return(ret);

    } /* End of function */

From <openssl dir>/crypto/err/err.h, you use ERR_get_error() to retrieve the error code:

err.h:#define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),__FILE__,__LINE__)
于 2014-03-08T05:56:08.880 回答
3

Step1 : 读取证书并将证书转换为 X509 结构 // 下面将展示如何从文件中读取证书(DER 或 PEM 编码)

X509* oCertificate=NULL;
FILE *lFp=NULL;
lFp=fopen(iFilePath.c_str(),"rb");  // iFilepath is the string 
if(lFp==NULL)
{
    oCertificate=NULL;      
}
else
{
    oCertificate = PEM_read_X509(lFp, NULL, NULL, NULL);
            if (oCertificate  == NULL )
            {
              //Certificate may be DER encode 
             oCertificate = d2i_X509_fp(lFp, NULL);
            }    
    fclose(lFp);
}
// OCertificate contains

第2步:现在读取根证书密钥(注意在使用前检查X509是否为NULL)

第 3 步:使用 X509_verify() 函数。

于 2013-06-19T05:25:28.273 回答