加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

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

(2012-08-29 09:10:32)
标签:

it

/ 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


char *szX509RsaPswd = "PASSWORD";

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


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


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

   

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


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,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(0 == isCa)
    ...{
        if(0 != read_cert(&pCaCert, szIsser))
        ...{
            printf("read cert error ");
            return;
        }
    }

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

   
    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());
    }

   

    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

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有