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 \