File indexing completed on 2024-05-12 16:06:47
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 "pdfsignatureutils.h" 0008 0009 #include <KLocalizedString> 0010 #include <QDebug> 0011 #include <QInputDialog> 0012 0013 static Okular::CertificateInfo::KeyUsageExtensions fromPoppler(Poppler::CertificateInfo::KeyUsageExtensions popplerKu) 0014 { 0015 using namespace Okular; 0016 CertificateInfo::KeyUsageExtensions ku = CertificateInfo::KuNone; 0017 if (popplerKu.testFlag(Poppler::CertificateInfo::KuDigitalSignature)) { 0018 ku |= CertificateInfo::KuDigitalSignature; 0019 } 0020 if (popplerKu.testFlag(Poppler::CertificateInfo::KuNonRepudiation)) { 0021 ku |= CertificateInfo::KuNonRepudiation; 0022 } 0023 if (popplerKu.testFlag(Poppler::CertificateInfo::KuKeyEncipherment)) { 0024 ku |= CertificateInfo::KuKeyEncipherment; 0025 } 0026 if (popplerKu.testFlag(Poppler::CertificateInfo::KuDataEncipherment)) { 0027 ku |= CertificateInfo::KuDataEncipherment; 0028 } 0029 if (popplerKu.testFlag(Poppler::CertificateInfo::KuKeyAgreement)) { 0030 ku |= CertificateInfo::KuKeyAgreement; 0031 } 0032 if (popplerKu.testFlag(Poppler::CertificateInfo::KuKeyCertSign)) { 0033 ku |= CertificateInfo::KuKeyCertSign; 0034 } 0035 if (popplerKu.testFlag(Poppler::CertificateInfo::KuClrSign)) { 0036 ku |= CertificateInfo::KuClrSign; 0037 } 0038 if (popplerKu.testFlag(Poppler::CertificateInfo::KuEncipherOnly)) { 0039 ku |= CertificateInfo::KuEncipherOnly; 0040 } 0041 return ku; 0042 } 0043 0044 static Okular::CertificateInfo::PublicKeyType fromPoppler(Poppler::CertificateInfo::PublicKeyType type) 0045 { 0046 switch (type) { 0047 case Poppler::CertificateInfo::RsaKey: 0048 return Okular::CertificateInfo::RsaKey; 0049 case Poppler::CertificateInfo::DsaKey: 0050 return Okular::CertificateInfo::DsaKey; 0051 case Poppler::CertificateInfo::EcKey: 0052 return Okular::CertificateInfo::EcKey; 0053 case Poppler::CertificateInfo::OtherKey: 0054 return Okular::CertificateInfo::OtherKey; 0055 } 0056 return Okular::CertificateInfo::OtherKey; 0057 } 0058 0059 #if POPPLER_VERSION_MACRO > QT_VERSION_CHECK(23, 8, 0) 0060 static Okular::CertificateInfo::KeyLocation fromPoppler(Poppler::CertificateInfo::KeyLocation location) 0061 { 0062 switch (location) { 0063 case Poppler::CertificateInfo::KeyLocation::Computer: 0064 return Okular::CertificateInfo::KeyLocation::Computer; 0065 case Poppler::CertificateInfo::KeyLocation::Unknown: 0066 return Okular::CertificateInfo::KeyLocation::Unknown; 0067 case Poppler::CertificateInfo::KeyLocation::HardwareToken: 0068 return Okular::CertificateInfo::KeyLocation::HardwareToken; 0069 case Poppler::CertificateInfo::KeyLocation::Other: 0070 return Okular::CertificateInfo::KeyLocation::Other; 0071 } 0072 return Okular::CertificateInfo::KeyLocation::Unknown; 0073 } 0074 #endif 0075 0076 Okular::CertificateInfo fromPoppler(const Poppler::CertificateInfo &pInfo) 0077 { 0078 Okular::CertificateInfo oInfo; 0079 if (pInfo.isNull()) { 0080 return oInfo; 0081 } 0082 oInfo.setNull(false); 0083 oInfo.setVersion(pInfo.version()); 0084 oInfo.setSerialNumber(pInfo.serialNumber()); 0085 for (auto key : 0086 {Poppler::CertificateInfo::EntityInfoKey::CommonName, Poppler::CertificateInfo::EntityInfoKey::DistinguishedName, Poppler::CertificateInfo::EntityInfoKey::EmailAddress, Poppler::CertificateInfo::EntityInfoKey::Organization}) { 0087 oInfo.setIssuerInfo(static_cast<Okular::CertificateInfo::EntityInfoKey>(key), pInfo.issuerInfo(key)); 0088 oInfo.setSubjectInfo(static_cast<Okular::CertificateInfo::EntityInfoKey>(key), pInfo.subjectInfo(key)); 0089 } 0090 oInfo.setNickName(pInfo.nickName()); 0091 oInfo.setValidityStart(pInfo.validityStart()); 0092 oInfo.setValidityEnd(pInfo.validityEnd()); 0093 oInfo.setKeyUsageExtensions(fromPoppler(pInfo.keyUsageExtensions())); 0094 oInfo.setPublicKey(pInfo.publicKey()); 0095 oInfo.setPublicKeyType(fromPoppler(pInfo.publicKeyType())); 0096 oInfo.setPublicKeyStrength(pInfo.publicKeyStrength()); 0097 oInfo.setSelfSigned(pInfo.isSelfSigned()); 0098 oInfo.setCertificateData(pInfo.certificateData()); 0099 #if POPPLER_VERSION_MACRO > QT_VERSION_CHECK(23, 8, 0) 0100 oInfo.setKeyLocation(fromPoppler(pInfo.keyLocation())); 0101 #endif 0102 oInfo.setCheckPasswordFunction([pInfo](const QString &password) { 0103 #if POPPLER_VERSION_MACRO >= QT_VERSION_CHECK(23, 06, 0) 0104 auto backend = Poppler::activeCryptoSignBackend(); 0105 if (!backend) { 0106 return false; 0107 } 0108 if (Poppler::hasCryptoSignBackendFeature(backend.value(), Poppler::CryptoSignBackendFeature::BackendAsksPassphrase)) { 0109 // we shouldn't ask anyone about passwords. The backend will do that themselves, so just assume everything is okay. 0110 return true; 0111 } 0112 #endif 0113 return pInfo.checkPassword(password); 0114 }); 0115 #if POPPLER_VERSION_MACRO >= QT_VERSION_CHECK(23, 06, 0) 0116 if (Poppler::activeCryptoSignBackend() == Poppler::CryptoSignBackend::GPG) { 0117 oInfo.setBackend(Okular::CertificateInfo::Backend::Gpg); 0118 } 0119 #endif 0120 return oInfo; 0121 } 0122 0123 Okular::SignatureInfo::CertificateStatus fromPoppler(Poppler::SignatureValidationInfo::CertificateStatus status) 0124 { 0125 switch (status) { 0126 case Poppler::SignatureValidationInfo::CertificateTrusted: 0127 return Okular::SignatureInfo::CertificateTrusted; 0128 case Poppler::SignatureValidationInfo::CertificateUntrustedIssuer: 0129 return Okular::SignatureInfo::CertificateUntrustedIssuer; 0130 case Poppler::SignatureValidationInfo::CertificateUnknownIssuer: 0131 return Okular::SignatureInfo::CertificateUnknownIssuer; 0132 case Poppler::SignatureValidationInfo::CertificateRevoked: 0133 return Okular::SignatureInfo::CertificateRevoked; 0134 case Poppler::SignatureValidationInfo::CertificateExpired: 0135 return Okular::SignatureInfo::CertificateExpired; 0136 case Poppler::SignatureValidationInfo::CertificateGenericError: 0137 return Okular::SignatureInfo::CertificateGenericError; 0138 case Poppler::SignatureValidationInfo::CertificateNotVerified: 0139 return Okular::SignatureInfo::CertificateNotVerified; 0140 default: 0141 return Okular::SignatureInfo::CertificateStatusUnknown; 0142 } 0143 } 0144 0145 Okular::SignatureInfo::SignatureStatus fromPoppler(Poppler::SignatureValidationInfo::SignatureStatus status) 0146 { 0147 switch (status) { 0148 case Poppler::SignatureValidationInfo::SignatureValid: 0149 return Okular::SignatureInfo::SignatureValid; 0150 case Poppler::SignatureValidationInfo::SignatureInvalid: 0151 return Okular::SignatureInfo::SignatureInvalid; 0152 case Poppler::SignatureValidationInfo::SignatureDigestMismatch: 0153 return Okular::SignatureInfo::SignatureDigestMismatch; 0154 case Poppler::SignatureValidationInfo::SignatureDecodingError: 0155 return Okular::SignatureInfo::SignatureDecodingError; 0156 case Poppler::SignatureValidationInfo::SignatureGenericError: 0157 return Okular::SignatureInfo::SignatureGenericError; 0158 case Poppler::SignatureValidationInfo::SignatureNotFound: 0159 return Okular::SignatureInfo::SignatureNotFound; 0160 case Poppler::SignatureValidationInfo::SignatureNotVerified: 0161 return Okular::SignatureInfo::SignatureNotVerified; 0162 default: 0163 return Okular::SignatureInfo::SignatureStatusUnknown; 0164 } 0165 } 0166 0167 Okular::SignatureInfo::HashAlgorithm fromPoppler(Poppler::SignatureValidationInfo::HashAlgorithm hash) 0168 { 0169 switch (hash) { 0170 case Poppler::SignatureValidationInfo::HashAlgorithmMd2: 0171 return Okular::SignatureInfo::HashAlgorithmMd2; 0172 case Poppler::SignatureValidationInfo::HashAlgorithmMd5: 0173 return Okular::SignatureInfo::HashAlgorithmMd5; 0174 case Poppler::SignatureValidationInfo::HashAlgorithmSha1: 0175 return Okular::SignatureInfo::HashAlgorithmSha1; 0176 case Poppler::SignatureValidationInfo::HashAlgorithmSha256: 0177 return Okular::SignatureInfo::HashAlgorithmSha256; 0178 case Poppler::SignatureValidationInfo::HashAlgorithmSha384: 0179 return Okular::SignatureInfo::HashAlgorithmSha384; 0180 case Poppler::SignatureValidationInfo::HashAlgorithmSha512: 0181 return Okular::SignatureInfo::HashAlgorithmSha512; 0182 case Poppler::SignatureValidationInfo::HashAlgorithmSha224: 0183 return Okular::SignatureInfo::HashAlgorithmSha224; 0184 default: 0185 return Okular::SignatureInfo::HashAlgorithmUnknown; 0186 } 0187 } 0188 0189 Okular::SignatureInfo fromPoppler(const Poppler::SignatureValidationInfo &pInfo) 0190 { 0191 Okular::SignatureInfo oInfo; 0192 oInfo.setCertificateInfo(fromPoppler(pInfo.certificateInfo())); 0193 oInfo.setSignatureStatus(fromPoppler(pInfo.signatureStatus())); 0194 oInfo.setCertificateStatus(fromPoppler(pInfo.certificateStatus())); 0195 oInfo.setHashAlgorithm(fromPoppler(pInfo.hashAlgorithm())); 0196 oInfo.setSignerName(pInfo.signerName()); 0197 oInfo.setSignerSubjectDN(pInfo.signerSubjectDN()); 0198 oInfo.setLocation(pInfo.location()); 0199 oInfo.setReason(pInfo.reason()); 0200 oInfo.setSigningTime(QDateTime::fromSecsSinceEpoch(pInfo.signingTime())); 0201 oInfo.setSignature(pInfo.signature()); 0202 oInfo.setSignedRangeBounds(pInfo.signedRangeBounds()); 0203 oInfo.setSignsTotalDocument(pInfo.signsTotalDocument()); 0204 return oInfo; 0205 } 0206 0207 PopplerCertificateStore::~PopplerCertificateStore() = default; 0208 0209 QList<Okular::CertificateInfo> PopplerCertificateStore::signingCertificates(bool *userCancelled) const 0210 { 0211 *userCancelled = false; 0212 auto PDFGeneratorNSSPasswordCallback = [&userCancelled](const char *element) -> char * { 0213 bool ok; 0214 const QString pwd = QInputDialog::getText(nullptr, i18n("Enter Password"), i18n("Enter password to open %1:", QString::fromUtf8(element)), QLineEdit::Password, QString(), &ok); 0215 *userCancelled = !ok; 0216 return ok ? strdup(pwd.toUtf8().constData()) : nullptr; 0217 }; 0218 Poppler::setNSSPasswordCallback(PDFGeneratorNSSPasswordCallback); 0219 0220 const QVector<Poppler::CertificateInfo> certs = Poppler::getAvailableSigningCertificates(); 0221 QList<Okular::CertificateInfo> vReturnCerts; 0222 for (const auto &cert : certs) { 0223 vReturnCerts.append(fromPoppler(cert)); 0224 } 0225 0226 Poppler::setNSSPasswordCallback(nullptr); 0227 0228 return vReturnCerts; 0229 }