使用openssl编码实现一本自签名证书的示例(改进版)

 

//  ca_demo.cpp : Defines the entry point for the console application.
//

#include 
" stdafx.h "

#include 
< openssl / conf.h >
#include 
< openssl / bio.h >
#include 
< openssl / err.h >
#include 
< openssl / bn.h >
#include 
< openssl / txt_db.h >
#include 
< openssl / evp.h >
#include 
< openssl / x509.h >
#include 
< openssl / x509v3.h >
#include 
< openssl / objects.h >
#include 
< openssl / pem.h >
#include 
< openssl / engine.h >
#include 
< openssl / pkcs12.h >
#include 
< memory.h >
#include 
< malloc.h >
#include 
< stdio.h >

/*描述符长度*/
#define  MA_X509_ENTITY_LEN 128

/*密钥对文件名字长度*/
#define  MA_X509_RSAKEY_FILENAME_LEN 256

/*证书文件名字长度*/
#define  MA_X509_CERT_FILENAME_LEN 256

/*密钥对长度*/
#define  MA_X509_RSAKEY_LEN 1024

/*版本号*/
#define  MA_X509_V1 0
#define  MA_X509_V2 1
#define  MA_X509_V3 2

/*序列号*/
#define  MA_SN 1111

/*设置RSA密钥对的存储密钥*/
char   * szX509RsaPswd  =   " PASSWORD " ;

X509_REQ 
* req  =  NULL;
X509_NAME 
* pSubjectName = NULL;
X509_NAME_ENTRY 
* ent = NULL;
EVP_PKEY 
* pNewRsaKey  =  NULL;
EVP_MD 
* digest = NULL;

/*CONFIG*/
char  szCountry[MA_X509_ENTITY_LEN]  =   {0} ;
char  szState[MA_X509_ENTITY_LEN]  =   {0} ;
char  szLocation[MA_X509_ENTITY_LEN]  =   {0} ;
char  szCommonName[MA_X509_ENTITY_LEN]  =   {0} ;
char  szOrganization[MA_X509_ENTITY_LEN]  =   {0} ;
char  szOrganizationUnit[MA_X509_ENTITY_LEN]  =   {0} ;
char  szIsser[MA_X509_ENTITY_LEN]  =   {0} ;
unsigned 
long  ulSn  =   0 ;

char  szRsaKeyFileName[MA_X509_RSAKEY_FILENAME_LEN]  =   {0} ;
char  szRsaKey[MA_X509_RSAKEY_LEN]  =   {0} ;
char  szCertFileName[MA_X509_CERT_FILENAME_LEN]  =   {0} ;
char  szCaRsaKeyFileName[MA_X509_RSAKEY_FILENAME_LEN]  =   {0} ;

/*CA证书*/
X509 
* m_pCACert  =  NULL;

int  isCa  =   0 ;

