Public key encryption: code refactoring

This commit is contained in:
Jakub Melka 2022-06-12 15:45:32 +02:00
parent 1c03bd85cd
commit c20959c190
16 changed files with 790 additions and 648 deletions

View File

@ -47,8 +47,11 @@ SOURCES += \
sources/pdfannotation.cpp \
sources/pdfblendfunction.cpp \
sources/pdfccittfaxdecoder.cpp \
sources/pdfcertificatemanager.cpp \
sources/pdfcertificatemanagerdialog.cpp \
sources/pdfcms.cpp \
sources/pdfcompiler.cpp \
sources/pdfcreatecertificatedialog.cpp \
sources/pdfdiff.cpp \
sources/pdfdocumentbuilder.cpp \
sources/pdfdocumentmanipulator.cpp \
@ -121,8 +124,11 @@ HEADERS += \
sources/pdfannotation.h \
sources/pdfblendfunction.h \
sources/pdfccittfaxdecoder.h \
sources/pdfcertificatemanager.h \
sources/pdfcertificatemanagerdialog.h \
sources/pdfcms.h \
sources/pdfcompiler.h \
sources/pdfcreatecertificatedialog.h \
sources/pdfdbgheap.h \
sources/pdfdiff.h \
sources/pdfdocumentbuilder.h \
@ -202,6 +208,8 @@ HEADERS += \
sources/pdfimage.h
FORMS += \
sources/pdfcertificatemanagerdialog.ui \
sources/pdfcreatecertificatedialog.ui \
sources/pdfpagecontenteditorstylesettings.ui \
sources/pdfpagecontenteditorwidget.ui \
sources/pdfrenderingerrorswidget.ui \

View File

@ -15,7 +15,7 @@
// You should have received a copy of the GNU Lesser General Public License
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "certificatemanager.h"
#include "pdfcertificatemanager.h"
#include <QDir>
#include <QFile>
@ -32,10 +32,10 @@
#include <memory>
namespace pdfplugin
namespace pdf
{
CertificateManager::CertificateManager()
PDFCertificateManager::PDFCertificateManager()
{
}
@ -43,7 +43,7 @@ CertificateManager::CertificateManager()
template<typename T>
using openssl_ptr = std::unique_ptr<T, void(*)(T*)>;
void CertificateManager::createCertificate(const NewCertificateInfo& info)
void PDFCertificateManager::createCertificate(const NewCertificateInfo& info)
{
openssl_ptr<BIO> pksBuffer(BIO_new(BIO_s_mem()), &BIO_free_all);
@ -132,19 +132,19 @@ void CertificateManager::createCertificate(const NewCertificateInfo& info)
}
}
QFileInfoList CertificateManager::getCertificates()
QFileInfoList PDFCertificateManager::getCertificates()
{
QDir directory(getCertificateDirectory());
return directory.entryInfoList(QStringList() << "*.pfx", QDir::Files | QDir::NoDotAndDotDot | QDir::Readable, QDir::Name);
}
QString CertificateManager::getCertificateDirectory()
QString PDFCertificateManager::getCertificateDirectory()
{
QDir directory(QStandardPaths::standardLocations(QStandardPaths::AppDataLocation).front() + "/certificates/");
return directory.absolutePath();
}
QString CertificateManager::generateCertificateFileName()
QString PDFCertificateManager::generateCertificateFileName()
{
QString directoryString = getCertificateDirectory();
QDir directory(directoryString);
@ -162,7 +162,7 @@ QString CertificateManager::generateCertificateFileName()
return QString();
}
bool CertificateManager::isCertificateValid(QString fileName, QString password)
bool PDFCertificateManager::isCertificateValid(QString fileName, QString password)
{
QFile file(fileName);
if (file.open(QFile::ReadOnly))
@ -190,7 +190,7 @@ bool CertificateManager::isCertificateValid(QString fileName, QString password)
return false;
}
bool SignatureFactory::sign(QString certificateName, QString password, QByteArray data, QByteArray& result)
bool PDFSignatureFactory::sign(QString certificateName, QString password, QByteArray data, QByteArray& result)
{
QFile file(certificateName);
if (file.open(QFile::ReadOnly))
@ -247,4 +247,4 @@ bool SignatureFactory::sign(QString certificateName, QString password, QByteArra
return false;
}
} // namespace pdfplugin
} // namespace pdf

View File

@ -15,19 +15,21 @@
// You should have received a copy of the GNU Lesser General Public License
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef CERTIFICATEMANAGER_H
#define CERTIFICATEMANAGER_H
#ifndef PDFCERTIFICATEMANAGER_H
#define PDFCERTIFICATEMANAGER_H
#include "pdfglobal.h"
#include <QString>
#include <QFileInfoList>
namespace pdfplugin
namespace pdf
{
class CertificateManager
class PDF4QTLIBSHARED_EXPORT PDFCertificateManager
{
public:
CertificateManager();
PDFCertificateManager();
struct NewCertificateInfo
{
@ -53,12 +55,12 @@ public:
static bool isCertificateValid(QString fileName, QString password);
};
class SignatureFactory
class PDF4QTLIBSHARED_EXPORT PDFSignatureFactory
{
public:
static bool sign(QString certificateName, QString password, QByteArray data, QByteArray& result);
};
} // namespace pdfplugin
} // namespace pdf
#endif // CERTIFICATEMANAGER_H
#endif // PDFCERTIFICATEMANAGER_H

View File

@ -15,9 +15,9 @@
// You should have received a copy of the GNU Lesser General Public License
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "certificatemanagerdialog.h"
#include "ui_certificatemanagerdialog.h"
#include "createcertificatedialog.h"
#include "pdfcertificatemanagerdialog.h"
#include "ui_pdfcertificatemanagerdialog.h"
#include "pdfcreatecertificatedialog.h"
#include "pdfwidgetutils.h"
@ -28,12 +28,12 @@
#include <QMessageBox>
#include <QFileDialog>
namespace pdfplugin
namespace pdf
{
CertificateManagerDialog::CertificateManagerDialog(QWidget *parent) :
PDFCertificateManagerDialog::PDFCertificateManagerDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::CertificateManagerDialog),
ui(new Ui::PDFCertificateManagerDialog),
m_newCertificateButton(nullptr),
m_openCertificateDirectoryButton(nullptr),
m_deleteCertificateButton(nullptr),
@ -42,10 +42,10 @@ CertificateManagerDialog::CertificateManagerDialog(QWidget *parent) :
{
ui->setupUi(this);
QDir::root().mkpath(CertificateManager::getCertificateDirectory());
QDir::root().mkpath(PDFCertificateManager::getCertificateDirectory());
m_certificateFileModel = new QFileSystemModel(this);
QModelIndex rootIndex = m_certificateFileModel->setRootPath(CertificateManager::getCertificateDirectory());
QModelIndex rootIndex = m_certificateFileModel->setRootPath(PDFCertificateManager::getCertificateDirectory());
ui->fileView->setModel(m_certificateFileModel);
ui->fileView->setRootIndex(rootIndex);
@ -54,35 +54,35 @@ CertificateManagerDialog::CertificateManagerDialog(QWidget *parent) :
m_deleteCertificateButton = ui->buttonBox->addButton(tr("Delete"), QDialogButtonBox::ActionRole);
m_importCertificateButton = ui->buttonBox->addButton(tr("Import"), QDialogButtonBox::ActionRole);
connect(m_newCertificateButton, &QPushButton::clicked, this, &CertificateManagerDialog::onNewCertificateClicked);
connect(m_openCertificateDirectoryButton, &QPushButton::clicked, this, &CertificateManagerDialog::onOpenCertificateDirectoryClicked);
connect(m_deleteCertificateButton, &QPushButton::clicked, this, &CertificateManagerDialog::onDeleteCertificateClicked);
connect(m_importCertificateButton, &QPushButton::clicked, this, &CertificateManagerDialog::onImportCertificateClicked);
connect(m_newCertificateButton, &QPushButton::clicked, this, &PDFCertificateManagerDialog::onNewCertificateClicked);
connect(m_openCertificateDirectoryButton, &QPushButton::clicked, this, &PDFCertificateManagerDialog::onOpenCertificateDirectoryClicked);
connect(m_deleteCertificateButton, &QPushButton::clicked, this, &PDFCertificateManagerDialog::onDeleteCertificateClicked);
connect(m_importCertificateButton, &QPushButton::clicked, this, &PDFCertificateManagerDialog::onImportCertificateClicked);
setMinimumSize(pdf::PDFWidgetUtils::scaleDPI(this, QSize(640, 480)));
}
CertificateManagerDialog::~CertificateManagerDialog()
PDFCertificateManagerDialog::~PDFCertificateManagerDialog()
{
delete ui;
}
void CertificateManagerDialog::onNewCertificateClicked()
void PDFCertificateManagerDialog::onNewCertificateClicked()
{
CreateCertificateDialog dialog(this);
if (dialog.exec() == CreateCertificateDialog::Accepted)
PDFCreateCertificateDialog dialog(this);
if (dialog.exec() == PDFCreateCertificateDialog::Accepted)
{
const CertificateManager::NewCertificateInfo info = dialog.getNewCertificateInfo();
const PDFCertificateManager::NewCertificateInfo info = dialog.getNewCertificateInfo();
m_certificateManager.createCertificate(info);
}
}
void CertificateManagerDialog::onOpenCertificateDirectoryClicked()
void PDFCertificateManagerDialog::onOpenCertificateDirectoryClicked()
{
QDesktopServices::openUrl(QString("file:///%1").arg(CertificateManager::getCertificateDirectory(), QUrl::TolerantMode));
QDesktopServices::openUrl(QString("file:///%1").arg(PDFCertificateManager::getCertificateDirectory(), QUrl::TolerantMode));
}
void CertificateManagerDialog::onDeleteCertificateClicked()
void PDFCertificateManagerDialog::onDeleteCertificateClicked()
{
QFileInfo fileInfo = m_certificateFileModel->fileInfo(ui->fileView->currentIndex());
if (fileInfo.exists())
@ -98,7 +98,7 @@ void CertificateManagerDialog::onDeleteCertificateClicked()
}
}
void CertificateManagerDialog::onImportCertificateClicked()
void PDFCertificateManagerDialog::onImportCertificateClicked()
{
QString selectedFile = QFileDialog::getOpenFileName(this, tr("Import Certificate"), QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), tr("Certificate file (*.pfx);;All files (*.*)"));
@ -110,7 +110,7 @@ void CertificateManagerDialog::onImportCertificateClicked()
QFile file(selectedFile);
if (file.exists())
{
QString path = CertificateManager::getCertificateDirectory();
QString path = PDFCertificateManager::getCertificateDirectory();
QString targetFile = QString("%1/%2").arg(path, QFileInfo(file).fileName());
if (QFile::exists(targetFile))
{
@ -130,4 +130,4 @@ void CertificateManagerDialog::onImportCertificateClicked()
}
}
} // namespace pdfplugin
} // namespace pdf

View File

@ -15,10 +15,10 @@
// You should have received a copy of the GNU Lesser General Public License
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef CERTIFICATEMANAGERDIALOG_H
#define CERTIFICATEMANAGERDIALOG_H
#ifndef PDFCERTIFICATEMANAGERDIALOG_H
#define PDFCERTIFICATEMANAGERDIALOG_H
#include "certificatemanager.h"
#include "pdfcertificatemanager.h"
#include <QDialog>
@ -27,19 +27,19 @@ class QFileSystemModel;
namespace Ui
{
class CertificateManagerDialog;
class PDFCertificateManagerDialog;
}
namespace pdfplugin
namespace pdf
{
class CertificateManagerDialog : public QDialog
class PDF4QTLIBSHARED_EXPORT PDFCertificateManagerDialog : public QDialog
{
Q_OBJECT
public:
explicit CertificateManagerDialog(QWidget* parent);
virtual ~CertificateManagerDialog() override;
explicit PDFCertificateManagerDialog(QWidget* parent);
virtual ~PDFCertificateManagerDialog() override;
private:
void onNewCertificateClicked();
@ -47,8 +47,8 @@ private:
void onDeleteCertificateClicked();
void onImportCertificateClicked();
Ui::CertificateManagerDialog* ui;
CertificateManager m_certificateManager;
Ui::PDFCertificateManagerDialog* ui;
PDFCertificateManager m_certificateManager;
QPushButton* m_newCertificateButton;
QPushButton* m_openCertificateDirectoryButton;
QPushButton* m_deleteCertificateButton;
@ -56,6 +56,6 @@ private:
QFileSystemModel* m_certificateFileModel;
};
} // namespace pdfplugin
} // namespace pdf
#endif // CERTIFICATEMANAGERDIALOG_H
#endif // PDFCERTIFICATEMANAGERDIALOG_H

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CertificateManagerDialog</class>
<widget class="QDialog" name="CertificateManagerDialog">
<class>PDFCertificateManagerDialog</class>
<widget class="QDialog" name="PDFCertificateManagerDialog">
<property name="geometry">
<rect>
<x>0</x>
@ -43,7 +43,7 @@
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>CertificateManagerDialog</receiver>
<receiver>PDFCertificateManagerDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
@ -59,7 +59,7 @@
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>CertificateManagerDialog</receiver>
<receiver>PDFCertificateManagerDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">

View File

@ -15,27 +15,27 @@
// You should have received a copy of the GNU Lesser General Public License
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "createcertificatedialog.h"
#include "ui_createcertificatedialog.h"
#include "pdfcreatecertificatedialog.h"
#include "ui_pdfcreatecertificatedialog.h"
#include "certificatemanager.h"
#include "pdfcertificatemanager.h"
#include <QMessageBox>
#include <QInputDialog>
#include <QDate>
#include <QCalendar>
namespace pdfplugin
namespace pdf
{
CreateCertificateDialog::CreateCertificateDialog(QWidget *parent) :
PDFCreateCertificateDialog::PDFCreateCertificateDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::CreateCertificateDialog)
ui(new Ui::PDFCreateCertificateDialog)
{
ui->setupUi(this);
ui->fileNameEdit->setReadOnly(true);
ui->fileNameEdit->setText(CertificateManager::generateCertificateFileName());
ui->fileNameEdit->setText(PDFCertificateManager::generateCertificateFileName());
ui->keyLengthCombo->addItem(tr("1024 bits"), 1024);
ui->keyLengthCombo->addItem(tr("2048 bits"), 2048);
@ -88,12 +88,12 @@ CreateCertificateDialog::CreateCertificateDialog(QWidget *parent) :
ui->validTillEdit->setSelectedDate(selectedDate);
}
CreateCertificateDialog::~CreateCertificateDialog()
PDFCreateCertificateDialog::~PDFCreateCertificateDialog()
{
delete ui;
}
void CreateCertificateDialog::accept()
void PDFCreateCertificateDialog::accept()
{
if (validate())
{
@ -132,7 +132,7 @@ void CreateCertificateDialog::accept()
}
}
bool CreateCertificateDialog::validate()
bool PDFCreateCertificateDialog::validate()
{
// validate empty text fields
if (ui->commonNameEdit->text().isEmpty())
@ -159,4 +159,4 @@ bool CreateCertificateDialog::validate()
return true;
}
} // namespace plugin
} // namespace pdf

View File

@ -15,22 +15,22 @@
// You should have received a copy of the GNU Lesser General Public License
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef CREATECERTIFICATEDIALOG_H
#define CREATECERTIFICATEDIALOG_H
#ifndef PDFCREATECERTIFICATEDIALOG_H
#define PDFCREATECERTIFICATEDIALOG_H
#include "certificatemanager.h"
#include "pdfcertificatemanager.h"
#include <QDialog>
namespace Ui
{
class CreateCertificateDialog;
class PDFCreateCertificateDialog;
}
namespace pdfplugin
namespace pdf
{
class CreateCertificateDialog : public QDialog
class PDF4QTLIBSHARED_EXPORT PDFCreateCertificateDialog : public QDialog
{
Q_OBJECT
@ -38,10 +38,10 @@ private:
using BaseClass = QDialog;
public:
explicit CreateCertificateDialog(QWidget* parent);
virtual ~CreateCertificateDialog() override;
explicit PDFCreateCertificateDialog(QWidget* parent);
virtual ~PDFCreateCertificateDialog() override;
const CertificateManager::NewCertificateInfo& getNewCertificateInfo() const { return m_newCertificateInfo; }
const PDFCertificateManager::NewCertificateInfo& getNewCertificateInfo() const { return m_newCertificateInfo; }
public slots:
virtual void accept() override;
@ -49,11 +49,11 @@ public slots:
private:
bool validate();
CertificateManager::NewCertificateInfo m_newCertificateInfo;
PDFCertificateManager::NewCertificateInfo m_newCertificateInfo;
Ui::CreateCertificateDialog* ui;
Ui::PDFCreateCertificateDialog* ui;
};
} // namespace plugin
} // namespace pdf
#endif // CREATECERTIFICATEDIALOG_H
#endif // PDFCREATECERTIFICATEDIALOG_H

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CreateCertificateDialog</class>
<widget class="QDialog" name="CreateCertificateDialog">
<class>PDFCreateCertificateDialog</class>
<widget class="QDialog" name="PDFCreateCertificateDialog">
<property name="geometry">
<rect>
<x>0</x>
@ -149,7 +149,7 @@
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>CreateCertificateDialog</receiver>
<receiver>PDFCreateCertificateDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
@ -165,7 +165,7 @@
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>CreateCertificateDialog</receiver>
<receiver>PDFCreateCertificateDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">

File diff suppressed because it is too large Load Diff

View File

@ -35,6 +35,7 @@ enum class EncryptionMode
{
None, ///< Document is not encrypted
Standard, ///< Document is encrypted and using standard security handler
PublicKey, ///< Document is encrypted and using public key security handler
Custom ///< Document is encrypted and using custom security handler. Custom handlers must return this value.
};
@ -68,11 +69,14 @@ struct CryptFilter
CryptFilterType type = CryptFilterType::None;
AuthEvent authEvent = AuthEvent::DocOpen;
int keyLength = 0; ///< Key length in bytes
QByteArrayList recipients; ///< Recipients for public key security handler
};
class PDFSecurityHandler;
using PDFSecurityHandlerPointer = QSharedPointer<PDFSecurityHandler>;
class PDFStandardSecurityHandler;
class PDFSecurityHandler
{
public:
@ -196,6 +200,14 @@ public:
static PDFSecurityHandlerPointer createSecurityHandler(const PDFObject& encryptionDictionaryObject, const QByteArray& id);
protected:
static QByteArray parseName(const PDFDictionary* dictionary, const char* key, bool required, const char* defaultValue = nullptr);
static PDFInteger parseInt(const PDFDictionary* dictionary, const char* key, bool required, PDFInteger defaultValue = -1);
static CryptFilter parseCryptFilter(PDFInteger length, const PDFObject& object);
static PDFSecurityHandlerPointer createSecurityHandlerInstance(const PDFDictionary* dictionary);
static QByteArrayList parseRecipients(const PDFDictionary* dictionary);
static void parseCryptFilters(const PDFDictionary* dictionary, PDFSecurityHandler& handler, int Length);
static void parseDataStandardSecurityHandler(const PDFDictionary* dictionary, const QByteArray& id, int Length, PDFStandardSecurityHandler& handler);
/// Fills encryption dictionary with basic data
/// \param factory Factory
@ -242,23 +254,15 @@ public:
virtual PDFObject createEncryptionDictionaryObject() const override { return PDFObject(); }
};
/// Specifies the security using standard security handler (see PDF specification
/// for details).
class PDFStandardSecurityHandler : public PDFSecurityHandler
class PDFStandardOrPublicSecurityHandler : public PDFSecurityHandler
{
public:
virtual EncryptionMode getMode() const override { return EncryptionMode::Standard; }
virtual PDFSecurityHandler* clone() const override;
virtual AuthorizationResult authenticate(const std::function<QString(bool*)>& getPasswordCallback, bool authorizeOwnerOnly) override;
virtual QByteArray decrypt(const QByteArray& data, PDFObjectReference reference, EncryptionScope encryptionScope) const override;
virtual QByteArray decryptByFilter(const QByteArray& data, const QByteArray& filterName, PDFObjectReference reference) const override;
virtual QByteArray encrypt(const QByteArray& data, PDFObjectReference reference, EncryptionScope encryptionScope) const override;
virtual QByteArray encryptByFilter(const QByteArray& data, const QByteArray& filterName, PDFObjectReference reference) const override;
virtual bool isMetadataEncrypted() const override { return m_encryptMetadata; }
virtual bool isAllowed(Permission permission) const override { return m_authorizationData.authorizationResult == AuthorizationResult::OwnerAuthorized || (m_permissions & static_cast<uint32_t>(permission)); }
virtual bool isEncryptionAllowed() const override { return m_authorizationData.isAuthorized(); }
virtual AuthorizationResult getAuthorizationResult() const override { return m_authorizationData.authorizationResult; }
virtual PDFObject createEncryptionDictionaryObject() const override;
virtual bool isEncryptionAllowed() const override { return m_authorizationData.isAuthorized(); }
struct AuthorizationData
{
@ -268,10 +272,46 @@ public:
QByteArray fileEncryptionKey;
};
protected:
/// Decrypts data using specified filter. This function can be called only, if authorization was successfull.
/// \param data Data to be decrypted
/// \param filter Filter to be used for decryption
/// \param reference Object reference for key generation
/// \returns Decrypted data
QByteArray decryptUsingFilter(const QByteArray& data, CryptFilter filter, PDFObjectReference reference) const;
/// Encrypts data using specified filter. This function can be called only, if authorization was successfull.
/// \param data Data to be encrypted
/// \param filter Filter to be used for encryption
/// \param reference Object reference for key generation
/// \returns Encrypted data
QByteArray encryptUsingFilter(const QByteArray& data, CryptFilter filter, PDFObjectReference reference) const;
std::vector<uint8_t> createV2_ObjectEncryptionKey(PDFObjectReference reference, CryptFilter filter) const;
std::vector<uint8_t> createAESV2_ObjectEncryptionKey(PDFObjectReference reference) const;
CryptFilter getCryptFilter(EncryptionScope encryptionScope) const;
/// Authorization data
AuthorizationData m_authorizationData;
};
/// Specifies the security using standard security handler (see PDF specification
/// for details).
class PDFStandardSecurityHandler : public PDFStandardOrPublicSecurityHandler
{
public:
virtual EncryptionMode getMode() const override { return EncryptionMode::Standard; }
virtual PDFSecurityHandler* clone() const override;
virtual AuthorizationResult authenticate(const std::function<QString(bool*)>& getPasswordCallback, bool authorizeOwnerOnly) override;
virtual bool isMetadataEncrypted() const override { return m_encryptMetadata; }
virtual bool isAllowed(Permission permission) const override { return m_authorizationData.authorizationResult == AuthorizationResult::OwnerAuthorized || (m_permissions & static_cast<uint32_t>(permission)); }
virtual PDFObject createEncryptionDictionaryObject() const override;
/// Adjusts the password according to the PDF specification
static QByteArray adjustPassword(const QString& password, int revision);
private:
friend class PDFSecurityHandler;
friend class PDFSecurityHandlerFactory;
friend PDFSecurityHandlerPointer PDFSecurityHandler::createSecurityHandler(const PDFObject& encryptionDictionaryObject, const QByteArray& id);
@ -311,25 +351,6 @@ private:
/// Parses parts of the user/owner data (U/O values of the encryption dictionary)
UserOwnerData_r6 parseParts(const QByteArray& data) const;
/// Decrypts data using specified filter. This function can be called only, if authorization was successfull.
/// \param data Data to be decrypted
/// \param filter Filter to be used for decryption
/// \param reference Object reference for key generation
/// \returns Decrypted data
QByteArray decryptUsingFilter(const QByteArray& data, CryptFilter filter, PDFObjectReference reference) const;
/// Encrypts data using specified filter. This function can be called only, if authorization was successfull.
/// \param data Data to be encrypted
/// \param filter Filter to be used for encryption
/// \param reference Object reference for key generation
/// \returns Encrypted data
QByteArray encryptUsingFilter(const QByteArray& data, CryptFilter filter, PDFObjectReference reference) const;
std::vector<uint8_t> createV2_ObjectEncryptionKey(PDFObjectReference reference, CryptFilter filter) const;
std::vector<uint8_t> createAESV2_ObjectEncryptionKey(PDFObjectReference reference) const;
CryptFilter getCryptFilter(EncryptionScope encryptionScope) const;
/// Returns true, if character with unicode code is non-ascii space character
/// according the RFC 3454, section C.1.2
/// \param unicode Unicode code to be tested
@ -372,9 +393,19 @@ private:
/// First part of the id of the document
QByteArray m_ID;
};
/// Authorization data
AuthorizationData m_authorizationData;
/// Specifies the security using public key security handler (see PDF specification
/// for details).
class PDFPublicKeySecurityHandler : public PDFStandardOrPublicSecurityHandler
{
public:
virtual EncryptionMode getMode() const override { return EncryptionMode::PublicKey; }
virtual PDFSecurityHandler* clone() const override;
virtual AuthorizationResult authenticate(const std::function<QString(bool*)>& getPasswordCallback, bool authorizeOwnerOnly) override;
virtual bool isMetadataEncrypted() const override;
virtual bool isAllowed(Permission permission) const override;
virtual PDFObject createEncryptionDictionaryObject() const override;
};
/// Factory, which creates security handler based on settings.

View File

@ -189,6 +189,10 @@ void PDFDocumentPropertiesDialog::initializeSecurity(const pdf::PDFDocument* doc
modeString = tr("Standard");
break;
case pdf::EncryptionMode::PublicKey:
modeString = tr("Public Key");
break;
case pdf::EncryptionMode::Custom:
modeString = tr("Custom");
break;

View File

@ -40,16 +40,10 @@ INCLUDEPATH += $$Pdf4Qt_OPENSSL_PATH/OpenSSL/Win_x64/include
DEPENDPATH += $$Pdf4Qt_OPENSSL_PATH/OpenSSL/Win_x64/include
SOURCES += \
certificatemanager.cpp \
certificatemanagerdialog.cpp \
createcertificatedialog.cpp \
signatureplugin.cpp \
signdialog.cpp
HEADERS += \
certificatemanager.h \
certificatemanagerdialog.h \
createcertificatedialog.h \
signatureplugin.h \
signdialog.h
@ -62,7 +56,5 @@ RESOURCES += \
icons.qrc
FORMS += \
certificatemanagerdialog.ui \
createcertificatedialog.ui \
signdialog.ui

View File

@ -21,7 +21,7 @@
#include "pdfpagecontenteditorwidget.h"
#include "pdfpagecontenteditorstylesettings.h"
#include "pdfdocumentbuilder.h"
#include "certificatemanagerdialog.h"
#include "pdfcertificatemanagerdialog.h"
#include "signdialog.h"
#include "pdfdocumentwriter.h"
@ -314,11 +314,11 @@ void SignaturePlugin::onSignDigitally()
// Jakub Melka: do we have certificates? If not,
// open certificate dialog, so the user can create
// a new one.
if (CertificateManager::getCertificates().isEmpty())
if (pdf::PDFCertificateManager::getCertificates().isEmpty())
{
onOpenCertificatesManager();
if (CertificateManager::getCertificates().isEmpty())
if (pdf::PDFCertificateManager::getCertificates().isEmpty())
{
return;
}
@ -329,7 +329,7 @@ void SignaturePlugin::onSignDigitally()
{
QByteArray data = "SampleDataToBeSigned" + QByteArray::number(QDateTime::currentMSecsSinceEpoch());
QByteArray signature;
if (!SignatureFactory::sign(dialog.getCertificatePath(), dialog.getPassword(), data, signature))
if (!pdf::PDFSignatureFactory::sign(dialog.getCertificatePath(), dialog.getPassword(), data, signature))
{
QMessageBox::critical(m_widget, tr("Error"), tr("Failed to create digital signature."));
return;
@ -458,7 +458,7 @@ void SignaturePlugin::onSignDigitally()
buffer.seek(i3);
dataToBeSigned.append(buffer.read(i4));
if (!SignatureFactory::sign(dialog.getCertificatePath(), dialog.getPassword(), dataToBeSigned, signature))
if (!pdf::PDFSignatureFactory::sign(dialog.getCertificatePath(), dialog.getPassword(), dataToBeSigned, signature))
{
QMessageBox::critical(m_widget, tr("Error"), tr("Failed to create digital signature."));
buffer.close();
@ -492,7 +492,7 @@ QString SignaturePlugin::getSignedFileName() const
void SignaturePlugin::onOpenCertificatesManager()
{
CertificateManagerDialog dialog(m_dataExchangeInterface->getMainWindow());
pdf::PDFCertificateManagerDialog dialog(m_dataExchangeInterface->getMainWindow());
dialog.exec();
}

View File

@ -18,7 +18,7 @@
#include "signdialog.h"
#include "ui_signdialog.h"
#include "certificatemanager.h"
#include "pdfcertificatemanager.h"
#include <openssl/pkcs7.h>
@ -41,7 +41,7 @@ SignDialog::SignDialog(QWidget* parent, bool isSceneEmpty) :
ui->methodCombo->addItem(tr("Sign digitally (invisible signature)"), SignDigitallyInvisible);
ui->methodCombo->setCurrentIndex(0);
QFileInfoList certificates = CertificateManager::getCertificates();
QFileInfoList certificates = pdf::PDFCertificateManager::getCertificates();
for (const QFileInfo& certificateFileInfo : certificates)
{
ui->certificateCombo->addItem(certificateFileInfo.fileName(), certificateFileInfo.absoluteFilePath());
@ -89,7 +89,7 @@ void SignDialog::accept()
}
// Check we can access the certificate
if (!CertificateManager::isCertificateValid(getCertificatePath(), ui->certificatePasswordEdit->text()))
if (!pdf::PDFCertificateManager::isCertificateValid(getCertificatePath(), ui->certificatePasswordEdit->text()))
{
QMessageBox::critical(this, tr("Error"), tr("Password to open certificate is invalid."));
ui->certificatePasswordEdit->setFocus();

View File

@ -179,6 +179,10 @@ int PDFToolInfoApplication::execute(const PDFToolOptions& options)
modeString = PDFToolTranslationContext::tr("Standard");
break;
case pdf::EncryptionMode::PublicKey:
modeString = PDFToolTranslationContext::tr("Public Key");
break;
case pdf::EncryptionMode::Custom:
modeString = PDFToolTranslationContext::tr("Custom");
break;