1 /* vi: set sw=4 ts=4:
2  *
3  * Copyright (C) 2014 Christian Hohnstaedt.
4  *
5  * All rights reserved.
6  */
7 
8 
9 #include "ExportDialog.h"
10 #include "MainWindow.h"
11 #include "Help.h"
12 #include "XcaWarning.h"
13 #include "lib/base.h"
14 
15 #include <QComboBox>
16 #include <QLineEdit>
17 #include <QFileDialog>
18 #include <QPushButton>
19 #include <QMessageBox>
20 #include <QStringList>
21 
ExportDialog(QWidget * w,const QString & title,const QString & filt,pki_base * pki,const QPixmap & img,QList<exportType> types,const QString & help_ctx)22 ExportDialog::ExportDialog(QWidget *w, const QString &title,
23 			const QString &filt, pki_base *pki, const QPixmap &img,
24 			QList<exportType> types, const QString &help_ctx)
25 	: QDialog(w ?: mainwin)
26 {
27 	setupUi(this);
28 	setWindowTitle(XCA_TITLE);
29 	if (pki)
30 		descr->setText(pki->getIntName());
31 	descr->setReadOnly(true);
32 	image->setPixmap(img);
33 	label->setText(title);
34 	mainwin->helpdlg->register_ctxhelp_button(this, help_ctx);
35 
36 	if (pki) {
37 		QString fn = Settings["workingdir"] +
38 			pki->getUnderlinedName() + "." + types[0].extension;
39 		filename->setText(nativeSeparator(fn));
40 	}
41 	filter = filt + ";;" + tr("All files ( * )");
42 
43 	foreach(exportType t, types) {
44 		QVariant q;
45 		q.setValue(t);
46 		if (t.type == exportType::Separator)
47 			exportFormat->insertSeparator(exportFormat->count());
48 		else
49 			exportFormat->addItem(QString("%1 (*.%2)").
50 					arg(t.desc).arg(t.extension), q);
51 	}
52 
53 	for (int i=0; i < exportType::ETYPE_max; i++)
54 		help.append(QString());
55 	help[exportType::Separator] = "What the heck!?";
56 	help[exportType::PEM] = tr("PEM Text format with headers");
57 	help[exportType::PEM_selected] =
58 		tr("Concatenated list of all selected items in one PEM text file");
59 	help[exportType::PEM_chain] = tr("Concatenated text format of the complete certificate chain in one PEM file");
60 	help[exportType::PEM_unrevoked] =
61 		tr("Concatenated text format of all unrevoked certificates in one PEM file");
62 	help[exportType::PEM_all] =
63 		tr("Concatenated text format of all certificates in one PEM file");
64 	help[exportType::DER] = tr("Binary DER encoded file");
65 	help[exportType::PKCS7] = tr("PKCS#7 encoded single certificate");
66 	help[exportType::PKCS7_chain] =
67 		tr("PKCS#7 encoded complete certificate chain");
68 	help[exportType::PKCS7_unrevoked] =
69 		tr("All unrevoked certificates encoded in one PKCS#7 file");
70 	help[exportType::PKCS7_selected] =
71 		tr("All selected certificates encoded in one PKCS#7 file");
72 	help[exportType::PKCS7_all] =
73 		tr("All certificates encoded in one PKCS#7 file");
74 	help[exportType::PKCS12] =
75 		tr("The certificate and the private key as encrypted PKCS#12 file");
76 	help[exportType::PKCS12_chain] = tr("The complete certificate chain and the private key as encrypted PKCS#12 file");
77 	help[exportType::PEM_cert_key] = tr("Concatenation of the certificate and the unencrypted private key in one PEM file");
78 	help[exportType::PEM_cert_pk8] = tr("Concatenation of the certificate and the encrypted private key in PKCS#8 format in one file");
79 	help[exportType::PEM_key] = tr("Text format of the public key in one PEM file");
80 	help[exportType::DER_key] = tr("Binary DER format of the public key");
81 	help[exportType::PEM_private] =
82 		tr("Unencrypted private key in text format");
83 	help[exportType::PEM_private_encrypt] =
84 		tr("OpenSSL specific encrypted private key in text format");
85 	help[exportType::DER_private] =
86 		tr("Unencrypted private key in binary DER format");
87 	help[exportType::PKCS8] =
88 		tr("Unencrypted private key in PKCS#8 text format");
89 	help[exportType::PKCS8_encrypt] =
90 		tr("Encrypted private key in PKCS#8 text format");
91 	help[exportType::SSH2_public] = tr("The public key encoded in SSH2 format");
92 	help[exportType::Index] = tr("OpenSSL specific Certificate Index file as created by the 'ca' command and required by the OCSP tool");
93 	help[exportType::vcalendar] = tr("vCalendar expiry reminder for the selected items");
94 	help[exportType::vcalendar_ca] = tr("vCalendar expiry reminder containing all issued, valid certificates, the CA itself and the latest CRL");
95 	help[exportType::PVK_private] = tr("Private key in Microsoft PVK format not encrypted");
96 	help[exportType::PVK_encrypt] = tr("Encrypted private key in Microsoft PVK format");
97 
98 	on_exportFormat_highlighted(0);
99 }
100 
on_fileBut_clicked()101 void ExportDialog::on_fileBut_clicked()
102 {
103 	QString s = QFileDialog::getSaveFileName(this, QString(),
104 		filename->text(), filter, NULL,
105 		QFileDialog::DontConfirmOverwrite);
106 
107 	if (!s.isEmpty())
108 		filename->setText(nativeSeparator(s));
109 }
110 
on_exportFormat_activated(int selected)111 void ExportDialog::on_exportFormat_activated(int selected)
112 {
113 	QString fn = filename->text();
114 	exportType form = exportFormat->itemData(selected).value<exportType>();
115 
116 	for (int i=0; i< exportFormat->count(); i++) {
117 		exportType t = exportFormat->itemData(i).value<exportType>();
118 		if (fn.endsWith(QString(".") + t.extension)) {
119 			fn = fn.left(fn.length() - t.extension.length()) +
120 				form.extension;
121 			break;
122 		}
123 	}
124 	if (filename->isEnabled())
125 		filename->setText(fn);
126 	on_exportFormat_highlighted(selected);
127 }
128 
mayWriteFile(const QString & fname)129 bool ExportDialog::mayWriteFile(const QString &fname)
130 {
131         if (QFile::exists(fname)) {
132 		xcaWarning msg(NULL,
133 			tr("The file: '%1' already exists!").arg(fname));
134 		msg.addButton(QMessageBox::Ok, tr("Overwrite"));
135 		msg.addButton(QMessageBox::Cancel, tr("Do not overwrite"));
136 		if (msg.exec() != QMessageBox::Ok)
137 			return false;
138 	}
139 	return true;
140 }
141 
accept()142 void ExportDialog::accept()
143 {
144 	QString fn = filename->text();
145 
146 	if (!filename->isEnabled()) {
147 		QDialog::accept();
148 		return;
149 	}
150 	if (fn.isEmpty()) {
151 		reject();
152 		return;
153 	}
154 	if (mayWriteFile(fn)) {
155 		update_workingdir(fn);
156 		QDialog::accept();
157 	}
158 }
159 
type()160 enum exportType::etype ExportDialog::type()
161 {
162 	int selected = exportFormat->currentIndex();
163 	exportType form = exportFormat->itemData(selected).value<exportType>();
164 	return form.type;
165 }
166 
on_exportFormat_highlighted(int index)167 void ExportDialog::on_exportFormat_highlighted(int index)
168 {
169 	exportType form = exportFormat->itemData(index).value<exportType>();
170 	infoBox->setText(help[form.type]);
171 }
172