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