Add poppler NSS support

Move certificate config down into generator code
Read available signing certificates from poppler NSS
remotes/origin/work/aacid/dont_show_non_valid_certs
Thorsten Behrens 6 years ago committed by Albert Astals Cid
parent ae2c6a55c2
commit f7d6045b92
  1. 3
      CMakeLists.txt
  2. 4
      conf/okular.kcfg
  3. 5
      core/document.cpp
  4. 14
      core/document.h
  5. 3
      generators/poppler/CMakeLists.txt
  6. 189
      generators/poppler/certificatetools.cpp
  7. 37
      generators/poppler/certificatetools.h
  8. 12
      generators/poppler/conf/certsettings.kcfg
  9. 4
      generators/poppler/conf/certsettings.kcfgc
  10. 0
      generators/poppler/conf/certsettingswidget.ui
  11. 48
      generators/poppler/generator_pdf.cpp
  12. 1
      generators/poppler/generator_pdf.h
  13. 90
      part/certificatetools.cpp
  14. 34
      part/dlgsignatures.cpp
  15. 29
      part/dlgsignatures.h
  16. 33
      part/pageviewannotator.cpp
  17. 8
      part/preferencesdialog.cpp

@ -360,8 +360,6 @@ if(BUILD_DESKTOP)
part/dlgannotations.cpp
part/dlgperformance.cpp
part/dlgpresentation.cpp
part/dlgsignatures.cpp
part/certificatetools.cpp
part/editannottooldialog.cpp
part/editdrawingtooldialog.cpp
part/widgetannottools.cpp
@ -433,7 +431,6 @@ ki18n_wrap_ui(okularpart_SRCS
part/dlgannotationsbase.ui
part/dlgperformancebase.ui
part/dlgpresentationbase.ui
part/dlgsignaturesbase.ui
)
kconfig_add_kcfg_files(okularpart_SRCS GENERATE_MOC conf/settings.kcfgc)

@ -398,8 +398,4 @@
<default code="true">userString</default>
</entry>
</group>
<group name="Signatures" >
<entry key="Certificates" type="StringList">
</entry>
</group>
</kcfg>

@ -2734,6 +2734,11 @@ void Document::sign( const Okular::Annotation* pWhichAnnotation )
}
}
Okular::CertificateStore* Document::getCertStore()
{
return d->m_generator ? d->m_generator->getCertStore() : nullptr;
}
DocumentInfo Document::documentInfo() const
{
QSet<DocumentInfo::Key> keys;

@ -38,6 +38,7 @@ namespace Okular
{
class Annotation;
class BookmarkManager;
class CertificateStore;
class DocumentInfoPrivate;
class DocumentObserver;
class DocumentPrivate;
@ -1057,8 +1058,21 @@ public Q_SLOTS:
*/
void reloadDocument() const;
/**
* Digitally sign document, as the passed annotation's place
*
* @since 1.9
*/
void sign( const Okular::Annotation* pWhichAnnotation );
/**
* Returns the generator's certificate store (if any)
*
* @since 1.9
*/
CertificateStore* getCertStore();
/**
* Returns the part of document covered by the given signature @p info.
*

@ -38,14 +38,17 @@ set(okularGenerator_poppler_PART_SRCS
generator_pdf.cpp
formfields.cpp
annots.cpp
certificatetools.cpp
pdfsignatureutils.cpp
)
ki18n_wrap_ui(okularGenerator_poppler_PART_SRCS
conf/pdfsettingswidget.ui
conf/certsettingswidget.ui
)
kconfig_add_kcfg_files(okularGenerator_poppler_PART_SRCS conf/pdfsettings.kcfgc )
kconfig_add_kcfg_files(okularGenerator_poppler_PART_SRCS conf/certsettings.kcfgc )
okular_add_generator(okularGenerator_poppler ${okularGenerator_poppler_PART_SRCS})

@ -0,0 +1,189 @@
/***************************************************************************
* Copyright (C) 2019 by Bubli *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#include "certificatetools.h"
#include <iostream>
#include <klocalizedstring.h>
#include "certsettings.h"
#include <poppler-form.h>
#include <QInputDialog>
#include <QListWidget>
#include <QListWidgetItem>
#include <QIcon>
#include <QHBoxLayout>
#include <QDialogButtonBox>
#include <QPushButton>
#include <QVBoxLayout>
#include <QJsonDocument>
#include <QJsonObject>
CertificateTools::CertificateTools( QWidget * parent )
: QWidget( parent )
{
QHBoxLayout *hBoxLayout = new QHBoxLayout( this );
m_list = new QListWidget( this );
m_list->setIconSize( QSize( 32, 32 ) );
hBoxLayout->addWidget( m_list );
QVBoxLayout *vBoxLayout = new QVBoxLayout();
m_btnAdd = new QPushButton( i18n("&Add..."), this );
m_btnAdd->setIcon( QIcon::fromTheme(QStringLiteral("list-add")) );
vBoxLayout->addWidget( m_btnAdd );
m_btnEdit = new QPushButton( i18n("&Edit..."), this );
m_btnEdit->setIcon( QIcon::fromTheme(QStringLiteral("edit-rename")) );
m_btnEdit->setEnabled( false );
vBoxLayout->addWidget( m_btnEdit );
m_btnRemove = new QPushButton( i18n("&Remove"), this );
m_btnRemove->setIcon( QIcon::fromTheme(QStringLiteral("list-remove")) );
m_btnRemove->setEnabled( false );
vBoxLayout->addWidget( m_btnRemove );
m_btnMoveUp = new QPushButton( i18n("Move &Up"), this );
m_btnMoveUp->setIcon( QIcon::fromTheme(QStringLiteral("arrow-up")) );
m_btnMoveUp->setEnabled( false );
vBoxLayout->addWidget( m_btnMoveUp );
m_btnMoveDown = new QPushButton( i18n("Move &Down"), this );
m_btnMoveDown->setIcon( QIcon::fromTheme(QStringLiteral("arrow-down")) );
m_btnMoveDown->setEnabled( false );
vBoxLayout->addWidget( m_btnMoveDown );
vBoxLayout->addStretch();
hBoxLayout->addLayout( vBoxLayout );
connect(m_list, &QListWidget::itemDoubleClicked, this, &CertificateTools::slotEdit);
connect(m_list, &QListWidget::currentRowChanged, this, &CertificateTools::updateButtons);
connect(m_btnAdd, &QPushButton::clicked, this, &CertificateTools::slotAdd);
connect(m_btnEdit, &QPushButton::clicked, this, &CertificateTools::slotEdit);
connect(m_btnRemove, &QPushButton::clicked, this, &CertificateTools::slotRemove);
connect(m_btnMoveUp, &QPushButton::clicked, this, &CertificateTools::slotMoveUp);
connect(m_btnMoveDown, &QPushButton::clicked, this, &CertificateTools::slotMoveDown);
}
CertificateTools::~CertificateTools()
{
}
QStringList CertificateTools::certificates() const
{
QStringList res;
const int count = m_list->count();
for ( int i = 0; i < count; ++i )
{
QListWidgetItem * listEntry = m_list->item(i);
res << listEntry->data(Qt::UserRole).toString();
}
return res;
}
void CertificateTools::setCertificates(const QStringList& /*items*/)
{
m_list->clear();
/* TODO: custom list of certs, perhaps from files? also permit ordering...
QStringList certs = CertificateSettings::certificates();
foreach( const QString cert, certs )
{
QListWidgetItem * listEntry = new QListWidgetItem( cert, m_list );
(void)listEntry;
}
*/
QVector<Poppler::CertificateInfo*> nssCerts = Poppler::getAvailableSigningCertificates();
foreach( auto cert, nssCerts )
{
QListWidgetItem * listEntry = new QListWidgetItem(
cert->subjectInfo(
Poppler::CertificateInfo::EntityInfoKey::CommonName ) + "\t(" +
cert->validityEnd().toString("yyyy-MM-dd") + ")",
m_list );
QJsonObject json;
json["CommonName"] = cert->subjectInfo( Poppler::CertificateInfo::EntityInfoKey::CommonName );
json["SerialNumber"] = QString::fromStdString(cert->serialNumber().toStdString());
json["ValidUntil"] = cert->validityEnd().toString();
listEntry->setData( Qt::UserRole, QJsonDocument(json).toJson() );
}
updateButtons();
}
void CertificateTools::slotAdd()
{
QString certCN = QInputDialog::getText( this, i18n("Enter Certificate CN"), i18n("CertificateCN"), QLineEdit::Normal, QString() );
if (certCN.isEmpty())
return;
// Create list entry
QListWidgetItem * listEntry = new QListWidgetItem( certCN, m_list );
// Select and scroll
m_list->setCurrentItem( listEntry );
m_list->scrollToItem( listEntry );
updateButtons();
emit changed();
}
void CertificateTools::slotEdit()
{
QListWidgetItem *listEntry = m_list->currentItem();
bool ok;
QString certCN = QInputDialog::getText( this, i18n("Change Certificate CN"), i18n("CertificateCN"), QLineEdit::Normal, listEntry->text(), &ok );
if( ok )
{
listEntry->setText(certCN);
// Select and scrolldd
m_list->setCurrentItem( listEntry );
m_list->scrollToItem( listEntry );
updateButtons();
emit changed();
}
}
void CertificateTools::updateButtons()
{
const int row = m_list->currentRow();
const int last = m_list->count() - 1;
m_btnEdit->setEnabled( row != -1 );
m_btnRemove->setEnabled( row != -1 );
m_btnMoveUp->setEnabled( row > 0 );
m_btnMoveDown->setEnabled( row != -1 && row != last );
}
void CertificateTools::slotRemove()
{
const int row = m_list->currentRow();
delete m_list->takeItem(row);
updateButtons();
emit changed();
}
void CertificateTools::slotMoveUp()
{
const int row = m_list->currentRow();
m_list->insertItem( row, m_list->takeItem(row-1) );
m_list->scrollToItem( m_list->currentItem() );
updateButtons();
emit changed();
}
void CertificateTools::slotMoveDown()
{
const int row = m_list->currentRow();
m_list->insertItem( row, m_list->takeItem(row+1) );
m_list->scrollToItem( m_list->currentItem() );
updateButtons();
emit changed();
}

@ -10,23 +10,42 @@
#ifndef _CERTIFICATETOOLS_H_
#define _CERTIFICATETOOLS_H_
#include "widgetconfigurationtoolsbase.h"
#include <QWidget>
class QListWidget;
class QPushButton;
#include <qwidget.h>
class CertificateTools : public WidgetConfigurationToolsBase
class CertificateTools : public QWidget
{
Q_OBJECT
Q_PROPERTY( QStringList certificates READ certificates WRITE setCertificates NOTIFY changed USER true )
public:
explicit CertificateTools( QWidget * parent = nullptr );
~CertificateTools() {};
~CertificateTools() override;
QStringList certificates() const;
void setCertificates(const QStringList& items);
Q_SIGNALS:
void changed();
QStringList tools() const override;
void setTools(const QStringList& items) override;
protected:
QListWidget *m_list;
private:
QPushButton *m_btnAdd;
QPushButton *m_btnEdit;
QPushButton *m_btnRemove;
QPushButton *m_btnMoveUp;
QPushButton *m_btnMoveDown;
protected Q_SLOTS:
void slotAdd() override;
void slotEdit() override;
void slotAdd();
void slotEdit();
void updateButtons();
void slotRemove();
void slotMoveUp();
void slotMoveDown();
};
#endif

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
<kcfgfile name="okular-generator-popplercertsrc"/>
<group name="Signatures" >
<entry key="Certificates" type="StringList">
</entry>
</group>
</kcfg>
<!-- vim:set ts=4 -->

@ -0,0 +1,4 @@
File=certsettings.kcfg
ClassName=CertificateSettings
Mutators=true
Singleton=true

@ -36,6 +36,7 @@
#include <KAboutData>
#include <KConfigDialog>
#include <KConfigDialogManager>
#include <KLocalizedString>
#include <KMessageBox>
@ -49,10 +50,17 @@
#include <core/sourcereference.h>
#include <core/textpage.h>
#include <core/utils.h>
#include <core/signatureutils.h>
#include "pdfsettings.h"
#include "ui_pdfsettingswidget.h"
#include "certificatetools.h"
#include "ui_certsettingswidget.h"
#include "certsettings.h"
#include <config-okular-poppler.h>
#include <poppler-media.h>
#include <poppler-version.h>
@ -60,6 +68,7 @@
#include "debug_pdf.h"
#include "formfields.h"
#include "popplerembeddedfile.h"
#include "pdfsignatureutils.h"
Q_DECLARE_METATYPE(Poppler::Annotation *)
Q_DECLARE_METATYPE(Poppler::FontInfo)
@ -544,6 +553,7 @@ PDFGenerator::PDFGenerator(QObject *parent, const QVariantList &args)
, docEmbeddedFilesDirty(true)
, nextFontPage(0)
, annotProxy(nullptr)
, certStore( nullptr )
{
setFeature(Threaded);
setFeature(TextExtraction);
@ -1468,6 +1478,17 @@ void PDFGenerator::addPages(KConfigDialog *dlg)
QWidget *w = new QWidget(dlg);
pdfsw.setupUi(w);
dlg->addPage(w, PDFSettings::self(), i18n("PDF"), QStringLiteral("application-pdf"), i18n("PDF Backend Configuration"));
Ui_DlgSignaturesBase certsw;
QWidget* w2 = new QWidget(dlg);
certsw.setupUi(w2);
CertificateTools * kcfg_CertTools = new CertificateTools( certsw.certificatesGroup );
certsw.certificatesPlaceholder->addWidget( kcfg_CertTools );
kcfg_CertTools->setObjectName( QStringLiteral("kcfg_Certificates") );
KConfigDialogManager::changedMap()->insert( QStringLiteral("CertificateTools"), SIGNAL(changed()) );
dlg->addPage(w2, CertificateSettings::self(), i18n("Certificates"), QStringLiteral("application-pkcs7-signature"), i18n("Digital Signature Certificates") );
}
bool PDFGenerator::setDocumentRenderHints()
@ -1885,6 +1906,33 @@ bool PDFGenerator::sign( const Okular::Annotation* pWhichAnnotation, const QStri
return true;
}
namespace {
struct CertificateStoreImpl : public Okular::CertificateStore
{
virtual QList<Okular::CertificateInfo*> getSigningCertificates() const
{
QVector<Poppler::CertificateInfo*> certs = Poppler::getAvailableSigningCertificates();
QList<Okular::CertificateInfo*> vReturnCerts;
for (auto cert : certs)
vReturnCerts.append(new PopplerCertificateInfo(*cert));
return vReturnCerts;
}
};
}
Okular::CertificateStore* PDFGenerator::getCertStore()
{
#ifdef HAVE_POPPLER_SIGNING
if( !certStore )
certStore = new CertificateStoreImpl();
return certStore;
#else
return nullptr;
#endif
}
#include "generator_pdf.moc"
Q_LOGGING_CATEGORY(OkularPdfDebug, "org.kde.okular.generators.pdf", QtWarningMsg)

@ -143,6 +143,7 @@ private:
mutable QList<Okular::EmbeddedFile *> docEmbeddedFiles;
int nextFontPage;
PopplerAnnotationProxy *annotProxy;
Okular::CertificateStore* certStore;
// the hash below only contains annotations that were present on the file at open time
// this is enough for what we use it for
QHash<Okular::Annotation *, Poppler::Annotation *> annotationsOnOpenHash;

@ -1,90 +0,0 @@
/***************************************************************************
* Copyright (C) 2019 by Bubli *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#include "certificatetools.h"
#include <iostream>
#include <klocalizedstring.h>
#include "settings.h"
#include <QInputDialog>
#include <QListWidget>
#include <QListWidgetItem>
CertificateTools::CertificateTools( QWidget * parent )
: WidgetConfigurationToolsBase( parent )
{
}
QStringList CertificateTools::tools() const
{
QStringList res;
const int count = m_list->count();
for ( int i = 0; i < count; ++i )
{
QListWidgetItem * listEntry = m_list->item(i);
res << listEntry->text();
}
return res;
}
void CertificateTools::setTools(const QStringList& /*items*/)
{
m_list->clear();
QStringList certs = Okular::Settings::certificates();
foreach( const QString cert, certs )
{
QListWidgetItem * listEntry = new QListWidgetItem( cert, m_list );
(void)listEntry;
}
//QVector<Poppler::CertificateInfo*> nssCerts = Poppler::getAvailableSigningCertificates();
Poppler::getAvailableSigningCertificates();
foreach( auto cert, nssCerts )
{
QListWidgetItem * listEntry = new QListWidgetItem( cert->getSubjectInfo().commonName,
m_list );
(void)listEntry;
}
updateButtons();
}
void CertificateTools::slotAdd()
{
QString certCN = QInputDialog::getText( this, i18n("Enter Certificate CN"), i18n("CertificateCN"), QLineEdit::Normal, QString() );
if (certCN.isEmpty())
return;
// Create list entry
QListWidgetItem * listEntry = new QListWidgetItem( certCN, m_list );
// Select and scroll
m_list->setCurrentItem( listEntry );
m_list->scrollToItem( listEntry );
updateButtons();
emit changed();
}
void CertificateTools::slotEdit()
{
QListWidgetItem *listEntry = m_list->currentItem();
QString certCN = QInputDialog::getText( this, i18n("Change Certificate CN"), i18n("CertificateCN"), QLineEdit::Normal, listEntry->text() );
listEntry->setText(certCN);
// Select and scrolldd
m_list->setCurrentItem( listEntry );
m_list->scrollToItem( listEntry );
updateButtons();
emit changed();
}

@ -1,34 +0,0 @@
/***************************************************************************
* Copyright (C) 2019 by Bubli *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#include "dlgsignatures.h"
#include "certificatetools.h"
#include "ui_dlgsignaturesbase.h"
#include <KConfigDialogManager>
DlgSignatures::DlgSignatures(QWidget *parent)
: QWidget(parent)
{
m_dlg = new Ui_DlgSignaturesBase();
m_dlg->setupUi(this);
CertificateTools * kcfg_CertTools = new CertificateTools( m_dlg->certificatesGroup );
m_dlg->certificatesPlaceholder->addWidget( kcfg_CertTools );
kcfg_CertTools->setObjectName( QStringLiteral("kcfg_Certificates") );
KConfigDialogManager::changedMap()->insert( QStringLiteral("CertificateTools"), SIGNAL(changed()) );
}
DlgSignatures::~DlgSignatures()
{
delete m_dlg;
}
#include "moc_dlgsignatures.cpp"

@ -1,29 +0,0 @@
/***************************************************************************
* Copyright (C) 2019 by Bubli *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#ifndef DLGSIGNATURES_H
#define DLGSIGNATURES_H
#include <qwidget.h>
class Ui_DlgSignaturesBase;
class DlgSignatures : public QWidget
{
Q_OBJECT
public:
explicit DlgSignatures(QWidget *parent = nullptr);
virtual ~DlgSignatures();
private:
Ui_DlgSignaturesBase *m_dlg;
};
#endif

@ -40,6 +40,7 @@
#include "core/area.h"
#include "core/document.h"
#include "core/page.h"
#include "core/signatureutils.h"
#include "debug_ui.h"
#include "editannottooldialog.h"
#include "guiutils.h"
@ -313,15 +314,15 @@ private:
class PickPointEngine2 : public PickPointEngine
{
public:
PickPointEngine2(const QDomElement &engineElement)
: PickPointEngine(engineElement)
{
clicked = false;
m_block = true;
xscale = 1.0;
yscale = 1.0;
}
public:
PickPointEngine2( const QDomElement & engineElement, Okular::Document* storage )
: PickPointEngine( engineElement ), m_document(storage)
{
clicked = false;
m_block = true;
xscale = 1.0;
yscale = 1.0;
}
QRect event(EventType type, Button button, Modifiers modifiers, double nX, double nY, double xScale, double yScale, const Okular::Page *page) override
{
@ -330,10 +331,15 @@ public:
QList<Okular::Annotation *> end() override
{
QStringList items = Okular::Settings::certificates();
Okular::Annotation * ann = nullptr;
Okular::CertificateStore* certStore = m_document->getCertStore();
QList<Okular::CertificateInfo*> certs = certStore->getSigningCertificates();
QStringList items;
for( auto cert : certs )
items.append(cert->subjectInfo( Okular::CertificateInfo::EntityInfoKey::CommonName ));
bool resok = false;
QString cert = QInputDialog::getItem(nullptr, i18n( "Select certificate to sign with" ), i18n( "Certificates:" ), items, 0, false, &resok);
@ -368,6 +374,9 @@ public:
return QList< Okular::Annotation* >() << ann;
}
private:
Okular::Document* m_document;
};
/** @short PolyLineEngine */
@ -885,7 +894,7 @@ QRect PageViewAnnotator::performRouteMouseOrTabletEvent(const AnnotatorEngine::E
QDomElement elem;
elem.setTagName("engine");
elem.setAttribute("block", 1);
m_engine = new PickPointEngine2(elem);
m_engine = new PickPointEngine2(elem, m_document);
}
// 1. lock engine to current item

@ -11,7 +11,6 @@
#include "preferencesdialog.h"
#include <KLocalizedString>
#include "../generators/poppler/config-okular-poppler.h"
// single config pages
#include "dlgaccessibility.h"
@ -21,7 +20,6 @@
#include "dlggeneral.h"
#include "dlgperformance.h"
#include "dlgpresentation.h"
#include "dlgsignatures.h"
PreferencesDialog::PreferencesDialog(QWidget *parent, KConfigSkeleton *skeleton, Okular::EmbedMode embedMode)
: KConfigDialog(parent, QStringLiteral("preferences"), skeleton)
@ -49,15 +47,9 @@ PreferencesDialog::PreferencesDialog(QWidget *parent, KConfigSkeleton *skeleton,
m_presentation = new DlgPresentation(this);
m_annotations = new DlgAnnotations(this);
m_editor = new DlgEditor(this);
#ifdef HAVE_POPPLER_SIGNING
m_signatures = new DlgSignatures(this);
#endif
addPage(m_presentation, i18n("Presentation"), QStringLiteral("view-presentation"), i18n("Options for Presentation Mode"));
m_annotationsPage = addPage(m_annotations, i18n("Annotations"), QStringLiteral("draw-freehand"), i18n("Annotation Options"));
addPage(m_editor, i18n("Editor"), QStringLiteral("accessories-text-editor"), i18n("Editor Options"));
#ifdef HAVE_POPPLER_SIGNING
addPage(m_signatures, i18n("Signatures"), QStringLiteral("application-pkcs7-signature"), i18n("Digital Signatures"));
#endif
}
#ifdef OKULAR_DEBUG_CONFIGPAGE
addPage(m_debug, "Debug", "system-run", "Debug options");

Loading…
Cancel
Save