00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "ksslkeygen.h"
00023 #include "keygenwizard.h"
00024 #include "keygenwizard2.h"
00025
00026 #include <kapplication.h>
00027 #include <kdebug.h>
00028 #include <klocale.h>
00029 #include <kmessagebox.h>
00030 #include <kopenssl.h>
00031 #include <kprogress.h>
00032 #include <kstandarddirs.h>
00033 #include <ktempfile.h>
00034 #include <kwallet.h>
00035
00036 #include <qlineedit.h>
00037 #include <qpushbutton.h>
00038
00039 #include <assert.h>
00040
00041
00042 KSSLKeyGen::KSSLKeyGen(QWidget *parent, const char *name, bool modal)
00043 :KWizard(parent,name,modal) {
00044 _idx = -1;
00045
00046 #ifdef KSSL_HAVE_SSL
00047 page1 = new KGWizardPage1(this, "Wizard Page 1");
00048 addPage(page1, i18n("KDE Certificate Request"));
00049 page2 = new KGWizardPage2(this, "Wizard Page 2");
00050 addPage(page2, i18n("KDE Certificate Request - Password"));
00051 setHelpEnabled(page1, false);
00052 setHelpEnabled(page2, false);
00053 setFinishEnabled(page2, false);
00054 connect(page2->_password1, SIGNAL(textChanged(const QString&)), this, SLOT(slotPassChanged()));
00055 connect(page2->_password2, SIGNAL(textChanged(const QString&)), this, SLOT(slotPassChanged()));
00056 connect(finishButton(), SIGNAL(clicked()), SLOT(slotGenerate()));
00057 #else
00058
00059 #endif
00060 }
00061
00062
00063 KSSLKeyGen::~KSSLKeyGen() {
00064
00065 }
00066
00067
00068 void KSSLKeyGen::slotPassChanged() {
00069 setFinishEnabled(page2, page2->_password1->text() == page2->_password2->text() && page2->_password1->text().length() >= 4);
00070 }
00071
00072
00073 void KSSLKeyGen::slotGenerate() {
00074 assert(_idx >= 0 && _idx <= 3);
00075
00076
00077
00078 int bits;
00079 switch (_idx) {
00080 case 0:
00081 bits = 2048;
00082 break;
00083 case 1:
00084 bits = 1024;
00085 break;
00086 case 2:
00087 bits = 768;
00088 break;
00089 case 3:
00090 bits = 512;
00091 break;
00092 default:
00093 KMessageBox::sorry(NULL, i18n("Unsupported key size."), i18n("KDE SSL Information"));
00094 return;
00095 }
00096
00097 KProgressDialog *kpd = new KProgressDialog(this, "progress dialog", i18n("KDE"), i18n("Please wait while the encryption keys are generated..."));
00098 kpd->progressBar()->setProgress(0);
00099 kpd->show();
00100
00101
00102 int rc = generateCSR("This CSR" , page2->_password1->text(), bits, 0x10001 );
00103 kpd->progressBar()->setProgress(100);
00104
00105 #ifndef Q_OS_WIN //TODO: reenable for WIN32
00106 if (rc == 0 && KWallet::Wallet::isEnabled()) {
00107 rc = KMessageBox::questionYesNo(this, i18n("Do you wish to store the passphrase in your wallet file?"), QString::null, i18n("Store"), i18n("Do Not Store"));
00108 if (rc == KMessageBox::Yes) {
00109 KWallet::Wallet *w = KWallet::Wallet::openWallet(KWallet::Wallet::LocalWallet(), winId());
00110 if (w) {
00111
00112 delete w;
00113 }
00114 }
00115 }
00116 #endif
00117
00118 kpd->deleteLater();
00119 }
00120
00121
00122 int KSSLKeyGen::generateCSR(const QString& name, const QString& pass, int bits, int e) {
00123 #ifdef KSSL_HAVE_SSL
00124 KOSSL *kossl = KOSSL::self();
00125 int rc;
00126
00127 X509_REQ *req = kossl->X509_REQ_new();
00128 if (!req) {
00129 return -2;
00130 }
00131
00132 EVP_PKEY *pkey = kossl->EVP_PKEY_new();
00133 if (!pkey) {
00134 kossl->X509_REQ_free(req);
00135 return -4;
00136 }
00137
00138 RSA *rsakey = kossl->RSA_generate_key(bits, e, NULL, NULL);
00139 if (!rsakey) {
00140 kossl->X509_REQ_free(req);
00141 kossl->EVP_PKEY_free(pkey);
00142 return -3;
00143 }
00144
00145 rc = kossl->EVP_PKEY_assign(pkey, EVP_PKEY_RSA, (char *)rsakey);
00146
00147 rc = kossl->X509_REQ_set_pubkey(req, pkey);
00148
00149
00150 X509_NAME *n = kossl->X509_NAME_new();
00151
00152 kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_countryName, MBSTRING_UTF8, (unsigned char*)name.local8Bit().data(), -1, -1, 0);
00153 kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_organizationName, MBSTRING_UTF8, (unsigned char*)name.local8Bit().data(), -1, -1, 0);
00154 kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_organizationalUnitName, MBSTRING_UTF8, (unsigned char*)name.local8Bit().data(), -1, -1, 0);
00155 kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_localityName, MBSTRING_UTF8, (unsigned char*)name.local8Bit().data(), -1, -1, 0);
00156 kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_stateOrProvinceName, MBSTRING_UTF8, (unsigned char*)name.local8Bit().data(), -1, -1, 0);
00157 kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_commonName, MBSTRING_UTF8, (unsigned char*)name.local8Bit().data(), -1, -1, 0);
00158 kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_pkcs9_emailAddress, MBSTRING_UTF8, (unsigned char*)name.local8Bit().data(), -1, -1, 0);
00159
00160 rc = kossl->X509_REQ_set_subject_name(req, n);
00161
00162
00163 rc = kossl->X509_REQ_sign(req, pkey, kossl->EVP_md5());
00164
00165
00166
00167
00168
00169 KGlobal::dirs()->addResourceType("kssl", KStandardDirs::kde_default("data") + "kssl");
00170
00171 QString path = KGlobal::dirs()->saveLocation("kssl");
00172 KTempFile csrFile(path + "csr_", ".der");
00173
00174 if (!csrFile.fstream()) {
00175 kossl->X509_REQ_free(req);
00176 kossl->EVP_PKEY_free(pkey);
00177 return -5;
00178 }
00179
00180 KTempFile p8File(path + "pkey_", ".p8");
00181
00182 if (!p8File.fstream()) {
00183 kossl->X509_REQ_free(req);
00184 kossl->EVP_PKEY_free(pkey);
00185 return -5;
00186 }
00187
00188 kossl->i2d_X509_REQ_fp(csrFile.fstream(), req);
00189
00190 kossl->i2d_PKCS8PrivateKey_fp(p8File.fstream(), pkey,
00191 kossl->EVP_bf_cbc(), pass.local8Bit().data(),
00192 pass.length(), 0L, 0L);
00193
00194
00195
00196 kossl->X509_REQ_free(req);
00197 kossl->EVP_PKEY_free(pkey);
00198
00199 return 0;
00200 #else
00201 return -1;
00202 #endif
00203 }
00204
00205
00206 QStringList KSSLKeyGen::supportedKeySizes() {
00207 QStringList x;
00208
00209 #ifdef KSSL_HAVE_SSL
00210 x << i18n("2048 (High Grade)")
00211 << i18n("1024 (Medium Grade)")
00212 << i18n("768 (Low Grade)")
00213 << i18n("512 (Low Grade)");
00214 #else
00215 x << i18n("No SSL support.");
00216 #endif
00217
00218 return x;
00219 }
00220
00221
00222 #include "ksslkeygen.moc"
00223