首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

openssl重要流程程序代码

2013-10-22 
openssl主要流程程序代码// CA.cpp : Defines the entry point for the DLL application.//#define sprint

openssl主要流程程序代码

// 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(x,name);//设置发行者名称等同于上面的           //加入扩展信息        /* Add various extensions: standard extensions */       Add_ExtCert(x,x,NID_basic_constraints, "critical,CA:TRUE");       //主题密钥标示符---当发行者有多个签名密钥时        Add_ExtCert(x,x,NID_subject_key_identifier, "hash");       //颁发机构密钥标示符        Add_ExtCert(x,x,NID_authority_key_identifier, "keyid:always");       //密钥用法        Add_ExtCert(x,x,NID_key_usage, "nonRepudiation,digitalSignature,keyEncipherment");       Add_ExtCert(x,x,NID_domainComponent, "no");        Add_ExtCert(x,x,NID_Domain, "no");       /* Some Netscape specific extensions */   //  Add_ExtCert(x, NID_netscape_cert_type, "sslCA");    //  Add_ExtCert(x, NID_netscape_comment, "example comment extension");//netscape_comment                      /* Maybe even add our own extension based on existing */       //加入自定义信息begin    //  int nid;    //  nid = OBJ_create("1.2.3.4.9", "Hpxs", "I love you!");    //  X509V3_EXT_add_alias(nid, NID_netscape_comment);    //  Add_ExtCert(x, nid, "I love you");        //加入自定义信息end        X509V3_EXT_cleanup();//cleanup the extension code if any custom extensions have been added        if (!X509_sign(x,pk,EVP_sha1()))//签名算法EVP_sha1,EVP_md5,用私钥签名公钥        {           strcpy(out,"证书签名失败");           goto err;       }       *x509p=x;       *pkeyp=pk;       return true;   err:       return false;   }         BOOL MakeRoot(stuSUBJECT * rootInfo,/*信息*/int bits/*位数*/, int serial/*序列号*/,                  int days/*有效期*/,char * certFile/*证书文件*/,char * priFile/*私钥文件*/,                 char * outMsg/*操作结果*/,int type/*类型pem-der*/)   {              X509 *x509=NULL;       EVP_PKEY *pkey=NULL;       BIO * bcert=NULL,* bkey=NULL;       bool ret=true;       int i=0,j=0;          if(((bcert=BIO_new_file(certFile, "w"))== NULL)||((bkey=BIO_new_file(priFile, "w")) == NULL))       {           strcpy(outMsg,"Create File Error");           return false;       }       if(mkRoot(rootInfo,&x509,&pkey,bits,serial,days,outMsg))       {           if (type==DER)           {               i=i2d_X509_bio(bcert,x509);//returns 1 for success                 j=i2d_PrivateKey_bio(bkey,pkey);           }           else if(type==PEM)           {               i=PEM_write_bio_X509(bcert,x509);               j=PEM_write_bio_PrivateKey(bkey,pkey,NULL,NULL,0,NULL, NULL);           }           if(!i||!j)           {               ret=false;               strcpy(outMsg,"Save Cert or Key File Error");           }       }       else           ret=false;       BIO_free(bcert);       BIO_free(bkey);       X509_free(x509);       EVP_PKEY_free(pkey);       return ret;      }      ///////////////////////// end ////////////////////////////////////////    //////////////////////////////////////////////////////////////////////    ///////////////////////// begin //////////////////////////////////////       /* Add extension using V3 code: we can set the config file as NULL   * because we wont reference any other sections.   */   int Add_ExtReq(STACK_OF(X509_REQUEST) *sk, int nid, char *value)   {       X509_EXTENSION *ex;       ex = X509V3_EXT_conf_nid(NULL, NULL, nid, value);       if (!ex)           return 0;       sk_X509_EXTENSION_push(sk, ex);              return 1;   }          int mkReq(stuSUBJECT * reqInfo,X509_REQ **req, EVP_PKEY **pkeyp, int bits,char * out)   {       X509_REQ *x;       EVP_PKEY *pk;       RSA *rsa;       X509_NAME *name=NULL;       ASN1_STRING stmp, *str = &stmp;              STACK_OF(X509_EXTENSION) *exts = NULL;              if ((pk=EVP_PKEY_new()) == NULL)           goto err;              if ((x=X509_REQ_new()) == NULL)           goto err;       Rand(NULL,1,out);//产生随机数种子        rsa=RSA_generate_key(bits,RSA_F4,0/*回调函数callback*/,NULL);//产生密钥对        //PEM_write_bio_RSAPrivateKey        if (!EVP_PKEY_assign_RSA(pk,rsa))           goto err;              rsa=NULL;              X509_REQ_set_pubkey(x,pk);              name=X509_REQ_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      */          setlocale(LC_CTYPE, "");          Add_Name(name,NID_countryName,(char *)reqInfo->C,sizeof(reqInfo->C),out);       Add_Name(name,NID_stateOrProvinceName,(char *)reqInfo->ST,sizeof(reqInfo->ST),out);       Add_Name(name,NID_localityName,(char *)reqInfo->L,sizeof(reqInfo->L),out);       Add_Name(name,NID_organizationName,(char *)reqInfo->O,sizeof(reqInfo->O),out);       Add_Name(name,NID_organizationalUnitName,(char *)reqInfo->OU,sizeof(reqInfo->OU),out);       Add_Name(name,NID_commonName,(char *)reqInfo->CN,sizeof(reqInfo->CN),out);       Add_Name(name,NID_pkcs9_emailAddress,(char *)reqInfo->MAIL,sizeof(reqInfo->MAIL),out);       Add_Name(name,NID_email_protect,(char *)reqInfo->PMAIL,sizeof(reqInfo->PMAIL),out);          Add_Name(name,NID_title,(char *)reqInfo->T,sizeof(reqInfo->T),out);       Add_Name(name,NID_description,(char *)reqInfo->D,sizeof(reqInfo->D),out);       Add_Name(name,NID_givenName,(char *)reqInfo->G,sizeof(reqInfo->G),out);       Add_Name(name,NID_initials,(char *)reqInfo->I,sizeof(reqInfo->I),out);       Add_Name(name,NID_name,(char *)reqInfo->NAME,sizeof(reqInfo->NAME),out);         Add_Name(name,NID_surname,(char *)reqInfo->S,sizeof(reqInfo->S),out);       Add_Name(name,NID_dnQualifier,(char *)reqInfo->QUAL,sizeof(reqInfo->QUAL),out);       Add_Name(name,NID_pkcs9_unstructuredName,(char *)reqInfo->STN,sizeof(reqInfo->STN),out);       Add_Name(name,NID_pkcs9_challengePassword,(char *)reqInfo->PW,sizeof(reqInfo->PW),out);       Add_Name(name,NID_pkcs9_unstructuredAddress,(char *)reqInfo->ADD,sizeof(reqInfo->ADD),out);             /* Certificate requests can contain extensions, which can be used          * to indicate the extensions the requestor would like added to           * their certificate. CAs might ignore them however or even choke          * if they are present.      */              /* For request extensions they are all packed in a single attribute.      * We save them in a STACK and add them all at once later      */              exts = sk_X509_EXTENSION_new_null();       /* Standard extenions */       //主题备用名称,URL:http://my.url.here/、支持email  copy        Add_ExtReq(exts, NID_subject_alt_name, "DNS:localhost,email:hpxs@hotmail.com,RID:1.2.3.4,URI:192.168.2.22,IP:C0A80216");          //加入自定义扩展        int nid;       nid = OBJ_create("1.3.6.1.4.1.5315.100.2.5", "UserID", "User ID Number");       X509V3_EXT_add_alias(nid, NID_netscape_comment);       Add_ExtReq(exts, nid, "ID130203197703060618");       /* Now we've created the extensions we add them to the request */          X509_REQ_add_extensions(x, exts);       sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);         X509V3_EXT_cleanup();//cleanup the extension code if any custom extensions have been added               if (!X509_REQ_sign(x,pk,EVP_sha1()))//用自己的公钥签名私钥            goto err;              *req=x;       *pkeyp=pk;       return(1);   err:       return(0);   }      BOOL MakeReq(stuSUBJECT * reqInfo,/*请求信息*/int bits/*位数*/,char * reqFile/*证书请求文件*/,                char * priFile/*私钥文件*/,char * outMsg/*操作结果*/,int type)   {       X509_REQ *req=NULL;       EVP_PKEY *pkey=NULL;       BIO * breq=NULL,* bkey=NULL;       int i=0,j=0;       if(((breq=BIO_new_file(reqFile, "w"))== NULL)||((bkey=BIO_new_file(priFile, "w")) == NULL))       {           strcpy(outMsg,"Create File Error");           return false;       }       if(!mkReq(reqInfo,&req,&pkey,bits,outMsg))       {           strcpy(outMsg,"Make CertReq Error");           return false;       }          if(type==PEM)       {           i=PEM_write_bio_X509_REQ(breq,req);                j=PEM_write_bio_PrivateKey(bkey,pkey,NULL,NULL,0,NULL, NULL);       }       else if(type==DER)       {           i=i2d_X509_REQ_bio(breq,req);           j=i2d_PrivateKey_bio(bkey,pkey);       }       BIO_free(breq);       BIO_free(bkey);       X509_REQ_free(req);       EVP_PKEY_free(pkey);       if(!i||!j)       {           strcpy(outMsg,"Save Cert or Key File Error");           return false;       }       return true;   }   ////////////////////////// end //////////////////////////////////////    ////////////////////////////////////////////////////////////////////    /////////////////////////// begin ////////////////////////////////////////    int copy_extensions(X509 *x, X509_REQ *req, int copy_type)//在证书中加入req自带扩展信息    {       STACK_OF(X509_EXTENSION) *exts = NULL;       X509_EXTENSION *ext, *tmpext;       ASN1_OBJECT *obj;       int i, idx, ret = 0;       if (!x || !req || (copy_type == EXT_COPY_NONE))           return 1;       exts = X509_REQ_get_extensions(req);              for(i = 0; i < sk_X509_EXTENSION_num(exts); i++)       {           ext = sk_X509_EXTENSION_value(exts, i);           obj = X509_EXTENSION_get_object(ext);           idx = X509_get_ext_by_OBJ(x, obj, -1);           /* Does extension exist? */           if (idx != -1)            {               /* If normal copy don't override existing extension */               if (copy_type == EXT_COPY_ADD)                   continue;               /* Delete all extensions of same type */               do               {                   tmpext = X509_get_ext(x, idx);                   X509_delete_ext(x, idx);                   X509_EXTENSION_free(tmpext);                   idx = X509_get_ext_by_OBJ(x, obj, -1);               } while (idx != -1);           }           if (!X509_add_ext(x, ext, -1))               goto end;       }              ret = 1;          end:              sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);              return ret;   }         int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,int serial,               char *startdate, char *enddate, int days,X509_REQ * req,stuKEYUSAGE * KUSAGE,               stuEKEYUSAGE * EKUSAGE,char * outMsg)   {       X509_NAME *name=NULL,*CAname=NULL;       X509 *ret=NULL;       X509_CINF *ci;       EVP_PKEY *pktmp;       int ok= -1,i=0;   //  STACK_OF (X509_EXTENSION) * req_exts;//如何释放??        char kusage[160]={0};       char ekusage[360]={0};       name=X509_REQ_get_subject_name(req);       if ((ret=X509_new()) == NULL)        {           ok=0;           goto err;       }       ci=ret->cert_info;          /* Make it an X509 v3 certificate. 版本1扩展*/       if (!X509_set_version(ret,2L)) //版本        {           ok=0;           goto err;       }              ASN1_INTEGER_set(X509_get_serialNumber(ret),serial);//序列号           if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))//发行者        {           ok=0;           goto err;       }              if (strcmp(startdate,"today") == 0)           X509_gmtime_adj(X509_get_notBefore(ret),0);//开始日期        else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);              if (enddate == NULL)           X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);//结束日期        else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);              if (!X509_set_subject_name(ret,name)) //主体 ---所有者        {           ok=0;           goto err;       }              pktmp=X509_REQ_get_pubkey(req);       i = X509_set_pubkey(ret,pktmp);//公钥        EVP_PKEY_free(pktmp);       if (!i)        {           ok=0;           goto err;       }              //加入req自带扩展信息,生成REQ文件时候加入的        if (!copy_extensions(ret, req, EXT_COPY_ALL))       {           strcpy("加入自带扩展信息失败",outMsg);           goto err;       }          /* Lets add the extensions, if there are any 加入标准扩展*/          //基本限制Note if the CA option is false the pathlen option should be omitted.         Add_ExtCert(ret,ret,NID_basic_constraints, "critical,CA:FALSE,pathlen:1");          //主题密钥标示符--------区分拥有者多对密钥        Add_ExtCert(ret,ret,NID_subject_key_identifier, "hash");          //Authority密钥标示符----区分发行者有多个签名密钥时        Add_ExtCert(ret,x509, NID_authority_key_identifier, "keyid,issuer:always");                 //密钥用法 ----数字签名、不可否认性、密钥加密、数据加密、密钥协商、证书签名、        //CRL签名、仅仅加密、仅仅解密                   if(KUSAGE->DS)           strcpy(kusage,"digitalSignature");       if(KUSAGE->NR)           if(strlen(kusage))//添加                strcat(kusage, ",nonRepudiation");           else               strcpy(kusage,"nonRepudiation");       if(KUSAGE->KE)           if(strlen(kusage))//添加                strcat(kusage, ",keyEncipherment");           else               strcpy(kusage,"keyEncipherment");       if(KUSAGE->DE)           if(strlen(kusage))//添加                strcat(kusage, ",dataEncipherment");           else               strcpy(kusage,"dataEncipherment");       if(KUSAGE->KA)           if(strlen(kusage))//添加                strcat(kusage, ",keyAgreement");           else               strcpy(kusage,"keyAgreement");       if(KUSAGE->KC)           if(strlen(kusage))//添加                strcat(kusage, ",keyCertSign");           else               strcpy(kusage,"keyCertSign");       if(KUSAGE->CS)           if(strlen(kusage))//添加                strcat(kusage, ",cRLSign");           else               strcpy(kusage,"cRLSign");       if(KUSAGE->EO)           if(strlen(kusage))//添加                strcat(kusage, ",encipherOnly");           else               strcpy(kusage,"encipherOnly");       if(KUSAGE->DO)           if(strlen(kusage))//添加                strcat(kusage, ",decipherOnly");           else               strcpy(kusage,"decipherOnly");       if(strlen(kusage))           Add_ExtCert(ret,ret, NID_key_usage, kusage);          //增强型密钥用法--一般只用于末端证书RFC3280        //增强用法     证书目的        //--------------------------------------------------------------------------------------------------------------        //服务器验证          保证远程计算机的身份             //客户端验证      向远程计算机证明您的身份         //代码签名           确保软件来自软件发行商           //安全电子邮件         保护软件在发行后不被改动         //时间戳            保护电子邮件消息            //--------------------------------------------------------------------------------------------------------------        //                  保证软件来自一个软件发行商        //                  保护软件在发行后不被改动。        //                  保证软件来自商业软件发行商        //                  允许您用数字签名证书信任列表        //                  允许联机事务处理/通讯的严格加密        //                  允许加密磁盘上的数据        //                  智能卡登录        //IP安全终端系统           允许 Internet 上的安全通讯             //IP安全隧道终止               //IP 安全用户                   //--------------------------------------------------------------------------------------------------------------           if(EKUSAGE->SA)           strcpy(ekusage,"serverAuth");       if(EKUSAGE->CA)           if(strlen(ekusage))//添加                strcat(ekusage,",clientAuth");           else               strcpy(ekusage,"clientAuth");       if(EKUSAGE->CS)           if(strlen(ekusage))//添加                strcat(ekusage,",codeSigning");           else               strcpy(ekusage,"codeSigning");       if(EKUSAGE->EP)           if(strlen(ekusage))//添加                strcat(ekusage,",emailProtection");           else               strcpy(ekusage,"emailProtection");       if(EKUSAGE->TS)           if(strlen(ekusage))//添加                strcat(ekusage,",timeStamping");           else               strcpy(ekusage,"timeStamping");       if(EKUSAGE->msCC)           if(strlen(ekusage))//添加                strcat(ekusage,",msCodeCom");           else               strcpy(ekusage,"msCodeCom");       if(EKUSAGE->msCTLS)           if(strlen(ekusage))//添加                strcat(ekusage,",msCTLSign");           else               strcpy(ekusage,"msCTLSign");       if(EKUSAGE->msSGC)           if(strlen(ekusage))//添加                strcat(ekusage,",msSGC");           else               strcpy(ekusage,"msSGC");       if(EKUSAGE->msEFS)           if(strlen(ekusage))//添加                strcat(ekusage,",msEFS");           else               strcpy(ekusage,"msEFS");       if(EKUSAGE->msSC)           if(strlen(ekusage))//添加                strcat(ekusage,",msSmartcardLogin");           else               strcpy(ekusage,"msSmartcardLogin");       if(EKUSAGE->IP)           if(strlen(ekusage))//添加                strcat(ekusage,",ipsecEndSystem,ipsecTunnel,ipsecUser");           else               strcpy(ekusage,"ipsecEndSystem,ipsecTunnel,ipsecUser");       if(strlen(ekusage))       Add_ExtCert(ret,ret,NID_ext_key_usage,ekusage);          /*      Application         keyUsage  Values       SSL Client          digitalSignature       SSL Server          keyEncipherment       S/MIME Signing      digitalSignature       S/MIME Encryption   keyEncipherment       Certificate         Signing keyCertSign       Object Signing      digitalSignature */          //颁发者备用名称,URL:http://my.url.here/、不支持email  copy        Add_ExtCert(ret,ret, NID_issuer_alt_name, "DNS:hpxs,email:hpxs@hotmail.com,RID:1.2.3.4,URI:https://hpxs,IP:192.168.0.22");          //证书策略        Add_ExtCert(ret,ret,NID_certificate_policies,"OK");       //颁发机构信息访问        Add_ExtCert(ret,ret,NID_info_access,"OCSP;URI:https://hpxs");//或者caIssuers;URI:http://my.ca/ca.html       //CRL分发点        Add_ExtCert(ret,x509, NID_crl_distribution_points, "URI:https://hpxs/hpxs.crl");          /* Some Netscape specific extensions */   //  Add_ExtCert(ret,ret, NID_crl_number, "sslCA");       //  Add_ExtCert(ret,x509, NID_netscape_comment, "See http://cert.umd.edu/root for details.");        /* In each case the 'value' of the extension is placed directly in the      extension. Currently supported extensions in this category are: nsBaseUrl,      nsRevocationUrl, nsCaRevocationUrl, nsRenewalUrl, nsCaPolicyUrl,      nsSslServerName and nsComment   */      //  Add_ExtCert(ret,x509, NID_netscape_cert_type, "client, server, email,objsign, reserved, sslCA,emailCA, objCA");        /*nsCertType (netscape certificate type) takes the flags: client, server, email,      objsign, reserved, sslCA, emailCA, objCA.*/       /* Maybe even add our own extension based on existing */       //加入自定义信息begin        int nid;       nid = OBJ_create("1.2.3.4.9", "Hpxs", "I love OpenSSL!");       X509V3_EXT_add_alias(nid, NID_netscape_comment);       Add_ExtCert(ret,ret, nid, "I love OpenSSL");       //加入自定义信息end        X509V3_EXT_cleanup();//cleanup the extension code if any custom extensions have been added           if (!X509_sign(ret,pkey,dgst))//加入签名,签名算法        {           ok=0;           goto err;       }       ok=1;   err:       if (CAname != NULL)           X509_NAME_free(CAname);       if (ok <= 0)       {           if (ret != NULL) X509_free(ret);           ret=NULL;       }       else           *xret=ret;       return(ok);   }      int certify(X509 **xret, X509_REQ *req, EVP_PKEY *pkey, X509 *x509,const EVP_MD *dgst,                      int serial, char *startdate, char *enddate, int days,stuKEYUSAGE * KUSAGE,                      stuEKEYUSAGE * EKUSAGE,char * outMsg)   {//返回公钥证书,请求文件,根私钥,根公钥,        EVP_PKEY *pktmp=NULL;       int ok= -1,i=0;        if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)//得到公钥        {           sprintf(outMsg,"error unpacking public key\n");           ok=0;           goto err;       }       i=X509_REQ_verify(req,pktmp);//证书请求里面有私要签名,这里验证一下,看此公钥主人是否持有私钥        EVP_PKEY_free(pktmp);       if (i < 0)       {           ok=0;           sprintf(outMsg,"Signature verification problems.\n");           goto err;       }       if (i == 0)       {           ok=0;           sprintf(outMsg,"Signature did not match the certificate request\n");           goto err;       }              ok=do_body(xret,pkey,x509,dgst,serial,startdate, enddate,           days,req,KUSAGE,EKUSAGE,outMsg);          err:       return(ok);   }         BOOL MakeCert(char *certfile/*根证书公钥*/,int certlen,/*为0则certfile为磁盘文件,否则为内存区域*/                 char *keyfile/*根证书私钥*/,int keylen,int serial/*序列号*/,char *enddate/*作废日期*/,                 int days/*有效期*/, char *reqfile/*请求文件*/,stuKEYUSAGE * KUSAGE/*密钥用法*/,                 stuEKEYUSAGE * EKUSAGE/*增强密钥用法*/,char *outfile/*结果文件*/,                 char * outMsg/*操作结果*/,int type/*结果类型DER,PEM*/)//通过证书请求,得到证书    {       int ret=1;       char * md=NULL;       EVP_PKEY *pkey=NULL;       X509 * x509=NULL;       X509_REQ *req=NULL;       X509 * x=NULL;       BIO * bcert=NULL,* reqbio=NULL;       int j;       const EVP_MD *dgst=NULL;          OpenSSL_add_all_digests();//加入签名算法           if((reqbio=BIO_new_file(reqfile, "r")) == NULL)       {           ret=0;           goto err;       }              if ((req=PEM_read_bio_X509_REQ(reqbio,NULL,NULL,NULL)) == NULL)//PEM_read_X509_REQ         {           BIO_reset(reqbio);           if ((req=d2i_X509_REQ_bio(reqbio,NULL)) == NULL)           {               sprintf(outMsg,"Error get certificate request");               ret=0;               goto err;           }       }          pkey=LoadKey(keyfile,keylen,NULL,outMsg);       if (pkey == NULL)       {           ret = 0;           goto err;       }          x509=LoadCert(certfile,certlen,outMsg);       if (x509 == NULL)       {           ret = 0;           goto err;       }              if (!X509_check_private_key(x509,pkey))       {           sprintf(outMsg,"CA certificate and CA private key do not match\n");           ret = 0;           goto err;       }       md="sha1";//////////!!!!!!!!!!!!!!!!!////////////////////////////        if ((dgst=EVP_get_digestbyname(md)) == NULL)//return an EVP_MD structure when passed a digest name        {           sprintf(outMsg,"%s is an unsupported message digest type\n",md);           ret = 0;           goto err;       }       j=certify(&x,req,pkey,x509,dgst,//公钥证书out,请求文件,根私钥,根公钥,            serial,"today",enddate,days,KUSAGE,EKUSAGE,outMsg);       if (j <= 0)        {           ret=0;           goto err;       }          if(((bcert=BIO_new_file(outfile, "w"))== NULL))       {           strcpy(outMsg,"Create File Error");           goto err;       }       if (type==DER)       {           i2d_X509_bio(bcert,x);       }       else if(type==PEM)       {           PEM_write_bio_X509(bcert,x);       }   err:       if (reqbio != NULL) BIO_free(reqbio);       BIO_free_all(bcert);       EVP_PKEY_free(pkey);       X509_free(x509);       X509_free(x);       if (req != NULL) X509_REQ_free(req);       EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER        return ret;      }   ///////////////////////// end ////////////////////////////////////////    BOOL DirectCert(char *certfile/*根证书公钥*/,int certlen,/*为0则certfile为磁盘文件,否则为内存区域*/                char *keyfile/*根证书私钥*/,int keylen,int serial/*序列号*/,char *enddate/*作废日期*/,                int days/*有效期*/,stuCERT * sCERT/*用户信息与密钥用法*/,int bits,char * cert/*输出证书公钥*/,int * certl/*长度*/,                char * key/*输出证书私钥*/,int * keyl/*长度*/,char * outMsg/*,int type结果类型DER,PEM*/)//直接生成公私钥    {       X509_REQ * req=NULL;       EVP_PKEY * pkey=NULL, * prkey=NULL;//证书私钥,//根私钥        X509 * x509=NULL,* x=NULL;//根公钥,证书公钥        BIO * memcert=NULL, * memkey=NULL;//输出证书公私钥        BUF_MEM *bptrcert=NULL,*bptrkey=NULL;       int ret=1;       char * md=NULL;       int i=0,j=0,ok=0;       const EVP_MD *dgst=NULL;          OpenSSL_add_all_digests();//加入签名算法        memcert= BIO_new(BIO_s_mem());       memkey= BIO_new(BIO_s_mem());       BIO_set_close(memcert, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */       BIO_set_close(memkey, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */          prkey=LoadKey(keyfile,keylen,NULL,outMsg);//RAND_bytes        if (prkey == NULL)       {           ret = 0;           goto err;       }          x509=LoadCert(certfile,certlen,outMsg);       if (x509 == NULL)       {           ret = 0;           goto err;       }              if (!X509_check_private_key(x509,prkey))       {           sprintf(outMsg,"CA certificate and CA private key do not match\n");           ret = 0;           goto err;       }          if(!mkReq(&(sCERT->SUBJECT),&req,&pkey, bits,outMsg))       {           sprintf(outMsg,"Make CertReq error");           ret = 0;           goto err;       }          md="sha1";//////////!!!!!!!!!!!!!!!!!////////////////////////////        if ((dgst=EVP_get_digestbyname(md)) == NULL)//return an EVP_MD structure when passed a digest name        {           sprintf(outMsg,"%s is an unsupported message digest type\n",md);           ret = 0;           goto err;       }       ok=certify(&x,req,prkey,x509,dgst,//公钥证书out,请求,根私钥,根公钥,            serial,"today",enddate,days,&(sCERT->KUSAGE),&(sCERT->EKUSAGE),outMsg);       if (ok <= 0)        {           ret=0;           goto err;       }   /*  if (type==DER)      {          i=i2d_X509_bio(memcert,x);          j=i2d_PrivateKey_bio(memkey,pkey);//生成的结果错误!?????????????      }      else if(type==PEM)  */  {           i=PEM_write_bio_X509(memcert,x);           j=PEM_write_bio_PrivateKey(memkey,pkey,NULL,NULL,0,NULL, NULL);       }          if(!i||!j)       {           strcpy(outMsg,"Get Mem Cert or Key File Error");           ret=0;           goto err;       }          BIO_get_mem_ptr(memcert, &bptrcert);       *certl=bptrcert->length;       memcpy(cert,bptrcert->data,*certl);          BIO_get_mem_ptr(memkey, &bptrkey);       *keyl=bptrkey->length;       memcpy(key,bptrkey->data,*keyl);      err:       BIO_free_all(memcert);       BIO_free_all(memkey);       EVP_PKEY_free(pkey);       EVP_PKEY_free(prkey);       X509_free(x509);       X509_free(x);       if (req != NULL) X509_REQ_free(req);       EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER        return ret;   }   //////////////////////////////////////////////////////////////////////    ///////////////////////// begin //////////////////////////////////////    /*添加链表节点*/   void AddRevoke(stuREVOKE *& Head,int index,time_t time)   {       stuREVOKE * End=new stuREVOKE(index,time);//钥增加的节点        if(Head==NULL)       {           Head=End;       }       else        {           stuREVOKE * p=Head;           while(p->Link!=NULL)                 p=p->Link;           p->Link=End;        }          return;   }      int Add_ExtCrl(X509_CRL *crl/*正被添加的证书*/,X509 * root/*根证书(从中得到信息)*/,                   int nid, char *value)   {       X509V3_CTX ctx;       X509_EXTENSION *ex;          /* This sets the 'context' of the extensions. */       /* No configuration database */   //  X509V3_set_ctx_nodb(&ctx);        X509V3_set_ctx(&ctx, root, NULL, NULL, crl, 0);   //  issuerAltName  authorityKeyIdentifier        ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);       if (!ex)           return 0;       X509_CRL_add_ext(crl,ex,-1);       X509_EXTENSION_free(ex);       return 1;   }         BOOL MakeCrl(char *certfile/*根证书公钥*/,int certlen,/*为0则certfile为磁盘文件,否则为内存区域*/                 char *keyfile/*根证书私钥*/,int keylen,                 stuREVOKE * Head/*作废链表*/,PNewCrlMem NewCrlMem/*回调函数*/,char *& outCrl,int * crll,char * outfile/*crl文件*/,                 char * outMsg/*操作结果*/)   {       X509_CRL_INFO *ci = NULL;       X509_CRL *crl = NULL;       int ret=1,i=0;       char *key=NULL;       char *md=NULL;       EVP_PKEY *pkey=NULL;       X509 *x509=NULL;       BIO *in=NULL,*out=NULL;       const EVP_MD *dgst=NULL;       X509_REVOKED *r=NULL;       long crldays=30;       long crlhours=0;       stuREVOKE * temp =NULL;       BIO * memcrl=NULL;       BUF_MEM *bptrcrl=NULL;          OpenSSL_add_all_algorithms();          pkey=LoadKey(keyfile,keylen,NULL,outMsg);       if (pkey == NULL)       {           ret = 0;           goto err;       }       x509=LoadCert(certfile,certlen,outMsg);       if (x509 == NULL)       {           ret = 0;           goto err;       }              if (!X509_check_private_key(x509,pkey))       {           sprintf(outMsg,"CA certificate and CA private key do not match\n");           ret = 0;           goto err;       }       md="md5";//////////!!!!!!!!!!!!!!!!!////////////////////////////        if ((dgst=EVP_get_digestbyname(md)) == NULL)//return an EVP_MD structure when passed a digest name        {           sprintf(outMsg,"%s is an unsupported message digest type\n",md);           ret = 0;           goto err;       }              if ((crl=X509_CRL_new()) == NULL)       {           ret = 0;           goto err;       }       ci=crl->crl;       X509_NAME_free(ci->issuer);       ci->issuer=X509_NAME_dup(x509->cert_info->subject);       if (ci->issuer == NULL)       {           ret = 0;           goto err;       }       X509_gmtime_adj(ci->lastUpdate,0);       if (ci->nextUpdate == NULL)           ci->nextUpdate=ASN1_UTCTIME_new();       X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);          if(!ci->revoked)           ci->revoked = sk_X509_REVOKED_new_null();                 while(Head!=NULL)//遍历链表        {           temp=Head;           X509_REVOKED *r = NULL;           BIGNUM *serial_bn = NULL;           r = X509_REVOKED_new();           ASN1_TIME_set(r->revocationDate,Head->time);//时间            char index[100];           BN_hex2bn(&serial_bn,itoa(Head->Index,index,10));//序号            BN_to_ASN1_INTEGER(serial_bn,r->serialNumber);           sk_X509_REVOKED_push(ci->revoked,r);           Head=Head->Link;           delete temp;       }   //  sk_X509_REVOKED_sort(ci->revoked);        for (i=0; i<SK_X509_REVOKED_NUM(CI->revoked); i++)       {           r=sk_X509_REVOKED_value(ci->revoked,i);           r->sequence=i;       }          if (ci->version == NULL)       if ((ci->version=ASN1_INTEGER_new()) == NULL)       {           ret = 0;           goto err;       }       ASN1_INTEGER_set(ci->version,1);       //  issuerAltName  authorityKeyIdentifier    //  Add_ExtCrl(crl,x509,NID_subject_alt_name,"DNS:hpxs,email:hpxs@hotmail.com,RID:1.2.3.4,URI:https://hpxs,IP:192.168.0.22");        Add_ExtCrl(crl,x509,NID_issuer_alt_name, "DNS:hpxs,email:hpxs@hotmail.com,RID:1.2.3.4,URI:https://hpxs,IP:192.168.0.22");       Add_ExtCrl(crl,x509,NID_authority_key_identifier, "keyid,issuer:always");       if (!X509_CRL_sign(crl,pkey,dgst))       {           ret = 0;           goto err;       }       if(NewCrlMem)//输出内存        {           memcrl= BIO_new(BIO_s_mem());           BIO_set_close(memcrl, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */           PEM_write_bio_X509_CRL(memcrl,crl);           BIO_get_mem_ptr(memcrl, &bptrcrl);           *crll=bptrcrl->length;           outCrl=NewCrlMem(*crll);           memcpy(outCrl,bptrcrl->data,*crll);       }       if(outfile)//输出文件        {           out=BIO_new_file(outfile, "w");           if(out==NULL)           {               sprintf(outMsg,"%s is error",outfile);               ret = 0;               goto err;           }           PEM_write_bio_X509_CRL(out,crl);       }          X509V3_EXT_cleanup();//cleanup the extension code if any custom extensions have been added    err:       if(out)           BIO_free_all(out);       if(memcrl)           BIO_free_all(memcrl);       BIO_free(in);       EVP_PKEY_free(pkey);       X509_CRL_free(crl);       X509_free(x509);       EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER        if(ret==1)           strcpy(outMsg,"CRL制作成功");       return ret;          }      BOOL CertFormatConver(char * buf/*文件内容或文件名称*/,int len/*内存长度为0则buf为文件名*/,                 char * pwd/*p12文件密码*/,char * pem/*输出文件*/,                 int outformat,char * out/*操作结果*/)   {       EVP_PKEY *key=NULL;       X509 *cert=NULL;       BIO *biout=NULL;       int i=0;       //输出文件        if ((biout=BIO_new_file(pem, "w")) == NULL)       {           return false;       }              cert = LoadCert(buf,len,out);//首先尝试公钥,bio被改写        if(cert)//输入文件为公钥文件        {              if  (outformat == DER)               i=i2d_X509_bio(biout,cert);           else if (outformat == PEM)           {           //  if (trustout) i=PEM_write_bio_X509_AUX(biout,x);                i=PEM_write_bio_X509(biout,cert);           }           if(!i)//失败                strcpy(out,"保存公钥失败");           else               strcpy(out,"公钥证书格式转换成功");                  }          else//输入文件为私钥文件        {           key=LoadKey(buf,len,pwd,out);           if(!key)            {               strcpy(out,"不能识别的文件格式");               return false;           }           if(outformat==PEM)           {                  PEM_write_bio_PrivateKey(biout, key, NULL, NULL, 0, 0, NULL);           }           if(outformat==DER)           {               i2d_PrivateKey_bio(biout,key);//得到解密后的私钥            }                      strcpy(out,"私钥证书格式转换成功");       }              if (biout != NULL) BIO_free(biout);       X509_free(cert);       EVP_PKEY_free(key);          return true;   }      //分解p12包    BOOL ParseDB(char * strP12/*包文件*/,char * strPwd/*私钥密码*/,char * strCert/*公钥存放*/,                char * strkey/*私钥存放*/,int outformat/*输出格式*/,char * out/*返回结果*/)   {       EVP_PKEY *key=NULL;       X509 *cert=NULL;       STACK_OF(X509) *ca = NULL;       BIO * bio=NULL,*bioCert=NULL,*bioKey=NULL;       PKCS12 *p12=NULL;       int i=0,j=0;              if((bio=BIO_new_file(strP12, "r")) == NULL)       {           strcpy(out,"打开文件错误");           return false;       }       SSLeay_add_all_algorithms();       p12 = d2i_PKCS12_bio(bio, NULL);       if (!PKCS12_parse(p12, strPwd, &key, &cert/*PEM*/, &ca))        {           strcpy(out,"解包失败");           return false;       }       PKCS12_free(p12);          //输出文件        if ((bioCert=BIO_new_file(strCert, "w")) == NULL)       {           return false;       }       if ((bioKey=BIO_new_file(strkey, "w")) == NULL)       {           return false;       }              if(outformat == DER)       {           i=i2d_X509_bio(bioCert,cert);           j=i2d_PrivateKey_bio(bioKey,key);       }       else if (outformat == PEM)       {           i=PEM_write_bio_X509(bioCert,cert);           j=PEM_write_bio_PrivateKey(bioKey, key, NULL, NULL, 0, 0, NULL);       }          if (bio != NULL) BIO_free(bio);       if (bioCert != NULL) BIO_free(bioCert);       if (bioKey != NULL) BIO_free(bioKey);       X509_free(cert);       EVP_PKEY_free(key);          EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER        if(i!=0&&j!=0)       {           strcpy(out,"分解P12成功");           return true;       }       return false;   }      //组合p12包    BOOL CreateDB(char * strP12/*OUT包文件*/,char * strPwd/*IN密码*/,char * strCert/*IN公钥*/,                 char * strkey/*IN私钥*/,char * out/*返回结果*/)   {       FILE *fp=NULL;       EVP_PKEY *key=NULL;       X509 *cert=NULL;       PKCS12 *p12;       cert =LoadCert(strCert,0,out);       if(!cert)        {           strcpy(out,"读取公钥文件失败");           return false;       }       key=LoadKey(strkey,0,NULL,out);//解密后私钥        if(!key)        {           strcpy(out,"读取私钥文件失败");           return false;       }       SSLeay_add_all_algorithms();       p12 = PKCS12_create(strPwd,"(hpxs)", key, cert, NULL, 0,0,0,0,0);       if(!p12)       {           strcpy(out,"创建p12结构失败");           return false;       }       if (!(fp = fopen(strP12, "wb")))        {           strcpy(out,"保存p12文件失败");       }       i2d_PKCS12_fp(fp, p12);       PKCS12_free(p12);       fclose(fp);       strcpy(out,"合并P12成功");       X509_free(cert);       EVP_PKEY_free(key);       EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER        return true;   }      //修改p12包密码    BOOL ChangePB(char * strP12/*in包文件*/,char * strPwd/*IN原密码*/,char * strPwd2/*IN新密码*/,                 char * strOutP12/*in包文件*/,char * out/*返回结果*/)   {       FILE *fp=NULL;       EVP_PKEY *key=NULL;       X509 *cert=NULL;       STACK_OF(X509) *ca = NULL;       PKCS12 *p12=NULL;       int len=0,wlen=0;          SSLeay_add_all_algorithms();       if (!(fp = fopen(strP12, "rb")))       {           strcpy(out,"打开文件错误");           return false;       }       p12 = d2i_PKCS12_fp(fp, NULL);       fclose (fp);       if (!p12)        {           strcpy(out,"读取包文件错误");           return false;       }       if (!PKCS12_parse(p12, strPwd, &key, &cert, &ca))        {           strcpy(out,"解包失败");           return false;       }       PKCS12_free(p12);       fclose(fp);       p12=NULL;       ///////////////////////////////////////        p12 = PKCS12_create(strPwd2,"(null)", key, cert, NULL, 0,0,0,0,0);       if(!p12)       {           strcpy(out,"创建p12结构失败");           return false;       }       if (!(fp = fopen(strOutP12, "wb")))        {           strcpy(out,"保存p12文件失败");       }       i2d_PKCS12_fp(fp, p12);       PKCS12_free(p12);       fclose(fp);       strcpy(out,"转换P12密码成功");       X509_free(cert);       EVP_PKEY_free(key);       return true;   }      BOOL CertPairCheck(char * cert,char * key,char * out)//检验公钥、私钥是否配对    {       EVP_PKEY *pkey=NULL;       X509 *x509=NULL;       x509=LoadCert(cert,0,out);       if(x509==NULL)       {           strcpy(out,"不能打开公钥文件");           return FALSE;       }       pkey=LoadKey(key,0,NULL,out);       if(pkey==NULL)       {           strcpy(out,"不能打开私钥文件");           X509_free(x509);           return FALSE;       }       if(X509_check_private_key(x509,pkey))//匹配        {           X509_free(x509);           EVP_PKEY_free(pkey);           return TRUE;       }       else       {           strcpy(out,"公私钥对不匹配");           X509_free(x509);           EVP_PKEY_free(pkey);           return FALSE;       }      }      #include  #define DER                1 //FORMAT_ASN1 #define PEM                3    /*定义格式*/ #define NET                4 #define P12                5  typedef char * (* PNewCrlMem)(UINT len);  struct stuSUBJECT//个体信息 {     UCHAR C[4];//国家     UCHAR ST[4];//省份     UCHAR L[12];//城市     UCHAR O[48];//组织     UCHAR OU[24];//组织部门     UCHAR CN[12];//个人信息     UCHAR MAIL[24];//电子邮件     UCHAR PMAIL[24];//安全电子邮件     UCHAR T[12];//头衔     UCHAR D[12];//描述     UCHAR G[12];//曾用名     UCHAR I[12];//描述     UCHAR NAME[12];//描述     UCHAR S[12];//描述     UCHAR QUAL[12];//描述     UCHAR STN[12];//没有结构的名称     UCHAR PW[12];//挑战密码     UCHAR ADD[12];//无结构地址      stuSUBJECT()     {         memset(this,0,sizeof(stuSUBJECT));     } };  struct stuKEYUSAGE//密钥用途 {     BOOL DS;//Digital Signature     BOOL NR;//Non-Repudiation     BOOL KE;//Key Encipherment     BOOL DE;//Data Encipherment     BOOL KA;//keyAgreement     BOOL KC;//keyCertSign      BOOL CS;//cRLSign     BOOL EO;//Encipher Only     BOOL DO;//Decipher Only     stuKEYUSAGE()     {         memset(this,0,sizeof(stuKEYUSAGE));     }  };  struct stuEKEYUSAGE//增强型密钥用途 {     BOOL SA;//服务器验证     BOOL CA;//客户端验证     BOOL CS;//代码签名     BOOL EP;//安全电子邮件     BOOL TS;//时间戳     BOOL msCC;//代码完整     BOOL msCTLS;//可签名信任列表     BOOL msSGC;//联机事务处理     BOOL msEFS;//加密磁盘上的数据     BOOL msSC;//智能卡登录     BOOL IP;//Internet     stuEKEYUSAGE()     {         memset(this,0,sizeof(stuEKEYUSAGE));     }  };  struct stuCERT//三者之和 {     stuSUBJECT SUBJECT;     stuKEYUSAGE KUSAGE;     stuEKEYUSAGE EKUSAGE;     stuCERT()     {         memset(this,0,sizeof(stuCERT));     } };  struct stuREVOKE//证书作废结构链表 {     int Index;//证书序号     time_t time;//吊销时间     stuREVOKE * Link;     stuREVOKE()     {         memset(this,0,sizeof(stuREVOKE));     }     stuREVOKE(int index,time_t t)     {         Index=index;         time=t;;         Link=NULL;     } };  /*添加链表节点*/ void AddRevoke(stuREVOKE *& Head,int index,time_t time);  /*证书格式转换函数*/ BOOL CertFormatConver(char * buf/*内存区域,存储文件内容或文件名称*/,int len/*内存长度==0则buf为文件名*/,               char * pwd/*p12文件密码*/,char * pem/*输出文件*/,int outformat,char * out/*操作结果*/);  /*根证书生成函数,根据rootInfo信息,生成根证书公、私钥文件*/ BOOL MakeRoot(stuSUBJECT * rootInfo,/*请求信息IN*/int bits/*位数IN*/, int serial/*序列号IN*/,                int days/*有效期IN*/,char * certFile/*证书请求文件OUT*/,char * priFile/*私钥文件OUT*/,               char * out/*操作结果OUT*/,int type=PEM/*类型pem-der*/);  /*证书请求生成函数,根据reqInfo信息,生成用户证书私钥文件、证书请求文件*/ BOOL MakeReq(stuSUBJECT * reqInfo,/*请求信息IN*/int bits/*位数IN*/, char * reqFile/*证书请求文件OUT*/,              char * priFile/*私钥文件OUT*/,char * out/*操作结果OUT*/,int type=PEM/*类型pem-der*/);  /*证书生成函数,通过证书请求,生成用户证书公钥文件*/ BOOL MakeCert(char *certfile/*根证书公钥*/,int certlen,/*为0则certfile为磁盘文件,否则为内存区域*/               char *keyfile/*根证书私钥*/,int keylen,int serial/*序列号*/,char *enddate/*作废日期*/,               int days/*有效期*/, char *reqfile/*请求文件*/,stuKEYUSAGE * KUSAGE/*密钥用法*/,               stuEKEYUSAGE * EKUSAGE/*增强密钥用法*/,char *outfile/*结果文件*/,               char * outMsg/*操作结果*/,int type/*结果类型DER,PEM*/);//通过证书请求,得到证书  //直接生成公私钥 BOOL DirectCert(char *certfile/*根证书公钥*/,int certlen,/*为0则certfile为磁盘文件,否则为内存区域*/              char *keyfile/*根证书私钥*/,int keylen,int serial/*序列号*/,char *enddate/*作废日期*/,              int days/*有效期*/,stuCERT * sCERT/*用户信息与密钥用法*/,int bits,char * cert/*输出证书公钥*/,int * certl/*长度*/,              char * key/*输出证书私钥*/,int * keyl/*长度*/,char * outMsg/*,int type结果类型DER,PEM*/);//直接生成公私钥  /*黑名单生成函数*/ BOOL MakeCrl(char *certfile/*根证书公钥*/,int certlen,/*为0则certfile为磁盘文件,否则为内存区域*/               char *keyfile/*根证书私钥*/,int keylen,               stuREVOKE * Head/*作废链表*/,PNewCrlMem NewCrlMem/*回调函数*/,char *& outCrl,int * crll,char * outfile/*crl文件*/,               char * outMsg/*操作结果*/);  /*分解p12包*/ BOOL ParseDB(char * strP12/*包文件*/,char * strPwd/*解包密码*/,char * strCert/*公钥存放*/,              char * strkey/*私钥存放*/,int outformat/*输出格式*/,char * out/*返回结果*/);  /*组合p12包*/ BOOL CreateDB(char * strP12/*包文件IN*/,char * strPwd/*密码IN*/,char * strCert/*公钥存放IN*/,               char * strkey/*私钥存放IN*/,char * out/*返回结果OUT*/);  BOOL ChangePB(char * strP12/*IN包文件*/,char * strPwd/*IN原密码*/,char * strPwd2/*IN新密码*/,               char * strOutP12/*OUT包文件*/,char * out/*返回结果OUT*/);  //检验公钥、私钥是否配对 BOOL CertPairCheck(char * cert,char * key,char * out);//检验公钥、私钥是否配对 

热点排行