mirror of
https://github.com/chris2511/xca.git
synced 2026-09-12 19:51:05 +05:00
Close #36: Support adding CN to X509v3 SAN automatically
Translate the special text "DNS:copycn" in the SAN to the final common name. Add checkobox "Copy Common Name" to the SAN Edit box, for a user-friendly editing of the "DNS:copycn" During certificate creation, an empty common name together with "DNS:copycn" in the SAN will raise a warning message and the opportunity to change the settings. Change the SAN in the HTTP-server XCA template from "DNS:your.server.name.here" to "DNS:copycn" to already take advantage of this feature in the default template.
This commit is contained in:
parent
4b2375101b
commit
22966937de
@ -474,7 +474,6 @@ pki_x509 *db_x509::newCert(NewX509 *dlg)
|
||||
pki_x509req *req = NULL;
|
||||
pki_key *signkey = NULL, *clientkey = NULL, *tempkey = NULL;
|
||||
a1int serial;
|
||||
x509name subject;
|
||||
QString intname;
|
||||
|
||||
try {
|
||||
@ -484,7 +483,6 @@ pki_x509 *db_x509::newCert(NewX509 *dlg)
|
||||
clientkey = dlg->getSelectedKey();
|
||||
if (!clientkey)
|
||||
return NULL;
|
||||
subject = dlg->getX509name();
|
||||
intname = dlg->description->text();
|
||||
} else {
|
||||
// A PKCS#10 Request was selected
|
||||
@ -496,10 +494,6 @@ pki_x509 *db_x509::newCert(NewX509 *dlg)
|
||||
clientkey = req->getPubKey();
|
||||
tempkey = clientkey;
|
||||
}
|
||||
if (dlg->reqSubChange->isChecked())
|
||||
subject = dlg->getX509name();
|
||||
else
|
||||
subject = req->getSubject();
|
||||
intname = req->getIntName();
|
||||
}
|
||||
TransThrow();
|
||||
@ -509,7 +503,7 @@ pki_x509 *db_x509::newCert(NewX509 *dlg)
|
||||
// initially create cert
|
||||
cert = new pki_x509();
|
||||
cert->setIntName(intname);
|
||||
cert->setSubject(subject);
|
||||
cert->setSubject(dlg->getX509name());
|
||||
cert->setPubKey(clientkey);
|
||||
|
||||
// Step 2 - select Signing
|
||||
|
||||
@ -53,7 +53,17 @@ x509v3ext &x509v3ext::create(int nid, const QString &et, X509V3_CTX *ctx)
|
||||
ext = NULL;
|
||||
}
|
||||
if (!et.isEmpty()) {
|
||||
QByteArray ba = et.toLocal8Bit();
|
||||
QString etext = et;
|
||||
if (et.contains("DNS:copycn") && ctx && ctx->subject_cert &&
|
||||
nid == NID_subject_alt_name)
|
||||
{
|
||||
x509name xn(X509_get_subject_name(ctx->subject_cert));
|
||||
QString cn = xn.getEntryByNid(NID_commonName);
|
||||
if (!cn.isEmpty())
|
||||
etext.replace(QString("DNS:copycn"),
|
||||
QString("DNS:%1").arg(cn));
|
||||
}
|
||||
QByteArray ba = etext.toLocal8Bit();
|
||||
ext = X509V3_EXT_conf_nid(NULL, ctx, nid, ba.data());
|
||||
}
|
||||
if (!ext)
|
||||
|
||||
BIN
misc/CA.xca
BIN
misc/CA.xca
Binary file not shown.
Binary file not shown.
Binary file not shown.
33
ui/v3ext.ui
33
ui/v3ext.ui
@ -12,11 +12,22 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="critical">
|
||||
<property name="text">
|
||||
<string notr="true">Critical</string>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="critical">
|
||||
<property name="text">
|
||||
<string notr="true">Critical</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="copy_cn">
|
||||
<property name="text">
|
||||
<string>Copy Common Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
@ -39,12 +50,6 @@
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="addEntry">
|
||||
<property name="text">
|
||||
@ -78,12 +83,6 @@
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="apply">
|
||||
<property name="text">
|
||||
|
||||
@ -797,6 +797,9 @@ x509name NewX509::getX509name(int _throw)
|
||||
x509name x;
|
||||
int j, row, nid;
|
||||
|
||||
if (fromReqCB->isChecked() && !reqSubChange->isChecked())
|
||||
return getSelectedReq()->getSubject();
|
||||
|
||||
try {
|
||||
foreach(nameEdit ne, nameEdits) {
|
||||
x.addEntryByNid(ne.nid, ne.edit->text());
|
||||
@ -857,15 +860,14 @@ void NewX509::setupTmpCtx()
|
||||
|
||||
// initially create temporary ctx cert
|
||||
if (ctx_cert)
|
||||
delete(ctx_cert);
|
||||
delete ctx_cert;
|
||||
ctx_cert = new pki_x509();
|
||||
ctx_cert->setSubject(getX509name());
|
||||
if (fromReqCB->isChecked()) {
|
||||
req = getSelectedReq();
|
||||
ctx_cert->setSubject(req->getSubject());
|
||||
if (req)
|
||||
key = req->getRefKey();
|
||||
} else {
|
||||
ctx_cert->setSubject(getX509name());
|
||||
key = getSelectedKey();
|
||||
}
|
||||
if (key)
|
||||
@ -1097,10 +1099,7 @@ QString NewX509::mandatoryDnRemain()
|
||||
if (QString(Settings["mandatory_dn"]).isEmpty())
|
||||
return QString();
|
||||
|
||||
if (fromReqCB->isChecked() && !reqSubChange->isChecked())
|
||||
n = getSelectedReq()->getSubject();
|
||||
else
|
||||
n = getX509name();
|
||||
n = getX509name();
|
||||
|
||||
for (i=0; i< n.entryCount(); i++) {
|
||||
int j = dnl.indexOf(QString(OBJ_nid2sn(n.nid(i))));
|
||||
@ -1345,5 +1344,25 @@ void NewX509::accept()
|
||||
break;
|
||||
}
|
||||
}
|
||||
QString cn = xn.getEntryByNid(NID_commonName);
|
||||
QStringList san = subAltName->text().split(QRegExp(" *, *"));
|
||||
if (cn.isEmpty() && san.contains("DNS:copycn") && pt != tmpl) {
|
||||
gotoTab(2);
|
||||
xcaWarning msg(this, tr("The subject alternative name shall contain a copy of the common name. However, the common name is empty."));
|
||||
msg.addButton(QMessageBox::Ok)->setText(tr("Edit extensions"));
|
||||
msg.addButton(QMessageBox::Close)->setText(tr("Abort rollout"));
|
||||
msg.addButton(QMessageBox::Apply)->setText(tr("Continue rollout"));
|
||||
switch (msg.exec())
|
||||
{
|
||||
case QMessageBox::Ok:
|
||||
case QMessageBox::Cancel:
|
||||
return;
|
||||
case QMessageBox::Close:
|
||||
reject();
|
||||
return;
|
||||
case QMessageBox::Apply:
|
||||
break;
|
||||
}
|
||||
}
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
@ -41,6 +41,8 @@ void v3ext::addInfo(QLineEdit *myle, const QStringList &sl, int n,
|
||||
this, SLOT(setupLineEdit(const QString &, QLineEdit *)));
|
||||
if (le && !le->text().trimmed().isEmpty())
|
||||
addItem(le->text());
|
||||
if (n != NID_subject_alt_name)
|
||||
copy_cn->hide();
|
||||
}
|
||||
|
||||
void v3ext::addItem(QString list)
|
||||
@ -52,8 +54,12 @@ void v3ext::addItem(QString list)
|
||||
sl.takeFirst();
|
||||
critical->setChecked(true);
|
||||
}
|
||||
for (i=0; i< sl.count(); i++)
|
||||
addEntry(sl[i]);
|
||||
for (i=0; i< sl.count(); i++) {
|
||||
if (sl[i] == "DNS:copycn" && nid == NID_subject_alt_name)
|
||||
copy_cn->setChecked(true);
|
||||
else
|
||||
addEntry(sl[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void v3ext::setupLineEdit(const QString &s, QLineEdit *l)
|
||||
@ -67,17 +73,20 @@ void v3ext::setupLineEdit(const QString &s, QLineEdit *l)
|
||||
else
|
||||
tt = tr("An email address");
|
||||
} else if (s == "RID") {
|
||||
tt = tr("a registered ID: OBJECT IDENTIFIER");
|
||||
tt = tr("A registered ID: OBJECT IDENTIFIER");
|
||||
QRegExp rx("[a-zA-Z0-9.]+");
|
||||
v = new QRegExpValidator(rx, this);
|
||||
} else if (s == "URI") {
|
||||
tt = tr("a uniform resource indicator");
|
||||
tt = tr("A uniform resource indicator");
|
||||
QRegExp rx("[a-z]+://.*");
|
||||
v = new QRegExpValidator(rx, this);
|
||||
} else if (s == "DNS") {
|
||||
tt = tr("a DNS domain name");
|
||||
if (nid == NID_subject_alt_name)
|
||||
tt = tr("A DNS domain name or 'copycn'");
|
||||
else
|
||||
tt = tr("A DNS domain name");
|
||||
} else if (s == "IP") {
|
||||
tt = tr("an IP address");
|
||||
tt = tr("An IP address");
|
||||
v = new ipValidator();
|
||||
} else if (s == "otherName") {
|
||||
tt = tr("Syntax: <OID>;TYPE:text like '1.2.3.4:UTF8:name'");
|
||||
@ -123,6 +132,8 @@ QString v3ext::toString()
|
||||
|
||||
if (critical->isChecked())
|
||||
str << "critical";
|
||||
if (copy_cn->isChecked())
|
||||
str << "DNS:copycn";
|
||||
|
||||
for (i=0; i<row; i++) {
|
||||
QStringList s = tab->getRow(i);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user