From 91e4e78cef1c91e9a082ffb3525da28cb2b78de8 Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 17 May 2007 14:02:38 +0200 Subject: [PATCH] Add options dialog to set the default hash algo, mandatory distinguished name entries and allow duplicate key use as requested by some users. show CRL signature alg information Version 0.6.3 --- VERSION | 2 +- changelog | 9 ++- lib/pki_crl.cpp | 5 ++ lib/pki_crl.h | 1 + ui/Options.ui | 4 +- widgets/CrlDetail.cpp | 2 +- widgets/MW_menu.cpp | 9 +-- widgets/MainWindow.cpp | 1 + widgets/MainWindow.h | 2 +- widgets/NewX509.cpp | 109 +++++++++++++++++++++++++--- widgets/NewX509.h | 161 +++++++++++++++++++++-------------------- widgets/Options.cpp | 11 +-- widgets/Options.h | 2 +- xca.pro | 2 +- 14 files changed, 210 insertions(+), 110 deletions(-) diff --git a/VERSION b/VERSION index b6160487..844f6a91 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.6.2 +0.6.3 diff --git a/changelog b/changelog index 286a103c..c4fd46f5 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,9 @@ - * Add options dialog +xca 0.6.3 + + * show CRL signature algorithm information + * Add options dialog to set the default hash algo, + mandatory distinguished name entries and allow duplicate key use + as requested by some users * make cert, crl and key details copy&paste able * fix background color of clicklabels Bug [ 1704699 ] @@ -322,6 +327,6 @@ xca 0.1.11 * RSA Keys are generated and stored to or loaded from a file in either DER or PEM format. - * They get stored in a local Bercley DB. + * They get stored in a local Berkeley DB. * Changing their description and viewing their contents, as well as deleting them from local DB is possible. diff --git a/lib/pki_crl.cpp b/lib/pki_crl.cpp index 4a9f4bb8..f0aaa0f6 100644 --- a/lib/pki_crl.cpp +++ b/lib/pki_crl.cpp @@ -40,6 +40,11 @@ void pki_crl::fload(const QString fname ) else fopen_error(fname); } +QString pki_crl::getSigAlg() +{ + QString alg = OBJ_nid2ln(OBJ_obj2nid(crl->sig_alg->algorithm)); + return alg; +} void pki_crl::createCrl(const QString d, pki_x509 *iss ) { diff --git a/lib/pki_crl.h b/lib/pki_crl.h index bd7c4b92..9106ec0c 100644 --- a/lib/pki_crl.h +++ b/lib/pki_crl.h @@ -27,6 +27,7 @@ class pki_crl: public pki_base /* destructor */ ~pki_crl(); void fload(const QString fname); + QString getSigAlg(); void writeDefault(const QString fname); static QPixmap *icon; void createCrl(const QString d, pki_x509 *iss); diff --git a/ui/Options.ui b/ui/Options.ui index f2ea52dc..9f6b05df 100644 --- a/ui/Options.ui +++ b/ui/Options.ui @@ -5,8 +5,8 @@ 0 0 - 362 - 390 + 379 + 294 diff --git a/widgets/CrlDetail.cpp b/widgets/CrlDetail.cpp index d82aec18..e508fbe9 100644 --- a/widgets/CrlDetail.cpp +++ b/widgets/CrlDetail.cpp @@ -48,7 +48,7 @@ void CrlDetail::setCrl(pki_crl *crl) issuerIntName->setGreen(); pki_key *key = iss->getPubKey(); if (crl->verify(key)) { - signCheck->setText(tr("Ok")); + signCheck->setText(crl->getSigAlg()); signCheck->setGreen(); } else { signCheck->setText(tr("Failed")); diff --git a/widgets/MW_menu.cpp b/widgets/MW_menu.cpp index 4f2b1868..f73b3636 100644 --- a/widgets/MW_menu.cpp +++ b/widgets/MW_menu.cpp @@ -34,7 +34,7 @@ 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()) ); + acList += file->addAction(tr("Options"), this, SLOT(setOptions()) ); file->addSeparator(); file->addAction(tr("E&xit"), qApp, SLOT(quit()), Qt::ALT+Qt::Key_F4 ); @@ -135,7 +135,7 @@ void MainWindow::import_dbdump() void MainWindow::setOptions() { unsigned char bol; - Options *opt = new Options(this, mandatory_dn); + Options *opt = new Options(this); opt->multiple_use->setChecked(multiple_key_use); if (!opt->exec()) @@ -146,13 +146,12 @@ void MainWindow::setOptions() mydb.set((const unsigned char *)CCHAR(alg), alg.length()+1, 1, setting, "default_hash"); hashBox::setDefault(alg); - + mandatory_dn = opt->getDnString(); - printf("DNString = %s\n", CCHAR(mandatory_dn)); mydb.set((const unsigned char *)CCHAR(mandatory_dn), mandatory_dn.length()+1, 1, setting, "mandatory_dn"); - + multiple_key_use = opt->multiple_use->isChecked(); bol = multiple_key_use ? 1 : 0; mydb.set(&bol, sizeof(bol), 1, setting, "multiple_key_use"); diff --git a/widgets/MainWindow.cpp b/widgets/MainWindow.cpp index 86d36e18..43305b6f 100644 --- a/widgets/MainWindow.cpp +++ b/widgets/MainWindow.cpp @@ -43,6 +43,7 @@ NIDlist *MainWindow::eku_nid = NULL; NIDlist *MainWindow::dn_nid = NULL; NIDlist *MainWindow::aia_nid = NULL; +QString MainWindow::mandatory_dn; MainWindow::MainWindow(QWidget *parent ) :QMainWindow(parent) diff --git a/widgets/MainWindow.h b/widgets/MainWindow.h index 0606d855..7d82f07c 100644 --- a/widgets/MainWindow.h +++ b/widgets/MainWindow.h @@ -34,7 +34,6 @@ class MainWindow: public QMainWindow, public Ui::MainWindow QString workingdir; QList wdList; QList acList; - QString mandatory_dn; protected: void init_images(); @@ -52,6 +51,7 @@ class MainWindow: public QMainWindow, public Ui::MainWindow static db_crl *crls; static QPixmap *keyImg, *csrImg, *certImg, *tempImg, *nsImg, *revImg, *appIco; static NIDlist *eku_nid, *dn_nid, *aia_nid; + static QString mandatory_dn; int exitApp; QString dbfile; QLabel *dbindex; diff --git a/widgets/NewX509.cpp b/widgets/NewX509.cpp index c414fe5e..2d064934 100644 --- a/widgets/NewX509.cpp +++ b/widgets/NewX509.cpp @@ -112,7 +112,7 @@ NewX509::NewX509(QWidget *parent) // init the X509 v3 context X509V3_set_ctx(&ext_ctx, NULL , NULL, NULL, NULL, 0); - X509V3_set_ctx_nodb((&ext_ctx)); + X509V3_set_ctx_nodb(&ext_ctx); // setup the list of x509nameEntrys name_ptr[0] = countryName; @@ -356,7 +356,7 @@ void NewX509::toggleOkBut() countryName->text().length() !=1 && ( keyList->count() > 0 || !keyList->isEnabled() ); ok |= fromReqCB->isChecked(); - okButton->setEnabled(ok); + //okButton->setEnabled(ok); } void NewX509::on_description_textChanged(QString) @@ -628,26 +628,113 @@ void NewX509::on_editAuthInfAcc_clicked() editV3ext(authInfAcc, "email,RID,URI,DNS,IP", NID_info_access); } +QString NewX509::mandatoryDnRemain() +{ + QStringList dnl = MainWindow::mandatory_dn.split(","); + x509name n; + int i; + + if (fromReqCB->isChecked()) + n = getSelectedReq()->getSubject(); + else + n = getX509name(); + + for (i=0; i< n.entryCount(); i++) { + int j = dnl.indexOf(QString(OBJ_nid2sn(n.nid(i)))); + if (j>=0) + dnl.removeAt(j); + } + return dnl.join(","); +} + void NewX509::on_okButton_clicked() { + if (description->text().isEmpty() && !fromReqCB->isChecked()) { + if (commonName->text().isEmpty()) { + if (QMessageBox::warning(this, tr(XCA_TITLE), + tr("The internal name and the common name are empty.\n" + "Please set at least the internal name."), + tr("Ok"), tr("Abort rollout")) == 1) + { + reject(); + } + return; + } else { + description->setText(commonName->text()); + } + } + + if (countryName->text().length() == 1) { + if (QMessageBox::warning(this, tr(XCA_TITLE), + tr("The Country name must be either empty or 2 digits long."), + tr("Ok"), tr("Abort rollout")) == 1) + { + reject(); + } + return; + } + + if ( keyList->count() == 0 && + keyList->isEnabled() && + !fromReqCB->isChecked()) + { + if (QMessageBox::warning(this, tr(XCA_TITLE), + tr("There is no Key selected for signing."), + tr("Ok"), tr("Abort rollout")) == 1) + { + reject(); + } + return; + } + + QString unsetDN; + if (pt != tmpl) + unsetDN = mandatoryDnRemain(); + if (!unsetDN.isEmpty()) + { + switch (QMessageBox::warning(this, tr(XCA_TITLE), + tr("The following distinguished name entries are empty,\n" + "though you have declared them as mandatory " + "in the options menu:\n") + unsetDN, + tr("Ok"), tr("Abort rollout"), + tr("Continue rollout"))) + { + case -1: + case 0: + return; + case 1: + reject(); + return; + } + } if (notBefore->getDate().get_utc() == NULL || notAfter->getDate().get_utc() == NULL) { - if (QMessageBox::warning(this, tr(XCA_TITLE), + switch (QMessageBox::warning(this, tr(XCA_TITLE), tr("The validity dates are out of range (1950 - 2049) to create " - "valid certificates. If you continue, your client may " - "reject the certificate."), tr("Continue to issue"), - tr("Change validity times"))) + "valid certificates. If you continue, your client may " + "reject the certificate."), + tr("Ok"), tr("Abort rollout"), tr("Continue rollout"))) { - return; + case -1: + case 0: + return; + case 1: + reject(); + return; } } if (notBefore->getDate() > notAfter->getDate()) { - if (QMessageBox::warning(this, tr(XCA_TITLE), + switch (QMessageBox::warning(this, tr(XCA_TITLE), tr("The certificate will be out of date before it becomes valid. " - "You most probably mixed up both dates."), - tr("Continue to issue"), tr("Change validity times"))) + "You most probably mixed up both dates."), + tr("Ok"), tr("Abort rollout"), tr("Continue rollout"))) { - return; + case -1: + case 0: + return; + case 1: + reject(); + return; } } accept(); diff --git a/widgets/NewX509.h b/widgets/NewX509.h index ccd44fbf..ad9fefef 100644 --- a/widgets/NewX509.h +++ b/widgets/NewX509.h @@ -29,86 +29,87 @@ class extList; class NewX509: public QDialog, public Ui::NewX509 { - Q_OBJECT - private: - NIDlist eku_nid; - NIDlist dn_nid; - NIDlist aia_nid; -#define EXPLICIT_NAME_CNT 7 - static int name_nid[EXPLICIT_NAME_CNT]; - QLineEdit *name_ptr[EXPLICIT_NAME_CNT]; - X509V3_CTX ext_ctx; - void editV3ext(QLineEdit *le, QString types, int n); - enum pki_type pt; - void templateChanged(QString templatename); - public: - QRadioButton *selfQASignRB; - NewX509(QWidget *parent); - virtual ~NewX509(); - void initCtx(); - void setRequest(); // reduce to request form - void setTemp(pki_temp *temp); // reduce to template form - void setCert(); // reduce to certificate form - void toTemplate(pki_temp *temp); - void fromTemplate(pki_temp *temp); - void defineTemplate(pki_temp *temp); - void defineRequest(pki_x509req *req); - void defineSigner(pki_x509 *defcert); - int lb2int(QListWidget *lb); - void int2lb(QListWidget *lb, int x); - void templateChanged(pki_temp *templ); - pki_key *getSelectedKey(); - pki_x509 *getSelectedSigner(); - pki_x509req *getSelectedReq(); - x509name getX509name(); - void setX509name(const x509name &n); - void setImage(QPixmap *image); - void setAuthInfAcc_string(QString aia_txt); - QString getAuthInfAcc_string(); - x509v3ext getBasicConstraints(); - x509v3ext getSubKeyIdent(); - x509v3ext getAuthKeyIdent(); - x509v3ext getKeyUsage(); - x509v3ext getEkeyUsage(); - x509v3ext getSubAltName(); - x509v3ext getIssAltName(); - x509v3ext getCrlDist(); - x509v3ext getAuthInfAcc(); - x509v3ext getCertPol(); - extList getNetscapeExt(); - extList getAllExt(); - void initCtx(pki_x509 *subj, pki_x509 *iss, pki_x509req *req); - void setBasicConstraints(const x509v3ext &e); - void setExt(const x509v3ext &ext); - QString createRequestText(); - void checkAuthKeyId(); - void switchHashAlgo(); - public slots: - void on_fromReqCB_clicked(); - void on_keyList_currentIndexChanged(const QString &); - void on_reqList_currentIndexChanged(const QString &); - void toggleOkBut(); - void newKeyDone(QString name); - void on_extDNadd_clicked(); - void on_extDNdel_clicked(); - void on_applyTime_clicked(); - void on_editSubAlt_clicked(); - void on_editIssAlt_clicked(); - void on_editCrlDist_clicked(); - void on_editAuthInfAcc_clicked(); - void on_foreignSignRB_toggled(bool checked); - void on_selfSignRB_toggled(bool checked); - void on_subKey_clicked(); - void on_genKeyBUT_clicked(); - void on_showReqBut_clicked(); - void on_description_textChanged(QString text); - void on_countryName_textChanged(QString); - void on_certList_currentIndexChanged(int index); - void on_applyTemplate_clicked(); - void on_okButton_clicked(); - signals: - void genKey(); - void showReq(QString req); + Q_OBJECT + private: + NIDlist eku_nid; + NIDlist dn_nid; + NIDlist aia_nid; + #define EXPLICIT_NAME_CNT 7 + static int name_nid[EXPLICIT_NAME_CNT]; + QLineEdit *name_ptr[EXPLICIT_NAME_CNT]; + X509V3_CTX ext_ctx; + void editV3ext(QLineEdit *le, QString types, int n); + enum pki_type pt; + void templateChanged(QString templatename); + QString mandatoryDnRemain(); + public: + QRadioButton *selfQASignRB; + NewX509(QWidget *parent); + virtual ~NewX509(); + void initCtx(); + void setRequest(); // reduce to request form + void setTemp(pki_temp *temp); // reduce to template form + void setCert(); // reduce to certificate form + void toTemplate(pki_temp *temp); + void fromTemplate(pki_temp *temp); + void defineTemplate(pki_temp *temp); + void defineRequest(pki_x509req *req); + void defineSigner(pki_x509 *defcert); + int lb2int(QListWidget *lb); + void int2lb(QListWidget *lb, int x); + void templateChanged(pki_temp *templ); + pki_key *getSelectedKey(); + pki_x509 *getSelectedSigner(); + pki_x509req *getSelectedReq(); + x509name getX509name(); + void setX509name(const x509name &n); + void setImage(QPixmap *image); + void setAuthInfAcc_string(QString aia_txt); + QString getAuthInfAcc_string(); + x509v3ext getBasicConstraints(); + x509v3ext getSubKeyIdent(); + x509v3ext getAuthKeyIdent(); + x509v3ext getKeyUsage(); + x509v3ext getEkeyUsage(); + x509v3ext getSubAltName(); + x509v3ext getIssAltName(); + x509v3ext getCrlDist(); + x509v3ext getAuthInfAcc(); + x509v3ext getCertPol(); + extList getNetscapeExt(); + extList getAllExt(); + void initCtx(pki_x509 *subj, pki_x509 *iss, pki_x509req *req); + void setBasicConstraints(const x509v3ext &e); + void setExt(const x509v3ext &ext); + QString createRequestText(); + void checkAuthKeyId(); + void switchHashAlgo(); + public slots: + void on_fromReqCB_clicked(); + void on_keyList_currentIndexChanged(const QString &); + void on_reqList_currentIndexChanged(const QString &); + void toggleOkBut(); + void newKeyDone(QString name); + void on_extDNadd_clicked(); + void on_extDNdel_clicked(); + void on_applyTime_clicked(); + void on_editSubAlt_clicked(); + void on_editIssAlt_clicked(); + void on_editCrlDist_clicked(); + void on_editAuthInfAcc_clicked(); + void on_foreignSignRB_toggled(bool checked); + void on_selfSignRB_toggled(bool checked); + void on_subKey_clicked(); + void on_genKeyBUT_clicked(); + void on_showReqBut_clicked(); + void on_description_textChanged(QString text); + void on_countryName_textChanged(QString); + void on_certList_currentIndexChanged(int index); + void on_applyTemplate_clicked(); + void on_okButton_clicked(); + signals: + void genKey(); + void showReq(QString req); }; #endif diff --git a/widgets/Options.cpp b/widgets/Options.cpp index 3cb18c3c..e19c4b7e 100644 --- a/widgets/Options.cpp +++ b/widgets/Options.cpp @@ -8,19 +8,20 @@ #include "Options.h" #include -Options::Options(QWidget *parent, QString dn) +Options::Options(QWidget *parent) :QDialog(parent) { - QStringList dnl = dn.split(","); - if (dn.isEmpty()) - dnl.clear(); + QStringList dnl; + if (!MainWindow::mandatory_dn.isEmpty()) + dnl = MainWindow::mandatory_dn.split(","); + 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])); - + for (int i=0; i < dnl.count(); i++) { int nid; nid = OBJ_sn2nid(CCHAR(dnl[i])); diff --git a/widgets/Options.h b/widgets/Options.h index 32435dda..b135439a 100644 --- a/widgets/Options.h +++ b/widgets/Options.h @@ -17,7 +17,7 @@ class Options: public QDialog, public Ui::Options { Q_OBJECT public: - Options(QWidget *parent, QString dn); + Options(QWidget *parent); public slots: void on_extDNadd_clicked(); void on_extDNdel_clicked(); diff --git a/xca.pro b/xca.pro index 988d6fa1..02f7860f 100644 --- a/xca.pro +++ b/xca.pro @@ -126,7 +126,7 @@ SOURCES += lib/asn1int.cpp \ widgets/MW_menu.cpp \ widgets/NewX509.cpp \ widgets/NewX509_ext.cpp \ - Widgets/Options.cpp \ + widgets/Options.cpp \ widgets/ReqDetail.cpp \ widgets/v3ext.cpp \ widgets/validity.cpp \