openssl主要流程程序代码

本文档提供了openssl库的C语言代码,用于处理不同格式(如DER, PEM, P12)的证书和密钥加载。包含了读取、转换、分解和合并P12包的功能,以及公钥、私钥的验证和格式转换。同时,还涉及随机数生成、根证书创建以及证书吊销列表(CRL)的生成。代码中包含了关键函数如`LoadCert`、`LoadKey`、`ParseDB`和`CreateDB`等,用于证书和密钥的处理。" 114899011,10539915,SpringBoot使用POI导出Excel文件示例,"['Java', 'Spring框架', 'Excel处理', '文件导出']
摘要由CSDN通过智能技术生成
// CA.cpp : Defines the entry point for the DLL application.    
//    
#define sprintf_s sprintf     
#include "stdafx.h"    
#include <LOCALE.H>    
#include "ca.h"    
#include <OPENSSL pem.h>    
#include <OPENSSL x509.h>    
#include <OPENSSL x509v3.h>    
#include <OPENSSL pkcs12.h>    
#include <OPENSSL rand.h>    
#include<STDLIB.H>    
#include<STDIO.H>    
#include <OPENSSL engine.h>    
#define EXT_COPY_NONE   0    
#define EXT_COPY_ADD    1    
#define EXT_COPY_ALL    2    
   
   
BOOL APIENTRY DllMain( HANDLE hModule,    
                       DWORD  ul_reason_for_call,    
                       LPVOID lpReserved   
                     )   
{   
    return TRUE;   
}   
   
/*此函数可以将DER、PEM、P12文件公钥读出来*/   
X509 *load_cert(BIO *cert/*输入BIO*/, int format/*格式*/,char * pwd,/*P12密码*/   
                char * outMsg) //从DER、PEM、P12格式中读取公钥证书    
{   
    X509 * x=NULL;   
    if  (format == DER)   
        x=d2i_X509_bio(cert,NULL);   
    else if (format == PEM)   
        x=PEM_read_bio_X509(cert,NULL,NULL,NULL);//PEM_read_bio_X509_AUX    
    else if (format == P12)   
    {   
        PKCS12 *p12 = d2i_PKCS12_bio(cert, NULL);   
        PKCS12_parse(p12, pwd, NULL, &x, NULL);   
        PKCS12_free(p12);   
        p12 = NULL;   
    }   
    else   
    {   
           
sprintf_s(outMsg,"bad input format specified for input cert\n");   
        goto end;   
    }   
end:   
    if (x == NULL)   
    {   
        sprintf(outMsg,"unable to load certificate\n");   
    }   
    return(x);   
}   
   
X509 * LoadCert(char * cert,int certlen,char * outMsg)//枚举DER/PEM格式    
{   
    BIO * in=NULL;   
    X509 * x509=NULL;   
   
    if(certlen==0)//输入为磁盘文件    
    {   
        if((in=BIO_new_file(cert, "r")) == NULL)   
        {   
            sprintf(outMsg,"open CA certificate file error");   
            return NULL;   
        }   
    }   
    else//输入为内存中文件    
    {   
        if((in=BIO_new_mem_buf(cert,certlen))== NULL)//只读类型    
        {   
            sprintf(outMsg,"Make Mem Bio Error");   
            return NULL;   
        }   
    }   
    if((x509=load_cert(in,DER,NULL,outMsg))==NULL)//尝试DER    
    {   
        BIO_reset(in);//恢复bio    
        x509=load_cert(in,PEM,NULL,outMsg);//尝试PEM    
    }   
    if (in != NULL) BIO_free(in);   
    return x509;   
}   
   
EVP_PKEY *load_key(BIO *bio, int format, char *pass,char * outMsg)//枚举DER/PEM格式    
{   
    EVP_PKEY *pkey=NULL;   
   
    if (format == DER)   
    {   
        pkey=d2i_PrivateKey_bio(bio, NULL);   
    }   
    else if (format == PEM)   
    {   
        pkey=PEM_read_bio_PrivateKey(bio,NULL,NULL,pass);   
    }   
    else if (format == P12)   
    {   
        PKCS12 *p12 = d2i_PKCS12_bio(bio, NULL);   
        PKCS12_parse(p12, pass, &pkey, NULL, NULL);   
        PKCS12_free(p12);   
        p12 = NULL;   
    }   
    else   
    {   
        sprintf(outMsg,"bad input format specified for key\n");   
        goto end;   
    }   
end:   
    if (pkey == NULL)   
        sprintf(outMsg,"unable to load Private Key\n");   
    return(pkey);   
}   
   
