#include "certificatemanagementdialog.hpp" #include "ui_certificatemanagementdialog.h" #include "kristall.hpp" #include "newidentitiydialog.hpp" #include "certificateiodialog.hpp" #include "ioutil.hpp" #include #include CertificateManagementDialog::CertificateManagementDialog(QWidget *parent) : QDialog(parent), ui(new Ui::CertificateManagementDialog), selected_identity { nullptr } { ui->setupUi(this); connect( // connect with "this" as context, so the connection will die when the window is destroyed kristall::globals().localization.get(), &Localization::translationChanged, this, [this]() { this->ui->retranslateUi(this); }, Qt::DirectConnection ); this->ui->certificates->setModel(&identity_set); this->ui->certificates->expandAll(); connect( this->ui->certificates->selectionModel(), &QItemSelectionModel::currentChanged, this, &CertificateManagementDialog::on_certificates_selected ); on_certificates_selected(QModelIndex { }, QModelIndex { }); } CertificateManagementDialog::~CertificateManagementDialog() { delete ui; } IdentityCollection CertificateManagementDialog::identitySet() const { return this->identity_set; } void CertificateManagementDialog::setIdentitySet(const IdentityCollection &src) { this->identity_set = src; this->ui->certificates->expandAll(); } void CertificateManagementDialog::on_certificates_selected(QModelIndex const& index, QModelIndex const & previous) { Q_UNUSED(previous); selected_identity = identity_set.getMutableIdentity(index); this->ui->export_cert_button->setEnabled(selected_identity != nullptr); if(selected_identity != nullptr) { auto & cert = *selected_identity; this->ui->groupBox->setEnabled(true); this->ui->cert_display_name->setText(cert.display_name); this->ui->cert_common_name->setText(cert.certificate.subjectInfo(QSslCertificate::CommonName).join(", ")); this->ui->cert_expiration_date->setDateTime(cert.certificate.expiryDate()); auto days = QDateTime::currentDateTime().daysTo(cert.certificate.expiryDate()); this->ui->cert_livetime->setText(tr("%1 day","%1 days", days).arg(days)); this->ui->cert_fingerprint->setPlainText(toFingerprintString(cert.certificate)); this->ui->cert_notes->setPlainText(cert.user_notes); this->ui->cert_host_filter->setText(cert.host_filter); this->ui->cert_auto_enable->setEnabled(not cert.host_filter.isEmpty()); this->ui->cert_auto_enable->setChecked(cert.auto_enable); this->ui->delete_cert_button->setEnabled(true); } else { this->ui->groupBox->setEnabled(false); this->ui->cert_display_name->setText(""); this->ui->cert_common_name->setText(""); this->ui->cert_expiration_date->setDateTime(QDateTime { }); this->ui->cert_livetime->setText(""); this->ui->cert_fingerprint->setPlainText(""); this->ui->cert_host_filter->setText(""); this->ui->cert_auto_enable->setChecked(false); if(auto group_name = identity_set.group(index); not group_name.isEmpty()) { this->ui->delete_cert_button->setEnabled(identity_set.canDeleteGroup(group_name)); } else { this->ui->delete_cert_button->setEnabled(false); } } } void CertificateManagementDialog::on_cert_notes_textChanged() { if(this->selected_identity != nullptr) { this->selected_identity->user_notes = this->ui->cert_notes->toPlainText(); } } void CertificateManagementDialog::on_cert_display_name_textChanged(const QString &arg1) { Q_UNUSED(arg1) if(this->selected_identity != nullptr) { this->selected_identity->display_name = this->ui->cert_display_name->text(); } } void CertificateManagementDialog::on_delete_cert_button_clicked() { auto index = this->ui->certificates->currentIndex(); if(identity_set.getMutableIdentity(index) != nullptr) { auto answer = QMessageBox::question( this, tr("Kristall"), tr("Do you really want to delete this certificate?\r\n\r\nYou will not be able to restore the identity after this!"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No ); if(answer != QMessageBox::Yes) return; if(not identity_set.destroyIdentity(index)) { QMessageBox::warning(this, tr("Kristall"), tr("Could not destroy identity!")); } } else if(auto group_name = identity_set.group(index); not group_name.isEmpty()) { auto answer = QMessageBox::question( this, tr("Kristall"), tr("Do you want to delete the group '%1'").arg(group_name) ); if(answer != QMessageBox::Yes) return; if(not identity_set.deleteGroup(group_name)) { QMessageBox::warning(this, tr("Kristall"), tr("Could not delete group!")); } } } void CertificateManagementDialog::on_export_cert_button_clicked() { if(this->selected_identity == nullptr) return; CertificateIoDialog dialog { this }; dialog.setKeyAlgorithm(this->selected_identity->private_key.algorithm()); dialog.setIoMode(CertificateIoDialog::Export); if(dialog.exec() != QDialog::Accepted) return; { QFile cert_file { dialog.certificateFileName() }; if(not cert_file.open(QFile::WriteOnly)) { QMessageBox::warning( this, tr("Kristall"), tr("The file %1 could not be found!").arg(dialog.certificateFileName()) ); return; } QByteArray cert_blob; if(dialog.certificateFileName().endsWith(".der")) { cert_blob = this->selected_identity->certificate.toDer(); } else { cert_blob = this->selected_identity->certificate.toPem(); } if(not IoUtil::writeAll(cert_file, cert_blob)) { QMessageBox::warning( this, tr("Kristall"), tr("The file %1 could not be created found!").arg(dialog.certificateFileName()) ); return; } } { QFile key_file { dialog.keyFileName() }; if(not key_file.open(QFile::WriteOnly)) { QMessageBox::warning( this, tr("Kristall"), tr("The file %1 could not be found!").arg(dialog.keyFileName()) ); return; } QByteArray key_blob; if(dialog.keyFileName().endsWith(".der")) { key_blob = this->selected_identity->private_key.toDer(); } else { key_blob = this->selected_identity->private_key.toPem(); } if(not IoUtil::writeAll(key_file, key_blob)) { QMessageBox::warning( this, tr("Kristall"), tr("The file %1 could not be created!").arg(dialog.keyFileName()) ); return; } } } void CertificateManagementDialog::on_import_cert_button_clicked() { CertificateIoDialog dialog { this }; dialog.setIoMode(CertificateIoDialog::Import); if(dialog.exec() != QDialog::Accepted) return; QFile cert_file { dialog.certificateFileName() }; if(not cert_file.open(QFile::ReadOnly)) { QMessageBox::warning( this, tr("Kristall"), tr("The file %1 could not be found!").arg(dialog.certificateFileName()) ); return; } QFile key_file { dialog.keyFileName() }; if(not key_file.open(QFile::ReadOnly)) { QMessageBox::warning( this, tr("Kristall"), tr("The file %1 could not be found!").arg(dialog.keyFileName()) ); return; } CryptoIdentity ident; ident.private_key = QSslKey { &key_file, dialog.keyAlgorithm(), dialog.keyFileName().endsWith(".der") ? QSsl::Der : QSsl::Pem, QSsl::PrivateKey }; ident.certificate = QSslCertificate { &cert_file, dialog.keyFileName().endsWith(".der") ? QSsl::Der : QSsl::Pem, }; ident.user_notes = tr("Imported from:\r\nkey: %1\r\n:cert: %2").arg(dialog.keyFileName(), dialog.certificateFileName()); //: Default name ident.display_name = tr("Imported Certificate"); ident.auto_enable = false; ident.host_filter = ""; ident.is_persistent = true; if(ident.private_key.isNull()) { QMessageBox::warning( this, tr("Kristall"), tr("The key file %1 could not be loaded. Please verify your key file.").arg(dialog.keyFileName()) ); return; } if(ident.certificate.isNull()) { QMessageBox::warning( this, tr("Kristall"), tr("The certificate file %1 could not be loaded. Please verify your certificate.").arg(dialog.keyFileName()) ); return; } if(not identity_set.addCertificate(tr("Imported Certificates"), ident)) { QMessageBox::warning( this, tr("Kristall"), tr("Failed to import the certificate.") ); } } void CertificateManagementDialog::on_create_cert_button_clicked() { NewIdentitiyDialog dialog { this }; dialog.setGroupName(identity_set.group(this->ui->certificates->currentIndex())); if(dialog.exec() != QDialog::Accepted) return; auto id = dialog.createIdentity(); if(not id.isValid()) return; id.is_persistent = true; identity_set.addCertificate( dialog.groupName(), id); } void CertificateManagementDialog::on_cert_host_filter_textChanged(const QString &host_filter) { if(this->selected_identity != nullptr) { this->ui->cert_auto_enable->setEnabled(not host_filter.isEmpty()); this->selected_identity->host_filter = host_filter; } else { this->ui->cert_auto_enable->setEnabled(false); } } void CertificateManagementDialog::on_cert_auto_enable_clicked(bool checked) { if(this->selected_identity != nullptr) { this->selected_identity->auto_enable = checked; } }