📄 certview.cpp
字号:
/* vi: set sw=4 ts=4: *//* * Copyright (C) 2001 Christian Hohnstaedt. * * All rights reserved. * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the author nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * This program links to software with different licenses from: * * http://www.openssl.org which includes cryptographic software * written by Eric Young (eay@cryptsoft.com)" * * http://www.sleepycat.com * * http://www.trolltech.com * * * * http://www.hohnstaedt.de/xca * email: christian@hohnstaedt.de * * $Id: CertView.cpp,v 1.35 2004/05/25 20:31:40 chris2511 Exp $ * */ #include "CertView.h"#include "widgets/MainWindow.h"#include <qcheckbox.h>#include <qlabel.h>#include <qcombobox.h>#include <qradiobutton.h>#include <qmessagebox.h>#include <qpopupmenu.h>#include <qtextview.h>#include <qpushbutton.h>#include <qinputdialog.h>#include "widgets/CertExtend.h"#include "widgets/ExportCert.h"#include "widgets/CertDetail.h"#include "widgets/KeyDetail.h"#include "ui/TrustState.h"#include "widgets/ExportTinyCA.h"#include "widgets/validity.h"#include "widgets/clicklabel.h"#include "lib/pki_pkcs12.h"#include "lib/pki_pkcs7.h"#ifdef WIN32#include <direct.h> // to define mkdir function#include <windows.h> // to define mkdir function#else#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#endifCertView::CertView(QWidget * parent, const char * name, WFlags f) :XcaListView(parent, name, f){ addColumn(tr("Internal name")); addColumn(tr("Common name")); addColumn(tr("Serial")); addColumn(tr("not After")); addColumn(tr("Trust state")); addColumn(tr("Revocation")); viewState=1; // Tree View} void CertView::newItem(){ CHECK_DB NewX509 *dlg = new NewX509(this, NULL, true); emit connNewX509(dlg); dlg->setCert(); dlg->defineSigner((pki_x509*)getSelected()); if (dlg->exec()) { newCert(dlg); } delete dlg;}void CertView::newCert(pki_x509req *req){ NewX509 *dlg = new NewX509(this, NULL, true); emit connNewX509(dlg); dlg->setCert(); dlg->defineRequest(req); dlg->defineSigner((pki_x509*)getSelected()); if (dlg->exec()) { newCert(dlg); } delete dlg;}void CertView::newCert(pki_temp *req){ NewX509 *dlg = new NewX509(this, NULL, true); emit connNewX509(dlg); dlg->setCert(); dlg->defineTemplate(req); if (dlg->exec()) { newCert(dlg); } delete dlg;}void CertView::newCert(NewX509 *dlg){ pki_x509 *cert = NULL; pki_x509 *signcert = NULL; pki_x509req *req = NULL; pki_key *signkey = NULL, *clientkey = NULL, *tempkey = NULL; a1int serial; a1time notBefore, notAfter; x509name subject; QString intname; CHECK_DB try { // Step 1 - Subject and key if (!dlg->fromReqCB->isChecked()) { clientkey = dlg->getSelectedKey(); subject = dlg->getX509name(); intname = dlg->description->text(); } else { // A PKCS#10 Request was selected req = dlg->getSelectedReq(); if (Error(req)) return; clientkey = req->getRefKey(); if (clientkey == NULL) { clientkey = req->getPubKey(); tempkey = clientkey; } subject = req->getSubject(); intname = req->getIntName(); } // initially create cert cert = new pki_x509(); cert->setIntName(intname); cert->setSubject(subject); cert->setPubKey(clientkey); // Step 2 - select Signing if (dlg->foreignSignRB->isChecked()) { signcert = dlg->getSelectedSigner(); if (Error(signcert)) return; serial = signcert->getIncCaSerial(); signkey = signcert->getRefKey(); cert->setTrust(1); } else { signcert = cert; signkey = clientkey; bool ok; serial = dlg->serialNr->text().toInt(&ok); if (!ok) serial = 0; cert->setTrust(2); } dlg->initCtx(cert, signcert); // if we can not sign if (! signkey || signkey->isPubKey()) { throw errorEx(tr("The key you selected for signing is not a private one.")); } // set the issuers name cert->setIssuer(signcert->getSubject()); cert->setSerial(serial); // Step 3 - Choose the Date // Date handling cert->setNotBefore( dlg->notBefore->getDate() ); cert->setNotAfter( dlg->notAfter->getDate() ); if (cert->resetTimes(signcert) > 0) { if (QMessageBox::information(this,tr(XCA_TITLE), tr("The validity times for the certificate need to get adjusted to not exceed those of the signer"), tr("Continue creation"), tr("Abort") )) throw errorEx(""); } // STEP 4 // handle extensions cert->addV3ext(dlg->getBasicConstraints()); cert->addV3ext(dlg->getSubKeyIdent()); cert->addV3ext(dlg->getAuthKeyIdent()); cert->addV3ext(dlg->getKeyUsage()); cert->addV3ext(dlg->getEkeyUsage()); cert->addV3ext(dlg->getSubAltName()); cert->addV3ext(dlg->getIssAltName()); cert->addV3ext(dlg->getCrlDist()); cert->addV3ext(dlg->getAuthInfAcc()); cert->addV3ext(dlg->getCertPol()); extList ne = dlg->getNetscapeExt(); int m = ne.count(); for (int i=0; i<m; i++) cert->addV3ext(ne[i]); // and finally sign the request cert->sign(signkey, dlg->getHashAlgo()); db->insert(cert); db->updatePKI(signcert); if (tempkey != NULL) delete(tempkey); updateView(); return; } // EOF try catch (errorEx &err) { Error(err); delete cert; if (tempkey != NULL) delete(tempkey); } }void CertView::extendCert(){ pki_x509 *oldcert = NULL, *signer = NULL, *newcert =NULL; pki_key *signkey = NULL; a1time time; a1int serial; emit init_database(); try { CertExtend *dlg = new CertExtend(this, NULL, true); if (!dlg->exec()) { delete dlg; return; } oldcert = (pki_x509 *)getSelected(); if (!oldcert || !(signer = oldcert->getSigner()) || !(signkey = signer->getRefKey()) || signkey->isPubKey()) return; newcert = new pki_x509(oldcert); serial = signer->getIncCaSerial(); // get signers own serial to avoid having the same if (serial == signer->getSerial()) { serial = signer->getIncCaSerial(); // just take the next one } db->updatePKI(signer); // FIXME::not so pretty .... // change date and serial newcert->setSerial(serial); newcert->setNotBefore(dlg->notBefore->getDate()); newcert->setNotAfter(dlg->notAfter->getDate()); if (newcert->resetTimes(signer) > 0) { if (QMessageBox::information(this,tr(XCA_TITLE), tr("The validity times for the certificate need to get adjusted to not exceed those of the signer"), tr("Continue creation"), tr("Abort") )) throw errorEx(""); } // and finally sign the request newcert->sign(signkey, oldcert->getDigest()); db->insert(newcert); delete dlg; } catch (errorEx &err) { Error(err); if (newcert) delete newcert; } updateView();} void CertView::showItem(pki_base *item, bool import){ if (!item) return; CertDetail *dlg=NULL; try { dlg = new CertDetail(this,0,true); dlg->setCert((pki_x509 *)item); connect( dlg->privKey, SIGNAL( doubleClicked(QString) ), this, SLOT( showKey(QString) )); connect( dlg->signCert, SIGNAL( doubleClicked(QString) ), this, SLOT( showItem(QString) )); dlg->exec(); } catch (errorEx &err) { Error(err); } if (dlg) delete dlg; return ;}void CertView::deleteItem(){ try { pki_x509 *cert = (pki_x509 *)getSelected(); if (!cert) return; if (cert->getSigner() && cert->getSigner() != cert && cert->getSigner()->canSign()) { QMessageBox::information(this,tr(XCA_TITLE), tr("It is actually not a good idea to delete a cert that was signed by you") +":\n'" + cert->getIntName() + "'\n" , tr("Ok") ); } deleteItem_default(tr("The certificate"), tr("is going to be deleted")); } catch (errorEx &err) { Error(err); }}void CertView::load(){ load_cert l; load_default(l);}void CertView::loadPKCS12(){ load_pkcs12 l; load_default(l);}void CertView::loadPKCS7(){ load_pkcs7 l; load_default(l);}#define P7_ONLY 0#define P7_CHAIN 1#define P7_TRUSTED 2#define P7_ALL 3void CertView::store(){ QStringList filt; pki_x509 *crt = (pki_x509 *)getSelected(); pki_x509 *oldcrt = NULL; emit init_database(); if (!crt) return; pki_key *privkey = crt->getRefKey(); ExportCert *dlg = new ExportCert((crt->getIntName() + ".crt"), (privkey && privkey->isPrivKey()), MainWindow::getPath(), crt->tinyCAfname() ); dlg->image->setPixmap(*MainWindow::certImg); int dlgret = dlg->exec(); if (!dlgret) { delete dlg; return; } QString fname = dlg->filename->text(); if (fname == "") { delete dlg; return; } try { switch (dlg->exportFormat->currentItem()) { case 0: // PEM crt->writeCert(fname,true,false); break; case 1: // PEM with chain while(crt && crt != oldcrt) { crt->writeCert(fname,true,true); oldcrt = crt; crt = crt->getSigner(); } break; case 2: // PEM all trusted Certificates MainWindow::certs->writeAllCerts(fname,true); break; case 3: // PEM all Certificates MainWindow::certs->writeAllCerts(fname,false); break; case 4: // DER crt->writeCert(fname,false,false); break; case 5: // P7 lonely writePKCS7(fname, P7_ONLY); break; case 6: // P7 writePKCS7(fname, P7_CHAIN); break; case 7: // P7 writePKCS7(fname, P7_TRUSTED); break; case 8: // P7 writePKCS7(fname, P7_ALL); break; case 9: // P12 writePKCS12(fname,false); break; case 10: // P12 + cert chain writePKCS12(fname,true); break; } } catch (errorEx &err) { Error(err); } delete dlg;}void CertView::writePKCS12(QString s, bool chain){ QStringList filt; try { pki_x509 *cert = (pki_x509 *)getSelected(); if (!cert) return; pki_key *privkey = cert->getRefKey(); if (!privkey || privkey->isPubKey()) { QMessageBox::warning(this,tr(XCA_TITLE), tr("There was no key found for the Certificate: ") + cert->getIntName() ); return; } if (s.isEmpty()) return; s = QDir::convertSeparators(s); pki_pkcs12 *p12 = new pki_pkcs12(cert->getIntName(), cert, privkey, &MainWindow::passWrite); pki_x509 *signer = cert->getSigner(); while ((signer != NULL ) && (signer != cert) && chain) { p12->addCaCert(signer); cert=signer; signer=signer->getSigner(); } p12->writePKCS12(s); delete p12; } catch (errorEx &err) { Error(err); }}void CertView::writePKCS7(QString s, int type){ pki_pkcs7 *p7 = NULL; QList<pki_base> list; pki_x509 *cert = (pki_x509 *)getSelected(); pki_base *cer; emit init_database(); try { p7 = new pki_pkcs7(""); if ( type == P7_CHAIN ) { while (cert != NULL) { p7->addCert(cert); if (cert->getSigner() == cert) cert = NULL; else cert = cert->getSigner(); } } if ( type == P7_ONLY ) { p7->addCert(cert); } if (type == P7_TRUSTED) { list = db->getContainer(); if (!list.isEmpty()) { for ( cer = list.first(); cer != NULL; cer = list.next() ) { if (((pki_x509*)cer)->getTrust() == 2) p7->addCert((pki_x509 *)cer); } } } if (type == P7_ALL) { list = db->getContainer(); if (!list.isEmpty()) { for ( cer = list.first(); cer != NULL; cer = list.next() ) { p7->addCert((pki_x509 *)cer); } } } p7->writeP7(s, false); } catch (errorEx &err) { Error(err); } if (p7 != NULL ) delete p7; } void CertView::signP7(){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -