diff --git a/changelog b/changelog index ae783c84..286a103c 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,4 @@ + * Add options dialog * make cert, crl and key details copy&paste able * fix background color of clicklabels Bug [ 1704699 ] diff --git a/lib/db_crl.cpp b/lib/db_crl.cpp index 0f215c15..4c8751a8 100644 --- a/lib/db_crl.cpp +++ b/lib/db_crl.cpp @@ -153,31 +153,22 @@ pki_crl *db_crl::newItem(pki_x509 *cert) a1time time; pki_crl *crl = NULL; Ui::NewCrl ui; - const EVP_MD *dgst; - const EVP_MD *algolist[] = { EVP_md2(), EVP_md5(), EVP_sha1() -#ifdef HAS_SHA256 - ,EVP_sha256(), EVP_sha512() -#endif - }; + x509v3ext e; X509V3_CTX ext_ctx; X509V3_set_ctx(&ext_ctx, cert->getCert() , NULL, NULL, NULL, 0); X509V3_set_ctx_nodb((&ext_ctx)); QDialog *dlg = new QDialog(mainwin); + ui.setupUi(dlg); ui.image->setPixmap(*MainWindow::revImg); -#ifdef HAS_SHA256 - ui.hashAlgo->addItem(tr("SHA 256")); - ui.hashAlgo->addItem(tr("SHA 512")); - ui.hashAlgo->setCurrentIndex(3); -#endif ui.lastUpdate->setDate(time.now()); ui.nextUpdate->setDate(time.now(cert->getCrlDays() *60*60*24)); if (cert->getRefKey()->getType() == EVP_PKEY_DSA) - ui.hashAlgo->setEnabled(false); + ui.hashAlgo->setDsa(true); else - ui.hashAlgo->setEnabled(true); + ui.hashAlgo->setDsa(false); if (cert->hasExtension(NID_subject_alt_name)) ui.subAltName->setEnabled(true); @@ -212,12 +203,8 @@ pki_crl *db_crl::newItem(pki_x509 *cert) crl->setLastUpdate(ui.lastUpdate->getDate()); crl->setNextUpdate(ui.nextUpdate->getDate()); cert->setCrlExpiry(ui.nextUpdate->getDate()); - if (cert->getRefKey()->getType() == EVP_PKEY_DSA) - dgst = EVP_dss1(); - else - dgst = algolist[ui.hashAlgo->currentIndex()]; - crl->sign(cert->getRefKey(), dgst); + crl->sign(cert->getRefKey(), ui.hashAlgo->currentHash()); mainwin->certs->updatePKI(cert); insert(crl); } diff --git a/lib/db_crl.h b/lib/db_crl.h index 923355f8..ad5faeb5 100644 --- a/lib/db_crl.h +++ b/lib/db_crl.h @@ -17,25 +17,25 @@ class db_crl: public db_base { - Q_OBJECT - protected: - QPixmap *crlicon; - db_x509 *certs; - public: - db_crl(QString db, MainWindow *mw); - pki_base *newPKI(); - void revokeCerts(pki_crl *crl); - void inToCont(pki_base *pki); - pki_base *insert(pki_base *item); - pki_crl *newItem(pki_x509 *cert); - void showContextMenu(QContextMenuEvent *e, const QModelIndex &index); - void removeSigner(pki_base *signer); - public slots: - void store(); - void load(); - void showPki(pki_base *pki); - signals: - void updateCertView(); + Q_OBJECT + protected: + QPixmap *crlicon; + db_x509 *certs; + public: + db_crl(QString db, MainWindow *mw); + pki_base *newPKI(); + void revokeCerts(pki_crl *crl); + void inToCont(pki_base *pki); + pki_base *insert(pki_base *item); + pki_crl *newItem(pki_x509 *cert); + void showContextMenu(QContextMenuEvent *e, const QModelIndex &index); + void removeSigner(pki_base *signer); + public slots: + void store(); + void load(); + void showPki(pki_base *pki); + signals: + void updateCertView(); }; #endif diff --git a/lib/db_dump.cpp b/lib/db_dump.cpp index 3c895335..db230c95 100644 --- a/lib/db_dump.cpp +++ b/lib/db_dump.cpp @@ -5,6 +5,8 @@ * All rights reserved. */ +#include "db.h" + int main(int argc, char *argv[]) { if (argc<2) diff --git a/lib/db_x509.cpp b/lib/db_x509.cpp index 249fcbf5..3964f45e 100644 --- a/lib/db_x509.cpp +++ b/lib/db_x509.cpp @@ -515,9 +515,7 @@ void db_x509::newCert(NewX509 *dlg) for (int i=0; iaddV3ext(ne[i]); - const EVP_MD *hashAlgo = dlg->getHashAlgo(); - if (signkey->getType() == EVP_PKEY_DSA) - hashAlgo = EVP_dss1(); + const EVP_MD *hashAlgo = dlg->hashAlgo->currentHash(); #ifdef WG_QA_SERIAL if (dlg->selfQASignRB->isChecked()) { // sign the request intermediately in order to finally fill diff --git a/lib/db_x509req.cpp b/lib/db_x509req.cpp index 1781fe92..478832d3 100644 --- a/lib/db_x509req.cpp +++ b/lib/db_x509req.cpp @@ -62,17 +62,14 @@ void db_x509req::newItem(pki_temp *temp) return; } try { - const EVP_MD *hashAlgo = dlg->getHashAlgo(); pki_key *key = dlg->getSelectedKey(); x509name xn = dlg->getX509name(); req = new pki_x509req(); req->setIntName(dlg->description->text()); - if (key->getType() == EVP_PKEY_DSA) - hashAlgo = EVP_dss1(); dlg->initCtx(NULL, NULL, req); - req->createReq(key, xn, hashAlgo, dlg->getAllExt()); + req->createReq(key, xn, dlg->hashAlgo->currentHash(), dlg->getAllExt()); insert(req); } catch (errorEx &err) { diff --git a/ui/NewCrl.ui b/ui/NewCrl.ui index 0e067aaf..253afceb 100644 --- a/ui/NewCrl.ui +++ b/ui/NewCrl.ui @@ -143,23 +143,7 @@ - - - - MD 2 - - - - - MD 5 - - - - - SHA 1 - - - + @@ -245,6 +229,11 @@ + + hashBox + QComboBox +
widgets/hashBox.h
+
Validity QWidget diff --git a/ui/NewX509.ui b/ui/NewX509.ui index ac0a2abe..229adf53 100644 --- a/ui/NewX509.ui +++ b/ui/NewX509.ui @@ -280,23 +280,7 @@ If this list is disabled, you only can create a self-signed certificate. - - - - MD 2 - - - - - MD 5 - - - - - SHA 1 - - - + @@ -1491,6 +1475,11 @@ email:my@other.address, RID:1.2.3.4, DNS: ns.server.tld + + hashBox + QComboBox +
widgets/hashBox.h
+
Validity QWidget diff --git a/ui/Options.ui b/ui/Options.ui new file mode 100644 index 00000000..16049da5 --- /dev/null +++ b/ui/Options.ui @@ -0,0 +1,234 @@ + + Options + + + + 0 + 0 + 362 + 390 + + + + Dialog + + + + 9 + + + 6 + + + + + + Arial + 14 + 50 + false + false + false + false + + + + <html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Arial'; font-size:14pt; font-weight:400; font-style:normal; text-decoration:none;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">XCA Options</p></body></html> + + + Qt::AlignCenter + + + + + + + Mandatory subject entries + + + + 9 + + + 6 + + + + + 0 + + + 6 + + + + + + + + + + + + + 0 + + + 6 + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Add + + + + + + + Delete + + + + + + + + + + + + Allow multiple use of keys + + + + + + + 0 + + + 6 + + + + + Default hash algorithm + + + + + + + + + + + + Qt::Horizontal + + + + + + + 0 + + + 6 + + + + + Cancel + + + + + + + Qt::Horizontal + + + + 21 + 21 + + + + + + + + OK + + + + + + + + + + hashBox + QComboBox +
widgets/hashBox.h
+
+
+ + hashAlgo + okButton + cancelButton + + + + + okButton + clicked() + Options + accept() + + + 224 + 332 + + + 96 + 254 + + + + + cancelButton + clicked() + Options + reject() + + + 305 + 332 + + + 179 + 282 + + + + +
diff --git a/widgets/MW_database.cpp b/widgets/MW_database.cpp index 44ced750..d6cce65b 100644 --- a/widgets/MW_database.cpp +++ b/widgets/MW_database.cpp @@ -78,6 +78,12 @@ void MainWindow::init_database() free(p); } } + if (!mydb.find(setting, "default_hash")) { + if ((p = (char *)mydb.load(NULL))) { + hashBox::setDefault(p); + free(p); + } + } } catch (errorEx &err) { Error(err); return; diff --git a/widgets/MW_menu.cpp b/widgets/MW_menu.cpp index 21cfebb9..0eee771b 100644 --- a/widgets/MW_menu.cpp +++ b/widgets/MW_menu.cpp @@ -7,8 +7,11 @@ #include "MainWindow.h" +#include "Options.h" #include "lib/load_obj.h" #include "lib/pass_info.h" +#include "ui_Options.h" +#include "widgets/hashBox.h" #include #include #include @@ -31,6 +34,8 @@ void MainWindow::init_menu() acList += file->addAction(tr("&Undelete items"), this, SLOT(undelete()), Qt::CTRL+Qt::Key_U ); file->addSeparator(); + file->addAction(tr("Options"), this, SLOT(setOptions()) ); + file->addSeparator(); file->addAction(tr("E&xit"), qApp, SLOT(quit()), Qt::ALT+Qt::Key_F4 ); import = menuBar()->addMenu(tr("&Import")); @@ -51,6 +56,7 @@ void MainWindow::init_menu() import->addAction(tr("PEM file"), this, SLOT(loadPem()) ); + help = menuBar()->addMenu(tr("&Help") ); help->addAction(tr("&Content"), this, SLOT(help()), Qt::Key_F1 ); help->addAction(tr("&About"), this, SLOT(about()) ); @@ -125,3 +131,22 @@ void MainWindow::import_dbdump() Error(err); } } + +void MainWindow::setOptions() +{ + Options *opt = new Options(this); + + if (!opt->exec()) + return; + + QString alg = opt->hashAlgo->currentHashName(); + db mydb(dbfile); + mydb.set((const unsigned char *)CCHAR(alg), alg.length()+1, 1, + setting, "default_hash"); + hashBox::setDefault(alg); + + QString mandatory = opt->getDnString(); + printf("DNString = %s\n", CCHAR(mandatory)); + mydb.set((const unsigned char *)CCHAR(mandatory), mandatory.length()+1, 1, + setting, "mandatory_dn"); +} diff --git a/widgets/MainWindow.h b/widgets/MainWindow.h index cf21a8d0..1771a183 100644 --- a/widgets/MainWindow.h +++ b/widgets/MainWindow.h @@ -87,6 +87,7 @@ class MainWindow: public QMainWindow, public Ui::MainWindow void loadPem(); private slots: + void setOptions(); void on_keyView_doubleClicked(const QModelIndex &m); void on_reqView_doubleClicked(const QModelIndex &m); void on_certView_doubleClicked(const QModelIndex &m); diff --git a/widgets/Makefile b/widgets/Makefile index 028988c4..7f7742c1 100644 --- a/widgets/Makefile +++ b/widgets/Makefile @@ -5,7 +5,7 @@ endif MOC_NAMES=MainWindow KeyDetail clicklabel XcaTreeView ExportKey NewX509 \ validity v3ext ReqDetail distname CertDetail CertExtend ExportCert \ - ImportMulti CrlDetail ExportDer + ImportMulti CrlDetail ExportDer hashBox Options NAMES=$(MOC_NAMES) NewX509_ext MW_menu MW_help MW_database NAMES=$(MOC_NAMES) NewX509_ext MW_help MW_database diff --git a/widgets/NewX509.cpp b/widgets/NewX509.cpp index 4257fc8d..c414fe5e 100644 --- a/widgets/NewX509.cpp +++ b/widgets/NewX509.cpp @@ -57,12 +57,6 @@ NewX509::NewX509(QWidget *parent) serialNr->setValidator( new QRegExpValidator(QRegExp("[0-9a-fA-F]*"), this)); QStringList strings; - hashAlgo->setCurrentIndex(2); -#ifdef HAS_SHA256 - hashAlgo->addItem(tr("SHA 256")); - hashAlgo->addItem(tr("SHA 512")); - hashAlgo->setCurrentIndex(3); -#endif // are there any useable private keys ? strings = MainWindow::keys->get0PrivateDesc(); keyList->insertItems(0, strings); @@ -339,10 +333,8 @@ void NewX509::on_reqList_currentIndexChanged(const QString &) void NewX509::switchHashAlgo() { - static int h_index = 0; pki_key *key; pki_x509super *sig; - bool disable; if (foreignSignRB->isChecked()) sig = getSelectedSigner(); @@ -352,22 +344,10 @@ void NewX509::switchHashAlgo() sig = NULL; key = sig ? sig->getRefKey() : getSelectedKey(); - disable = (key && key->getType() == EVP_PKEY_DSA) ? true : false; - - if (disable) { - if (hashAlgo->isEnabled()) { - /* backup */ - h_index = hashAlgo->currentIndex(); - hashAlgo->setCurrentIndex(2); - hashAlgo->setDisabled(true); - } - } else { - if (!hashAlgo->isEnabled()) { - /* restore */ - hashAlgo->setCurrentIndex(h_index); - hashAlgo->setDisabled(false); - } - } + if (key && key->getType() == EVP_PKEY_DSA) + hashAlgo->setDsa(true); + else + hashAlgo->setDsa(false); } void NewX509::toggleOkBut() @@ -587,16 +567,6 @@ void NewX509::on_extDNdel_clicked() extDNlist->removeRow(extDNlist->currentRow()); } -const EVP_MD *NewX509::getHashAlgo() -{ - const EVP_MD *ha[] = { EVP_md2(), EVP_md5(), EVP_sha1() -#ifdef HAS_SHA256 - , EVP_sha256(), EVP_sha512() -#endif - }; - return ha[hashAlgo->currentIndex()]; -} - void NewX509::on_applyTime_clicked() { applyTD(this, validNumber->text().toInt(), validRange->currentIndex(), diff --git a/widgets/NewX509.h b/widgets/NewX509.h index c70c050b..ccd44fbf 100644 --- a/widgets/NewX509.h +++ b/widgets/NewX509.h @@ -77,7 +77,6 @@ class NewX509: public QDialog, public Ui::NewX509 x509v3ext getCertPol(); extList getNetscapeExt(); extList getAllExt(); - const EVP_MD *getHashAlgo(); void initCtx(pki_x509 *subj, pki_x509 *iss, pki_x509req *req); void setBasicConstraints(const x509v3ext &e); void setExt(const x509v3ext &ext); diff --git a/widgets/Options.cpp b/widgets/Options.cpp new file mode 100644 index 00000000..3f77e87e --- /dev/null +++ b/widgets/Options.cpp @@ -0,0 +1,40 @@ +/* vi: set sw=4 ts=4: + * + * Copyright (C) 2001 - 2007 Christian Hohnstaedt. + * + * All rights reserved. + */ + +#include "Options.h" +#include + +Options::Options(QWidget *parent) + :QDialog(parent) +{ + NIDlist dn_nid = *MainWindow::dn_nid; + setWindowTitle(tr(XCA_TITLE)); + setupUi(this); + + for (int i=0; i < dn_nid.count(); i++) + extDNobj->addItem(OBJ_nid2ln(dn_nid[i])); +} + +void Options::on_extDNadd_clicked() +{ + extDNlist->insertItem(0, extDNobj->currentText()); +} +void Options::on_extDNdel_clicked() +{ + extDNlist->takeItem(extDNlist->currentRow()); +} + +QString Options::getDnString() +{ + QStringList dn; + for (int j=0; jcount(); j++) { + int nid; + nid = OBJ_ln2nid(CCHAR(extDNlist->item(j)->text())); + dn << QString(OBJ_nid2sn(nid)); + } + return dn.join(","); +} diff --git a/widgets/Options.h b/widgets/Options.h new file mode 100644 index 00000000..b135439a --- /dev/null +++ b/widgets/Options.h @@ -0,0 +1,27 @@ +/* vi: set sw=4 ts=4: + * + * Copyright (C) 2001 - 2007 Christian Hohnstaedt. + * + * All rights reserved. + */ + +#ifndef OPTIONS_H +#define OPTIONS_H + +#include "ui_Options.h" +#include +#include "lib/base.h" +#include "widgets/MainWindow.h" + +class Options: public QDialog, public Ui::Options +{ + Q_OBJECT + public: + Options(QWidget *parent); + public slots: + void on_extDNadd_clicked(); + void on_extDNdel_clicked(); + QString getDnString(); +}; + +#endif diff --git a/widgets/hashBox.cpp b/widgets/hashBox.cpp new file mode 100644 index 00000000..9c9753f1 --- /dev/null +++ b/widgets/hashBox.cpp @@ -0,0 +1,88 @@ +/* vi: set sw=4 ts=4: + * + * Copyright (C) 2001 - 2007 Christian Hohnstaedt. + * + * All rights reserved. + */ + +#include "hashBox.h" +#include "lib/base.h" + +#define DSA_INDEX 2 + +#ifdef HAS_SHA256 +int hashBox::default_md = 3; /* SHA256 */ +#else +int hashBox::default_md = 2; /* SHA1 */ +#endif + +static struct { + char *name; + const EVP_MD *md; +} hashalgos[] = { + { "MD 2", EVP_md2() }, + { "MD 5", EVP_md5() }, + { "SHA 1", EVP_sha1() }, +#ifdef HAS_SHA256 + { "SHA 256", EVP_sha256() }, + { "SHA 512", EVP_sha512() }, +#endif + { NULL, NULL }, +}; + +hashBox::hashBox(QWidget *parent) + :QComboBox(parent) +{ + for (int i=0; hashalgos[i].name; i++) + addItem(QString(hashalgos[i].name)); + setDefaultHash(); + backup = default_md; +} + +void hashBox::setDsa(bool new_dsa) +{ + if (dsa == new_dsa) + return; + dsa = new_dsa; + if (dsa) { + backup = currentIndex(); + setCurrentIndex(DSA_INDEX); + setDisabled(true); + } else { + setCurrentIndex(backup); + setDisabled(false); + } +} + +const EVP_MD *hashBox::currentHash() +{ + if (dsa) + return EVP_dss1(); + return hashalgos[currentIndex()].md; +} + +QString hashBox::currentHashName() +{ + return QString(hashalgos[currentIndex()].name); +} + +void hashBox::setDefaultHash() +{ + setCurrentIndex(default_md); +} + +void hashBox::setCurrentAsDefault() +{ + default_md = currentIndex(); +} + +void hashBox::setDefault(QString def) +{ + for (int i=0; hashalgos[i].name; i++) { + if (QString(hashalgos[i].name) == def) { + default_md = i; + return; + } + } +} + diff --git a/widgets/hashBox.h b/widgets/hashBox.h new file mode 100644 index 00000000..ef8e762c --- /dev/null +++ b/widgets/hashBox.h @@ -0,0 +1,31 @@ +/* vi: set sw=4 ts=4: + * + * Copyright (C) 2001 - 2007 Christian Hohnstaedt. + * + * All rights reserved. + */ + +#ifndef HASH_BOX_H +#define HASH_BOX_H + +#include +#include + +class hashBox: public QComboBox +{ + Q_OBJECT + private: + static int default_md; + int backup; + bool dsa; + public: + hashBox(QWidget *parent); + void setDsa(bool dsa); + const EVP_MD *currentHash(); + QString currentHashName(); + void setCurrentAsDefault(); + void setDefaultHash(); + static void setDefault(QString def); +}; + +#endif diff --git a/xca.pro b/xca.pro index 07064c65..988d6fa1 100644 --- a/xca.pro +++ b/xca.pro @@ -49,10 +49,12 @@ HEADERS += lib/asn1int.h \ widgets/ExportCert.h \ widgets/ExportDer.h \ widgets/ExportKey.h \ + widgets/hashBox.h \ widgets/ImportMulti.h \ widgets/KeyDetail.h \ widgets/MainWindow.h \ widgets/NewX509.h \ + widgets/Options.h \ widgets/ReqDetail.h \ widgets/v3ext.h \ widgets/validity.h \ @@ -73,6 +75,7 @@ FORMS += ui/About.ui \ ui/NewCrl.ui \ ui/NewKey.ui \ ui/NewX509.ui \ + ui/Options.ui \ ui/PassRead.ui \ ui/PassWrite.ui \ ui/ReqDetail.ui \ @@ -114,6 +117,7 @@ SOURCES += lib/asn1int.cpp \ widgets/ExportCert.cpp \ widgets/ExportDer.cpp \ widgets/ExportKey.cpp \ + widgets/hashBox.cpp \ widgets/ImportMulti.cpp \ widgets/KeyDetail.cpp \ widgets/MainWindow.cpp \ @@ -122,6 +126,7 @@ SOURCES += lib/asn1int.cpp \ widgets/MW_menu.cpp \ widgets/NewX509.cpp \ widgets/NewX509_ext.cpp \ + Widgets/Options.cpp \ widgets/ReqDetail.cpp \ widgets/v3ext.cpp \ widgets/validity.cpp \