okular/gui/certificatemodel.cpp
Sune Vuorela 763328a6ba Better dialog for selecting certificates
Instead of just a simple list of "nickname"'s which is kind of like the
signing backend's internal ID for a given certificate, provide some more
context to each key.

This is a slight improvement, not a complete overhaul.
2023-05-03 13:41:14 +00:00

167 lines
6.2 KiB
C++

/*
SPDX-FileCopyrightText: 2018 Chinmoy Ranjan Pradhan <chinmoyrp65@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "certificatemodel.h"
#include "signatureguiutils.h"
#include <KLocalizedString>
#include <QCryptographicHash>
#include <QDebug>
#include <QFile>
#include <QUrl>
CertificateModel::CertificateModel(const Okular::CertificateInfo &certInfo, QObject *parent)
: QAbstractTableModel(parent)
, m_certificateProperties({Version, SerialNumber, Issuer, IssuedOn, ExpiresOn, Subject, PublicKey, KeyUsage})
, m_certificateInfo(certInfo)
{
}
int CertificateModel::columnCount(const QModelIndex &) const
{
return 2;
}
int CertificateModel::rowCount(const QModelIndex &) const
{
return m_certificateProperties.size();
}
static QString propertyVisibleName(CertificateModel::Property p)
{
switch (p) {
case CertificateModel::Version:
return i18n("Version");
case CertificateModel::SerialNumber:
return i18n("Serial Number");
case CertificateModel::Issuer:
return i18n("Issuer");
case CertificateModel::IssuedOn:
return i18n("Issued On");
case CertificateModel::ExpiresOn:
return i18n("Expires On");
case CertificateModel::Subject:
return i18nc("The person/company that made the signature", "Subject");
case CertificateModel::PublicKey:
return i18n("Public Key");
case CertificateModel::KeyUsage:
return i18n("Key Usage");
case CertificateModel::IssuerName:
case CertificateModel::IssuerEmail:
case CertificateModel::IssuerOrganization:
case CertificateModel::SubjectName:
case CertificateModel::SubjectEmail:
case CertificateModel::SubjectOrganization:
case CertificateModel::Sha1:
case CertificateModel::Sha256:
Q_ASSERT(false);
qWarning() << "Unimplemented";
}
return QString();
}
QString CertificateModel::propertyVisibleValue(CertificateModel::Property p) const
{
switch (p) {
case CertificateModel::Version:
return i18n("V%1", QString::number(m_certificateInfo.version()));
case CertificateModel::SerialNumber:
return QString::fromLatin1(m_certificateInfo.serialNumber().toHex(' '));
case CertificateModel::Issuer:
return m_certificateInfo.issuerInfo(Okular::CertificateInfo::DistinguishedName, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
case CertificateModel::IssuedOn:
return QLocale().toString(m_certificateInfo.validityStart(), QLocale::LongFormat);
case CertificateModel::ExpiresOn:
return QLocale().toString(m_certificateInfo.validityEnd(), QLocale::LongFormat);
case CertificateModel::Subject:
return m_certificateInfo.subjectInfo(Okular::CertificateInfo::DistinguishedName, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
case CertificateModel::PublicKey:
return i18n("%1 (%2 bits)", SignatureGuiUtils::getReadablePublicKeyType(m_certificateInfo.publicKeyType()), m_certificateInfo.publicKeyStrength());
case CertificateModel::KeyUsage:
return SignatureGuiUtils::getReadableKeyUsageCommaSeparated(m_certificateInfo.keyUsageExtensions());
case CertificateModel::IssuerName:
return m_certificateInfo.issuerInfo(Okular::CertificateInfo::CommonName, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
case CertificateModel::IssuerEmail:
return m_certificateInfo.issuerInfo(Okular::CertificateInfo::EmailAddress, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
case CertificateModel::IssuerOrganization:
return m_certificateInfo.issuerInfo(Okular::CertificateInfo::Organization, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
case CertificateModel::SubjectName:
return m_certificateInfo.subjectInfo(Okular::CertificateInfo::CommonName, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
case CertificateModel::SubjectEmail:
return m_certificateInfo.subjectInfo(Okular::CertificateInfo::EmailAddress, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
case CertificateModel::SubjectOrganization:
return m_certificateInfo.subjectInfo(Okular::CertificateInfo::Organization, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
case CertificateModel::Sha1:
return QString::fromLatin1(QCryptographicHash::hash(m_certificateInfo.certificateData(), QCryptographicHash::Sha1).toHex(' '));
case CertificateModel::Sha256:
return QString::fromLatin1(QCryptographicHash::hash(m_certificateInfo.certificateData(), QCryptographicHash::Sha256).toHex(' '));
}
return QString();
}
QVariant CertificateModel::data(const QModelIndex &index, int role) const
{
const int row = index.row();
if (!index.isValid() || row < 0 || row >= m_certificateProperties.count()) {
return QVariant();
}
switch (role) {
case Qt::DisplayRole:
case Qt::ToolTipRole:
switch (index.column()) {
case 0:
return propertyVisibleName(m_certificateProperties[row]);
case 1:
return propertyVisibleValue(m_certificateProperties[row]);
default:
return QString();
}
case PropertyKeyRole:
return m_certificateProperties[row];
case PropertyVisibleValueRole:
return propertyVisibleValue(m_certificateProperties[row]);
}
return QVariant();
}
QVariant CertificateModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::TextAlignmentRole) {
return QVariant(Qt::AlignLeft);
}
if (orientation != Qt::Horizontal || role != Qt::DisplayRole) {
return QVariant();
}
switch (section) {
case 0:
return i18n("Property");
case 1:
return i18n("Value");
default:
return QVariant();
}
}
bool CertificateModel::exportCertificateTo(const QString &path)
{
const QUrl url = QUrl::fromUserInput(path);
if (!url.isLocalFile()) {
return false;
}
QFile targetFile(url.toLocalFile());
if (!targetFile.open(QIODevice::WriteOnly)) {
return false;
}
const QByteArray data = m_certificateInfo.certificateData();
return targetFile.write(data) == data.size();
}