diff options
| author | Felix (xq) Queißner <git@mq32.de> | 2020-06-12 17:22:43 +0200 |
|---|---|---|
| committer | Felix (xq) Queißner <git@mq32.de> | 2020-06-12 17:22:43 +0200 |
| commit | 4f8f8fc2a9450982078f18d49ddfa9036023bc29 (patch) | |
| tree | 6c0452651d4954c65a1542d46aaaebeef47da64d /src | |
| parent | 79e62a80579c5669542c65d1e9e7b31dc3872137 (diff) | |
| download | kristall-4f8f8fc2a9450982078f18d49ddfa9036023bc29.tar.gz | |
Adds certificate manager, removes client certificate window.
Diffstat (limited to 'src')
| -rw-r--r-- | src/certificatemanagementdialog.cpp | 70 | ||||
| -rw-r--r-- | src/certificatemanagementdialog.hpp | 33 | ||||
| -rw-r--r-- | src/certificatemanagementdialog.ui | 261 | ||||
| -rw-r--r-- | src/certificateselectiondialog.ui | 4 | ||||
| -rw-r--r-- | src/cryptoidentity.hpp | 9 | ||||
| -rw-r--r-- | src/identitycollection.cpp | 18 | ||||
| -rw-r--r-- | src/identitycollection.hpp | 2 | ||||
| -rw-r--r-- | src/kristall.pro | 3 | ||||
| -rw-r--r-- | src/mainwindow.cpp | 14 | ||||
| -rw-r--r-- | src/mainwindow.hpp | 2 | ||||
| -rw-r--r-- | src/mainwindow.ui | 41 | ||||
| -rw-r--r-- | src/newidentitiydialog.ui | 8 | ||||
| -rw-r--r-- | src/settingsdialog.ui | 4 |
13 files changed, 433 insertions, 36 deletions
diff --git a/src/certificatemanagementdialog.cpp b/src/certificatemanagementdialog.cpp new file mode 100644 index 0000000..defa3cc --- /dev/null +++ b/src/certificatemanagementdialog.cpp @@ -0,0 +1,70 @@ +#include "certificatemanagementdialog.hpp" +#include "ui_certificatemanagementdialog.h" + +#include "kristall.hpp" + +#include <QCryptographicHash> + +CertificateManagementDialog::CertificateManagementDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CertificateManagementDialog), + selected_identity { nullptr } +{ + ui->setupUi(this); + + this->ui->certificates->setModel(&global_identities); + this->ui->certificates->expandAll(); + + on_certificates_clicked(QModelIndex { }); +} + +CertificateManagementDialog::~CertificateManagementDialog() +{ + delete ui; +} + +void CertificateManagementDialog::on_certificates_clicked(const QModelIndex &index) +{ + selected_identity = global_identities.getMutableIdentity(index); + + this->ui->delete_cert_button->setEnabled(selected_identity != nullptr); + 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()); + this->ui->cert_livetime->setText(QString("%1 days").arg(QDateTime::currentDateTime().daysTo(cert.certificate.expiryDate()))); + this->ui->cert_fingerprint->setPlainText( + QCryptographicHash::hash(cert.certificate.toDer(), QCryptographicHash::Sha256).toHex(':') + ); + this->ui->cert_notes->setPlainText(cert.user_notes); + + } + 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(""); + } +} + +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) +{ + if(this->selected_identity != nullptr) { + this->selected_identity->display_name = this->ui->cert_display_name->text(); + } +} diff --git a/src/certificatemanagementdialog.hpp b/src/certificatemanagementdialog.hpp new file mode 100644 index 0000000..7b43053 --- /dev/null +++ b/src/certificatemanagementdialog.hpp @@ -0,0 +1,33 @@ +#ifndef CERTIFICATEMANAGEMENTDIALOG_HPP +#define CERTIFICATEMANAGEMENTDIALOG_HPP + +#include <QDialog> + +#include "cryptoidentity.hpp" + +namespace Ui { +class CertificateManagementDialog; +} + +class CertificateManagementDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CertificateManagementDialog(QWidget *parent = nullptr); + ~CertificateManagementDialog(); + +private slots: + void on_certificates_clicked(const QModelIndex &index); + + void on_cert_notes_textChanged(); + + void on_cert_display_name_textChanged(const QString &arg1); + +private: + Ui::CertificateManagementDialog *ui; + + CryptoIdentity * selected_identity; +}; + +#endif // CERTIFICATEMANAGEMENTDIALOG_HPP diff --git a/src/certificatemanagementdialog.ui b/src/certificatemanagementdialog.ui new file mode 100644 index 0000000..2c3acc6 --- /dev/null +++ b/src/certificatemanagementdialog.ui @@ -0,0 +1,261 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>CertificateManagementDialog</class> + <widget class="QDialog" name="CertificateManagementDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>731</width> + <height>480</height> + </rect> + </property> + <property name="windowTitle"> + <string>Certificate Manager</string> + </property> + <property name="windowIcon"> + <iconset resource="icons.qrc"> + <normaloff>:/icons/certificate.svg</normaloff>:/icons/certificate.svg</iconset> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <property name="rightMargin"> + <number>0</number> + </property> + <item> + <widget class="QTreeView" name="certificates"> + <attribute name="headerVisible"> + <bool>false</bool> + </attribute> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QToolButton" name="create_cert_button"> + <property name="toolTip"> + <string>Craete new certificate</string> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="icon"> + <iconset resource="icons.qrc"> + <normaloff>:/icons/plus.svg</normaloff>:/icons/plus.svg</iconset> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="import_cert_button"> + <property name="toolTip"> + <string>Import certificate</string> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="icon"> + <iconset resource="icons.qrc"> + <normaloff>:/icons/content-save-import.svg</normaloff>:/icons/content-save-import.svg</iconset> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QToolButton" name="export_cert_button"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Export certificate</string> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="icon"> + <iconset resource="icons.qrc"> + <normaloff>:/icons/content-save-move.svg</normaloff>:/icons/content-save-move.svg</iconset> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="delete_cert_button"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Delete certificate</string> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="title"> + <string>Certificate</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Display Name</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="cert_display_name"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Common Name</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="cert_common_name"> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Expiration Date</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QDateTimeEdit" name="cert_expiration_date"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Expires in</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLabel" name="cert_livetime"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>??? days</string> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>Fingerprint</string> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>Notes</string> + </property> + </widget> + </item> + <item row="4" column="1"> + <widget class="QPlainTextEdit" name="cert_fingerprint"> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QPlainTextEdit" name="cert_notes"/> + </item> + </layout> + </item> + </layout> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources> + <include location="icons.qrc"/> + </resources> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>CertificateManagementDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>CertificateManagementDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/certificateselectiondialog.ui b/src/certificateselectiondialog.ui index 006f973..22855a6 100644 --- a/src/certificateselectiondialog.ui +++ b/src/certificateselectiondialog.ui @@ -13,6 +13,10 @@ <property name="windowTitle"> <string>Select client certificate</string> </property> + <property name="windowIcon"> + <iconset resource="icons.qrc"> + <normaloff>:/icons/certificate.svg</normaloff>:/icons/certificate.svg</iconset> + </property> <layout class="QVBoxLayout" name="verticalLayout"> <item> <widget class="QLabel" name="label"> diff --git a/src/cryptoidentity.hpp b/src/cryptoidentity.hpp index a5fbb7f..09e9489 100644 --- a/src/cryptoidentity.hpp +++ b/src/cryptoidentity.hpp @@ -10,10 +10,19 @@ //! of a key-certificate pair and some user information. struct CryptoIdentity { + //! The certificate that is used for cryptography QSslCertificate certificate; + + //! The actual private key that is used for cryptography QSslKey private_key; + + //! The title with which the identity is presented to the user. QString display_name; + //! Notes that the user can have per identity for improved identity management + QString user_notes; + + //! True for long-lived identities bool is_persistent = false; bool isValid() const { diff --git a/src/identitycollection.cpp b/src/identitycollection.cpp index 43683b2..989dc9f 100644 --- a/src/identitycollection.cpp +++ b/src/identitycollection.cpp @@ -32,6 +32,7 @@ void IdentityCollection::load(QSettings &settings) id->identity.is_persistent = true; id->identity.display_name = settings.value("display_name").toString(); + id->identity.user_notes = settings.value("user_notes").toString(); id->identity.certificate = QSslCertificate::fromData( settings.value("certificate").toByteArray(), @@ -82,6 +83,7 @@ void IdentityCollection::save(QSettings &settings) const auto & id = _id->as<IdentityNode>(); settings.setValue("display_name", id.identity.display_name); + settings.setValue("user_notes", id.identity.user_notes); settings.setValue("certificate", id.identity.certificate.toDer()); settings.setValue("private_key", id.identity.private_key.toDer()); } @@ -143,6 +145,22 @@ CryptoIdentity IdentityCollection::getIdentity(const QModelIndex &index) const } } +CryptoIdentity * IdentityCollection::getMutableIdentity(const QModelIndex &index) +{ + if (!index.isValid()) + return nullptr; + + if (index.column() != 0) + return nullptr; + + Node *item = static_cast<Node*>(index.internalPointer()); + switch(item->type) { + case Node::Identity: return &static_cast<IdentityNode *>(item)->identity; + default: + return nullptr; + } +} + QStringList IdentityCollection::groups() const { QStringList result; diff --git a/src/identitycollection.hpp b/src/identitycollection.hpp index 38463ab..3290688 100644 --- a/src/identitycollection.hpp +++ b/src/identitycollection.hpp @@ -52,6 +52,8 @@ public: CryptoIdentity getIdentity(QModelIndex const & index) const; + CryptoIdentity * getMutableIdentity(QModelIndex const & index); + QStringList groups() const; public: diff --git a/src/kristall.pro b/src/kristall.pro index 991a499..413bc6b 100644 --- a/src/kristall.pro +++ b/src/kristall.pro @@ -37,6 +37,7 @@ SOURCES += \ ../lib/luis-l-gist/interactiveview.cpp \ browsertab.cpp \ certificatehelper.cpp \ + certificatemanagementdialog.cpp \ certificateselectiondialog.cpp \ cryptoidentity.cpp \ documentoutlinemodel.cpp \ @@ -64,6 +65,7 @@ HEADERS += \ ../lib/luis-l-gist/interactiveview.hpp \ browsertab.hpp \ certificatehelper.hpp \ + certificatemanagementdialog.hpp \ certificateselectiondialog.hpp \ cryptoidentity.hpp \ documentoutlinemodel.hpp \ @@ -89,6 +91,7 @@ HEADERS += \ FORMS += \ browsertab.ui \ + certificatemanagementdialog.ui \ certificateselectiondialog.ui \ mainwindow.ui \ mediaplayer.ui \ diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 1c0dc9e..1f37d5d 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -13,6 +13,7 @@ #include "ioutil.hpp" #include "kristall.hpp" +#include "certificatemanagementdialog.hpp" MainWindow::MainWindow(QApplication * app, QWidget *parent) : QMainWindow(parent), @@ -41,12 +42,8 @@ MainWindow::MainWindow(QApplication * app, QWidget *parent) : ui->favourites_view->setModel(&favourites); - ui->clientcert_view->setModel(&global_identities); - ui->clientcert_view->expandAll(); - this->ui->outline_window->setVisible(false); this->ui->history_window->setVisible(false); - this->ui->clientcert_window->setVisible(false); this->ui->bookmarks_window->setVisible(false); for(QDockWidget * dock : findChildren<QDockWidget *>()) @@ -464,3 +461,12 @@ void MainWindow::on_actionChangelog_triggered() { this->addNewTab(true, QUrl("about:updates")); } + +void MainWindow::on_actionManage_Certificates_triggered() +{ + CertificateManagementDialog dialog { this }; + + dialog.exec(); + + this->saveSettings(); +} diff --git a/src/mainwindow.hpp b/src/mainwindow.hpp index 174f06a..b929484 100644 --- a/src/mainwindow.hpp +++ b/src/mainwindow.hpp @@ -87,6 +87,8 @@ private slots: void on_actionChangelog_triggered(); + void on_actionManage_Certificates_triggered(); + private: void reloadTheme(); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 782d0e3..445c748 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -148,37 +148,6 @@ </layout> </widget> </widget> - <widget class="QDockWidget" name="clientcert_window"> - <property name="windowTitle"> - <string>Client Certificates</string> - </property> - <attribute name="dockWidgetArea"> - <number>2</number> - </attribute> - <widget class="QWidget" name="dockWidgetContents_4"> - <layout class="QVBoxLayout" name="verticalLayout_5"> - <property name="leftMargin"> - <number>0</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <property name="rightMargin"> - <number>0</number> - </property> - <property name="bottomMargin"> - <number>0</number> - </property> - <item> - <widget class="QTreeView" name="clientcert_view"> - <property name="headerHidden"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </widget> - </widget> <widget class="QMenuBar" name="menuBar"> <property name="geometry"> <rect> @@ -197,6 +166,7 @@ <addaction name="actionSave_as"/> <addaction name="actionClose_Tab"/> <addaction name="separator"/> + <addaction name="actionManage_Certificates"/> <addaction name="actionSettings"/> <addaction name="separator"/> <addaction name="actionQuit"/> @@ -373,6 +343,15 @@ <string>Changelog</string> </property> </action> + <action name="actionManage_Certificates"> + <property name="icon"> + <iconset resource="icons.qrc"> + <normaloff>:/icons/certificate.svg</normaloff>:/icons/certificate.svg</iconset> + </property> + <property name="text"> + <string>Manage Certificates…</string> + </property> + </action> </widget> <resources> <include location="icons.qrc"/> diff --git a/src/newidentitiydialog.ui b/src/newidentitiydialog.ui index 05c8155..34c6e6a 100644 --- a/src/newidentitiydialog.ui +++ b/src/newidentitiydialog.ui @@ -13,6 +13,10 @@ <property name="windowTitle"> <string>Dialog</string> </property> + <property name="windowIcon"> + <iconset resource="icons.qrc"> + <normaloff>:/icons/certificate.svg</normaloff>:/icons/certificate.svg</iconset> + </property> <layout class="QVBoxLayout" name="verticalLayout"> <item> <layout class="QFormLayout" name="formLayout"> @@ -74,7 +78,9 @@ </item> </layout> </widget> - <resources/> + <resources> + <include location="icons.qrc"/> + </resources> <connections> <connection> <sender>buttonBox</sender> diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 23d1bc8..67767bf 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -13,6 +13,10 @@ <property name="windowTitle"> <string>Settings</string> </property> + <property name="windowIcon"> + <iconset resource="icons.qrc"> + <normaloff>:/icons/settings.svg</normaloff>:/icons/settings.svg</iconset> + </property> <layout class="QVBoxLayout" name="verticalLayout"> <item> <widget class="QTabWidget" name="tabWidget"> |
