How can we use X509_verify(). I have two certificates. The first certificate is the Root Certificate which signed the next certificate (which is my Certificate). So I want to check if my certificate is signed by the root certificate using x509_verify() in C++. My goal is to keep the code simple and Understandable so I can also put it online.
问题:
回答1:
Signature of X509_verify is
int X509_verify(X509 * x509, EVP_PKEY * pkey);
Suppose of you have root certificate in root and your certificate in 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);
I think this would help you.
回答2:
Step1 : Read the certificate and convert the Certificate into X509 structure // the below will show how to read the certificate from the file (DER or PEM Encoded)
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
Step 2: now read the Root certificate key (Note check the X509 is NULL or not before use)
Step 3 : use the X509_verify() function.
回答3:
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
ifpkey
isNULL
ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM
ifalg
is unknown using an OID lookupASN1_R_WRONG_PUBLIC_KEY_TYPE
if thepkey
type does not match thepkey->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
ifEVP_DigestVerifyInit
failsERR_R_EVP_LIB
ifEVP_DigestVerifyUpdate
failsERR_R_EVP_LIB
ifEVP_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__)