pki_x509req.cpp
上传用户:stc1860
上传日期:2007-01-12
资源大小:234k
文件大小:7k
源码类别:

CA认证

开发平台:

MultiPlatform

  1. /*
  2.  * Copyright (C) 2001 Christian Hohnstaedt.
  3.  *
  4.  *  All rights reserved.
  5.  *
  6.  *
  7.  *  Redistribution and use in source and binary forms, with or without 
  8.  *  modification, are permitted provided that the following conditions are met:
  9.  *
  10.  *  - Redistributions of source code must retain the above copyright notice,
  11.  *    this list of conditions and the following disclaimer.
  12.  *  - Redistributions in binary form must reproduce the above copyright notice,
  13.  *    this list of conditions and the following disclaimer in the documentation
  14.  *    and/or other materials provided with the distribution.
  15.  *  - Neither the name of the author nor the names of its contributors may be 
  16.  *    used to endorse or promote products derived from this software without
  17.  *    specific prior written permission.
  18.  *
  19.  *
  20.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  21.  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  22.  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  23.  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  24.  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  25.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  26.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  27.  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  28.  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  29.  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  30.  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31.  *
  32.  *
  33.  * This program links to software with different licenses from:
  34.  *
  35.  * http://www.openssl.org which includes cryptographic software
  36.  *  written by Eric Young (eay@cryptsoft.com)"
  37.  *
  38.  * http://www.sleepycat.com
  39.  *
  40.  * http://www.trolltech.com
  41.  * 
  42.  *
  43.  *
  44.  * http://www.hohnstaedt.de/xca
  45.  * email: christian@hohnstaedt.de
  46.  *
  47.  * $Id: pki_x509req.cpp,v 1.29 2003/01/06 19:35:51 chris Exp $
  48.  *
  49.  */                           
  50. #include "pki_x509.h"
  51. void pki_x509req::init()
  52. {
  53. request = NULL;
  54. privkey = NULL;
  55. className = "pki_x509req";
  56. }
  57. pki_x509req::pki_x509req(pki_key *key, const string cn,
  58. const string c, const string l,
  59. const string st,const string o,
  60. const string ou,const string email, 
  61. const string d, const string challenge)
  62. :pki_base( d )
  63. {
  64. init();
  65. X509_NAME *subj = X509_NAME_new();
  66. if (cn != "")
  67. X509_NAME_add_entry_by_NID(subj,NID_commonName, MBSTRING_ASC,
  68. (unsigned char*)cn.c_str(),-1,-1,0);
  69. if (c != "")
  70. X509_NAME_add_entry_by_NID(subj,NID_countryName, MBSTRING_ASC, 
  71. (unsigned char*)c.c_str() , -1, -1, 0);
  72. if (l != "")
  73. X509_NAME_add_entry_by_NID(subj,NID_localityName, MBSTRING_ASC, 
  74. (unsigned char*)l.c_str() , -1, -1, 0);
  75. if (st != "")
  76. X509_NAME_add_entry_by_NID(subj,NID_stateOrProvinceName, MBSTRING_ASC, 
  77. (unsigned char*)st.c_str() , -1, -1, 0);
  78. if (o != "")
  79. X509_NAME_add_entry_by_NID(subj,NID_organizationName, MBSTRING_ASC, 
  80. (unsigned char*)o.c_str() , -1, -1, 0);
  81. if (ou != "")
  82. X509_NAME_add_entry_by_NID(subj,NID_organizationalUnitName, MBSTRING_ASC, 
  83. (unsigned char*)ou.c_str() , -1, -1, 0);
  84. if (email != "")
  85. X509_NAME_add_entry_by_NID(subj,NID_pkcs9_emailAddress, MBSTRING_ASC, 
  86. (unsigned char*)email.c_str() , -1, -1, 0);
  87. createReq(key, subj);
  88. X509_NAME_free(subj);
  89. }
  90. pki_x509req::pki_x509req(pki_x509 *cert) :pki_base()
  91. {
  92. init();
  93. if (!cert) return;
  94. setDescription(cert->getDescription());
  95. createReq(cert->getKey(), X509_get_subject_name(cert->getCert()));
  96. }
  97. void pki_x509req::createReq(pki_key *key, X509_NAME *dist_name)
  98. {
  99. request = X509_REQ_new();
  100. openssl_error();
  101. if (!key || key->isPubKey()) {
  102. openssl_error("key not valid");
  103. return;
  104. }
  105. openssl_error();
  106. X509_REQ_set_version(request, 0L);
  107. openssl_error();
  108. X509_REQ_set_pubkey(request, key->key);
  109. openssl_error();
  110. X509_REQ_get_subject_name(request) = X509_NAME_dup( dist_name);
  111. openssl_error();
  112. const EVP_MD *digest = EVP_md5();
  113. X509_REQ_sign(request,key->key ,digest);
  114. openssl_error();
  115. setKey(key);
  116. }
  117. pki_x509req::pki_x509req() : pki_base()
  118. {
  119. init();
  120. request = X509_REQ_new();
  121. openssl_error();
  122. }
  123. pki_x509req::~pki_x509req()
  124. {
  125. if (request)
  126. X509_REQ_free(request);
  127. openssl_error();
  128. if (privkey)
  129. privkey->decUcount();
  130. }
  131. pki_x509req::pki_x509req(const string fname)
  132. {
  133. init();
  134. FILE *fp = fopen(fname.c_str(),"r");
  135. if (fp != NULL) {
  136.    request = PEM_read_X509_REQ(fp, NULL, NULL, NULL);
  137.    if (!request) {
  138. ign_openssl_error();
  139. rewind(fp);
  140. CERR("Fallback to private key DER"); 
  141.     request = d2i_X509_REQ_fp(fp, NULL);
  142. openssl_error();
  143.    }
  144.    int r = fname.rfind('.');
  145. #ifdef WIN32    
  146.    int l = fname.rfind('\');
  147. #else
  148.    int l = fname.rfind('/');
  149. #endif
  150.    desc = fname.substr(l+1,r-l-1);
  151.    if (desc == "") desc = fname;
  152.    openssl_error();
  153. }
  154. else fopen_error(fname);
  155. fclose(fp);
  156. }
  157. void pki_x509req::fromData(unsigned char *p, int size)
  158. {
  159. privkey = NULL;
  160. request = d2i_X509_REQ(NULL, &p, size);
  161. openssl_error();
  162. }
  163. string pki_x509req::getDN(int nid)
  164. {
  165. char buf[200] = "";
  166. string s;
  167. X509_NAME *subj = X509_REQ_get_subject_name(request);
  168. X509_NAME_get_text_by_NID(subj, nid, buf, 200);
  169. openssl_error();
  170. s = buf;
  171. return s;
  172. }
  173. unsigned char *pki_x509req::toData(int *size)
  174. {
  175. unsigned char *p, *p1;
  176. *size = i2d_X509_REQ(request, NULL);
  177. openssl_error();
  178. p = (unsigned char*)OPENSSL_malloc(*size);
  179. p1 = p;
  180. i2d_X509_REQ(request, &p1);
  181. openssl_error();
  182. return p;
  183. }
  184. void pki_x509req::writeReq(const string fname, bool PEM)
  185. {
  186. FILE *fp = fopen(fname.c_str(),"w");
  187. if (fp != NULL) {
  188.    if (request){
  189. if (PEM) 
  190.    PEM_write_X509_REQ(fp, request);
  191. else
  192.    i2d_X509_REQ_fp(fp, request);
  193.         openssl_error();
  194.    }
  195. }
  196. else fopen_error(fname);
  197. fclose(fp);
  198. }
  199. bool pki_x509req::compare(pki_base *refreq)
  200. {
  201. if (!refreq) return false;
  202. const EVP_MD *digest=EVP_md5();
  203. unsigned char d1[EVP_MAX_MD_SIZE], d2[EVP_MAX_MD_SIZE];
  204. unsigned int d1_len,d2_len;
  205. X509_REQ_digest(request, digest, d1, &d1_len);
  206. X509_REQ_digest(((pki_x509req *)refreq)->request, digest, d2, &d2_len);
  207. ign_openssl_error();
  208. if ((d1_len == d2_len) && 
  209.     (d1_len >0) &&
  210.     (memcmp(d1,d2,d1_len) == 0) )return true;
  211. return false;
  212. }
  213. int pki_x509req::verify()
  214. {
  215.  EVP_PKEY *pkey = X509_REQ_get_pubkey(request);
  216.  bool x = (X509_REQ_verify(request,pkey) != 0);
  217.  EVP_PKEY_free(pkey);
  218.  openssl_error();
  219.  return x;
  220. }
  221. pki_key *pki_x509req::getPubKey()
  222. {
  223.  EVP_PKEY *pkey = X509_REQ_get_pubkey(request);
  224.  pki_key *key = new pki_key(pkey);
  225.  openssl_error();
  226.  return key;
  227. }
  228. pki_key *pki_x509req::getKey()
  229. {
  230. return privkey;
  231. }
  232. bool pki_x509req::setKey(pki_key *key)
  233. {
  234. bool ret = false;
  235. if (!privkey && key) {
  236. CERR( "KEY COUNT UP");
  237. key->incUcount();
  238. ret=true;
  239. }
  240. privkey = key;
  241. return ret;
  242. }