openssl主要流程程序代码

19 篇文章 0 订阅
17 篇文章 0 订阅

 
  1. // CA.cpp : Defines the entry point for the DLL application.      
  2. //      
  3. #define sprintf_s sprintf       
  4. #include "stdafx.h"      
  5. #include <LOCALE.H>      
  6. #include "ca.h"      
  7. #include <OPENSSL pem.h>      
  8. #include <OPENSSL x509.h>      
  9. #include <OPENSSL x509v3.h>      
  10. #include <OPENSSL pkcs12.h>      
  11. #include <OPENSSL rand.h>      
  12. #include<STDLIB.H>      
  13. #include<STDIO.H>      
  14. #include <OPENSSL engine.h>      
  15. #define EXT_COPY_NONE   0      
  16. #define EXT_COPY_ADD    1      
  17. #define EXT_COPY_ALL    2      
  18.      
  19.      
  20. BOOL APIENTRY DllMain( HANDLE hModule,      
  21.                        DWORD  ul_reason_for_call,      
  22.                        LPVOID lpReserved     
  23.                      )     
  24. {     
  25.     return TRUE;     
  26. }     
  27.      
  28. /*此函数可以将DER、PEM、P12文件公钥读出来*/     
  29. X509 *load_cert(BIO *cert/*输入BIO*/int format/*格式*/,char * pwd,/*P12密码*/     
  30.                 char * outMsg) //从DER、PEM、P12格式中读取公钥证书      
  31. {     
  32.     X509 * x=NULL;     
  33.     if  (format == DER)     
  34.         x=d2i_X509_bio(cert,NULL);     
  35.     else if (format == PEM)     
  36.         x=PEM_read_bio_X509(cert,NULL,NULL,NULL);//PEM_read_bio_X509_AUX      
  37.     else if (format == P12)     
  38.     {     
  39.         PKCS12 *p12 = d2i_PKCS12_bio(cert, NULL);     
  40.         PKCS12_parse(p12, pwd, NULL, &x, NULL);     
  41.         PKCS12_free(p12);     
  42.         p12 = NULL;     
  43.     }     
  44.     else     
  45.     {     
  46.              
  47. sprintf_s(outMsg,"bad input format specified for input cert\n");     
  48.         goto end;     
  49.     }     
  50. end:     
  51.     if (x == NULL)     
  52.     {     
  53.         sprintf(outMsg,"unable to load certificate\n");     
  54.     }     
  55.     return(x);     
  56. }     
  57.      
  58. X509 * LoadCert(char * cert,int certlen,char * outMsg)//枚举DER/PEM格式      
  59. {     
  60.     BIO * in=NULL;     
  61.     X509 * x509=NULL;     
  62.      
  63.     if(certlen==0)//输入为磁盘文件      
  64.     {     
  65.         if((in=BIO_new_file(cert, "r")) == NULL)     
  66.         {     
  67.             sprintf(outMsg,"open CA certificate file error");     
  68.             return NULL;     
  69.         }     
  70.     }     
  71.     else//输入为内存中文件      
  72.     {     
  73.         if((in=BIO_new_mem_buf(cert,certlen))== NULL)//只读类型      
  74.         {     
  75.             sprintf(outMsg,"Make Mem Bio Error");     
  76.             return NULL;     
  77.         }     
  78.     }     
  79.     if((x509=load_cert(in,DER,NULL,outMsg))==NULL)//尝试DER      
  80.     {     
  81.         BIO_reset(in);//恢复bio      
  82.         x509=load_cert(in,PEM,NULL,outMsg);//尝试PEM      
  83.     }     
  84.     if (in != NULL) BIO_free(in);     
  85.     return x509;     
  86. }     
  87.      
  88. EVP_PKEY *load_key(BIO *bio, int format, char *pass,char * outMsg)//枚举DER/PEM格式      
  89. {     
  90.     EVP_PKEY *pkey=NULL;     
  91.      
  92.     if (format == DER)     
  93.     {     
  94.         pkey=d2i_PrivateKey_bio(bio, NULL);     
  95.     }     
  96.     else if (format == PEM)     
  97.     {     
  98.         pkey=PEM_read_bio_PrivateKey(bio,NULL,NULL,pass);     
  99.     }     
  100.     else if (format == P12)     
  101.     {     
  102.         PKCS12 *p12 = d2i_PKCS12_bio(bio, NULL);     
  103.         PKCS12_parse(p12, pass, &pkey, NULL, NULL);     
  104.         PKCS12_free(p12);     
  105.         p12 = NULL;     
  106.     }     
  107.     else     
  108.     {     
  109.         sprintf(outMsg,"bad input format specified for key\n");     
  110.         goto end;     
  111.     }     
  112. end:     
  113.     if (pkey == NULL)     
  114.         sprintf(outMsg,"unable to load Private Key\n");     
  115.     return(pkey);     
  116. }     
  117.      
  118. EVP_PKEY * LoadKey(char * key,int keylen,char * pass,char * outMsg)     
  119. {     
  120.     EVP_PKEY *pkey=NULL;     
  121.     BIO * in=NULL;     
  122.      
  123.     if(keylen==0)//输入为磁盘文件      
  124.     {     
  125.         if((in=BIO_new_file(key, "r")) == NULL)     
  126.         {     
  127.             sprintf(outMsg,"open CA certificate file error");     
  128.             return NULL;     
  129.         }     
  130.     }     
  131.     else//输入为内存中文件      
  132.     {     
  133.         if((in=BIO_new_mem_buf(key,keylen))== NULL)//只读类型      
  134.         {     
  135.             sprintf(outMsg,"Make Mem Bio Error");     
  136.             return NULL;     
  137.         }     
  138.     }     
  139.      
  140.     if((pkey=load_key(in,DER,pass,outMsg))==NULL)//尝试DER      
  141.     {     
  142.         BIO_reset(in);//BIO是可读写的,那么该BIO所有数据都会被清空;      
  143.                         //如果该BIO是只读的,那么该操作只会简单将指      
  144.                         //针指向原始位置,里面的数据可以再读.      
  145.         pkey=load_key(in,PEM,pass,outMsg);//尝试PEM      
  146.     }     
  147.     if (in != NULL) BIO_free(in);     
  148.     return pkey;     
  149. }     
  150. int Rand(const char *file,int dont_warn,char * outMsg)//产生随机数,return 0 ---成功      
  151. {     
  152.     int consider_randfile = (file == NULL);     
  153.     char buffer[200];     
  154.          
  155.     RAND_screen();     
  156.     if (file == NULL)     
  157.         file = RAND_file_name(buffer, sizeof buffer);     
  158.     else if (RAND_egd(file) > 0)     
  159.     {     
  160.     /* we try if the given filename is an EGD socket.   
  161.         if it is, we don't write anything back to the file. */     
  162.         return 1;     
  163.     }     
  164.     if (file == NULL || !RAND_load_file(file, -1))     
  165.     {     
  166.         if (RAND_status() == 0 && !dont_warn)     
  167.         {     
  168.             sprintf(outMsg,"unable to load 'random state'\n");     
  169.             sprintf(outMsg,"This means that the random number generator has not been seeded\n");     
  170.             if (consider_randfile) /* explanation does not apply when a file is explicitly named */     
  171.             {     
  172.                 sprintf(outMsg,"Consider setting the RANDFILE environment variable to point at a file that\n");     
  173.                 sprintf(outMsg,"'random' data can be kept in (the file will be overwritten).\n");     
  174.             }     
  175.         }     
  176.         return 0;     
  177.     }     
  178.     return 1;     
  179. }     
  180.      
  181.      
  182. / end       
  183. //      
  184. / begin //      
  185.      
  186. /* Add extension using V3 code: we can set the config file as NULL   
  187. * because we wont reference any other sections.   
  188. */     
  189. int Add_ExtCert(X509 *cert/*正被添加的证书*/,X509 * root/*根证书(从中得到信息)*/int nid, char *value)     
  190. {     
  191.     X509_EXTENSION *ex;     
  192.     X509V3_CTX ctx;     
  193.     /* This sets the 'context' of the extensions. */     
  194.     /* No configuration database */     
  195.     //  X509V3_set_ctx_nodb(&ctx);      
  196.     /* Issuer and subject certs: both the target since it is self signed,   
  197.     * no request and no CRL   
  198.     */     
  199.     X509V3_set_ctx(&ctx,root, cert, NULL, NULL, 0);     
  200.     ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);     
  201.     if (!ex)     
  202.         return 0;     
  203.          
  204.     X509_add_ext(cert,ex,-1);     
  205.     X509_EXTENSION_free(ex);     
  206.     return 1;     
  207. }     
  208.      
  209. bool Add_Name(X509_NAME * x509name,int type/*c\cn*/,char * iput/*中国*/,     
  210.               int ilen/*输入长度*/,char * outMsg)//支持中文名称      
  211. {     
  212.     wchar_t * ws,wc;     
  213.     ASN1_STRING stmp, *str = &stmp;     
  214.     UCHAR cbuf[256]={0};     
  215.     int wslen, wcnt,i;     
  216.     char input[256]={0};     
  217.     strncpy(input, iput, ilen);     
  218.     wslen = strlen(input) + 1;     
  219.     if(wslen==1)     
  220.         return true;     
  221.   ws =new unsigned short[sizeof(wchar_t) * wslen];       
  222.     if ((wcnt = mbstowcs(ws, input, wslen)) == -1)     
  223.     {     
  224.         sprintf(outMsg,"mbstowcs convert error");     
  225.         delete ws;     
  226.         return false;                    
  227.     }     
  228.     for(i=0;i<(int)wcslen(ws);i++)     
  229.     {      
  230.         wc=ws[i];     
  231.         cbuf[2*i]=wc/256;     
  232.         cbuf[2*i+1]=wc%256;     
  233.     }     
  234.      
  235.     ASN1_mbstring_copy(&str, cbuf, 2*wslen, MBSTRING_BMP, B_ASN1_UTF8STRING);     
  236.     X509_NAME_add_entry_by_NID(x509name,type,V_ASN1_UTF8STRING,stmp.data,stmp.length, -1, 0);     
  237.     delete ws;     
  238.     return true;     
  239. }     
  240. bool mkRoot(stuSUBJECT * rootInfo,X509 **x509p/*out公钥*/, EVP_PKEY **pkeyp/*out私钥*/,      
  241.            int bits/*位数*/int serial/*序列号*/int days/*有效期*/,char * out/*操作结果*/)     
  242. {     
  243.     X509 *x;     
  244.     EVP_PKEY *pk;     
  245.     RSA *rsa;     
  246.     X509_NAME *name=NULL;     
  247.     int i=0,len=0;     
  248.     if ((pkeyp == NULL) || (*pkeyp == NULL))     
  249.     {     
  250.         if ((pk=EVP_PKEY_new()) == NULL)     
  251.         {     
  252.             abort();      
  253.             return false;     
  254.         }     
  255.     }     
  256.     else     
  257.         pk= *pkeyp;     
  258.          
  259.     if ((x509p == NULL) || (*x509p == NULL))     
  260.     {     
  261.         if ((x=X509_new()) == NULL)     
  262.             goto err;     
  263.     }     
  264.     else     
  265.         x= *x509p;     
  266.      
  267.     Rand(NULL,1,out);//产生随机数种子      
  268.     rsa=RSA_generate_key(bits,RSA_F4,0/*回调函数callback*/,NULL);//产生密钥对,//RSA存储了公钥私钥      
  269.     if (!EVP_PKEY_assign_RSA(pk,rsa))//完成RSA密钥的pkey结构初始工作,当pk不为NULL的时候,返回1,否则返回0      
  270.     {     
  271.         abort();     
  272.         goto err;     
  273.     }     
  274.     rsa=NULL;     
  275.          
  276.     X509_set_version(x,2);//版本号,显示+1      
  277.     ASN1_INTEGER_set(X509_get_serialNumber(x),serial);//序列号      
  278.     X509_gmtime_adj(X509_get_notBefore(x),0);//起始时间      
  279.     X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);//结束时间      
  280.     X509_set_pubkey(x,pk);//公钥      
  281.          
  282.     name=X509_get_subject_name(x);     
  283.          
  284.     /* This function creates and adds the entry, working out the   
  285.     * correct string type and performing checks on its length.   
  286.     * Normally we'd check the return value for errors   
  287.     */     
  288.      
  289.     //C-国家,ST-省,L-城市,O-组织,OU-部门,CN-个体,T-title,D-description,G-givenName,I-initials,      
  290.     //Email-emailAddress,S-surname,SN-serialNumber,dnQualifier-dnQualifier,unstructuredName,challengePassword,unstructuredAddress,      
  291.      
  292.     setlocale(LC_CTYPE, "");     
  293.      
  294.     Add_Name(name,NID_countryName,(char *)rootInfo->C,sizeof(rootInfo->C),out);     
  295.     Add_Name(name,NID_stateOrProvinceName,(char *)rootInfo->ST,sizeof(rootInfo->ST),out);     
  296.     Add_Name(name,NID_localityName,(char *)rootInfo->L,sizeof(rootInfo->L),out);     
  297.     Add_Name(name,NID_organizationName,(char *)rootInfo->O,sizeof(rootInfo->O),out);     
  298.     Add_Name(name,NID_organizationalUnitName,(char *)rootInfo->OU,sizeof(rootInfo->OU),out);     
  299.     Add_Name(name,NID_commonName,(char *)rootInfo->CN,sizeof(rootInfo->CN),out);     
  300.     Add_Name(name,NID_pkcs9_emailAddress,(char *)rootInfo->MAIL,sizeof(rootInfo->MAIL),out);     
  301.     Add_Name(name,NID_email_protect,(char *)rootInfo->PMAIL,sizeof(rootInfo->PMAIL),out);     
  302.      
  303.          
  304.     Add_Name(name,NID_title,(char *)rootInfo->T,sizeof(rootInfo->T),out);     
  305.     Add_Name(name,NID_description,(char *)rootInfo->D,sizeof(rootInfo->D),out);     
  306.     Add_Name(name,NID_givenName,(char *)rootInfo->G,sizeof(rootInfo->G),out);      
  307.     Add_Name(name,NID_initials,(char *)rootInfo->I,sizeof(rootInfo->I),out);     
  308.     Add_Name(name,NID_name,(char *)rootInfo->NAME,sizeof(rootInfo->NAME),out);         
  309.     Add_Name(name,NID_surname,(char *)rootInfo->S,sizeof(rootInfo->S),out);     
  310.     Add_Name(name,NID_dnQualifier,(char *)rootInfo->QUAL,sizeof(rootInfo->QUAL),out);     
  311.     Add_Name(name,NID_pkcs9_unstructuredName,(char *)rootInfo->STN,sizeof(rootInfo->STN),out);     
  312.     Add_Name(name,NID_pkcs9_challengePassword,(char *)rootInfo->PW,sizeof(rootInfo->PW),out);     
  313.     Add_Name(name,NID_pkcs9_unstructuredAddress,(char *)rootInfo->ADD,sizeof(rootInfo->ADD),out);     
  314.      
  315.     /* Its self signed so set the issuer name to be the same as the   
  316.     * subject.   
  317.     */     
  318.          
  319.     X509_set_issuer_name(x,name);//设置发行者名称等同于上面的      
  320.      
  321.     //加入扩展信息      
  322.     /* Add various extensions: standard extensions */     
  323.     Add_ExtCert(x,x,NID_basic_constraints, "critical,CA:TRUE");     
  324.     //主题密钥标示符---当发行者有多个签名密钥时      
  325.     Add_ExtCert(x,x,NID_subject_key_identifier, "hash");     
  326.     //颁发机构密钥标示符      
  327.     Add_ExtCert(x,x,NID_authority_key_identifier, "keyid:always");     
  328.     //密钥用法      
  329.     Add_ExtCert(x,x,NID_key_usage, "nonRepudiation,digitalSignature,keyEncipherment");     
  330.     Add_ExtCert(x,x,NID_domainComponent, "no");      
  331.     Add_ExtCert(x,x,NID_Domain, "no");     
  332.     /* Some Netscape specific extensions */     
  333. //  Add_ExtCert(x, NID_netscape_cert_type, "sslCA");      
  334. //  Add_ExtCert(x, NID_netscape_comment, "example comment extension");//netscape_comment      
  335.          
  336.          
  337.     /* Maybe even add our own extension based on existing */     
  338.     //加入自定义信息begin      
  339. //  int nid;      
  340. //  nid = OBJ_create("1.2.3.4.9", "Hpxs", "I love you!");      
  341. //  X509V3_EXT_add_alias(nid, NID_netscape_comment);      
  342. //  Add_ExtCert(x, nid, "I love you");      
  343.     //加入自定义信息end      
  344.     X509V3_EXT_cleanup();//cleanup the extension code if any custom extensions have been added      
  345.     if (!X509_sign(x,pk,EVP_sha1()))//签名算法EVP_sha1,EVP_md5,用私钥签名公钥      
  346.     {     
  347.         strcpy(out,"证书签名失败");     
  348.         goto err;     
  349.     }     
  350.     *x509p=x;     
  351.     *pkeyp=pk;     
  352.     return true;     
  353. err:     
  354.     return false;     
  355. }     
  356.      
  357.      
  358. BOOL MakeRoot(stuSUBJECT * rootInfo,/*信息*/int bits/*位数*/int serial/*序列号*/,      
  359.               int days/*有效期*/,char * certFile/*证书文件*/,char * priFile/*私钥文件*/,     
  360.               char * outMsg/*操作结果*/,int type/*类型pem-der*/)     
  361. {     
  362.          
  363.     X509 *x509=NULL;     
  364.     EVP_PKEY *pkey=NULL;     
  365.     BIO * bcert=NULL,* bkey=NULL;     
  366.     bool ret=true;     
  367.     int i=0,j=0;     
  368.      
  369.     if(((bcert=BIO_new_file(certFile, "w"))== NULL)||((bkey=BIO_new_file(priFile, "w")) == NULL))     
  370.     {     
  371.         strcpy(outMsg,"Create File Error");     
  372.         return false;     
  373.     }     
  374.     if(mkRoot(rootInfo,&x509,&pkey,bits,serial,days,outMsg))     
  375.     {     
  376.         if (type==DER)     
  377.         {     
  378.             i=i2d_X509_bio(bcert,x509);//returns 1 for success       
  379.             j=i2d_PrivateKey_bio(bkey,pkey);     
  380.         }     
  381.         else if(type==PEM)     
  382.         {     
  383.             i=PEM_write_bio_X509(bcert,x509);     
  384.             j=PEM_write_bio_PrivateKey(bkey,pkey,NULL,NULL,0,NULL, NULL);     
  385.         }     
  386.         if(!i||!j)     
  387.         {     
  388.             ret=false;     
  389.             strcpy(outMsg,"Save Cert or Key File Error");     
  390.         }     
  391.     }     
  392.     else     
  393.         ret=false;     
  394.     BIO_free(bcert);     
  395.     BIO_free(bkey);     
  396.     X509_free(x509);     
  397.     EVP_PKEY_free(pkey);     
  398.     return ret;     
  399.      
  400. }     
  401.      
  402. / end       
  403. //      
  404. / begin //      
  405.      
  406. /* Add extension using V3 code: we can set the config file as NULL   
  407.  * because we wont reference any other sections.   
  408.  */     
  409. int Add_ExtReq(STACK_OF(X509_REQUEST) *sk, int nid, char *value)     
  410. {     
  411.     X509_EXTENSION *ex;     
  412.     ex = X509V3_EXT_conf_nid(NULL, NULL, nid, value);     
  413.     if (!ex)     
  414.         return 0;     
  415.     sk_X509_EXTENSION_push(sk, ex);     
  416.          
  417.     return 1;     
  418. }     
  419.          
  420. int mkReq(stuSUBJECT * reqInfo,X509_REQ **req, EVP_PKEY **pkeyp, int bits,char * out)     
  421. {     
  422.     X509_REQ *x;     
  423.     EVP_PKEY *pk;     
  424.     RSA *rsa;     
  425.     X509_NAME *name=NULL;     
  426.     ASN1_STRING stmp, *str = &stmp;     
  427.          
  428.     STACK_OF(X509_EXTENSION) *exts = NULL;     
  429.          
  430.     if ((pk=EVP_PKEY_new()) == NULL)     
  431.         goto err;     
  432.          
  433.     if ((x=X509_REQ_new()) == NULL)     
  434.         goto err;     
  435.     Rand(NULL,1,out);//产生随机数种子      
  436.     rsa=RSA_generate_key(bits,RSA_F4,0/*回调函数callback*/,NULL);//产生密钥对      
  437.     //PEM_write_bio_RSAPrivateKey      
  438.     if (!EVP_PKEY_assign_RSA(pk,rsa))     
  439.         goto err;     
  440.          
  441.     rsa=NULL;     
  442.          
  443.     X509_REQ_set_pubkey(x,pk);     
  444.          
  445.     name=X509_REQ_get_subject_name(x);     
  446.          
  447.     /* This function creates and adds the entry, working out the   
  448.     * correct string type and performing checks on its length.   
  449.     * Normally we'd check the return value for errors   
  450.     */     
  451.      
  452.     setlocale(LC_CTYPE, "");     
  453.      
  454.     Add_Name(name,NID_countryName,(char *)reqInfo->C,sizeof(reqInfo->C),out);     
  455.     Add_Name(name,NID_stateOrProvinceName,(char *)reqInfo->ST,sizeof(reqInfo->ST),out);     
  456.     Add_Name(name,NID_localityName,(char *)reqInfo->L,sizeof(reqInfo->L),out);     
  457.     Add_Name(name,NID_organizationName,(char *)reqInfo->O,sizeof(reqInfo->O),out);     
  458.     Add_Name(name,NID_organizationalUnitName,(char *)reqInfo->OU,sizeof(reqInfo->OU),out);     
  459.     Add_Name(name,NID_commonName,(char *)reqInfo->CN,sizeof(reqInfo->CN),out);     
  460.     Add_Name(name,NID_pkcs9_emailAddress,(char *)reqInfo->MAIL,sizeof(reqInfo->MAIL),out);     
  461.     Add_Name(name,NID_email_protect,(char *)reqInfo->PMAIL,sizeof(reqInfo->PMAIL),out);     
  462.      
  463.     Add_Name(name,NID_title,(char *)reqInfo->T,sizeof(reqInfo->T),out);     
  464.     Add_Name(name,NID_description,(char *)reqInfo->D,sizeof(reqInfo->D),out);     
  465.     Add_Name(name,NID_givenName,(char *)reqInfo->G,sizeof(reqInfo->G),out);     
  466.     Add_Name(name,NID_initials,(char *)reqInfo->I,sizeof(reqInfo->I),out);     
  467.     Add_Name(name,NID_name,(char *)reqInfo->NAME,sizeof(reqInfo->NAME),out);       
  468.     Add_Name(name,NID_surname,(char *)reqInfo->S,sizeof(reqInfo->S),out);     
  469.     Add_Name(name,NID_dnQualifier,(char *)reqInfo->QUAL,sizeof(reqInfo->QUAL),out);     
  470.     Add_Name(name,NID_pkcs9_unstructuredName,(char *)reqInfo->STN,sizeof(reqInfo->STN),out);     
  471.     Add_Name(name,NID_pkcs9_challengePassword,(char *)reqInfo->PW,sizeof(reqInfo->PW),out);     
  472.     Add_Name(name,NID_pkcs9_unstructuredAddress,(char *)reqInfo->ADD,sizeof(reqInfo->ADD),out);     
  473.      
  474.      
  475.     /* Certificate requests can contain extensions, which can be used   
  476.         * to indicate the extensions the requestor would like added to    
  477.         * their certificate. CAs might ignore them however or even choke   
  478.         * if they are present.   
  479.     */     
  480.          
  481.     /* For request extensions they are all packed in a single attribute.   
  482.     * We save them in a STACK and add them all at once later   
  483.     */     
  484.          
  485.     exts = sk_X509_EXTENSION_new_null();     
  486.     /* Standard extenions */     
  487.     //主题备用名称,URL:http://my.url.here/、支持email  copy      
  488.     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");     
  489.      
  490.     //加入自定义扩展      
  491.     int nid;     
  492.     nid = OBJ_create("1.3.6.1.4.1.5315.100.2.5""UserID""User ID Number");     
  493.     X509V3_EXT_add_alias(nid, NID_netscape_comment);     
  494.     Add_ExtReq(exts, nid, "ID130203197703060618");     
  495.     /* Now we've created the extensions we add them to the request */     
  496.      
  497.     X509_REQ_add_extensions(x, exts);     
  498.     sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);       
  499.     X509V3_EXT_cleanup();//cleanup the extension code if any custom extensions have been added      
  500.          
  501.     if (!X509_REQ_sign(x,pk,EVP_sha1()))//用自己的公钥签名私钥      
  502.         goto err;     
  503.          
  504.     *req=x;     
  505.     *pkeyp=pk;     
  506.     return(1);     
  507. err:     
  508.     return(0);     
  509. }     
  510.      
  511. BOOL MakeReq(stuSUBJECT * reqInfo,/*请求信息*/int bits/*位数*/,char * reqFile/*证书请求文件*/,     
  512.              char * priFile/*私钥文件*/,char * outMsg/*操作结果*/,int type)     
  513. {     
  514.     X509_REQ *req=NULL;     
  515.     EVP_PKEY *pkey=NULL;     
  516.     BIO * breq=NULL,* bkey=NULL;     
  517.     int i=0,j=0;     
  518.     if(((breq=BIO_new_file(reqFile, "w"))== NULL)||((bkey=BIO_new_file(priFile, "w")) == NULL))     
  519.     {     
  520.         strcpy(outMsg,"Create File Error");     
  521.         return false;     
  522.     }     
  523.     if(!mkReq(reqInfo,&req,&pkey,bits,outMsg))     
  524.     {     
  525.         strcpy(outMsg,"Make CertReq Error");     
  526.         return false;     
  527.     }     
  528.      
  529.     if(type==PEM)     
  530.     {     
  531.         i=PEM_write_bio_X509_REQ(breq,req);          
  532.         j=PEM_write_bio_PrivateKey(bkey,pkey,NULL,NULL,0,NULL, NULL);     
  533.     }     
  534.     else if(type==DER)     
  535.     {     
  536.         i=i2d_X509_REQ_bio(breq,req);     
  537.         j=i2d_PrivateKey_bio(bkey,pkey);     
  538.     }     
  539.     BIO_free(breq);     
  540.     BIO_free(bkey);     
  541.     X509_REQ_free(req);     
  542.     EVP_PKEY_free(pkey);     
  543.     if(!i||!j)     
  544.     {     
  545.         strcpy(outMsg,"Save Cert or Key File Error");     
  546.         return false;     
  547.     }     
  548.     return true;     
  549. }     
  550. // end //      
  551.       
  552. /// begin       
  553. int copy_extensions(X509 *x, X509_REQ *req, int copy_type)//在证书中加入req自带扩展信息      
  554. {     
  555.     STACK_OF(X509_EXTENSION) *exts = NULL;     
  556.     X509_EXTENSION *ext, *tmpext;     
  557.     ASN1_OBJECT *obj;     
  558.     int i, idx, ret = 0;     
  559.     if (!x || !req || (copy_type == EXT_COPY_NONE))     
  560.         return 1;     
  561.     exts = X509_REQ_get_extensions(req);     
  562.          
  563.     for(i = 0; i < sk_X509_EXTENSION_num(exts); i++)     
  564.     {     
  565.         ext = sk_X509_EXTENSION_value(exts, i);     
  566.         obj = X509_EXTENSION_get_object(ext);     
  567.         idx = X509_get_ext_by_OBJ(x, obj, -1);     
  568.         /* Does extension exist? */     
  569.         if (idx != -1)      
  570.         {     
  571.             /* If normal copy don't override existing extension */     
  572.             if (copy_type == EXT_COPY_ADD)     
  573.                 continue;     
  574.             /* Delete all extensions of same type */     
  575.             do     
  576.             {     
  577.                 tmpext = X509_get_ext(x, idx);     
  578.                 X509_delete_ext(x, idx);     
  579.                 X509_EXTENSION_free(tmpext);     
  580.                 idx = X509_get_ext_by_OBJ(x, obj, -1);     
  581.             } while (idx != -1);     
  582.         }     
  583.         if (!X509_add_ext(x, ext, -1))     
  584.             goto end;     
  585.     }     
  586.          
  587.     ret = 1;     
  588.          
  589. end:     
  590.          
  591.     sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);     
  592.          
  593.     return ret;     
  594. }     
  595.      
  596.      
  597. int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,int serial,     
  598.             char *startdate, char *enddate, int days,X509_REQ * req,stuKEYUSAGE * KUSAGE,     
  599.             stuEKEYUSAGE * EKUSAGE,char * outMsg)     
  600. {     
  601.     X509_NAME *name=NULL,*CAname=NULL;     
  602.     X509 *ret=NULL;     
  603.     X509_CINF *ci;     
  604.     EVP_PKEY *pktmp;     
  605.     int ok= -1,i=0;     
  606. //  STACK_OF (X509_EXTENSION) * req_exts;//如何释放??      
  607.     char kusage[160]={0};     
  608.     char ekusage[360]={0};     
  609.     name=X509_REQ_get_subject_name(req);     
  610.     if ((ret=X509_new()) == NULL)      
  611.     {     
  612.         ok=0;     
  613.         goto err;     
  614.     }     
  615.     ci=ret->cert_info;     
  616.      
  617.     /* Make it an X509 v3 certificate. 版本1扩展*/     
  618.     if (!X509_set_version(ret,2L)) //版本      
  619.     {     
  620.         ok=0;     
  621.         goto err;     
  622.     }     
  623.          
  624.     ASN1_INTEGER_set(X509_get_serialNumber(ret),serial);//序列号      
  625.      
  626.     if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))//发行者      
  627.     {     
  628.         ok=0;     
  629.         goto err;     
  630.     }     
  631.          
  632.     if (strcmp(startdate,"today") == 0)     
  633.         X509_gmtime_adj(X509_get_notBefore(ret),0);//开始日期      
  634.     else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);     
  635.          
  636.     if (enddate == NULL)     
  637.         X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);//结束日期      
  638.     else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);     
  639.          
  640.     if (!X509_set_subject_name(ret,name)) //主体 ---所有者      
  641.     {     
  642.         ok=0;     
  643.         goto err;     
  644.     }     
  645.          
  646.     pktmp=X509_REQ_get_pubkey(req);     
  647.     i = X509_set_pubkey(ret,pktmp);//公钥      
  648.     EVP_PKEY_free(pktmp);     
  649.     if (!i)      
  650.     {     
  651.         ok=0;     
  652.         goto err;     
  653.     }     
  654.          
  655.     //加入req自带扩展信息,生成REQ文件时候加入的      
  656.     if (!copy_extensions(ret, req, EXT_COPY_ALL))     
  657.     {     
  658.         strcpy("加入自带扩展信息失败",outMsg);     
  659.         goto err;     
  660.     }     
  661.      
  662.     /* Lets add the extensions, if there are any 加入标准扩展*/     
  663.      
  664.     //基本限制Note if the CA option is false the pathlen option should be omitted.       
  665.     Add_ExtCert(ret,ret,NID_basic_constraints, "critical,CA:FALSE,pathlen:1");     
  666.      
  667.     //主题密钥标示符--------区分拥有者多对密钥      
  668.     Add_ExtCert(ret,ret,NID_subject_key_identifier, "hash");     
  669.      
  670.     //Authority密钥标示符----区分发行者有多个签名密钥时      
  671.     Add_ExtCert(ret,x509, NID_authority_key_identifier, "keyid,issuer:always");     
  672.          
  673.      
  674.     //密钥用法 ----数字签名、不可否认性、密钥加密、数据加密、密钥协商、证书签名、      
  675.     //CRL签名、仅仅加密、仅仅解密      
  676.              
  677.     if(KUSAGE->DS)     
  678.         strcpy(kusage,"digitalSignature");     
  679.     if(KUSAGE->NR)     
  680.         if(strlen(kusage))//添加      
  681.             strcat(kusage, ",nonRepudiation");     
  682.         else     
  683.             strcpy(kusage,"nonRepudiation");     
  684.     if(KUSAGE->KE)     
  685.         if(strlen(kusage))//添加      
  686.             strcat(kusage, ",keyEncipherment");     
  687.         else     
  688.             strcpy(kusage,"keyEncipherment");     
  689.     if(KUSAGE->DE)     
  690.         if(strlen(kusage))//添加      
  691.             strcat(kusage, ",dataEncipherment");     
  692.         else     
  693.             strcpy(kusage,"dataEncipherment");     
  694.     if(KUSAGE->KA)     
  695.         if(strlen(kusage))//添加      
  696.             strcat(kusage, ",keyAgreement");     
  697.         else     
  698.             strcpy(kusage,"keyAgreement");     
  699.     if(KUSAGE->KC)     
  700.         if(strlen(kusage))//添加      
  701.             strcat(kusage, ",keyCertSign");     
  702.         else     
  703.             strcpy(kusage,"keyCertSign");     
  704.     if(KUSAGE->CS)     
  705.         if(strlen(kusage))//添加      
  706.             strcat(kusage, ",cRLSign");     
  707.         else     
  708.             strcpy(kusage,"cRLSign");     
  709.     if(KUSAGE->EO)     
  710.         if(strlen(kusage))//添加      
  711.             strcat(kusage, ",encipherOnly");     
  712.         else     
  713.             strcpy(kusage,"encipherOnly");     
  714.     if(KUSAGE->DO)     
  715.         if(strlen(kusage))//添加      
  716.             strcat(kusage, ",decipherOnly");     
  717.         else     
  718.             strcpy(kusage,"decipherOnly");     
  719.     if(strlen(kusage))     
  720.         Add_ExtCert(ret,ret, NID_key_usage, kusage);     
  721.      
  722.     //增强型密钥用法--一般只用于末端证书RFC3280      
  723.     //增强用法     证书目的      
  724.     //--------------------------------------------------------------------------------------------------------------      
  725.     //服务器验证          保证远程计算机的身份           
  726.     //客户端验证      向远程计算机证明您的身份       
  727.     //代码签名           确保软件来自软件发行商         
  728.     //安全电子邮件         保护软件在发行后不被改动       
  729.     //时间戳            保护电子邮件消息          
  730.     //--------------------------------------------------------------------------------------------------------------      
  731.     //                  保证软件来自一个软件发行商      
  732.     //                  保护软件在发行后不被改动。      
  733.     //                  保证软件来自商业软件发行商      
  734.     //                  允许您用数字签名证书信任列表      
  735.     //                  允许联机事务处理/通讯的严格加密      
  736.     //                  允许加密磁盘上的数据      
  737.     //                  智能卡登录      
  738.     //IP安全终端系统           允许 Internet 上的安全通讯           
  739.     //IP安全隧道终止             
  740.     //IP 安全用户                 
  741.     //--------------------------------------------------------------------------------------------------------------      
  742.      
  743.     if(EKUSAGE->SA)     
  744.         strcpy(ekusage,"serverAuth");     
  745.     if(EKUSAGE->CA)     
  746.         if(strlen(ekusage))//添加      
  747.             strcat(ekusage,",clientAuth");     
  748.         else     
  749.             strcpy(ekusage,"clientAuth");     
  750.     if(EKUSAGE->CS)     
  751.         if(strlen(ekusage))//添加      
  752.             strcat(ekusage,",codeSigning");     
  753.         else     
  754.             strcpy(ekusage,"codeSigning");     
  755.     if(EKUSAGE->EP)     
  756.         if(strlen(ekusage))//添加      
  757.             strcat(ekusage,",emailProtection");     
  758.         else     
  759.             strcpy(ekusage,"emailProtection");     
  760.     if(EKUSAGE->TS)     
  761.         if(strlen(ekusage))//添加      
  762.             strcat(ekusage,",timeStamping");     
  763.         else     
  764.             strcpy(ekusage,"timeStamping");     
  765.     if(EKUSAGE->msCC)     
  766.         if(strlen(ekusage))//添加      
  767.             strcat(ekusage,",msCodeCom");     
  768.         else     
  769.             strcpy(ekusage,"msCodeCom");     
  770.     if(EKUSAGE->msCTLS)     
  771.         if(strlen(ekusage))//添加      
  772.             strcat(ekusage,",msCTLSign");     
  773.         else     
  774.             strcpy(ekusage,"msCTLSign");     
  775.     if(EKUSAGE->msSGC)     
  776.         if(strlen(ekusage))//添加      
  777.             strcat(ekusage,",msSGC");     
  778.         else     
  779.             strcpy(ekusage,"msSGC");     
  780.     if(EKUSAGE->msEFS)     
  781.         if(strlen(ekusage))//添加      
  782.             strcat(ekusage,",msEFS");     
  783.         else     
  784.             strcpy(ekusage,"msEFS");     
  785.     if(EKUSAGE->msSC)     
  786.         if(strlen(ekusage))//添加      
  787.             strcat(ekusage,",msSmartcardLogin");     
  788.         else     
  789.             strcpy(ekusage,"msSmartcardLogin");     
  790.     if(EKUSAGE->IP)     
  791.         if(strlen(ekusage))//添加      
  792.             strcat(ekusage,",ipsecEndSystem,ipsecTunnel,ipsecUser");     
  793.         else     
  794.             strcpy(ekusage,"ipsecEndSystem,ipsecTunnel,ipsecUser");     
  795.     if(strlen(ekusage))     
  796.     Add_ExtCert(ret,ret,NID_ext_key_usage,ekusage);     
  797.      
  798.     /*   
  799.     Application         keyUsage  Values    
  800.     SSL Client          digitalSignature    
  801.     SSL Server          keyEncipherment    
  802.     S/MIME Signing      digitalSignature    
  803.     S/MIME Encryption   keyEncipherment    
  804.     Certificate         Signing keyCertSign    
  805.     Object Signing      digitalSignature */     
  806.      
  807.     //颁发者备用名称,URL:http://my.url.here/、不支持email  copy      
  808.     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");     
  809.      
  810.     //证书策略      
  811.     Add_ExtCert(ret,ret,NID_certificate_policies,"OK");     
  812.     //颁发机构信息访问      
  813.     Add_ExtCert(ret,ret,NID_info_access,"OCSP;URI:https://hpxs");//或者caIssuers;URI:http://my.ca/ca.html     
  814.     //CRL分发点      
  815.     Add_ExtCert(ret,x509, NID_crl_distribution_points, "URI:https://hpxs/hpxs.crl");     
  816.      
  817.     /* Some Netscape specific extensions */     
  818. //  Add_ExtCert(ret,ret, NID_crl_number, "sslCA");      
  819.      
  820. //  Add_ExtCert(ret,x509, NID_netscape_comment, "See http://cert.umd.edu/root for details.");      
  821.     /* In each case the 'value' of the extension is placed directly in the   
  822.     extension. Currently supported extensions in this category are: nsBaseUrl,   
  823.     nsRevocationUrl, nsCaRevocationUrl, nsRenewalUrl, nsCaPolicyUrl,   
  824.     nsSslServerName and nsComment   */     
  825.      
  826. //  Add_ExtCert(ret,x509, NID_netscape_cert_type, "client, server, email,objsign, reserved, sslCA,emailCA, objCA");      
  827.     /*nsCertType (netscape certificate type) takes the flags: client, server, email,   
  828.     objsign, reserved, sslCA, emailCA, objCA.*/     
  829.     /* Maybe even add our own extension based on existing */     
  830.     //加入自定义信息begin      
  831.     int nid;     
  832.     nid = OBJ_create("1.2.3.4.9""Hpxs""I love OpenSSL!");     
  833.     X509V3_EXT_add_alias(nid, NID_netscape_comment);     
  834.     Add_ExtCert(ret,ret, nid, "I love OpenSSL");     
  835.     //加入自定义信息end      
  836.     X509V3_EXT_cleanup();//cleanup the extension code if any custom extensions have been added      
  837.      
  838.     if (!X509_sign(ret,pkey,dgst))//加入签名,签名算法      
  839.     {     
  840.         ok=0;     
  841.         goto err;     
  842.     }     
  843.     ok=1;     
  844. err:     
  845.     if (CAname != NULL)     
  846.         X509_NAME_free(CAname);     
  847.     if (ok <= 0)     
  848.     {     
  849.         if (ret != NULL) X509_free(ret);     
  850.         ret=NULL;     
  851.     }     
  852.     else     
  853.         *xret=ret;     
  854.     return(ok);     
  855. }     
  856.      
  857. int certify(X509 **xret, X509_REQ *req, EVP_PKEY *pkey, X509 *x509,const EVP_MD *dgst,     
  858.                    int serial, char *startdate, char *enddate, int days,stuKEYUSAGE * KUSAGE,     
  859.                    stuEKEYUSAGE * EKUSAGE,char * outMsg)     
  860. {//返回公钥证书,请求文件,根私钥,根公钥,      
  861.     EVP_PKEY *pktmp=NULL;     
  862.     int ok= -1,i=0;      
  863.     if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)//得到公钥      
  864.     {     
  865.         sprintf(outMsg,"error unpacking public key\n");     
  866.         ok=0;     
  867.         goto err;     
  868.     }     
  869.     i=X509_REQ_verify(req,pktmp);//证书请求里面有私要签名,这里验证一下,看此公钥主人是否持有私钥      
  870.     EVP_PKEY_free(pktmp);     
  871.     if (i < 0)     
  872.     {     
  873.         ok=0;     
  874.         sprintf(outMsg,"Signature verification problems.\n");     
  875.         goto err;     
  876.     }     
  877.     if (i == 0)     
  878.     {     
  879.         ok=0;     
  880.         sprintf(outMsg,"Signature did not match the certificate request\n");     
  881.         goto err;     
  882.     }     
  883.          
  884.     ok=do_body(xret,pkey,x509,dgst,serial,startdate, enddate,     
  885.         days,req,KUSAGE,EKUSAGE,outMsg);     
  886.          
  887. err:     
  888.     return(ok);     
  889. }     
  890.      
  891.      
  892. BOOL MakeCert(char *certfile/*根证书公钥*/,int certlen,/*为0则certfile为磁盘文件,否则为内存区域*/     
  893.               char *keyfile/*根证书私钥*/,int keylen,int serial/*序列号*/,char *enddate/*作废日期*/,     
  894.               int days/*有效期*/char *reqfile/*请求文件*/,stuKEYUSAGE * KUSAGE/*密钥用法*/,     
  895.               stuEKEYUSAGE * EKUSAGE/*增强密钥用法*/,char *outfile/*结果文件*/,     
  896.               char * outMsg/*操作结果*/,int type/*结果类型DER,PEM*/)//通过证书请求,得到证书      
  897. {     
  898.     int ret=1;     
  899.     char * md=NULL;     
  900.     EVP_PKEY *pkey=NULL;     
  901.     X509 * x509=NULL;     
  902.     X509_REQ *req=NULL;     
  903.     X509 * x=NULL;     
  904.     BIO * bcert=NULL,* reqbio=NULL;     
  905.     int j;     
  906.     const EVP_MD *dgst=NULL;     
  907.      
  908.     OpenSSL_add_all_digests();//加入签名算法      
  909.      
  910.     if((reqbio=BIO_new_file(reqfile, "r")) == NULL)     
  911.     {     
  912.         ret=0;     
  913.         goto err;     
  914.     }     
  915.          
  916.     if ((req=PEM_read_bio_X509_REQ(reqbio,NULL,NULL,NULL)) == NULL)//PEM_read_X509_REQ       
  917.     {     
  918.         BIO_reset(reqbio);     
  919.         if ((req=d2i_X509_REQ_bio(reqbio,NULL)) == NULL)     
  920.         {     
  921.             sprintf(outMsg,"Error get certificate request");     
  922.             ret=0;     
  923.             goto err;     
  924.         }     
  925.     }     
  926.      
  927.     pkey=LoadKey(keyfile,keylen,NULL,outMsg);     
  928.     if (pkey == NULL)     
  929.     {     
  930.         ret = 0;     
  931.         goto err;     
  932.     }     
  933.      
  934.     x509=LoadCert(certfile,certlen,outMsg);     
  935.     if (x509 == NULL)     
  936.     {     
  937.         ret = 0;     
  938.         goto err;     
  939.     }     
  940.          
  941.     if (!X509_check_private_key(x509,pkey))     
  942.     {     
  943.         sprintf(outMsg,"CA certificate and CA private key do not match\n");     
  944.         ret = 0;     
  945.         goto err;     
  946.     }     
  947.     md="sha1";//!!!!!!!!!!!!!!!!!      
  948.     if ((dgst=EVP_get_digestbyname(md)) == NULL)//return an EVP_MD structure when passed a digest name      
  949.     {     
  950.         sprintf(outMsg,"%s is an unsupported message digest type\n",md);     
  951.         ret = 0;     
  952.         goto err;     
  953.     }     
  954.     j=certify(&x,req,pkey,x509,dgst,//公钥证书out,请求文件,根私钥,根公钥,      
  955.         serial,"today",enddate,days,KUSAGE,EKUSAGE,outMsg);     
  956.     if (j <= 0)      
  957.     {     
  958.         ret=0;     
  959.         goto err;     
  960.     }     
  961.      
  962.     if(((bcert=BIO_new_file(outfile, "w"))== NULL))     
  963.     {     
  964.         strcpy(outMsg,"Create File Error");     
  965.         goto err;     
  966.     }     
  967.     if (type==DER)     
  968.     {     
  969.         i2d_X509_bio(bcert,x);     
  970.     }     
  971.     else if(type==PEM)     
  972.     {     
  973.         PEM_write_bio_X509(bcert,x);     
  974.     }     
  975. err:     
  976.     if (reqbio != NULL) BIO_free(reqbio);     
  977.     BIO_free_all(bcert);     
  978.     EVP_PKEY_free(pkey);     
  979.     X509_free(x509);     
  980.     X509_free(x);     
  981.     if (req != NULL) X509_REQ_free(req);     
  982.     EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER      
  983.     return ret;     
  984.      
  985. }     
  986. / end       
  987. BOOL DirectCert(char *certfile/*根证书公钥*/,int certlen,/*为0则certfile为磁盘文件,否则为内存区域*/     
  988.              char *keyfile/*根证书私钥*/,int keylen,int serial/*序列号*/,char *enddate/*作废日期*/,     
  989.              int days/*有效期*/,stuCERT * sCERT/*用户信息与密钥用法*/,int bits,char * cert/*输出证书公钥*/,int * certl/*长度*/,     
  990.              char * key/*输出证书私钥*/,int * keyl/*长度*/,char * outMsg/*,int type结果类型DER,PEM*/)//直接生成公私钥      
  991. {     
  992.     X509_REQ * req=NULL;     
  993.     EVP_PKEY * pkey=NULL, * prkey=NULL;//证书私钥,//根私钥      
  994.     X509 * x509=NULL,* x=NULL;//根公钥,证书公钥      
  995.     BIO * memcert=NULL, * memkey=NULL;//输出证书公私钥      
  996.     BUF_MEM *bptrcert=NULL,*bptrkey=NULL;     
  997.     int ret=1;     
  998.     char * md=NULL;     
  999.     int i=0,j=0,ok=0;     
  1000.     const EVP_MD *dgst=NULL;     
  1001.      
  1002.     OpenSSL_add_all_digests();//加入签名算法      
  1003.     memcert= BIO_new(BIO_s_mem());     
  1004.     memkey= BIO_new(BIO_s_mem());     
  1005.     BIO_set_close(memcert, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */     
  1006.     BIO_set_close(memkey, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */     
  1007.      
  1008.     prkey=LoadKey(keyfile,keylen,NULL,outMsg);//RAND_bytes      
  1009.     if (prkey == NULL)     
  1010.     {     
  1011.         ret = 0;     
  1012.         goto err;     
  1013.     }     
  1014.      
  1015.     x509=LoadCert(certfile,certlen,outMsg);     
  1016.     if (x509 == NULL)     
  1017.     {     
  1018.         ret = 0;     
  1019.         goto err;     
  1020.     }     
  1021.          
  1022.     if (!X509_check_private_key(x509,prkey))     
  1023.     {     
  1024.         sprintf(outMsg,"CA certificate and CA private key do not match\n");     
  1025.         ret = 0;     
  1026.         goto err;     
  1027.     }     
  1028.      
  1029.     if(!mkReq(&(sCERT->SUBJECT),&req,&pkey, bits,outMsg))     
  1030.     {     
  1031.         sprintf(outMsg,"Make CertReq error");     
  1032.         ret = 0;     
  1033.         goto err;     
  1034.     }     
  1035.      
  1036.     md="sha1";//!!!!!!!!!!!!!!!!!      
  1037.     if ((dgst=EVP_get_digestbyname(md)) == NULL)//return an EVP_MD structure when passed a digest name      
  1038.     {     
  1039.         sprintf(outMsg,"%s is an unsupported message digest type\n",md);     
  1040.         ret = 0;     
  1041.         goto err;     
  1042.     }     
  1043.     ok=certify(&x,req,prkey,x509,dgst,//公钥证书out,请求,根私钥,根公钥,      
  1044.         serial,"today",enddate,days,&(sCERT->KUSAGE),&(sCERT->EKUSAGE),outMsg);     
  1045.     if (ok <= 0)      
  1046.     {     
  1047.         ret=0;     
  1048.         goto err;     
  1049.     }     
  1050. /*  if (type==DER)   
  1051.     {   
  1052.         i=i2d_X509_bio(memcert,x);   
  1053.         j=i2d_PrivateKey_bio(memkey,pkey);//生成的结果错误!?????????????   
  1054.     }   
  1055.     else if(type==PEM)   
  1056. */  {     
  1057.         i=PEM_write_bio_X509(memcert,x);     
  1058.         j=PEM_write_bio_PrivateKey(memkey,pkey,NULL,NULL,0,NULL, NULL);     
  1059.     }     
  1060.      
  1061.     if(!i||!j)     
  1062.     {     
  1063.         strcpy(outMsg,"Get Mem Cert or Key File Error");     
  1064.         ret=0;     
  1065.         goto err;     
  1066.     }     
  1067.      
  1068.     BIO_get_mem_ptr(memcert, &bptrcert);     
  1069.     *certl=bptrcert->length;     
  1070.     memcpy(cert,bptrcert->data,*certl);     
  1071.      
  1072.     BIO_get_mem_ptr(memkey, &bptrkey);     
  1073.     *keyl=bptrkey->length;     
  1074.     memcpy(key,bptrkey->data,*keyl);     
  1075.      
  1076. err:     
  1077.     BIO_free_all(memcert);     
  1078.     BIO_free_all(memkey);     
  1079.     EVP_PKEY_free(pkey);     
  1080.     EVP_PKEY_free(prkey);     
  1081.     X509_free(x509);     
  1082.     X509_free(x);     
  1083.     if (req != NULL) X509_REQ_free(req);     
  1084.     EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER      
  1085.     return ret;     
  1086. }     
  1087. //      
  1088. / begin //      
  1089. /*添加链表节点*/     
  1090. void AddRevoke(stuREVOKE *& Head,int index,time_t time)     
  1091. {     
  1092.     stuREVOKE * End=new stuREVOKE(index,time);//钥增加的节点      
  1093.     if(Head==NULL)     
  1094.     {     
  1095.         Head=End;     
  1096.     }     
  1097.     else      
  1098.     {     
  1099.         stuREVOKE * p=Head;     
  1100.         while(p->Link!=NULL)       
  1101.             p=p->Link;     
  1102.         p->Link=End;      
  1103.     }     
  1104.      
  1105.     return;     
  1106. }     
  1107.      
  1108. int Add_ExtCrl(X509_CRL *crl/*正被添加的证书*/,X509 * root/*根证书(从中得到信息)*/,      
  1109.                int nid, char *value)     
  1110. {     
  1111.     X509V3_CTX ctx;     
  1112.     X509_EXTENSION *ex;     
  1113.      
  1114.     /* This sets the 'context' of the extensions. */     
  1115.     /* No configuration database */     
  1116. //  X509V3_set_ctx_nodb(&ctx);      
  1117.     X509V3_set_ctx(&ctx, root, NULL, NULL, crl, 0);     
  1118. //  issuerAltName  authorityKeyIdentifier      
  1119.     ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);     
  1120.     if (!ex)     
  1121.         return 0;     
  1122.     X509_CRL_add_ext(crl,ex,-1);     
  1123.     X509_EXTENSION_free(ex);     
  1124.     return 1;     
  1125. }     
  1126.      
  1127.      
  1128. BOOL MakeCrl(char *certfile/*根证书公钥*/,int certlen,/*为0则certfile为磁盘文件,否则为内存区域*/     
  1129.               char *keyfile/*根证书私钥*/,int keylen,     
  1130.               stuREVOKE * Head/*作废链表*/,PNewCrlMem NewCrlMem/*回调函数*/,char *& outCrl,int * crll,char * outfile/*crl文件*/,     
  1131.               char * outMsg/*操作结果*/)     
  1132. {     
  1133.     X509_CRL_INFO *ci = NULL;     
  1134.     X509_CRL *crl = NULL;     
  1135.     int ret=1,i=0;     
  1136.     char *key=NULL;     
  1137.     char *md=NULL;     
  1138.     EVP_PKEY *pkey=NULL;     
  1139.     X509 *x509=NULL;     
  1140.     BIO *in=NULL,*out=NULL;     
  1141.     const EVP_MD *dgst=NULL;     
  1142.     X509_REVOKED *r=NULL;     
  1143.     long crldays=30;     
  1144.     long crlhours=0;     
  1145.     stuREVOKE * temp =NULL;     
  1146.     BIO * memcrl=NULL;     
  1147.     BUF_MEM *bptrcrl=NULL;     
  1148.      
  1149.     OpenSSL_add_all_algorithms();     
  1150.      
  1151.     pkey=LoadKey(keyfile,keylen,NULL,outMsg);     
  1152.     if (pkey == NULL)     
  1153.     {     
  1154.         ret = 0;     
  1155.         goto err;     
  1156.     }     
  1157.     x509=LoadCert(certfile,certlen,outMsg);     
  1158.     if (x509 == NULL)     
  1159.     {     
  1160.         ret = 0;     
  1161.         goto err;     
  1162.     }     
  1163.          
  1164.     if (!X509_check_private_key(x509,pkey))     
  1165.     {     
  1166.         sprintf(outMsg,"CA certificate and CA private key do not match\n");     
  1167.         ret = 0;     
  1168.         goto err;     
  1169.     }     
  1170.     md="md5";//!!!!!!!!!!!!!!!!!      
  1171.     if ((dgst=EVP_get_digestbyname(md)) == NULL)//return an EVP_MD structure when passed a digest name      
  1172.     {     
  1173.         sprintf(outMsg,"%s is an unsupported message digest type\n",md);     
  1174.         ret = 0;     
  1175.         goto err;     
  1176.     }     
  1177.          
  1178.     if ((crl=X509_CRL_new()) == NULL)     
  1179.     {     
  1180.         ret = 0;     
  1181.         goto err;     
  1182.     }     
  1183.     ci=crl->crl;     
  1184.     X509_NAME_free(ci->issuer);     
  1185.     ci->issuer=X509_NAME_dup(x509->cert_info->subject);     
  1186.     if (ci->issuer == NULL)     
  1187.     {     
  1188.         ret = 0;     
  1189.         goto err;     
  1190.     }     
  1191.     X509_gmtime_adj(ci->lastUpdate,0);     
  1192.     if (ci->nextUpdate == NULL)     
  1193.         ci->nextUpdate=ASN1_UTCTIME_new();     
  1194.     X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);     
  1195.      
  1196.     if(!ci->revoked)     
  1197.         ci->revoked = sk_X509_REVOKED_new_null();     
  1198.      
  1199.          
  1200.     while(Head!=NULL)//遍历链表      
  1201.     {     
  1202.         temp=Head;     
  1203.         X509_REVOKED *r = NULL;     
  1204.         BIGNUM *serial_bn = NULL;     
  1205.         r = X509_REVOKED_new();     
  1206.         ASN1_TIME_set(r->revocationDate,Head->time);//时间      
  1207.         char index[100];     
  1208.         BN_hex2bn(&serial_bn,itoa(Head->Index,index,10));//序号      
  1209.         BN_to_ASN1_INTEGER(serial_bn,r->serialNumber);     
  1210.         sk_X509_REVOKED_push(ci->revoked,r);     
  1211.         Head=Head->Link;     
  1212.         delete temp;     
  1213.     }     
  1214. //  sk_X509_REVOKED_sort(ci->revoked);      
  1215.     for (i=0; i<SK_X509_REVOKED_NUM(CI->revoked); i++)     
  1216.     {     
  1217.         r=sk_X509_REVOKED_value(ci->revoked,i);     
  1218.         r->sequence=i;     
  1219.     }     
  1220.      
  1221.     if (ci->version == NULL)     
  1222.     if ((ci->version=ASN1_INTEGER_new()) == NULL)     
  1223.     {     
  1224.         ret = 0;     
  1225.         goto err;     
  1226.     }     
  1227.     ASN1_INTEGER_set(ci->version,1);     
  1228.     //  issuerAltName  authorityKeyIdentifier      
  1229. //  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");      
  1230.     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");     
  1231.     Add_ExtCrl(crl,x509,NID_authority_key_identifier, "keyid,issuer:always");     
  1232.     if (!X509_CRL_sign(crl,pkey,dgst))     
  1233.     {     
  1234.         ret = 0;     
  1235.         goto err;     
  1236.     }     
  1237.     if(NewCrlMem)//输出内存      
  1238.     {     
  1239.         memcrl= BIO_new(BIO_s_mem());     
  1240.         BIO_set_close(memcrl, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */     
  1241.         PEM_write_bio_X509_CRL(memcrl,crl);     
  1242.         BIO_get_mem_ptr(memcrl, &bptrcrl);     
  1243.         *crll=bptrcrl->length;     
  1244.         outCrl=NewCrlMem(*crll);     
  1245.         memcpy(outCrl,bptrcrl->data,*crll);     
  1246.     }     
  1247.     if(outfile)//输出文件      
  1248.     {     
  1249.         out=BIO_new_file(outfile, "w");     
  1250.         if(out==NULL)     
  1251.         {     
  1252.             sprintf(outMsg,"%s is error",outfile);     
  1253.             ret = 0;     
  1254.             goto err;     
  1255.         }     
  1256.         PEM_write_bio_X509_CRL(out,crl);     
  1257.     }     
  1258.      
  1259.     X509V3_EXT_cleanup();//cleanup the extension code if any custom extensions have been added      
  1260. err:     
  1261.     if(out)     
  1262.         BIO_free_all(out);     
  1263.     if(memcrl)     
  1264.         BIO_free_all(memcrl);     
  1265.     BIO_free(in);     
  1266.     EVP_PKEY_free(pkey);     
  1267.     X509_CRL_free(crl);     
  1268.     X509_free(x509);     
  1269.     EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER      
  1270.     if(ret==1)     
  1271.         strcpy(outMsg,"CRL制作成功");     
  1272.     return ret;     
  1273.          
  1274. }     
  1275.      
  1276. BOOL CertFormatConver(char * buf/*文件内容或文件名称*/,int len/*内存长度为0则buf为文件名*/,     
  1277.               char * pwd/*p12文件密码*/,char * pem/*输出文件*/,     
  1278.               int outformat,char * out/*操作结果*/)     
  1279. {     
  1280.     EVP_PKEY *key=NULL;     
  1281.     X509 *cert=NULL;     
  1282.     BIO *biout=NULL;     
  1283.     int i=0;     
  1284.     //输出文件      
  1285.     if ((biout=BIO_new_file(pem, "w")) == NULL)     
  1286.     {     
  1287.         return false;     
  1288.     }            
  1289.     cert = LoadCert(buf,len,out);//首先尝试公钥,bio被改写      
  1290.     if(cert)//输入文件为公钥文件      
  1291.     {     
  1292.      
  1293.         if  (outformat == DER)     
  1294.             i=i2d_X509_bio(biout,cert);     
  1295.         else if (outformat == PEM)     
  1296.         {     
  1297.         //  if (trustout) i=PEM_write_bio_X509_AUX(biout,x);      
  1298.             i=PEM_write_bio_X509(biout,cert);     
  1299.         }     
  1300.         if(!i)//失败      
  1301.             strcpy(out,"保存公钥失败");     
  1302.         else     
  1303.             strcpy(out,"公钥证书格式转换成功");     
  1304.              
  1305.     }     
  1306.      
  1307.     else//输入文件为私钥文件      
  1308.     {     
  1309.         key=LoadKey(buf,len,pwd,out);     
  1310.         if(!key)      
  1311.         {     
  1312.             strcpy(out,"不能识别的文件格式");     
  1313.             return false;     
  1314.         }     
  1315.         if(outformat==PEM)     
  1316.         {        
  1317.             PEM_write_bio_PrivateKey(biout, key, NULL, NULL, 0, 0, NULL);     
  1318.         }     
  1319.         if(outformat==DER)     
  1320.         {     
  1321.             i2d_PrivateKey_bio(biout,key);//得到解密后的私钥      
  1322.         }     
  1323.              
  1324.         strcpy(out,"私钥证书格式转换成功");     
  1325.     }     
  1326.          
  1327.     if (biout != NULL) BIO_free(biout);     
  1328.     X509_free(cert);     
  1329.     EVP_PKEY_free(key);     
  1330.      
  1331.     return true;     
  1332. }     
  1333.      
  1334. //分解p12包      
  1335. BOOL ParseDB(char * strP12/*包文件*/,char * strPwd/*私钥密码*/,char * strCert/*公钥存放*/,     
  1336.              char * strkey/*私钥存放*/,int outformat/*输出格式*/,char * out/*返回结果*/)     
  1337. {     
  1338.     EVP_PKEY *key=NULL;     
  1339.     X509 *cert=NULL;     
  1340.     STACK_OF(X509) *ca = NULL;     
  1341.     BIO * bio=NULL,*bioCert=NULL,*bioKey=NULL;     
  1342.     PKCS12 *p12=NULL;     
  1343.     int i=0,j=0;     
  1344.          
  1345.     if((bio=BIO_new_file(strP12, "r")) == NULL)     
  1346.     {     
  1347.         strcpy(out,"打开文件错误");     
  1348.         return false;     
  1349.     }     
  1350.     SSLeay_add_all_algorithms();     
  1351.     p12 = d2i_PKCS12_bio(bio, NULL);     
  1352.     if (!PKCS12_parse(p12, strPwd, &key, &cert/*PEM*/, &ca))      
  1353.     {     
  1354.         strcpy(out,"解包失败");     
  1355.         return false;     
  1356.     }     
  1357.     PKCS12_free(p12);     
  1358.      
  1359.     //输出文件      
  1360.     if ((bioCert=BIO_new_file(strCert, "w")) == NULL)     
  1361.     {     
  1362.         return false;     
  1363.     }     
  1364.     if ((bioKey=BIO_new_file(strkey, "w")) == NULL)     
  1365.     {     
  1366.         return false;     
  1367.     }     
  1368.          
  1369.     if(outformat == DER)     
  1370.     {     
  1371.         i=i2d_X509_bio(bioCert,cert);     
  1372.         j=i2d_PrivateKey_bio(bioKey,key);     
  1373.     }     
  1374.     else if (outformat == PEM)     
  1375.     {     
  1376.         i=PEM_write_bio_X509(bioCert,cert);     
  1377.         j=PEM_write_bio_PrivateKey(bioKey, key, NULL, NULL, 0, 0, NULL);     
  1378.     }     
  1379.      
  1380.     if (bio != NULL) BIO_free(bio);     
  1381.     if (bioCert != NULL) BIO_free(bioCert);     
  1382.     if (bioKey != NULL) BIO_free(bioKey);     
  1383.     X509_free(cert);     
  1384.     EVP_PKEY_free(key);     
  1385.      
  1386.     EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER      
  1387.     if(i!=0&&j!=0)     
  1388.     {     
  1389.         strcpy(out,"分解P12成功");     
  1390.         return true;     
  1391.     }     
  1392.     return false;     
  1393. }     
  1394.      
  1395. //组合p12包      
  1396. BOOL CreateDB(char * strP12/*OUT包文件*/,char * strPwd/*IN密码*/,char * strCert/*IN公钥*/,     
  1397.               char * strkey/*IN私钥*/,char * out/*返回结果*/)     
  1398. {     
  1399.     FILE *fp=NULL;     
  1400.     EVP_PKEY *key=NULL;     
  1401.     X509 *cert=NULL;     
  1402.     PKCS12 *p12;     
  1403.     cert =LoadCert(strCert,0,out);     
  1404.     if(!cert)      
  1405.     {     
  1406.         strcpy(out,"读取公钥文件失败");     
  1407.         return false;     
  1408.     }     
  1409.     key=LoadKey(strkey,0,NULL,out);//解密后私钥      
  1410.     if(!key)      
  1411.     {     
  1412.         strcpy(out,"读取私钥文件失败");     
  1413.         return false;     
  1414.     }     
  1415.     SSLeay_add_all_algorithms();     
  1416.     p12 = PKCS12_create(strPwd,"(hpxs)", key, cert, NULL, 0,0,0,0,0);     
  1417.     if(!p12)     
  1418.     {     
  1419.         strcpy(out,"创建p12结构失败");     
  1420.         return false;     
  1421.     }     
  1422.     if (!(fp = fopen(strP12, "wb")))      
  1423.     {     
  1424.         strcpy(out,"保存p12文件失败");     
  1425.     }     
  1426.     i2d_PKCS12_fp(fp, p12);     
  1427.     PKCS12_free(p12);     
  1428.     fclose(fp);     
  1429.     strcpy(out,"合并P12成功");     
  1430.     X509_free(cert);     
  1431.     EVP_PKEY_free(key);     
  1432.     EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER      
  1433.     return true;     
  1434. }     
  1435.      
  1436. //修改p12包密码      
  1437. BOOL ChangePB(char * strP12/*in包文件*/,char * strPwd/*IN原密码*/,char * strPwd2/*IN新密码*/,     
  1438.               char * strOutP12/*in包文件*/,char * out/*返回结果*/)     
  1439. {     
  1440.     FILE *fp=NULL;     
  1441.     EVP_PKEY *key=NULL;     
  1442.     X509 *cert=NULL;     
  1443.     STACK_OF(X509) *ca = NULL;     
  1444.     PKCS12 *p12=NULL;     
  1445.     int len=0,wlen=0;     
  1446.      
  1447.     SSLeay_add_all_algorithms();     
  1448.     if (!(fp = fopen(strP12, "rb")))     
  1449.     {     
  1450.         strcpy(out,"打开文件错误");     
  1451.         return false;     
  1452.     }     
  1453.     p12 = d2i_PKCS12_fp(fp, NULL);     
  1454.     fclose (fp);     
  1455.     if (!p12)      
  1456.     {     
  1457.         strcpy(out,"读取包文件错误");     
  1458.         return false;     
  1459.     }     
  1460.     if (!PKCS12_parse(p12, strPwd, &key, &cert, &ca))      
  1461.     {     
  1462.         strcpy(out,"解包失败");     
  1463.         return false;     
  1464.     }     
  1465.     PKCS12_free(p12);     
  1466.     fclose(fp);     
  1467.     p12=NULL;     
  1468.     ///      
  1469.     p12 = PKCS12_create(strPwd2,"(null)", key, cert, NULL, 0,0,0,0,0);     
  1470.     if(!p12)     
  1471.     {     
  1472.         strcpy(out,"创建p12结构失败");     
  1473.         return false;     
  1474.     }     
  1475.     if (!(fp = fopen(strOutP12, "wb")))      
  1476.     {     
  1477.         strcpy(out,"保存p12文件失败");     
  1478.     }     
  1479.     i2d_PKCS12_fp(fp, p12);     
  1480.     PKCS12_free(p12);     
  1481.     fclose(fp);     
  1482.     strcpy(out,"转换P12密码成功");     
  1483.     X509_free(cert);     
  1484.     EVP_PKEY_free(key);     
  1485.     return true;     
  1486. }     
  1487.      
  1488. BOOL CertPairCheck(char * cert,char * key,char * out)//检验公钥、私钥是否配对      
  1489. {     
  1490.     EVP_PKEY *pkey=NULL;     
  1491.     X509 *x509=NULL;     
  1492.     x509=LoadCert(cert,0,out);     
  1493.     if(x509==NULL)     
  1494.     {     
  1495.         strcpy(out,"不能打开公钥文件");     
  1496.         return FALSE;     
  1497.     }     
  1498.     pkey=LoadKey(key,0,NULL,out);     
  1499.     if(pkey==NULL)     
  1500.     {     
  1501.         strcpy(out,"不能打开私钥文件");     
  1502.         X509_free(x509);     
  1503.         return FALSE;     
  1504.     }     
  1505.     if(X509_check_private_key(x509,pkey))//匹配      
  1506.     {     
  1507.         X509_free(x509);     
  1508.         EVP_PKEY_free(pkey);     
  1509.         return TRUE;     
  1510.     }     
  1511.     else     
  1512.     {     
  1513.         strcpy(out,"公私钥对不匹配");     
  1514.         X509_free(x509);     
  1515.         EVP_PKEY_free(pkey);     
  1516.         return FALSE;     
  1517.     }     
  1518.      
  1519. }     
  1520.      
  1521. #include    
  1522. #define DER                1 //FORMAT_ASN1   
  1523. #define PEM                3    /*定义格式*/   
  1524. #define NET                4   
  1525. #define P12                5   
  1526.    
  1527. typedef char * (* PNewCrlMem)(UINT len);   
  1528.    
  1529. struct stuSUBJECT//个体信息   
  1530. {   
  1531.     UCHAR C[4];//国家   
  1532.     UCHAR ST[4];//省份   
  1533.     UCHAR L[12];//城市   
  1534.     UCHAR O[48];//组织   
  1535.     UCHAR OU[24];//组织部门   
  1536.     UCHAR CN[12];//个人信息   
  1537.     UCHAR MAIL[24];//电子邮件   
  1538.     UCHAR PMAIL[24];//安全电子邮件   
  1539.     UCHAR T[12];//头衔   
  1540.     UCHAR D[12];//描述   
  1541.     UCHAR G[12];//曾用名   
  1542.     UCHAR I[12];//描述   
  1543.     UCHAR NAME[12];//描述   
  1544.     UCHAR S[12];//描述   
  1545.     UCHAR QUAL[12];//描述   
  1546.     UCHAR STN[12];//没有结构的名称   
  1547.     UCHAR PW[12];//挑战密码   
  1548.     UCHAR ADD[12];//无结构地址   
  1549.    
  1550.     stuSUBJECT()   
  1551.     {   
  1552.         memset(this,0,sizeof(stuSUBJECT));   
  1553.     }   
  1554. };   
  1555.    
  1556. struct stuKEYUSAGE//密钥用途   
  1557. {   
  1558.     BOOL DS;//Digital Signature   
  1559.     BOOL NR;//Non-Repudiation   
  1560.     BOOL KE;//Key Encipherment   
  1561.     BOOL DE;//Data Encipherment   
  1562.     BOOL KA;//keyAgreement   
  1563.     BOOL KC;//keyCertSign    
  1564.     BOOL CS;//cRLSign   
  1565.     BOOL EO;//Encipher Only   
  1566.     BOOL DO;//Decipher Only   
  1567.     stuKEYUSAGE()   
  1568.     {   
  1569.         memset(this,0,sizeof(stuKEYUSAGE));   
  1570.     }   
  1571.    
  1572. };   
  1573.    
  1574. struct stuEKEYUSAGE//增强型密钥用途   
  1575. {   
  1576.     BOOL SA;//服务器验证   
  1577.     BOOL CA;//客户端验证   
  1578.     BOOL CS;//代码签名   
  1579.     BOOL EP;//安全电子邮件   
  1580.     BOOL TS;//时间戳   
  1581.     BOOL msCC;//代码完整   
  1582.     BOOL msCTLS;//可签名信任列表   
  1583.     BOOL msSGC;//联机事务处理   
  1584.     BOOL msEFS;//加密磁盘上的数据   
  1585.     BOOL msSC;//智能卡登录   
  1586.     BOOL IP;//Internet   
  1587.     stuEKEYUSAGE()   
  1588.     {   
  1589.         memset(this,0,sizeof(stuEKEYUSAGE));   
  1590.     }   
  1591.    
  1592. };   
  1593.    
  1594. struct stuCERT//三者之和   
  1595. {   
  1596.     stuSUBJECT SUBJECT;   
  1597.     stuKEYUSAGE KUSAGE;   
  1598.     stuEKEYUSAGE EKUSAGE;   
  1599.     stuCERT()   
  1600.     {   
  1601.         memset(this,0,sizeof(stuCERT));   
  1602.     }   
  1603. };   
  1604.    
  1605. struct stuREVOKE//证书作废结构链表   
  1606. {   
  1607.     int Index;//证书序号   
  1608.     time_t time;//吊销时间   
  1609.     stuREVOKE * Link;   
  1610.     stuREVOKE()   
  1611.     {   
  1612.         memset(this,0,sizeof(stuREVOKE));   
  1613.     }   
  1614.     stuREVOKE(int index,time_t t)   
  1615.     {   
  1616.         Index=index;   
  1617.         time=t;;   
  1618.         Link=NULL;   
  1619.     }   
  1620. };   
  1621.    
  1622. /*添加链表节点*/   
  1623. void AddRevoke(stuREVOKE *& Head,int index,time_t time);   
  1624.    
  1625. /*证书格式转换函数*/   
  1626. BOOL CertFormatConver(char * buf/*内存区域,存储文件内容或文件名称*/,int len/*内存长度==0则buf为文件名*/,   
  1627.               char * pwd/*p12文件密码*/,char * pem/*输出文件*/,int outformat,char * out/*操作结果*/);   
  1628.    
  1629. /*根证书生成函数,根据rootInfo信息,生成根证书公、私钥文件*/   
  1630. BOOL MakeRoot(stuSUBJECT * rootInfo,/*请求信息IN*/int bits/*位数IN*/int serial/*序列号IN*/,    
  1631.               int days/*有效期IN*/,char * certFile/*证书请求文件OUT*/,char * priFile/*私钥文件OUT*/,   
  1632.               char * out/*操作结果OUT*/,int type=PEM/*类型pem-der*/);   
  1633.    
  1634. /*证书请求生成函数,根据reqInfo信息,生成用户证书私钥文件、证书请求文件*/   
  1635. BOOL MakeReq(stuSUBJECT * reqInfo,/*请求信息IN*/int bits/*位数IN*/char * reqFile/*证书请求文件OUT*/,   
  1636.              char * priFile/*私钥文件OUT*/,char * out/*操作结果OUT*/,int type=PEM/*类型pem-der*/);   
  1637.    
  1638. /*证书生成函数,通过证书请求,生成用户证书公钥文件*/   
  1639. BOOL MakeCert(char *certfile/*根证书公钥*/,int certlen,/*为0则certfile为磁盘文件,否则为内存区域*/   
  1640.               char *keyfile/*根证书私钥*/,int keylen,int serial/*序列号*/,char *enddate/*作废日期*/,   
  1641.               int days/*有效期*/char *reqfile/*请求文件*/,stuKEYUSAGE * KUSAGE/*密钥用法*/,   
  1642.               stuEKEYUSAGE * EKUSAGE/*增强密钥用法*/,char *outfile/*结果文件*/,   
  1643.               char * outMsg/*操作结果*/,int type/*结果类型DER,PEM*/);//通过证书请求,得到证书   
  1644.    
  1645. //直接生成公私钥   
  1646. BOOL DirectCert(char *certfile/*根证书公钥*/,int certlen,/*为0则certfile为磁盘文件,否则为内存区域*/   
  1647.              char *keyfile/*根证书私钥*/,int keylen,int serial/*序列号*/,char *enddate/*作废日期*/,   
  1648.              int days/*有效期*/,stuCERT * sCERT/*用户信息与密钥用法*/,int bits,char * cert/*输出证书公钥*/,int * certl/*长度*/,   
  1649.              char * key/*输出证书私钥*/,int * keyl/*长度*/,char * outMsg/*,int type结果类型DER,PEM*/);//直接生成公私钥   
  1650.    
  1651. /*黑名单生成函数*/   
  1652. BOOL MakeCrl(char *certfile/*根证书公钥*/,int certlen,/*为0则certfile为磁盘文件,否则为内存区域*/   
  1653.               char *keyfile/*根证书私钥*/,int keylen,   
  1654.               stuREVOKE * Head/*作废链表*/,PNewCrlMem NewCrlMem/*回调函数*/,char *& outCrl,int * crll,char * outfile/*crl文件*/,   
  1655.               char * outMsg/*操作结果*/);   
  1656.    
  1657. /*分解p12包*/   
  1658. BOOL ParseDB(char * strP12/*包文件*/,char * strPwd/*解包密码*/,char * strCert/*公钥存放*/,   
  1659.              char * strkey/*私钥存放*/,int outformat/*输出格式*/,char * out/*返回结果*/);   
  1660.    
  1661. /*组合p12包*/   
  1662. BOOL CreateDB(char * strP12/*包文件IN*/,char * strPwd/*密码IN*/,char * strCert/*公钥存放IN*/,   
  1663.               char * strkey/*私钥存放IN*/,char * out/*返回结果OUT*/);   
  1664.    
  1665. BOOL ChangePB(char * strP12/*IN包文件*/,char * strPwd/*IN原密码*/,char * strPwd2/*IN新密码*/,   
  1666.               char * strOutP12/*OUT包文件*/,char * out/*返回结果OUT*/);   
  1667.    
  1668. //检验公钥、私钥是否配对   
  1669. BOOL CertPairCheck(char * cert,char * key,char * out);//检验公钥、私钥是否配对  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值