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

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: MainWindowX509.cpp,v 1.72 2003/01/06 19:35:46 chris Exp $ 
  48.  *
  49.  */                           
  50. #include "MainWindow.h"
  51. void MainWindow::newCert()
  52. {
  53. NewX509 *dlg = new NewX509(this, NULL, keys, reqs, certs, temps, certImg, nsImg );
  54. dlg->setCert();
  55. if (dlg->exec()) {
  56. newCert(dlg);
  57. }
  58. delete dlg;
  59. }
  60. void MainWindow::newCert(pki_temp *templ)
  61. {
  62. NewX509 *dlg = new NewX509(this, NULL, keys, reqs, certs, temps, certImg, nsImg );
  63. if (templ) {
  64. dlg->defineTemplate(templ);
  65. }
  66. dlg->setCert();
  67. if (dlg->exec()) {
  68. newCert(dlg);
  69. }
  70. delete dlg;
  71. }
  72. void MainWindow::newCert(pki_x509req *req)
  73. {
  74. NewX509 *dlg = new NewX509(this, NULL, keys, reqs, certs, temps, certImg, nsImg );
  75. if (req) {
  76. dlg->defineRequest(req);
  77. }
  78. dlg->setCert();
  79. if (dlg->exec()) {
  80. newCert(dlg);
  81. }
  82. delete dlg;
  83. }
  84. void MainWindow::newCert(NewX509 *dlg)
  85. {
  86. pki_x509 *cert = NULL;
  87. pki_x509 *signcert = NULL;
  88. pki_x509req *req = NULL;
  89. pki_key *signkey = NULL, *clientkey = NULL;
  90. int serial = 42; // :-)
  91. bool tempReq=false;
  92. int i, x, days;
  93. string cont="", subAltName="", issAltName="", constraints="",
  94. keyuse="", keyuse1="", pathstr="", certTypeStr = "";
  95. char *ekeyusage[]= {"serverAuth","clientAuth","codeSigning","emailProtection",
  96. "timeStamping","msCodeInd","msCodeCom",
  97. "msCTLSign","msSGC","msEFS","nsSGC"};
  98. char *keyusage[] ={"digitalSignature", "nonRepudiation", "keyEncipherment",
  99. "dataEncipherment", "keyAgreement", "keyCertSign",
  100. "cRLSign", "encipherOnly", "decipherOnly"};
  101. char *certTypeList[] = { "client", "server", "email", "objsign",
  102.  "sslCA", "emailCA", "objCA" };
  103. QListBoxItem *item;
  104.     try {
  105. // Step 1 - Subject and key
  106. if (!dlg->fromReqCB->isChecked()) {
  107.     clientkey = (pki_key *)keys->getSelectedPKI(dlg->keyList->currentText().latin1());
  108.     string cn = dlg->commonName->text().latin1();
  109.     string c = dlg->countryName->text().latin1();
  110.     string l = dlg->localityName->text().latin1();
  111.     string st = dlg->stateOrProvinceName->text().latin1();
  112.     string o = dlg->organisationName->text().latin1();
  113.     string ou = dlg->organisationalUnitName->text().latin1();
  114.     string email = dlg->emailAddress->text().latin1();
  115.     string desc = dlg->description->text().latin1();
  116.     tempReq = true;
  117.     req = new pki_x509req(clientkey, cn,c,l,st,o,ou,email,desc,"");
  118. }
  119. else {
  120.     // A PKCS#10 Request was selected 
  121.     req = (pki_x509req *)reqs->getSelectedPKI(dlg->reqList->currentText().latin1());
  122.     if (opensslError(req)) return;
  123.     clientkey = req->getKey();
  124. }
  125. // Step 2 - select Signing
  126. if (dlg->foreignSignRB->isChecked()) {
  127. signcert = (pki_x509 *)certs->getSelectedPKI(dlg->certList->currentText().latin1());
  128. signkey = signcert->getKey();
  129. // search for serial in database
  130. }
  131. else {
  132. signkey = clientkey;
  133. bool ok;
  134. serial = dlg->serialNr->text().toInt(&ok);
  135. if (!ok) serial = 0;
  136. }
  137. // Step 3 - Choose the Date and all the V3 extensions
  138. // Date handling
  139. x = dlg->validNumber->text().toInt();
  140. days = dlg->validRange->currentItem();
  141. if (days == 1) x *= 30;
  142. if (days == 2) x *= 365;
  143. // increase serial here
  144. if (dlg->foreignSignRB->isChecked()) {
  145. serial = signcert->getIncCaSerial();
  146. // get own serial to avoid having the same
  147. int sigser;
  148. sscanf(signcert->getSerial().c_str(), "%x", &sigser);
  149. if (serial == sigser) { // FIXME: anybody tell me the string method for this ?
  150. serial = signcert->getIncCaSerial(); // just take the next one
  151. }
  152. certs->updatePKI(signcert);  // not so pretty ....
  153. CERR("serial is: " << serial );
  154. }
  155. // initially create cert 
  156. cert = new pki_x509(req->getDescription(), clientkey, req, signcert, x, serial);
  157. if (!signcert) signcert=cert;
  158. if (cert->resetTimes(signcert) > 0) {
  159. if (QMessageBox::information(this,tr(XCA_TITLE),
  160. tr("The validity times for the certificate need to get adjusted to not exceed those of the signer"),
  161. tr("Continue creation"), tr("Abort")
  162. ))
  163. throw errorEx("");
  164. }
  165. // handle extensions
  166. // basic constraints
  167. if (dlg->bcCritical->isChecked()) constraints = "critical,";
  168. constraints +="CA:";
  169. constraints += dlg->basicCA->currentText().latin1();
  170. pathstr = dlg->basicPath->text().latin1();
  171. if (pathstr.length()>0) {
  172. constraints += ", pathlen:";
  173. constraints += pathstr;
  174. }
  175. cert->addV3ext(NID_basic_constraints, constraints);
  176. // Subject Key identifier
  177. if (dlg->subKey->isChecked()) {
  178. string subkey="hash";
  179. cert->addV3ext(NID_subject_key_identifier, subkey);
  180. CERR( subkey );
  181. }
  182. // Authority Key identifier
  183. if (dlg->authKey->isChecked()) {
  184. string authkey="keyid:always,issuer:always";
  185. cert->addV3ext(NID_authority_key_identifier, authkey);
  186. CERR( authkey );
  187. }
  188.  
  189. // key usage
  190. for (i=0; (item = dlg->keyUsage->item(i)); i++) {
  191. if (item->selected()){
  192. addStr(keyuse, keyusage[i]);
  193. }
  194. }
  195. if (keyuse.length() > 0) {
  196. keyuse1 = keyuse;
  197. if (dlg->kuCritical->isChecked()) keyuse1 = "critical, " +keyuse;
  198. cert->addV3ext(NID_key_usage, keyuse1);
  199. CERR( "KeyUsage:" <<keyuse1);
  200. }
  201. // extended key usage
  202. keyuse=""; keyuse1="";
  203. for (i=0; (item = dlg->ekeyUsage->item(i)); i++) {
  204. if (item->selected()){
  205. addStr(keyuse, ekeyusage[i]);
  206. }
  207. }
  208. if (keyuse.length() > 0) {
  209. keyuse1 = keyuse;
  210. if (dlg->ekuCritical->isChecked()) keyuse1 = "critical, " +keyuse;
  211. cert->addV3ext(NID_ext_key_usage, keyuse1);
  212. CERR( "Extended Key Usage:" <<keyuse1 );
  213. }
  214. // STEP 4
  215. // Subject Alternative name
  216. cont = "";
  217. cont = dlg->subAltName->text().latin1();
  218. if (dlg->subAltCp->isChecked()) {
  219. if (req->getDN(NID_pkcs9_emailAddress).length() == 0) {
  220. if (QMessageBox::information(this,tr(XCA_TITLE),
  221.    tr("You requested to copy the subject E-Mail address but it is empty !"),
  222.    tr("Continue creation"), tr("Abort")
  223. ))
  224. throw errorEx("");
  225. }
  226. else {
  227. subAltName = "email:copy";
  228. }
  229. }
  230. if (cont.length() > 0){
  231. addStr(subAltName,cont.c_str());
  232. }
  233. if (subAltName.length() > 0) {
  234. CERR( "SubAltName:" << subAltName);
  235. cert->addV3ext(NID_subject_alt_name, subAltName);
  236. }
  237. cont = "";
  238. cont = dlg->issAltName->text().latin1();
  239. // issuer alternative name
  240. if (dlg->issAltCp->isChecked()) {
  241. if (!signcert->hasSubAltName()) {
  242. if (QMessageBox::information(this,tr(XCA_TITLE),
  243.    tr("You requested to copy the issuer alternative name but it is empty !"),
  244.    tr("Continue creation"), tr("Abort")
  245. ))
  246. throw errorEx("");
  247. }
  248. else {
  249. issAltName = "issuer:copy";
  250. }
  251. }
  252. if (cont.length() > 0){
  253. addStr(issAltName,cont.c_str());
  254. }
  255. if (issAltName.length() > 0) {
  256. CERR("IssAltName:" << issAltName);
  257. cert->addV3ext(NID_issuer_alt_name, issAltName);
  258. }
  259. // CRL distribution points
  260. if (!dlg->crlDist->text().isEmpty()) {
  261. CERR("CRL dist. Point: "<<  dlg->crlDist->text().latin1() );
  262. cert->addV3ext(NID_crl_distribution_points, dlg->crlDist->text().latin1());
  263. }
  264. // Step 5
  265. // Nestcape extensions 
  266. for (i=0; (item = dlg->nsCertType->item(i)); i++) {
  267. if (item->selected()){
  268. addStr(certTypeStr, certTypeList[i]);
  269. }
  270. }
  271. cert->addV3ext(NID_netscape_cert_type, certTypeStr);
  272. cert->addV3ext(NID_netscape_base_url, dlg->nsBaseUrl->text().latin1());
  273. cert->addV3ext(NID_netscape_revocation_url, dlg->nsRevocationUrl->text().latin1());
  274. cert->addV3ext(NID_netscape_ca_revocation_url, dlg->nsCARevocationUrl->text().latin1());
  275. cert->addV3ext(NID_netscape_renewal_url, dlg->nsRenewalUrl->text().latin1());
  276. cert->addV3ext(NID_netscape_ca_policy_url, dlg->nsCaPolicyUrl->text().latin1());
  277. cert->addV3ext(NID_netscape_ssl_server_name, dlg->nsSslServerName->text().latin1());
  278. cert->addV3ext(NID_netscape_comment, dlg->nsComment->text().latin1());
  279. // and finally sign the request 
  280. cert->sign(signkey);
  281. CERR( "SIGNED");
  282. insertCert(cert);
  283. CERR("inserted");
  284. if (tempReq && req) delete(req);
  285. CERR("Dialog deleted" );
  286. keys->updateView();
  287. return;
  288.     }
  289.     catch (errorEx &err) {
  290. Error(err);
  291.     }
  292. }
  293. void MainWindow::addStr(string &str, const  char *add)
  294. {
  295. string sadd = add;
  296. if (sadd.length() == 0) return;
  297. if (str.length() > 0 ) {
  298. str += ", ";
  299. }
  300. str += add;
  301. }
  302. void MainWindow::extendCert()
  303. {
  304. pki_x509 *oldcert = NULL, *signer = NULL, *newcert =NULL;
  305. pki_key *signkey = NULL;
  306. int serial, days, x;
  307. try {
  308. CertExtend_UI *dlg = new CertExtend_UI(this, NULL, true);
  309. dlg->image->setPixmap(*certImg);
  310. if (!dlg->exec()) {
  311. delete dlg;
  312. return;
  313. }
  314. oldcert = (pki_x509 *)certs->getSelectedPKI();
  315. if (!oldcert || !(signer = oldcert->getSigner()) || !(signkey = signer->getKey()) || signkey->isPubKey()) return;
  316. newcert = new pki_x509(oldcert);
  317. serial = signer->getIncCaSerial();
  318. // get signers own serial to avoid having the same
  319. if (serial == atoi(signer->getSerial().c_str())) { // FIXME: anybody tell me the string method for this ?
  320. serial = signer->getIncCaSerial(); // just take the next one
  321. }
  322. certs->updatePKI(signer);  // not so pretty ....
  323. CERR("serial is: " << serial );
  324. // Date handling
  325. x = dlg->validNumber->text().toInt();
  326. days = dlg->validRange->currentItem();
  327. if (days == 1) x *= 30;
  328. if (days == 2) x *= 365;
  329. // change date and serial
  330. newcert->setSerial(serial);
  331. newcert->setDates(x); // now and now + x days
  332. if (newcert->resetTimes(signer) > 0) {
  333. if (QMessageBox::information(this,tr(XCA_TITLE),
  334. tr("The validity times for the certificate need to get adjusted to not exceed those of the signer"),
  335. tr("Continue creation"), tr("Abort")
  336. ))
  337. throw errorEx("");
  338. }
  339. // and finally sign the request 
  340. newcert->sign(signkey);
  341. CERR( "SIGNED");
  342. insertCert(newcert);
  343. CERR("inserted");
  344. delete dlg;
  345. }
  346. catch (errorEx &err) {
  347. Error(err);
  348. }
  349. }
  350. void MainWindow::showDetailsCert()
  351. {
  352. pki_x509 *cert = (pki_x509 *)certs->getSelectedPKI();
  353.         showDetailsCert(cert);
  354. }
  355. void MainWindow::showDetailsCert(QListViewItem *item)
  356. {
  357. string cert = item->text(0).latin1();
  358.         showDetailsCert((pki_x509 *)certs->getSelectedPKI(cert));
  359. }
  360. bool MainWindow::showDetailsCert(pki_x509 *cert, bool import)
  361. {
  362. if (!cert) return false;
  363. if (opensslError(cert)) return false;
  364.     try {
  365. CertDetail_UI *dlg = new CertDetail_UI(this,0,true);
  366. dlg->image->setPixmap(*certImg);
  367. dlg->descr->setText(cert->getDescription().c_str());
  368. dlg->setCaption(tr(XCA_TITLE));
  369. // examine the key
  370. pki_key *key= cert->getKey();
  371. if (key)
  372.      if (key->isPrivKey()) {
  373. dlg->privKey->setText(key->getDescription().c_str());
  374.        dlg->privKey->setDisabled(false);
  375.      }
  376. // examine the signature
  377. if ( cert->getSigner() == NULL) {
  378. dlg->verify->setText(tr("SIGNER UNKNOWN"));
  379. }
  380. else if ( cert->compare(cert->getSigner()) ) {
  381. dlg->verify->setText(tr("SELF SIGNED"));
  382. }
  383. else {
  384. dlg->verify->setText(cert->getSigner()->getDescription().c_str());
  385. }
  386. // check trust state
  387. if (cert->getEffTrust() == 0) {
  388.        dlg->verify->setDisabled(true);
  389. }
  390. CERR( cert->getEffTrust() );
  391. // the serial
  392. dlg->serialNr->setText(cert->getSerial().c_str());
  393. // details of subject
  394. string land = cert->getDNs(NID_countryName);
  395. string land1 = cert->getDNs(NID_stateOrProvinceName);
  396. if (land != "" && land1 != "")
  397. land += " / " +land1;
  398. else
  399. land+=land1;
  400. dlg->dnCN->setText(cert->getDNs(NID_commonName).c_str() );
  401. dlg->dnC->setText(land.c_str());
  402. dlg->dnL->setText(cert->getDNs(NID_localityName).c_str());
  403. dlg->dnO->setText(cert->getDNs(NID_organizationName).c_str());
  404. dlg->dnOU->setText(cert->getDNs(NID_organizationalUnitName).c_str());
  405. dlg->dnEmail->setText(cert->getDNs(NID_pkcs9_emailAddress).c_str());
  406. // same for issuer....
  407. land = cert->getDNi(NID_countryName);
  408. land1 = cert->getDNi(NID_stateOrProvinceName);
  409. if (land != "" && land1 != "")
  410. land += " / " +land1;
  411. else
  412. land+=land1;
  413. dlg->dnCN_2->setText(cert->getDNi(NID_commonName).c_str() );
  414. dlg->dnC_2->setText(land.c_str());
  415. dlg->dnL_2->setText(cert->getDNi(NID_localityName).c_str());
  416. dlg->dnO_2->setText(cert->getDNi(NID_organizationName).c_str());
  417. dlg->dnOU_2->setText(cert->getDNi(NID_organizationalUnitName).c_str());
  418. dlg->dnEmail_2->setText(cert->getDNi(NID_pkcs9_emailAddress).c_str());
  419. dlg->notBefore->setText(cert->notBefore().c_str());
  420. dlg->notAfter->setText(cert->notAfter().c_str());
  421. // validation of the Date
  422. if (cert->checkDate() == -1) {
  423. dlg->dateValid->setText(tr("Not valid"));
  424.        dlg->dateValid->setDisabled(true);
  425. }
  426. if (cert->checkDate() == +1) {
  427. dlg->dateValid->setText(tr("Not valid"));
  428.        dlg->dateValid->setDisabled(true);
  429. }
  430. string revdate = cert->revokedAt();
  431. if (revdate != "") {
  432. dlg->dateValid->setText(tr("Revoked: ")+ revdate.c_str());
  433.        dlg->dateValid->setDisabled(true);
  434. }
  435. // the fingerprints
  436. dlg->fpMD5->setText(cert->fingerprint(EVP_md5()).c_str());
  437. dlg->fpSHA1->setText(cert->fingerprint(EVP_sha1()).c_str());
  438. // V3 extensions
  439. dlg->v3Extensions->setText(cert->printV3ext().c_str());
  440. // rename the buttons in case of import 
  441. if (import) {
  442. dlg->but_ok->setText(tr("Import"));
  443. dlg->but_cancel->setText(tr("Discard"));
  444. }
  445. // show it to the user...
  446. if (dlg->exec()) {
  447. string ndesc = dlg->descr->text().latin1();
  448. if (ndesc != cert->getDescription()) {
  449. certs->renamePKI(cert, ndesc);
  450. }
  451. delete dlg;
  452. return true;
  453. }
  454. delete dlg;
  455. return false;
  456.     }
  457.     catch (errorEx &err) {
  458.     Error(err);
  459.     }
  460.     return false;
  461. }
  462. void MainWindow::deleteCert()
  463. {
  464.     try {
  465. pki_x509 *cert = (pki_x509 *)certs->getSelectedPKI();
  466. if (!cert) return;
  467. if (cert->getSigner() && cert->getSigner() != cert && cert->getSigner()->canSign()) {
  468. QMessageBox::information(this,tr(XCA_TITLE),
  469. tr("It is actually not a good idea to delete a cert that was signed by you") +":n'" + 
  470. QString::fromLatin1(cert->getDescription().c_str()) + "'n" ,
  471. tr("Ok") );
  472. }
  473. if (QMessageBox::information(this,tr(XCA_TITLE),
  474. tr("Really want to delete the Certificate") +":n'" + 
  475. QString::fromLatin1(cert->getDescription().c_str()) + "'n" ,
  476. tr("Delete"), tr("Cancel") )
  477. ) return;
  478. pki_key *pkey = cert->getKey();
  479. certs->deletePKI(cert);
  480. if (pkey) keys->updateViewPKI(pkey);
  481.     }
  482.     catch (errorEx &err) {
  483.     Error(err);
  484.     }
  485. }
  486. void MainWindow::loadCert()
  487. {
  488. QStringList filt;
  489. filt.append(tr("Certificates ( *.pem *.der *.crt *.cer)")); 
  490. filt.append(tr("PKCS#12 Certificates ( *.p12 )")); 
  491. //filt.append(tr("PKCS#7 Signatures ( *.p7s )")); 
  492. filt.append(tr("All files ( *.* )"));
  493. QStringList slist;
  494. QString s="";
  495. QFileDialog *dlg = new QFileDialog(this,0,true);
  496. dlg->setCaption(tr("Certificate import"));
  497. dlg->setFilters(filt);
  498. dlg->setMode( QFileDialog::ExistingFiles );
  499. setPath(dlg);
  500. if (dlg->exec()) {
  501. slist = dlg->selectedFiles();
  502. newPath(dlg);
  503. }
  504. delete dlg;
  505. for ( QStringList::Iterator it = slist.begin(); it != slist.end(); ++it ) {
  506. s = *it;
  507. s = QDir::convertSeparators(s);
  508. try {
  509. pki_x509 *cert = new pki_x509(s.latin1());
  510. insertCert(cert);
  511. keys->updateViewPKI(cert->getKey());
  512. }
  513. catch (errorEx &err) {
  514. Error(err);
  515. }
  516. }
  517. }
  518. void MainWindow::loadPKCS12()
  519. {
  520. pki_pkcs12 *pk12;
  521. pki_x509 *acert;
  522. pki_key *akey;
  523. QStringList filt;
  524. filt.append(tr("PKCS#12 Certificates ( *.p12 )")); 
  525. filt.append(tr("All files ( *.* )"));
  526. QStringList slist;
  527. QString s="";
  528. QFileDialog *dlg = new QFileDialog(this,0,true);
  529. dlg->setCaption(tr("Certificate import"));
  530. dlg->setFilters(filt);
  531. dlg->setMode( QFileDialog::ExistingFiles );
  532. setPath(dlg);
  533. if (dlg->exec()) {
  534. slist = dlg->selectedFiles();
  535. newPath(dlg);
  536. }
  537. delete dlg;
  538. for ( QStringList::Iterator it = slist.begin(); it != slist.end(); ++it ) {
  539. s = *it;
  540. s = QDir::convertSeparators(s);
  541. try {
  542. pk12 = new pki_pkcs12(s.latin1(), &MainWindow::passRead);
  543. akey = pk12->getKey();
  544. acert = pk12->getCert();
  545. insertKey(akey);
  546. insertCert(acert);
  547. for (int i=0; i<pk12->numCa(); i++) {
  548. acert = pk12->getCa(i);
  549. insertCert(acert);
  550. }
  551. delete pk12;
  552. keys->updateView();
  553. }
  554. catch (errorEx &err) {
  555. Error(err);
  556. }
  557. }
  558. /* insert with asking.....
  559. if (showDetailsKey(akey, true)) {
  560. insertKey(akey);
  561. }
  562. else {
  563. delete(akey);
  564. }
  565. if (showDetailsCert(acert,true)) {
  566. insertCert(acert);
  567. }
  568. else {
  569. delete(acert);
  570. }
  571. for (int i=0; i<pk12->numCa(); i++) {
  572. acert = pk12->getCa(i);
  573. if (showDetailsCert(acert, true)) {
  574. insertCert(acert);
  575. }
  576. else {
  577. delete(acert);
  578. }
  579. }
  580. */
  581. }
  582. void MainWindow::loadPKCS7()
  583. {
  584. pki_pkcs7 *pk7;
  585. pki_x509 *acert;
  586. QStringList filt;
  587. filt.append(tr("PKCS#7 data ( *.p7s *.p7m )")); 
  588. filt.append(tr("All files ( *.* )"));
  589. QStringList slist;
  590. QString s="";
  591. QFileDialog *dlg = new QFileDialog(this,0,true);
  592. dlg->setCaption(tr("Certificate import"));
  593. dlg->setFilters(filt);
  594. dlg->setMode( QFileDialog::ExistingFiles );
  595. setPath(dlg);
  596. if (dlg->exec()) {
  597. slist = dlg->selectedFiles();
  598. newPath(dlg);
  599. }
  600. delete dlg;
  601. for ( QStringList::Iterator it = slist.begin(); it != slist.end(); ++it ) {
  602. s = *it;
  603. s = QDir::convertSeparators(s);
  604. try {
  605. pk7 = new pki_pkcs7("");
  606. pk7->readP7(s.latin1());
  607. for (int i=0; i<pk7->numCert(); i++) {
  608. acert = pk7->getCert(i);
  609. insertCert(acert);
  610. }
  611. delete pk7;
  612. keys->updateView();
  613. }
  614. catch (errorEx &err) {
  615. Error(err);
  616. }
  617. }
  618. }
  619. void MainWindow::insertCert(pki_x509 *cert)
  620. {
  621.     try {
  622. pki_x509 *oldcert = (pki_x509 *)certs->findPKI(cert);
  623. if (oldcert) {
  624.    QMessageBox::information(this,tr(XCA_TITLE),
  625. tr("The certificate already exists in the database as") +":n'" +
  626. QString::fromLatin1(oldcert->getDescription().c_str()) + 
  627. "'n" + tr("and so it was not imported"), "OK");
  628.    delete(cert);
  629.    return;
  630. }
  631. CERR( "insertCert: inserting" );
  632. certs->insertPKI(cert);
  633.     }
  634.     catch (errorEx &err) {
  635.     Error(err);
  636.     }
  637.     int serial;
  638.     if (cert->getSigner() != cert && cert->getSigner()) {
  639. sscanf(cert->getSerial().c_str(), "%x", &serial);
  640. CERR("OTHER SIGNER" << serial);
  641.      if (serial >= cert->getSigner()->getCaSerial()) {
  642.     QMessageBox::information(this,tr(XCA_TITLE),
  643. tr("The certificate-serial is higher than the next serial of the signer it will be set to ") +
  644. QString::number(serial + 1), "OK");
  645.     cert->getSigner()->setCaSerial(serial+1);
  646. }
  647.     }
  648.     serial = certs->searchSerial(cert);
  649.     if ( serial > 0) {
  650. QMessageBox::information(this,tr(XCA_TITLE),
  651. tr("The certificate CA serial is lower than the highest serial of one signed certificate it will be set to ") +
  652. QString::number(serial ), "OK");
  653. cert->setCaSerial(serial);
  654.     }
  655.     certs->updatePKI(cert);
  656. }
  657. void MainWindow::writeCert()
  658. {
  659. QStringList filt;
  660. pki_x509 *crt = (pki_x509 *)certs->getSelectedPKI();
  661. pki_x509 *oldcrt = NULL;
  662. if (!crt) return;
  663. pki_key *privkey = crt->getKey();
  664. ExportCert *dlg = new ExportCert((crt->getDescription() + ".crt").c_str(),
  665.   (privkey && privkey->isPrivKey()));
  666. if (!dlg->exec()) {
  667. delete dlg;
  668. return;
  669. }
  670. QString fname = dlg->filename->text();
  671.         if (fname == "") {
  672.                 delete dlg;
  673.                 return;
  674.         }
  675. try {
  676.     switch (dlg->exportFormat->currentItem()) {
  677. case 0: // PEM
  678. crt->writeCert(fname.latin1(),true,false);
  679. break;
  680. case 1: // PEM with chain
  681. while(crt && crt != oldcrt) {
  682. crt->writeCert(fname.latin1(),true,true);
  683. oldcrt = crt;
  684. crt = crt->getSigner();
  685. }
  686. break;
  687. case 2: // PEM all trusted Certificates
  688. certs->writeAllCerts(fname,true);
  689. break;
  690. case 3: // PEM all Certificates
  691. certs->writeAllCerts(fname,false);
  692. break;
  693. case 4: // DER
  694. crt->writeCert(fname.latin1(),false,false);
  695. break;
  696. case 5: // P12
  697. writePKCS12(fname,false);
  698. break;
  699. case 6: // P12 + cert chain
  700. writePKCS12(fname,true);
  701. break;
  702.     }
  703. }
  704. catch (errorEx &err) {
  705. Error(err);
  706. }
  707. delete dlg;
  708. }
  709. void MainWindow::writePKCS12(QString s, bool chain)
  710. {
  711. QStringList filt;
  712.     try {
  713. pki_x509 *cert = (pki_x509 *)certs->getSelectedPKI();
  714. if (!cert) return;
  715. pki_key *privkey = cert->getKey();
  716. if (!privkey || privkey->isPubKey()) {
  717. QMessageBox::warning(this,tr(XCA_TITLE),
  718.                  tr("There was no key found for the Certificate: ") +
  719. QString::fromLatin1(cert->getDescription().c_str()) );
  720. return; 
  721. }
  722. if (s.isEmpty()) return;
  723. s = QDir::convertSeparators(s);
  724. pki_pkcs12 *p12 = new pki_pkcs12(cert->getDescription(), cert, privkey, &MainWindow::passWrite);
  725. pki_x509 *signer = cert->getSigner();
  726. int cnt =0;
  727. while ((signer != NULL ) && (signer != cert) && chain) {
  728. CERR("SIGNER:"<<(int)signer);
  729. p12->addCaCert(signer);
  730. CERR( "signer: " << ++cnt );
  731. cert=signer;
  732. signer=signer->getSigner();
  733. }
  734. CERR("start writing" );
  735. p12->writePKCS12(s.latin1());
  736. delete p12;
  737.     }
  738.     catch (errorEx &err) {
  739.     Error(err);
  740.     }
  741. }
  742. void MainWindow::signP7()
  743. {
  744. QStringList filt;
  745.     try {
  746. pki_x509 *cert = (pki_x509 *)certs->getSelectedPKI();
  747. if (!cert) return;
  748. pki_key *privkey = cert->getKey();
  749. if (!privkey || privkey->isPubKey()) {
  750. QMessageBox::warning(this,tr(XCA_TITLE),
  751.                  tr("There was no key found for the Certificate: ") +
  752. QString::fromLatin1(cert->getDescription().c_str()) );
  753. return; 
  754. }
  755.         filt.append("All Files ( *.* )");
  756. QString s="";
  757. QStringList slist;
  758. QFileDialog *dlg = new QFileDialog(this,0,true);
  759. dlg->setCaption(tr("Import Certificate signing request"));
  760. dlg->setFilters(filt);
  761. dlg->setMode( QFileDialog::ExistingFiles );
  762. setPath(dlg);
  763. if (dlg->exec()) {
  764. slist = dlg->selectedFiles();
  765. newPath(dlg);
  766.         }
  767. delete dlg;
  768. pki_pkcs7 * p7 = new pki_pkcs7("");
  769. for ( QStringList::Iterator it = slist.begin(); it != slist.end(); ++it ) {
  770. s = *it;
  771. s = QDir::convertSeparators(s);
  772. p7->signFile(cert, s.latin1());
  773. p7->writeP7((s + ".p7s").latin1(), true);
  774. }
  775. delete p7;
  776.     }
  777.     catch (errorEx &err) {
  778. Error(err);
  779.     }
  780. }
  781. void MainWindow::encryptP7()
  782. {
  783. QStringList filt;
  784.     try {
  785. pki_x509 *cert = (pki_x509 *)certs->getSelectedPKI();
  786. if (!cert) return;
  787. pki_key *privkey = cert->getKey();
  788. if (!privkey || privkey->isPubKey()) {
  789. QMessageBox::warning(this,tr(XCA_TITLE),
  790.                  tr("There was no key found for the Certificate: ") +
  791. QString::fromLatin1(cert->getDescription().c_str()) );
  792. return; 
  793. }
  794.         filt.append("All Files ( *.* )");
  795. QString s="";
  796. QStringList slist;
  797. QFileDialog *dlg = new QFileDialog(this,0,true);
  798. dlg->setCaption(tr("Import Certificate signing request"));
  799. dlg->setFilters(filt);
  800. dlg->setMode( QFileDialog::ExistingFiles );
  801. setPath(dlg);
  802. if (dlg->exec()) {
  803. slist = dlg->selectedFiles();
  804. newPath(dlg);
  805.         }
  806. delete dlg;
  807. pki_pkcs7 * p7 = new pki_pkcs7("");
  808. for ( QStringList::Iterator it = slist.begin(); it != slist.end(); ++it ) {
  809. MARK
  810. s = *it;
  811. MARK
  812. s = QDir::convertSeparators(s);
  813. MARK
  814. p7->encryptFile(cert, s.latin1());
  815. MARK
  816. p7->writeP7((s + ".p7m").latin1(), true);
  817. MARK
  818. }
  819. delete p7;
  820. MARK
  821.     }
  822.     catch (errorEx &err) {
  823. Error(err);
  824.     }
  825. }
  826. void MainWindow::showPopupCert(QListViewItem *item, const QPoint &pt, int x) {
  827. CERR( "popup Cert");
  828. QPopupMenu *menu = new QPopupMenu(this);
  829. QPopupMenu *subCa = new QPopupMenu(this);
  830. QPopupMenu *subP7 = new QPopupMenu(this);
  831. QPopupMenu *subExport = new QPopupMenu(this);
  832. int itemExtend, itemRevoke, itemTrust, itemCA, itemTemplate, itemReq, itemP7;
  833. bool canSign, parentCanSign, hasTemplates, hasPrivkey;
  834. if (!item) {
  835. menu->insertItem(tr("New Certificate"), this, SLOT(newCert()));
  836. menu->insertItem(tr("Import"), this, SLOT(loadCert()));
  837. menu->insertItem(tr("Import PKCS#12"), this, SLOT(loadPKCS12()));
  838. menu->insertItem(tr("Import from PKCS#7"), this, SLOT(loadPKCS7()));
  839. }
  840. else {
  841. pki_x509 *cert = (pki_x509 *)certs->getSelectedPKI(item->text(0).latin1());
  842. menu->insertItem(tr("Rename"), this, SLOT(startRenameCert()));
  843. menu->insertItem(tr("Show Details"), this, SLOT(showDetailsCert()));
  844. menu->insertItem(tr("Export"), subExport);
  845. subExport->insertItem(tr("File"), this, SLOT(writeCert()));
  846. itemReq = subExport->insertItem(tr("Request"), this, SLOT(toRequest()));
  847. menu->insertItem(tr("Delete"), this, SLOT(deleteCert()));
  848. itemTrust = menu->insertItem(tr("Trust"), this, SLOT(setTrust()));
  849. menu->insertSeparator();
  850. itemCA = menu->insertItem(tr("CA"), subCa);
  851. subCa->insertItem(tr("Serial"), this, SLOT(setSerial()));
  852. subCa->insertItem(tr("CRL days"), this, SLOT(setCrlDays()));
  853. itemTemplate = subCa->insertItem(tr("Signing Template"), this, SLOT(setTemplate()));
  854. subCa->insertItem(tr("Generate CRL"), this, SLOT(genCrl()));
  855. itemP7 = menu->insertItem(tr("PKCS#7"), subP7);
  856. subP7->insertItem(tr("Sign"), this, SLOT(signP7()));
  857. subP7->insertItem(tr("Encrypt"), this, SLOT(encryptP7()));
  858. menu->insertSeparator();
  859. itemExtend = menu->insertItem(tr("Renewal"), this, SLOT(extendCert()));
  860. if (cert) {
  861. if (cert->isRevoked()) {
  862. itemRevoke = menu->insertItem(tr("Unrevoke"), this, SLOT(unRevoke()));
  863. menu->setItemEnabled(itemTrust, false);
  864. }
  865. else
  866. itemRevoke = menu->insertItem(tr("Revoke"), this, SLOT(revoke()));
  867. parentCanSign = (cert->getSigner() && cert->getSigner()->canSign() && (cert->getSigner() != cert));
  868. canSign = cert->canSign();
  869. hasTemplates = temps->getDesc().count() > 0 ;
  870. hasPrivkey = cert->getKey();
  871. }
  872. menu->setItemEnabled(itemExtend, parentCanSign);
  873. menu->setItemEnabled(itemRevoke, parentCanSign);
  874. menu->setItemEnabled(itemCA, canSign);
  875. subExport->setItemEnabled(itemReq, hasPrivkey);
  876. menu->setItemEnabled(itemP7, hasPrivkey);
  877. subCa->setItemEnabled(itemTemplate, hasTemplates);
  878. }
  879. menu->exec(pt);
  880. delete menu;
  881. delete subCa;
  882. delete subP7;
  883. delete subExport;
  884. return;
  885. }
  886. void MainWindow::renameCert(QListViewItem *item, int col, const QString &text)
  887. {
  888. if (col != 0) return;
  889. try {
  890. pki_base *pki = certs->getSelectedPKI(item);
  891. string txt =  text.latin1();
  892. certs->renamePKI(pki, txt);
  893. }
  894. catch (errorEx &err) {
  895. Error(err);
  896. }
  897. }
  898. void MainWindow::setTrust()
  899. {
  900. pki_x509 *cert = (pki_x509 *)certs->getSelectedPKI();
  901. if (!cert) return;
  902. TrustState_UI *dlg = new TrustState_UI(this,0,true);
  903. int state, newstate;
  904. state = cert->getTrust();
  905. if (cert->getSigner() == cert) {
  906. if (state == 1) state = 0;
  907. dlg->trust1->setDisabled(true);
  908. }
  909. if (state == 0 ) dlg->trust0->setChecked(true);
  910. if (state == 1 ) dlg->trust1->setChecked(true);
  911. if (state == 2 ) dlg->trust2->setChecked(true);
  912. dlg->certName->setText(cert->getDescription().c_str());
  913. if (dlg->exec()) {
  914. if (dlg->trust0->isChecked()) newstate = 0;
  915. if (dlg->trust1->isChecked()) newstate = 1;
  916. if (dlg->trust2->isChecked()) newstate = 2;
  917. if (newstate!=state) {
  918. cert->setTrust(newstate);
  919. certs->updatePKI(cert);
  920. certs->updateViewAll();
  921. }
  922. }
  923. delete dlg;
  924. }
  925. void MainWindow::toRequest()
  926. {
  927. pki_x509 *cert = (pki_x509 *)certs->getSelectedPKI();
  928. if (!cert) return;
  929. try {
  930. pki_x509req *req = new pki_x509req(cert);
  931. insertReq(req);
  932. }
  933. catch (errorEx &err) {
  934. Error(err);
  935. }
  936. }
  937. void MainWindow::revoke()
  938. {
  939. pki_x509 *cert = (pki_x509 *)certs->getSelectedPKI();
  940. if (!cert) return;
  941. cert->setRevoked(true);
  942. CERR("setRevoked..." );
  943. certs->updatePKI(cert);
  944. CERR("updatePKI done");
  945. certs->updateViewAll();
  946. CERR("view updated");
  947. }
  948. void MainWindow::unRevoke()
  949. {
  950. pki_x509 *cert = (pki_x509 *)certs->getSelectedPKI();
  951. if (!cert) return;
  952. cert->setRevoked(false);
  953. certs->updatePKI(cert);
  954. certs->updateViewAll();
  955. }
  956. void MainWindow::setSerial()
  957. {
  958. pki_x509 *cert = (pki_x509 *)certs->getSelectedPKI();
  959. if (!cert) return;
  960. int serial = cert->getCaSerial();
  961. bool ok;
  962. int nserial = QInputDialog::getInteger (tr(XCA_TITLE),
  963. tr("Please enter the new Serial for signing"),
  964. serial, serial, 2147483647, 1, &ok, this );
  965. if (ok && nserial > serial) {
  966. cert->setCaSerial(nserial);
  967. certs->updatePKI(cert);
  968. }
  969. }
  970. void MainWindow::setCrlDays()
  971. {
  972. pki_x509 *cert = (pki_x509 *)certs->getSelectedPKI();
  973. if (!cert) return;
  974. int crlDays = cert->getCrlDays();
  975. bool ok;
  976. int nCrlDays = QInputDialog::getInteger (tr(XCA_TITLE),
  977. tr("Please enter the CRL renewal periode in days"),
  978. crlDays, crlDays, 365, 1, &ok, this );
  979. if (ok && (crlDays != nCrlDays)) {
  980. cert->setCrlDays(nCrlDays);
  981. certs->updatePKI(cert);
  982. }
  983. }
  984. void MainWindow::setTemplate()
  985. {
  986. pki_x509 *cert = (pki_x509 *)certs->getSelectedPKI();
  987. if (!cert) return;
  988. QString templ = cert->getTemplate().c_str();
  989. QStringList tempList = temps->getDesc();
  990. unsigned int i, sel=0;
  991. bool ok;
  992. for (i=0; i<tempList.count(); i++) {
  993. if (tempList[i] == templ) {
  994. sel = i;
  995. }
  996. }
  997. QString nTempl = QInputDialog::getItem (tr(XCA_TITLE),
  998. tr("Please select the default Template for signing"),
  999. tempList, sel, false, &ok, this );
  1000. if (ok && (templ != nTempl)) {
  1001. cert->setTemplate(nTempl.latin1());
  1002. certs->updatePKI(cert);
  1003. }
  1004. }
  1005. void MainWindow::genCrl() 
  1006. {
  1007. QStringList filt;
  1008. pki_x509 *cert = (pki_x509 *)certs->getSelectedPKI();
  1009. if (!cert) return;
  1010. if (cert->getKey()->isPubKey()) return;
  1011. filt.append(tr("CRLs ( *.crl )")); 
  1012. filt.append(tr("All Files ( *.* )"));
  1013. QString s="";
  1014. QFileDialog *dlg = new QFileDialog(this,0,true);
  1015. dlg->setCaption(tr("CRL export"));
  1016. dlg->setFilters(filt);
  1017. dlg->setMode( QFileDialog::AnyFile );
  1018. dlg->setSelection( (cert->getDescription() + ".crl").c_str() );
  1019. if (dlg->exec())
  1020. s = dlg->selectedFile();
  1021. delete dlg;
  1022. if (s.isEmpty()) return;
  1023. s = QDir::convertSeparators(s);
  1024. try {
  1025. pki_crl *crl = new pki_crl(cert->getDescription(), cert);
  1026. certs->assignClients(crl);
  1027. crl->addV3ext(NID_authority_key_identifier,"keyid,issuer");
  1028. //crl->addV3ext(NID_issuer_alt_name,"issuer:copy");
  1029. crl->sign(cert->getKey());
  1030. crl->writeCrl(s.latin1());
  1031. cert->setLastCrl(crl->getDate());
  1032. certs->updatePKI(cert);
  1033. CERR( "CRL done, completely");
  1034. delete(crl);
  1035.   CERR("crl deleted");
  1036. }
  1037. catch (errorEx &err) {
  1038. Error(err);
  1039. }
  1040. }
  1041. void MainWindow::startRenameCert()
  1042. {
  1043. try {
  1044. #ifdef qt3
  1045. pki_base *pki = certs->getSelectedPKI();
  1046. if (!pki) return;
  1047. QListViewItem *item = (QListViewItem *)pki->getPointer();
  1048. item->startRename(0);
  1049. #else
  1050. renamePKI(certs);
  1051. #endif
  1052. }
  1053. catch (errorEx &err) {
  1054. Error(err);
  1055. }
  1056. }