Skip to content

Commit

Permalink
Update to new UI
Browse files Browse the repository at this point in the history
Signed-off-by: Raul Metsma <[email protected]>
  • Loading branch information
metsma committed Dec 4, 2024
1 parent 8434f19 commit 01b2698
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 75 deletions.
14 changes: 9 additions & 5 deletions client/CDoc2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,10 @@ CDoc2::CDoc2(const QString &path)

CKey CDoc2::canDecrypt(const QSslCertificate &cert) const
{
return keys.value(keys.indexOf(CKey(cert)));
auto key = keys.value(keys.indexOf(CKey(cert)));
if(key.unsupported || (!key.transaction_id.isEmpty() && cert.expiryDate() <= QDateTime::currentDateTimeUtc()))
return {};
return key;
}

bool CDoc2::decryptPayload(const QByteArray &fmk)
Expand Down Expand Up @@ -558,6 +561,7 @@ bool CDoc2::save(const QString &path)
if(!cdoc20::checkConnection())
return false;
QScopedPointer<QNetworkAccessManager,QScopedPointerDeleteLater> nam(CheckConnection::setupNAM(req, Settings::CDOC2_POST_CERT));
req.setRawHeader("x-expiry-time", QDateTime::currentDateTimeUtc().addMonths(6).toString(Qt::ISODate).toLatin1());
QEventLoop e;
QNetworkReply *reply = nam->post(req, QJsonDocument({
{QLatin1String("recipient_id"), QLatin1String(recipient_id.toBase64())},
Expand Down Expand Up @@ -598,7 +602,7 @@ bool CDoc2::save(const QString &path)
toVector(key.key), toVector(encrytpedKek));
recipients.push_back(cdoc20::Header::CreateRecipientRecord(builder,
cdoc20::Recipients::Capsule::RSAPublicKeyCapsule, rsaPublicKey.Union(),
toString(key.recipient), toVector(xor_key), cdoc20::Header::FMKEncryptionMethod::XOR));
toString(key.toKeyLabel()), toVector(xor_key), cdoc20::Header::FMKEncryptionMethod::XOR));
continue;
}

Expand All @@ -610,7 +614,7 @@ bool CDoc2::save(const QString &path)
rsaKeyServer.Union(), toString(key.keyserver_id), toString(key.transaction_id));
recipients.push_back(cdoc20::Header::CreateRecipientRecord(builder,
cdoc20::Recipients::Capsule::KeyServerCapsule, keyServer.Union(),
toString(key.recipient), toVector(xor_key), cdoc20::Header::FMKEncryptionMethod::XOR));
toString(key.toKeyLabel()), toVector(xor_key), cdoc20::Header::FMKEncryptionMethod::XOR));
continue;
}

Expand Down Expand Up @@ -638,7 +642,7 @@ bool CDoc2::save(const QString &path)
cdoc20::Recipients::EllipticCurve::secp384r1, toVector(key.key), toVector(ephPublicKeyDer));
recipients.push_back(cdoc20::Header::CreateRecipientRecord(builder,
cdoc20::Recipients::Capsule::ECCPublicKeyCapsule, eccPublicKey.Union(),
toString(key.recipient), toVector(xor_key), cdoc20::Header::FMKEncryptionMethod::XOR));
toString(key.toKeyLabel()), toVector(xor_key), cdoc20::Header::FMKEncryptionMethod::XOR));
continue;
}

Expand All @@ -651,7 +655,7 @@ bool CDoc2::save(const QString &path)
eccKeyServer.Union(), toString(key.keyserver_id), toString(key.transaction_id));
recipients.push_back(cdoc20::Header::CreateRecipientRecord(builder,
cdoc20::Recipients::Capsule::KeyServerCapsule, keyServer.Union(),
toString(key.recipient), toVector(xor_key), cdoc20::Header::FMKEncryptionMethod::XOR));
toString(key.toKeyLabel()), toVector(xor_key), cdoc20::Header::FMKEncryptionMethod::XOR));
}

auto offset = cdoc20::Header::CreateHeader(builder, builder.CreateVector(recipients),
Expand Down
52 changes: 52 additions & 0 deletions client/CryptoDoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <QtCore/QRegularExpression>
#include <QtCore/QThread>
#include <QtCore/QUrl>
#include <QtCore/QUrlQuery>
#include <QtGui/QDesktopServices>
#include <QtNetwork/QSslKey>
#include <QtWidgets/QMessageBox>
Expand Down Expand Up @@ -250,6 +251,57 @@ void CKey::setCert(const QSslCertificate &c)
isRSA = k.algorithm() == QSsl::Rsa;
}

