File indexing completed on 2024-04-28 04:33:05

0001 /*
0002     SPDX-FileCopyrightText: 2018 Chinmoy Ranjan Pradhan <chinmoyrp65@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "certificatemodel.h"
0008 
0009 #include "signatureguiutils.h"
0010 
0011 #include <KLocalizedString>
0012 
0013 #include <QCryptographicHash>
0014 #include <QDebug>
0015 #include <QFile>
0016 #include <QUrl>
0017 
0018 CertificateModel::CertificateModel(const Okular::CertificateInfo &certInfo, QObject *parent)
0019     : QAbstractTableModel(parent)
0020     , m_certificateProperties({Version, SerialNumber, Issuer, IssuedOn, ExpiresOn, Subject, PublicKey, KeyUsage})
0021     , m_certificateInfo(certInfo)
0022 {
0023 }
0024 
0025 int CertificateModel::columnCount(const QModelIndex &) const
0026 {
0027     return 2;
0028 }
0029 
0030 int CertificateModel::rowCount(const QModelIndex &) const
0031 {
0032     return m_certificateProperties.size();
0033 }
0034 
0035 static QString propertyVisibleName(CertificateModel::Property p)
0036 {
0037     switch (p) {
0038     case CertificateModel::Version:
0039         return i18n("Version");
0040     case CertificateModel::SerialNumber:
0041         return i18n("Serial Number");
0042     case CertificateModel::Issuer:
0043         return i18n("Issuer");
0044     case CertificateModel::IssuedOn:
0045         return i18n("Issued On");
0046     case CertificateModel::ExpiresOn:
0047         return i18n("Expires On");
0048     case CertificateModel::Subject:
0049         return i18nc("The person/company that made the signature", "Subject");
0050     case CertificateModel::PublicKey:
0051         return i18n("Public Key");
0052     case CertificateModel::KeyUsage:
0053         return i18n("Key Usage");
0054     case CertificateModel::IssuerName:
0055     case CertificateModel::IssuerEmail:
0056     case CertificateModel::IssuerOrganization:
0057     case CertificateModel::SubjectName:
0058     case CertificateModel::SubjectEmail:
0059     case CertificateModel::SubjectOrganization:
0060     case CertificateModel::Sha1:
0061     case CertificateModel::Sha256:
0062         Q_ASSERT(false);
0063         qWarning() << "Unimplemented";
0064     }
0065     return QString();
0066 }
0067 
0068 QString CertificateModel::propertyVisibleValue(CertificateModel::Property p) const
0069 {
0070     switch (p) {
0071     case CertificateModel::Version:
0072         return i18n("V%1", QString::number(m_certificateInfo.version()));
0073     case CertificateModel::SerialNumber:
0074         return QString::fromLatin1(m_certificateInfo.serialNumber().toHex(' '));
0075     case CertificateModel::Issuer:
0076         return m_certificateInfo.issuerInfo(Okular::CertificateInfo::DistinguishedName, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
0077     case CertificateModel::IssuedOn:
0078         return QLocale().toString(m_certificateInfo.validityStart(), QLocale::LongFormat);
0079     case CertificateModel::ExpiresOn:
0080         return QLocale().toString(m_certificateInfo.validityEnd(), QLocale::LongFormat);
0081     case CertificateModel::Subject:
0082         return m_certificateInfo.subjectInfo(Okular::CertificateInfo::DistinguishedName, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
0083     case CertificateModel::PublicKey:
0084         return i18n("%1 (%2 bits)", SignatureGuiUtils::getReadablePublicKeyType(m_certificateInfo.publicKeyType()), m_certificateInfo.publicKeyStrength());
0085     case CertificateModel::KeyUsage:
0086         return SignatureGuiUtils::getReadableKeyUsageCommaSeparated(m_certificateInfo.keyUsageExtensions());
0087     case CertificateModel::IssuerName:
0088         return m_certificateInfo.issuerInfo(Okular::CertificateInfo::CommonName, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
0089     case CertificateModel::IssuerEmail:
0090         return m_certificateInfo.issuerInfo(Okular::CertificateInfo::EmailAddress, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
0091     case CertificateModel::IssuerOrganization:
0092         return m_certificateInfo.issuerInfo(Okular::CertificateInfo::Organization, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
0093     case CertificateModel::SubjectName:
0094         return m_certificateInfo.subjectInfo(Okular::CertificateInfo::CommonName, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
0095     case CertificateModel::SubjectEmail:
0096         return m_certificateInfo.subjectInfo(Okular::CertificateInfo::EmailAddress, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
0097     case CertificateModel::SubjectOrganization:
0098         return m_certificateInfo.subjectInfo(Okular::CertificateInfo::Organization, Okular::CertificateInfo::EmptyString::TranslatedNotAvailable);
0099     case CertificateModel::Sha1:
0100         return QString::fromLatin1(QCryptographicHash::hash(m_certificateInfo.certificateData(), QCryptographicHash::Sha1).toHex(' '));
0101     case CertificateModel::Sha256:
0102         return QString::fromLatin1(QCryptographicHash::hash(m_certificateInfo.certificateData(), QCryptographicHash::Sha256).toHex(' '));
0103     }
0104     return QString();
0105 }
0106 
0107 QVariant CertificateModel::data(const QModelIndex &index, int role) const
0108 {
0109     const int row = index.row();
0110     if (!index.isValid() || row < 0 || row >= m_certificateProperties.count()) {
0111         return QVariant();
0112     }
0113 
0114     switch (role) {
0115     case Qt::DisplayRole:
0116     case Qt::ToolTipRole:
0117         switch (index.column()) {
0118         case 0:
0119             return propertyVisibleName(m_certificateProperties[row]);
0120         case 1:
0121             return propertyVisibleValue(m_certificateProperties[row]);
0122         default:
0123             return QString();
0124         }
0125     case PropertyKeyRole:
0126         return m_certificateProperties[row];
0127     case PropertyVisibleValueRole:
0128         return propertyVisibleValue(m_certificateProperties[row]);
0129     }
0130 
0131     return QVariant();
0132 }
0133 
0134 QVariant CertificateModel::headerData(int section, Qt::Orientation orientation, int role) const
0135 {
0136     if (role == Qt::TextAlignmentRole) {
0137         return QVariant(Qt::AlignLeft);
0138     }
0139 
0140     if (orientation != Qt::Horizontal || role != Qt::DisplayRole) {
0141         return QVariant();
0142     }
0143 
0144     switch (section) {
0145     case 0:
0146         return i18n("Property");
0147     case 1:
0148         return i18n("Value");
0149     default:
0150         return QVariant();
0151     }
0152 }
0153 
0154 bool CertificateModel::exportCertificateTo(const QString &path)
0155 {
0156     const QUrl url = QUrl::fromUserInput(path);
0157     if (!url.isLocalFile()) {
0158         return false;
0159     }
0160     QFile targetFile(url.toLocalFile());
0161     if (!targetFile.open(QIODevice::WriteOnly)) {
0162         return false;
0163     }
0164     const QByteArray data = m_certificateInfo.certificateData();
0165     return targetFile.write(data) == data.size();
0166 }