diff options
Diffstat (limited to 'kcert')
-rw-r--r-- | kcert/Makefile.am | 18 | ||||
-rw-r--r-- | kcert/kcertpart.cc | 883 | ||||
-rw-r--r-- | kcert/kcertpart.desktop | 99 | ||||
-rw-r--r-- | kcert/kcertpart.h | 139 | ||||
-rw-r--r-- | kcert/kcertpart.rc | 10 |
5 files changed, 1149 insertions, 0 deletions
diff --git a/kcert/Makefile.am b/kcert/Makefile.am new file mode 100644 index 000000000..aad4f2343 --- /dev/null +++ b/kcert/Makefile.am @@ -0,0 +1,18 @@ +INCLUDES= -I$(top_srcdir)/kio/kssl -I$(top_builddir)/kio/kssl -I$(top_srcdir) $(SSL_INCLUDES) $(all_includes) + +kde_module_LTLIBRARIES = libkcertpart.la + +libkcertpart_la_SOURCES = kcertpart.cc + +libkcertpart_la_LDFLAGS = $(KDE_PLUGIN) $(all_libraries) +libkcertpart_la_LIBADD = $(LIB_KPARTS) +libkcertpart_la_DEPENDENCIES = $(LIB_KPARTS) + +libkcertpart_la_METASOURCES = AUTO + +servicedir = $(kde_servicesdir) +service_DATA = kcertpart.desktop + +rcdir = $(kde_datadir)/kcertpart +rc_DATA = kcertpart.rc + diff --git a/kcert/kcertpart.cc b/kcert/kcertpart.cc new file mode 100644 index 000000000..bd3b9f74c --- /dev/null +++ b/kcert/kcertpart.cc @@ -0,0 +1,883 @@ +/* This file is part of the KDE project + * + * Copyright (C) 2001-2003 George Staikos <staikos@kde.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + + +#include "kcertpart.h" +#include <kparts/genericfactory.h> +#include <kinstance.h> +#include <kaboutdata.h> +#include <qframe.h> +#include <klocale.h> +#include <kdebug.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qbutton.h> +#include <qpushbutton.h> +#include <qcombobox.h> +#include <kmessagebox.h> +#include <kpassdlg.h> +#include <ksslall.h> +#include <kopenssl.h> +#include <ksslpemcallback.h> +#include <kfiledialog.h> +#include <kprocess.h> +#include <qtabwidget.h> +#include <kseparator.h> +#include <klistview.h> +#include <kio/kmimemagic.h> +#include <qmultilineedit.h> +#include <qregexp.h> +#include <kcombobox.h> +#include <kparts/browserextension.h> +#include <kparts/browserinterface.h> +#include <kio/kservicetypefactory.h> + +K_EXPORT_COMPONENT_FACTORY( libkcertpart, KParts::GenericFactory<KCertPart> ) + + +KX509Item::KX509Item(KListViewItem *parent, KSSLCertificate *x) : + KListViewItem(parent, 0L) +{ + setup(x); +} + +KX509Item::KX509Item(KListView *parent, KSSLCertificate *x) : + KListViewItem(parent) +{ + setup(x); +} + +void KX509Item::setup(KSSLCertificate *x) { + cert = x; + if (x) { + KSSLX509Map xm(x->getSubject()); + QString OU = "OU"; + QString CN = "CN"; + OU = xm.getValue(OU); + CN = xm.getValue(CN); + OU.replace(QRegExp("\n.*"), ""); + CN.replace(QRegExp("\n.*"), ""); + + if (OU.length() > 0) { + _prettyName = OU; + } + + if (CN.length() > 0) { + if (_prettyName.length() > 0) { + _prettyName += " - "; + } + _prettyName += CN; + } + setText(0, _prettyName); + } else { + setText(0, i18n("Invalid certificate!")); + } +} + + +KX509Item::~KX509Item() +{ + delete cert; +} + + +KPKCS12Item::KPKCS12Item(KListViewItem *parent, KSSLPKCS12 *x) : + KListViewItem(parent, 0L) +{ + cert = x; + if (x) { + KSSLX509Map xm(x->getCertificate()->getSubject()); + QString CN = "CN"; + CN = xm.getValue(CN); + CN.replace(QRegExp("\n.*"), ""); + _prettyName = CN; + setText(0, _prettyName); + } else { + setText(0, i18n("Invalid certificate!")); + } +} + + +KPKCS12Item::~KPKCS12Item() +{ + delete cert; +} + + +class KCertPartPrivate { + public: + KParts::BrowserExtension *browserExtension; +}; + + +KCertPart::KCertPart(QWidget *parentWidget, const char *widgetName, + QObject *parent, const char *name, + const QStringList & /*args*/ ) + : KParts::ReadWritePart(parent, name) { +KInstance *instance = new KInstance("KCertPart"); +QGridLayout *grid; +setInstance(instance); + + +_signers = new KSSLSigners; +// This is a bit confusing now. Here's how it works: +// We create a _frame and split it left/right +// Then we add the ListView to the left and create +// a new frame on the right. We set the main widget +// on the right. + +_p12 = NULL; +_ca = NULL; +_silentImport = false; +d = new KCertPartPrivate; +d->browserExtension = new KParts::BrowserExtension(this); + +_frame = new QFrame(parentWidget, widgetName); +setWidget(_frame); + +_baseGrid = new QGridLayout(_frame, 15, 9, KDialog::marginHint(), + KDialog::spacingHint()); + +_sideList = new KListView(_frame); +_sideList->setRootIsDecorated(true); +_sideList->addColumn(i18n("Certificates")); +_parentCA = new KListViewItem(_sideList, i18n("Signers")); +_parentCA->setExpandable(true); +_sideList->setOpen(_parentCA, true); +_parentP12 = new KListViewItem(_sideList, i18n("Client")); +_parentP12->setExpandable(true); +_sideList->setOpen(_parentP12, true); + +_baseGrid->addMultiCellWidget(_sideList, 0, 13, 0, 1); + +_importAll = new QPushButton(i18n("Import &All"), _frame); +_baseGrid->addMultiCellWidget(_importAll, 14, 14, 0, 1); +connect(_importAll, SIGNAL(clicked()), SLOT(slotImportAll())); + + + +//------------------------------------------------------------------------ +// The PKCS widget +//------------------------------------------------------------------------ +_pkcsFrame = new QFrame(_frame); + +grid = new QGridLayout(_pkcsFrame, 13, 6, KDialog::marginHint(), + KDialog::spacingHint() ); +grid->addMultiCellWidget(new QLabel(i18n("KDE Secure Certificate Import"), _pkcsFrame), 0, 0, 0, 5); +grid->addWidget(new QLabel(i18n("Chain:"), _pkcsFrame), 1, 0); +_p12_chain = new KComboBox(_pkcsFrame); +grid->addMultiCellWidget(_p12_chain, 1, 1, 1, 4); +connect(_p12_chain, SIGNAL(activated(int)), SLOT(slotChain(int))); + +grid->addWidget(new QLabel(i18n("Subject:"), _pkcsFrame), 2, 0); +grid->addWidget(new QLabel(i18n("Issued by:"), _pkcsFrame), 2, 3); +_p12_subject = KSSLInfoDlg::certInfoWidget(_pkcsFrame, QString("")); +_p12_issuer = KSSLInfoDlg::certInfoWidget(_pkcsFrame, QString("")); +grid->addMultiCellWidget(_p12_subject, 3, 6, 0, 2); +grid->addMultiCellWidget(_p12_issuer, 3, 6, 3, 5); + +grid->addWidget(new QLabel(i18n("File:"), _pkcsFrame), 7, 0); +_p12_filenameLabel = new QLabel("", _pkcsFrame); +grid->addWidget(_p12_filenameLabel, 7, 1); +grid->addWidget(new QLabel(i18n("File format:"), _pkcsFrame), 7, 3); +grid->addWidget(new QLabel("PKCS#12", _pkcsFrame), 7, 4); + + +// +// Make the first tab +// +_tabs = new QTabWidget(_pkcsFrame); +grid->addMultiCellWidget(_tabs, 8, 12, 0, 5); + +QFrame *tab = new QFrame(_pkcsFrame); +QGridLayout *tabGrid = new QGridLayout(tab, 4, 5, KDialog::marginHint(), + KDialog::spacingHint() ); +tabGrid->addWidget(new QLabel(i18n("State:"), tab), 0, 0); +_p12_certState = new QLabel("", tab); +tabGrid->addMultiCellWidget(_p12_certState, 0, 0, 1, 4); + +tabGrid->addWidget(new QLabel(i18n("Valid from:"), tab), 1, 0); +_p12_validFrom = new QLabel("", tab); +tabGrid->addMultiCellWidget(_p12_validFrom, 1, 1, 1, 4); + +tabGrid->addWidget(new QLabel(i18n("Valid until:"), tab), 2, 0); +_p12_validUntil = new QLabel("", tab); +tabGrid->addMultiCellWidget(_p12_validUntil, 2, 2, 1, 4); + +tabGrid->addWidget(new QLabel(i18n("Serial number:"), tab), 3, 0); +_p12_serialNum = new QLabel("", tab); +tabGrid->addWidget(_p12_serialNum, 3, 1); +_tabs->addTab(tab, i18n("State")); + + +// +// Make the second tab +// +tab = new QFrame(_pkcsFrame); +tabGrid = new QGridLayout(tab, 4, 5, KDialog::marginHint(), + KDialog::spacingHint() ); +tabGrid->addWidget(new QLabel(i18n("MD5 digest:"), tab), 0, 0); +_p12_digest = new QLabel(tab); +tabGrid->addMultiCellWidget(_p12_digest, 0, 0, 1, 4); +tabGrid->addWidget(new QLabel(i18n("Signature:"), tab), 1, 0); +_p12_sig = new QMultiLineEdit(tab); +tabGrid->addMultiCellWidget(_p12_sig, 1, 3, 1, 4); +_p12_sig->setReadOnly(true); + +_tabs->addTab(tab, i18n("Signature")); + + +// +// Make the third tab +// +tab = new QFrame(_pkcsFrame); +tabGrid = new QGridLayout(tab, 4, 5, KDialog::marginHint(), + KDialog::spacingHint() ); +tabGrid->addWidget(new QLabel(i18n("Public key:"), tab), 0, 0); +_p12_pubkey = new QMultiLineEdit(tab); +tabGrid->addMultiCellWidget(_p12_pubkey, 0, 3, 1, 4); +_p12_pubkey->setReadOnly(true); + + +_tabs->addTab(tab, i18n("Public Key")); + +_pkcsFrame->hide(); + +//------------------------------------------------------------------------ +// The X509 widget +//------------------------------------------------------------------------ +// Note: this is almost identical to the above, but I duplicate it for +// the simple reason that the above has potential to display much +// more information, and this one has potential to display different +// information. +_x509Frame = new QFrame(_frame); + +grid = new QGridLayout(_x509Frame, 12, 6, KDialog::marginHint(), + KDialog::spacingHint() ); +grid->addMultiCellWidget(new QLabel(i18n("KDE Secure Certificate Import"), _x509Frame), 0, 0, 0, 5); + +grid->addWidget(new QLabel(i18n("Subject:"), _x509Frame), 1, 0); +grid->addWidget(new QLabel(i18n("Issued by:"), _x509Frame), 1, 3); +_ca_subject = KSSLInfoDlg::certInfoWidget(_x509Frame, QString("")); +_ca_issuer = KSSLInfoDlg::certInfoWidget(_x509Frame, QString("")); +grid->addMultiCellWidget(_ca_subject, 2, 5, 0, 2); +grid->addMultiCellWidget(_ca_issuer, 2, 5, 3, 5); + +grid->addWidget(new QLabel(i18n("File:"), _x509Frame), 6, 0); +_ca_filenameLabel = new QLabel("", _x509Frame); +grid->addWidget(_ca_filenameLabel, 6, 1); +grid->addWidget(new QLabel(i18n("File format:"), _x509Frame), 6, 3); +grid->addWidget(new QLabel("PEM or DER Encoded X.509", _x509Frame), 6, 4); + + +// +// Make the first tab +// +_tabs = new QTabWidget(_x509Frame); +grid->addMultiCellWidget(_tabs, 7, 11, 0, 5); + +tab = new QFrame(_x509Frame); +tabGrid = new QGridLayout(tab, 4, 5, KDialog::marginHint(), + KDialog::spacingHint() ); +tabGrid->addWidget(new QLabel(i18n("State:"), tab), 0, 0); +_ca_certState = new QLabel("", tab); +tabGrid->addMultiCellWidget(_ca_certState, 0, 0, 1, 4); + +tabGrid->addWidget(new QLabel(i18n("Valid from:"), tab), 1, 0); +_ca_validFrom = new QLabel("", tab); +tabGrid->addMultiCellWidget(_ca_validFrom, 1, 1, 1, 4); + +tabGrid->addWidget(new QLabel(i18n("Valid until:"), tab), 2, 0); +_ca_validUntil = new QLabel("", tab); +tabGrid->addMultiCellWidget(_ca_validUntil, 2, 2, 1, 4); + +tabGrid->addWidget(new QLabel(i18n("Serial number:"), tab), 3, 0); +_ca_serialNum = new QLabel("", tab); +tabGrid->addWidget(_ca_serialNum, 3, 1); +_tabs->addTab(tab, i18n("State")); + + +// +// Make the second tab +// +tab = new QFrame(_x509Frame); +tabGrid = new QGridLayout(tab, 4, 5, KDialog::marginHint(), + KDialog::spacingHint() ); +tabGrid->addWidget(new QLabel(i18n("MD5 digest:"), tab), 0, 0); +_ca_digest = new QLabel(tab); +tabGrid->addMultiCellWidget(_ca_digest, 0, 0, 1, 4); +tabGrid->addWidget(new QLabel(i18n("Signature:"), tab), 1, 0); +_ca_sig = new QMultiLineEdit(tab); +tabGrid->addMultiCellWidget(_ca_sig, 1, 3, 1, 4); +_ca_sig->setReadOnly(true); + +_tabs->addTab(tab, i18n("Signature")); + + +// +// Make the third tab +// +tab = new QFrame(_x509Frame); +tabGrid = new QGridLayout(tab, 4, 5, KDialog::marginHint(), + KDialog::spacingHint() ); +tabGrid->addWidget(new QLabel(i18n("Public key:"), tab), 0, 0); +_ca_pubkey = new QMultiLineEdit(tab); +tabGrid->addMultiCellWidget(_ca_pubkey, 0, 3, 1, 4); +_ca_pubkey->setReadOnly(true); + + +_tabs->addTab(tab, i18n("Public Key")); + +_x509Frame->hide(); + + + + +//------------------------------------------------------------------------ +// The blank widget +//------------------------------------------------------------------------ +_blankFrame = new QFrame(_frame); +grid = new QGridLayout(_blankFrame, 1, 1, KDialog::marginHint(), + KDialog::spacingHint() ); +grid->addMultiCellWidget(new QLabel(i18n("KDE Secure Certificate Import"), _blankFrame), 0, 0, 0, 0); +_blankFrame->show(); + + + +// +// Finish it off +// +_baseGrid->addMultiCellWidget(new KSeparator(KSeparator::HLine, _frame), 13, 13, 2, 8); +_launch = new QPushButton(i18n("&Crypto Manager..."), _frame); +_import = new QPushButton(i18n("&Import"), _frame); +_save = new QPushButton(i18n("&Save..."), _frame); +_done = new QPushButton(i18n("&Done"), _frame); +_baseGrid->addMultiCellWidget(_launch, 14, 14, 4, 5); +_baseGrid->addWidget(_import, 14, 6); +_baseGrid->addWidget(_save, 14, 7); +_baseGrid->addWidget(_done, 14, 8); +connect(_launch, SIGNAL(clicked()), SLOT(slotLaunch())); +connect(_import, SIGNAL(clicked()), SLOT(slotImport())); +connect(_save, SIGNAL(clicked()), SLOT(slotSave())); +connect(_done, SIGNAL(clicked()), SLOT(slotDone())); +_import->setEnabled(false); +_save->setEnabled(false); + + + +_baseGrid->addMultiCellWidget(_pkcsFrame, 0, 12, 2, 8); +_baseGrid->addMultiCellWidget(_x509Frame, 0, 12, 2, 8); +_baseGrid->addMultiCellWidget(_blankFrame, 0, 12, 2, 8); + +connect(_sideList, SIGNAL(selectionChanged(QListViewItem*)), + this, SLOT(slotSelectionChanged(QListViewItem*))); +setReadWrite(true); +} + + +KCertPart::~KCertPart() { + delete _signers; + delete d->browserExtension; + delete d; +} + + +void KCertPart::setReadWrite(bool rw) { + if (!rw) { + _import->setEnabled(false); + _save->setEnabled(false); + } + KParts::ReadWritePart::setReadWrite(rw); +} + + +bool KCertPart::saveFile() { +if (_p12) { + QString certFile = KFileDialog::getSaveFileName(QString::null, "application/x-pkcs12"); + if (certFile.isEmpty()) + return false; + + if (!_p12->toFile(certFile)) { + KMessageBox::sorry(_frame, i18n("Save failed."), i18n("Certificate Import")); + return false; + } + + return true; +} else if (_ca) { + QString certFile = KFileDialog::getSaveFileName(QString::null, "application/x-x509-ca-cert"); + if (certFile.isEmpty()) + return false; + + QByteArray enc; + if (certFile.endsWith("der") || certFile.endsWith("crt")) { + enc = _ca->toDer(); + } else if (certFile.endsWith("netscape")) { + enc = _ca->toNetscape(); + } else { + enc = _ca->toPem(); + } + + QFile of(certFile); + + if (!of.open(IO_WriteOnly) || (unsigned)of.writeBlock(enc) != enc.size()) { + KMessageBox::sorry(_frame, i18n("Save failed."), i18n("Certificate Import")); + return false; + } + + of.flush(); + + return true; +} else { + return false; +} +} + + +bool KCertPart::openFile() { +#ifndef HAVE_SSL + KMessageBox::sorry(_frame, i18n("You do not seem to have compiled KDE with SSL support."), i18n("Certificate Import")); + return false; +#else + +if (QFileInfo(m_file).size() == 0) { + KMessageBox::sorry(_frame, i18n("Certificate file is empty."), i18n("Certificate Import")); + return false; +} + +QString whatType = d->browserExtension->urlArgs().serviceType; +//whatType = KMimeType::findByURL(m_url,0,true)->name(); +if (whatType.isEmpty()) + whatType = KServiceTypeFactory::self()->findFromPattern(m_file)->name(); + +/* + QString blah = "file: " + m_file + + "\nurl: " + m_url.url() + + "\nserviceType: " + d->browserExtension->urlArgs().serviceType + + "\nfactory: " + KServiceTypeFactory::self()->findFromPattern(m_file)->name() + + "\nmimeType: " + KMimeType::findByURL(m_url)->name(); + KMessageBox::information(_frame, blah, "ssl"); + */ + + +emit completed(); + +///////////////////////////////////////////////////////////////////////////// +// x-pkcs12 loading +///////////////////////////////////////////////////////////////////////////// +if (whatType == "application/x-pkcs12") { + QCString pass; + _p12 = KSSLPKCS12::loadCertFile(m_file); + + while (!_p12) { + // try prompting for a password. + int rc = KPasswordDialog::getPassword(pass, i18n("Certificate Password")); + if (rc != KPasswordDialog::Accepted) break; + + _p12 = KSSLPKCS12::loadCertFile(m_file, QString(pass)); + + if (!_p12) { + rc = KMessageBox::warningContinueCancel(_frame, i18n("The certificate file could not be loaded. Try a different password?"), i18n("Certificate Import"),i18n("Try Different")); + if (rc == KMessageBox::Continue) continue; + break; + } + } + + if (!_p12) return false; + + new KPKCS12Item(_parentP12, _p12); + _p12 = NULL; + return true; + ///////////////////////////////////////////////////////////////////////////// + // x-509-ca-cert loading + ///////////////////////////////////////////////////////////////////////////// +} else if (whatType == "application/x-x509-ca-cert" || + whatType == "application/binary-certificate") { + FILE *fp; + bool isPEM = false; + + _ca_filenameLabel->setText(m_file); + + ///////////// UGLY HACK TO GET AROUND OPENSSL PROBLEMS /////////// + if (whatType == "application/x-x509-ca-cert") { + // Check if it is PEM or not + QFile qf(m_file); + qf.open(IO_ReadOnly); + QByteArray theFile = qf.readAll(); + qf.close(); + + const char *signature = "-----BEGIN CERTIFICATE-----"; + theFile[(uint)(qf.size()-1)] = 0; + isPEM = (QCString(theFile.data()).find(signature) >= 0); + } + + fp = fopen(m_file.local8Bit(), "r"); + if (!fp) { + KMessageBox::sorry(_frame, i18n("This file cannot be opened."), i18n("Certificate Import")); + return false; + } + + /* + kdDebug() << "Reading in a file in " + << (isPEM ? "PEM" : "DER") + << " format." << endl; + */ + + if (!isPEM) { + X509 *dx = KOSSL::self()->X509_d2i_fp(fp, NULL); + + if (dx) { + KSSLCertificate *xc = KSSLCertificate::fromX509(dx); + if (xc) { + if (xc->x509V3Extensions().certTypeCA()) + new KX509Item(_parentCA, xc); + else + new KX509Item(_sideList, xc); + fclose(fp); + return true; + } + KOSSL::self()->X509_free(dx); + } + return false; + } + +#define sk_free KOSSL::self()->sk_free +#define sk_num KOSSL::self()->sk_num +#define sk_value KOSSL::self()->sk_value + STACK_OF(X509_INFO) *sx5i = KOSSL::self()->PEM_X509_INFO_read(fp, NULL, KSSLPemCallback, NULL); + + if (!sx5i) { + KMessageBox::sorry(_frame, i18n("This file cannot be opened."), i18n("Certificate Import")); + fclose(fp); + return false; + } + + _ca_filenameLabel->setText(m_file); + for (int i = 0; i < sk_X509_INFO_num(sx5i); i++) { + X509_INFO* x5i = sk_X509_INFO_value(sx5i, i); + if (x5i->x_pkey && x5i->x509) { // a personal cert (like PKCS12) + KSSLCertificate *xc = KSSLCertificate::fromX509(x5i->x509); + new KX509Item(_sideList, xc); + } else if (x5i->x509) { // something else - maybe a CA file + KSSLCertificate *xc = KSSLCertificate::fromX509(x5i->x509); + if (xc->x509V3Extensions().certTypeCA()) + new KX509Item(_parentCA, xc); + else new KX509Item(_sideList, xc); + } else if (x5i->crl) { // a crl + kdDebug() << "Found a CRL..." << endl; + } + } + + sk_X509_INFO_free(sx5i); + +#undef sk_free +#undef sk_num +#undef sk_value + + fclose(fp); + return true; + ///////////////////////////////////////////////////////////////////////////// + // Dunno how to load this + ///////////////////////////////////////////////////////////////////////////// +} else { + QString emsg = i18n("I do not know how to handle this type of file.") + "\n" + whatType; + KMessageBox::sorry(_frame, emsg, i18n("Certificate Import")); + return false; +} +#endif +} + + +void KCertPart::displayPKCS12() { + KSSLCertificate *xc = _p12->getCertificate(); + _p12_filenameLabel->setText(m_file); + displayPKCS12Cert(xc); + _p12_certState->setText(KSSLCertificate::verifyText(_p12->validate())); + + // Set the chain if it's there + if (xc->chain().depth() > 1) { + QPtrList<KSSLCertificate> cl = xc->chain().getChain(); + int cnt = 0; + _p12_chain->setEnabled(true); + _p12_chain->clear(); + _p12_chain->insertItem(i18n("0 - Site Certificate")); + for (KSSLCertificate *c = cl.first(); c != 0; c = cl.next()) { + KSSLX509Map map(c->getSubject()); + _p12_chain->insertItem(QString::number(++cnt)+" - "+map.getValue("CN")); + } + _p12_chain->setCurrentItem(0); + } else { + _p12_chain->clear(); + _p12_chain->setEnabled(false); + } +} + + +void KCertPart::displayCACert(KSSLCertificate *c) { + // We have the file, lets work with it. + _ca_subject->setValues(c->getSubject()); + _ca_issuer->setValues(c->getIssuer()); + + // Set the valid period + QPalette cspl = _ca_validFrom->palette(); + if (QDateTime::currentDateTime() < c->getQDTNotBefore()) { + cspl.setColor(QColorGroup::Foreground, QColor(196,33,21)); + } else { + cspl.setColor(QColorGroup::Foreground, QColor(42,153,59)); + } + _ca_validFrom->setPalette(cspl); + _ca_validFrom->setText(c->getNotBefore()); + + cspl = _ca_validUntil->palette(); + if (QDateTime::currentDateTime() > c->getQDTNotAfter()) { + cspl.setColor(QColorGroup::Foreground, QColor(196,33,21)); + } else { + cspl.setColor(QColorGroup::Foreground, QColor(42,153,59)); + } + _ca_validUntil->setPalette(cspl); + _ca_validUntil->setText(c->getNotAfter()); + + _ca_serialNum->setText(c->getSerialNumber()); + cspl = _ca_certState->palette(); + if (!c->isValid()) { + cspl.setColor(QColorGroup::Foreground, QColor(196,33,21)); + } else { + cspl.setColor(QColorGroup::Foreground, QColor(42,153,59)); + } + _ca_certState->setPalette(cspl); + _ca_certState->setText(KSSLCertificate::verifyText(c->validate())); + + _ca_pubkey->setText(c->getPublicKeyText()); + _ca_digest->setText(c->getMD5DigestText()); + _ca_sig->setText(c->getSignatureText()); +} + + + +void KCertPart::displayPKCS12Cert(KSSLCertificate *c) { + // We have the file, lets work with it. + _p12_subject->setValues(c->getSubject()); + _p12_issuer->setValues(c->getIssuer()); + + // Set the valid period + QPalette cspl = _p12_validFrom->palette(); + if (QDateTime::currentDateTime() < c->getQDTNotBefore()) { + cspl.setColor(QColorGroup::Foreground, QColor(196,33,21)); + } else { + cspl.setColor(QColorGroup::Foreground, QColor(42,153,59)); + } + _p12_validFrom->setPalette(cspl); + _p12_validFrom->setText(c->getNotBefore()); + + cspl = _p12_validUntil->palette(); + if (QDateTime::currentDateTime() > c->getQDTNotAfter()) { + cspl.setColor(QColorGroup::Foreground, QColor(196,33,21)); + } else { + cspl.setColor(QColorGroup::Foreground, QColor(42,153,59)); + } + _p12_validUntil->setPalette(cspl); + _p12_validUntil->setText(c->getNotAfter()); + + _p12_serialNum->setText(c->getSerialNumber()); + cspl = _p12_certState->palette(); + if (!c->isValid()) { + cspl.setColor(QColorGroup::Foreground, QColor(196,33,21)); + } else { + cspl.setColor(QColorGroup::Foreground, QColor(42,153,59)); + } + _p12_certState->setPalette(cspl); + _p12_certState->setText(KSSLCertificate::verifyText(c->validate())); + + _p12_pubkey->setText(c->getPublicKeyText()); + _p12_digest->setText(c->getMD5DigestText()); + _p12_sig->setText(c->getSignatureText()); +} + + + +void KCertPart::slotChain(int c) { + if (c == 0) { + displayPKCS12Cert(_p12->getCertificate()); + _p12_certState->setText(KSSLCertificate::verifyText(_p12->validate())); + } else { + displayPKCS12Cert(_p12->getCertificate()->chain().getChain().at(c-1)); + } +} + + +void KCertPart::slotImport() { + if (_p12) { + KSimpleConfig cfg("ksslcertificates", false); + + if (cfg.hasGroup(_p12->getCertificate()->getSubject())) { + QString msg = _curName + "\n" + i18n("A certificate with that name already exists. Are you sure that you wish to replace it?"); + int rc= KMessageBox::warningContinueCancel(_frame, msg, i18n("Certificate Import"),i18n("Replace")); + if (rc == KMessageBox::Cancel) { + return; + } + } + + cfg.setGroup(_p12->getCertificate()->getSubject()); + cfg.writeEntry("PKCS12Base64", _p12->toString()); + cfg.writeEntry("Password", ""); + cfg.sync(); + if (!_silentImport) + KMessageBox::information(_frame, i18n("Certificate has been successfully imported into KDE.\nYou can manage your certificate settings from the KDE Control Center."), i18n("Certificate Import")); + } else if (_ca) { + KConfig cfg("ksslcalist", true, false); + if (cfg.hasGroup(_ca->getSubject())) { + QString msg = _curName + "\n" + i18n("A certificate with that name already exists. Are you sure that you wish to replace it?"); + int rc= KMessageBox::warningContinueCancel(_frame, msg, i18n("Certificate Import"),i18n("Replace")); + if (rc == KMessageBox::Cancel) { + return; + } + } + _signers->addCA(_ca->toString(), + _ca->x509V3Extensions().certTypeSSLCA(), + _ca->x509V3Extensions().certTypeEmailCA(), + _ca->x509V3Extensions().certTypeCodeCA()); + if (!_silentImport) + _signers->regenerate(); + + if (!_silentImport) + KMessageBox::information(_frame, i18n("Certificate has been successfully imported into KDE.\nYou can manage your certificate settings from the KDE Control Center."), i18n("Certificate Import")); + } +} + + +void KCertPart::slotSave() { + saveFile(); +} + + +void KCertPart::slotDone() { + KParts::BrowserInterface *iface = d->browserExtension->browserInterface(); + iface->callMethod("goHistory(int)", -1); +} + + +void KCertPart::slotLaunch() { +KShellProcess p; +p << "kcmshell" << "crypto"; +p.start(KProcess::DontCare); +} + + +void KCertPart::slotSelectionChanged(QListViewItem *x) { + KX509Item *x5i = dynamic_cast<KX509Item*>(x); + KPKCS12Item *p12i = dynamic_cast<KPKCS12Item*>(x); + _p12 = NULL; + _ca = NULL; + if (x && x->parent() == _parentCA) { + if (!x5i) { + return; + } + x5i->cert->revalidate(); + _blankFrame->hide(); + _pkcsFrame->hide(); + _x509Frame->show(); + _ca = x5i->cert; + _import->setEnabled(true); + _save->setEnabled(true); + _curName = x5i->_prettyName; + displayCACert(_ca); + } else if (x && x->parent() == NULL && x->rtti() == 1) { + if (!x5i) { + return; + } + x5i->cert->revalidate(); + _blankFrame->hide(); + _pkcsFrame->hide(); + _x509Frame->show(); + _ca = x5i->cert; + _import->setEnabled(false); + _save->setEnabled(false); + _curName = x5i->_prettyName; + displayCACert(_ca); + } else if (x && x->parent() == _parentP12) { + if (!p12i) { + return; + } + p12i->cert->revalidate(); + _blankFrame->hide(); + _x509Frame->hide(); + _pkcsFrame->show(); + _p12 = p12i->cert; + _import->setEnabled(true); + _save->setEnabled(true); + _curName = p12i->_prettyName; + displayPKCS12(); + } else { + _pkcsFrame->hide(); + _x509Frame->hide(); + _blankFrame->show(); + _import->setEnabled(false); + _save->setEnabled(false); + _curName = ""; + } +} + + +void KCertPart::slotImportAll() { +KSSLPKCS12 *p12Save = _p12; +KSSLCertificate *caSave = _ca; +QString curNameSave = _curName; + +_p12 = NULL; +_ca = NULL; +_silentImport = true; + +for (KPKCS12Item *t = dynamic_cast<KPKCS12Item*>(_parentP12->firstChild()); + t; + t = dynamic_cast<KPKCS12Item*>(t->nextSibling())) { + if (t) { + _p12 = t->cert; + _curName = t->_prettyName; + } + slotImport(); +} +_p12 = NULL; + +for (KX509Item *t = dynamic_cast<KX509Item*>(_parentCA->firstChild()); + t; + t = dynamic_cast<KX509Item*>(t->nextSibling())) { + if (t) { + _ca = t->cert; + _curName = t->_prettyName; + } + slotImport(); +} +_ca = NULL; + +_signers->regenerate(); +_silentImport = false; +_p12 = p12Save; +_ca = caSave; +_curName = curNameSave; +KMessageBox::information(_frame, i18n("Certificates have been successfully imported into KDE.\nYou can manage your certificate settings from the KDE Control Center."), i18n("Certificate Import")); +} + + +KAboutData *KCertPart::createAboutData() +{ + return new KAboutData("KCertPart", I18N_NOOP("KDE Certificate Part"), "1.0"); +} + +#include "kcertpart.moc" + diff --git a/kcert/kcertpart.desktop b/kcert/kcertpart.desktop new file mode 100644 index 000000000..9e1c9c872 --- /dev/null +++ b/kcert/kcertpart.desktop @@ -0,0 +1,99 @@ +[Desktop Entry] +Type=Service +Comment=Embeddable Personal Certificate Manager +Comment[af]=Inlegbare Persoonlike Sertifikaat Bestuurder +Comment[ar]=مدير شهادات اعتماد شخصي قابل للدمج +Comment[az]=Hopdurulabilən Şəxsi Vəsiqə İdarəçisi +Comment[be]=Унутраны кіраўнік асабістых сертыфікатаў +Comment[bg]=Вграден личен мениджър за удостоверения +Comment[bn]=অভ্যন্তরীণ ব্যক্তিগত সার্টিফিকেট ম্যানেজার +Comment[bs]=Umetljivi upravljač ličnim certifikatima +Comment[ca]=Gestor encastable de certificats personals +Comment[cs]=Pohltitelný správce osobních certifikátů +Comment[csb]=Swój menedżera certëfikatów +Comment[cy]=Rheolydd Tystysgrif Bersonol Mewnadeiladadwy +Comment[da]=Indlejrbar personlig certifikathåndtering +Comment[de]=Einbettungsfähige persönliche Zertifikatsverwaltung +Comment[el]=Ενσωματώσιμος διαχειριστής προσωπικών πιστοποιητικών +Comment[eo]=Enkorpigebla administrilo por personaj atestoj +Comment[es]=Administrador empotrable de certificados personales +Comment[et]=Põimitav personaalsete sertifikaatide haldur +Comment[eu]=Ziurtagiri pertsonalen kudeatzaile kapsulagarria +Comment[fa]=مدیر گواهینامۀ شخصی نهفته +Comment[fi]=Upotettava henkilökohtaisten sertifikaattien hallintatyökalu +Comment[fr]=Gestionnaire de certificats personnels intégrable +Comment[fy]=Yn te sluten Persoanlik-sertifikaatbehearder +Comment[ga]=Bainisteoir Teastas Pearsanta Inleabaithe +Comment[gl]=Xestor Persoal de Certificados Incrustábel +Comment[he]=מנהל תעודות אישי בר־הטבעה +Comment[hi]=अंतर्निहित निजी सर्टिफिकेट प्रबंधक +Comment[hr]=Ugradivi upravitelj osobnim potvrdama +Comment[hsb]=Integrujomny Personal Certificate Manager +Comment[hu]=Beágyazható személyes tanúsítványkezelő +Comment[id]=Manajer Sertifikat Pribadi Tersisipkan +Comment[is]=Ívefjanlegur einkaskírteina-stjóri +Comment[it]=Gestione integrabile dei certificati personali +Comment[ja]=埋め込み可能な個人証明書マネージャ +Comment[ka]=პერსონალური სერთიფიკატების ჩადგმული მმართველი +Comment[kk]=Ендірілетін дербес куәлік менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងវិញ្ញាបនបត្រឯកជនដែលអាចបង្កប់ +Comment[ko]=끼워넣는 개인용 인증서 관리 +Comment[lb]=Abettbare perséinlechen Zertifikatsmanager +Comment[lt]=Įdedama asmeninių sertifikatų tvarkyklė +Comment[lv]=Iegulstams personālo sertifikātu menedžeris +Comment[mk]=Вгнездлив менаџер на лични сертификати +Comment[mn]=Суулгах боломж бүхий хувийн үнэмлэхийн зохион байгуулагч +Comment[ms]=Pengurus Sijil Peribadi Boleh Serta +Comment[mt]=Maniġer ta' ċertifikati personali integrat +Comment[nb]=Innebyggbar personlig sertifikathåndterer +Comment[nds]=Inbettbor Pleger för persöönliche Zertifikaten +Comment[ne]=सम्मिलित व्यक्तिगत प्रमाणपत्र प्रबन्धक +Comment[nl]=Ingebedde Persoonlijke Certificaat-beheerder +Comment[nn]=Innebyggbar handsaming av personlege sertifikat +Comment[nso]=Molaodi yo a Robatsegago wa Kgonthisiso ya Botho +Comment[pa]=ਨਿੱਜੀ ਸਰਟੀਫਕੇਟ ਪ੍ਰਬੰਧਕ ਸ਼ਾਮਿਲ ਹੋਣਯੋਗ +Comment[pl]=Osobisty menedżer certyfikatów +Comment[pt]=Gestor de Certificados Pessoais Incorporado +Comment[pt_BR]=Gerenciador embutido de Certificados Pessoais +Comment[ro]=Componentă manager de certificate personale +Comment[ru]=Встраиваемый персональный менеджер сертификатов +Comment[rw]=Umuyobozi w'Impamyabushobozi Yihariye Ishyirwamo +Comment[se]=Vuojuhanláhkái persuvnnalaš duođaštusaid gieđahalli +Comment[sk]=Vložiteľný osobný správca certifikátov +Comment[sl]=Vgradljivi osebni upravljalnik certifikatov +Comment[sq]=Menagjer për diplomë personale +Comment[sr]=Уградиви менаџер личних сертификата +Comment[sr@Latn]=Ugradivi menadžer ličnih sertifikata +Comment[ss]=Siphatsi sesithifikethi samuntfu sicu lesinamatselekako +Comment[sv]=Inbäddningsbar personlig certifikatshanterare +Comment[ta]=உட்பொதிந்த சொந்தச் சான்றிதழ் மேலாளர் +Comment[te]=పొదగబడె వక్తిగత ప్రమాణ పత్రాల అభికర్త +Comment[tg]=Мудири шахсии сохташудаи сертификатҳо +Comment[th]=ตัวจัดการแบบฝังตัวของใบรับรองส่วนบุคคล +Comment[tr]=Gömülebilir Kişisel Sertifika Yöneticisi +Comment[tt]=Şäxsi Tanıqlıqlar öçen Quşılma-İdäräçe +Comment[uk]=Менеджер персональних сертифікатів, який можна вбудовувати +Comment[uz]=Ichiga oʻrnatib boʻladigan shaxsiy sertifikat boshqaruvchisi +Comment[uz@cyrillic]=Ичига ўрнатиб бўладиган шахсий сертификат бошқарувчиси +Comment[ven]=Mulanguli wa sethifikheithi ya vhune +Comment[vi]=Bộ Quản lý Chứng nhận Cá nhân có khả năng nhúng +Comment[xh]=Umphathi Wesiqinisekiso Sobuntu bakho Obulungiselelweyo +Comment[zh_CN]=可嵌入的个人证书管理器 +Comment[zh_HK]=可嵌入的個人證書管理工具 +Comment[zh_TW]=可嵌入的個人認證管理工具 +Comment[zu]=Imeneja Yesitifiketi Sobunini Oshuthekiwe +MimeType=application/x-pkcs12;application/x-x509-ca-cert;application/binary-certificate; +Icon=lock +Name=KCertPart +Name[af]=Kcertpart +Name[bn]=কে-সার্ট-পার্ট +Name[cy]=KRhanTyst +Name[eo]=Katestilo-parto +Name[nso]=Seripa sa KCert +Name[sv]=Kcertpart +Name[ta]=கேசான்றிதழ்பகுதி +Name[te]=కెసెర్ట్ పార్ట్ +Name[ven]=Tshipida tsha cert ya K +ServiceTypes=KParts/ReadWritePart +X-KDE-Library=libkcertpart +InitialPreference=15 diff --git a/kcert/kcertpart.h b/kcert/kcertpart.h new file mode 100644 index 000000000..59dab9fa1 --- /dev/null +++ b/kcert/kcertpart.h @@ -0,0 +1,139 @@ +/* This file is part of the KDE project + * + * Copyright (C) 2001 George Staikos <staikos@kde.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#ifndef _INCLUDE_KCERTPART_H +#define _INCLUDE_KCERTPART_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <kparts/part.h> +#include <qptrlist.h> +#include <qlistview.h> +#include <klistview.h> + +class KSSLCertBox; +class QFrame; +class QLabel; +class KCertPartPrivate; +class KComboBox; +class QButton; +class KSSLSigners; +class KSSLPKCS12; +class KSSLCertificate; +class QTabWidget; +class QMultiLineEdit; +class KAboutData; +class QGridLayout; + + +class KX509Item : public KListViewItem { + public: + KX509Item(KListViewItem *parent, KSSLCertificate *x); + KX509Item(KListView *parent, KSSLCertificate *x); + void setup(KSSLCertificate *x); + ~KX509Item(); + virtual int rtti() const { return 1; } + KSSLCertificate *cert; + QString _prettyName; +}; + + +class KPKCS12Item : public KListViewItem { + public: + KPKCS12Item(KListViewItem *parent, KSSLPKCS12 *x); + ~KPKCS12Item(); + KSSLPKCS12 *cert; + QString _prettyName; +}; + + +class KCertPart : public KParts::ReadWritePart { +Q_OBJECT +public: + KCertPart(QWidget *parentWidget, const char *widgetName, + QObject *parent = 0L, const char *name = 0L, + const QStringList &args = QStringList() ); + virtual ~KCertPart(); + + virtual void setReadWrite(bool readwrite); + + static KAboutData *createAboutData(); + +protected slots: + void slotChain(int c); + void slotImport(); + void slotSave(); + void slotDone(); + void slotLaunch(); + void slotSelectionChanged(QListViewItem *x); + void slotImportAll(); + +protected: + + virtual bool openFile(); + virtual bool saveFile(); + + void displayPKCS12Cert(KSSLCertificate *c); + void displayCACert(KSSLCertificate *c); + + KListView *_sideList; + KListViewItem *_parentCA, *_parentP12; + QFrame *_pkcsFrame, *_blankFrame, *_x509Frame, *_frame; + + // for the PKCS12 widget + QLabel *_p12_filenameLabel, *_p12_validFrom, *_p12_validUntil, + *_p12_serialNum, *_p12_certState; + QLabel *_p12_digest; + KComboBox *_p12_chain; + QMultiLineEdit *_p12_pubkey, *_p12_sig; + KSSLCertBox *_p12_subject, *_p12_issuer; + + // for the CA widget + QLabel *_ca_filenameLabel, *_ca_validFrom, *_ca_validUntil, + *_ca_serialNum, *_ca_certState; + QLabel *_ca_digest; + QMultiLineEdit *_ca_pubkey, *_ca_sig; + KSSLCertBox *_ca_subject, *_ca_issuer; + + + // The rest + KInstance *_instance; + QButton *_import, *_save, *_done, *_launch, *_importAll; + // Store the pointer to the current item + KSSLPKCS12 *_p12; + KSSLCertificate *_ca; + QTabWidget *_tabs; + QGridLayout *_baseGrid; + KSSLSigners *_signers; + bool _silentImport; + QString _curName; + +private: + KCertPartPrivate *d; + void displayPKCS12(); +}; + + + + +#endif + + diff --git a/kcert/kcertpart.rc b/kcert/kcertpart.rc new file mode 100644 index 000000000..4deb2d7c8 --- /dev/null +++ b/kcert/kcertpart.rc @@ -0,0 +1,10 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="KCertPart" version="2"> +<MenuBar> + <Menu name="Certificate"><Text>&Certificate</Text> + <Action name="Import"/> +</Menu> +</MenuBar> +<StatusBar/> +</kpartgui> + |