仪陇家园分类信息网、仪陇生活网、仪陇家园网

搜索

OPENSSL X509证书验证

[复制链接]
seo 发表于 2022-5-31 13:32:11 | 显示全部楼层 |阅读模式
OPENSSL X509证书验证发布时间:2022/5/31 13:09:51
            
                                                       
                                                       
            
        
        
               
                    openssl实现了标准的x509v3数字证书,其源码在crypto/x509和crypto/x509v3中。其中x509目录实现了数字证书以及证书申请相关的各种函数,包括了X509和X509_REQ结构的设置、读取、打印和比较;数字证书的验证、摘要;各种公钥的导入导出等功能。x509v3目录主要实现了数字证书扩展项相关的函数。

在进行身份认证时,首先要对发送给服务器进行认证的x509证书有效性进行验证,在Openssl中,可以用一个API接口可以实现:int X509_verify_cert(X509_STORE_CTX *ctx);
接口中形参是X509_STORE_CTX(X509证书库上下文)类型,在X509证书库上下文中,存在一个X509证书库和一个待验证的X509证书,可以加入信任的证书链,也可以加入CRL证书链(证书撤销列表)~
对X509证书有效性进行验证可以由以下几个函数来完成~

X509_STORE_CTX *ctx; //证书上下文  
X509_STORE *cert_store; //证书库,存在证书链  
X509* x509; //待验证X509证书  
ctx = X509_STORE_CTX_new();  
X509_STORE_CTX_init(ctx,cert_store,x509,NULL);  
X509_verify_cert(ctx);//根据返回值可以确认X509证书是否有效,也可以根据X509_STORE_CTX_get_error和X509_verify_cert_error_string函数来确认无效原因   
示例程序如下:

#include
#include
#include
#include
#include
#define CERT_PATH       "/home/dengaj/Desktop/openssl"
#define ROOT_CERT       "RootCert.crt"
#define CARD_CERT       "CardCert.crt"
#define GET_DEFAULT_CA_CERT(str) sprintf(str, "%s/%s", CERT_PATH, ROOT_CERT)
#define GET_CUSTOM_CERT(str, path, name) sprintf(str, "%s/%s", path, name)
#define MAX_LEGTH 4096

int my_load_cert(unsigned char *str, unsigned long *str_len,
              const char *verify_cert, const unsigned int cert_len)
{
    FILE *fp;
    fp = fopen(verify_cert, "rb");
    if ( NULL == fp)
    {
        fprintf(stderr, "fopen fail\n");
        return -1;
    }
    *str_len = fread(str, 1, cert_len, fp);
    fclose(fp);
    return 0;
}
X509 *der_to_x509(const unsigned char *der_str, unsigned int der_str_len)
{
    X509 *x509;
    x509 = d2i_X509(NULL, &der_str, der_str_len);
    if ( NULL == x509 )
    {
        fprintf(stderr, "d2i_X509 fail\n");
        return NULL;
    }
    return x509;
}
int x509_verify()
{
    int ret;
    char cert[MAX_LEGTH];
    unsigned char user_der[MAX_LEGTH];
    unsigned long user_der_len;
    X509 *user = NULL;
    unsigned char ca_der[MAX_LEGTH];
    unsigned long ca_der_len;
    X509 *ca = NULL;
    X509_STORE *ca_store = NULL;
    X509_STORE_CTX *ctx = NULL;
    STACK_OF(X509) *ca_stack = NULL;
    /* x509初始化 */
    ca_store = X509_STORE_new();
    ctx = X509_STORE_CTX_new();
    /* root ca*/
    GET_DEFAULT_CA_CERT(cert);
    /* 从文件中读取 */
    my_load_cert(ca_der, &ca_der_len, cert, MAX_LEGTH);
    /* DER编码转X509结构 */
    ca = der_to_x509(ca_der, ca_der_len);
    /* 加入证书存储区 */
    ret = X509_STORE_add_cert(ca_store, ca);
    if ( ret != 1 )
    {
        fprintf(stderr, "X509_STORE_add_cert fail, ret = %d\n", ret);
        goto EXIT;
    }
    /* 需要校验的证书 */
    GET_CUSTOM_CERT(cert, CERT_PATH, CARD_CERT);
    my_load_cert(user_der, &user_der_len, cert, MAX_LEGTH);
    user = der_to_x509(user_der, user_der_len);
    ret = X509_STORE_CTX_init(ctx, ca_store, user, ca_stack);
    if ( ret != 1 )
    {
        fprintf(stderr, "X509_STORE_CTX_init fail, ret = %d\n", ret);
        goto EXIT;
    }
    //openssl-1.0.1c/crypto/x509/x509_vfy.h
    ret = X509_verify_cert(ctx);
    if ( ret != 1 )
    {
        fprintf(stderr, "X509_verify_cert fail, ret = %d, error id = %d, %s\n",
                ret, ctx->error, X509_verify_cert_error_string(ctx->error));
        goto EXIT;
    }
    fprintf(stdout, "X509_verify_cert successful\n");
EXIT:
    X509_free(user);
    X509_free(ca);
    X509_STORE_CTX_cleanup(ctx);
    X509_STORE_CTX_free(ctx);
    X509_STORE_free(ca_store);
    return ret == 1 ? 0 : -1;
}
int main()
{
    OpenSSL_add_all_algorithms();
    x509_verify();
    return 0;
}


第二种方法使用

int X509_verify(X509 * x509, EVP_PKEY * pkey);
  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);

               
        
        
  
   
      
        

      
      
        
          创作挑战赛
         

        
        新人创作奖励来咯,坚持创作打卡瓜分现金大奖
      
   
  
   
            
        
        
回复

使用道具 举报

全部回复0 显示全部楼层

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

楼主

审核员

热门推荐

联系客服 关注微信 下载APP 返回顶部 返回列表