QUrlQuery CKey::fromKeyLabel() const
{
if(!recipient.startsWith(QLatin1String("data:"), Qt::CaseInsensitive))
return {};
QString payload = recipient.mid(5);
QString mimeType;
QString encoding;
if(auto pos = payload.indexOf(','); pos != -1)
{
mimeType = payload.left(pos);
payload = payload.mid(pos + 1);
if(auto header = mimeType.split(';'); header.size() == 2)
{
mimeType = header.value(0);
encoding = header.value(1);
}
}
if(!mimeType.isEmpty() && mimeType != QLatin1String("application/x-www-form-urlencoded"))
return {};
if(encoding == QLatin1String("base64"))
payload = QByteArray::fromBase64(payload.toLatin1());
QUrlQuery query(payload);
if(!query.hasQueryItem(QStringLiteral("type")) || !query.hasQueryItem(QStringLiteral("v")))
query.clear();
return query;
}

QString CKey::toKeyLabel() const
{
if(cert.isNull())
return recipient;
QDateTime exp = cert.expiryDate();
if(Settings::CDOC2_USE_KEYSERVER)
exp = std::min(exp, QDateTime::currentDateTimeUtc().addMonths(6));
auto escape = [](QString data) { return data.replace(',', QLatin1String("%2C")); };
QString type = QStringLiteral("ID-card");
if(auto t = SslCertificate(cert).type(); t & SslCertificate::EResidentSubType)
type = QStringLiteral("Digi-ID E-RESIDENT");
else if(t & SslCertificate::DigiIDType)
type = QStringLiteral("Digi-ID");
QUrlQuery q;
q.setQueryItems({
{QStringLiteral("v"), QString::number(1)},
{QStringLiteral("type"), type},
{QStringLiteral("serial_number"), escape(cert.subjectInfo("serialNumber").join(','))},
{QStringLiteral("cn"), escape(cert.subjectInfo("CN").join(','))},
{QStringLiteral("server_exp"), QString::number(exp.toSecsSinceEpoch())},
});
return "data:" + q.query(QUrl::FullyEncoded);
}



CryptoDoc::CryptoDoc( QObject *parent )
Expand Down
3 changes: 3 additions & 0 deletions client/CryptoDoc.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <memory>

class QSslKey;
class QUrlQuery;

class CKey
{
Expand All @@ -43,6 +44,8 @@ class CKey
bool operator==(const CKey &other) const { return other.key == key; }

void setCert(const QSslCertificate &c);
QUrlQuery fromKeyLabel() const;
QString toKeyLabel() const;

QByteArray key, cipher, publicKey;
QSslCertificate cert;
Expand Down
12 changes: 12 additions & 0 deletions client/translations/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,18 @@
<source>Unsupported cryptographic algorithm or recipient type</source>
<translation>Unsupported cryptographic algorithm or recipient type</translation>
</message>
<message>
<source>Decryption is possible until:</source>
<translation>Decryption is possible until:</translation>
</message>
<message>
<source>Decryption has expired</source>
<translation>Decryption has expired</translation>
</message>
<message>
<source>ID-CARD</source>
<translation>ID-CARD</translation>
</message>
</context>
<context>
<name>Application</name>
Expand Down
12 changes: 12 additions & 0 deletions client/translations/et.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,18 @@
<source>Unsupported cryptographic algorithm or recipient type</source>
<translation>Mittetoetatud krüptograafiline algoritm või adressaadi tüüp</translation>
</message>
<message>
<source>Decryption is possible until:</source>
<translation>Dekrüpteerimine on võimalik kuni:</translation>
</message>
<message>
<source>Decryption has expired</source>
<translation>Dekrüpteerimine on aegunud</translation>
</message>
<message>
<source>ID-CARD</source>
<translation>ID-KAART</translation>
</message>
</context>
<context>
<name>Application</name>
Expand Down
12 changes: 12 additions & 0 deletions client/translations/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,18 @@
<source>Unsupported cryptographic algorithm or recipient type</source>
<translation>Неподдерживаемый криптографический алгоритм или тип получателя</translation>
</message>
<message>
<source>Decryption is possible until:</source>
<translation>Расшифровка возможна до:</translation>
</message>
<message>
<source>Decryption has expired</source>
<translation>Срок расшифровки истек</translation>
</message>
<message>
<source>ID-CARD</source>
<translation>ID-КАРТА</translation>
</message>
</context>
<context>
<name>Application</name>
Expand Down
114 changes: 62 additions & 52 deletions client/widgets/AddressItem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@
#include "CryptoDoc.h"
#include "DateTime.h"
#include "SslCertificate.h"
#include "Styles.h"
#include "dialogs/KeyDialog.h"

#include <QUrlQuery>

using namespace ria::qdigidoc4;

class AddressItem::Private: public Ui::AddressItem
Expand All @@ -46,27 +47,28 @@ AddressItem::AddressItem(CKey k, QWidget *parent, bool showIcon)
if(showIcon)
ui->icon->load(QStringLiteral(":/images/icon_Krypto_small.svg"));
ui->icon->setVisible(showIcon);
ui->name->setFont(Styles::font(Styles::Regular, 14, QFont::DemiBold));
ui->name->installEventFilter(this);
ui->idType->setFont(Styles::font(Styles::Regular, 11));
ui->idType->installEventFilter(this);
ui->name->setAttribute(Qt::WA_TransparentForMouseEvents, true);
ui->expire->setAttribute(Qt::WA_TransparentForMouseEvents, true);
ui->idType->setAttribute(Qt::WA_TransparentForMouseEvents, true);
if(!ui->key.unsupported)
setCursor(Qt::PointingHandCursor);

connect(ui->add, &QToolButton::clicked, this, [this]{ emit add(this);});
connect(ui->remove, &QToolButton::clicked, this, [this]{ emit remove(this);});

ui->add->setFont(Styles::font(Styles::Condensed, 12));
ui->added->setFont(ui->add->font());

ui->code = SslCertificate(ui->key.cert).personalCode().toHtmlEscaped();
ui->label = (!ui->key.cert.subjectInfo("GN").isEmpty() && !ui->key.cert.subjectInfo("SN").isEmpty() ?
ui->key.cert.subjectInfo("GN").join(' ') + " " + ui->key.cert.subjectInfo("SN").join(' ') :
ui->key.cert.subjectInfo("CN").join(' ')).toHtmlEscaped();
ui->code = SslCertificate(ui->key.cert).personalCode();
ui->label = !ui->key.cert.subjectInfo("GN").isEmpty() && !ui->key.cert.subjectInfo("SN").isEmpty() ?
ui->key.cert.subjectInfo("GN").join(' ') + ' ' + ui->key.cert.subjectInfo("SN").join(' ') :
ui->key.cert.subjectInfo("CN").join(' ');
if(ui->label.isEmpty())
ui->label = ui->key.recipient.toHtmlEscaped();
{
if(QUrlQuery q = ui->key.fromKeyLabel(); !q.isEmpty())
ui->label = q.queryItemValue(QStringLiteral("cn"), QUrl::FullyDecoded);
else
ui->label = ui->key.recipient;
}
setIdType();
showButton(AddressItem::Remove);
if(ui->key.unsupported)
ui->idType->setText(tr("Unsupported cryptographic algorithm or recipient type"));
}

AddressItem::~AddressItem()
Expand All @@ -85,37 +87,24 @@ void AddressItem::changeEvent(QEvent* event)
QWidget::changeEvent(event);
}

bool AddressItem::eventFilter(QObject *o, QEvent *e)
{
if((o == ui->name || o == ui->idType) && e->type() == QEvent::MouseButtonRelease)
{
(new KeyDialog(ui->key, this))->open();
return true;
}
return Item::eventFilter(o, e);
}

const CKey& AddressItem::getKey() const
{
return ui->key;
}

void AddressItem::idChanged(const CKey &key)
void AddressItem::idChanged(const SslCertificate &cert)
{
CKey key(cert);
ui->yourself = !key.key.isNull() && ui->key == key;
setName();
}

void AddressItem::idChanged(const SslCertificate &cert)
{
idChanged(CKey(cert));
}

void AddressItem::initTabOrder(QWidget *item)
{
setTabOrder(item, ui->name);
setTabOrder(ui->name, ui->idType);
setTabOrder(ui->idType, ui->remove);
setTabOrder(ui->idType, ui->expire);
setTabOrder(ui->expire, ui->remove);
setTabOrder(ui->remove, ui->added);
setTabOrder(ui->added, lastTabWidget());
}
Expand All @@ -127,13 +116,14 @@ QWidget* AddressItem::lastTabWidget()

void AddressItem::mouseReleaseEvent(QMouseEvent * /*event*/)
{
(new KeyDialog(ui->key, this))->open();
if(!ui->key.unsupported)
(new KeyDialog(ui->key, this))->open();
}

void AddressItem::setName()
{
ui->name->setText(QStringLiteral("%1 <span style=\"font-weight:normal;\">%2</span>")
.arg(ui->label, ui->yourself ? ui->code + tr(" (Yourself)") : ui->code));
.arg(ui->label.toHtmlEscaped(), (ui->yourself ? ui->code + tr(" (Yourself)") : ui->code).toHtmlEscaped()));
if(ui->name->text().isEmpty())
ui->name->hide();
}
Expand All @@ -152,33 +142,53 @@ void AddressItem::stateChange(ContainerState state)

void AddressItem::setIdType()
{
ui->idType->setHidden(ui->key.cert.isNull());
if(ui->key.cert.isNull())
return;

QString str;
ui->expire->clear();
SslCertificate cert(ui->key.cert);
SslCertificate::CertType type = cert.type();
if(type & SslCertificate::DigiIDType)
str = tr("digi-ID");
if(ui->key.unsupported)
{
ui->label = tr("Unsupported cryptographic algorithm or recipient type");
ui->idType->clear();
}
else if(type & SslCertificate::DigiIDType)
ui->idType->setText(tr("digi-ID"));
else if(type & SslCertificate::EstEidType)
str = tr("ID-card");
ui->idType->setText(tr("ID-card"));
else if(type & SslCertificate::MobileIDType)
str = tr("mobile-ID");
ui->idType->setText(tr("mobile-ID"));
else if(type & SslCertificate::TempelType)
{
if(cert.keyUsage().contains(SslCertificate::NonRepudiation))
str = tr("e-Seal");
ui->idType->setText(tr("e-Seal"));
else if(cert.enhancedKeyUsage().contains(SslCertificate::ClientAuth))
str = tr("Authentication certificate");
ui->idType->setText(tr("Authentication certificate"));
else
str = tr("Certificate for Encryption");
ui->idType->setText(tr("Certificate for Encryption"));
}
else
{
QUrlQuery q = ui->key.fromKeyLabel();
void(QT_TR_NOOP("ID-CARD"));
ui->idType->setText(tr(q.queryItemValue(QStringLiteral("type"), QUrl::FullyDecoded).toUtf8().data()));
if(QString server_exp = q.queryItemValue(QStringLiteral("server_exp"), QUrl::FullyDecoded); !server_exp.isEmpty())
{
auto date = QDateTime::fromSecsSinceEpoch(server_exp.toLongLong());
bool canDecrypt = QDateTime::currentDateTimeUtc() < date;
ui->expire->setProperty("label", canDecrypt ? QStringLiteral("good") : QStringLiteral("error"));
ui->expire->setText(canDecrypt ? QStringLiteral("%1 %2").arg(
tr("Decryption is possible until:"), DateTime(date.toLocalTime()).formatDate(QStringLiteral("dd. MMMM yyyy"))) :
tr("Decryption has expired"));
}
}

if(!cert.isNull())
{
ui->expire->setProperty("label", QStringLiteral("default"));
ui->expire->setText(QStringLiteral("%1 %2").arg(
cert.isValid() ? tr("Expires on") : tr("Expired on"),
DateTime(cert.expiryDate().toLocalTime()).formatDate(QStringLiteral("dd. MMMM yyyy"))));
}

if(!str.isEmpty())
str += QStringLiteral(" - ");
DateTime date(cert.expiryDate().toLocalTime());
ui->idType->setText(QStringLiteral("%1%2 %3").arg(str,
cert.isValid() ? tr("Expires on") : tr("Expired on"),
date.formatDate(QStringLiteral("dd. MMMM yyyy"))));
ui->idType->setHidden(ui->idType->text().isEmpty());
ui->expire->setHidden(ui->expire->text().isEmpty());
}
2 changes: 0 additions & 2 deletions client/widgets/AddressItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ class AddressItem final : public Item
~AddressItem() final;

const CKey& getKey() const;
void idChanged(const CKey &cert);
void idChanged(const SslCertificate &cert) final;
void initTabOrder(QWidget *item) final;
QWidget* lastTabWidget() final;
Expand All @@ -48,7 +47,6 @@ class AddressItem final : public Item

private:
void changeEvent(QEvent *event) final;
bool eventFilter(QObject *o, QEvent *e) final;
void mouseReleaseEvent(QMouseEvent *event) final;
void setName();
void setIdType();
Expand Down
Loading

0 comments on commit 01b2698

Please sign in to comment.