x509证书验证
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日凌晨算起的秒數,
總結
- 上一篇: Lync Server 2013企业版部
- 下一篇: IIS配置教程。。。。。