1 /* vi: set sw=4 ts=4:
2  *
3  * Copyright (C) 2015 Christian Hohnstaedt.
4  *
5  * All rights reserved.
6  */
7 
8 #include "CertTreeView.h"
9 #include "XcaWarning.h"
10 #include "MainWindow.h"
11 #include "RevocationList.h"
12 #include "NewCrl.h"
13 #include "lib/database_model.h"
14 #include "lib/db_crl.h"
15 
16 #include <QAbstractItemModel>
17 #include <QAbstractItemView>
18 #include <QMenu>
19 
fillContextMenu(QMenu * menu,QMenu * subExport,const QModelIndex & index,QModelIndexList indexes)20 void CertTreeView::fillContextMenu(QMenu *menu, QMenu *subExport,
21 		const QModelIndex &index, QModelIndexList indexes)
22 {
23 	QMenu *subCa;
24 	bool parentCanSign, multi, hasScard, sameParent,
25 		allRevoked, allUnrevoked;
26 	pki_key *privkey;
27 
28 	X509SuperTreeView::fillContextMenu(menu, subExport, index, indexes);
29 
30 	menu->addAction(tr("Import PKCS#12"), this, SLOT(loadPKCS12()));
31 	menu->addAction(tr("Import from PKCS#7"), this, SLOT(loadPKCS7()));
32 
33 	pki_x509 *cert = db_base::fromIndex<pki_x509>(index);
34 	pki_x509 *parent;
35 
36 	if (indexes.size() == 0 || !cert)
37 		return;
38 
39 	privkey = cert->getRefKey();
40 	parent = cert->getSigner();
41 	parentCanSign = parent && parent->canSign() && (parent != cert);
42 	hasScard = pkcs11::libraries.loaded();
43 
44 	multi = indexes.size() > 1;
45 
46 	allUnrevoked = allRevoked = sameParent = true;
47 	foreach(QModelIndex i, indexes) {
48 		pki_x509 *c = db_base::fromIndex<pki_x509>(i);
49 		if (!c)
50 			continue;
51 		if (c->getSigner() != parent)
52 			sameParent = false;
53 		if (c->isRevoked())
54 			allUnrevoked = false;
55 		else
56 			allRevoked = false;
57 	}
58 
59 	if (!multi) {
60 		transform->addAction(tr("Request"), this, SLOT(toRequest()))->
61 			setEnabled(privkey && privkey->isPrivKey());
62 		subExport->addAction(tr("Security token"), this,
63 			SLOT(toToken()))->setEnabled(hasScard);
64 		subExport->addAction(tr("Other token"), this,
65 			SLOT(toOtherToken()))->setEnabled(
66 					hasScard && privkey && privkey->isToken());
67 
68 		transform->addAction(tr("Similar Certificate"), this,
69 			SLOT(toCertificate()));
70 
71 		menu->addAction(tr("Delete from Security token"), this,
72 			SLOT(deleteFromToken()))->setEnabled(hasScard);
73 
74 		subCa = menu->addMenu(tr("CA"));
75 		subCa->addAction(tr("Properties"), this, SLOT(caProperties()));
76 		subCa->addAction(tr("Generate CRL"), this, SLOT(genCrl()));
77 		subCa->addAction(tr("Manage revocations"), this,
78 			 SLOT(manageRevocations()));
79 		subCa->setEnabled(cert->canSign());
80 	}
81 	if (parent == cert && parent->canSign())
82 		menu->addAction(tr("Renewal"), this, SLOT(certRenewal()));
83 	if (sameParent && parentCanSign) {
84 		QString n = multi ? QString(" [%1]").arg(indexes.size()) : "";
85 		menu->addAction(tr("Renewal") +n, this, SLOT(certRenewal()));
86 		if (allUnrevoked)
87 			menu->addAction(tr("Revoke") +n, this, SLOT(revoke()));
88 		if (allRevoked)
89 			menu->addAction(tr("Unrevoke") +n, this,
90 				SLOT(unRevoke()));
91 	}
92 }
93 
toRequest()94 void CertTreeView::toRequest()
95 {
96 	if (basemodel)
97 		certs()->toRequest(currentIndex());
98 }
99 
toToken()100 void CertTreeView::toToken()
101 {
102 	if (basemodel)
103 		certs()->toToken(currentIndex(), false);
104 }
105 
toOtherToken()106 void CertTreeView::toOtherToken()
107 {
108 	if (basemodel)
109 		certs()->toToken(currentIndex(), true);
110 }
111 
loadPKCS12()112 void CertTreeView::loadPKCS12()
113 {
114 	if (basemodel) {
115 		load_pkcs12 l;
116 		certs()->load_default(l);
117 	}
118 }
119 
loadPKCS7()120 void CertTreeView::loadPKCS7()
121 {
122 	if (basemodel) {
123 		load_pkcs7 l;
124 		certs()->load_default(l);
125 	}
126 }
127 
genCrl()128 void CertTreeView::genCrl()
129 {
130 	pki_x509 *ca = db_base::fromIndex<pki_x509>(currentIndex());
131 
132 	NewCrl::newCrl(this, ca);
133 }
134 
toCertificate()135 void CertTreeView::toCertificate()
136 {
137 	if (basemodel)
138 		certs()->toCertificate(currentIndex());
139 }
140 
deleteFromToken()141 void CertTreeView::deleteFromToken()
142 {
143 	pki_x509 *cert = db_base::fromIndex<pki_x509>(currentIndex());
144 	try {
145 		cert->deleteFromToken();
146 	} catch (errorEx &err) {
147 		XCA_ERROR(err);
148 	}
149 }
150 
changeView()151 void CertTreeView::changeView()
152 {
153 	if (!basemodel)
154 		return;
155 	XcaTreeView::changeView();
156 	mainwin->BNviewState->setText(basemodel->treeViewMode() ?
157 		tr("Plain View") : tr("Tree View"));
158 }
159 
manageRevocations()160 void CertTreeView::manageRevocations()
161 {
162 	pki_x509 *cert = db_base::fromIndex<pki_x509>(currentIndex());
163 	if (!cert)
164 		return;
165 
166 	RevocationList *dlg = new RevocationList();
167 	dlg->setRevList(cert->getRevList(), cert);
168 	if (dlg->exec()) {
169 		cert->setRevocations(dlg->getRevList());
170 		columnsChanged();
171 	}
172 }
173 
caProperties()174 void CertTreeView::caProperties()
175 {
176 	if (basemodel)
177 		certs()->caProperties(currentIndex());
178 }
179 
certRenewal()180 void CertTreeView::certRenewal()
181 {
182 	if (basemodel)
183 		certs()->certRenewal(getSelectedIndexes());
184 }
185 
revoke()186 void CertTreeView::revoke()
187 {
188 	if (basemodel)
189 		certs()->revoke(getSelectedIndexes());
190 }
191 
unRevoke()192 void CertTreeView::unRevoke()
193 {
194 	if (basemodel)
195 		certs()->unRevoke(getSelectedIndexes());
196 }
197