X509_verify_cert函數負責用來驗證證書的有效性,函數原型如下
int X509_verify_cert(X509_STORE_CTX *ctx),驗證成功返回1,失敗返回其他值,失敗的原因可以通過
long nCode = X509_STORE_CTX_get_error(ctx);
const char * pChError = X509_verify_cert_error_string(nCode);得到
下面來演示一下如何使用這個函數
int VerifyCertificate()
{
//聲明X509_STORE用來存儲證書鏈
X509_STORE * certChain = NULL;
//證書鏈上下文
X509_STORE_CTX *ctx = NULL;
//初始化證書鏈
cerChain = X509_STORE_new();
//通過這個函數將被信任的證書加入信任鏈,rootCert是指被信任的證書,
for(int i = 0 ; i < nTrustCount ; i++)
{
X509 * rootCert = GetTrustCert();//這個函數openssl中沒有,用來讀取可以被信任的證書
X509_STORE_add_cert(certChain,rootCert);
}
//為證書鏈上下文分配內存
ctx = X509_STORE_CTX_new();
//初始化證書鏈上下文,certChain是證書鏈,cert是要被驗證的證書
X509_STORE_CTX_init(ctx,certChain,cert,NULL);
//在證書驗證之前,可以通過設置flags來確定驗證的內容,flags的內容在x509_vfy.h中聲明/* Certificate verify flags */之后就是
X509_STORE_CTX_set_flags(ctx,flags);
//驗證證書,根據返回值可以確認X509證書是否有效,也可以根據X509_STORE_CTX_get_error和X509_verify_cert_error_string函數來確認無效原因
int nX509Verify = X509_verify_cert(ctx);
if (1 != nX509Verify )
{
long nCode = X509_STORE_CTX_get_error(ctx);
const char * pChError = X509_verify_cert_error_string(nCode);
}
//釋放內存,這個很重要
if(NULL != ctx)
{
X509_STORE_CTX_free(ctx);
}
if (NULL != certChain)
{
X509_STORE_free(certChain);
}
return nX509Verify;
}
注:在驗證證書的過程中,證書鏈的構造一定要完整,例如root為自簽名的證書,頒發證書給TopCA,TopCA頒發證書給SecondCA,SecondCA頒發證書給User
為了驗證User的證書,root,TopCA,SecondCA都要在證書鏈中。
接下來我們看看X509_verify主要驗證的內容
int X509_verify_cert(X509_STORE_CTX *ctx)
{
//檢查頒發者
ctx->check_issued(ctx, x,x);
//檢查擴展部分
ok = check_chain_extensions(ctx);
/* Check name constraints ,檢查名稱約束*/
ok = check_name_constraints(ctx);
/* The chain extensions are OK: check trust,檢查信任部分 */
ok = check_trust(ctx);
/* Check revocation status,檢查撤銷狀態*/
ok = ctx->check_revocation(ctx);
/* At this point, we have a chain and need to verify it */
ok=internal_verify(ctx);
/* If we get this far evaluate policies */
ok = ctx->check_policy(ctx);
}
在internal_verify有檢查證書有效期的函數,即X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time);
ASN1_TIME可以通過X509_get_notBefore()與X509_get_notAfter()兩個函數來得到,time_t為從1970年1月1日凌晨算起的秒數,