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 if (rc == 0 && KWallet::Wallet::isEnabled()) {
00106 rc = KMessageBox::questionYesNo(this, i18n("Do you wish to store the passphrase in your wallet file?"), i18n("KDE"));
00107 if (rc == KMessageBox::Yes) {
00108 KWallet::Wallet *w = KWallet::Wallet::openWallet(KWallet::Wallet::LocalWallet(), winId());
00109 if (w) {
00110
00111 delete w;
00112 }
00113 }
00114 }
00115
00116 kpd->deleteLater();
00117 }
00118
00119
00120 int KSSLKeyGen::generateCSR(const QString& name, const QString& pass, int bits, int e) {
00121 #ifdef KSSL_HAVE_SSL
00122 KOSSL *kossl = KOSSL::self();
00123 int rc;
00124
00125 X509_REQ *req = kossl->X509_REQ_new();
00126 if (!req) {
00127 return -2;
00128 }
00129
00130 EVP_PKEY *pkey = kossl->EVP_PKEY_new();
00131 if (!pkey) {
00132 kossl->X509_REQ_free(req);
00133 return -4;
00134 }
00135
00136 RSA *rsakey = kossl->RSA_generate_key(bits, e, NULL, NULL);
00137 if (!rsakey) {
00138 kossl->X509_REQ_free(req);
00139 kossl->EVP_PKEY_free(pkey);
00140 return -3;
00141 }
00142
00143 rc = kossl->EVP_PKEY_assign(pkey, EVP_PKEY_RSA, (char *)rsakey);
00144
00145 rc = kossl->X509_REQ_set_pubkey(req, pkey);
00146
00147
00148 X509_NAME *n = kossl->X509_NAME_new();
00149
00150 kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_countryName, MBSTRING_UTF8, (unsigned char*)name.local8Bit().data(), -1, -1, 0);
00151 kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_organizationName, MBSTRING_UTF8, (unsigned char*)name.local8Bit().data(), -1, -1, 0);
00152 kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_organizationalUnitName, MBSTRING_UTF8, (unsigned char*)name.local8Bit().data(), -1, -1, 0);
00153 kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_localityName, MBSTRING_UTF8, (unsigned char*)name.local8Bit().data(), -1, -1, 0);
00154 kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_stateOrProvinceName, MBSTRING_UTF8, (unsigned char*)name.local8Bit().data(), -1, -1, 0);
00155 kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_commonName, MBSTRING_UTF8, (unsigned char*)name.local8Bit().data(), -1, -1, 0);
00156 kossl->X509_NAME_add_entry_by_txt(n, (char*)LN_pkcs9_emailAddress, MBSTRING_UTF8, (unsigned char*)name.local8Bit().data(), -1, -1, 0);
00157
00158 rc = kossl->X509_REQ_set_subject_name(req, n);
00159
00160
00161 rc = kossl->X509_REQ_sign(req, pkey, kossl->EVP_md5());
00162
00163
00164
00165
00166
00167 KGlobal::dirs()->addResourceType("kssl", KStandardDirs::kde_default("data") + "kssl");
00168
00169 QString path = KGlobal::dirs()->saveLocation("kssl");
00170 KTempFile csrFile(path + "csr_", ".der");
00171
00172 if (!csrFile.fstream()) {
00173 kossl->X509_REQ_free(req);
00174 kossl->EVP_PKEY_free(pkey);
00175 return -5;
00176 }
00177
00178 KTempFile p8File(path + "pkey_", ".p8");
00179
00180 if (!p8File.fstream()) {
00181 kossl->X509_REQ_free(req);
00182 kossl->EVP_PKEY_free(pkey);
00183 return -5;
00184 }
00185
00186 kossl->i2d_X509_REQ_fp(csrFile.fstream(), req);
00187
00188 kossl->i2d_PKCS8PrivateKey_fp(p8File.fstream(), pkey,
00189 kossl->EVP_bf_cbc(), pass.local8Bit().data(),
00190 pass.length(), 0L, 0L);
00191
00192
00193
00194 kossl->X509_REQ_free(req);
00195 kossl->EVP_PKEY_free(pkey);
00196
00197 return 0;
00198 #else
00199 return -1;
00200 #endif
00201 }
00202
00203
00204 QStringList KSSLKeyGen::supportedKeySizes() {
00205 QStringList x;
00206
00207 #ifdef KSSL_HAVE_SSL
00208 x << i18n("2048 (High Grade)")
00209 << i18n("1024 (Medium Grade)")
00210 << i18n("768 (Low Grade)")
00211 << i18n("512 (Low Grade)");
00212 #else
00213 x << i18n("No SSL support.");
00214 #endif
00215
00216 return x;
00217 }
00218
00219
00220 #include "ksslkeygen.moc"
00221