// 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;
}