aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFelix (xq) Queißner <git@mq32.de>2020-06-12 17:22:43 +0200
committerFelix (xq) Queißner <git@mq32.de>2020-06-12 17:22:43 +0200
commit4f8f8fc2a9450982078f18d49ddfa9036023bc29 (patch)
tree6c0452651d4954c65a1542d46aaaebeef47da64d /src
parent79e62a80579c5669542c65d1e9e7b31dc3872137 (diff)
downloadkristall-4f8f8fc2a9450982078f18d49ddfa9036023bc29.tar.gz
Adds certificate manager, removes client certificate window.
Diffstat (limited to 'src')
-rw-r--r--src/certificatemanagementdialog.cpp70
-rw-r--r--src/certificatemanagementdialog.hpp33
-rw-r--r--src/certificatemanagementdialog.ui261
-rw-r--r--src/certificateselectiondialog.ui4
-rw-r--r--src/cryptoidentity.hpp9
-rw-r--r--src/identitycollection.cpp18
-rw-r--r--src/identitycollection.hpp2
-rw-r--r--src/kristall.pro3
-rw-r--r--src/mainwindow.cpp14
-rw-r--r--src/mainwindow.hpp2
-rw-r--r--src/mainwindow.ui41
-rw-r--r--src/newidentitiydialog.ui8
-rw-r--r--src/settingsdialog.ui4
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">