EVP_PKEY * LoadKey(char * key,int keylen,char * pass,char * outMsg)   
{   
    EVP_PKEY *pkey=NULL;   
    BIO * in=NULL;   
   
    if(keylen==0)//输入为磁盘文件    
    {   
        if((in=BIO_new_file(key, "r")) == NULL)   
        {   
            sprintf(outMsg,"open CA certificate file error");   
            return NULL;   
        }   
    }   
    else//输入为内存中文件    
    {   
        if((in=BIO_new_mem_buf(key,keylen))== NULL)//只读类型    
        {   
            sprintf(outMsg,"Make Mem Bio Error");   
            return NULL;   
        }   
    }   
   
    if((pkey=load_key(in,DER,pass,outMsg))==NULL)//尝试DER    
    {   
        BIO_reset(in);//BIO是可读写的,那么该BIO所有数据都会被清空;    
                        //如果该BIO是只读的,那么该操作只会简单将指    
                        //针指向原始位置,里面的数据可以再读.    
        pkey=load_key(in,PEM,pass,outMsg);//尝试PEM    
    }   
    if (in != NULL) BIO_free(in);   
    return pkey;   
}   
int Rand(const char *file,int dont_warn,char * outMsg)//产生随机数,return 0 ---成功    
{   
    int consider_randfile = (file == NULL);   
    char buffer[200];   
       
    RAND_screen();   
    if (file == NULL)   
        file = RAND_file_name(buffer, sizeof buffer);   
    else if (RAND_egd(file) > 0)   
    {   
    /* we try if the given filename is an EGD socket.  
        if it is, we don't write anything back to the file. */   
        return 1;   
    }   
    if (file == NULL || !RAND_load_file(file, -1))   
    {   
        if (RAND_status() == 0 && !dont_warn)   
        {   
            sprintf(outMsg,"unable to load 'random state'\n");   
            sprintf(outMsg,"This means that the random number generator has not been seeded\n");   
            if (consider_randfile) /* explanation does not apply when a file is explicitly named */   
            {   
                sprintf(outMsg,"Consider setting the RANDFILE environment variable to point at a file that\n");   
                sprintf(outMsg,"'random' data can be kept in (the file will be overwritten).\n");   
            }   
        }   
        return 0;   
    }   
    return 1;   
}   
   
   
/ end     
//    
/ begin //    
   
/* Add extension using V3 code: we can set the config file as NULL  
* because we wont reference any other sections.  
*/   
int Add_ExtCert(X509 *cert/*正被添加的证书*/,X509 * root/*根证书(从中得到信息)*/, int nid, char *value)   
{   
    X509_EXTENSION *ex;   
    X509V3_CTX ctx;   
    /* This sets the 'context' of the extensions. */   
    /* No configuration database */   
    //  X509V3_set_ctx_nodb(&ctx);    
    /* Issuer and subject certs: both the target since it is self signed,  
    * no request and no CRL  
    */   
    X509V3_set_ctx(&ctx,root, cert, NULL, NULL, 0);   
    ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);   
    if (!ex)   
        return 0;   
       
    X509_add_ext(cert,ex,-1);   
    X509_EXTENSION_free(ex);   
    return 1;   
}   
   
