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

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: db_x509.cpp,v 1.31 2003/01/06 19:35:50 chris Exp $
  48.  *
  49.  */                           
  50. #include "db_x509.h"
  51. db_x509::db_x509(DbEnv *dbe, string DBfile, QListView *l, db_key *keyl)
  52. :db_base(dbe, DBfile, "certdb")
  53. {
  54. keylist = keyl;
  55. listView = l;
  56. certicon[0] = loadImg("validcert.png");
  57.         certicon[1] = loadImg("validcertkey.png");
  58.         certicon[2] = loadImg("invalidcert.png");
  59.         certicon[3] = loadImg("invalidcertkey.png");
  60. listView->addColumn(tr("Common Name"));
  61. listView->addColumn(tr("Serial"));
  62. listView->addColumn(tr("not After"));
  63. listView->addColumn(tr("Trust state"));
  64. listView->addColumn(tr("Revokation"));
  65. loadContainer();
  66. updateView();
  67. connect(keyl, SIGNAL(delKey(pki_key *)), this, SLOT(delKey(pki_key *)));
  68. connect(keyl, SIGNAL(newKey(pki_key *)), this, SLOT(newKey(pki_key *)));
  69. }
  70. pki_base *db_x509::newPKI(){
  71. return new pki_x509();
  72. }
  73. pki_x509 *db_x509::findSigner(pki_x509 *client)
  74. {
  75.         pki_x509 *signer;
  76. if ((signer = client->getSigner()) != NULL) return signer;
  77. QListIterator<pki_base> it(container); 
  78. if (client->verify(client)) {
  79. CERR("SELF signed");
  80. return signer;
  81. }
  82. for ( ; it.current(); ++it ) {
  83. signer = (pki_x509 *)it.current();
  84. if (client->verify(signer)) {
  85. CERR("SIGNER found");
  86. return signer;
  87. }
  88. }
  89. return NULL;
  90. }
  91. bool db_x509::updateView()
  92. {
  93.         listView->clear();
  94. listView->setRootIsDecorated(true);
  95. pki_x509 *pki;
  96. pki_base *pkib;
  97. pki_x509 *signer;
  98. QListViewItem *parentitem;
  99. QListViewItem *current;
  100. CERR("myupdate");
  101. if ( container.isEmpty() ) return false;
  102. QList<pki_base> mycont = container;
  103. for ( pkib = container.first(); pkib != NULL; pkib = container.next() ) pkib->delPointer();
  104. int f=0;
  105. while (! mycont.isEmpty() ) {
  106. CERR("-----------------------------------------------------------------Round "<< f++);
  107. QListIterator<pki_base> it(mycont); 
  108. for ( ; it.current(); ++it ) {
  109. pki = (pki_x509 *)it.current();
  110. parentitem = NULL;
  111. signer = pki->getSigner();
  112. if ((signer != pki) && (signer != NULL)) // foreign signed
  113. parentitem = (QListViewItem *)signer->getPointer();
  114. if (((parentitem != NULL) || (signer == pki) || (signer == NULL)) && (pki->getPointer() == NULL )) {
  115. // create the listview item
  116. if (parentitem != NULL) {
  117. current = new QListViewItem(parentitem, pki->getDescription().c_str());
  118. CERR("Adding as client: "<<pki->getDescription().c_str());
  119. }
  120. else {
  121. current = new QListViewItem(listView, pki->getDescription().c_str());
  122. CERR("Adding as parent: "<<pki->getDescription().c_str());
  123. }
  124. pki->setPointer(current);
  125. mycont.remove(pki);
  126. updateViewPKI(pki);
  127. it.toFirst();
  128. }
  129. }
  130. }
  131. return true;
  132. }
  133. void db_x509::updateViewPKI(pki_base *pki)
  134. {
  135. db_base::updateViewPKI(pki);
  136. if (! pki) return;
  137. QString truststatus[] = { tr("Not trusted"), tr("Trust inherited"), tr("Always Trusted") };
  138. int pixnum = 0;
  139. QListViewItem *current = (QListViewItem *)pki->getPointer();
  140. if (!current) return;
  141. if (((pki_x509 *)pki)->getKey()) {
  142. pixnum += 1;
  143. }
  144. if (((pki_x509 *)pki)->calcEffTrust() == 0){ 
  145. pixnum += 2;
  146. }
  147. current->setPixmap(0, *certicon[pixnum]);
  148. current->setText(1, ((pki_x509 *)pki)->getDNs(NID_commonName).c_str());
  149. current->setText(2, ((pki_x509 *)pki)->getSerial().c_str() );  
  150. current->setText(3, ((pki_x509 *)pki)->notAfter().c_str() );  
  151. current->setText(4, truststatus[((pki_x509 *)pki)->getTrust() ]);  
  152. current->setText(5, ((pki_x509 *)pki)->revokedAt().c_str());
  153. }
  154. void db_x509::updateViewAll()
  155. {
  156.   pki_x509 *pki;
  157.         QListIterator<pki_base> it(container);
  158.         for ( ; it.current(); ++it ) {
  159.                 pki = (pki_x509 *)it.current();
  160. updateViewPKI(pki);
  161. }
  162. return;
  163. }
  164. QStringList db_x509::getPrivateDesc()
  165. {
  166. pki_x509 *pki;
  167. QStringList x;
  168.         if ( container.isEmpty() ) return x;
  169.         for ( pki = (pki_x509 *)container.first(); pki != 0; pki = (pki_x509 *)container.next() ) {
  170. if (pki->getKey())
  171. x.append(pki->getDescription().c_str());
  172. }
  173. return x;
  174. }
  175. QStringList db_x509::getSignerDesc()
  176. {
  177. pki_x509 *pki;
  178. QStringList x;
  179.         if ( container.isEmpty() ) return x;
  180.         for ( pki = (pki_x509 *)container.first(); pki != 0; pki = (pki_x509 *)container.next() ) {
  181. if (pki->canSign())
  182. x.append(pki->getDescription().c_str());
  183. }
  184. return x;
  185. }
  186. void db_x509::remFromCont(pki_base *pki)
  187. {
  188.         container.remove(pki);
  189.   pki_x509 *pkiit;
  190.         QListIterator<pki_base> it(container);
  191.         for ( ; it.current(); ++it ) {
  192.                 pkiit = (pki_x509 *)it.current();
  193. if (pkiit->getSigner() == pki) {
  194. pkiit->delSigner();
  195. }
  196. }
  197. return;
  198. }
  199. pki_key *db_x509::findKey(pki_x509* cert)
  200. {
  201. pki_key *key = NULL, *refkey = NULL;
  202. if (!cert) return NULL;
  203. if ((key = cert->getKey()) != NULL ) return key;
  204. refkey = cert->getPubKey();
  205. key = (pki_key *)keylist->findPKI(refkey);
  206. if (key && key->isPubKey()) {
  207. key = NULL;
  208. }
  209. if (cert->setKey(key)) keylist->updateViewPKI(key);
  210. if (refkey) delete(refkey);
  211. return key;
  212. }
  213. void db_x509::delKey(pki_key *delkey)
  214. {
  215. pki_x509 *pki;
  216.         if ( container.isEmpty() ) return ;
  217.         for ( pki = (pki_x509 *)container.first(); pki != 0; pki = (pki_x509 *)container.next() ) {
  218. if (pki->getKey() == delkey) {
  219. pki->delKey();
  220. updateViewPKI(pki);
  221. }
  222. }
  223. }
  224. void db_x509::newKey(pki_key *newkey)
  225. {
  226. pki_x509 *pki;
  227. pki_key *refkey;
  228.         if ( container.isEmpty() ) return ;
  229.         for ( pki = (pki_x509 *)container.first(); pki != 0; pki = (pki_x509 *)container.next() ) {
  230. if (!pki->getKey()) { 
  231. refkey = pki->getPubKey();
  232. if (newkey->compare(refkey)) {
  233. if (pki->setKey(newkey)) keylist->updateViewPKI(newkey);
  234. updateViewPKI(pki);
  235. }
  236. delete(refkey);
  237. }
  238. }
  239. }
  240. void db_x509::preprocess()
  241. {
  242. pki_x509 *pki;
  243. CERR("preprocess X509");
  244. if ( container.isEmpty() ) return ;
  245. QListIterator<pki_base> iter(container); 
  246. for ( ; iter.current(); ++iter ) { // find the signer and the key of the certificate...
  247. pki = (pki_x509 *)iter.current();
  248. findSigner(pki);
  249. CERR("Signer of "<< pki->getDescription().c_str());
  250. findKey(pki);
  251. CERR("Key of "<< pki->getDescription().c_str());
  252. }
  253. CERR("Signers and keys done ");
  254. calcEffTrust();
  255. /*
  256. pki_x509 *signer;
  257. while (! mycont.isEmpty() ) {
  258.     QListIterator<pki_base> it(mycont); 
  259.     for (it.toFirst(); it.current(); ++it ) {
  260. int trust = 1; // dont know
  261. pki = (pki_x509 *)it.current();
  262. signer = pki->getSigner();
  263.     CERR << "inloop " << pki->getDescription() <<endl;
  264. if (pki->getTrust() != 1){ // Always trust it or never
  265. trust = pki->getTrust();
  266. }
  267. else if ( signer) { // Trust it, if we trust parent and there is a parent
  268. if (signer == pki) {  // if self signed
  269. trust = 0; // no trust
  270. }
  271. else {
  272. trust = signer->getEffTrust(); // inherit trustment of parent
  273. }
  274. }
  275. else { // we do not trust an unknown signer
  276. trust=0;
  277. }
  278. if (trust != 1) { // trustment deterministic
  279. pki->setEffTrust(trust);
  280. mycont.remove(pki);
  281. it.toFirst();
  282. }
  283.     }
  284. }
  285. return ;
  286. */
  287. }
  288. void db_x509::calcEffTrust()
  289. {
  290. pki_x509 *pki;
  291. CERR("re calc eff trust X509");
  292. if ( container.isEmpty() ) return ;
  293. QListIterator<pki_base> iter(container); 
  294. for ( ; iter.current(); ++iter ) { // find the signer and the key of the certificate...
  295. pki = (pki_x509 *)iter.current();
  296. CERR("CalcTrust for: " << pki->getDescription().c_str());
  297. pki->calcEffTrust();
  298. }
  299. }
  300. void db_x509::insertPKI(pki_base *pki)
  301. {
  302. db_base::insertPKI(pki);
  303. pki_x509 *cert, *x = (pki_x509 *)pki;
  304. findSigner(x);
  305. findKey(x);
  306. for ( cert = (pki_x509 *)container.first(); cert != 0; cert = (pki_x509 *)container.next() ) {
  307. cert->verify(x);
  308. }
  309. calcEffTrust();
  310. updateView();
  311. keylist->updateView();
  312. }
  313. void db_x509::assignClients(pki_crl *crl)
  314. {
  315. if (!crl) return;
  316. pki_x509 *issuer = crl->getIssuer();
  317. pki_x509 *cert = NULL;
  318. if (!issuer) return;
  319.         for ( cert = (pki_x509 *)container.first(); cert != 0; cert = (pki_x509 *)container.next() ) {
  320. if ((cert->getSigner() == issuer) && (cert->isRevoked())) {
  321. crl->addRevoked(cert);
  322. }
  323. }
  324. }
  325. void db_x509::writeAllCerts(QString fname, bool onlyTrusted)
  326. {
  327. pki_x509 *cert = NULL;
  328.         for ( cert = (pki_x509 *)container.first(); cert != 0; cert = (pki_x509 *)container.next() ) {
  329. if (onlyTrusted && cert->getTrust() != 2) continue;
  330. cert->writeCert(fname.latin1(),true,true);
  331. }
  332. }
  333. int db_x509::searchSerial(pki_x509 *signer)
  334. {
  335. if (!signer) return 0;
  336. int serial = signer->getCaSerial();
  337. int oserial = serial, myserial =0;
  338. pki_x509 *cert = NULL;
  339.         for ( cert = (pki_x509 *)container.first(); cert != 0; cert = (pki_x509 *)container.next() ) {
  340. if (cert->getSigner() == signer)  {
  341. sscanf(cert->getSerial().c_str(), "%x", &myserial);
  342. if (myserial >= serial) {
  343. serial = myserial + 1;
  344. }
  345. }
  346. }
  347. if (oserial < serial) return serial;
  348. return 0;
  349. }