1 /* poppler-form.h: qt interface to poppler
2  * Copyright (C) 2007-2008, 2011, Pino Toscano <pino@kde.org>
3  * Copyright (C) 2008, 2011, 2012, 2015-2021 Albert Astals Cid <aacid@kde.org>
4  * Copyright (C) 2011 Carlos Garcia Campos <carlosgc@gnome.org>
5  * Copyright (C) 2012, Adam Reichold <adamreichold@myopera.com>
6  * Copyright (C) 2016, Hanno Meyer-Thurow <h.mth@web.de>
7  * Copyright (C) 2017, Hans-Ulrich Jüttner <huj@froreich-bioscientia.de>
8  * Copyright (C) 2018, Andre Heinecke <aheinecke@intevation.de>
9  * Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich
10  * Copyright (C) 2018 Chinmoy Ranjan Pradhan <chinmoyrp65@protonmail.com>
11  * Copyright (C) 2018, 2020 Oliver Sander <oliver.sander@tu-dresden.de>
12  * Copyright (C) 2019 João Netto <joaonetto901@gmail.com>
13  * Copyright (C) 2020 David García Garzón <voki@canvoki.net>
14  * Copyright (C) 2020 Thorsten Behrens <Thorsten.Behrens@CIB.de>
15  * Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by Technische Universität Dresden
16  * Copyright (C) 2021 Georgiy Sgibnev <georgiy@sgibnev.com>. Work sponsored by lab50.net.
17  * Copyright (C) 2021 Theofilos Intzoglou <int.teo@gmail.com>
18  *
19  * This program is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 2, or (at your option)
22  * any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program; if not, write to the Free Software
31  * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
32  */
33 
34 #include "poppler-qt5.h"
35 
36 #include <config.h>
37 
38 #include <QtCore/QSizeF>
39 #include <QUrl>
40 
41 #include <Form.h>
42 #include <Object.h>
43 #include <Link.h>
44 #include <SignatureInfo.h>
45 #include <CertificateInfo.h>
46 #ifdef ENABLE_NSS3
47 #    include <SignatureHandler.h>
48 #endif
49 
50 #include "poppler-form.h"
51 #include "poppler-page-private.h"
52 #include "poppler-private.h"
53 #include "poppler-annotation-helper.h"
54 
55 #include <cmath>
56 #include <cctype>
57 
58 #ifdef ENABLE_NSS3
59 #    include <hasht.h>
60 #endif
61 
62 namespace {
63 
formTextAlignment(::FormWidget * fm)64 Qt::Alignment formTextAlignment(::FormWidget *fm)
65 {
66     Qt::Alignment qtalign = Qt::AlignLeft;
67     switch (fm->getField()->getTextQuadding()) {
68     case quaddingCentered:
69         qtalign = Qt::AlignHCenter;
70         break;
71     case quaddingRightJustified:
72         qtalign = Qt::AlignRight;
73         break;
74     case quaddingLeftJustified:
75         qtalign = Qt::AlignLeft;
76     }
77     return qtalign;
78 }
79 
80 }
81 
82 namespace Poppler {
83 
FormFieldIcon(FormFieldIconData * data)84 FormFieldIcon::FormFieldIcon(FormFieldIconData *data) : d_ptr(data) { }
85 
FormFieldIcon(const FormFieldIcon & ffIcon)86 FormFieldIcon::FormFieldIcon(const FormFieldIcon &ffIcon)
87 {
88     d_ptr = new FormFieldIconData;
89     d_ptr->icon = ffIcon.d_ptr->icon;
90 }
91 
operator =(const FormFieldIcon & ffIcon)92 FormFieldIcon &FormFieldIcon::operator=(const FormFieldIcon &ffIcon)
93 {
94     if (this != &ffIcon) {
95         delete d_ptr;
96         d_ptr = nullptr;
97 
98         d_ptr = new FormFieldIconData;
99         *d_ptr = *ffIcon.d_ptr;
100     }
101 
102     return *this;
103 }
104 
~FormFieldIcon()105 FormFieldIcon::~FormFieldIcon()
106 {
107     delete d_ptr;
108 }
109 
FormField(std::unique_ptr<FormFieldData> dd)110 FormField::FormField(std::unique_ptr<FormFieldData> dd) : m_formData(std::move(dd))
111 {
112     if (m_formData->page) {
113         const int rotation = m_formData->page->getRotate();
114         // reading the coords
115         double left, top, right, bottom;
116         m_formData->fm->getRect(&left, &bottom, &right, &top);
117         // build a normalized transform matrix for this page at 100% scale
118         GfxState gfxState(72.0, 72.0, m_formData->page->getCropBox(), rotation, true);
119         const double *gfxCTM = gfxState.getCTM();
120         double MTX[6];
121         double pageWidth = m_formData->page->getCropWidth();
122         double pageHeight = m_formData->page->getCropHeight();
123         // landscape and seascape page rotation: be sure to use the correct (== rotated) page size
124         if (((rotation / 90) % 2) == 1)
125             qSwap(pageWidth, pageHeight);
126         for (int i = 0; i < 6; i += 2) {
127             MTX[i] = gfxCTM[i] / pageWidth;
128             MTX[i + 1] = gfxCTM[i + 1] / pageHeight;
129         }
130         QPointF topLeft;
131         XPDFReader::transform(MTX, qMin(left, right), qMax(top, bottom), topLeft);
132         QPointF bottomRight;
133         XPDFReader::transform(MTX, qMax(left, right), qMin(top, bottom), bottomRight);
134         m_formData->box = QRectF(topLeft, QSizeF(bottomRight.x() - topLeft.x(), bottomRight.y() - topLeft.y()));
135     }
136 }
137 
138 FormField::~FormField() = default;
139 
rect() const140 QRectF FormField::rect() const
141 {
142     return m_formData->box;
143 }
144 
id() const145 int FormField::id() const
146 {
147     return m_formData->fm->getID();
148 }
149 
name() const150 QString FormField::name() const
151 {
152     QString name;
153     if (const GooString *goo = m_formData->fm->getPartialName()) {
154         name = UnicodeParsedString(goo);
155     }
156     return name;
157 }
158 
setName(const QString & name) const159 void FormField::setName(const QString &name) const
160 {
161     GooString *goo = QStringToGooString(name);
162     m_formData->fm->setPartialName(*goo);
163     delete goo;
164 }
165 
fullyQualifiedName() const166 QString FormField::fullyQualifiedName() const
167 {
168     QString name;
169     if (GooString *goo = m_formData->fm->getFullyQualifiedName()) {
170         name = UnicodeParsedString(goo);
171     }
172     return name;
173 }
174 
uiName() const175 QString FormField::uiName() const
176 {
177     QString name;
178     if (const GooString *goo = m_formData->fm->getAlternateUiName()) {
179         name = UnicodeParsedString(goo);
180     }
181     return name;
182 }
183 
isReadOnly() const184 bool FormField::isReadOnly() const
185 {
186     return m_formData->fm->isReadOnly();
187 }
188 
setReadOnly(bool value)189 void FormField::setReadOnly(bool value)
190 {
191     m_formData->fm->setReadOnly(value);
192 }
193 
isVisible() const194 bool FormField::isVisible() const
195 {
196     return !(m_formData->fm->getWidgetAnnotation()->getFlags() & Annot::flagHidden);
197 }
198 
setVisible(bool value)199 void FormField::setVisible(bool value)
200 {
201     unsigned int flags = m_formData->fm->getWidgetAnnotation()->getFlags();
202     if (value) {
203         flags &= ~Annot::flagHidden;
204     } else {
205         flags |= Annot::flagHidden;
206     }
207     m_formData->fm->getWidgetAnnotation()->setFlags(flags);
208 }
209 
isPrintable() const210 bool FormField::isPrintable() const
211 {
212     return (m_formData->fm->getWidgetAnnotation()->getFlags() & Annot::flagPrint);
213 }
214 
setPrintable(bool value)215 void FormField::setPrintable(bool value)
216 {
217     unsigned int flags = m_formData->fm->getWidgetAnnotation()->getFlags();
218     if (value) {
219         flags |= Annot::flagPrint;
220     } else {
221         flags &= ~Annot::flagPrint;
222     }
223     m_formData->fm->getWidgetAnnotation()->setFlags(flags);
224 }
225 
activationAction() const226 Link *FormField::activationAction() const
227 {
228     Link *action = nullptr;
229     if (::LinkAction *act = m_formData->fm->getActivationAction()) {
230         action = PageData::convertLinkActionToLink(act, m_formData->doc, QRectF());
231     }
232     return action;
233 }
234 
additionalAction(AdditionalActionType type) const235 Link *FormField::additionalAction(AdditionalActionType type) const
236 {
237     Annot::FormAdditionalActionsType actionType = Annot::actionFieldModified;
238     switch (type) {
239     case FieldModified:
240         actionType = Annot::actionFieldModified;
241         break;
242     case FormatField:
243         actionType = Annot::actionFormatField;
244         break;
245     case ValidateField:
246         actionType = Annot::actionValidateField;
247         break;
248     case CalculateField:
249         actionType = Annot::actionCalculateField;
250         break;
251     }
252 
253     Link *action = nullptr;
254     if (std::unique_ptr<::LinkAction> act = m_formData->fm->getAdditionalAction(actionType)) {
255         action = PageData::convertLinkActionToLink(act.get(), m_formData->doc, QRectF());
256     }
257     return action;
258 }
259 
additionalAction(Annotation::AdditionalActionType type) const260 Link *FormField::additionalAction(Annotation::AdditionalActionType type) const
261 {
262     ::AnnotWidget *w = m_formData->fm->getWidgetAnnotation();
263     if (!w) {
264         return nullptr;
265     }
266 
267     const Annot::AdditionalActionsType actionType = toPopplerAdditionalActionType(type);
268 
269     Link *action = nullptr;
270     if (std::unique_ptr<::LinkAction> act = w->getAdditionalAction(actionType)) {
271         action = PageData::convertLinkActionToLink(act.get(), m_formData->doc, QRectF());
272     }
273     return action;
274 }
275 
FormFieldButton(DocumentData * doc,::Page * p,::FormWidgetButton * w)276 FormFieldButton::FormFieldButton(DocumentData *doc, ::Page *p, ::FormWidgetButton *w) : FormField(std::make_unique<FormFieldData>(doc, p, w)) { }
277 
~FormFieldButton()278 FormFieldButton::~FormFieldButton() { }
279 
type() const280 FormFieldButton::FormType FormFieldButton::type() const
281 {
282     return FormField::FormButton;
283 }
284 
buttonType() const285 FormFieldButton::ButtonType FormFieldButton::buttonType() const
286 {
287     FormWidgetButton *fwb = static_cast<FormWidgetButton *>(m_formData->fm);
288     switch (fwb->getButtonType()) {
289     case formButtonCheck:
290         return FormFieldButton::CheckBox;
291         break;
292     case formButtonPush:
293         return FormFieldButton::Push;
294         break;
295     case formButtonRadio:
296         return FormFieldButton::Radio;
297         break;
298     }
299     return FormFieldButton::CheckBox;
300 }
301 
caption() const302 QString FormFieldButton::caption() const
303 {
304     FormWidgetButton *fwb = static_cast<FormWidgetButton *>(m_formData->fm);
305     QString ret;
306     if (fwb->getButtonType() == formButtonPush) {
307         Dict *dict = m_formData->fm->getObj()->getDict();
308         Object obj1 = dict->lookup("MK");
309         if (obj1.isDict()) {
310             AnnotAppearanceCharacs appearCharacs(obj1.getDict());
311             if (appearCharacs.getNormalCaption()) {
312                 ret = UnicodeParsedString(appearCharacs.getNormalCaption());
313             }
314         }
315     } else {
316         if (const char *goo = fwb->getOnStr()) {
317             ret = QString::fromUtf8(goo);
318         }
319     }
320     return ret;
321 }
322 
icon() const323 FormFieldIcon FormFieldButton::icon() const
324 {
325     FormWidgetButton *fwb = static_cast<FormWidgetButton *>(m_formData->fm);
326     if (fwb->getButtonType() == formButtonPush) {
327         Dict *dict = m_formData->fm->getObj()->getDict();
328         FormFieldIconData *data = new FormFieldIconData;
329         data->icon = dict;
330         return FormFieldIcon(data);
331     }
332     return FormFieldIcon(nullptr);
333 }
334 
setIcon(const FormFieldIcon & icon)335 void FormFieldButton::setIcon(const FormFieldIcon &icon)
336 {
337     if (FormFieldIconData::getData(icon) == nullptr)
338         return;
339 
340     FormWidgetButton *fwb = static_cast<FormWidgetButton *>(m_formData->fm);
341     if (fwb->getButtonType() == formButtonPush) {
342         ::AnnotWidget *w = m_formData->fm->getWidgetAnnotation();
343         FormFieldIconData *data = FormFieldIconData::getData(icon);
344         if (data->icon != nullptr)
345             w->setNewAppearance(data->icon->lookup("AP"));
346     }
347 }
348 
state() const349 bool FormFieldButton::state() const
350 {
351     FormWidgetButton *fwb = static_cast<FormWidgetButton *>(m_formData->fm);
352     return fwb->getState();
353 }
354 
setState(bool state)355 void FormFieldButton::setState(bool state)
356 {
357     FormWidgetButton *fwb = static_cast<FormWidgetButton *>(m_formData->fm);
358     fwb->setState((bool)state);
359 }
360 
siblings() const361 QList<int> FormFieldButton::siblings() const
362 {
363     FormWidgetButton *fwb = static_cast<FormWidgetButton *>(m_formData->fm);
364     ::FormFieldButton *ffb = static_cast<::FormFieldButton *>(fwb->getField());
365     if (fwb->getButtonType() == formButtonPush)
366         return QList<int>();
367 
368     QList<int> ret;
369     for (int i = 0; i < ffb->getNumSiblings(); ++i) {
370         ::FormFieldButton *sibling = static_cast<::FormFieldButton *>(ffb->getSibling(i));
371         for (int j = 0; j < sibling->getNumWidgets(); ++j) {
372             FormWidget *w = sibling->getWidget(j);
373             if (w)
374                 ret.append(w->getID());
375         }
376     }
377 
378     return ret;
379 }
380 
FormFieldText(DocumentData * doc,::Page * p,::FormWidgetText * w)381 FormFieldText::FormFieldText(DocumentData *doc, ::Page *p, ::FormWidgetText *w) : FormField(std::make_unique<FormFieldData>(doc, p, w)) { }
382 
~FormFieldText()383 FormFieldText::~FormFieldText() { }
384 
type() const385 FormField::FormType FormFieldText::type() const
386 {
387     return FormField::FormText;
388 }
389 
textType() const390 FormFieldText::TextType FormFieldText::textType() const
391 {
392     FormWidgetText *fwt = static_cast<FormWidgetText *>(m_formData->fm);
393     if (fwt->isFileSelect())
394         return FormFieldText::FileSelect;
395     else if (fwt->isMultiline())
396         return FormFieldText::Multiline;
397     return FormFieldText::Normal;
398 }
399 
text() const400 QString FormFieldText::text() const
401 {
402     const GooString *goo = static_cast<FormWidgetText *>(m_formData->fm)->getContent();
403     return UnicodeParsedString(goo);
404 }
405 
setText(const QString & text)406 void FormFieldText::setText(const QString &text)
407 {
408     FormWidgetText *fwt = static_cast<FormWidgetText *>(m_formData->fm);
409     GooString *goo = QStringToUnicodeGooString(text);
410     fwt->setContent(goo);
411     delete goo;
412 }
413 
setAppearanceText(const QString & text)414 void FormFieldText::setAppearanceText(const QString &text)
415 {
416     FormWidgetText *fwt = static_cast<FormWidgetText *>(m_formData->fm);
417     GooString *goo = QStringToUnicodeGooString(text);
418     fwt->setAppearanceContent(goo);
419     delete goo;
420 }
421 
isPassword() const422 bool FormFieldText::isPassword() const
423 {
424     FormWidgetText *fwt = static_cast<FormWidgetText *>(m_formData->fm);
425     return fwt->isPassword();
426 }
427 
isRichText() const428 bool FormFieldText::isRichText() const
429 {
430     FormWidgetText *fwt = static_cast<FormWidgetText *>(m_formData->fm);
431     return fwt->isRichText();
432 }
433 
maximumLength() const434 int FormFieldText::maximumLength() const
435 {
436     FormWidgetText *fwt = static_cast<FormWidgetText *>(m_formData->fm);
437     const int maxlen = fwt->getMaxLen();
438     return maxlen > 0 ? maxlen : -1;
439 }
440 
textAlignment() const441 Qt::Alignment FormFieldText::textAlignment() const
442 {
443     return formTextAlignment(m_formData->fm);
444 }
445 
canBeSpellChecked() const446 bool FormFieldText::canBeSpellChecked() const
447 {
448     FormWidgetText *fwt = static_cast<FormWidgetText *>(m_formData->fm);
449     return !fwt->noSpellCheck();
450 }
451 
getFontSize() const452 double FormFieldText::getFontSize() const
453 {
454     FormWidgetText *fwt = static_cast<FormWidgetText *>(m_formData->fm);
455     return fwt->getTextFontSize();
456 }
457 
setFontSize(int fontSize)458 void FormFieldText::setFontSize(int fontSize)
459 {
460     FormWidgetText *fwt = static_cast<FormWidgetText *>(m_formData->fm);
461     fwt->setTextFontSize(fontSize);
462 }
463 
FormFieldChoice(DocumentData * doc,::Page * p,::FormWidgetChoice * w)464 FormFieldChoice::FormFieldChoice(DocumentData *doc, ::Page *p, ::FormWidgetChoice *w) : FormField(std::make_unique<FormFieldData>(doc, p, w)) { }
465 
~FormFieldChoice()466 FormFieldChoice::~FormFieldChoice() { }
467 
type() const468 FormFieldChoice::FormType FormFieldChoice::type() const
469 {
470     return FormField::FormChoice;
471 }
472 
choiceType() const473 FormFieldChoice::ChoiceType FormFieldChoice::choiceType() const
474 {
475     FormWidgetChoice *fwc = static_cast<FormWidgetChoice *>(m_formData->fm);
476     if (fwc->isCombo())
477         return FormFieldChoice::ComboBox;
478     return FormFieldChoice::ListBox;
479 }
480 
choices() const481 QStringList FormFieldChoice::choices() const
482 {
483     FormWidgetChoice *fwc = static_cast<FormWidgetChoice *>(m_formData->fm);
484     QStringList ret;
485     int num = fwc->getNumChoices();
486     ret.reserve(num);
487     for (int i = 0; i < num; ++i) {
488         ret.append(UnicodeParsedString(fwc->getChoice(i)));
489     }
490     return ret;
491 }
492 
choicesWithExportValues() const493 QVector<QPair<QString, QString>> FormFieldChoice::choicesWithExportValues() const
494 {
495     FormWidgetChoice *fwc = static_cast<FormWidgetChoice *>(m_formData->fm);
496     QVector<QPair<QString, QString>> ret;
497     const int num = fwc->getNumChoices();
498     ret.reserve(num);
499     for (int i = 0; i < num; ++i) {
500         const QString display = UnicodeParsedString(fwc->getChoice(i));
501         const GooString *exportValueG = fwc->getExportVal(i);
502         const QString exportValue = exportValueG ? UnicodeParsedString(exportValueG) : display;
503         ret.append({ display, exportValue });
504     }
505     return ret;
506 }
507 
isEditable() const508 bool FormFieldChoice::isEditable() const
509 {
510     FormWidgetChoice *fwc = static_cast<FormWidgetChoice *>(m_formData->fm);
511     return fwc->isCombo() ? fwc->hasEdit() : false;
512 }
513 
multiSelect() const514 bool FormFieldChoice::multiSelect() const
515 {
516     FormWidgetChoice *fwc = static_cast<FormWidgetChoice *>(m_formData->fm);
517     return !fwc->isCombo() ? fwc->isMultiSelect() : false;
518 }
519 
currentChoices() const520 QList<int> FormFieldChoice::currentChoices() const
521 {
522     FormWidgetChoice *fwc = static_cast<FormWidgetChoice *>(m_formData->fm);
523     int num = fwc->getNumChoices();
524     QList<int> choices;
525     for (int i = 0; i < num; ++i)
526         if (fwc->isSelected(i))
527             choices.append(i);
528     return choices;
529 }
530 
setCurrentChoices(const QList<int> & choice)531 void FormFieldChoice::setCurrentChoices(const QList<int> &choice)
532 {
533     FormWidgetChoice *fwc = static_cast<FormWidgetChoice *>(m_formData->fm);
534     fwc->deselectAll();
535     for (int i = 0; i < choice.count(); ++i)
536         fwc->select(choice.at(i));
537 }
538 
editChoice() const539 QString FormFieldChoice::editChoice() const
540 {
541     FormWidgetChoice *fwc = static_cast<FormWidgetChoice *>(m_formData->fm);
542 
543     if (fwc->isCombo() && fwc->hasEdit())
544         return UnicodeParsedString(fwc->getEditChoice());
545     else
546         return QString();
547 }
548 
setEditChoice(const QString & text)549 void FormFieldChoice::setEditChoice(const QString &text)
550 {
551     FormWidgetChoice *fwc = static_cast<FormWidgetChoice *>(m_formData->fm);
552 
553     if (fwc->isCombo() && fwc->hasEdit()) {
554         GooString *goo = QStringToUnicodeGooString(text);
555         fwc->setEditChoice(goo);
556         delete goo;
557     }
558 }
559 
textAlignment() const560 Qt::Alignment FormFieldChoice::textAlignment() const
561 {
562     return formTextAlignment(m_formData->fm);
563 }
564 
canBeSpellChecked() const565 bool FormFieldChoice::canBeSpellChecked() const
566 {
567     FormWidgetChoice *fwc = static_cast<FormWidgetChoice *>(m_formData->fm);
568     return !fwc->noSpellCheck();
569 }
570 
571 class CertificateInfoPrivate
572 {
573 public:
574     struct EntityInfo
575     {
576         QString common_name;
577         QString email_address;
578         QString org_name;
579         QString distinguished_name;
580     };
581 
582     EntityInfo issuer_info;
583     EntityInfo subject_info;
584     QString nick_name;
585     QByteArray certificate_der;
586     QByteArray serial_number;
587     QByteArray public_key;
588     QDateTime validity_start;
589     QDateTime validity_end;
590     int public_key_type;
591     int public_key_strength;
592     int ku_extensions;
593     int version;
594     bool is_self_signed;
595     bool is_null;
596 };
597 
CertificateInfo()598 CertificateInfo::CertificateInfo() : d_ptr(new CertificateInfoPrivate())
599 {
600     d_ptr->is_null = true;
601 }
602 
CertificateInfo(CertificateInfoPrivate * priv)603 CertificateInfo::CertificateInfo(CertificateInfoPrivate *priv) : d_ptr(priv) { }
604 
CertificateInfo(const CertificateInfo & other)605 CertificateInfo::CertificateInfo(const CertificateInfo &other) : d_ptr(other.d_ptr) { }
606 
607 CertificateInfo::~CertificateInfo() = default;
608 
operator =(const CertificateInfo & other)609 CertificateInfo &CertificateInfo::operator=(const CertificateInfo &other)
610 {
611     if (this != &other)
612         d_ptr = other.d_ptr;
613 
614     return *this;
615 }
616 
isNull() const617 bool CertificateInfo::isNull() const
618 {
619     Q_D(const CertificateInfo);
620     return d->is_null;
621 }
622 
version() const623 int CertificateInfo::version() const
624 {
625     Q_D(const CertificateInfo);
626     return d->version;
627 }
628 
serialNumber() const629 QByteArray CertificateInfo::serialNumber() const
630 {
631     Q_D(const CertificateInfo);
632     return d->serial_number;
633 }
634 
issuerInfo(EntityInfoKey key) const635 QString CertificateInfo::issuerInfo(EntityInfoKey key) const
636 {
637     Q_D(const CertificateInfo);
638     switch (key) {
639     case CommonName:
640         return d->issuer_info.common_name;
641     case DistinguishedName:
642         return d->issuer_info.distinguished_name;
643     case EmailAddress:
644         return d->issuer_info.email_address;
645     case Organization:
646         return d->issuer_info.org_name;
647     default:
648         return QString();
649     }
650 }
651 
subjectInfo(EntityInfoKey key) const652 QString CertificateInfo::subjectInfo(EntityInfoKey key) const
653 {
654     Q_D(const CertificateInfo);
655     switch (key) {
656     case CommonName:
657         return d->subject_info.common_name;
658     case DistinguishedName:
659         return d->subject_info.distinguished_name;
660     case EmailAddress:
661         return d->subject_info.email_address;
662     case Organization:
663         return d->subject_info.org_name;
664     default:
665         return QString();
666     }
667 }
668 
nickName() const669 QString CertificateInfo::nickName() const
670 {
671     Q_D(const CertificateInfo);
672     return d->nick_name;
673 }
674 
validityStart() const675 QDateTime CertificateInfo::validityStart() const
676 {
677     Q_D(const CertificateInfo);
678     return d->validity_start;
679 }
680 
validityEnd() const681 QDateTime CertificateInfo::validityEnd() const
682 {
683     Q_D(const CertificateInfo);
684     return d->validity_end;
685 }
686 
keyUsageExtensions() const687 CertificateInfo::KeyUsageExtensions CertificateInfo::keyUsageExtensions() const
688 {
689     Q_D(const CertificateInfo);
690 
691     KeyUsageExtensions kuExtensions = KuNone;
692     if (d->ku_extensions & KU_DIGITAL_SIGNATURE)
693         kuExtensions |= KuDigitalSignature;
694     if (d->ku_extensions & KU_NON_REPUDIATION)
695         kuExtensions |= KuNonRepudiation;
696     if (d->ku_extensions & KU_KEY_ENCIPHERMENT)
697         kuExtensions |= KuKeyEncipherment;
698     if (d->ku_extensions & KU_DATA_ENCIPHERMENT)
699         kuExtensions |= KuDataEncipherment;
700     if (d->ku_extensions & KU_KEY_AGREEMENT)
701         kuExtensions |= KuKeyAgreement;
702     if (d->ku_extensions & KU_KEY_CERT_SIGN)
703         kuExtensions |= KuKeyCertSign;
704     if (d->ku_extensions & KU_CRL_SIGN)
705         kuExtensions |= KuClrSign;
706     if (d->ku_extensions & KU_ENCIPHER_ONLY)
707         kuExtensions |= KuEncipherOnly;
708 
709     return kuExtensions;
710 }
711 
publicKey() const712 QByteArray CertificateInfo::publicKey() const
713 {
714     Q_D(const CertificateInfo);
715     return d->public_key;
716 }
717 
publicKeyType() const718 CertificateInfo::PublicKeyType CertificateInfo::publicKeyType() const
719 {
720     Q_D(const CertificateInfo);
721     switch (d->public_key_type) {
722     case RSAKEY:
723         return RsaKey;
724     case DSAKEY:
725         return DsaKey;
726     case ECKEY:
727         return EcKey;
728     default:
729         return OtherKey;
730     }
731 }
732 
publicKeyStrength() const733 int CertificateInfo::publicKeyStrength() const
734 {
735     Q_D(const CertificateInfo);
736     return d->public_key_strength;
737 }
738 
isSelfSigned() const739 bool CertificateInfo::isSelfSigned() const
740 {
741     Q_D(const CertificateInfo);
742     return d->is_self_signed;
743 }
744 
certificateData() const745 QByteArray CertificateInfo::certificateData() const
746 {
747     Q_D(const CertificateInfo);
748     return d->certificate_der;
749 }
750 
checkPassword(const QString & password) const751 bool CertificateInfo::checkPassword(const QString &password) const
752 {
753 #ifdef ENABLE_NSS3
754     Q_D(const CertificateInfo);
755     SignatureHandler sigHandler(d->nick_name.toUtf8().constData(), SEC_OID_SHA256);
756     unsigned char buffer[5];
757     memcpy(buffer, "test", 5);
758     sigHandler.updateHash(buffer, 5);
759     std::unique_ptr<GooString> tmpSignature = sigHandler.signDetached(password.toUtf8().constData());
760     return tmpSignature.get() != nullptr;
761 #else
762     return false;
763 #endif
764 }
765 
766 class SignatureValidationInfoPrivate
767 {
768 public:
SignatureValidationInfoPrivate(CertificateInfo && ci)769     explicit SignatureValidationInfoPrivate(CertificateInfo &&ci) : cert_info(ci) { }
770 
771     SignatureValidationInfo::SignatureStatus signature_status;
772     SignatureValidationInfo::CertificateStatus certificate_status;
773     CertificateInfo cert_info;
774 
775     QByteArray signature;
776     QString signer_name;
777     QString signer_subject_dn;
778     QString location;
779     QString reason;
780     int hash_algorithm;
781     time_t signing_time;
782     QList<qint64> range_bounds;
783     qint64 docLength;
784 };
785 
SignatureValidationInfo(SignatureValidationInfoPrivate * priv)786 SignatureValidationInfo::SignatureValidationInfo(SignatureValidationInfoPrivate *priv) : d_ptr(priv) { }
787 
SignatureValidationInfo(const SignatureValidationInfo & other)788 SignatureValidationInfo::SignatureValidationInfo(const SignatureValidationInfo &other) : d_ptr(other.d_ptr) { }
789 
~SignatureValidationInfo()790 SignatureValidationInfo::~SignatureValidationInfo() { }
791 
signatureStatus() const792 SignatureValidationInfo::SignatureStatus SignatureValidationInfo::signatureStatus() const
793 {
794     Q_D(const SignatureValidationInfo);
795     return d->signature_status;
796 }
797 
certificateStatus() const798 SignatureValidationInfo::CertificateStatus SignatureValidationInfo::certificateStatus() const
799 {
800     Q_D(const SignatureValidationInfo);
801     return d->certificate_status;
802 }
803 
signerName() const804 QString SignatureValidationInfo::signerName() const
805 {
806     Q_D(const SignatureValidationInfo);
807     return d->signer_name;
808 }
809 
signerSubjectDN() const810 QString SignatureValidationInfo::signerSubjectDN() const
811 {
812     Q_D(const SignatureValidationInfo);
813     return d->signer_subject_dn;
814 }
815 
location() const816 QString SignatureValidationInfo::location() const
817 {
818     Q_D(const SignatureValidationInfo);
819     return d->location;
820 }
821 
reason() const822 QString SignatureValidationInfo::reason() const
823 {
824     Q_D(const SignatureValidationInfo);
825     return d->reason;
826 }
827 
hashAlgorithm() const828 SignatureValidationInfo::HashAlgorithm SignatureValidationInfo::hashAlgorithm() const
829 {
830 #ifdef ENABLE_NSS3
831     Q_D(const SignatureValidationInfo);
832 
833     switch (d->hash_algorithm) {
834     case HASH_AlgMD2:
835         return HashAlgorithmMd2;
836     case HASH_AlgMD5:
837         return HashAlgorithmMd5;
838     case HASH_AlgSHA1:
839         return HashAlgorithmSha1;
840     case HASH_AlgSHA256:
841         return HashAlgorithmSha256;
842     case HASH_AlgSHA384:
843         return HashAlgorithmSha384;
844     case HASH_AlgSHA512:
845         return HashAlgorithmSha512;
846     case HASH_AlgSHA224:
847         return HashAlgorithmSha224;
848     }
849 #endif
850     return HashAlgorithmUnknown;
851 }
852 
signingTime() const853 time_t SignatureValidationInfo::signingTime() const
854 {
855     Q_D(const SignatureValidationInfo);
856     return d->signing_time;
857 }
858 
signature() const859 QByteArray SignatureValidationInfo::signature() const
860 {
861     Q_D(const SignatureValidationInfo);
862     return d->signature;
863 }
864 
signedRangeBounds() const865 QList<qint64> SignatureValidationInfo::signedRangeBounds() const
866 {
867     Q_D(const SignatureValidationInfo);
868     return d->range_bounds;
869 }
870 
signsTotalDocument() const871 bool SignatureValidationInfo::signsTotalDocument() const
872 {
873     Q_D(const SignatureValidationInfo);
874     if (d->range_bounds.size() == 4 && d->range_bounds.value(0) == 0 && d->range_bounds.value(1) >= 0 && d->range_bounds.value(2) > d->range_bounds.value(1) && d->range_bounds.value(3) >= d->range_bounds.value(2)) {
875         // The range from d->range_bounds.value(1) to d->range_bounds.value(2) is
876         // not authenticated by the signature and should only contain the signature
877         // itself padded with 0 bytes. This has been checked in readSignature().
878         // If it failed, d->signature is empty.
879         // A potential range after d->range_bounds.value(3) would be also not
880         // authenticated. Therefore d->range_bounds.value(3) should coincide with
881         // the end of the document.
882         if (d->docLength == d->range_bounds.value(3) && !d->signature.isEmpty())
883             return true;
884     }
885     return false;
886 }
887 
certificateInfo() const888 CertificateInfo SignatureValidationInfo::certificateInfo() const
889 {
890     Q_D(const SignatureValidationInfo);
891     return d->cert_info;
892 }
893 
operator =(const SignatureValidationInfo & other)894 SignatureValidationInfo &SignatureValidationInfo::operator=(const SignatureValidationInfo &other)
895 {
896     if (this != &other)
897         d_ptr = other.d_ptr;
898 
899     return *this;
900 }
901 
FormFieldSignature(DocumentData * doc,::Page * p,::FormWidgetSignature * w)902 FormFieldSignature::FormFieldSignature(DocumentData *doc, ::Page *p, ::FormWidgetSignature *w) : FormField(std::make_unique<FormFieldData>(doc, p, w)) { }
903 
~FormFieldSignature()904 FormFieldSignature::~FormFieldSignature() { }
905 
type() const906 FormField::FormType FormFieldSignature::type() const
907 {
908     return FormField::FormSignature;
909 }
910 
signatureType() const911 FormFieldSignature::SignatureType FormFieldSignature::signatureType() const
912 {
913     SignatureType sigType = AdbePkcs7detached;
914     FormWidgetSignature *fws = static_cast<FormWidgetSignature *>(m_formData->fm);
915     switch (fws->signatureType()) {
916     case adbe_pkcs7_sha1:
917         sigType = AdbePkcs7sha1;
918         break;
919     case adbe_pkcs7_detached:
920         sigType = AdbePkcs7detached;
921         break;
922     case ETSI_CAdES_detached:
923         sigType = EtsiCAdESdetached;
924         break;
925     case unknown_signature_type:
926         sigType = UnknownSignatureType;
927         break;
928     }
929     return sigType;
930 }
931 
validate(ValidateOptions opt) const932 SignatureValidationInfo FormFieldSignature::validate(ValidateOptions opt) const
933 {
934     return validate(opt, QDateTime());
935 }
936 
createCertificateInfoPrivate(const X509CertificateInfo * ci)937 static CertificateInfoPrivate *createCertificateInfoPrivate(const X509CertificateInfo *ci)
938 {
939     CertificateInfoPrivate *certPriv = new CertificateInfoPrivate;
940     certPriv->is_null = true;
941     if (ci) {
942         certPriv->version = ci->getVersion();
943         certPriv->ku_extensions = ci->getKeyUsageExtensions();
944 
945         const GooString &certSerial = ci->getSerialNumber();
946         certPriv->serial_number = QByteArray(certSerial.c_str(), certSerial.getLength());
947 
948         const X509CertificateInfo::EntityInfo &issuerInfo = ci->getIssuerInfo();
949         certPriv->issuer_info.common_name = issuerInfo.commonName.c_str();
950         certPriv->issuer_info.distinguished_name = issuerInfo.distinguishedName.c_str();
951         certPriv->issuer_info.email_address = issuerInfo.email.c_str();
952         certPriv->issuer_info.org_name = issuerInfo.organization.c_str();
953 
954         const X509CertificateInfo::EntityInfo &subjectInfo = ci->getSubjectInfo();
955         certPriv->subject_info.common_name = subjectInfo.commonName.c_str();
956         certPriv->subject_info.distinguished_name = subjectInfo.distinguishedName.c_str();
957         certPriv->subject_info.email_address = subjectInfo.email.c_str();
958         certPriv->subject_info.org_name = subjectInfo.organization.c_str();
959 
960         certPriv->nick_name = ci->getNickName().c_str();
961 
962         X509CertificateInfo::Validity certValidity = ci->getValidity();
963         certPriv->validity_start = QDateTime::fromSecsSinceEpoch(certValidity.notBefore, Qt::UTC);
964         certPriv->validity_end = QDateTime::fromSecsSinceEpoch(certValidity.notAfter, Qt::UTC);
965 
966         const X509CertificateInfo::PublicKeyInfo &pkInfo = ci->getPublicKeyInfo();
967         certPriv->public_key = QByteArray(pkInfo.publicKey.c_str(), pkInfo.publicKey.getLength());
968         certPriv->public_key_type = static_cast<int>(pkInfo.publicKeyType);
969         certPriv->public_key_strength = pkInfo.publicKeyStrength;
970 
971         const GooString &certDer = ci->getCertificateDER();
972         certPriv->certificate_der = QByteArray(certDer.c_str(), certDer.getLength());
973 
974         certPriv->is_null = false;
975     }
976 
977     return certPriv;
978 }
979 
validate(int opt,const QDateTime & validationTime) const980 SignatureValidationInfo FormFieldSignature::validate(int opt, const QDateTime &validationTime) const
981 {
982     FormWidgetSignature *fws = static_cast<FormWidgetSignature *>(m_formData->fm);
983     const time_t validationTimeT = validationTime.isValid() ? validationTime.toSecsSinceEpoch() : -1;
984     SignatureInfo *si = fws->validateSignature(opt & ValidateVerifyCertificate, opt & ValidateForceRevalidation, validationTimeT, !(opt & ValidateWithoutOCSPRevocationCheck), opt & ValidateUseAIACertFetch);
985 
986     // get certificate info
987     const X509CertificateInfo *ci = si->getCertificateInfo();
988     CertificateInfoPrivate *certPriv = createCertificateInfoPrivate(ci);
989 
990     SignatureValidationInfoPrivate *priv = new SignatureValidationInfoPrivate(CertificateInfo(certPriv));
991     switch (si->getSignatureValStatus()) {
992     case SIGNATURE_VALID:
993         priv->signature_status = SignatureValidationInfo::SignatureValid;
994         break;
995     case SIGNATURE_INVALID:
996         priv->signature_status = SignatureValidationInfo::SignatureInvalid;
997         break;
998     case SIGNATURE_DIGEST_MISMATCH:
999         priv->signature_status = SignatureValidationInfo::SignatureDigestMismatch;
1000         break;
1001     case SIGNATURE_DECODING_ERROR:
1002         priv->signature_status = SignatureValidationInfo::SignatureDecodingError;
1003         break;
1004     default:
1005     case SIGNATURE_GENERIC_ERROR:
1006         priv->signature_status = SignatureValidationInfo::SignatureGenericError;
1007         break;
1008     case SIGNATURE_NOT_FOUND:
1009         priv->signature_status = SignatureValidationInfo::SignatureNotFound;
1010         break;
1011     case SIGNATURE_NOT_VERIFIED:
1012         priv->signature_status = SignatureValidationInfo::SignatureNotVerified;
1013         break;
1014     }
1015     switch (si->getCertificateValStatus()) {
1016     case CERTIFICATE_TRUSTED:
1017         priv->certificate_status = SignatureValidationInfo::CertificateTrusted;
1018         break;
1019     case CERTIFICATE_UNTRUSTED_ISSUER:
1020         priv->certificate_status = SignatureValidationInfo::CertificateUntrustedIssuer;
1021         break;
1022     case CERTIFICATE_UNKNOWN_ISSUER:
1023         priv->certificate_status = SignatureValidationInfo::CertificateUnknownIssuer;
1024         break;
1025     case CERTIFICATE_REVOKED:
1026         priv->certificate_status = SignatureValidationInfo::CertificateRevoked;
1027         break;
1028     case CERTIFICATE_EXPIRED:
1029         priv->certificate_status = SignatureValidationInfo::CertificateExpired;
1030         break;
1031     default:
1032     case CERTIFICATE_GENERIC_ERROR:
1033         priv->certificate_status = SignatureValidationInfo::CertificateGenericError;
1034         break;
1035     case CERTIFICATE_NOT_VERIFIED:
1036         priv->certificate_status = SignatureValidationInfo::CertificateNotVerified;
1037         break;
1038     }
1039     priv->signer_name = si->getSignerName();
1040     priv->signer_subject_dn = si->getSubjectDN();
1041     priv->hash_algorithm = si->getHashAlgorithm();
1042     priv->location = UnicodeParsedString(si->getLocation().toStr());
1043     priv->reason = UnicodeParsedString(si->getReason().toStr());
1044 
1045     priv->signing_time = si->getSigningTime();
1046     const std::vector<Goffset> ranges = fws->getSignedRangeBounds();
1047     if (!ranges.empty()) {
1048         for (Goffset bound : ranges) {
1049             priv->range_bounds.append(bound);
1050         }
1051     }
1052     GooString *checkedSignature = fws->getCheckedSignature(&priv->docLength);
1053     if (priv->range_bounds.size() == 4 && checkedSignature) {
1054         priv->signature = QByteArray::fromHex(checkedSignature->c_str());
1055     }
1056     delete checkedSignature;
1057 
1058     return SignatureValidationInfo(priv);
1059 }
1060 
hasNSSSupport()1061 bool hasNSSSupport()
1062 {
1063 #ifdef ENABLE_NSS3
1064     return true;
1065 #else
1066     return false;
1067 #endif
1068 }
1069 
getAvailableSigningCertificates()1070 QVector<CertificateInfo> getAvailableSigningCertificates()
1071 {
1072     QVector<CertificateInfo> vReturnCerts;
1073 
1074 #ifdef ENABLE_NSS3
1075     std::vector<std::unique_ptr<X509CertificateInfo>> vCerts = SignatureHandler::getAvailableSigningCertificates();
1076 
1077     for (auto &cert : vCerts) {
1078         CertificateInfoPrivate *certPriv = createCertificateInfoPrivate(cert.get());
1079         vReturnCerts.append(CertificateInfo(certPriv));
1080     }
1081 #endif
1082 
1083     return vReturnCerts;
1084 }
1085 
getNSSDir()1086 QString POPPLER_QT5_EXPORT getNSSDir()
1087 {
1088 #ifdef ENABLE_NSS3
1089     return QString::fromLocal8Bit(SignatureHandler::getNSSDir().c_str());
1090 #else
1091     return QString();
1092 #endif
1093 }
1094 
setNSSDir(const QString & path)1095 void setNSSDir(const QString &path)
1096 {
1097 #ifdef ENABLE_NSS3
1098     if (path.isEmpty())
1099         return;
1100 
1101     GooString *goo = QStringToGooString(path);
1102     SignatureHandler::setNSSDir(*goo);
1103     delete goo;
1104 #else
1105     (void)path;
1106 #endif
1107 }
1108 
1109 namespace {
1110 std::function<QString(const QString &)> nssPasswordCall;
1111 }
1112 
setNSSPasswordCallback(const std::function<char * (const char *)> & f)1113 void setNSSPasswordCallback(const std::function<char *(const char *)> &f)
1114 {
1115 #ifdef ENABLE_NSS3
1116     SignatureHandler::setNSSPasswordCallback(f);
1117 #else
1118     qWarning() << "setNSSPasswordCallback called but this poppler is built without NSS support";
1119     (void)f;
1120 #endif
1121 }
1122 
1123 }
1124