xca/widgets/v3ext.cpp
Christian Hohnstaedt a9b5caa0bc Bug #3461403 Error when create certificate with CRL distribution point
become more userfriendly:
 - by indicating the validity with an appropriate
   icon in front of AIA, SAN IAN and CDP.

 - by checking the validity before creating the real certificate.

 - by improving the edit button, to automatically add an "URI"
   as type, if the type is missing, or is for example "http"
2012-04-01 12:41:43 +02:00

199 lines
5.1 KiB
C++

/* vi: set sw=4 ts=4:
*
* Copyright (C) 2001 - 2010 Christian Hohnstaedt.
*
* All rights reserved.
*/
#include "v3ext.h"
#include <QtGui/QLabel>
#include <QtGui/QListWidget>
#include <QtGui/QComboBox>
#include <QtGui/QLineEdit>
#include <QtGui/QHeaderView>
#include <QtCore/QStringList>
#include <QtGui/QMessageBox>
#include "MainWindow.h"
#include "lib/exception.h"
// Complex regular expressions.
#define BYTE_DEC "(?:25[0-5]|2[0-4]\\d|1\\d\\d|\\d{1,2})"
#define IPV4_ADDR "(?:(?:" BYTE_DEC "\\.){3}" BYTE_DEC ")"
#define SHORT_HEX "[0-9a-fA-F]{1,4}"
#define IPV6_FORM0 "(?:(?:" SHORT_HEX ":){7}" SHORT_HEX ")"
#define IPV6_FORM1 "(?::(?::" SHORT_HEX "){1,7})"
#define IPV6_FORM2 "(?:" SHORT_HEX ":(?::" SHORT_HEX "){1,6})"
#define IPV6_FORM3 "(?:(?:" SHORT_HEX ":){2}(?::" SHORT_HEX "){1,5})"
#define IPV6_FORM4 "(?:(?:" SHORT_HEX ":){3}(?::" SHORT_HEX "){1,4})"
#define IPV6_FORM5 "(?:(?:" SHORT_HEX ":){4}(?::" SHORT_HEX "){1,3})"
#define IPV6_FORM6 "(?:(?:" SHORT_HEX ":){5}(?::" SHORT_HEX "){1,2})"
#define IPV6_FORM7 "(?:(?:" SHORT_HEX ":){6}:" SHORT_HEX ")"
#define IPV6_FORM8 "(?:(?:" SHORT_HEX ":){7}:)"
#define IPV6_FORM9 "(?:::)"
#define IPV6_V4_0 "(?:(?:" SHORT_HEX ":){6}" IPV4_ADDR ")"
#define IPV6_V4_1 "(?::(?::" SHORT_HEX "){0,5}:" IPV4_ADDR ")"
#define IPV6_V4_2 "(?:" SHORT_HEX ":(?::" SHORT_HEX "){0,4}:" IPV4_ADDR ")"
#define IPV6_V4_3 "(?:(?:" SHORT_HEX ":){2}(?::" SHORT_HEX "){0,3}:" IPV4_ADDR ")"
#define IPV6_V4_4 "(?:(?:" SHORT_HEX ":){3}(?::" SHORT_HEX "){0,2}:" IPV4_ADDR ")"
#define IPV6_V4_5 "(?:(?:" SHORT_HEX ":){4}(?::" SHORT_HEX ")?:" IPV4_ADDR ")"
#define IPV6_V4_6 "(?:(?:" SHORT_HEX ":){5}:" IPV4_ADDR ")"
#define IPV6_ADDR "(?:" IPV6_FORM0 "|" IPV6_FORM1 "|" IPV6_FORM2 "|" \
IPV6_FORM3 "|" IPV6_FORM4 "|" IPV6_FORM5 "|" \
IPV6_FORM6 "|" IPV6_FORM7 "|" IPV6_FORM8 "|" \
IPV6_FORM9 "|" IPV6_V4_0 "|" IPV6_V4_1 "|" \
IPV6_V4_2 "|" IPV6_V4_3 "|" IPV6_V4_4 "|" \
IPV6_V4_5 "|" IPV6_V4_6 ")"
v3ext::v3ext(QWidget *parent)
:QDialog(parent)
{
setupUi(this);
setWindowTitle(XCA_TITLE);
tab->horizontalHeader()->setDefaultSectionSize(80);
}
void v3ext::addInfo(QLineEdit *myle, const QStringList &sl, int n,
X509V3_CTX *ctx)
{
nid = n;
le = myle;
ext_ctx = ctx;
tab->setKeys(sl);
keys = sl;
tab->setInfoLabel(infoLabel);
connect(tab->itemDelegateForColumn(1),
SIGNAL(setupLineEdit(const QString &, QLineEdit *)),
this, SLOT(setupLineEdit(const QString &, QLineEdit *)));
if (le && !le->text().trimmed().isEmpty())
addItem(le->text());
}
void v3ext::addItem(QString list)
{
int i;
QStringList sl;
sl = list.split(',');
if (sl[0] == "critical") {
sl.takeFirst();
critical->setChecked(true);
}
for (i=0; i< sl.count(); i++)
addEntry(sl[i]);
}
void v3ext::setupLineEdit(const QString &s, QLineEdit *l)
{
QString tt;
QValidator *v = NULL;
if (s == "email") {
if (nid == NID_subject_alt_name)
tt = tr("An email address or 'copy'");
else
tt = tr("An email address");
} else if (s == "RID") {
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");
QRegExp rx("[a-z]+://.*");
v = new QRegExpValidator(rx, this);
} else if (s == "DNS") {
tt = tr("a DNS domain name");
} else if (s == "IP") {
tt = tr("an IP address");
QRegExp rx(IPV4_ADDR "|" IPV6_ADDR);
v = new QRegExpValidator(rx, this);
} else if (s == "otherName") {
tt = tr("Syntax: <OID>;TYPE:text like '1.2.3.4:UTF8:name'");
QRegExp rx("[a-zA-Z0-9.]+;.*");
v = new QRegExpValidator(rx, this);
} else if (s == "issuer") {
tt = tr("No editing. Only 'copy' allowed here");
l->setText(QString("copy"));
l->setReadOnly(true);
QRegExp rx("copy");
v = new QRegExpValidator(rx, this);
}
l->setToolTip(tt);
l->setValidator(v);
}
/* for one TYPE:Content String */
void v3ext::addEntry(QString line)
{
int idx = line.indexOf(':');
QString type, value;
if (idx == -1) {
value = line;
} else {
type = line.left(idx);
value = line.mid(idx+1);
}
if (!keys.contains(type)) {
type = keys[0];
value = line;
}
tab->addRow(QStringList(type) << value);
}
QString v3ext::toString()
{
QStringList str;
int i, row = tab->rowCount();
if (critical->isChecked())
str << "critical";
for (i=0; i<row; i++) {
QStringList s = tab->getRow(i);
str += s[0] + ":" +s[1];
}
return str.join(",");
}
void v3ext::on_apply_clicked()
{
if (le)
le->setText(toString());
__validate(false);
accept();
}
bool v3ext::__validate(bool showSuccess)
{
x509v3ext ext;
QString str, error;
if (nid==NID_info_access) {
str = "OCSP;";
}
str += toString();
ext.create(nid, str, ext_ctx);
while (int i = ERR_get_error() ) {
error += ERR_error_string(i ,NULL);
error += "\n";
}
if (!error.isEmpty()) {
QMessageBox::warning(this, XCA_TITLE,
tr("Validation failed:\n'%1'\n%2").
arg(str).arg(error));
return false;
}
if (showSuccess) {
QMessageBox::information(this, XCA_TITLE,
tr("Validation successful:\n'%1'").
arg(ext.getValue()));
}
return true;
}
void v3ext::on_validate_clicked()
{
__validate(true);
}