bool Add_Name(X509_NAME * x509name,int type/*c\cn*/,char * iput/*中国*/,   
              int ilen/*输入长度*/,char * outMsg)//支持中文名称    
{   
    wchar_t * ws,wc;   
    ASN1_STRING stmp, *str = &stmp;   
    UCHAR cbuf[256]={0};   
    int wslen, wcnt,i;   
    char input[256]={0};   
    strncpy(input, iput, ilen);   
    wslen = strlen(input) + 1;   
    if(wslen==1)   
        return true;   
  ws =new unsigned short[sizeof(wchar_t) * wslen];     
    if ((wcnt = mbstowcs(ws, input, wslen)) == -1)   
    {   
        sprintf(outMsg,"mbstowcs convert error");   
        delete ws;   
        return false;                  
    }   
    for(i=0;i<(int)wcslen(ws);i++)   
    {    
        wc=ws[i];   
        cbuf[2*i]=wc/256;   
        cbuf[2*i+1]=wc%256;   
    }   
   
    ASN1_mbstring_copy(&str, cbuf, 2*wslen, MBSTRING_BMP, B_ASN1_UTF8STRING);   
    X509_NAME_add_entry_by_NID(x509name,type,V_ASN1_UTF8STRING,stmp.data,stmp.length, -1, 0);   
    delete ws;   
    return true;   
}   
bool mkRoot(stuSUBJECT * rootInfo,X509 **x509p/*out公钥*/, EVP_PKEY **pkeyp/*out私钥*/,    
           int bits/*位数*/, int serial/*序列号*/, int days/*有效期*/,char * out/*操作结果*/)   
{   
    X509 *x;   
    EVP_PKEY *pk;   
    RSA *rsa;   
    X509_NAME *name=NULL;   
    int i=0,len=0;   
    if ((pkeyp == NULL) || (*pkeyp == NULL))   
    {   
        if ((pk=EVP_PKEY_new()) == NULL)   
        {   
            abort();    
            return false;   
        }   
    }   
    else   
        pk= *pkeyp;   
       
    if ((x509p == NULL) || (*x509p == NULL))   
    {   
        if ((x=X509_new()) == NULL)   
            goto err;   
    }   
    else   
        x= *x509p;   
   
    Rand(NULL,1,out);//产生随机数种子    
    rsa=RSA_generate_key(bits,RSA_F4,0/*回调函数callback*/,NULL);//产生密钥对,//RSA存储了公钥私钥    
    if (!EVP_PKEY_assign_RSA(pk,rsa))//完成RSA密钥的pkey结构初始工作,当pk不为NULL的时候,返回1,否则返回0    
    {   
        abort();   
        goto err;   
    }   
    rsa=NULL;   
       
    X509_set_version(x,2);//版本号,显示+1    
    ASN1_INTEGER_set(X509_get_serialNumber(x),serial);//序列号    
    X509_gmtime_adj(X509_get_notBefore(x),0);//起始时间    
    X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);//结束时间    
    X509_set_pubkey(x,pk);//公钥    
       
    name=X509_get_subject_name(x);   
       
    /* This function creates and adds the entry, working out the  
    * correct string type and performing checks on its length.  
    * Normally we'd check the return value for errors  
    */   
   
    //C-国家,ST-省,L-城市,O-组织,OU-部门,CN-个体,T-title,D-description,G-givenName,I-initials,    
    //Email-emailAddress,S-surname,SN-serialNumber,dnQualifier-dnQualifier,unstructuredName,challengePassword,unstructuredAddress,    
   
    setlocale(LC_CTYPE, "");   
   
    Add_Name(name,NID_countryName,(char *)rootInfo->C,sizeof(rootInfo->C),out);   
    Add_Name(name,NID_stateOrProvinceName,(char *)rootInfo->ST,sizeof(rootInfo->ST),out);   
    Add_Name(name,NID_localityName,(char *)rootInfo->L,sizeof(rootInfo->L),out);   
    Add_Name(name,NID_organizationName,(char *)rootInfo->O,sizeof(rootInfo->O),out);   
    Add_Name(name,NID_organizationalUnitName,(char *)rootInfo->OU,sizeof(rootInfo->OU),out);   
    Add_Name(name,NID_commonName,(char *)rootInfo->CN,sizeof(rootInfo->CN),out);   
    Add_Name(name,NID_pkcs9_emailAddress,(char *)rootInfo->MAIL,sizeof(rootInfo->MAIL),out);   
    Add_Name(name,NID_email_protect,(char *)rootInfo->PMAIL,sizeof(rootInfo->PMAIL),out);   
   
       
    Add_Name(name,NID_title,(char *)rootInfo->T,sizeof(rootInfo->T),out);   
    Add_Name(name,NID_description,(char *)rootInfo->D,sizeof(rootInfo->D),out);   
    Add_Name(name,NID_givenName,(char *)rootInfo->G,sizeof(rootInfo->G),out);    
    Add_Name(name,NID_initials,(char *)rootInfo->I,sizeof(rootInfo->I),out);   
    Add_Name(name,NID_name,(char *)rootInfo->NAME,sizeof(rootInfo->NAME),out);       
    Add_Name(name,NID_surname,(char *)rootInfo->S,sizeof(rootInfo->S),out);   
    Add_Name(name,NID_dnQualifier,(char *)rootInfo->QUAL,sizeof(rootInfo->QUAL),out);   
    Add_Name(name,NID_pkcs9_unstructuredName,(char *)rootInfo->STN,sizeof(rootInfo->STN),out);   
    Add_Name(name,NID_pkcs9_challengePassword,(char *)rootInfo->PW,sizeof(rootInfo->PW),out);   
    Add_Name(name,NID_pkcs9_unstructuredAddress,(char *)rootInfo->ADD,sizeof(rootInfo->ADD),out);   
   
    /* Its self signed so set the issuer name to be the same as the  
    * subject.  
    */   
       
    X509_set_issuer_name
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值