CA.cpp
上传用户:dengkfang
上传日期:2008-12-30
资源大小:5233k
文件大小:68k
源码类别:

CA认证

开发平台:

Visual C++

  1. // CA.cpp : Defines the entry point for the DLL application.
  2. //
  3. #include "stdafx.h"
  4. #include <locale.h>
  5. #include "ca.h"
  6. #include <openssl/pem.h>
  7. #include <openssl/err.h>
  8. #include <openssl/x509.h>
  9. #include <openssl/x509v3.h>
  10. #include <openssl/pkcs12.h>
  11. #include <openssl/rand.h>
  12. //#include <sys/stat.h>   stat() 可以得到文件状态
  13. #define EXT_COPY_NONE 0
  14. #define EXT_COPY_ADD 1
  15. #define EXT_COPY_ALL 2
  16. #define MAX_CERT_LEN 8192 //最大公钥长度
  17. #define MAX_KEY_LEN 4096 //最大私钥长度
  18. BOOL APIENTRY DllMain( HANDLE hModule, 
  19.                        DWORD  ul_reason_for_call, 
  20.                        LPVOID lpReserved
  21.  )
  22. {
  23. switch(ul_reason_for_call) 
  24. case DLL_PROCESS_ATTACH: 
  25. OpenSSL_add_all_algorithms(); //leak EVP_cleanup(void);
  26. ERR_load_crypto_strings(); // leak  ERR_free_strings()
  27. //ENGINE_load_builtin_engines();
  28. break;
  29. case DLL_PROCESS_DETACH: 
  30. CONF_modules_unload(1);
  31. EVP_cleanup();
  32. CRYPTO_cleanup_all_ex_data(); 
  33. ERR_remove_state(0);
  34. ERR_free_strings(); 
  35. CONF_modules_free();
  36. break; 
  37. }
  38. return TRUE;
  39. }
  40. void LastError(char * info)
  41. {
  42. /* BIO * mem = BIO_new(BIO_s_mem());
  43. BIO_set_close(mem, BIO_CLOSE); 
  44. ERR_print_errors(mem);
  45. BUF_MEM * bptr = NULL;
  46. BIO_get_mem_ptr(mem, &bptr);
  47. int len = bptr->length;
  48. char * pbuf = new char[len+1];
  49. memset(pbuf,0,len+1);
  50. memcpy(pbuf,bptr->data,len);
  51. delete [] pbuf;*/
  52. }
  53. /*此函数可以将DER、PEM、P12文件公钥读出来*/
  54. X509 *load_cert(BIO * pBioCert/*输入BIO*/, const int iFormat/*格式*/,
  55. const char * lpszPwd,/*P12密码*/
  56. char * outMsg) //从DER、PEM、P12格式中加载公钥证书
  57. {
  58. X509 * x = NULL;
  59. if(iFormat == DER)
  60. x = d2i_X509_bio(pBioCert,NULL);
  61. else if (iFormat == PEM)
  62. x = PEM_read_bio_X509(pBioCert,NULL,NULL,NULL);//PEM_read_bio_X509_AUX
  63. else if (iFormat == P12)
  64. {
  65. OpenSSL_add_all_algorithms();
  66. PKCS12 *p12 = d2i_PKCS12_bio(pBioCert, NULL);
  67. PKCS12_parse(p12, lpszPwd, NULL, &x, NULL);
  68. PKCS12_free(p12);
  69. p12 = NULL;
  70. // EVP_cleanup();
  71. }
  72. else
  73. {
  74. sprintf(outMsg,"bad input format specified for input certn");
  75. goto end;
  76. }
  77. end:
  78. if (x == NULL)
  79. {
  80. sprintf(outMsg,"unable to load certificaten");
  81. }
  82. else
  83. sprintf(outMsg,"");
  84. return(x);
  85. }
  86. X509 * LoadCert(const char * lpszCert,const int iCertlen,
  87. const char * lpszPass,char * outMsg)//枚举DER/PEM格式
  88. {
  89. BIO * in = NULL;
  90. X509 * x509 = NULL;
  91. if(iCertlen == 0)//输入为磁盘文件
  92. {
  93. if((in = BIO_new_file(lpszCert, "r")) == NULL)
  94. {
  95. sprintf(outMsg,"open CA certificate file error");
  96. return NULL;
  97. }
  98. }
  99. else//输入为内存中文件
  100. {
  101. if((in = BIO_new_mem_buf((void *)lpszCert,iCertlen)) == NULL)//只读类型
  102. {
  103. sprintf(outMsg,"Make Mem Bio Error");
  104. return NULL;
  105. }
  106. }
  107. if((x509 = load_cert(in,DER,NULL,outMsg)) == NULL)//尝试DER
  108. {
  109. BIO_reset(in);//恢复bio
  110. if((x509 = load_cert(in,PEM,NULL,outMsg)) == NULL)//尝试PEM
  111. {
  112. BIO_reset(in);//恢复bio
  113. x509 = load_cert(in,P12,lpszPass,outMsg);//尝试P12
  114. }
  115. }
  116. if (in != NULL) BIO_free(in);
  117. return x509;
  118. }
  119. EVP_PKEY * load_key(BIO * pBioKey, const int iFormat, const char * lpszPass,char * outMsg)//枚举DER/PEM格式
  120. {
  121. EVP_PKEY * pkey = NULL;
  122. OpenSSL_add_all_algorithms();
  123. if (iFormat == DER)
  124. {
  125. if(NULL == lpszPass || strlen(lpszPass) == 0)
  126. {
  127. pkey = d2i_PrivateKey_bio(pBioKey, NULL);
  128. }
  129. else
  130. {
  131. //添加解密链
  132. unsigned char key[EVP_MAX_KEY_LENGTH] = "";//算法最长的KEY长度
  133. unsigned char iv[EVP_MAX_IV_LENGTH] = "";//算法最长的IV长度
  134. BIO * bDec = NULL;
  135. bDec = BIO_new(BIO_f_cipher());
  136. const EVP_CIPHER * cipher = NULL;
  137. cipher = EVP_des_ede3_cbc(); // 3DES-EDE-CBC 
  138. if(EVP_BytesToKey(cipher,EVP_sha1(),NULL,(unsigned char *)lpszPass,
  139. strlen(lpszPass),1,key,iv))
  140. {
  141. BIO_set_cipher(bDec,cipher,key,iv, 0);//1-加密、0-解密
  142. pBioKey = BIO_push(bDec, pBioKey); 
  143. BIO_flush(pBioKey);
  144. pkey = d2i_PrivateKey_bio(pBioKey, NULL);//私钥解密
  145. pBioKey = BIO_pop(pBioKey);
  146. BIO_free(bDec);
  147. }
  148. else
  149. {
  150. strcpy(outMsg,"初始化key or iv 失败");
  151. goto end;
  152. }
  153. }
  154. }
  155. else if (iFormat == PEM)
  156. {
  157. pkey = PEM_read_bio_PrivateKey(pBioKey,NULL,NULL,(void * )lpszPass);
  158. }
  159. else if (iFormat == P12)
  160. {
  161. PKCS12 *p12 = d2i_PKCS12_bio(pBioKey, NULL);
  162. PKCS12_parse(p12, lpszPass, &pkey, NULL, NULL);
  163. PKCS12_free(p12);
  164. p12 = NULL;
  165. }
  166. else
  167. {
  168. sprintf(outMsg,"bad input format specified for keyn");
  169. goto end;
  170. }
  171. end:
  172. // EVP_cleanup();
  173. if (pkey == NULL)
  174. sprintf(outMsg,"unable to load Private Keyn");
  175. else
  176. sprintf(outMsg,"");
  177. return(pkey);
  178. }
  179. EVP_PKEY * LoadKey(const char * lpszkey,const int iKeylen,const char * lpszPass,char * outMsg) //leak 4772
  180. {
  181. EVP_PKEY *pkey = NULL;
  182. BIO * in = NULL;
  183. if(iKeylen ==0 )//输入为磁盘文件
  184. {
  185. if((in = BIO_new_file(lpszkey, "r")) == NULL)
  186. {
  187. sprintf(outMsg,"open CA certificate file error");
  188. goto end;
  189. }
  190. }
  191. else//输入为内存中文件
  192. {
  193. if((in = BIO_new_mem_buf((void *)lpszkey,iKeylen)) == NULL)//只读类型
  194. {
  195. sprintf(outMsg,"Make Mem Bio Error");
  196. goto end;
  197. }
  198. }
  199. if((pkey = load_key(in,DER,lpszPass,outMsg)) == NULL)//尝试DER
  200. {
  201. BIO_reset(in);//BIO是可读写的,那么该BIO所有数据都会被清空;
  202. //如果该BIO是只读的,那么该操作只会简单将指
  203. //针指向原始位置,里面的数据可以再读.
  204. if((pkey = load_key(in,PEM,lpszPass,outMsg)) == NULL)//尝试PEM
  205. {
  206. BIO_reset(in);
  207. pkey = load_key(in,P12,lpszPass,outMsg);
  208. }
  209. }
  210. end:
  211. if (in != NULL)
  212. {
  213. BIO_flush(in);
  214. BIO_free_all(in);
  215. }
  216. return pkey;
  217. }
  218. int Rand(const char * file,const int dont_warn,char * outMsg)//产生随机数,return 0 ---成功
  219. {
  220. int consider_randfile = (file == NULL);
  221. char buffer[200];
  222. RAND_screen();
  223. if (file == NULL)
  224. file = RAND_file_name(buffer, sizeof buffer);
  225. else if (RAND_egd(file) > 0)
  226. {
  227. /* we try if the given filename is an EGD socket.
  228. if it is, we don't write anything back to the file. */
  229. return 1;
  230. }
  231. if (file == NULL || !RAND_load_file(file, -1))
  232. {
  233. if (RAND_status() == 0 && !dont_warn)
  234. {
  235. sprintf(outMsg,"unable to load 'random state'n");
  236. sprintf(outMsg,"This means that the random number generator has not been seededn");
  237. if (consider_randfile) /* explanation does not apply when a file is explicitly named */
  238. {
  239. sprintf(outMsg,"Consider setting the RANDFILE environment variable to point at a file thatn");
  240. sprintf(outMsg,"'random' data can be kept in (the file will be overwritten).n");
  241. }
  242. }
  243. return 0;
  244. }
  245. return 1;
  246. }
  247. ///////////////////////// end ////////////////////////////////////////
  248. //////////////////////////////////////////////////////////////////////
  249. ///////////////////////// begin //////////////////////////////////////
  250. /* Add extension using V3 code: we can set the config file as NULL
  251. * because we wont reference any other sections.
  252. */
  253. int Add_ExtCert(X509 * pCert/*正被添加的证书*/,X509 * pRoot/*根证书(从中得到信息)*/,
  254. const int iNid, const char * lpszValue)
  255. {
  256. X509_EXTENSION * ex = NULL;
  257. X509V3_CTX ctx;
  258. /* This sets the 'context' of the extensions. */
  259. /* No configuration database */
  260. X509V3_set_ctx_nodb(&ctx);
  261. /* Issuer and subject certs: both the target since it is self signed,
  262. * no request and no CRL
  263. */
  264. X509V3_set_ctx(&ctx,pRoot, pCert, NULL, NULL, 0);
  265. ex = X509V3_EXT_nconf_nid(NULL, &ctx, iNid, (char *)lpszValue);//X509V3_EXT_nconf
  266. if (!ex)
  267. {
  268. return 0;
  269. }
  270. X509_add_ext(pCert,ex,-1);
  271. X509_EXTENSION_free(ex);
  272. return 1;
  273. }
  274. int Add_ExtCert(X509 *pCert/*正被添加的证书*/,X509 * pRoot/*根证书(从中得到信息)*/, 
  275. const char * lpszName, const char *lpszValue)
  276. {
  277. X509_EXTENSION * ex = NULL;
  278. X509V3_CTX ctx;
  279. /* This sets the 'context' of the extensions. */
  280. /* No configuration database */
  281. X509V3_set_ctx_nodb(&ctx);
  282. /* Issuer and subject certs: both the target since it is self signed,
  283. * no request and no CRL
  284. */
  285. X509V3_set_ctx(&ctx, pRoot, pCert, NULL, NULL, 0);
  286. ex = X509V3_EXT_conf(NULL, &ctx, (char *)lpszName, (char *)lpszValue);//X509V3_EXT_nconf
  287. if (!ex)
  288. {
  289. return 0;
  290. }
  291. X509_add_ext(pCert,ex,-1);
  292. X509_EXTENSION_free(ex);
  293. return 1;
  294. }
  295. int AddExtCert(X509 *pCert/*正被添加的证书*/,X509 * pRoot/*根证书(从中得到信息)*/, 
  296.    const stuCERTEXT * pCertExt)
  297. {
  298. /* This sets the 'context' of the extensions. */
  299. /* No configuration database */
  300. /* Issuer and subject certs: both the target since it is self signed,
  301. * no request and no CRL
  302. */
  303. //基本限制Note if the CA option is FALSE the pathlen option should be omitted. 
  304. // Add_ExtCert(pCert,pCert,NID_friendlyName, "130203197703060618");
  305. //主题密钥标示符--------区分拥有者多对密钥
  306. // Add_ExtCert(pCert,pCert,NID_subject_key_identifier, "hash");
  307. //Authority密钥标示符----区分发行者有多个签名密钥时
  308. // Add_ExtCert(pCert,pRoot, NID_authority_key_identifier, "keyid,issuer:always");
  309. //密钥用法 ----数字签名、不可否认性、密钥加密、数据加密、密钥协商、证书签名、
  310. //颁发者备用名称,URL:http://my.url.here/、不支持email  copy
  311. // Add_ExtCert(pCert,pCert, NID_issuer_alt_name, 
  312. // "DNS:hpxs,email:hpxs@hotmail.com,RID:1.2.3.4,URI:https://hpxs,IP:192.168.0.22");
  313. //
  314. //证书策略
  315. // Add_ExtCert(pCert,pCert,NID_certificate_policies,"requireExplicitPolicy:3");
  316. //颁发机构信息访问
  317. // Add_ExtCert(pCert,pCert,NID_info_access,"OCSP;URI:https://hpxs");//或者caIssuers;URI:http://my.ca/ca.html
  318. //CRL分发点
  319. // Add_ExtCert(pCert,pCert, NID_crl_distribution_points, "URI:https://hpxs/hpxs.crl");
  320. /* Some Netscape specific extensions */
  321. // Add_ExtCert(ret,ret, NID_crl_number, "sslCA");
  322. // Add_ExtCert(ret,px509, NID_netscape_comment, "See http://cert.umd.edu/root for details.");
  323. /* In each case the 'value' of the extension is placed directly in the
  324. extension. Currently supported extensions in this category are: nsBaseUrl,
  325. nsRevocationUrl, nsCaRevocationUrl, nsRenewalUrl, nsCaPolicyUrl,
  326. nsSslServerName and nsComment */
  327. // Add_ExtCert(ret,px509, NID_netscape_cert_type, "client, server, email,objsign, reserved, sslCA,emailCA, objCA");
  328. /*nsCertType (netscape certificate type) takes the flags: client, server, email,
  329. objsign, reserved, sslCA, emailCA, objCA.*/
  330. /* Maybe even add our own extension based on existing */
  331. // nid = OBJ_create("1.3.6.1.4.1.5315.100.2.5", "Hpxs", "OC61108551");0.9.2342.19200300.100.1.1
  332. // X509V3_EXT_add_alias(nid, NID_netscape_comment);
  333. // Add_ExtCert(ret,ret, nid, "OC61108551");
  334. while(pCertExt!=NULL)//遍历链表
  335. {
  336. if(OBJ_sn2nid(pCertExt->cName) == NID_authority_key_identifier)
  337. {
  338. Add_ExtCert(pCert, pRoot, OBJ_sn2nid(pCertExt->cName), (char *)pCertExt->cInfo);
  339. }
  340. else if(strstr(pCertExt->cName, ".") == NULL) //没有发现.
  341. {
  342. Add_ExtCert(pCert, pCert, OBJ_sn2nid(pCertExt->cName), (char *)pCertExt->cInfo);
  343. }
  344. else
  345. { //加入自定义信息begin
  346. int nid;
  347. nid = OBJ_create(pCertExt->cName, pCertExt->cName, pCertExt->cName);
  348. if(nid != NID_undef)
  349. {
  350. X509V3_EXT_add_alias(nid, NID_netscape_comment);
  351. Add_ExtCert(pCert,pCert, nid, pCertExt->cInfo);
  352. }
  353. OBJ_cleanup();
  354. }
  355. pCertExt = pCertExt->Link;
  356. }
  357. return 1;
  358. }
  359. void Ansi2Utf8(const LPSTR lpsrc, const int srclen, LPSTR lpdst, int& dstlen)
  360. {
  361. WCHAR * pwUnicode;      
  362.     int len = MultiByteToWideChar(CP_ACP,0,(char*)lpsrc,srclen,NULL,0);      
  363.     pwUnicode = new WCHAR[len];  
  364.     memset(pwUnicode,0,len);
  365.     MultiByteToWideChar(CP_ACP,0 ,(char*)lpsrc,srclen,pwUnicode,len);      
  366.     dstlen = WideCharToMultiByte(CP_UTF8,0,pwUnicode,len,NULL,0,NULL,NULL);      
  367.     WideCharToMultiByte(CP_UTF8,0,pwUnicode,len,lpdst,dstlen,NULL,NULL);      
  368.     delete []pwUnicode;      
  369. }
  370. BOOL Add_Name(X509_NAME * px509Name,const int iNid/*ccn*/,
  371.   const int iType/*V_ASN1_UTF8STRING*/,
  372.   const char * lpszInput/*中国*/,
  373.   const int iLen/*输入长度*/)//支持中文名称
  374. {
  375. if(NULL == lpszInput || strlen(lpszInput) == 0)
  376. return FALSE;
  377. if(iType == V_ASN1_UTF8STRING)
  378. {
  379. char lpdst[1024] = {0};
  380. int dstlen = 0;
  381. char input[256]={0};
  382. strncpy(input, lpszInput, iLen);
  383. Ansi2Utf8(input, iLen, lpdst, dstlen);
  384. X509_NAME_add_entry_by_NID(px509Name,iNid,V_ASN1_UTF8STRING,(UCHAR *)lpdst,dstlen, -1, 0);
  385. }
  386. else
  387. X509_NAME_add_entry_by_NID(px509Name,iNid,iType,(UCHAR *)lpszInput,iLen, -1, 0);
  388. return TRUE;
  389. }
  390. BOOL Add_Name(X509_NAME * px509Name,const char * field/*ccn*/,
  391.   const char * lpszInput/*中国*/,
  392.   const int iLen/*输入长度*/)//支持中文名称
  393. {
  394. if(NULL == lpszInput || strlen(lpszInput) == 0)
  395. return FALSE;
  396. BOOL bRet = FALSE;
  397. int nid = NID_undef;
  398. int iType = V_ASN1_UTF8STRING;
  399. if(strstr(field, ".") == NULL) //没有发现.
  400. {
  401. nid = OBJ_txt2nid(field);
  402. }
  403. else
  404. {
  405. nid = OBJ_create(field, field, field);
  406. }
  407. if(nid != NID_undef)
  408. {
  409. if(NID_pkcs9_emailAddress == nid)
  410. {
  411. iType = V_ASN1_IA5STRING;
  412. }
  413. else
  414. {
  415. iType = V_ASN1_UTF8STRING;
  416. }
  417. bRet = Add_Name(px509Name, nid, iType, lpszInput, iLen);
  418. }
  419. OBJ_cleanup();
  420. return bRet;
  421. }
  422. void AddName(X509_NAME * px509Name,const stuSUBJECT * pSubJect)
  423. {
  424. setlocale(LC_CTYPE, "");
  425. while(pSubJect != NULL)//遍历链表
  426. {
  427. Add_Name(px509Name, (char *)pSubJect->cName, (char *)pSubJect->cInfo,strlen((char *)pSubJect->cInfo));
  428. pSubJect = pSubJect->Link;
  429. }
  430. /*
  431. Add_Name(px509Name,NID_stateOrProvinceName,V_ASN1_UTF8STRING,(char *)pSubJect->ST,strlen((char *)pSubJect->ST));
  432. Add_Name(px509Name,NID_localityName,V_ASN1_UTF8STRING,(char *)pSubJect->L,strlen((char *)pSubJect->L));
  433. Add_Name(px509Name,NID_organizationName,V_ASN1_UTF8STRING,(char *)pSubJect->O,strlen((char *)pSubJect->O));
  434. Add_Name(px509Name,NID_organizationalUnitName,V_ASN1_UTF8STRING,(char *)pSubJect->OU,strlen((char *)pSubJect->OU));
  435. Add_Name(px509Name,NID_commonName,V_ASN1_UTF8STRING,(char *)pSubJect->CN,strlen((char *)pSubJect->CN));
  436. Add_Name(px509Name,NID_pkcs9_emailAddress,V_ASN1_IA5STRING,(char *)pSubJect->MAIL,strlen((char *)pSubJect->MAIL));
  437. Add_Name(px509Name,NID_title,V_ASN1_UTF8STRING,(char *)pSubJect->T,strlen((char *)pSubJect->T));
  438. // Add_Name(px509Name,NID_description,(char *)pSubJect->D,strlen((char *)pSubJect->D));
  439. Add_Name(px509Name,NID_givenName,V_ASN1_UTF8STRING,(char *)pSubJect->G,strlen((char *)pSubJect->G));
  440. // Add_Name(px509Name,NID_initials,(char *)pSubJect->I,strlen((char *)pSubJect->I));
  441. // Add_Name(px509Name,NID_name,(char *)pSubJect->NAME,strlen((char *)pSubJect->NAME));
  442. Add_Name(px509Name,NID_surname,V_ASN1_UTF8STRING,(char *)pSubJect->S,strlen((char *)pSubJect->S));
  443. // Add_Name(px509Name,NID_dnQualifier,(char *)pSubJect->QUAL,strlen((char *)pSubJect->QUAL));
  444. // Add_Name(px509Name,NID_pkcs9_unstructuredName,(char *)pSubJect->STN,strlen((char *)pSubJect->STN));
  445. // Add_Name(px509Name,NID_pkcs9_challengePassword,(char *)pSubJect->PW,strlen((char *)pSubJect->PW));
  446. // Add_Name(px509Name,NID_pkcs9_unstructuredAddress,(char *)pSubJect->ADD,strlen((char *)pSubJect->ADD));
  447. Add_Name(px509Name,NID_streetAddress,V_ASN1_UTF8STRING,(char *)pSubJect->CN,strlen((char *)pSubJect->CN));
  448. Add_Name(px509Name,NID_postalCode,V_ASN1_UTF8STRING,(char *)pSubJect->CN,strlen((char *)pSubJect->CN));
  449. Add_Name(px509Name,NID_homePostalAddress,V_ASN1_UTF8STRING,(char *)pSubJect->CN,strlen((char *)pSubJect->CN));
  450. Add_Name(px509Name,"2.5.4.20",V_ASN1_UTF8STRING,(char *)pSubJect->CN,strlen((char *)pSubJect->CN));
  451. */
  452. }
  453. //BOOL MakeRootPub(stuSUBJECT * rootInfo,/*信息*/ char * certMem/*证书文件*/,int * certLen,char * outMsg/*操作结果*/)
  454. /*{
  455. //所以证书预览序号0,位数384,有限期1,格式DER
  456. BIO * memcert = NULL;//输出证书公私钥
  457. BUF_MEM *bptrcert = NULL;
  458. X509 *x509=NULL;
  459. EVP_PKEY *pkey=NULL;
  460. memcert= BIO_new(BIO_s_mem());
  461. BOOL bRet = FALSE;
  462. if(mkRoot(rootInfo,&x509,&pkey,384,1,1,outMsg))
  463. {
  464. if(i2d_X509_bio(memcert,x509))//returns 1 for success  写入公钥
  465. {
  466. BIO_get_mem_ptr(memcert, &bptrcert);
  467. *certLen=bptrcert->length;
  468. memcpy(certMem,bptrcert->data,*certLen);
  469. bRet = TRUE;
  470. goto end;
  471. }
  472. else
  473. {
  474. strcpy(outMsg,"存储证书发生异常");
  475. }
  476. }
  477. end:
  478. BIO_free_all(memcert);
  479. memcert = NULL;
  480. EVP_PKEY_free(pkey);
  481. pkey = NULL;
  482. X509_free(x509);
  483. x509 = NULL;
  484. EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
  485. CRYPTO_cleanup_all_ex_data();
  486. return bRet;
  487. }*/
  488. /*将BIO转换未内存,和长度*/
  489. BOOL Bio2Mem(BIO * memBio/*[IN]*/,char * lpszMem/*[OUT]*/,
  490.  UINT * memLen/*[IN,OUT],输入为mem长度,输出为实际长度*/)
  491. {
  492. if(memBio == NULL || memLen == NULL || (*memLen !=0 && lpszMem == NULL))
  493. return FALSE;
  494. //if(BIO_method_type(memBio))//判断是否内存类型BIO
  495. UINT uCopy = 0;//拷贝实际长度
  496. BUF_MEM * bptrBio = NULL;
  497. BIO_get_mem_ptr(memBio, &bptrBio);
  498. (*memLen >(UINT)bptrBio->length)?(uCopy = bptrBio->length):(uCopy = *memLen);
  499. memcpy(lpszMem,bptrBio->data,uCopy);//拷贝输入长度,输入为0时候,测定长度
  500. *memLen = bptrBio->length;//返回实际长度
  501. return TRUE;
  502. }
  503. /*X509转换为Mem*/
  504. BOOL X5092Mem(X509 * px509/*[IN]*/,const int iType/*[in]类型pem-der*/,
  505.   char * x509Mem/*[OUT]*/,UINT * x509Len/*[OUT]*/)
  506. {
  507. if(px509 == NULL || x509Len == NULL)
  508. return FALSE;
  509. BIO * memcert = NULL;
  510. memcert = BIO_new(BIO_s_mem());
  511. BIO_set_close(memcert, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */
  512. BOOL ret = FALSE;
  513. if (iType == DER)
  514. {
  515. ret = i2d_X509_bio(memcert,px509);//returns 1 for success
  516. }
  517. else if(iType == PEM)
  518. {
  519. ret = PEM_write_bio_X509(memcert,px509);
  520. }
  521. else
  522. {
  523. // strcpy(outMsg,"指定证书格式错误");
  524. // ret = 0;
  525. goto err;
  526. }
  527. if(ret)
  528. {
  529.  ret = Bio2Mem(memcert,x509Mem,x509Len);
  530. }
  531. err:
  532. BIO_free_all(memcert);
  533. return ret;
  534. }
  535. /*EVP_PKEY转换为BIO*/
  536. BOOL Key2Mem(EVP_PKEY * pkey/*[IN]*/,const int iType/*[in]类型pem-der*/,
  537.  const char * priPwd/*[in]私钥密码*/,
  538.  char * keyMem/*[OUT]*/,UINT * keyLen/*[OUT]*/)
  539. {
  540. if(pkey == NULL || keyLen == NULL)
  541. return FALSE;
  542. BIO * memkey = NULL;
  543. BIO * bEnc = NULL;
  544. memkey = BIO_new(BIO_s_mem());
  545. BIO_set_close(memkey, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */
  546. BOOL ret = FALSE;
  547. if (iType==DER)
  548. {
  549. if(NULL == priPwd || strlen(priPwd) == 0) //写入私钥
  550. ret=i2d_PrivateKey_bio(memkey,pkey);//私钥未加密
  551. else
  552. {
  553. //添加加密链
  554. unsigned char key[EVP_MAX_KEY_LENGTH]="";//算法最长的KEY长度
  555. unsigned char iv[EVP_MAX_IV_LENGTH]="";//算法最长的IV长度
  556. bEnc = BIO_new(BIO_f_cipher());
  557. const EVP_CIPHER * cipher = NULL;
  558. cipher = EVP_des_ede3_cbc(); // 3DES-EDE-CBC 
  559. if(EVP_BytesToKey(cipher,EVP_sha1(),NULL,(unsigned char *)priPwd,
  560. strlen(priPwd),1,key,iv))
  561. {
  562. BIO_set_cipher(bEnc,cipher,key,iv, 1);//1-加密、0-解密
  563. memkey = BIO_push(bEnc, memkey); 
  564. ret = i2d_PrivateKey_bio(memkey,pkey);//私钥加密
  565. BIO_flush(memkey);
  566. memkey = BIO_pop(memkey);
  567. BIO_free(bEnc);
  568. }
  569. else
  570. {
  571. ret = FALSE;
  572. }
  573. }
  574. }
  575. else if(iType == PEM)
  576. {
  577. if(NULL == priPwd || strlen(priPwd) == 0)
  578. ret = PEM_write_bio_PrivateKey(memkey,pkey,NULL,NULL,0,NULL, NULL); //私钥不加密
  579. else
  580. ret = PEM_write_bio_PrivateKey(memkey,pkey,EVP_des_ede3_cbc(),NULL,0,NULL, (void *)priPwd); //私钥加密
  581. }
  582. else
  583. {
  584. ret = 0;
  585. goto err;
  586. }
  587. if(ret)
  588. {
  589.  ret = Bio2Mem(memkey,keyMem,keyLen);
  590. }
  591. err:
  592. BIO_free_all(memkey);
  593. return ret;
  594. }
  595. /*将stuCertPair结构转换为X509,EVP_PKEY,并验证密钥对*/
  596. BOOL CertPair2XE(const stuCertPair & RootPair/*[IN]*/,X509 *& pCert, EVP_PKEY *& pKey ,char * outMsg)
  597. {
  598. pCert = NULL;
  599. pKey = NULL;
  600. //检测stuCertPair结构合法性
  601. //检测公钥
  602. if(RootPair.memCert == NULL || strlen(RootPair.memCert) == 0 )//没有公钥信息
  603. {
  604. sprintf(outMsg,"结构中缺少公钥信息");
  605. return FALSE;
  606. }
  607. else if(RootPair.lenCert > MAX_CERT_LEN)//检测公钥长度,限定为8192
  608. {
  609. sprintf(outMsg,"公钥长度超过系统限制");
  610. return FALSE;
  611. }
  612. //检测私钥
  613. else if(RootPair.memKey == NULL || strlen(RootPair.memKey)==0 )//没有私钥信息
  614. {
  615. sprintf(outMsg,"结构中缺少私钥信息");
  616. return FALSE;
  617. }
  618. else if(RootPair.lenKey > MAX_KEY_LEN)//检测私钥长度,限定为4096
  619. {
  620. sprintf(outMsg,"私钥长度超过系统限制");
  621. return FALSE;
  622. }
  623. if(RootPair.pwdKey != NULL && strlen(RootPair.pwdKey))//私钥代密码
  624. {
  625. // OpenSSL_add_all_algorithms();
  626. }
  627. pKey = LoadKey(RootPair.memKey,RootPair.lenKey,RootPair.pwdKey,outMsg);
  628. if (pKey == NULL)
  629. {
  630. // EVP_cleanup();
  631. // CRYPTO_cleanup_all_ex_data();
  632. return FALSE;
  633. }
  634. pCert = LoadCert(RootPair.memCert,RootPair.lenCert,RootPair.pwdKey,outMsg);
  635. if (pCert == NULL)
  636. {
  637. // EVP_cleanup();
  638. // CRYPTO_cleanup_all_ex_data();
  639. return FALSE;
  640. }
  641. if (!X509_check_private_key(pCert,pKey))
  642. {
  643. sprintf(outMsg,"公私钥对不匹配");
  644. // EVP_cleanup();
  645. // CRYPTO_cleanup_all_ex_data();
  646. return FALSE;
  647. }
  648. return TRUE;
  649. }
  650. //在内存中创建PFX
  651. BOOL CreateMemPfx(X509 * pCert, EVP_PKEY * key, const  char * p12Pwd, const char * friendlyName,
  652.   char * memP12/*OUT*/, UINT * p12Len/*OUT*/) //
  653. {
  654.   BIO * memBio = NULL;
  655. BUF_MEM * bptrP12 = NULL;
  656.   memBio = BIO_new(BIO_s_mem());
  657. OpenSSL_add_all_algorithms();
  658. PKCS12 * p12 = PKCS12_create((char *)p12Pwd,(char *)friendlyName, key, pCert, NULL, 0,0,0,0,0);
  659. if(!p12)
  660. {
  661. BIO_free_all(memBio);
  662. return FALSE;
  663. }
  664. i2d_PKCS12_bio(memBio, p12);
  665. BIO_get_mem_ptr(memBio, &bptrP12);
  666. *p12Len = bptrP12->length;
  667. memcpy(memP12,bptrP12->data,*p12Len);
  668. PKCS12_free(p12);
  669. BIO_free_all(memBio);
  670. // EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
  671. // CRYPTO_cleanup_all_ex_data();
  672. return TRUE;
  673. }
  674. BOOL mkRoot(const stuSUBJECT * rootInfo,
  675. X509 ** x509p/*out公钥*/, 
  676. EVP_PKEY ** pkeyp/*out私钥*/, 
  677.     int bits/*位数*/, 
  678. const long serial/*序列号*/, 
  679. const int days/*有效期*/,
  680. const char * kusage,
  681. const char * ekusage,
  682. const stuCERTEXT * pCertExt,/*扩展*/
  683. char * outMsg/*操作结果*/)
  684. {
  685. if(bits < 384)
  686. bits = 384;
  687. X509 * x = NULL;
  688. EVP_PKEY * pk = NULL;
  689. RSA * rsa = NULL;
  690. X509_NAME * name = NULL;
  691. int i = 0,
  692. len = 0;
  693. char altname[255] = {0};
  694. if ((pkeyp == NULL) || (*pkeyp == NULL))
  695. {
  696. if ((pk = EVP_PKEY_new()) == NULL)
  697. {
  698. abort(); 
  699. return FALSE;
  700. }
  701. }
  702. else
  703. pk= *pkeyp;
  704. if ((x509p == NULL) || (*x509p == NULL))
  705. {
  706. if ((x=X509_new()) == NULL)
  707. goto err;
  708. }
  709. else
  710. x= *x509p;
  711. Rand(NULL,1,outMsg);//产生随机数种子
  712. rsa = RSA_generate_key(bits,RSA_F4,0/*回调函数callback*/,NULL);//产生密钥对,//RSA存储了公钥私钥
  713. if (!EVP_PKEY_assign_RSA(pk,rsa))//完成RSA密钥的pkey结构初始工作,当pk不为NULL的时候,返回1,否则返回0
  714. {
  715. abort();
  716. goto err;
  717. }
  718. rsa = NULL;
  719. X509_set_version(x,2);//版本号,显示+1
  720. ASN1_INTEGER_set(X509_get_serialNumber(x),serial);//序列号
  721. X509_gmtime_adj(X509_get_notBefore(x),0);//起始时间
  722. X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);//结束时间
  723. X509_set_pubkey(x,pk);//公钥
  724. name = X509_get_subject_name(x);
  725. /* This function creates and adds the entry, working out the
  726. * correct string type and performing checks on its length.
  727. * Normally we'd check the return value for errors...
  728. */
  729. //C-国家,ST-省,L-城市,O-组织,OU-部门,CN-个体,T-title,D-description,G-givenName,I-initials,
  730. //Email-emailAddress,S-surname,SN-serialNumber,dnQualifier-dnQualifier,unstructuredName,challengePassword,unstructuredAddress,
  731. AddName(name,rootInfo);
  732. /* Its self signed so set the issuer name to be the same as the
  733. * subject.
  734. */
  735. X509_set_issuer_name(x,name);//设置发行者名称等同于上面的
  736. if(kusage && strlen(kusage))
  737. Add_ExtCert(x,x, NID_key_usage, kusage);
  738. AddExtCert(x,x,pCertExt);//扩展
  739. if(ekusage && strlen(ekusage))
  740. Add_ExtCert(x,x,NID_ext_key_usage,ekusage);
  741. X509V3_EXT_cleanup();//cleanup the extension code if any custom extensions have been added
  742. OBJ_cleanup();
  743. if (!X509_sign(x,pk,EVP_sha1()))//签名算法EVP_sha1,EVP_md5,用私钥签名公钥
  744. {
  745. strcpy(outMsg,"证书签名失败");
  746. goto err;
  747. }
  748. *x509p = x;
  749. *pkeyp = pk;
  750. return TRUE;
  751. err:
  752. return FALSE;
  753. }
  754. /*输出标志,如果输出某项(certMem,或certLen == NULL),则不输出本项*/
  755. BOOL MakeRoot(const stuSUBJECT * rootInfo,/*[in]信息*/
  756.   const char * friendlyName/*好记的名称*/,
  757.   const int bits/*[in]位数*/, 
  758.   const long serial/*[in]序列号*/, 
  759.   const int days/*[in]有效期*/,
  760.   const char * priPwd/*[in]私钥密码*/,
  761.   const char * cKusage,/*密钥用法*/
  762.   const char * cEkusage,/*扩展密钥用法*/
  763.   const stuCERTEXT * pCertExt,/*证书扩展*/
  764.   char * certMem/*[OUT]证书*/,
  765.   UINT * certLen/*[OUT]*/,
  766.   char * keyMem/*[OUT]私钥*/,
  767.   UINT * keyLen/*[OUT]*/,
  768.   char * p12Mem/*[OUT]pkcs#12*/,
  769.   UINT * p12Len/*[OUT]*/,
  770.   char * outMsg,/*操作结果*/
  771.   const int iType/*[in]类型pem-der*/)
  772. {
  773. X509 * px509 = NULL;
  774. EVP_PKEY * pkey = NULL;
  775. BIO * memcert = NULL,
  776. * memkey = NULL;
  777. memcert = BIO_new(BIO_s_mem());
  778. memkey = BIO_new(BIO_s_mem());
  779. BIO_set_close(memcert, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */
  780. BIO_set_close(memkey, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */
  781. BOOL ret = TRUE;
  782. int i = 0,
  783. j = 0;
  784. if(mkRoot(rootInfo,&px509,&pkey,bits,serial,days,cKusage,
  785.   cEkusage,pCertExt,outMsg))
  786. {
  787. X5092Mem(px509,iType,certMem,certLen);
  788. Key2Mem(pkey,iType,priPwd,keyMem,keyLen);
  789. CreateMemPfx(px509, pkey, priPwd, friendlyName, p12Mem, p12Len);
  790. else
  791. ret = FALSE;
  792. BIO_free_all(memcert);
  793. BIO_free_all(memkey);
  794. X509_free(px509);
  795. EVP_PKEY_free(pkey);
  796. return ret;
  797. }
  798. ///////////////////////// end ////////////////////////////////////////
  799. //////////////////////////////////////////////////////////////////////
  800. ///////////////////////// begin //////////////////////////////////////
  801. /* Add extension using V3 code: we can set the config file as NULL
  802.  * because we wont reference any other sections.
  803.  */
  804. int Add_ExtReq(STACK_OF(X509_REQUEST) *sk,const int iNid,const char *lpszValue)
  805. {
  806. X509_EXTENSION *ex;
  807. ex = X509V3_EXT_conf_nid(NULL, NULL, iNid, (char *)lpszValue);
  808. if (!ex)
  809. return 0;
  810. sk_X509_EXTENSION_push(sk, ex);
  811. return 1;
  812. }
  813. int mkReq(const stuSUBJECT * reqInfo,X509_REQ **req,
  814.   EVP_PKEY **pkeyp, int bits,char * outMsg)
  815. {
  816. if(bits < 384)
  817. bits = 384;
  818. X509_REQ *x = NULL;
  819. EVP_PKEY *pk = NULL;
  820. RSA *rsa = NULL;
  821. X509_NAME * name=NULL;
  822. ASN1_STRING stmp, 
  823. *str = &stmp;
  824. char altname[255] = {0};
  825. STACK_OF(X509_EXTENSION) *exts = NULL;
  826. if ((pk=EVP_PKEY_new()) == NULL)
  827. goto err;
  828. if ((x=X509_REQ_new()) == NULL)
  829. goto err;
  830. Rand(NULL,1,outMsg);//产生随机数种子
  831. rsa=RSA_generate_key(bits,RSA_F4,0/*回调函数callback*/,NULL);//产生密钥对
  832. //PEM_write_bio_RSAPrivateKey
  833. if (!EVP_PKEY_assign_RSA(pk,rsa))
  834. goto err;
  835. rsa=NULL;
  836. X509_REQ_set_pubkey(x,pk);
  837. name=X509_REQ_get_subject_name(x);
  838. /* This function creates and adds the entry, working out the
  839. * correct string type and performing checks on its length.
  840. * Normally we'd check the return value for errors...
  841. */
  842. AddName(name,reqInfo);
  843. /* Certificate requests can contain extensions, which can be used
  844. * to indicate the extensions the requestor would like added to 
  845. * their certificate. CAs might ignore them however or even choke
  846. * if they are present.
  847. */
  848. /* For request extensions they are all packed in a single attribute.
  849. * We save them in a STACK and add them all at once later...
  850. */
  851. exts = sk_X509_EXTENSION_new_null();
  852. /* Standard extenions */
  853. //主题备用名称,URL:http://my.url.here/、支持email  copy
  854. // sprintf(altname,"email:%s",(char *)reqInfo->MAIL);
  855. // Add_ExtReq(exts, NID_subject_alt_name, altname);
  856. //加入自定义扩展
  857. // int nid;
  858. // nid = OBJ_create("1.3.6.1.4.1.5315.100.2.5", "UserID", "User ID Number");
  859. // X509V3_EXT_add_alias(nid, NID_netscape_comment);
  860. // Add_ExtReq(exts, nid, "ID130203197703060618");
  861. /* Now we've created the extensions we add them to the request */
  862. X509_REQ_add_extensions(x, exts);
  863. sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
  864. X509V3_EXT_cleanup();//cleanup the extension code if any custom extensions have been added
  865. OBJ_cleanup();
  866. if (!X509_REQ_sign(x,pk,EVP_sha1()))//用自己的公钥签名私钥
  867. goto err;
  868. *req=x;
  869. *pkeyp=pk;
  870. return(1);
  871. err:
  872. return(0);
  873. }
  874. BOOL MakeReq(const stuSUBJECT * reqInfo,/*请求信息IN*/
  875.  const int bits/*位数IN*/,
  876.  const char * priPwd/*私钥密码,IN*/,
  877.  char * reqMem/*证书请求文件OUT*/,
  878.  UINT * reqLen/*证书请求文件长度OUT*/,
  879.  char * priMem/*私钥文件OUT*/,
  880.  UINT * priLen/*私钥文件文件长度OUT*/,
  881.  char * outMsg/*操作结果OUT*/,
  882.  const int iType/*类型pem-der*/)
  883. {
  884. X509_REQ * req=NULL;
  885. EVP_PKEY * pkey=NULL;
  886. BIO * breq = NULL,
  887. * bkey = NULL;
  888. int i = 0,
  889. j = 0;
  890. breq = BIO_new(BIO_s_mem());
  891. bkey = BIO_new(BIO_s_mem());
  892. BIO_set_close(breq, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */
  893. BIO_set_close(bkey, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */
  894. /* if(((breq = BIO_new_file(reqFile, "w"))== NULL)||((bkey = BIO_new_file(priFile, "w")) == NULL))
  895. {
  896. strcpy(outMsg,"Create File Error");
  897. return FALSE;
  898. }
  899. */
  900. if(!mkReq(reqInfo,&req,&pkey,bits,outMsg))
  901. {
  902. strcpy(outMsg,"Make CertReq Error");
  903. return FALSE;
  904. }
  905. if(iType == PEM)
  906. {
  907. i = PEM_write_bio_X509_REQ(breq,req); //写入公钥
  908. if(NULL == priPwd || strlen(priPwd) == 0)
  909. j = PEM_write_bio_PrivateKey(bkey,pkey,NULL,NULL,0,NULL, NULL); //私钥不加密
  910. else
  911. j = PEM_write_bio_PrivateKey(bkey,pkey,EVP_des_ede3_cbc(),NULL,0,NULL, (void *)priPwd); //私钥加密
  912. }
  913. else if(iType == DER)
  914. {
  915. i = i2d_X509_REQ_bio(breq,req); //写入公钥
  916. if(NULL == priPwd || strlen(priPwd) == 0) //写入私钥
  917. j = i2d_PrivateKey_bio(bkey,pkey);//私钥未加密
  918. else
  919. {
  920. //添加加密链
  921. unsigned char key[EVP_MAX_KEY_LENGTH] = "";//算法最长的KEY长度
  922. unsigned char iv[EVP_MAX_IV_LENGTH] = "";//算法最长的IV长度
  923. BIO * bEnc = NULL;
  924. bEnc = BIO_new(BIO_f_cipher());
  925. const EVP_CIPHER * cipher = NULL;
  926. cipher = EVP_des_ede3_cbc(); // 3DES-EDE-CBC 
  927. if(EVP_BytesToKey(cipher,EVP_sha1(),NULL,(unsigned char *)priPwd,
  928. strlen(priPwd),1,key,iv))
  929. {
  930. BIO_set_cipher(bEnc,cipher,key,iv, 1);//1-加密、0-解密
  931. bkey = BIO_push(bEnc, bkey); 
  932. j = i2d_PrivateKey_bio(bkey,pkey);//私钥加密
  933. BIO_flush(bkey);
  934. bkey = BIO_pop(bkey);
  935. BIO_free(bEnc);
  936. }
  937. else
  938. strcpy(outMsg,"初始化key or iv 失败,");
  939. }
  940. }
  941. //转换BIO->MEM
  942. if(i&&j)
  943. {
  944. i = Bio2Mem(breq, reqMem, reqLen);
  945. j = Bio2Mem(bkey, priMem, priLen);
  946. }
  947. BIO_free(breq);
  948. BIO_free_all(bkey);
  949. X509_REQ_free(req);
  950. EVP_PKEY_free(pkey);
  951. if(!i||!j)
  952. {
  953. strcat(outMsg,"Save Cert or Key File Error");
  954. return FALSE;
  955. }
  956. return TRUE;
  957. }
  958. ////////////////////////// end //////////////////////////////////////
  959. ////////////////////////////////////////////////////////////////////
  960. /////////////////////////// begin ////////////////////////////////////////
  961. int copy_extensions(X509 *x, X509_REQ *req, const int copy_type)//在证书中加入req自带扩展信息
  962. {
  963. STACK_OF(X509_EXTENSION) * exts = NULL;
  964. X509_EXTENSION * ext = NULL,
  965.            * tmpext = NULL;
  966. ASN1_OBJECT * obj = NULL;
  967. int i = 0,
  968. idx = 0,
  969. ret = 0;
  970. if (!x || !req || (copy_type == EXT_COPY_NONE))
  971. return 1;
  972. exts = X509_REQ_get_extensions(req);
  973. for(i = 0; i < sk_X509_EXTENSION_num(exts); i++)
  974. {
  975. ext = sk_X509_EXTENSION_value(exts, i);
  976. obj = X509_EXTENSION_get_object(ext);
  977. idx = X509_get_ext_by_OBJ(x, obj, -1);
  978. /* Does extension exist? */
  979. if (idx != -1) 
  980. {
  981. /* If normal copy don't override existing extension */
  982. if (copy_type == EXT_COPY_ADD)
  983. continue;
  984. /* Delete all extensions of same type */
  985. do
  986. {
  987. tmpext = X509_get_ext(x, idx);
  988. X509_delete_ext(x, idx);
  989. X509_EXTENSION_free(tmpext);
  990. idx = X509_get_ext_by_OBJ(x, obj, -1);
  991. } while (idx != -1);
  992. }
  993. if (!X509_add_ext(x, ext, -1))
  994. goto end;
  995. }
  996. ret = 1;
  997. end:
  998. sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
  999. return ret;
  1000. }
  1001. int do_body(X509 **xret, EVP_PKEY *pkey, X509 *px509, 
  1002. const EVP_MD *dgst,const long serial,
  1003. const char *startdate, const char *enddate,
  1004. const int days,X509_REQ * req,const char * kusage,
  1005. const char * ekusage,const stuCERTEXT * pCertExt,char * outMsg)
  1006. {
  1007. X509_NAME * name = NULL, * CAname = NULL;
  1008. X509 * ret = NULL;
  1009. X509_CINF * ci = NULL;
  1010. EVP_PKEY * pktmp = NULL;
  1011. int ok= -1,
  1012. i=0;
  1013. // STACK_OF (X509_EXTENSION) * req_exts;//如何释放??
  1014. name = X509_REQ_get_subject_name(req);
  1015. if ((ret = X509_new()) == NULL) 
  1016. {
  1017. ok=0;
  1018. goto err;
  1019. }
  1020. ci = ret->cert_info;
  1021. /* Make it an X509 v3 certificate. 版本1扩展*/
  1022. if (!X509_set_version(ret,2L)) //版本
  1023. {
  1024. ok=0;
  1025. goto err;
  1026. }
  1027. ASN1_INTEGER_set(X509_get_serialNumber(ret),serial);//序列号
  1028. if (!X509_set_issuer_name(ret,X509_get_subject_name(px509)))//发行者
  1029. {
  1030. ok=0;
  1031. goto err;
  1032. }
  1033. //X509_gmtime_adj(X509_get_notBefore(x),0);//起始时间
  1034. //X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);//结束时间
  1035. if (strcmp(startdate,"today") == 0)
  1036. X509_gmtime_adj(X509_get_notBefore(ret),0);//开始日期
  1037. else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),(char *)startdate);
  1038. if (enddate == NULL)
  1039. X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);//结束日期
  1040. else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),(char *)enddate);
  1041. // X509_gmtime_adj(X509_get_notBefore(ret),0);//起始时间
  1042. // X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);//结束时间
  1043. if (!X509_set_subject_name(ret,name)) //主体 ---所有者
  1044. {
  1045. ok=0;
  1046. goto err;
  1047. }
  1048. pktmp = X509_REQ_get_pubkey(req);
  1049. i = X509_set_pubkey(ret,pktmp);//公钥
  1050. EVP_PKEY_free(pktmp);
  1051. if (!i) 
  1052. {
  1053. ok = 0;
  1054. goto err;
  1055. }
  1056. //加入req自带扩展信息,生成REQ文件时候加入的
  1057. if (!copy_extensions(ret, req, EXT_COPY_ALL))
  1058. {
  1059. strcpy("加入自带扩展信息失败",outMsg);
  1060. goto err;
  1061. }
  1062. //CRL签名、仅仅加密、仅仅解密
  1063. if(kusage && strlen(kusage))
  1064. Add_ExtCert(ret,ret, NID_key_usage, kusage);
  1065. AddExtCert(ret,px509,pCertExt);
  1066. if(ekusage && strlen(ekusage))
  1067. Add_ExtCert(ret,ret,NID_ext_key_usage,ekusage);
  1068. /*
  1069. Application keyUsage  Values 
  1070. SSL Client digitalSignature 
  1071. SSL Server keyEncipherment 
  1072. S/MIME Signing digitalSignature 
  1073. S/MIME Encryption keyEncipherment 
  1074. Certificate Signing keyCertSign 
  1075. Object Signing digitalSignature */
  1076. //加入自定义信息end
  1077. X509V3_EXT_cleanup();//cleanup the extension code if any custom extensions have been added
  1078. OBJ_cleanup();
  1079. if (!X509_sign(ret,pkey,dgst))//加入签名,签名算法
  1080. {
  1081. ok=0;
  1082. goto err;
  1083. }
  1084. ok=1;
  1085. err:
  1086. if (CAname != NULL)
  1087. X509_NAME_free(CAname);
  1088. if (ok <= 0)
  1089. {
  1090. if (ret != NULL) X509_free(ret);
  1091. ret=NULL;
  1092. }
  1093. else
  1094. * xret = ret;
  1095. return(ok);
  1096. }
  1097. int certify(X509 **xret, X509_REQ *req, EVP_PKEY *pkey, 
  1098. X509 *px509,const EVP_MD *dgst,
  1099. const long serial, const char *startdate, const char *enddate, 
  1100. const int days,const char * KUSAGE,
  1101. const char * EKUSAGE,const stuCERTEXT * pCertExt,char * outMsg)
  1102. {//返回公钥证书,请求文件,根私钥,根公钥,
  1103. EVP_PKEY *pktmp=NULL;
  1104. int ok= -1,i=0;
  1105. if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)//得到公钥
  1106. {
  1107. sprintf(outMsg,"error unpacking public keyn");
  1108. ok=0;
  1109. goto err;
  1110. }
  1111. i=X509_REQ_verify(req,pktmp);//证书请求里面有私要签名,这里验证一下,看此公钥主人是否持有私钥
  1112. EVP_PKEY_free(pktmp);
  1113. if (i < 0)
  1114. {
  1115. ok=0;
  1116. sprintf(outMsg,"Signature verification problems....n");
  1117. goto err;
  1118. }
  1119. if (i == 0)
  1120. {
  1121. ok=0;
  1122. sprintf(outMsg,"Signature did not match the certificate requestn");
  1123. goto err;
  1124. }
  1125. ok=do_body(xret,pkey,px509,dgst,serial,startdate, enddate,
  1126. days,req,KUSAGE,EKUSAGE,pCertExt,outMsg);
  1127. err:
  1128. return(ok);
  1129. }
  1130. BOOL MakeCert(const stuCertPair & RootPair/*根证书对*/,
  1131.   const long serial/*序列号*/,
  1132.   const char *enddate/*作废日期*/,
  1133.   const int days/*有效期*/, 
  1134.   const char * reqMem/*请求文件或内存*/,
  1135.   const int reqLen/*请求的长度,0-标示文件*/,
  1136.   const char * KUSAGE/*密钥用法*/,
  1137.   const char * EKUSAGE/*增强密钥用法*/,
  1138.   const stuCERTEXT * pCertExt,/*证书扩展*/
  1139.   char * outMem/*结果公钥文件*/,
  1140.   UINT * MemLen/*结果长度*/,
  1141.   char * outMsg/*操作结果*/,
  1142.   const int type/*结果类型DER,PEM*/)//通过证书请求,得到证书
  1143. {
  1144. int ret=1;
  1145. char * md=NULL;
  1146. EVP_PKEY *pkey=NULL;
  1147. X509 * px509=NULL;
  1148. X509_REQ *req=NULL;
  1149. X509 * x=NULL;
  1150. BIO * bcert=NULL,* reqbio=NULL;
  1151. int j;
  1152. const EVP_MD *dgst=NULL;
  1153. OpenSSL_add_all_algorithms();//加入签名算法
  1154. X509 * x509 = NULL;
  1155. if(reqLen == 0)//输入为磁盘文件
  1156. {
  1157. if((reqbio=BIO_new_file(reqMem, "r")) == NULL)
  1158. {
  1159. strcpy(outMsg,"找不到证书请求文件");
  1160. ret=0;
  1161. goto err;
  1162. }
  1163. }
  1164. else//输入为内存中文件
  1165. {
  1166. if((reqbio = BIO_new_mem_buf((void *)reqMem, reqLen)) == NULL)//只读类型
  1167. {
  1168. sprintf(outMsg,"Make Mem Bio Error");
  1169. ret=0;
  1170. goto err;
  1171. }
  1172. }
  1173. if ((req=PEM_read_bio_X509_REQ(reqbio,NULL,NULL,NULL)) == NULL)//PEM_read_X509_REQ 
  1174. {
  1175. BIO_reset(reqbio);
  1176. if ((req=d2i_X509_REQ_bio(reqbio,NULL)) == NULL)
  1177. {
  1178. sprintf(outMsg,"Error get certificate request");
  1179. ret=0;
  1180. goto err;
  1181. }
  1182. }
  1183. if(!CertPair2XE(RootPair,px509,pkey,outMsg))
  1184. {
  1185. ret = 0;
  1186. goto err;
  1187. }
  1188. md="sha1";//////////!!!!!!!!!!!!!!!!!////////////////////////////
  1189. if ((dgst=EVP_get_digestbyname(md)) == NULL)//return an EVP_MD structure when passed a digest name
  1190. {
  1191. sprintf(outMsg,"%s is an unsupported message digest typen",md);
  1192. ret = 0;
  1193. goto err;
  1194. }
  1195. j=certify(&x,req,pkey,px509,dgst,//公钥证书out,请求文件,根私钥,根公钥,
  1196. serial,"today",enddate,days,KUSAGE,EKUSAGE,pCertExt,outMsg);
  1197. if (j <= 0) 
  1198. {
  1199. ret=0;
  1200. goto err;
  1201. }
  1202. bcert = BIO_new(BIO_s_mem());
  1203. BIO_set_close(bcert, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */
  1204. if (type==DER)
  1205. {
  1206. ret = i2d_X509_bio(bcert,x); 
  1207. }
  1208. else if(type==PEM)
  1209. {
  1210. ret = PEM_write_bio_X509(bcert,x);
  1211. }
  1212. //转换BIO->内存
  1213. if(ret)
  1214. {
  1215. ret = Bio2Mem(bcert, outMem, MemLen);
  1216. }
  1217. err:
  1218. if (reqbio != NULL) BIO_free(reqbio);
  1219. BIO_free_all(bcert);
  1220. EVP_PKEY_free(pkey);
  1221. X509_free(px509);
  1222. X509_free(x);
  1223. if (req != NULL) X509_REQ_free(req);
  1224. // EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
  1225. // CRYPTO_cleanup_all_ex_data();
  1226. return ret;
  1227. }
  1228. ///////////////////////// end ////////////////////////////////////////
  1229. BOOL DirectCert(const stuCertPair & RootPair/*根证书对*/,
  1230. const int bits/*[IN]*/,
  1231. const long serial/*[IN]序列号*/,
  1232. const char * enddate/*[IN]作废日期*/,
  1233. const int days/*[IN]有效期*/,
  1234. const char * priPwd /*私钥加密密码,IN*/,
  1235. const stuSUBJECT * sSUBJECT/*[IN]用户信息*/,
  1236. const char * friendlyName/*好记的名称*/,
  1237. const char * keyUsage/*密钥用法*/,
  1238. const char * ekeyUsage/*扩展密钥用法*/,
  1239. const stuCERTEXT * pCertExt,/*证书扩展结构*/
  1240. char * pCert/*[OUT]输出证书公钥*/,
  1241. UINT * certl/*[OUT]长度*/,
  1242. char * key/*[OUT]输出证书私钥*/,
  1243. UINT * keyl/*[OUT]长度*/,
  1244. char * p12/*[OUT]输出证书私钥*/,
  1245. UINT * p12l/*[OUT]长度*/,
  1246. char * outMsg/*[OUT]返回错误信息*/,
  1247. const int iType/*结果类型DER,PEM*/)
  1248. {
  1249. X509_REQ * req=NULL;
  1250. EVP_PKEY * pkey=NULL, * prkey=NULL;//证书私钥,//根私钥
  1251. X509 * px509=NULL,* x=NULL;//根公钥,证书公钥
  1252. int ret=1;
  1253. char * md=NULL;
  1254. int i=0,j=0,ok=0;
  1255. const EVP_MD *dgst=NULL;
  1256. OpenSSL_add_all_algorithms();//加入签名算法
  1257. if(!CertPair2XE(RootPair,px509,prkey,outMsg))
  1258. {
  1259. ret = 0;
  1260. goto err;
  1261. }
  1262. if(!mkReq(sSUBJECT,&req,&pkey, bits,outMsg))
  1263. {
  1264. sprintf(outMsg,"Make CertReq error");
  1265. ret = 0;
  1266. goto err;
  1267. }
  1268. md = "sha1";//////////!!!!!!!!!!!!!!!!!////////////////////////////
  1269. if ((dgst = EVP_get_digestbyname(md)) == NULL)//return an EVP_MD structure when passed a digest name
  1270. {
  1271. sprintf(outMsg,"%s is an unsupported message digest typen",md);
  1272. ret = 0;
  1273. goto err;
  1274. }
  1275. ok = certify(&x,req,prkey,px509,dgst,//公钥证书out,请求,根私钥,根公钥,
  1276. serial,"today",enddate,days,keyUsage,ekeyUsage,pCertExt,outMsg);
  1277. if (ok > 0) 
  1278. {
  1279. X5092Mem(x,iType,pCert,certl);
  1280. Key2Mem(pkey,iType,priPwd,key,keyl);
  1281. CreateMemPfx(x, pkey, priPwd, friendlyName, p12, p12l);
  1282. }
  1283. err:
  1284. EVP_PKEY_free(pkey);
  1285. EVP_PKEY_free(prkey);
  1286. X509_free(px509);
  1287. X509_free(x);
  1288. if (req != NULL) X509_REQ_free(req);
  1289. // EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
  1290. // CRYPTO_cleanup_all_ex_data();
  1291. return ret;
  1292. }
  1293. //////////////////////////////////////////////////////////////////////
  1294. ///////////////////////// begin //////////////////////////////////////
  1295. int Add_ExtCrl(X509_CRL *crl/*正被添加的证书*/,X509 * pRoot/*根证书(从中得到信息)*/, 
  1296.    const int iNid, const char *lpszValue)
  1297. {
  1298. X509V3_CTX ctx;
  1299. X509_EXTENSION *ex;
  1300. /* This sets the 'context' of the extensions. */
  1301. /* No configuration database */
  1302. // X509V3_set_ctx_nodb(&ctx);
  1303.     X509V3_set_ctx(&ctx, pRoot, NULL, NULL, crl, 0);
  1304. // issuerAltName  authorityKeyIdentifier
  1305. ex = X509V3_EXT_conf_nid(NULL, &ctx, iNid, (char *)lpszValue);
  1306. if (!ex)
  1307. return 0;
  1308. X509_CRL_add_ext(crl,ex,-1);
  1309. X509_EXTENSION_free(ex);
  1310. return 1;
  1311. }
  1312. BOOL MakeCrl(const stuCertPair & RootPair/*根证书对*/,
  1313.  const stuREVOKE * Head/*作废链表*/,
  1314.  const PNewCrlMem NewCrlMem/*回调函数*/,
  1315.  char *& outCrl,
  1316.  int * crll,
  1317.  char * outfile/*crl文件*/,
  1318.  char * outMsg/*操作结果*/)
  1319. {
  1320. X509_CRL_INFO *ci = NULL;
  1321. X509_CRL *crl = NULL;
  1322. int ret = 1,
  1323. i = 0;
  1324. char *key = NULL;
  1325. char *md = NULL;
  1326. EVP_PKEY *pkey = NULL;
  1327. X509 *px509 = NULL;
  1328. BIO *in = NULL,
  1329. *out = NULL;
  1330. const EVP_MD *dgst = NULL;
  1331. X509_REVOKED *r = NULL;
  1332. long crldays = 30;
  1333. long crlhours = 0;
  1334. // stuREVOKE * temp =NULL;
  1335. BIO * memcrl = NULL;
  1336. BUF_MEM *bptrcrl = NULL;
  1337. OpenSSL_add_all_algorithms();
  1338. if(!CertPair2XE(RootPair,px509,pkey,outMsg))
  1339. {
  1340. ret = 0;
  1341. goto err;
  1342. }
  1343. md="md5";//////////!!!!!!!!!!!!!!!!!////////////////////////////
  1344. if ((dgst=EVP_get_digestbyname(md)) == NULL)//return an EVP_MD structure when passed a digest name
  1345. {
  1346. sprintf(outMsg,"%s is an unsupported message digest typen",md);
  1347. ret = 0;
  1348. goto err;
  1349. }
  1350. if ((crl = X509_CRL_new()) == NULL)
  1351. {
  1352. ret = 0;
  1353. goto err;
  1354. }
  1355. ci = crl->crl;
  1356. X509_NAME_free(ci->issuer);
  1357. ci->issuer = X509_NAME_dup(px509->cert_info->subject);
  1358. if (ci->issuer == NULL)
  1359. {
  1360. ret = 0;
  1361. goto err;
  1362. }
  1363. X509_gmtime_adj(ci->lastUpdate,0);
  1364. if (ci->nextUpdate == NULL)
  1365. ci->nextUpdate=ASN1_UTCTIME_new();
  1366. X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);
  1367. if(!ci->revoked)
  1368. ci->revoked = sk_X509_REVOKED_new_null();
  1369. while(Head!=NULL)//遍历链表
  1370. {
  1371. X509_REVOKED *r = NULL;
  1372.         BIGNUM *serial_bn = NULL;
  1373.         r = X509_REVOKED_new();
  1374. ASN1_TIME_set(r->revocationDate,Head->time);//时间
  1375. char index[100];
  1376.         BN_hex2bn(&serial_bn,itoa(Head->Index,index,10));//序号  -  leak BN_free
  1377.         ASN1_INTEGER *tmpser = BN_to_ASN1_INTEGER(serial_bn, r->serialNumber);
  1378. BN_free(serial_bn);
  1379.         sk_X509_REVOKED_push(ci->revoked,r);
  1380. Head=Head->Link;
  1381. }
  1382. // sk_X509_REVOKED_sort(ci->revoked);
  1383. for (i=0; i<sk_X509_REVOKED_num(ci->revoked); i++)
  1384. {
  1385. r=sk_X509_REVOKED_value(ci->revoked,i);
  1386. r->sequence=i;
  1387. }
  1388.     if (ci->version == NULL)
  1389.     if ((ci->version=ASN1_INTEGER_new()) == NULL)
  1390. {
  1391. ret = 0;
  1392. goto err;
  1393. }
  1394.     ASN1_INTEGER_set(ci->version,1);
  1395. // issuerAltName  authorityKeyIdentifier
  1396. Add_ExtCrl(crl,px509,NID_subject_alt_name,"DNS:hpxs,email:hpxs@hotmail.com,RID:1.2.3.4,URI:https://hpxs,IP:192.168.0.22");
  1397. Add_ExtCrl(crl,px509,NID_issuer_alt_name, "DNS:hpxs,email:hpxs@hotmail.com,RID:1.2.3.4,URI:https://hpxs,IP:192.168.0.22");
  1398. Add_ExtCrl(crl,px509,NID_authority_key_identifier, "keyid,issuer:always");
  1399. if (!X509_CRL_sign(crl,pkey,dgst))
  1400. {
  1401. ret = 0;
  1402. goto err;
  1403. }
  1404. if(NewCrlMem)//输出内存
  1405. {
  1406. memcrl= BIO_new(BIO_s_mem());
  1407. BIO_set_close(memcrl, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */
  1408. PEM_write_bio_X509_CRL(memcrl,crl);
  1409. BIO_get_mem_ptr(memcrl, &bptrcrl);
  1410. *crll=bptrcrl->length;
  1411. outCrl=NewCrlMem(*crll);
  1412. memcpy(outCrl,bptrcrl->data,*crll);
  1413. }
  1414. if(outfile)//输出文件
  1415. {
  1416. out=BIO_new_file(outfile, "w");
  1417. if(out==NULL)
  1418. {
  1419. sprintf(outMsg,"%s is error",outfile);
  1420. ret = 0;
  1421. goto err;
  1422. }
  1423. PEM_write_bio_X509_CRL(out,crl);
  1424. }
  1425. X509V3_EXT_cleanup();//cleanup the extension code if any custom extensions have been added
  1426. OBJ_cleanup();
  1427. err:
  1428. if(out)
  1429. BIO_free_all(out);
  1430. if(memcrl)
  1431. BIO_free_all(memcrl);
  1432. if(in)
  1433. BIO_free(in);
  1434. if(pkey)
  1435. EVP_PKEY_free(pkey);
  1436. if(px509)
  1437. X509_free(px509);
  1438. if(crl)
  1439. X509_CRL_free(crl);
  1440. // EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
  1441. // CRYPTO_cleanup_all_ex_data();
  1442. if(ret==1)
  1443. strcpy(outMsg,"CRL制作成功");
  1444. return ret;
  1445. }
  1446. BOOL CertFormatConver(const char * buf/*文件内容或文件名称*/,
  1447.   const int len/*内存长度为0则buf为文件名*/,
  1448.   const char * pwd/*p12文件密码,或者解密私钥密码*/,
  1449.   char * pem/*输出内存*/,
  1450.   UINT * pOutLen,/*输入内存长度,输出实际输出的长度*/
  1451.   char * keyPwd,/*加密私钥密码,只在私钥时候起作用*/
  1452.   const int outformat,char * outMsg/*操作结果*/)
  1453. {
  1454. BOOL bRet = TRUE;
  1455. EVP_PKEY *key=NULL;
  1456. X509 *pCert=NULL;
  1457. BIO * biout=NULL;
  1458. int i=0;
  1459. //输出文件
  1460. if(pOutLen == 0) //表示输出为文件
  1461. {
  1462. if ((biout=BIO_new_file(pem, "w")) == NULL)
  1463. {
  1464. return FALSE;
  1465. }
  1466. }
  1467. //输出
  1468. else
  1469. {
  1470. biout = BIO_new(BIO_s_mem());
  1471. BIO_set_close(biout, BIO_CLOSE); 
  1472. }
  1473. pCert = LoadCert(buf,len,pwd,outMsg);//首先尝试公钥,pBioKey被改写
  1474. if(pCert)//输入文件为公钥文件
  1475. {
  1476. if  (outformat == DER)
  1477. i=i2d_X509_bio(biout,pCert);
  1478. else if (outformat == PEM)
  1479. {
  1480. // if (trustout) i=PEM_write_bio_X509_AUX(biout,x);
  1481. i=PEM_write_bio_X509(biout,pCert);
  1482. }
  1483. if(!i)//失败
  1484. strcpy(outMsg,"保存公钥失败");
  1485. else
  1486. strcpy(outMsg,"公钥证书格式转换成功");
  1487. }
  1488. else//输入文件为私钥文件
  1489. {
  1490. key=LoadKey(buf,len,pwd,outMsg);
  1491. if(!key) 
  1492. {
  1493. strcpy(outMsg,"不能识别的文件格式");
  1494. return FALSE;
  1495. }
  1496. if(outformat==PEM)
  1497. {
  1498. if(keyPwd == NULL || strlen(keyPwd) == 0)
  1499. PEM_write_bio_PrivateKey(biout, key, NULL, NULL, 0, 0, NULL); //私钥不加密
  1500. else
  1501. PEM_write_bio_PrivateKey(biout,key,EVP_des_ede3_cbc(),NULL,0,NULL, (void *)keyPwd); //私钥加密
  1502. }
  1503. if(outformat==DER)
  1504. {
  1505. if(NULL == keyPwd || strlen(keyPwd) == 0) //写入私钥
  1506. i2d_PrivateKey_bio(biout,key);//私钥未加密
  1507. else
  1508. {
  1509. //添加加密链
  1510. unsigned char keyl[EVP_MAX_KEY_LENGTH]="";//算法最长的KEY长度
  1511. unsigned char iv[EVP_MAX_IV_LENGTH]="";//算法最长的IV长度
  1512. BIO * bEnc = NULL;
  1513. if((bEnc = BIO_new(BIO_f_cipher())) != NULL)
  1514. {
  1515. const EVP_CIPHER * cipher = NULL;
  1516. cipher = EVP_des_ede3_cbc(); // 3DES-EDE-CBC 
  1517. if(EVP_BytesToKey(cipher,EVP_sha1(),NULL,(unsigned char *)keyPwd,
  1518. strlen(keyPwd),1,keyl,iv))
  1519. {
  1520. BIO_set_cipher(bEnc,cipher,keyl,iv, 1);//1-加密、0-解密
  1521. biout = BIO_push(bEnc, biout); 
  1522. i2d_PrivateKey_bio(biout,key);//私钥加密
  1523. BIO_flush(biout);
  1524. biout = BIO_pop(biout);
  1525. BIO_free(bEnc);
  1526. }
  1527. else
  1528. strcpy(outMsg,"初始化key or iv 失败,");
  1529. }
  1530. }
  1531. }
  1532. strcpy(outMsg,"私钥证书格式转换成功");
  1533. }
  1534. if(*pOutLen != 0) //表示输出为文件
  1535. {
  1536. Bio2Mem(biout, pem, pOutLen);
  1537. }
  1538. if (biout != NULL)
  1539. BIO_free_all(biout);
  1540. if(pCert)
  1541. X509_free(pCert);
  1542. if(key)
  1543. EVP_PKEY_free(key);
  1544. return TRUE;
  1545. }
  1546. //分解p12包
  1547. BOOL ParsePfx(const char * strP12/*包文件或内存*/,
  1548.   const UINT iP12Len/* 如果包为文件,则为0,否则为内存长度*/,
  1549.   const char * strPwdP12/*P12密码*/,
  1550.   const char * strCert/*公钥存放*/,
  1551.   const char * strkey/*私钥存放*/,
  1552.   const char * keyPwd/*私钥密码*/,
  1553.   const int outformat/*输出格式*/,
  1554.   char * outMsg/*返回结果*/)
  1555. {
  1556. BOOL bRet = TRUE;
  1557. EVP_PKEY * key = NULL;
  1558. X509 * pCert = NULL;
  1559. // STACK_OF(X509) *ca = NULL;
  1560. BIO * bio = NULL, 
  1561. * bioCert = NULL,
  1562. * bioKey = NULL;
  1563. PKCS12 * p12 = NULL;
  1564. int i = 0,
  1565. j = 0;
  1566. if(iP12Len == 0)//输入为磁盘文件
  1567. {
  1568. if((bio = BIO_new_file(strP12, "r")) == NULL)
  1569. {
  1570. strcpy(outMsg,"加载PFX文件错误");
  1571. bRet = FALSE;
  1572. goto err;
  1573. }
  1574. }
  1575. else//输入为内存中文件
  1576. {
  1577. if((bio = BIO_new_mem_buf((void *)strP12,iP12Len)) == NULL)//只读类型
  1578. {
  1579. sprintf(outMsg,"Make Mem Bio Error");
  1580. bRet = FALSE;
  1581. goto err;
  1582. }
  1583. }
  1584. OpenSSL_add_all_algorithms(); //不能去掉
  1585. p12 = d2i_PKCS12_bio(bio, NULL);
  1586. if (!PKCS12_parse(p12, strPwdP12, &key, &pCert/*PEM*/, /*&ca*/NULL)) 
  1587. {
  1588. strcpy(outMsg,"解析文件失败");
  1589. bRet = FALSE;
  1590. goto err;
  1591. }
  1592. //输出文件 - 可能不输出公钥
  1593. if (strCert != NULL && strlen(strCert) >0)
  1594. {
  1595. if((bioCert = BIO_new_file(strCert, "w")) == NULL)
  1596. {
  1597. bRet = FALSE;
  1598. goto err;
  1599. }
  1600. }
  1601. if (strkey!= NULL && strlen(strkey) >0 )
  1602. {
  1603. if((bioKey = BIO_new_file(strkey, "w")) == NULL)
  1604. {
  1605. bRet = FALSE;
  1606. goto err;
  1607. }
  1608. }
  1609. if(outformat == DER)
  1610. {
  1611. if(bioCert)
  1612. i = i2d_X509_bio(bioCert,pCert); //写入公钥
  1613. if(bioKey)
  1614. {
  1615. if(NULL == keyPwd || strlen(keyPwd) == 0) //写入私钥
  1616. i2d_PrivateKey_bio(bioKey,key);//私钥未加密
  1617. else
  1618. {
  1619. //添加加密链
  1620. unsigned char keyl[EVP_MAX_KEY_LENGTH]="";//算法最长的KEY长度
  1621. unsigned char iv[EVP_MAX_IV_LENGTH]="";//算法最长的IV长度
  1622. BIO * bEnc = NULL;
  1623. bEnc = BIO_new(BIO_f_cipher());
  1624. const EVP_CIPHER * cipher = NULL;
  1625. cipher = EVP_des_ede3_cbc(); // 3DES-EDE-CBC 
  1626. if(EVP_BytesToKey(cipher,EVP_sha1(),NULL,(unsigned char *)keyPwd,
  1627. strlen(keyPwd),1,keyl,iv))
  1628. {
  1629. BIO_set_cipher(bEnc,cipher,keyl,iv, 1);//1-加密、0-解密
  1630. bioKey = BIO_push(bEnc, bioKey); 
  1631. i2d_PrivateKey_bio(bioKey,key);//私钥加密
  1632. BIO_flush(bioKey);
  1633. bioKey = BIO_pop(bioKey);
  1634. BIO_free(bEnc);
  1635. }
  1636. else
  1637. {
  1638. strcpy(outMsg,"初始化key or iv 失败,");
  1639. bRet = FALSE;
  1640. goto err;
  1641. }
  1642. }
  1643. }
  1644. }
  1645. else if (outformat == PEM)
  1646. {
  1647. if(bioCert)
  1648. i=PEM_write_bio_X509(bioCert,pCert);
  1649. if(bioKey)
  1650. {
  1651. if(NULL == keyPwd || strlen(keyPwd) == 0)
  1652. j=PEM_write_bio_PrivateKey(bioKey, key, NULL, NULL, 0, 0, NULL);//私钥不加密
  1653. else
  1654. j=PEM_write_bio_PrivateKey(bioKey,key,EVP_des_ede3_cbc(),NULL,0,NULL, (void *)keyPwd); //私钥加密
  1655. }
  1656. }
  1657. err:
  1658. if (bio != NULL)
  1659. BIO_free(bio);
  1660. if (bioCert != NULL) 
  1661. BIO_free(bioCert);
  1662. if (bioKey != NULL) 
  1663. BIO_free_all(bioKey);
  1664. if(pCert)
  1665. X509_free(pCert);
  1666. if(key)
  1667. EVP_PKEY_free(key);
  1668. if(p12)
  1669. PKCS12_free(p12);
  1670. // EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
  1671. // CRYPTO_cleanup_all_ex_data();
  1672. if(bRet && i !=0 || j != 0)
  1673. {
  1674. return TRUE;
  1675. }
  1676. return FALSE;
  1677. }
  1678. //组合p12包
  1679. BOOL CreatePfx(char * StreamP12/*OUT包文件路径或内存区域*/,
  1680.    UINT & uP12Len,/*输入时候为用于保存结果的内存区域长度, 输出为实际P12内存的长度*/
  1681.    const char * P12EncPwd/*IN 用于加密P12的密码*/,
  1682.    const char * FriendName,/*IN 好记名称*/
  1683.    const char * StreamCert/*IN公钥*/,
  1684.    const UINT uCertLen,/*IN,公钥内存区域长度, 0 - 标示输入为磁盘文件*/
  1685.    const char * Streamkey/*IN私钥*/,
  1686.    const UINT uKeyLen,/*IN,私钥内存区域长度, 0 - 标示输入为磁盘文件*/
  1687.    const char * KeyDecPwd/*解密私钥密码*/,
  1688.    char * outMsg/*返回结果*/)
  1689. {
  1690. BOOL bRet = TRUE;
  1691. EVP_PKEY *key = NULL;
  1692. X509 *pCert = NULL;
  1693. PKCS12 * p12 = NULL;
  1694. int i=0;
  1695. //输出文件
  1696. BIO * biout = BIO_new(BIO_s_mem());
  1697. BIO_set_close(biout, BIO_CLOSE); 
  1698. pCert = LoadCert(StreamCert, uCertLen, "", outMsg);
  1699. if(!pCert) 
  1700. {
  1701. strcpy(outMsg,"加载公钥文件失败");
  1702. bRet = FALSE;
  1703. goto err;
  1704. }
  1705. key = LoadKey(Streamkey, uKeyLen, KeyDecPwd, outMsg);//私钥
  1706. if(!key) 
  1707. {
  1708. strcpy(outMsg,"加载私钥文件失败");
  1709. bRet = FALSE;
  1710. goto err;
  1711. }
  1712. OpenSSL_add_all_algorithms();
  1713. p12 = PKCS12_create(const_cast<char *>(P12EncPwd), const_cast<char *>(FriendName), key, pCert, NULL, 0,0,0,0,0);
  1714. if(!p12)
  1715. {
  1716. strcpy(outMsg,"创建p12结构失败");
  1717. bRet = FALSE;
  1718. goto err;
  1719. }
  1720. i2d_PKCS12_bio(biout, p12);
  1721. bRet = Bio2Mem(biout, StreamP12, &uP12Len);
  1722. err:
  1723. if(pCert)
  1724. X509_free(pCert);
  1725. if(key)
  1726. EVP_PKEY_free(key);
  1727. if (biout != NULL)
  1728. BIO_free(biout);
  1729. if(p12)
  1730. PKCS12_free(p12);
  1731. // EVP_cleanup();
  1732. return bRet;
  1733. }
  1734. //修改p12包密码
  1735. BOOL ChangePfxPwd(const char * strP12/*in老包文件*/,
  1736.    const char * strPwd/*IN原密码*/,
  1737.    const char * strPwd2/*IN新密码*/,
  1738.    const char * strOutP12/*in新包文件*/,
  1739.    char * outMsg/*返回结果*/)
  1740. {
  1741. BIO *bin = NULL;
  1742. BIO *biout = NULL;
  1743. EVP_PKEY *key = NULL;
  1744. X509 *pCert = NULL;
  1745. PKCS12 *p12 = NULL;
  1746. int len = 0,
  1747. wlen = 0;
  1748. BOOL bRet = TRUE;
  1749. OpenSSL_add_all_algorithms();
  1750. //输入文件 
  1751. if ((bin=BIO_new_file(strP12, "rw")) == NULL)
  1752. {
  1753. strcpy(outMsg,"加载PFX文件错误");
  1754. bRet = FALSE;
  1755. goto err;
  1756. }
  1757. p12 = d2i_PKCS12_bio(bin, NULL);
  1758. if (!p12) 
  1759. {
  1760. strcpy(outMsg,"加载包文件失败");
  1761. bRet = FALSE;
  1762. goto err;
  1763. }
  1764. if (!PKCS12_parse(p12, strPwd, &key, &pCert, NULL)) 
  1765. {
  1766. strcpy(outMsg,"解包失败");
  1767. bRet = FALSE;
  1768. goto err;
  1769. }
  1770. ///////////////////////////////////////
  1771. if(p12)
  1772. PKCS12_free(p12);
  1773. p12 = NULL;
  1774. p12 = PKCS12_create((char *)strPwd2,"MiniCA", key, pCert, NULL, 0,0,0,0,0);
  1775. if(!p12)
  1776. {
  1777. strcpy(outMsg,"创建p12结构失败");
  1778. bRet = FALSE;
  1779. goto err;
  1780. }
  1781. //输出文件
  1782. if ((biout = BIO_new_file(strP12, "w")) == NULL)
  1783. {
  1784. strcpy(outMsg,"创建输出文件失败");
  1785. bRet = FALSE;
  1786. goto err;
  1787. }
  1788. i2d_PKCS12_bio(biout, p12);
  1789. err:
  1790. if(p12)
  1791. PKCS12_free(p12);
  1792. if(pCert)
  1793. X509_free(pCert);
  1794. if(key)
  1795. EVP_PKEY_free(key);
  1796. if (bin)
  1797. BIO_free(bin);
  1798. if (biout)
  1799. BIO_free(biout);
  1800. // EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
  1801. return bRet;
  1802. }
  1803. //检验公钥、私钥是否配对
  1804. BOOL CertPairCheck(const char * pCert,
  1805.    const char * key,
  1806.    char * outMsg,
  1807.    const char * priPwd )//检验公钥、私钥是否配对
  1808. {
  1809. EVP_PKEY *pkey=NULL;
  1810. X509 *px509=NULL;
  1811. px509=LoadCert(pCert,0,"",outMsg);
  1812. if(px509==NULL)
  1813. {
  1814. strcpy(outMsg,"不能加载公钥文件");
  1815. return FALSE;
  1816. }
  1817. pkey=LoadKey(key,0,priPwd,outMsg);
  1818. if(pkey==NULL)
  1819. {
  1820. strcpy(outMsg,"不能加载私钥文件");
  1821. X509_free(px509);
  1822. return FALSE;
  1823. }
  1824. if(X509_check_private_key(px509,pkey))//匹配
  1825. {
  1826. X509_free(px509);
  1827. EVP_PKEY_free(pkey);
  1828. return TRUE;
  1829. }
  1830. else
  1831. {
  1832. strcpy(outMsg,"公私钥对不匹配");
  1833. X509_free(px509);
  1834. EVP_PKEY_free(pkey);
  1835. return FALSE;
  1836. }
  1837. }
  1838. int HexToTen(const char * pHex)
  1839. {
  1840.     DWORD dwHexNum=0;
  1841.     for (; *pHex!=0 ; pHex++)
  1842.     {
  1843.         dwHexNum *= 16;
  1844.         if ((*pHex>='0') && (*pHex<='9'))
  1845.             dwHexNum += *pHex-'0';
  1846.         else if ((*pHex>='a') && (*pHex<='f'))
  1847.             dwHexNum += *pHex-'a'+10;
  1848.         else if ((*pHex>='A') && (*pHex<='F'))
  1849.             dwHexNum += *pHex-'A'+10;
  1850.         else
  1851.             -1;
  1852.     }
  1853. return dwHexNum;
  1854. }
  1855. void Utf8ToAnsi(const UCHAR * lpsrc,const int srclen, LPSTR lpdst, int& dstlen)
  1856. {
  1857. WCHAR * Unicode;
  1858.     int len = MultiByteToWideChar ( CP_UTF8 , 0 ,(char*) lpsrc ,-1 ,NULL,0);
  1859.     Unicode = new WCHAR[len * sizeof(WCHAR)];
  1860.     MultiByteToWideChar ( CP_UTF8 , 0 ,( char * ) lpsrc, -1, Unicode , len );
  1861.     len = WideCharToMultiByte(CP_ACP,0,Unicode,-1,NULL,0,NULL,NULL);
  1862.     dstlen = WideCharToMultiByte (CP_ACP,0,Unicode,-1,lpdst,len,NULL,NULL);
  1863.     delete []Unicode;
  1864. }
  1865. /////////////////////////////////////////////////////////////////////////////
  1866. // 通过黑名单验证证书,验证通过返回真,否则返回假
  1867. BOOL CheckCertWithCrl(const char *pubCert,const int pubCertLen,
  1868.   const char *crlData,const int crlLen,char * outMsg)
  1869. {
  1870. BOOL bRet = TRUE;
  1871. int i = 0;
  1872. BOOL bf = TRUE;
  1873. int num;
  1874. ASN1_INTEGER *serial = NULL;
  1875. STACK_OF(X509_REVOKED) *revoked = NULL;
  1876. X509_REVOKED *rc;
  1877. X509_CRL * crl = NULL;
  1878. BIO * in=NULL;
  1879. X509 *x509 = LoadCert(pubCert,pubCertLen,NULL,outMsg);
  1880. if (x509 == NULL)
  1881. {
  1882. strcpy(outMsg,"加载证书失败");
  1883. bRet = FALSE;
  1884. goto end;
  1885. }
  1886. if(crlLen==0)
  1887. {
  1888. if((in=BIO_new_file(crlData, "r"))==NULL)
  1889. {
  1890. strcpy(outMsg,"Create File Error");
  1891. bRet = FALSE;
  1892. goto end;
  1893. }
  1894. }
  1895. else
  1896. {
  1897. if((in=BIO_new_mem_buf((void *)crlData,crlLen))== NULL)
  1898. {
  1899. strcpy(outMsg,"GlobalLock mem Error");
  1900. bRet = FALSE;
  1901. goto end;
  1902. }
  1903. }
  1904. crl = d2i_X509_CRL_bio(in,NULL); //DER 格式?
  1905. if(crl == NULL)
  1906. {
  1907. BIO_reset(in);//恢复bio
  1908. crl = PEM_read_bio_X509_CRL(in,NULL,NULL,NULL); //PEM格式?
  1909. }
  1910. if(crl == NULL)
  1911. {
  1912. strcpy(outMsg,"加载 crl 失败");
  1913. bRet = FALSE;
  1914. goto end;
  1915. }
  1916. revoked = crl->crl->revoked;
  1917.     
  1918. serial = X509_get_serialNumber(x509);
  1919. num = sk_X509_REVOKED_num(revoked);
  1920. for(i=0;i<num;i++)
  1921. {
  1922. rc=sk_X509_REVOKED_pop(revoked); //leak
  1923. if(ASN1_INTEGER_cmp(serial,rc->serialNumber)==0)
  1924. {
  1925. strcpy(outMsg,"证书已作废");
  1926. bf = FALSE;
  1927. }
  1928. X509_REVOKED_free(rc); //leak
  1929. }
  1930.     
  1931. end:
  1932. if(crl)
  1933. X509_CRL_free(crl);
  1934. if(x509)
  1935. X509_free(x509);
  1936. if(in)
  1937. BIO_free(in);
  1938. if(bRet)
  1939. {
  1940. if(bf)
  1941. strcpy(outMsg,"证书有效");
  1942. }
  1943. return bf;
  1944. }
  1945.     
  1946. /////////////////////////////////////////////////////////////////////////////
  1947. // 通过根证书验证证书ENGINE_load_private_key
  1948. BOOL CheckCertWithRoot(const char *pubCert,const int pubCertLen,
  1949.    const char *rootCert,const int rootCertLen,char * outMsg)
  1950. {
  1951. OpenSSL_add_all_algorithms();
  1952. BOOL bRet = TRUE;
  1953. EVP_PKEY * pcert = NULL;
  1954. X509 *pRoot = NULL;
  1955. int ret =0;
  1956. X509 *x509 = LoadCert(pubCert,pubCertLen,NULL,outMsg);
  1957. if (x509 == NULL)
  1958. {
  1959. strcpy(outMsg,"加载证书失败");
  1960. bRet =  FALSE;
  1961. goto end;
  1962. }
  1963. pRoot = LoadCert(rootCert,rootCertLen,NULL,outMsg);
  1964. if (pRoot == NULL)
  1965. {
  1966. strcpy(outMsg,"加载根证书失败");
  1967. bRet =  FALSE;
  1968. goto end;
  1969. }
  1970.     
  1971. pcert = X509_get_pubkey(pRoot);
  1972. if (pcert == NULL)
  1973. {
  1974. strcpy(outMsg,"读取根证书公钥信息失败");
  1975. bRet =  FALSE;
  1976. goto end;
  1977. }
  1978. ret = X509_verify(x509,pcert);
  1979. end:
  1980. if(pcert)
  1981. EVP_PKEY_free (pcert); 
  1982.     if(x509)
  1983. X509_free(x509);
  1984. if(pRoot)
  1985. X509_free(pRoot);
  1986. // EVP_cleanup();
  1987. if(bRet)
  1988. {
  1989. if(ret==1)
  1990. {
  1991. strcpy(outMsg,"证书与根证书匹配");
  1992. return TRUE;
  1993. }
  1994. else
  1995. {
  1996. strcpy(outMsg,"证书与根证书不匹配");
  1997. return FALSE;
  1998. }
  1999. }
  2000. else
  2001. return FALSE;
  2002. }
  2003.     
  2004. /////////////////////////////////////////////////////////////////////////////
  2005. // 检查证书有效期,在有效期内返回真,否则返回假
  2006. BOOL CheckCertLife(const char *pubCert,const int pubCertLen,char * outMsg)
  2007. {
  2008. X509 *x509 = LoadCert(pubCert,pubCertLen,NULL,outMsg);
  2009. if (x509 == NULL)
  2010. {
  2011. strcpy(outMsg,"加载证书失败");
  2012. return FALSE;
  2013. }
  2014. time_t ct;
  2015. time( &ct );
  2016. asn1_string_st *before=X509_get_notBefore(x509),
  2017. *after=X509_get_notAfter(x509);
  2018. ASN1_UTCTIME *be=ASN1_STRING_dup(before),
  2019. *af=ASN1_STRING_dup(after);
  2020. BOOL bf;
  2021. if(ASN1_UTCTIME_cmp_time_t(be,ct)>=0||ASN1_UTCTIME_cmp_time_t(af,ct)<=0)
  2022. {
  2023. strcpy(outMsg,"证书超出有效期");
  2024. bf = FALSE;
  2025. }
  2026. else
  2027. {
  2028. strcpy(outMsg,"证书有效");
  2029. bf = TRUE;
  2030. }
  2031. M_ASN1_UTCTIME_free(be);
  2032. M_ASN1_UTCTIME_free(af);
  2033. X509_free(x509);
  2034. return bf;
  2035. }
  2036.  
  2037. /*组合P7包*/
  2038. BOOL CreateP7b(std::list<std::string> * pCertList,
  2039.    const char * lpszCrl,
  2040.    const char * outP7b,
  2041.    const int outformat,
  2042.    char * outMsg/*返回结果*/)
  2043. {
  2044. int i = 0;
  2045. BIO *in = NULL,
  2046. *out = NULL;
  2047. PKCS7 *p7 = NULL;
  2048. PKCS7_SIGNED *p7s = NULL;
  2049. X509_CRL *crl = NULL;
  2050. STACK *certflst = NULL;
  2051. STACK_OF(X509_CRL) *crl_stack = NULL;
  2052. STACK_OF(X509) *cert_stack = NULL;
  2053. in = BIO_new(BIO_s_file());
  2054. if(lpszCrl && strlen(lpszCrl) != 0) //有黑名单文件
  2055. {
  2056. //加载CRL结构
  2057. if (BIO_read_filename(in,lpszCrl) <= 0)
  2058. {
  2059. sprintf(outMsg, "加载CRL%s失败", lpszCrl);
  2060. goto end;
  2061. }
  2062. crl = d2i_X509_CRL_bio(in,NULL); //DER 格式?
  2063. if(crl == NULL)
  2064. {
  2065. BIO_reset(in);//恢复bio
  2066. crl = PEM_read_bio_X509_CRL(in,NULL,NULL,NULL); //PEM格式?
  2067. }
  2068. }
  2069. if ((p7 = PKCS7_new()) == NULL) goto end;
  2070. if ((p7s = PKCS7_SIGNED_new()) == NULL) goto end;
  2071. p7->type = OBJ_nid2obj(NID_pkcs7_signed);
  2072. p7->d.sign = p7s;
  2073. p7s->contents->type = OBJ_nid2obj(NID_pkcs7_data);
  2074. if (!ASN1_INTEGER_set(p7s->version,1))
  2075. goto end;
  2076. if ((crl_stack=sk_X509_CRL_new_null()) == NULL)
  2077. goto end;
  2078. p7s->crl = crl_stack;
  2079. if (crl != NULL)
  2080. {
  2081. sk_X509_CRL_push(crl_stack,crl);
  2082. crl = NULL; /* now part of p7 for OPENSSL_freeing */
  2083. }
  2084. if ((cert_stack = sk_X509_new_null()) == NULL) goto end;
  2085. p7s->cert = cert_stack;
  2086. if(pCertList)
  2087. {
  2088. std::list<std::string>::const_iterator pos;
  2089. for(pos = pCertList->begin(); pos != pCertList->end(); ++pos)
  2090. {
  2091. std::string strCert = *pos;
  2092. X509 * pX509 = LoadCert(strCert.c_str(), 0, 0, outMsg);
  2093. if(pX509)
  2094. {
  2095. sk_X509_push(cert_stack, pX509);
  2096. }
  2097. }
  2098. }
  2099. out = BIO_new(BIO_s_file());
  2100. if (BIO_write_filename(out, const_cast<char *>(outP7b)) <= 0)
  2101. {
  2102. goto end;
  2103. }
  2104. if(outformat == DER)
  2105. i=i2d_PKCS7_bio(out,p7);
  2106. else if(outformat == PEM)
  2107. i=PEM_write_bio_PKCS7(out,p7);
  2108. end:
  2109. if (in != NULL) BIO_free(in);
  2110. if (out != NULL) BIO_free_all(out);
  2111. if (p7 != NULL) PKCS7_free(p7); //free cert_stack
  2112. if (crl != NULL) X509_CRL_free(crl);
  2113. return i;
  2114. }
  2115. /*分解P7包*/
  2116. BOOL ParseP7b(const char * lpszInP7b/*包文件或内存*/,
  2117.   const UINT iP12Len/* 如果包为文件,则为0,否则为内存长度*/,
  2118.   const int outformat/*输出格式*/,
  2119.   const char * lpszCert/*公钥存放*/,
  2120.   const char * lpszCrl/*CRL存放*/,
  2121.   const char * lpszOutP7b/*用于转换P7格式的输出文件名*/,
  2122.   char * outMsg/*返回结果*/)
  2123. {
  2124. PKCS7 *p7 = NULL;
  2125. int i,badops=0;
  2126. BIO *in = NULL,
  2127. *out = NULL;
  2128. int ret = 1;
  2129. STACK_OF(X509) *certs=NULL;
  2130. STACK_OF(X509_CRL) *crls=NULL;
  2131. in=BIO_new(BIO_s_file());
  2132. out=BIO_new(BIO_s_file());
  2133. if ((in == NULL) || (out == NULL))
  2134. {
  2135. ret = 0;
  2136.         goto end;
  2137.     }
  2138. if (BIO_read_filename(in, lpszInP7b) <= 0)
  2139. if (in == NULL)
  2140. {
  2141. sprintf(outMsg, "读取P7B%s失败", lpszInP7b);
  2142. ret = 0;
  2143. goto end;
  2144. }
  2145. p7 = d2i_PKCS7_bio(in,NULL);
  2146. if(!p7)
  2147. {
  2148. BIO_reset(in);//恢复bio
  2149. p7=PEM_read_bio_PKCS7(in,NULL,NULL,NULL);
  2150. }
  2151. if (p7 == NULL)
  2152. {
  2153. sprintf(outMsg, "加载P7B%s失败", lpszInP7b);
  2154. ret = 0;
  2155. goto end;
  2156. }
  2157. i=OBJ_obj2nid(p7->type);
  2158. switch (i)
  2159. {
  2160. case NID_pkcs7_signed:
  2161. certs=p7->d.sign->cert;
  2162. crls=p7->d.sign->crl;
  2163. break;
  2164. case NID_pkcs7_signedAndEnveloped:
  2165. certs=p7->d.signed_and_enveloped->cert;
  2166. crls=p7->d.signed_and_enveloped->crl;
  2167. break;
  2168. default:
  2169. break;
  2170. }
  2171. if (certs != NULL && lpszCert && strlen(lpszCert) !=0 )
  2172. {
  2173. X509 *x;
  2174. for (i=0; i<sk_X509_num(certs); i++)
  2175. {
  2176. BIO * bioCert = NULL;
  2177. char buf[256] = {0};
  2178. sprintf(buf, "%s-%d.Cer", lpszCert, i);
  2179. if((bioCert = BIO_new_file(buf, "w")) == NULL)
  2180. {
  2181. goto end;
  2182. ret = 0;
  2183. }
  2184. x = sk_X509_value(certs,i); //保存证书公钥
  2185. if (outformat == DER)
  2186. {
  2187. i2d_X509_bio(bioCert,x);
  2188. }
  2189. else
  2190. {
  2191. PEM_write_bio_X509(bioCert,x);
  2192. }
  2193. BIO_free(bioCert);
  2194. }
  2195. }
  2196. if (crls != NULL  && lpszCrl && strlen(lpszCrl) !=0 )
  2197. {
  2198. X509_CRL *crl;
  2199. for (i=0; i<sk_X509_CRL_num(crls); i++)
  2200. {
  2201. BIO * bioCrl = NULL;
  2202. char buf[256] = {0};
  2203. sprintf(buf, "%s-%d.Crl", lpszCrl, i);
  2204. if((bioCrl = BIO_new_file(buf, "w")) == NULL)
  2205. {
  2206. ret = 0;
  2207. goto end;
  2208. }
  2209. crl = sk_X509_CRL_value(crls,i);
  2210. PEM_write_bio_X509_CRL(bioCrl, crl);
  2211. BIO_free(bioCrl);
  2212. }
  2213. }
  2214. //转换P7格式
  2215. if(lpszOutP7b && strlen(lpszOutP7b) != 0)
  2216. {
  2217. if (BIO_write_filename(out, const_cast<char *>(lpszOutP7b)) <= 0)
  2218. {
  2219. ret = 0;
  2220. goto end;
  2221. }
  2222. if(outformat == DER)
  2223. i=i2d_PKCS7_bio(out,p7);
  2224. else
  2225. i=PEM_write_bio_PKCS7(out,p7);
  2226. if (!i)
  2227. {
  2228. sprintf(outMsg, "保存P7B%s失败", lpszOutP7b);
  2229. ret = 0;
  2230. goto end;
  2231. }
  2232. }
  2233. end:
  2234. if (p7 != NULL) PKCS7_free(p7);
  2235. if (in != NULL) BIO_free(in);
  2236. if (out != NULL) BIO_free_all(out);
  2237. return ret;
  2238. }
  2239. //转换证书到REQ
  2240. BOOL X5092Req(char * Cert/*公钥*/,int Certlen,char * Key/*私钥,用于签名公钥*/,int Keylen,char * Keypwd/*密码*/,
  2241.   char * outFile/*输出文件,req或者公钥证书*/,char * outMsg,/*操作结果*/
  2242.   char * Rootcert,/*根证书公钥*/int Rootlen,/*为0则certfile为磁盘文件,否则为内存区域*/
  2243.   char * Rootkey/*根证书私钥*/,int RKeylen,char * Pwd/*私钥密码*/)
  2244. {
  2245. X509_REQ * req = NULL;
  2246. EVP_PKEY * pkey = NULL,
  2247.      * prkey = NULL;//证书私钥,//根私钥
  2248. X509 * x509 = NULL,
  2249.  * x = NULL,
  2250.  * newx = NULL;//根公钥,证书公钥,新公钥证书
  2251. BIO * memcert = NULL, 
  2252. * memkey = NULL;//输出证书公私钥
  2253. BUF_MEM * bptrcert = NULL,
  2254.     * bptrkey = NULL;
  2255. char * md=NULL;
  2256. BOOL bReq = TRUE;//制作REQ还是CERT ,TRUE 为REQ
  2257. int i = 0,
  2258. j = 0,
  2259. ok = 0,
  2260. ret = 1;
  2261. const EVP_MD * dgst = NULL;
  2262. BIO * out = BIO_new_file(outFile, "w");
  2263. OpenSSL_add_all_algorithms();//加入签名算法
  2264. memcert= BIO_new(BIO_s_mem());
  2265. memkey= BIO_new(BIO_s_mem());
  2266. BIO_set_close(memcert, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */
  2267. BIO_set_close(memkey, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */
  2268. pkey = LoadKey(Key, Keylen, Keypwd, outMsg);//加载私钥
  2269. if (pkey == NULL)
  2270. {
  2271. ret = 0;
  2272. goto err;
  2273. }
  2274. x = LoadCert(Cert,Certlen,"",outMsg);//加载公钥
  2275. if (x == NULL)
  2276. {
  2277. ret = 0;
  2278. goto err;
  2279. }
  2280. if (!X509_check_private_key(x,pkey))
  2281. {
  2282. sprintf(outMsg,"CA certificate and CA private key do not matchn");
  2283. ret = 0;
  2284. goto err;
  2285. }
  2286. //得到公钥REQ
  2287. req = X509_to_X509_REQ(x,pkey,EVP_sha1());//EVP_md5
  2288. if (req == NULL)
  2289. {
  2290. strcpy(outMsg,"证书转换为REQ失败");
  2291. ret = 0;
  2292. goto err;
  2293. }
  2294. /* prkey = LoadKey(Rootkey,Keylen,Pwd,outMsg);//加载根私钥
  2295. if (prkey != NULL)
  2296. {
  2297. x509 = LoadCert(Rootcert,Rootlen,"",outMsg);
  2298. if (x509 != NULL)
  2299. {
  2300. if(X509_check_private_key(x509,prkey))//匹配
  2301. {
  2302. bReq = FALSE;//制作证书
  2303. }
  2304. else
  2305. sprintf(outMsg,"根证书公私钥对不匹配");
  2306. }
  2307. else
  2308. sprintf(outMsg,"不能加载根证书公钥");
  2309. }
  2310. else
  2311. sprintf(outMsg,"不能加载根证书私钥");
  2312. if(bReq)//REQ
  2313. {
  2314. PEM_write_bio_X509_REQ(out,rq);
  2315. }
  2316. else //证书
  2317. {
  2318. md="sha1";//////////!!!!!!!!!!!!!!!!!////////////////////////////
  2319. if ((dgst=EVP_get_digestbyname(md)) == NULL)//return an EVP_MD structure when passed a digest name
  2320. {
  2321. sprintf(outMsg,"%s is an unsupported message digest typen",md);
  2322. ret = 0;
  2323. goto err;
  2324. }
  2325. j=certify(&newx,req,prkey,x509,dgst,//公钥证书out,请求文件,根私钥,根公钥,
  2326. serial,"today",enddate,days,KUSAGE,EKUSAGE,outMsg);
  2327. if (j <= 0) 
  2328. {
  2329. ret=0;
  2330. goto err;
  2331. }
  2332. if(((bcert=BIO_new_file(outfile, "w"))== NULL))
  2333. {
  2334. strcpy(outMsg,"Create File Error");
  2335. goto err;
  2336. }
  2337. if (iType==DER)
  2338. {
  2339. i2d_X509_bio(bcert,x);
  2340. }
  2341. else if(iType==PEM)
  2342. {
  2343. PEM_write_bio_X509(bcert,x);
  2344. }
  2345. }
  2346. */
  2347. err:
  2348. return TRUE;
  2349. }
  2350. /*
  2351. 这是转换函数:  
  2352.            int            CodePageConvert(UINT  SrcCodePage,  LPCTSTR  pBuff,  int  iBuffLen,  UINT  DestCodePage,  char*  &lpCodePage)  
  2353.            {  
  2354.                        int  iWideCharCnt  =  ::MultiByteToWideChar(SrcCodePage,  0,  pBuff,  iBuffLen,  NULL,  0);  
  2355.                        LPWSTR  lpszWideChar  =  new  wchar_t[iWideCharCnt  +  1];  
  2356.                        memset(lpszWideChar,  0,  (iWideCharCnt  +  1)  *  sizeof(WCHAR));  
  2357.                        iWideCharCnt  =  MultiByteToWideChar(SrcCodePage,  0,  pBuff,  iBuffLen,  lpszWideChar,  iWideCharCnt);  
  2358.  
  2359.                        if(DestCodePage  ==  54936    
  2360.                                                &&  !IsValidCodePage(54936))  
  2361.                                    DestCodePage  =  936;  
  2362.  
  2363.                        int  iDestCnt  =  WideCharToMultiByte(DestCodePage,  0,  lpszWideChar,  iWideCharCnt,  NULL,  0,  NULL,  NULL);  
  2364.                        lpCodePage  =  new  char[iDestCnt  +  1];  
  2365.                        memset(lpCodePage,  0,  iDestCnt  +  1);  
  2366.                        iDestCnt  =  WideCharToMultiByte(DestCodePage,  0,  lpszWideChar,  iWideCharCnt,  lpCodePage,  iDestCnt,  NULL,  NULL);  
  2367.  
  2368.                        delete  []lpszWideChar;              
  2369.                        return  iDestCnt;  
  2370.            }  
  2371. 下面是调用方法:  
  2372.      utf-8  到  gbk  
  2373.            int  nLen  =  CodePageConvertUnix("UTF-8",_T("标准"),2,"GBK",lpOut);  
  2374.      gbk  到utf-8  
  2375. int  nLen  =  CodePageConvertUnix("UTF-8",_T("标准"),2,"GBK",lpOut); 
  2376.   //加入扩展信息
  2377. // Add_ExtCert(ret,ret,NID_basic_constraints, "critical,CA:FALSE,pathlen:1");
  2378. // Add_ExtCert(x,x,NID_basic_constraints, "critical,CA:TRUE,pathlen:1");
  2379. //主题密钥标示符---当发行者有多个签名密钥时
  2380. // Add_ExtCert(x,x,NID_subject_key_identifier, "hash");
  2381. //颁发机构密钥标示符
  2382. // Add_ExtCert(x,x,NID_authority_key_identifier, "keyid:always");
  2383. //
  2384. // Add_ExtCert(x,x,NID_certificate_policies, "serverAuth");
  2385. //主题备用名称,URL:http://my.url.here/、支持email  copy
  2386. // Add_ExtCert(x ,x, NID_subject_alt_name, "email:camgr@rog.majki.net,URI:altname:/mirabile/,URI:otherName://tygScaowlOmi,email:nc-glaserth@netcologne.de");
  2387. //加入自定义信息begin
  2388. /* int nid;
  2389. nid = OBJ_create("1.2.3.4.9", "Hpxs", "I love you!");
  2390. X509V3_EXT_add_alias(nid, NID_netscape_comment);
  2391. Add_ExtCert(x, nid, "I love you");
  2392. //加入自定义信息end
  2393. */
  2394.   
  2395. /* Lets add the extensions, if there are any 加入标准扩展*/