• Skip to content
  • Skip to link menu
KDE 4.7 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KIO

ksslkeygen.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002  *
00003  * Copyright (C) 2001 George Staikos <staikos@kde.org>
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Library General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Library General Public License
00016  * along with this library; see the file COPYING.LIB.  If not, write to
00017  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019  */
00020 
00021 
00022 #include "ksslkeygen.h"
00023 #include "ksslkeygen_p.h"
00024 #include "ui_keygenwizard.h"
00025 
00026 #include <kdebug.h>
00027 #include <klocale.h>
00028 #include <kmessagebox.h>
00029 #include <kopenssl.h>
00030 #include <kprogressdialog.h>
00031 #include <kstandarddirs.h>
00032 #include <ktemporaryfile.h>
00033 #include <kwallet.h>
00034 
00035 #include <assert.h>
00036 
00037 KSSLKeyGenWizardPage2::KSSLKeyGenWizardPage2(QWidget* parent)
00038     : QWizardPage(parent)
00039 {
00040     ui2 = new Ui_KGWizardPage2;
00041     ui2->setupUi(this);
00042     connect(ui2->_password1, SIGNAL(textChanged(const QString&)), this, SLOT(slotPassChanged()));
00043     connect(ui2->_password2, SIGNAL(textChanged(const QString&)), this, SLOT(slotPassChanged()));
00044 }
00045 
00046 bool KSSLKeyGenWizardPage2::isComplete() const
00047 {
00048     return ui2->_password1->text() == ui2->_password2->text() && ui2->_password1->text().length() >= 4;
00049 }
00050 
00051 void KSSLKeyGenWizardPage2::slotPassChanged()
00052 {
00053     emit completeChanged(); // well maybe it hasn't changed, but it might have; QWizard calls isComplete() to find out
00054 }
00055 
00056 QString KSSLKeyGenWizardPage2::password() const
00057 {
00058     Q_ASSERT(isComplete());
00059     return ui2->_password1->text();
00060 }
00061 
00063 
00064 class KSSLKeyGenPrivate
00065 {
00066 public:
00067     KSSLKeyGenPrivate()
00068         : idx(-1)
00069     {
00070     }
00071     int idx;
00072     Ui_KGWizardPage1 *ui1;
00073     KSSLKeyGenWizardPage2* page2;
00074 };
00075 
00076 KSSLKeyGen::KSSLKeyGen(QWidget *parent)
00077     : QWizard(parent), d(new KSSLKeyGenPrivate)
00078 {
00079 #ifdef KSSL_HAVE_SSL
00080 
00081     QWizardPage* page1 = new QWizardPage(this);
00082     page1->setTitle(i18n("KDE Certificate Request"));
00083     d->ui1 = new Ui_KGWizardPage1;
00084     d->ui1->setupUi(page1);
00085     addPage(page1);
00086     //setHelpEnabled(page1, false);
00087 
00088     d->page2 = new KSSLKeyGenWizardPage2(this);
00089     d->page2->setTitle(i18n("KDE Certificate Request - Password"));
00090     addPage(d->page2);
00091 #else
00092     // tell him he doesn't have SSL
00093 #endif
00094 }
00095 
00096 
00097 KSSLKeyGen::~KSSLKeyGen() {
00098     delete d->ui1;
00099     delete d;
00100 }
00101 
00102 bool KSSLKeyGen::validateCurrentPage() {
00103     if (currentPage() != d->page2)
00104         return true;
00105 
00106     assert(d->idx >= 0 && d->idx <= 3);   // for now
00107 
00108     // Generate the CSR
00109     int bits;
00110     switch (d->idx) {
00111     case 0:
00112         bits = 2048;
00113         break;
00114     case 1:
00115         bits = 1024;
00116         break;
00117     case 2:
00118         bits = 768;
00119         break;
00120     case 3:
00121         bits = 512;
00122         break;
00123     default:
00124         KMessageBox::sorry(this, i18n("Unsupported key size."), i18n("KDE SSL Information"));
00125         return false;
00126     }
00127 
00128     KProgressDialog *kpd = new KProgressDialog(this);
00129     kpd->setObjectName("progress dialog");
00130     kpd->setWindowTitle(i18n("KDE"));
00131     kpd->setLabelText(i18n("Please wait while the encryption keys are generated..."));
00132     kpd->progressBar()->setValue(0);
00133     kpd->show();
00134     // FIXME - progress dialog won't show this way
00135 
00136     int rc = generateCSR("This CSR" /*FIXME */, d->page2->password(), bits, 0x10001 /* This is the traditional exponent used */);
00137     if (rc != 0) // error
00138         return false;
00139 
00140     kpd->progressBar()->setValue(100);
00141 
00142 #if 0 // TODO: implement
00143     if (rc == 0 && KWallet::Wallet::isEnabled()) {
00144         rc = KMessageBox::questionYesNo(this, i18n("Do you wish to store the passphrase in your wallet file?"), QString(), KGuiItem(i18n("Store")), KGuiItem(i18n("Do Not Store")));
00145         if (rc == KMessageBox::Yes) {
00146             KWallet::Wallet *w = KWallet::Wallet::openWallet(KWallet::Wallet::LocalWallet(), winId());
00147             if (w) {
00148                 // FIXME: store passphrase in wallet
00149                 delete w;
00150             }
00151         }
00152     }
00153 #endif
00154 
00155     kpd->deleteLater();
00156     return true;
00157 }
00158 
00159 
00160 int KSSLKeyGen::generateCSR(const QString& name, const QString& pass, int bits, int e) {
00161 #ifdef KSSL_HAVE_SSL
00162     KOSSL *kossl = KOSSL::self();
00163     int rc;
00164 
00165     X509_REQ *req = kossl->X509_REQ_new();
00166     if (!req) {
00167         return -2;
00168     }
00169 
00170     EVP_PKEY *pkey = kossl->EVP_PKEY_new();
00171     if (!pkey) {
00172         kossl->X509_REQ_free(req);
00173         return -4;
00174     }
00175 
00176     RSA *rsakey = kossl->RSA_generate_key(bits, e, NULL, NULL);
00177     if (!rsakey) {
00178         kossl->X509_REQ_free(req);
00179         kossl->EVP_PKEY_free(pkey);
00180         return -3;
00181     }
00182 
00183     rc = kossl->EVP_PKEY_assign(pkey, EVP_PKEY_RSA, (char *)rsakey);
00184 
00185     rc = kossl->X509_REQ_set_pubkey(req, pkey);
00186 
00187     // Set the subject
00188     X509_NAME *n = kossl->X509_NAME_new();
00189 
00190     kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_countryName, MBSTRING_UTF8, (unsigned char*)name.toLocal8Bit().data(), -1, -1, 0);
00191     kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_organizationName, MBSTRING_UTF8, (unsigned char*)name.toLocal8Bit().data(), -1, -1, 0);
00192     kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_organizationalUnitName, MBSTRING_UTF8, (unsigned char*)name.toLocal8Bit().data(), -1, -1, 0);
00193     kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_localityName, MBSTRING_UTF8, (unsigned char*)name.toLocal8Bit().data(), -1, -1, 0);
00194     kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_stateOrProvinceName, MBSTRING_UTF8, (unsigned char*)name.toLocal8Bit().data(), -1, -1, 0);
00195     kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_commonName, MBSTRING_UTF8, (unsigned char*)name.toLocal8Bit().data(), -1, -1, 0);
00196     kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_pkcs9_emailAddress, MBSTRING_UTF8, (unsigned char*)name.toLocal8Bit().data(), -1, -1, 0);
00197 
00198     rc = kossl->X509_REQ_set_subject_name(req, n);
00199 
00200 
00201     rc = kossl->X509_REQ_sign(req, pkey, kossl->EVP_md5());
00202 
00203     // We write it to the database and then the caller can obtain it
00204     // back from there.  Yes it's inefficient, but it doesn't happen
00205     // often and this way things are uniform.
00206 
00207     KGlobal::dirs()->addResourceType("kssl", "data", "kssl");
00208 
00209     QString path = KGlobal::dirs()->saveLocation("kssl");
00210     KTemporaryFile csrFile;
00211     csrFile.setAutoRemove(false);
00212     csrFile.setPrefix(path + "csr_");
00213     csrFile.setSuffix(".der");
00214 
00215     if (!csrFile.open()) {
00216         kossl->X509_REQ_free(req);
00217         kossl->EVP_PKEY_free(pkey);
00218         return -5;
00219     }
00220 
00221     KTemporaryFile p8File;
00222     p8File.setAutoRemove(false);
00223     p8File.setPrefix(path + "pkey_");
00224     p8File.setSuffix(".p8");
00225 
00226     if (!p8File.open()) {
00227         kossl->X509_REQ_free(req);
00228         kossl->EVP_PKEY_free(pkey);
00229         return -5;
00230     }
00231 
00232     FILE *csr_fs = fopen(QFile::encodeName(csrFile.fileName()), "r+");
00233     FILE *p8_fs = fopen(QFile::encodeName(p8File.fileName()), "r+");
00234 
00235     kossl->i2d_X509_REQ_fp(csr_fs, req);
00236 
00237     kossl->i2d_PKCS8PrivateKey_fp(p8_fs, pkey,
00238             kossl->EVP_bf_cbc(), pass.toLocal8Bit().data(),
00239             pass.length(), 0L, 0L);
00240 
00241     // FIXME Write kconfig entry to store the filenames under the md5 hash
00242 
00243     kossl->X509_REQ_free(req);
00244     kossl->EVP_PKEY_free(pkey);
00245 
00246     fclose(csr_fs);
00247     fclose(p8_fs);
00248 
00249     return 0;
00250 #else
00251     return -1;
00252 #endif
00253 }
00254 
00255 
00256 QStringList KSSLKeyGen::supportedKeySizes() {
00257     QStringList x;
00258 
00259 #ifdef KSSL_HAVE_SSL
00260     x   << i18n("2048 (High Grade)")
00261         << i18n("1024 (Medium Grade)")
00262         << i18n("768  (Low Grade)")
00263         << i18n("512  (Low Grade)");
00264 #else
00265     x   << i18n("No SSL support.");
00266 #endif
00267 
00268     return x;
00269 }
00270 
00271 void KSSLKeyGen::setKeySize(int idx)
00272 {
00273      d->idx = idx;
00274 }
00275 
00276 #include "ksslkeygen.moc"
00277 
00278 #include "ksslkeygen_p.moc"

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.5
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal