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

CA认证

开发平台:

Visual C++

  1. // CertKey.h: interface for the CCertKey class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #if !defined(AFX_CERTKEY_H__1727C3A6_9A84_4000_837B_9327D096738D__INCLUDED_)
  5. #define AFX_CERTKEY_H__1727C3A6_9A84_4000_837B_9327D096738D__INCLUDED_
  6. #if _MSC_VER > 1000
  7. #pragma once
  8. #endif // _MSC_VER > 1000
  9. #include <openssl/ssl.h>
  10. #include <openssl/pkcs12.h>
  11. #include <openssl/rand.h>
  12. #include <openssl/err.h>
  13. class CCertKey  
  14. {
  15. public:
  16. CCertKey()
  17. {
  18. }
  19. virtual ~CCertKey()
  20. {
  21. }
  22. public:
  23. static X509 * CCertKey::LoadCert(char * cert,int certlen,char * pass,char * outMsg)//枚举DER/PEM格式
  24. {
  25. BIO * in = NULL;
  26. X509 * x509 = NULL;
  27. if(certlen==0)//输入为磁盘文件
  28. {
  29. if((in = BIO_new_file(cert, "r")) == NULL)
  30. {
  31. sprintf(outMsg,"open CA certificate file %s error", cert);
  32. return NULL;
  33. }
  34. }
  35. else//输入为内存中文件
  36. {
  37. if((in = BIO_new_mem_buf(cert,certlen))== NULL)//只读类型
  38. {
  39. sprintf(outMsg,"Make Mem Bio Error");
  40. return NULL;
  41. }
  42. BIO_set_close(in, BIO_CLOSE); 
  43. }
  44. if((x509 = load_cert(in,DER,NULL,outMsg))==NULL)//尝试DER
  45. {
  46. BIO_reset(in);//恢复bio
  47. if((x509 = load_cert(in,PEM,NULL,outMsg))==NULL)//尝试PEM
  48. {
  49. BIO_reset(in);//恢复bio
  50. x509 = load_cert(in,P12,pass,outMsg);//尝试P12
  51. }
  52. }
  53. if (in != NULL) BIO_free(in);
  54. if(x509)
  55. sprintf(outMsg, "");
  56. // CRYPTO_cleanup_all_ex_data();
  57. return x509;
  58. }
  59. static EVP_PKEY * CCertKey::LoadKey(char * key,int keylen,char * pass,char * outMsg)
  60. {
  61. EVP_PKEY *pkey=NULL;
  62. BIO * in=NULL;
  63. if(keylen==0)//输入为磁盘文件
  64. {
  65. if((in=BIO_new_file(key, "r")) == NULL)
  66. {
  67. sprintf(outMsg,"open CA certificate file %s error", key);
  68. return NULL;
  69. }
  70. }
  71. else//输入为内存中文件
  72. {
  73. if((in=BIO_new_mem_buf(key,keylen))== NULL)//只读类型
  74. {
  75. sprintf(outMsg,"Make Mem Bio Error");
  76. return NULL;
  77. }
  78. }
  79. if((pkey=load_key(in,DER,pass,outMsg))==NULL)//尝试DER
  80. {
  81. BIO_reset(in);//BIO是可读写的,那么该BIO所有数据都会被清空;
  82. //如果该BIO是只读的,那么该操作只会简单将指
  83. //针指向原始位置,里面的数据可以再读.
  84. if((pkey=load_key(in,PEM,pass,outMsg))==NULL)//尝试PEM
  85. {
  86. BIO_reset(in);
  87. pkey=load_key(in,P12,pass,outMsg);
  88. }
  89. }
  90. if (in != NULL) BIO_free(in);
  91. if(pkey)
  92. sprintf(outMsg, "");
  93. // CRYPTO_cleanup_all_ex_data();
  94. return pkey;
  95. }
  96. private:
  97. static X509 * CCertKey::load_cert(BIO *cert/*输入BIO*/, int format/*格式*/,char * pwd,/*P12密钥*/char * outMsg)
  98. {
  99. ASN1_HEADER *ah=NULL;
  100. BUF_MEM *buf=NULL;
  101. X509 *x=NULL;
  102. if  (format == DER)
  103. x=d2i_X509_bio(cert,NULL);
  104. else if (format == PEM)
  105. x=PEM_read_bio_X509(cert,NULL,NULL,NULL);//PEM_read_bio_X509_AUX
  106. else if (format == P12)
  107. {
  108. SSLeay_add_all_algorithms();
  109. PKCS12 *p12 = d2i_PKCS12_bio(cert, NULL);
  110. PKCS12_parse(p12, pwd, NULL, &x, NULL);
  111. PKCS12_free(p12);
  112. p12 = NULL;
  113. }
  114. else
  115. {
  116. sprintf(outMsg,"bad input format specified for input certn");
  117. goto end;
  118. }
  119. end:
  120. if (x == NULL)
  121. {
  122. sprintf(outMsg,"unable to load certificaten");
  123. }
  124. else
  125. sprintf(outMsg,"");
  126. if (ah != NULL) ASN1_HEADER_free(ah);
  127. if (buf != NULL) BUF_MEM_free(buf);
  128. return(x);
  129. }
  130. static EVP_PKEY * CCertKey::load_key(BIO *bio, int format, char * pass,char * outMsg)
  131. {
  132. EVP_PKEY *pkey=NULL;
  133. SSLeay_add_all_algorithms();
  134. if (format == DER)
  135. {
  136. if(NULL == pass || strlen(pass) == 0)
  137. {
  138. pkey=d2i_PrivateKey_bio(bio, NULL);
  139. }
  140. else
  141. {
  142. //添加解密链
  143. unsigned char key[EVP_MAX_KEY_LENGTH]="";//算法最长的KEY长度
  144. unsigned char iv[EVP_MAX_IV_LENGTH]="";//算法最长的IV长度
  145. BIO * bDec = NULL;
  146. bDec = BIO_new(BIO_f_cipher());
  147. const EVP_CIPHER * cipher = NULL;
  148. cipher = EVP_des_ede3_cbc(); // 3DES-EDE-CBC 
  149. if(EVP_BytesToKey(cipher,EVP_sha1(),NULL,(unsigned char *)pass,
  150. strlen(pass),1,key,iv))
  151. {
  152. BIO_set_cipher(bDec,cipher,key,iv, 0);//1-加密、0-解密
  153. bio = BIO_push(bDec, bio); 
  154. BIO_flush(bio);
  155. pkey = d2i_PrivateKey_bio(bio, NULL);//私钥解密
  156. bio = BIO_pop(bio);
  157. BIO_free(bDec);
  158. }
  159. else
  160. {
  161. strcpy(outMsg,CMiniCaApp::NormalCode("初始化key or iv 失败"));
  162. goto end;
  163. }
  164. }
  165. }
  166. else if (format == PEM)
  167. {
  168. pkey=PEM_read_bio_PrivateKey(bio,NULL,NULL,pass);
  169. }
  170. else if (format == P12)
  171. {
  172. SSLeay_add_all_algorithms();
  173. PKCS12 *p12 = d2i_PKCS12_bio(bio, NULL);
  174. PKCS12_parse(p12, pass, &pkey, NULL, NULL);
  175. PKCS12_free(p12);
  176. p12 = NULL;
  177. }
  178. else
  179. {
  180. sprintf(outMsg,"bad input format specified for keyn");
  181. goto end;
  182. }
  183. end:
  184. if (pkey == NULL)
  185. sprintf(outMsg,"unable to load Private Keyn");
  186. else
  187. sprintf(outMsg,"");
  188. // EVP_cleanup();
  189. return(pkey);
  190. }
  191. };
  192. #endif // !defined(AFX_CERTKEY_H__1727C3A6_9A84_4000_837B_9327D096738D__INCLUDED_)