Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions client/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,9 +302,6 @@ class Application::Private
QString lang;
QTimer lastWindowTimer;
volatile bool ready = false;
#ifdef Q_OS_WIN
QStringList tempFiles;
#endif // Q_OS_WIN

~Private() {
delete signer;
Expand Down Expand Up @@ -520,11 +517,6 @@ Application::~Application()
{
for(QWidget *top: topLevelWidgets())
top->close();
#ifdef Q_OS_WIN
for(const QString &file: qAsConst(d->tempFiles))
QFile::remove(file);
d->tempFiles.clear();
#endif // Q_OS_WIN

#ifndef Q_OS_MAC
if( isRunning() )
Expand Down Expand Up @@ -559,13 +551,6 @@ Application::~Application()
void Application::addRecent( const QString & ) {}
#endif

#ifdef Q_OS_WIN
void Application::addTempFile(const QString &file)
{
d->tempFiles.append(file);
}
#endif

void Application::browse( const QUrl &url )
{
QUrl u = url;
Expand Down
3 changes: 0 additions & 3 deletions client/Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,6 @@ class Application final: public BaseApplication
explicit Application( int &argc, char **argv );
~Application() final;

#ifdef Q_OS_WIN
void addTempFile(const QString &file);
#endif
Configuration *conf();
void loadTranslation( const QString &lang );
bool notify(QObject *object, QEvent *event ) final;
Expand Down
4 changes: 1 addition & 3 deletions client/QPKCS11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@
#include <QtCore/QtEndian>
#include <QtCore/QLibrary>

#include <cdoc/utils/memory.h>

#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/kdf.h>
Expand Down Expand Up @@ -339,7 +337,7 @@ QByteArray QPKCS11::deriveHMACExtract(const QByteArray &publicKey, const QByteAr
QByteArray key = derive(publicKey);
if(key.isEmpty())
return key;
auto ctx = libcdoc::make_unique_ptr<EVP_PKEY_CTX_free>(EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr));
auto ctx = make_unique_ptr<EVP_PKEY_CTX_free>(EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr));
QByteArray out(keySize, 0);
auto outlen = size_t(out.length());
auto isError = [this](int err) {
Expand Down
20 changes: 1 addition & 19 deletions client/SslCertificate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "SslCertificate.h"

#include "Common.h"
#include "Utils.h"

#include <digidocpp/Exception.h>
#include <digidocpp/crypto/X509Cert.h>
Expand All @@ -35,18 +36,6 @@
#include <openssl/ocsp.h>
#include <openssl/x509v3.h>

#include <memory>

template<auto D>
struct free_deleter
{
template<class T>
void operator()(T *p) const noexcept
{
D(p);
}
};

template<typename> struct free_argument;
template<class T, class R>
struct free_argument<R (*)(T *)>
Expand All @@ -59,13 +48,6 @@ struct free_argument<R (&)(T *)>
using type = T;
};

template<auto F, typename T>
[[nodiscard]]
constexpr auto make_unique_ptr(T *t) noexcept
{
return std::unique_ptr<T, free_deleter<F>>(t);
}

template<class T>
static auto toQByteArray(T &x)
{
Expand Down
18 changes: 18 additions & 0 deletions client/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,27 @@

#include <exception>
#include <limits>
#include <memory>
#include <thread>

namespace {
template<auto F>
struct free_deleter
{
template<class T>
void operator()(T *p) const noexcept
{
F(p);
}
};

template<auto F, typename T>
[[nodiscard]]
constexpr auto make_unique_ptr(T *t) noexcept
{
return std::unique_ptr<T, free_deleter<F>>(t);
}

template <typename F, class... Args>
inline auto waitFor(F&& function, Args&& ...args) {
std::exception_ptr exception;
Expand Down
100 changes: 48 additions & 52 deletions client/dialogs/CertificateDetails.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,42 +21,50 @@
#include "CertificateDetails.h"
#include "ui_CertificateDetails.h"

#include "Application.h"
#include "DateTime.h"
#include "SslCertificate.h"
#include "Utils.h"
#include "effects/Overlay.h"
#include "dialogs/WarningDialog.h"

#include <QtCore/QDir>
#include <QtCore/QStandardPaths>
#include <QtCore/QTextStream>
#include <QtGui/QDesktopServices>
#include <QtNetwork/QSslKey>
#include <QtWidgets/QFileDialog>

#ifdef Q_OS_WIN
#include <qt_windows.h>
#include <cryptuiapi.h>
#include <wincrypt.h>
#endif

CertificateDetails::CertificateDetails(const SslCertificate &cert, QWidget *parent)
: QDialog(parent)
{
Ui::CertificateDetails ui;
ui.setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
#ifdef Q_OS_MAC
setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::Sheet);
#else
setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint);
#endif
new Overlay(this);

const QHash<SslCertificate::EnhancedKeyUsage,QString> enhancedKeyUsageHash = cert.enhancedKeyUsage();

QString i;
QTextStream s( &i );
s << "<b>" << tr("This certificate is intended for following purpose(s):") << "</b>";
s << "<ul>";
for(const QString &ext: cert.enhancedKeyUsage())
s << "<li>" << tr(ext.toStdString().c_str()) << "</li>";
for(const QString &ext: enhancedKeyUsageHash)
s << "<li>" << ext << "</li>";
s << "</ul>";
s << "<br />";
s << "<b>" << tr("Issued to:") << "</b><br />" << cert.subjectInfo( QSslCertificate::CommonName);
s << "<b>" << tr("Issued to:") << "</b><br />" << cert.subjectInfo( QSslCertificate::CommonName).toHtmlEscaped();
s << "<br /><br />";
s << "<b>" << tr("Issued by:") << "</b><br />" << cert.issuerInfo(QSslCertificate::CommonName);
s << "<b>" << tr("Issued by:") << "</b><br />" << cert.issuerInfo(QSslCertificate::CommonName).toHtmlEscaped();
s << "<br /><br />";
s << "<b>" << tr("Valid:") << "</b><br />";
s << "<b>" << tr("From") << "</b> " << cert.effectiveDate().toLocalTime().toString(QStringLiteral("dd.MM.yyyy")) << "<br />";
Expand All @@ -72,9 +80,7 @@ CertificateDetails::CertificateDetails(const SslCertificate &cert, QWidget *pare
if( file.isEmpty() )
return;

if(QFile f(file); f.open(QIODevice::WriteOnly))
f.write(cert.toPem());
else
if(QFile f(file); !f.open(QIODevice::WriteOnly) || f.write(cert.toPem()) < 0)
WarningDialog::create(this)->withTitle(QCoreApplication::translate("FileDialog", "Failed to save file"))->open();
});
connect(ui.close, &QPushButton::clicked, this, &CertificateDetails::accept);
Expand All @@ -98,48 +104,38 @@ CertificateDetails::CertificateDetails(const SslCertificate &cert, QWidget *pare
tblDetails->setItem(row, 1, item);
};

addItem(tr("Version"), QString("V" + cert.version()));
auto joinInfo = [](const QList<QByteArray> &attrs, auto infoFn) {
QStringList text, textExt;
for(const QByteArray &obj: attrs)
{
QString data = infoFn(obj);
if(data.isEmpty())
continue;
textExt.append(QStringLiteral("%1 = %2").arg(obj.constData(), data));
text.append(std::move(data));
}
return std::pair(text.join(QStringLiteral(", ")), textExt.join('\n'));
};

addItem(tr("Version"), "V" + cert.version());
addItem(tr("Serial number"), cert.serialNumber());
addItem(tr("Signature algorithm"), cert.signatureAlgorithm());

QStringList text, textExt;
static const QByteArray ORGID_OID = QByteArrayLiteral("2.5.4.97");
for(const QByteArray &obj: cert.issuerInfoAttributes())
{
const QString &data = cert.issuerInfo( obj );
if( data.isEmpty() )
continue;
text << data;
// organizationIdentifier OID might not be known by SSL backend
textExt << QStringLiteral("%1 = %2").arg(
obj.constData() == ORGID_OID ? "organizationIdentifier" : obj.constData(), data);
}
addItem(tr("Issuer"), text.join(QStringLiteral(", ")), textExt.join('\n'));
auto [issuerText, issuerTextExt] = joinInfo(cert.issuerInfoAttributes(),
[&cert](const QByteArray &obj) { return cert.issuerInfo(obj); });
addItem(tr("Issuer"), issuerText, issuerTextExt);
addItem(tr("Valid from"), DateTime(cert.effectiveDate().toLocalTime()).toStringZ(QStringLiteral("dd.MM.yyyy hh:mm:ss")));
addItem(tr("Valid to"), DateTime(cert.expiryDate().toLocalTime()).toStringZ(QStringLiteral("dd.MM.yyyy hh:mm:ss")));

text.clear();
textExt.clear();
for(const QByteArray &obj: cert.subjectInfoAttributes())
{
const QString &data = cert.subjectInfo( obj );
if( data.isEmpty() )
continue;
text << data;
textExt << QStringLiteral("%1 = %2").arg(obj.constData(), data);
}
addItem(tr("Subject"), text.join(QStringLiteral(", ")), textExt.join('\n'));
auto [subjectText, subjectTextExt] = joinInfo(cert.subjectInfoAttributes(),
[&cert](const QByteArray &obj) { return cert.subjectInfo(obj); });
addItem(tr("Subject"), subjectText, subjectTextExt);
addItem(tr("Public key"), cert.keyName(), cert.publicKey().toDer().toHex(' ').toUpper());
QStringList enhancedKeyUsage = cert.enhancedKeyUsage().values();
if( !enhancedKeyUsage.isEmpty() )
if(QStringList enhancedKeyUsage = enhancedKeyUsageHash.values(); !enhancedKeyUsage.isEmpty())
addItem(tr("Enhanced key usage"), enhancedKeyUsage.join(QStringLiteral(", ")), enhancedKeyUsage.join('\n'));
QStringList policies = cert.policies();
if( !policies.isEmpty() )
if(QStringList policies = cert.policies(); !policies.isEmpty())
addItem(tr("Certificate policies"), policies.join(QStringLiteral(", ")));
addItem(tr("Authority key identifier"), cert.authorityKeyIdentifier().toHex(' ').toUpper());
addItem(tr("Subject key identifier"), cert.subjectKeyIdentifier().toHex(' ').toUpper());
QStringList keyUsage = cert.keyUsage().values();
if( !keyUsage.isEmpty() )
if(QStringList keyUsage = cert.keyUsage().values(); !keyUsage.isEmpty())
addItem(tr("Key usage"), keyUsage.join(QStringLiteral(", ")), keyUsage.join('\n'));

// Disable resizing
Expand All @@ -150,17 +146,17 @@ CertificateDetails::CertificateDetails(const SslCertificate &cert, QWidget *pare
void CertificateDetails::showCertificate(const QSslCertificate &cert, QWidget *parent, const QString &suffix)
{
#ifdef Q_OS_UNIX
CertificateDetails(cert, parent).exec();
(new CertificateDetails(cert, parent))->open();
#else
Q_UNUSED(parent);
QString name = cert.subjectInfo("serialNumber").join('_');
if(name.isEmpty())
name = cert.serialNumber().replace(':', "");
QString path = QStringLiteral("%1/%2%3.cer").arg(QDir::tempPath(), name, suffix);
if(QFile f(path); f.open(QIODevice::WriteOnly))
f.write(cert.toPem());
qApp->addTempFile(path);
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
Q_UNUSED(suffix);
QByteArray der = cert.toDer();
if(auto ctx = make_unique_ptr<CertFreeCertificateContext>(CertCreateCertificateContext(
X509_ASN_ENCODING, LPBYTE(der.constData()), DWORD(der.size()))))
{
CryptUIDlgViewContext(CERT_STORE_CERTIFICATE_CONTEXT, ctx.get(),
parent && parent->window() ? HWND(parent->window()->winId()) : nullptr,
nullptr, 0, nullptr);
}
#endif
}
#endif
Loading