1 /* vi: set sw=4 ts=4:
2  *
3  * Copyright (C) 2001 - 2014 Christian Hohnstaedt.
4  *
5  * All rights reserved.
6  */
7 
8 
9 #include "CertDetail.h"
10 #include "KeyDetail.h"
11 #include "MainWindow.h"
12 #include "distname.h"
13 #include "clicklabel.h"
14 #include "XcaWarning.h"
15 #include "Help.h"
16 #include "OidResolver.h"
17 #include "lib/func.h"
18 #include <QLabel>
19 #include <QPushButton>
20 #include <QLineEdit>
21 #include <QMessageBox>
22 
CertDetail(QWidget * w)23 CertDetail::CertDetail(QWidget *w)
24 	: QDialog(w ?: mainwin), keySqlId(), issuerSqlId(), thisSqlId()
25 {
26 	setupUi(this);
27 	setWindowTitle(XCA_TITLE);
28 	showConf = false;
29 	myPubKey = NULL;
30 	tmpPubKey = NULL;
31 
32 	Database.connectToDbChangeEvt(this, SLOT(itemChanged(pki_base*)));
33 }
34 
on_showExt_clicked()35 void CertDetail::on_showExt_clicked()
36 {
37 	if (showConf) {
38 		showConf = false;
39 		v3extensions->document()->setHtml(exts);
40 		showExt->setText(tr("Show config"));
41 	} else {
42 		showConf = true;
43 		v3extensions->document()->setPlainText(conf);
44 		showExt->setText(tr("Show extensions"));
45 	}
46 
47 }
48 
setX509super(pki_x509super * x)49 void CertDetail::setX509super(pki_x509super *x)
50 {
51 	descr->setText(x->getIntName());
52 	thisSqlId = x->getSqlItemId();
53 
54 	// examine the key
55 	myPubKey = x->getRefKey();
56 	if (myPubKey) {
57 		privKey->setText(myPubKey->getIntName());
58 		privKey->setClickText(myPubKey->getSqlItemId().toString());
59 		if (myPubKey->isPrivKey()) {
60 			privKey->setGreen();
61 		} else {
62 			privKey->setRed();
63 		}
64 	} else {
65 		tmpPubKey = myPubKey = x->getPubKey();
66 		privKey->setText(tr("Show public key"));
67 		privKey->setRed();
68 		myPubKey->setIntName(x->getIntName());
69 		myPubKey->setComment(tr("This key is not in the database."));
70 	}
71 
72 	if (!myPubKey) {
73 		privKey->setText(tr("Not available"));
74 		privKey->setDisabled(true);
75 		privKey->disableToolTip();
76 	} else {
77 		keySqlId = myPubKey->getSqlItemId();
78 	}
79 	connect(privKey, SIGNAL(doubleClicked(QString)),
80 		this, SLOT(showPubKey()));
81 
82 	// details of the subject
83 	subject->setX509name(x->getSubject());
84 
85 	// V3 extensions
86 	extList el = x->getV3ext();
87 	if (el.count() == 0) {
88 		tabwidget->removeTab(4);
89 	} else {
90 		exts = el.getHtml("<br>");
91 		el.genGenericConf(&conf);
92 		v3extensions->document()->setHtml(exts);
93 	}
94 
95 	// Algorithm
96 	sigAlgo->setText(x->getSigAlg());
97 	connect(sigAlgo, SIGNAL(doubleClicked(QString)),
98 		MainWindow::getResolver(), SLOT(searchOid(QString)));
99 
100 	// Comment
101 	comment->setPlainText(x->getComment());
102 
103 	setCert(dynamic_cast<pki_x509*>(x));
104 	setReq(dynamic_cast<pki_x509req*>(x));
105 }
106 
setCert(pki_x509 * cert)107 void CertDetail::setCert(pki_x509 *cert)
108 {
109 	if (!cert)
110 		return;
111 	image->setPixmap(QPixmap(":certImg"));
112 	headerLabel->setText(tr("Details of the Certificate"));
113 	mainwin->helpdlg->register_ctxhelp_button(this, "certdetail");
114 	try {
115 		// No attributes
116 		tabwidget->removeTab(3);
117 
118 		// examine the signature
119 		if (cert->getSigner() == NULL) {
120 			signature->setText(tr("Signer unknown"));
121 			signature->setDisabled(true);
122 			signature->disableToolTip();
123 		} else if (cert == cert->getSigner())  {
124 			signature->setText(tr("Self signed"));
125 			signature->setGreen();
126 			signature->disableToolTip();
127 		} else {
128 			pki_x509 *issuer = cert->getSigner();
129 			signature->setText(issuer->getIntName());
130 			signature->setClickText(issuer->getSqlItemId().toString());
131 			signature->setGreen();
132 			issuerSqlId = issuer->getSqlItemId();
133 
134 			connect(signature, SIGNAL(doubleClicked(QString)),
135 				this, SLOT(showIssuer()));
136 		}
137 
138 		// the serial
139 		serialNr->setText(cert->getSerial());
140 
141 		// details of the issuer
142 		issuer->setX509name(cert->getIssuerName());
143 
144 		// The dates
145 		notBefore->setText(cert->getNotBefore().toPretty());
146 		notBefore->setToolTip(cert->getNotBefore().toPrettyGMT());
147 		notAfter->setText(cert->getNotAfter().toPretty());
148 		notAfter->setToolTip(cert->getNotAfter().toPrettyGMT());
149 
150 		// validation of the Date
151 		dateValid->disableToolTip();
152 		if (cert->isRevoked()) {
153 			x509rev rev = cert->getRevocation();
154 			dateValid->setText(tr("Revoked at %1")
155 				.arg(rev.getDate().toPretty()));
156 			dateValid->setRed();
157 			dateValid->setToolTip(rev.getDate().toPrettyGMT());
158 		} else if (!cert->checkDate()) {
159 			dateValid->setText(tr("Not valid"));
160 			dateValid->setRed();
161 		} else {
162 			dateValid->setGreen();
163 			dateValid->setText(tr("Valid"));
164 		}
165 		// the fingerprints
166 		fpMD5->setText(cert->fingerprint(EVP_md5()));
167 		fpSHA1->setText(cert->fingerprint(EVP_sha1()));
168 		QString fp = cert->fingerprint(EVP_sha256());
169 		int x = fp.size() / 2;
170 		fp = fp.mid(0,x) + "\n" + fp.mid(x+1, -1);
171 		fpSHA256->setText(fp);
172 
173 		openssl_error();
174 	} catch (errorEx &err) {
175 		XCA_WARN(err.getString());
176 	}
177 }
178 
setReq(pki_x509req * req)179 void CertDetail::setReq(pki_x509req *req)
180 {
181 	if (!req)
182 		return;
183 	image->setPixmap(QPixmap(":csrImg"));
184 	headerLabel->setText(tr("Details of the certificate signing request"));
185 	mainwin->helpdlg->register_ctxhelp_button(this, "csrdetail");
186 	try {
187 		// No issuer
188 		tabwidget->removeTab(2);
189 
190 		// verification
191 		if (!req->verify() ) {
192 			signature->setRed();
193 			signature->setText("Failed");
194 		} else {
195 			signature->setGreen();
196 			signature->setText("PKCS#10");
197 		}
198 		signature->disableToolTip();
199 		fingerprints->hide();
200 		validity->hide();
201 		serialLabel->hide();
202 		serialNr->hide();
203 
204 		// The non extension attributes
205 		int cnt = X509_REQ_get_attr_count(req->getReq());
206 		int added = 0;
207 		QGridLayout *attrLayout = new QGridLayout(attributes);
208 		attrLayout->setAlignment(Qt::AlignTop);
209 		attrLayout->setSpacing(6);
210 		attrLayout->setMargin(11);
211 
212 		for (int i = 0, ii = 0; i<cnt; i++) {
213 			int nid;
214 			QLabel *label;
215 			QString trans;
216 			X509_ATTRIBUTE *att = X509_REQ_get_attr(req->getReq(), i);
217 
218 			nid = OBJ_obj2nid(X509_ATTRIBUTE_get0_object(att));
219 
220 			if (X509_REQ_extension_nid(nid)) {
221 				continue;
222 			}
223 			label = new QLabel(this);
224 			trans = dn_translations[nid];
225 			if (Settings["translate_dn"] && !trans.isEmpty()) {
226 				label->setText(trans);
227 				label->setToolTip(QString(OBJ_nid2sn(nid)));
228 			} else {
229 				label->setText(QString(OBJ_nid2ln(nid)));
230 				label->setToolTip(trans);
231 			}
232 
233 			label->setText(QString(OBJ_nid2ln(nid)));
234 			label->setToolTip(QString(OBJ_nid2sn(nid)));
235 			attrLayout->addWidget(label, ii, 0);
236 			added++;
237 
238 			int count = X509_ATTRIBUTE_count(att);
239 			for (int j=0; j<count; j++) {
240 				ASN1_TYPE *at = X509_ATTRIBUTE_get0_type(att, j);
241 				label = labelFromAsn1String(at->value.asn1_string);
242 				attrLayout->addWidget(label, ii, j +1);
243 			}
244 			ii++;
245 		}
246 		if (!added) {
247 			tabwidget->removeTab(2);
248 		}
249 		openssl_error();
250 	} catch (errorEx &err) {
251 		XCA_WARN(err.getString());
252 	}
253 }
254 
labelFromAsn1String(ASN1_STRING * s)255 QLabel *CertDetail::labelFromAsn1String(ASN1_STRING *s)
256 {
257 	QLabel *label;
258 	label = new CopyLabel(this);
259 	label->setText(asn1ToQString(s));
260 	label->setToolTip(QString(ASN1_tag2str(s->type)));
261 	return label;
262 }
263 
itemChanged(pki_base * pki)264 void CertDetail::itemChanged(pki_base *pki)
265 {
266 	QVariant pkiSqlId = pki->getSqlItemId();
267 
268 	if (pkiSqlId == keySqlId)
269 		privKey->setText(pki->getIntName());
270 	if (pkiSqlId == issuerSqlId)
271 		signature->setText(pki->getIntName());
272 	if (pkiSqlId == thisSqlId)
273 		descr->setText(pki->getIntName());
274 }
275 
showPubKey()276 void CertDetail::showPubKey()
277 {
278 	KeyDetail::showKey(this, myPubKey, !keySqlId.isValid());
279 }
280 
showIssuer()281 void CertDetail::showIssuer()
282 {
283 	showCert(this, Store.lookupPki<pki_x509>(issuerSqlId));
284 }
285 
showCert(QWidget * parent,pki_x509super * x)286 void CertDetail::showCert(QWidget *parent, pki_x509super *x)
287 {
288 	if (!x)
289 		return;
290 	CertDetail *dlg = new CertDetail(parent);
291 	if (!dlg)
292                 return;
293 	dlg->setX509super(x);
294 	if (dlg->exec()) {
295 		db_base *db = Database.modelForPki(x);
296 		if (!db) {
297 			x->setIntName(dlg->descr->text());
298 			x->setComment(dlg->comment->toPlainText());
299 		} else {
300 			db->updateItem(x, dlg->descr->text(),
301 					dlg->comment->toPlainText());
302 		}
303         }
304         delete dlg;
305 }
306 
~CertDetail()307 CertDetail::~CertDetail()
308 {
309 	delete tmpPubKey;
310 }
311