/*默认配置*/
int  read_init()
{
    FILE 
*pFile = NULL;

    strcpy(szCountry, 
"CN");
    strcpy(szState, 
"ZJ");
    strcpy(szLocation, 
"HZ");
    strcpy(szCommonName, 
"CA_TEST");
    strcpy(szOrganization, 
"CODESTART");
    strcpy(szOrganizationUnit, 
"FW");

    pFile 
= fopen("config.ini""r");
    
if(NULL == pFile)
    
{
        printf(
"read_init:read config file error ");
        
return -1;
    }


    
/******************
    CN=piky
    COUNTRY=CN
    STATE=ZJ
    LOCATION=HZ
    ORGANIZATION=SNS
    ISSUER=SELF
    *****************
*/


    fscanf(pFile, 
"CN=%s ", szCommonName);
    fscanf(pFile, 
"COUNTRY=%s ", szCountry);
    fscanf(pFile, 
"STATE=%s ", szState);
    fscanf(pFile, 
"LOCATION=%s ", szLocation);
    fscanf(pFile, 
"ORGANIZATION=%s ", szOrganization);
    fscanf(pFile, 
"ISSUER=%s ", szIsser);
    fscanf(pFile, 
"ISSUERKEY=%s ", szCaRsaKeyFileName);
    fscanf(pFile, 
"SN=%d"&ulSn);

    printf(
"read entity: CN=%s,COUNTRY=%s,STATE=%s,LOCATION=%s,ORGANIZATION=%s,ISSUER=%s,ISSUERKEY=%s "
        szCommonName,
        szCountry,
        szState,
        szLocation,
        szOrganization,
        szIsser,
        szCaRsaKeyFileName);

    sprintf(szCertFileName, 
"CN=%s.cert.pem", szCommonName);
    sprintf(szRsaKeyFileName, 
"CN=%s.key.pem",szCommonName);

    
if (!strcmp(szIsser, "SELF"|| 0 == szIsser[0])
    
{
        isCa 
= 1;
        sprintf(szCertFileName, 
"ca.cert.pem");
        sprintf(szRsaKeyFileName, 
"ca.key.pem");
    }


    
return 0;
}


int  read_cert(X509 **  pCert,  char   * pCertFile)
{
    BIO 
*pbio;
    
if(NULL == pCert || NULL == pCertFile)
    
{
        printf(
"read_cert:parament error(%x,%x) "*pCert, pCertFile);
        
return -1;
    }


    pbio 
= BIO_new_file(pCertFile,"r");
    
if(NULL == pbio)
    
{
        printf(
"read_cert:create bio file error ");
        
return -1;
    }


    
*pCert = PEM_read_bio_X509(pbio,NULL,NULL,NULL);
    
if(NULL == *pCert)
    
{
        printf(
"read_cert:call PEM_read_bio_X509 error ");
        BIO_free(pbio);
        
return -1;
    }


    BIO_free(pbio);
    
return 0;
}


int  read_rsa_key(EVP_PKEY  ** pNewRsaKey,  char   * pRsaKeyFile, unsigned  char * pPwd)
{
    BIO 
*pbio;
    
if(NULL == pNewRsaKey || NULL == pRsaKeyFile || NULL == pPwd)
    
{
        
return -1;
    }


    pbio 
= BIO_new_file(pRsaKeyFile,"r");
    
if(NULL == pbio)
    
{
        
return -1;
    }


    
*pNewRsaKey = PEM_read_bio_PrivateKey(pbio,NULL,0,NULL);
    
if(NULL == *pNewRsaKey)
    
{
        printf(
"read_rsa_key:call PEM_read_bio_PrivateKey error ");
        BIO_free(pbio);
        
return -1;
    }


    BIO_free(pbio);
    
return 0;
}


/*存储RSA密钥对*/
int  save_rsa_key(EVP_PKEY  * pNewRsaKey)
{
    BIO 
*pbio;

    
if(NULL == pNewRsaKey)
    
{
        
return -1;
    }


    pbio 
= BIO_new_file(szRsaKeyFileName,"w");
    
if(NULL == pbio)
    
{
        printf(
" save_rsa_key:create bio file error");
        
return -1;
    }


    
/*存储密钥*/
/*if(!PEM_write_bio_PrivateKey(pbio, pNewRsaKey,EVP_des_cbc(),
            (unsigned char *)szX509RsaPswd, strlen(szX509RsaPswd),0,NULL))
*/


    
if(!PEM_write_bio_PrivateKey(pbio, pNewRsaKey,NULL,NULL, 0,0,NULL))
    
{
        printf(
"save_rsa_key:call PEM_write_bio_PrivateKey error");
        
return -1;
    }


    BIO_free(pbio);
    
return 0;
}


/*存储证书*/
int  save_cert(X509  * pCert,  char   * pCertFile)
{
    BIO 
*pbio;

    
if(NULL == pCert || NULL == pCertFile)
    
{
        
return -1;
    }


    pbio 
= BIO_new_file(pCertFile,"w");
    
if(NULL == pbio)
    
{
        
return -1;
    }


    
if(!PEM_write_bio_X509(pbio,pCert))
    
{
        printf(
"save_cert:call PEM_write_bio_X509 error ");
        
return -1;
    }


    BIO_free(pbio);
    
return 0;
}


/*读取配置文件*/
int  read_config()
{
    read_init();
    
return 0;
}


void  add_subject_entity( char   * key,  char   * value)
{
    
int nid;
    X509_NAME_ENTRY 
*ent;
    
if( (nid =OBJ_txt2nid(key)) == NID_undef )
    
{
        printf(
" add_subject_entity:concert nid error");
        
return ;
    }


    ent 
= X509_NAME_ENTRY_create_by_NID(NULL,nid,MBSTRING_UTF8,
        (unsigned 
char*)value,-1);
    
if(ent == NULL)
    
{
        printf(
"add_subject_entity:create ent error");
        
return;
    }


    
if(X509_NAME_add_entry(pSubjectName,ent,-1,0!= 1)
    
{
        printf(
"add_subject_entity:add to subjectname error");
        
return;
    }

    
return;
}


int  create_req()
{
    
/*读取配置文件*/
    
if(0 != read_config())
    
{
        
return -1;
    }


    
/*申请请求内存*/
    req 
= X509_REQ_new();

    
/*创建密钥对*/
    pNewRsaKey 
= EVP_PKEY_new();
    EVP_PKEY_assign_RSA(pNewRsaKey, RSA_generate_key(
512,0x10001,NULL,NULL));
    X509_REQ_set_pubkey(req,pNewRsaKey);

    
/*保存密钥对*/
    
if(0 != save_rsa_key(pNewRsaKey))
    
{
        printf(
"call save_rsa_key error ");
        
return -1;
    }


    pSubjectName 
= X509_NAME_new();
    
if(pSubjectName == NULL)
    
{
        printf(
"create_req_demo:create subjectname error ");
        
return -1;
    }


    
/*添加实体字段*/
    add_subject_entity(
"countryName", szCountry);
    add_subject_entity(
"stateOrProvinceName", szState);
    add_subject_entity(
"localityName", szLocation);
    add_subject_entity(
"organizationName", szOrganization);
    add_subject_entity(
"commonName", szCommonName);

    
/*添加实体*/
    
if(1 != X509_REQ_set_subject_name(req,pSubjectName))
    
{
        printf(
"create_req_demo:add subjectname to req error");
        
return -1;
    }


    
return 0;
}


void  create_cert_demo()
{
    
int ret = 0;
    X509 
*certTmp =NULL;
    X509 
*pCaCert = NULL;
    X509_NAME 
*pName=NULL;//X509_NAME_new();
    EVP_PKEY *pCaRsaKey = NULL;
    
char szRsaKeyFileName[256= {0};

    
/*创建请求*/
    ret 
= create_req();
    
if (0 != ret)
    
{
        
return;
    }


    
/*if (!strcmp(szIsser, "SELF") || 0 == szIsser[0])
    {
        isCa = 1;
    }
    else
*/

    
if(0 == isCa)
    
{
        
if(0 != read_cert(&pCaCert, szIsser))
        
{
            printf(
"read cert error ");
            
return;
        }

    }


    
/*申请内存*/
    certTmp 
= X509_new();
    
if (NULL == certTmp)
    
{
        printf(
"内存申请失败");
        
return;
    }


    
/*设置版本号:V3*/
    ret 
= X509_set_version(certTmp, MA_X509_V3);
    
if (ret != 1)
    
{
        printf(
"设置证书版本错误:0x%x",ret);
        
return;
    }


    
/*设置序列号*/
    ret 
= ASN1_INTEGER_set(X509_get_serialNumber(certTmp),ulSn);
    
if (ret != 1)
    
{
        printf(
"设置序列号错误:0x%x", ret);
        
return;
    }


    
/*设置开始时间*/
    
if(!X509_gmtime_adj(X509_get_notBefore(certTmp),0))
    
{
        printf(
"设置开始时间失败:0x%x", ret);
        
return;
    }


    
if (!X509_gmtime_adj(X509_get_notAfter(certTmp), (long)60*60*24*10))
    
{
        printf(
"设置结束时间失败");
    }


    
if (!X509_set_subject_name(certTmp, X509_REQ_get_subject_name(req)))
    
{
        printf(
"设置请求失败");
    }


    EVP_PKEY 
*tmppkey = X509_REQ_get_pubkey(req);
    
if (!tmppkey || !X509_set_pubkey(certTmp,tmppkey))
    
{
        EVP_PKEY_free(tmppkey);
        printf(
"设置公钥失败");
    }

    EVP_PKEY_free(tmppkey);

    
if(1 == isCa)
    
{
        pName 
= X509_REQ_get_subject_name(req);
    }

    
else
    
{
        pName 
= X509_get_subject_name(pCaCert);
    }


    
if(NULL == pName)
    
{
        printf(
"get issuer name error ");
        
return;
    }


    
if (!X509_set_issuer_name(certTmp, pName))
    
{
        printf(
"设置签发者名字失败 ");
        
return;
    }


    
if(1 == isCa)
    
{
        X509_sign(certTmp, pNewRsaKey, EVP_sha1());
    }

    
else
    
{
        
if(0 != read_rsa_key(&pCaRsaKey, szCaRsaKeyFileName, (unsigned char *)szX509RsaPswd))
        
{
            printf(
"read rsa key error ");
            
return;
        }

        X509_sign(certTmp, pCaRsaKey, EVP_sha1());
    }


    
/**********************************************
    BIO *pbio;
    pbio = BIO_new(BIO_s_mem());
    PEM_write_bio_X509(pbio,certTmp);
    BUF_MEM * bptr;
    BIO_get_mem_ptr(pbio,&bptr);
  
    char *buf = (char *)malloc(bptr->length);
    if(NULL == buf)
    {
        printf("malloc error");
        return;
    }

    memcpy(buf, bptr->data, bptr->length);
    printf("%s ", buf);
    *********************************************
*/


    
if(0 == save_cert(certTmp, szCertFileName))
    
{
        printf(
"create cert successfully, cert file name is %s ", szCertFileName);
        
return;
    }

    
return;
}


int  main( int  argc,  char *  argv[])
{
    create_cert_demo();
    system(
"pause");
    
return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值