1 /* vi: set sw=4 ts=4:
2  *
3  * Copyright (C) 2005 - 2014 Christian Hohnstaedt.
4  *
5  * All rights reserved.
6  */
7 
8 #include "v3ext.h"
9 #include <QLabel>
10 #include <QListWidget>
11 #include <QComboBox>
12 #include <QLineEdit>
13 #include <QHeaderView>
14 #include <QStringList>
15 #include <QMessageBox>
16 #include <QValidator>
17 #include "XcaWarning.h"
18 #include "lib/exception.h"
19 #include "lib/ipvalidator.h"
20 #include "lib/x509v3ext.h"
21 
22 #include <openssl/err.h>
23 
24 
v3ext(QWidget * parent)25 v3ext::v3ext(QWidget *parent)
26 	:QDialog(parent)
27 {
28 	setupUi(this);
29 	setWindowTitle(XCA_TITLE);
30 	tab->horizontalHeader()->setDefaultSectionSize(80);
31 }
32 
addInfo(QLineEdit * myle,const QStringList & sl,int n,X509V3_CTX * ctx)33 void v3ext::addInfo(QLineEdit *myle, const QStringList &sl, int n,
34 		X509V3_CTX *ctx)
35 {
36 	nid = n;
37 	le = myle;
38 	ext_ctx = ctx;
39 	tab->setKeys(sl);
40 	keys = sl;
41 	tab->setInfoLabel(infoLabel);
42 	connect(tab->itemDelegateForColumn(1),
43 		SIGNAL(setupLineEdit(const QString &, QLineEdit *)),
44 		this, SLOT(setupLineEdit(const QString &, QLineEdit *)));
45 	if (le && !le->text().trimmed().isEmpty())
46 		addItem(le->text());
47 	if (n != NID_subject_alt_name)
48 		copy_cn->hide();
49 }
50 
addItem(QString list)51 void v3ext::addItem(QString list)
52 {
53 	int i;
54 	QStringList sl;
55 	sl = list.split(',');
56 	if (sl[0] == "critical") {
57 		sl.takeFirst();
58 		critical->setChecked(true);
59 	}
60 	for (i=0; i< sl.count(); i++) {
61 		if (sl[i] == "DNS:copycn" && nid == NID_subject_alt_name)
62 			copy_cn->setChecked(true);
63 		else
64 			addEntry(sl[i]);
65 	}
66 }
67 
setupLineEdit(const QString & s,QLineEdit * l)68 void v3ext::setupLineEdit(const QString &s, QLineEdit *l)
69 {
70 	QString tt;
71 	QValidator *v = NULL;
72 
73 	if (s == "email") {
74 		if (nid == NID_subject_alt_name)
75 			tt = tr("An email address or 'copy'");
76 		else
77 			tt = tr("An email address");
78 	} else if (s == "RID") {
79 		tt = tr("A registered ID: OBJECT IDENTIFIER");
80 		QRegExp rx("[a-zA-Z0-9.]+");
81 		v = new QRegExpValidator(rx, this);
82 	} else if (s == "URI") {
83 		tt = tr("A uniform resource indicator");
84 		QRegExp rx("[a-z][a-z0-9\\.\\+\\-]*://.*");
85                 v = new QRegExpValidator(rx, this);
86 	} else if (s == "DNS") {
87 		if (nid == NID_subject_alt_name)
88 			tt = tr("A DNS domain name or 'copycn'");
89 		else
90 			tt = tr("A DNS domain name");
91 	} else if (s == "IP") {
92 		tt = tr("An IP address");
93 		v = new ipValidator();
94 	} else if (s == "otherName") {
95 		tt = tr("Syntax: <OID>;TYPE:text like '1.2.3.4:UTF8:name'");
96 		QRegExp rx("[a-zA-Z0-9.]+;.*");
97 		v = new QRegExpValidator(rx, this);
98 	} else if (s == "issuer") {
99 		tt = tr("No editing. Only 'copy' allowed here");
100 		l->setText(QString("copy"));
101 		l->setReadOnly(true);
102 		QRegExp rx("copy");
103                 v = new QRegExpValidator(rx, this);
104 	}
105 	l->setToolTip(tt);
106 	l->setValidator(v);
107 }
108 
109 /* for one TYPE:Content String */
addEntry(QString line)110 void v3ext::addEntry(QString line)
111 {
112 	int idx;
113 	QString type, value;
114 
115 	line = line.trimmed();
116 	idx = line.indexOf(':');
117 
118 	if (idx == -1) {
119 		value = line;
120 	} else {
121 		type = line.left(idx);
122 		value = line.mid(idx+1);
123 	}
124 	if (!keys.contains(type)) {
125 		type = keys[0];
126 		value = line;
127 	}
128 	tab->addRow(QStringList(type) << value);
129 }
130 
toString()131 QString v3ext::toString()
132 {
133 	QStringList str;
134 	int i, row = tab->rowCount();
135 
136 	if (critical->isChecked())
137 		str << "critical";
138 	if (copy_cn->isChecked())
139 		str << "DNS:copycn";
140 
141 	for (i=0; i<row; i++) {
142 		QStringList s = tab->getRow(i);
143 		str += s[0] + ":" +s[1];
144 	}
145 	return str.join(", ");
146 }
147 
on_apply_clicked()148 void v3ext::on_apply_clicked()
149 {
150 	__validate(false);
151 	if (le)
152 		le->setText(toString());
153 	accept();
154 }
155 
__validate(bool showSuccess)156 bool v3ext::__validate(bool showSuccess)
157 {
158 	x509v3ext ext;
159 	QString str, error;
160 	validate->setFocus(Qt::OtherFocusReason);
161 	str = prefix + toString();
162 	ext.create(nid, str, ext_ctx);
163 	while (int i = ERR_get_error() ) {
164 		error += ERR_error_string(i ,NULL);
165 		error += "\n";
166 	}
167 	if (!error.isEmpty()) {
168 		XCA_WARN(tr("Validation failed:\n'%1'\n%2").
169 			arg(str).arg(error));
170 		return false;
171 	}
172 	if (showSuccess) {
173 		XCA_INFO(tr("Validation successful:\n'%1'").
174 			arg(ext.getValue()));
175 	}
176 	return true;
177 }
178 
on_validate_clicked()179 void v3ext::on_validate_clicked()
180 {
181 	__validate(true);
182 }
183