File indexing completed on 2024-04-28 04:33:06
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 "signatureguiutils.h" 0008 0009 #include <KLocalizedString> 0010 0011 #include "core/document.h" 0012 #include "core/form.h" 0013 #include "core/page.h" 0014 0015 namespace SignatureGuiUtils 0016 { 0017 QVector<const Okular::FormFieldSignature *> getSignatureFormFields(const Okular::Document *doc) 0018 { 0019 uint curPage = 0; 0020 const uint endPage = doc->pages() - 1; 0021 QVector<const Okular::FormFieldSignature *> signatureFormFields; 0022 while (curPage <= endPage) { 0023 const QList<Okular::FormField *> formFields = doc->page(curPage++)->formFields(); 0024 for (Okular::FormField *f : formFields) { 0025 if (f->type() == Okular::FormField::FormSignature) { 0026 signatureFormFields.append(static_cast<Okular::FormFieldSignature *>(f)); 0027 } 0028 } 0029 } 0030 std::sort(signatureFormFields.begin(), signatureFormFields.end(), [](const Okular::FormFieldSignature *a, const Okular::FormFieldSignature *b) { 0031 const Okular::SignatureInfo &infoA = a->signatureInfo(); 0032 const Okular::SignatureInfo &infoB = b->signatureInfo(); 0033 return infoA.signingTime() < infoB.signingTime(); 0034 }); 0035 return signatureFormFields; 0036 } 0037 0038 QString getReadableSignatureStatus(Okular::SignatureInfo::SignatureStatus sigStatus) 0039 { 0040 switch (sigStatus) { 0041 case Okular::SignatureInfo::SignatureValid: 0042 return i18n("The signature is cryptographically valid."); 0043 case Okular::SignatureInfo::SignatureInvalid: 0044 return i18n("The signature is cryptographically invalid."); 0045 case Okular::SignatureInfo::SignatureDigestMismatch: 0046 return i18n("Digest Mismatch occurred."); 0047 case Okular::SignatureInfo::SignatureDecodingError: 0048 return i18n("The signature CMS/PKCS7 structure is malformed."); 0049 case Okular::SignatureInfo::SignatureNotFound: 0050 return i18n("The requested signature is not present in the document."); 0051 default: 0052 return i18n("The signature could not be verified."); 0053 } 0054 } 0055 0056 QString getReadableCertStatus(Okular::SignatureInfo::CertificateStatus certStatus) 0057 { 0058 switch (certStatus) { 0059 case Okular::SignatureInfo::CertificateTrusted: 0060 return i18n("Certificate is Trusted."); 0061 case Okular::SignatureInfo::CertificateUntrustedIssuer: 0062 return i18n("Certificate issuer isn't Trusted."); 0063 case Okular::SignatureInfo::CertificateUnknownIssuer: 0064 return i18n("Certificate issuer is unknown."); 0065 case Okular::SignatureInfo::CertificateRevoked: 0066 return i18n("Certificate has been Revoked."); 0067 case Okular::SignatureInfo::CertificateExpired: 0068 return i18n("Certificate has Expired."); 0069 case Okular::SignatureInfo::CertificateNotVerified: 0070 return i18n("Certificate has not yet been verified."); 0071 default: 0072 return i18n("Unknown issue with Certificate or corrupted data."); 0073 } 0074 } 0075 0076 QString getReadableHashAlgorithm(Okular::SignatureInfo::HashAlgorithm hashAlg) 0077 { 0078 switch (hashAlg) { 0079 case Okular::SignatureInfo::HashAlgorithmMd2: 0080 return i18n("MD2"); 0081 case Okular::SignatureInfo::HashAlgorithmMd5: 0082 return i18n("MD5"); 0083 case Okular::SignatureInfo::HashAlgorithmSha1: 0084 return i18n("SHA1"); 0085 case Okular::SignatureInfo::HashAlgorithmSha256: 0086 return i18n("SHA256"); 0087 case Okular::SignatureInfo::HashAlgorithmSha384: 0088 return i18n("SHA384"); 0089 case Okular::SignatureInfo::HashAlgorithmSha512: 0090 return i18n("SHA512"); 0091 case Okular::SignatureInfo::HashAlgorithmSha224: 0092 return i18n("SHA224"); 0093 default: 0094 return i18n("Unknown Algorithm"); 0095 } 0096 } 0097 0098 QString getReadablePublicKeyType(Okular::CertificateInfo::PublicKeyType type) 0099 { 0100 switch (type) { 0101 case Okular::CertificateInfo::RsaKey: 0102 return i18n("RSA"); 0103 case Okular::CertificateInfo::DsaKey: 0104 return i18n("DSA"); 0105 case Okular::CertificateInfo::EcKey: 0106 return i18n("EC"); 0107 case Okular::CertificateInfo::OtherKey: 0108 return i18n("Unknown Type"); 0109 } 0110 0111 return i18n("Unknown Type"); 0112 } 0113 0114 QString getReadableKeyUsage(Okular::CertificateInfo::KeyUsageExtensions kuExtensions, const QString &separator) 0115 { 0116 QStringList ku; 0117 if (kuExtensions.testFlag(Okular::CertificateInfo::KuDigitalSignature)) { 0118 ku << i18n("Digital Signature"); 0119 } 0120 if (kuExtensions.testFlag(Okular::CertificateInfo::KuNonRepudiation)) { 0121 ku << i18n("Non-Repudiation"); 0122 } 0123 if (kuExtensions.testFlag(Okular::CertificateInfo::KuKeyEncipherment)) { 0124 ku << i18n("Encrypt Keys"); 0125 } 0126 if (kuExtensions.testFlag(Okular::CertificateInfo::KuDataEncipherment)) { 0127 ku << i18n("Decrypt Keys"); 0128 } 0129 if (kuExtensions.testFlag(Okular::CertificateInfo::KuKeyAgreement)) { 0130 ku << i18n("Key Agreement"); 0131 } 0132 if (kuExtensions.testFlag(Okular::CertificateInfo::KuKeyCertSign)) { 0133 ku << i18n("Sign Certificate"); 0134 } 0135 if (kuExtensions.testFlag(Okular::CertificateInfo::KuClrSign)) { 0136 ku << i18n("Sign CRL"); 0137 } 0138 if (kuExtensions.testFlag(Okular::CertificateInfo::KuEncipherOnly)) { 0139 ku << i18n("Encrypt Only"); 0140 } 0141 if (ku.isEmpty()) { 0142 ku << i18n("No Usage Specified"); 0143 } 0144 return ku.join(separator); 0145 } 0146 0147 QString getReadableKeyUsageCommaSeparated(Okular::CertificateInfo::KeyUsageExtensions kuExtensions) 0148 { 0149 return getReadableKeyUsage(kuExtensions, i18nc("Joins the various ways a signature key can be used in a longer string", ", ")); 0150 } 0151 0152 QString getReadableKeyUsageNewLineSeparated(Okular::CertificateInfo::KeyUsageExtensions kuExtensions) 0153 { 0154 return getReadableKeyUsage(kuExtensions, QStringLiteral("\n")); 0155 } 0156 0157 QString getReadableModificationSummary(const Okular::SignatureInfo &signatureInfo) 0158 { 0159 const Okular::SignatureInfo::SignatureStatus signatureStatus = signatureInfo.signatureStatus(); 0160 // signature validation status 0161 if (signatureStatus == Okular::SignatureInfo::SignatureValid) { 0162 if (signatureInfo.signsTotalDocument()) { 0163 return i18n("The document has not been modified since it was signed."); 0164 } else { 0165 return i18n( 0166 "The revision of the document that was covered by this signature has not been modified;\n" 0167 "however there have been subsequent changes to the document."); 0168 } 0169 } else if (signatureStatus == Okular::SignatureInfo::SignatureDigestMismatch) { 0170 return i18n("The document has been modified in a way not permitted by a previous signer."); 0171 } else { 0172 return i18n("The document integrity verification could not be completed."); 0173 } 0174 } 0175 0176 std::pair<KMessageWidget::MessageType, QString> documentSignatureMessageWidgetText(const Okular::Document *doc) 0177 { 0178 const uint numPages = doc->pages(); 0179 bool isDigitallySigned = false; 0180 for (uint i = 0; i < numPages; i++) { 0181 const QList<Okular::FormField *> formFields = doc->page(i)->formFields(); 0182 for (const Okular::FormField *f : formFields) { 0183 if (f->type() == Okular::FormField::FormSignature) { 0184 isDigitallySigned = true; 0185 } 0186 } 0187 } 0188 0189 if (isDigitallySigned) { 0190 const QVector<const Okular::FormFieldSignature *> signatureFormFields = SignatureGuiUtils::getSignatureFormFields(doc); 0191 bool allSignaturesValid = true; 0192 bool anySignatureUnsigned = false; 0193 for (const Okular::FormFieldSignature *signature : signatureFormFields) { 0194 if (signature->signatureType() == Okular::FormFieldSignature::UnsignedSignature) { 0195 anySignatureUnsigned = true; 0196 } else { 0197 const Okular::SignatureInfo &info = signature->signatureInfo(); 0198 if (info.signatureStatus() != Okular::SignatureInfo::SignatureValid) { 0199 allSignaturesValid = false; 0200 } 0201 } 0202 } 0203 0204 if (anySignatureUnsigned) { 0205 return {KMessageWidget::Information, i18n("This document has unsigned signature fields.")}; 0206 } else if (allSignaturesValid) { 0207 if (signatureFormFields.last()->signatureInfo().signsTotalDocument()) { 0208 return {KMessageWidget::Information, i18n("This document is digitally signed.")}; 0209 } else { 0210 return {KMessageWidget::Warning, i18n("This document is digitally signed. There have been changes since last signed.")}; 0211 } 0212 } else { 0213 return {KMessageWidget::Warning, i18n("This document is digitally signed. Some of the signatures could not be validated properly.")}; 0214 } 0215 } 0216 0217 return {KMessageWidget::Information, QString()}; 0218 } 0219 }