1 /*
2     SPDX-FileCopyrightText: 2018 Chinmoy Ranjan Pradhan <chinmoyrp65@gmail.com>
3 
4     SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "pdfsignatureutils.h"
8 
9 #include <KLocalizedString>
10 #include <QDebug>
11 #include <QInputDialog>
12 
PopplerCertificateInfo(const Poppler::CertificateInfo & info)13 PopplerCertificateInfo::PopplerCertificateInfo(const Poppler::CertificateInfo &info)
14     : m_info(info)
15 {
16 }
17 
~PopplerCertificateInfo()18 PopplerCertificateInfo::~PopplerCertificateInfo()
19 {
20 }
21 
isNull() const22 bool PopplerCertificateInfo::isNull() const
23 {
24     return m_info.isNull();
25 }
26 
version() const27 int PopplerCertificateInfo::version() const
28 {
29     return m_info.version();
30 }
31 
serialNumber() const32 QByteArray PopplerCertificateInfo::serialNumber() const
33 {
34     return m_info.serialNumber();
35 }
36 
issuerInfo(PopplerCertificateInfo::EntityInfoKey key) const37 QString PopplerCertificateInfo::issuerInfo(PopplerCertificateInfo::EntityInfoKey key) const
38 {
39     QString str = m_info.issuerInfo(static_cast<Poppler::CertificateInfo::EntityInfoKey>(key));
40     return !str.isEmpty() ? str : i18n("Not Available");
41 }
42 
subjectInfo(PopplerCertificateInfo::EntityInfoKey key) const43 QString PopplerCertificateInfo::subjectInfo(PopplerCertificateInfo::EntityInfoKey key) const
44 {
45     QString str = m_info.subjectInfo(static_cast<Poppler::CertificateInfo::EntityInfoKey>(key));
46     return !str.isEmpty() ? str : i18n("Not Available");
47 }
48 
nickName() const49 QString PopplerCertificateInfo::nickName() const
50 {
51 #ifdef HAVE_POPPLER_SIGNING
52     return m_info.nickName();
53 #else
54     return i18n("Not Available");
55 #endif
56 }
57 
validityStart() const58 QDateTime PopplerCertificateInfo::validityStart() const
59 {
60     return m_info.validityStart();
61 }
62 
validityEnd() const63 QDateTime PopplerCertificateInfo::validityEnd() const
64 {
65     return m_info.validityEnd();
66 }
67 
keyUsageExtensions() const68 PopplerCertificateInfo::KeyUsageExtensions PopplerCertificateInfo::keyUsageExtensions() const
69 {
70     Poppler::CertificateInfo::KeyUsageExtensions popplerKu = m_info.keyUsageExtensions();
71     KeyUsageExtensions ku = KuNone;
72     if (popplerKu.testFlag(Poppler::CertificateInfo::KuDigitalSignature))
73         ku |= KuDigitalSignature;
74     if (popplerKu.testFlag(Poppler::CertificateInfo::KuNonRepudiation))
75         ku |= KuNonRepudiation;
76     if (popplerKu.testFlag(Poppler::CertificateInfo::KuKeyEncipherment))
77         ku |= KuKeyEncipherment;
78     if (popplerKu.testFlag(Poppler::CertificateInfo::KuDataEncipherment))
79         ku |= KuDataEncipherment;
80     if (popplerKu.testFlag(Poppler::CertificateInfo::KuKeyAgreement))
81         ku |= KuKeyAgreement;
82     if (popplerKu.testFlag(Poppler::CertificateInfo::KuKeyCertSign))
83         ku |= KuKeyCertSign;
84     if (popplerKu.testFlag(Poppler::CertificateInfo::KuClrSign))
85         ku |= KuClrSign;
86     if (popplerKu.testFlag(Poppler::CertificateInfo::KuEncipherOnly))
87         ku |= KuEncipherOnly;
88     return ku;
89 }
90 
publicKey() const91 QByteArray PopplerCertificateInfo::publicKey() const
92 {
93     return m_info.publicKey();
94 }
95 
publicKeyType() const96 PopplerCertificateInfo::PublicKeyType PopplerCertificateInfo::publicKeyType() const
97 {
98     switch (m_info.publicKeyType()) {
99     case Poppler::CertificateInfo::RsaKey:
100         return RsaKey;
101     case Poppler::CertificateInfo::DsaKey:
102         return DsaKey;
103     case Poppler::CertificateInfo::EcKey:
104         return EcKey;
105     case Poppler::CertificateInfo::OtherKey:
106         return OtherKey;
107     }
108 
109     return OtherKey;
110 }
111 
publicKeyStrength() const112 int PopplerCertificateInfo::publicKeyStrength() const
113 {
114     return m_info.publicKeyStrength();
115 }
116 
isSelfSigned() const117 bool PopplerCertificateInfo::isSelfSigned() const
118 {
119     return m_info.isSelfSigned();
120 }
121 
certificateData() const122 QByteArray PopplerCertificateInfo::certificateData() const
123 {
124     return m_info.certificateData();
125 }
126 
checkPassword(const QString & password) const127 bool PopplerCertificateInfo::checkPassword(const QString &password) const
128 {
129 #ifdef HAVE_POPPLER_SIGNING
130     return m_info.checkPassword(password);
131 #else
132     Q_UNUSED(password);
133     return false;
134 #endif
135 }
136 
PopplerSignatureInfo(const Poppler::SignatureValidationInfo & info)137 PopplerSignatureInfo::PopplerSignatureInfo(const Poppler::SignatureValidationInfo &info)
138     : m_info(info)
139 {
140     m_certfiticateInfo = new PopplerCertificateInfo(m_info.certificateInfo());
141 }
142 
~PopplerSignatureInfo()143 PopplerSignatureInfo::~PopplerSignatureInfo()
144 {
145     delete m_certfiticateInfo;
146 }
147 
signatureStatus() const148 PopplerSignatureInfo::SignatureStatus PopplerSignatureInfo::signatureStatus() const
149 {
150     switch (m_info.signatureStatus()) {
151     case Poppler::SignatureValidationInfo::SignatureValid:
152         return SignatureValid;
153     case Poppler::SignatureValidationInfo::SignatureInvalid:
154         return SignatureInvalid;
155     case Poppler::SignatureValidationInfo::SignatureDigestMismatch:
156         return SignatureDigestMismatch;
157     case Poppler::SignatureValidationInfo::SignatureDecodingError:
158         return SignatureDecodingError;
159     case Poppler::SignatureValidationInfo::SignatureGenericError:
160         return SignatureGenericError;
161     case Poppler::SignatureValidationInfo::SignatureNotFound:
162         return SignatureNotFound;
163     case Poppler::SignatureValidationInfo::SignatureNotVerified:
164         return SignatureNotVerified;
165     default:
166         return SignatureStatusUnknown;
167     }
168 }
169 
certificateStatus() const170 PopplerSignatureInfo::CertificateStatus PopplerSignatureInfo::certificateStatus() const
171 {
172     switch (m_info.certificateStatus()) {
173     case Poppler::SignatureValidationInfo::CertificateTrusted:
174         return CertificateTrusted;
175     case Poppler::SignatureValidationInfo::CertificateUntrustedIssuer:
176         return CertificateUntrustedIssuer;
177     case Poppler::SignatureValidationInfo::CertificateUnknownIssuer:
178         return CertificateUnknownIssuer;
179     case Poppler::SignatureValidationInfo::CertificateRevoked:
180         return CertificateRevoked;
181     case Poppler::SignatureValidationInfo::CertificateExpired:
182         return CertificateExpired;
183     case Poppler::SignatureValidationInfo::CertificateGenericError:
184         return CertificateGenericError;
185     case Poppler::SignatureValidationInfo::CertificateNotVerified:
186         return CertificateNotVerified;
187     default:
188         return CertificateStatusUnknown;
189     }
190 }
191 
hashAlgorithm() const192 PopplerSignatureInfo::HashAlgorithm PopplerSignatureInfo::hashAlgorithm() const
193 {
194     switch (m_info.hashAlgorithm()) {
195     case Poppler::SignatureValidationInfo::HashAlgorithmMd2:
196         return HashAlgorithmMd2;
197     case Poppler::SignatureValidationInfo::HashAlgorithmMd5:
198         return HashAlgorithmMd5;
199     case Poppler::SignatureValidationInfo::HashAlgorithmSha1:
200         return HashAlgorithmSha1;
201     case Poppler::SignatureValidationInfo::HashAlgorithmSha256:
202         return HashAlgorithmSha256;
203     case Poppler::SignatureValidationInfo::HashAlgorithmSha384:
204         return HashAlgorithmSha384;
205     case Poppler::SignatureValidationInfo::HashAlgorithmSha512:
206         return HashAlgorithmSha512;
207     case Poppler::SignatureValidationInfo::HashAlgorithmSha224:
208         return HashAlgorithmSha224;
209     default:
210         return HashAlgorithmUnknown;
211     }
212 }
213 
signerName() const214 QString PopplerSignatureInfo::signerName() const
215 {
216     return m_info.signerName();
217 }
218 
signerSubjectDN() const219 QString PopplerSignatureInfo::signerSubjectDN() const
220 {
221     return m_info.signerSubjectDN();
222 }
223 
location() const224 QString PopplerSignatureInfo::location() const
225 {
226     return m_info.location();
227 }
228 
reason() const229 QString PopplerSignatureInfo::reason() const
230 {
231     return m_info.reason();
232 }
233 
signingTime() const234 QDateTime PopplerSignatureInfo::signingTime() const
235 {
236     return QDateTime::fromSecsSinceEpoch(m_info.signingTime());
237 }
238 
signature() const239 QByteArray PopplerSignatureInfo::signature() const
240 {
241     return m_info.signature();
242 }
243 
signedRangeBounds() const244 QList<qint64> PopplerSignatureInfo::signedRangeBounds() const
245 {
246     return m_info.signedRangeBounds();
247 }
248 
signsTotalDocument() const249 bool PopplerSignatureInfo::signsTotalDocument() const
250 {
251     return m_info.signsTotalDocument();
252 }
253 
certificateInfo() const254 const Okular::CertificateInfo &PopplerSignatureInfo::certificateInfo() const
255 {
256     return *m_certfiticateInfo;
257 }
258 
259 #ifdef HAVE_POPPLER_SIGNING
260 PopplerCertificateStore::~PopplerCertificateStore() = default;
261 
signingCertificates(bool * userCancelled) const262 QList<Okular::CertificateInfo *> PopplerCertificateStore::signingCertificates(bool *userCancelled) const
263 {
264     *userCancelled = false;
265     auto PDFGeneratorNSSPasswordCallback = [&userCancelled](const char *element) -> char * {
266         bool ok;
267         const QString pwd = QInputDialog::getText(nullptr, i18n("Enter Password"), i18n("Enter password to open %1:", element), QLineEdit::Password, QString(), &ok);
268         *userCancelled = !ok;
269         return ok ? strdup(pwd.toUtf8().constData()) : nullptr;
270     };
271     Poppler::setNSSPasswordCallback(PDFGeneratorNSSPasswordCallback);
272 
273     const QVector<Poppler::CertificateInfo> certs = Poppler::getAvailableSigningCertificates();
274     QList<Okular::CertificateInfo *> vReturnCerts;
275     for (auto cert : certs)
276         vReturnCerts.append(new PopplerCertificateInfo(cert));
277 
278     Poppler::setNSSPasswordCallback(nullptr);
279 
280     return vReturnCerts;
281 }
282 #endif
283