diff --git a/lib/db_x509.cpp b/lib/db_x509.cpp index 95941824..8560ceab 100644 --- a/lib/db_x509.cpp +++ b/lib/db_x509.cpp @@ -495,10 +495,9 @@ void db_x509::newCert(NewX509 *dlg) cert->addV3ext(el[i]); } - extList ne = dlg->getAllExt(); - int m = ne.count(); - for (int i=0; iaddV3ext(ne[i]); + // 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 diff --git a/lib/x509v3ext.cpp b/lib/x509v3ext.cpp index b56ee147..9a29adc2 100644 --- a/lib/x509v3ext.cpp +++ b/lib/x509v3ext.cpp @@ -51,6 +51,13 @@ x509v3ext &x509v3ext::create(int nid, const QString &et, X509V3_CTX *ctx) } if (!ext) ext = X509_EXTENSION_new(); + else { + if (ctx && ctx->subject_cert) { + STACK_OF(X509_EXTENSION) **sk; + sk = &ctx->subject_cert->cert_info->extensions; + X509v3_add_ext(sk, ext, -1); + } + } return *this; } @@ -127,12 +134,12 @@ bool x509v3ext::isValid() const /*************************************************************/ -void extList::setStack(STACK_OF(X509_EXTENSION) *st) +void extList::setStack(STACK_OF(X509_EXTENSION) *st, int start) { clear(); int cnt = sk_X509_EXTENSION_num(st); x509v3ext e; - for (int i=0; i { public: - void setStack(STACK_OF(X509_EXTENSION) *st); + void setStack(STACK_OF(X509_EXTENSION) *st, int start=0); STACK_OF(X509_EXTENSION) *getStack(); QString getHtml(const QString &sep); int delByNid(int nid); diff --git a/widgets/NewX509.cpp b/widgets/NewX509.cpp index 28fb0f0c..66ab5938 100644 --- a/widgets/NewX509.cpp +++ b/widgets/NewX509.cpp @@ -150,7 +150,6 @@ NewX509::NewX509(QWidget *parent) // last polish on_certList_currentIndexChanged(0); certList->setDisabled(true); - checkAuthKeyId(); tabWidget->setCurrentIndex(0); attrWidget->hide(); pt = none; @@ -418,7 +417,6 @@ void NewX509::on_certList_currentIndexChanged(int) if (sna < notAfter->getDate()) notAfter->setDate(sna); - checkAuthKeyId(); if (templ.isEmpty()) return; @@ -458,21 +456,8 @@ void NewX509::on_applyTemplate_clicked() fromTemplate(temp); } -void NewX509::checkAuthKeyId() -{ - bool enabled = false; - - if (foreignSignRB->isChecked()) { - if (getSelectedSigner()->hasExtension(NID_subject_key_identifier)) { - enabled = true; - } - } - authKey->setEnabled(enabled); -} - void NewX509::on_foreignSignRB_toggled(bool checked) { - checkAuthKeyId(); switchHashAlgo(); certList->setEnabled(checked); } @@ -482,11 +467,6 @@ void NewX509::on_selfSignRB_toggled(bool checked) serialNr->setEnabled(checked); } -void NewX509::on_subKey_clicked() -{ - checkAuthKeyId(); -} - void NewX509::newKeyDone(QString name) { QStringList keys; @@ -626,6 +606,7 @@ void NewX509::setupTmpCtx() pki_x509 *signcert; pki_x509req *req = NULL; a1int serial; + QString errtxt; // initially create temporary ctx cert if (ctx_cert) @@ -648,7 +629,6 @@ void NewX509::setupTmpCtx() } ctx_cert->setSerial(serial); initCtx(ctx_cert, signcert, req); - ctx_cert->addV3ext(getSubKeyIdent()); } void NewX509::editV3ext(QLineEdit *le, QString types, int n) @@ -709,6 +689,7 @@ void NewX509::on_adv_validate_clicked() nconf_data->setReadOnly(true); adv_validate->setText(tr("Edit")); + checkExtDuplicates(); } else { nconf_data->document()->setPlainText(v3ext_backup); nconf_data->setReadOnly(false); diff --git a/widgets/NewX509.h b/widgets/NewX509.h index f56a8635..2b1d799f 100644 --- a/widgets/NewX509.h +++ b/widgets/NewX509.h @@ -88,9 +88,9 @@ class NewX509: public QDialog, public Ui::NewX509 void initCtx(pki_x509 *subj, pki_x509 *iss, pki_x509req *req); void setBasicConstraints(const x509v3ext &e); void setExt(const x509v3ext &ext); - void checkAuthKeyId(); void switchHashAlgo(); void addReqAttributes(pki_x509req *req); + void checkExtDuplicates(); public slots: void on_fromReqCB_clicked(); void on_keyList_currentIndexChanged(const QString &); @@ -105,7 +105,6 @@ class NewX509: public QDialog, public Ui::NewX509 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_certList_currentIndexChanged(int index); diff --git a/widgets/NewX509_ext.cpp b/widgets/NewX509_ext.cpp index 754eee18..1a2f5239 100644 --- a/widgets/NewX509_ext.cpp +++ b/widgets/NewX509_ext.cpp @@ -28,7 +28,7 @@ x509v3ext NewX509::getBasicConstraints() cont << ca[basicCA->currentIndex()]; if (!basicPath->text().isEmpty()) cont << (QString)"pathlen:" + basicPath->text(); - ext.create(NID_basic_constraints, cont.join(", ")); + ext.create(NID_basic_constraints, cont.join(", "), &ext_ctx); } return ext; } @@ -64,7 +64,7 @@ x509v3ext NewX509::getAuthKeyIdent() "keyid,issuer:always", &ext_ctx); else ext.create(NID_authority_key_identifier, - "keyid:always", &ext_ctx); + "keyid,issuer", &ext_ctx); } return ext; } @@ -88,7 +88,7 @@ x509v3ext NewX509::getKeyUsage() } if (kuCritical->isChecked() && cont.count() > 0) cont.prepend("critical"); - ext.create(NID_key_usage, cont.join(", ")); + ext.create(NID_key_usage, cont.join(", "), &ext_ctx); return ext; } @@ -107,7 +107,7 @@ x509v3ext NewX509::getEkeyUsage() } if (ekuCritical->isChecked() && cont.count() > 0) cont.prepend("critical"); - ext.create(NID_ext_key_usage, cont.join(", ")); + ext.create(NID_ext_key_usage, cont.join(", "), &ext_ctx); return ext; } @@ -147,7 +147,7 @@ x509v3ext NewX509::getCrlDist() { x509v3ext ext; if (!crlDist->text().isEmpty()) { - ext.create(NID_crl_distribution_points, crlDist->text()); + ext.create(NID_crl_distribution_points, crlDist->text(), &ext_ctx); } return ext; } @@ -191,7 +191,7 @@ x509v3ext NewX509::getAuthInfAcc() QString aia_txt = getAuthInfAcc_string(); if (!aia_txt.isEmpty()) { - ext.create(NID_info_access, aia_txt); + ext.create(NID_info_access, aia_txt, &ext_ctx); } return ext; } @@ -203,9 +203,9 @@ extList NewX509::getAdvanced() BIO *bio; extList elist; long err_line=0; - STACK_OF(X509_EXTENSION) *sk = NULL; + STACK_OF(X509_EXTENSION) **sk, *sk_tmp = NULL; char ext_name[] = "ext"; - int ret, i; + int ret, i, start; conf_str = nconf_data->toPlainText(); if (conf_str.isEmpty()) @@ -233,10 +233,20 @@ extList NewX509::getAdvanced() BIO_free(bio); return elist; } + + if (ext_ctx.subject_cert) { + sk = &ext_ctx.subject_cert->cert_info->extensions; + start = *sk ? sk_X509_EXTENSION_num(*sk) : 0; + } else { + sk = &sk_tmp; + start = 0; + } + X509V3_set_nconf(&ext_ctx, conf); - X509V3_EXT_add_nconf_sk(conf, &ext_ctx, ext_name, &sk); - elist.setStack(sk); - sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free); + X509V3_EXT_add_nconf_sk(conf, &ext_ctx, ext_name, sk); + elist.setStack(*sk, start); + if (sk == &sk_tmp) + sk_X509_EXTENSION_pop_free(sk_tmp, X509_EXTENSION_free); X509V3_set_nconf(&ext_ctx, NULL); NCONF_free(conf); BIO_free(bio); @@ -266,7 +276,6 @@ extList NewX509::getAllExt() ne += getAdvanced(); ne += getNetscapeExt(); return ne; - } extList NewX509::getNetscapeExt() @@ -287,14 +296,14 @@ extList NewX509::getNetscapeExt() } } - el << ext.create(NID_netscape_cert_type, cont.join(", ")); - el << ext.create(NID_netscape_base_url, nsBaseUrl->text()); - el << ext.create(NID_netscape_revocation_url, nsRevocationUrl->text()); - el << ext.create(NID_netscape_ca_revocation_url, nsCARevocationUrl->text()); - el << ext.create(NID_netscape_renewal_url, nsRenewalUrl->text()); - el << ext.create(NID_netscape_ca_policy_url, nsCaPolicyUrl->text()); - el << ext.create(NID_netscape_ssl_server_name, nsSslServerName->text()); - el << ext.create(NID_netscape_comment, nsComment->text()); + el << ext.create(NID_netscape_cert_type, cont.join(", "), &ext_ctx); + el << ext.create(NID_netscape_base_url, nsBaseUrl->text(), &ext_ctx); + el << ext.create(NID_netscape_revocation_url, nsRevocationUrl->text(), &ext_ctx); + el << ext.create(NID_netscape_ca_revocation_url, nsCARevocationUrl->text(), &ext_ctx); + el << ext.create(NID_netscape_renewal_url, nsRenewalUrl->text(), &ext_ctx); + el << ext.create(NID_netscape_ca_policy_url, nsCaPolicyUrl->text(), &ext_ctx); + el << ext.create(NID_netscape_ssl_server_name, nsSslServerName->text(), &ext_ctx); + el << ext.create(NID_netscape_comment, nsComment->text(), &ext_ctx); return el; } @@ -307,10 +316,37 @@ void NewX509::initCtx(pki_x509 *subj, pki_x509 *iss, pki_x509req *req) if (iss) s = iss->getCert(); if (req) r = req->getReq(); - memset(&ext_ctx, 0, sizeof(X509V3_CTX)); X509V3_set_ctx(&ext_ctx, s, s1, r, NULL, 0); } +void NewX509::checkExtDuplicates() +{ + int i, start, cnt, n1, n; + X509_EXTENSION *e, *e1; + STACK_OF(X509_EXTENSION) *sk; + + if (ext_ctx.subject_cert) { + sk = ext_ctx.subject_cert->cert_info->extensions; + } else + return; + + cnt = sk_X509_EXTENSION_num(sk); + for (start=0; start