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日凌晨算起的秒數,


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM