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