check for duplicate x509 v3 extensions

- while taking extensions from the request, the advanced tab
   and the other tabs, extensions may be duplicated.

   They will be now diplayed in
   detail and duplicates are found and shown clearly.
   Warning message will allow for modifications.

 - Fixes
    [ 1881482 ] Copy extensions from request seems to fail
    [ 1998815 ] xca adds basic constraint "CA" twice resulting in invalid CA
This commit is contained in:
Christian Hohnstaedt 2009-03-03 21:45:00 +01:00
parent 1a47ce9c22
commit 356cab3401
6 changed files with 76 additions and 18 deletions

View File

@ -486,7 +486,6 @@ void db_x509::newCert(NewX509 *dlg)
throw errorEx("");
}
// STEP 4 handle extensions
if (dlg->copyReqExtCB->isChecked() && dlg->fromReqCB->isChecked()) {
extList el = req->getV3ext();
@ -497,7 +496,6 @@ void db_x509::newCert(NewX509 *dlg)
// apply all extensions to the subject cert in the context
dlg->getAllExt();
dlg->checkExtDuplicates();
const EVP_MD *hashAlgo = dlg->hashAlgo->currentHash();
#ifdef WG_QA_SERIAL

View File

@ -177,6 +177,16 @@ int extList::delByNid(int nid)
return removed;
}
int extList::idxByNid(int nid)
{
for(int i = 0; i< size(); i++) {
if (at(i).nid() == nid) {
return i;
}
}
return -1;
}
int extList::delInvalid(void)
{
int removed=0;

View File

@ -45,5 +45,6 @@ class extList : public QList<x509v3ext>
QString getHtml(const QString &sep);
int delByNid(int nid);
int delInvalid();
int idxByNid(int nid);
};
#endif

View File

@ -163,6 +163,7 @@ void NewX509::setRequest()
signerBox->setEnabled(false);
timewidget->setEnabled(false);
capt->setText(tr("Create Certificate signing request"));
authKey->setEnabled(false);
setImage(MainWindow::csrImg);
pt = x509_req;
}
@ -651,7 +652,7 @@ void NewX509::on_adv_validate_clicked()
QString result;
setupTmpCtx();
v3ext_backup = nconf_data->toPlainText();
if (fromReqCB->isChecked()) {
if (fromReqCB->isChecked() && copyReqExtCB->isChecked()) {
el = getSelectedReq()->getV3ext();
}
if (el.size() > 0) {
@ -689,11 +690,13 @@ void NewX509::on_adv_validate_clicked()
nconf_data->setReadOnly(true);
adv_validate->setText(tr("Edit"));
valid_htmltext = result;
checkExtDuplicates();
} else {
nconf_data->document()->setPlainText(v3ext_backup);
nconf_data->setReadOnly(false);
adv_validate->setText(tr("Validate"));
valid_htmltext = "";
}
pki_base::ign_openssl_error();
}
@ -843,5 +846,21 @@ void NewX509::on_okButton_clicked()
return;
}
}
on_adv_validate_clicked();
if (checkExtDuplicates()) {
switch (QMessageBox::warning(this, tr(XCA_TITLE),
tr("The certificate contains duplicated extensions. "
"Check the validation on the advanced tab."),
tr("Ok"), tr("Abort rollout"), tr("Continue rollout")))
{
case -1:
case 0:
return;
case 1:
reject();
return;
}
}
accept();
}

View File

@ -47,6 +47,7 @@ class NewX509: public QDialog, public Ui::NewX509
QStringList private_keys, private_keys0;
pki_x509 *ctx_cert;
QString v3ext_backup;
QString valid_htmltext;
public:
QRadioButton *selfQASignRB;
NewX509(QWidget *parent);
@ -90,7 +91,7 @@ class NewX509: public QDialog, public Ui::NewX509
void setExt(const x509v3ext &ext);
void switchHashAlgo();
void addReqAttributes(pki_x509req *req);
void checkExtDuplicates();
int checkExtDuplicates();
public slots:
void on_fromReqCB_clicked();
void on_keyList_currentIndexChanged(const QString &);

View File

@ -207,6 +207,9 @@ extList NewX509::getAdvanced()
char ext_name[] = "ext";
int ret, i, start;
if (nconf_data->isReadOnly()) {
on_adv_validate_clicked();
}
conf_str = nconf_data->toPlainText();
if (conf_str.isEmpty())
return elist;
@ -215,7 +218,10 @@ extList NewX509::getAdvanced()
conf_str = QString("[") + ext_name + "]\n";
for (i=0; i< list.count(); i++) {
conf_str += list[i].trimmed() + "\n";
QString s = list[i].trimmed();
if (!s.isEmpty()){
conf_str += s + "\n";
}
}
bio = BIO_new_mem_buf((void*)CCHAR(conf_str), conf_str.length());
if (!bio)
@ -319,32 +325,55 @@ void NewX509::initCtx(pki_x509 *subj, pki_x509 *iss, pki_x509req *req)
X509V3_set_ctx(&ext_ctx, s, s1, r, NULL, 0);
}
void NewX509::checkExtDuplicates()
int NewX509::checkExtDuplicates()
{
int i, start, cnt, n1, n;
X509_EXTENSION *e, *e1;
x509v3ext e;
STACK_OF(X509_EXTENSION) *sk;
extList el_dup, el;
QString olist;
if (ext_ctx.subject_cert) {
sk = ext_ctx.subject_cert->cert_info->extensions;
} else
return;
return 0;
cnt = sk_X509_EXTENSION_num(sk);
for (start=0; start<cnt; start++) {
e1 = sk_X509_EXTENSION_value(sk, start);
n1 = OBJ_obj2nid(X509_EXTENSION_get_object(e1));
for (i=start+1; i<cnt; i++) {
e = sk_X509_EXTENSION_value(sk, i);
n = OBJ_obj2nid(X509_EXTENSION_get_object(e));
el.setStack(sk, 0);
if (fromReqCB->isChecked() && copyReqExtCB->isChecked()) {
el += getSelectedReq()->getV3ext();
}
cnt = el.size();
for (start=0; start < cnt; start++) {
n1 = el[start].nid();
for (i = start+1; i<cnt; i++) {
e = el[i];
n = e.nid();
if (n1 == n) {
// DUPLICATE
x509v3ext x;
x.set(e);
printf("DUPLICATE: %d %d, %d:%d %d\n%s\n", n, n1, cnt, start,i, CCHAR(x.getHtml()));
if (el_dup.idxByNid(n1) ==-1)
el_dup << e;
}
}
}
if (el_dup.size() <= 0)
return 0;
tabWidget->setCurrentIndex(tabWidget->count() -1);
if (!nconf_data->isReadOnly()) {
on_adv_validate_clicked();
}
olist = "<h2><center><font color=\"red\">Error:</font> "
"duplicate extensions:</center></h2><p><ul>\n";
for(int i = 0; i< el_dup.size(); i++) {
olist += "<li>" + el_dup[i].getObject() + "</li>\n";
}
olist += "</ul>\n<hr>\n";
olist += valid_htmltext;
nconf_data->document()->setHtml(olist);
return el_dup.size();
}
void NewX509::setExt(const x509v3ext &ext)