mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Encryption tool
This commit is contained in:
@ -495,7 +495,7 @@ PDFObjectFactory& PDFObjectFactory::operator<<(WrapEmptyArray)
|
|||||||
|
|
||||||
PDFObject PDFObjectFactory::createTextString(QString textString)
|
PDFObject PDFObjectFactory::createTextString(QString textString)
|
||||||
{
|
{
|
||||||
if (!PDFEncoding::canConvertToEncoding(textString, PDFEncoding::Encoding::PDFDoc))
|
if (!PDFEncoding::canConvertToEncoding(textString, PDFEncoding::Encoding::PDFDoc, nullptr))
|
||||||
{
|
{
|
||||||
// Use unicode encoding
|
// Use unicode encoding
|
||||||
QByteArray ba;
|
QByteArray ba;
|
||||||
|
@ -2132,7 +2132,7 @@ QString PDFEncoding::convert(const QByteArray& stream, PDFEncoding::Encoding enc
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray PDFEncoding::convertToEncoding(const QString& string, PDFEncoding::Encoding encoding)
|
QByteArray PDFEncoding::convertToEncoding(const QString& string, Encoding encoding)
|
||||||
{
|
{
|
||||||
QByteArray result;
|
QByteArray result;
|
||||||
|
|
||||||
@ -2160,11 +2160,12 @@ QByteArray PDFEncoding::convertToEncoding(const QString& string, PDFEncoding::En
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PDFEncoding::canConvertToEncoding(const QString& string, PDFEncoding::Encoding encoding)
|
bool PDFEncoding::canConvertToEncoding(const QString& string, Encoding encoding, QString* invalidCharacters)
|
||||||
{
|
{
|
||||||
const encoding::EncodingTable* table = getTableForEncoding(encoding);
|
const encoding::EncodingTable* table = getTableForEncoding(encoding);
|
||||||
Q_ASSERT(table);
|
Q_ASSERT(table);
|
||||||
|
|
||||||
|
bool isConvertible = true;
|
||||||
for (QChar character : string)
|
for (QChar character : string)
|
||||||
{
|
{
|
||||||
ushort unicode = character.unicode();
|
ushort unicode = character.unicode();
|
||||||
@ -2181,14 +2182,23 @@ bool PDFEncoding::canConvertToEncoding(const QString& string, PDFEncoding::Encod
|
|||||||
|
|
||||||
if (!converted)
|
if (!converted)
|
||||||
{
|
{
|
||||||
return false;
|
isConvertible = false;
|
||||||
|
|
||||||
|
if (!invalidCharacters)
|
||||||
|
{
|
||||||
|
// We are not storing invalid characters - we can break on first not convertible
|
||||||
|
// character.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*invalidCharacters += character;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return isConvertible;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PDFEncoding::canConvertFromEncoding(const QByteArray& stream, PDFEncoding::Encoding encoding)
|
bool PDFEncoding::canConvertFromEncoding(const QByteArray& stream, Encoding encoding)
|
||||||
{
|
{
|
||||||
const encoding::EncodingTable* table = getTableForEncoding(encoding);
|
const encoding::EncodingTable* table = getTableForEncoding(encoding);
|
||||||
for (const unsigned char index : stream)
|
for (const unsigned char index : stream)
|
||||||
@ -2403,6 +2413,24 @@ QString PDFEncoding::convertSmartFromByteStringToUnicode(const QByteArray& strea
|
|||||||
return QString::fromLatin1(stream.toHex()).toUpper();
|
return QString::fromLatin1(stream.toHex()).toUpper();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString PDFEncoding::getEncodingCharacters(Encoding encoding)
|
||||||
|
{
|
||||||
|
QString string;
|
||||||
|
|
||||||
|
if (const encoding::EncodingTable* table = getTableForEncoding(encoding))
|
||||||
|
{
|
||||||
|
for (const QChar& character : *table)
|
||||||
|
{
|
||||||
|
if (character != QChar(0xFFFD))
|
||||||
|
{
|
||||||
|
string += character;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
bool PDFEncoding::hasUnicodeLeadMarkings(const QByteArray& stream)
|
bool PDFEncoding::hasUnicodeLeadMarkings(const QByteArray& stream)
|
||||||
{
|
{
|
||||||
if (stream.size() >= 2)
|
if (stream.size() >= 2)
|
||||||
|
@ -75,7 +75,8 @@ public:
|
|||||||
/// are also present in given encoding).
|
/// are also present in given encoding).
|
||||||
/// \param string String to be tested
|
/// \param string String to be tested
|
||||||
/// \param encoding Encoding used in verification of conversion
|
/// \param encoding Encoding used in verification of conversion
|
||||||
static bool canConvertToEncoding(const QString& string, Encoding encoding);
|
/// \param[out] invalidCharacters Storage, where not convertible characters are inserted
|
||||||
|
static bool canConvertToEncoding(const QString& string, Encoding encoding, QString* invalidCharacters);
|
||||||
|
|
||||||
/// Checks, if stream can be converted to string using encoding (i.e. all
|
/// Checks, if stream can be converted to string using encoding (i.e. all
|
||||||
/// characters are defined). If all characters are valid, then true is
|
/// characters are defined). If all characters are valid, then true is
|
||||||
@ -120,6 +121,11 @@ public:
|
|||||||
/// \returns Unicode string or string converted to hexadecimal representation
|
/// \returns Unicode string or string converted to hexadecimal representation
|
||||||
static QString convertSmartFromByteStringToUnicode(const QByteArray& stream, bool* isBinary);
|
static QString convertSmartFromByteStringToUnicode(const QByteArray& stream, bool* isBinary);
|
||||||
|
|
||||||
|
/// Returns all characters of the given encoding
|
||||||
|
/// \param encoding Encoding
|
||||||
|
/// \returns All characters reprezentable by encoding.
|
||||||
|
static QString getEncodingCharacters(Encoding encoding);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Returns true, if byte array has UTF-16BE/LE unicode marking bytes at the
|
/// Returns true, if byte array has UTF-16BE/LE unicode marking bytes at the
|
||||||
/// stream start. If they are present, then byte stream is probably encoded
|
/// stream start. If they are present, then byte stream is probably encoded
|
||||||
|
@ -191,19 +191,26 @@ void PDFDecryptOrEncryptObjectVisitor::visitStream(const PDFStream* stream)
|
|||||||
QByteArray processedData;
|
QByteArray processedData;
|
||||||
if (!processedDictionary.hasKey("Crypt"))
|
if (!processedDictionary.hasKey("Crypt"))
|
||||||
{
|
{
|
||||||
|
// Is it an embedded file?
|
||||||
|
const PDFObject& object = processedDictionary.get("Type");
|
||||||
|
const bool isEmbeddedFile = object.isName() && object.getString() == "EmbeddedFile";
|
||||||
|
const PDFSecurityHandler::EncryptionScope scope = !isEmbeddedFile ? PDFSecurityHandler::EncryptionScope::Stream : PDFSecurityHandler::EncryptionScope::EmbeddedFile;
|
||||||
|
|
||||||
switch (m_mode)
|
switch (m_mode)
|
||||||
{
|
{
|
||||||
case pdf::PDFDecryptOrEncryptObjectVisitor::Mode::Decrypt:
|
case pdf::PDFDecryptOrEncryptObjectVisitor::Mode::Decrypt:
|
||||||
processedData = m_securityHandler->decrypt(*stream->getContent(), m_reference, PDFSecurityHandler::EncryptionScope::Stream);
|
processedData = m_securityHandler->decrypt(*stream->getContent(), m_reference, scope);
|
||||||
break;
|
break;
|
||||||
case pdf::PDFDecryptOrEncryptObjectVisitor::Mode::Encrypt:
|
case pdf::PDFDecryptOrEncryptObjectVisitor::Mode::Encrypt:
|
||||||
processedData = m_securityHandler->encrypt(*stream->getContent(), m_reference, PDFSecurityHandler::EncryptionScope::Stream);
|
processedData = m_securityHandler->encrypt(*stream->getContent(), m_reference, scope);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
processedDictionary.setEntry(PDFInplaceOrMemoryString("Length"), PDFObject::createInteger(processedData.size()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -212,8 +219,7 @@ void PDFDecryptOrEncryptObjectVisitor::visitStream(const PDFStream* stream)
|
|||||||
case pdf::PDFDecryptOrEncryptObjectVisitor::Mode::Decrypt:
|
case pdf::PDFDecryptOrEncryptObjectVisitor::Mode::Decrypt:
|
||||||
{
|
{
|
||||||
processedData = *stream->getContent();
|
processedData = *stream->getContent();
|
||||||
processedDictionary.removeEntry(PDFSecurityHandler::OBJECT_REFERENCE_DICTIONARY_NAME);
|
processedDictionary.setEntry(PDFInplaceOrMemoryString(PDFSecurityHandler::OBJECT_REFERENCE_DICTIONARY_NAME), PDFObject::createReference(m_reference));
|
||||||
processedDictionary.addEntry(PDFInplaceOrMemoryString(PDFSecurityHandler::OBJECT_REFERENCE_DICTIONARY_NAME), PDFObject::createReference(m_reference));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1991,4 +1997,48 @@ QByteArray PDFSecurityHandlerFactory::generateRandomByteArray(QRandomGenerator&
|
|||||||
return ba;
|
return ba;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PDFSecurityHandlerFactory::validate(const SecuritySettings& settings, QString* errorMessage)
|
||||||
|
{
|
||||||
|
switch (settings.algorithm)
|
||||||
|
{
|
||||||
|
case pdf::PDFSecurityHandlerFactory::RC4:
|
||||||
|
case pdf::PDFSecurityHandlerFactory::AES_128:
|
||||||
|
{
|
||||||
|
QString invalidCharacters;
|
||||||
|
|
||||||
|
if (!PDFEncoding::canConvertToEncoding(settings.userPassword, PDFEncoding::Encoding::PDFDoc, &invalidCharacters))
|
||||||
|
{
|
||||||
|
if (errorMessage)
|
||||||
|
{
|
||||||
|
Q_ASSERT(!invalidCharacters.isEmpty());
|
||||||
|
*errorMessage = tr("User password contains invalid characters: %1.").arg(invalidCharacters);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PDFEncoding::canConvertToEncoding(settings.ownerPassword, PDFEncoding::Encoding::PDFDoc, &invalidCharacters))
|
||||||
|
{
|
||||||
|
if (errorMessage)
|
||||||
|
{
|
||||||
|
Q_ASSERT(!invalidCharacters.isEmpty());
|
||||||
|
*errorMessage = tr("Owner password contains invalid characters: %1.").arg(invalidCharacters);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case pdf::PDFSecurityHandlerFactory::None:
|
||||||
|
case pdf::PDFSecurityHandlerFactory::AES_256:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Q_ASSERT(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
@ -380,6 +380,8 @@ private:
|
|||||||
/// Factory, which creates security handler based on settings.
|
/// Factory, which creates security handler based on settings.
|
||||||
class Pdf4QtLIBSHARED_EXPORT PDFSecurityHandlerFactory
|
class Pdf4QtLIBSHARED_EXPORT PDFSecurityHandlerFactory
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_TR_FUNCTIONS(pdf::PDFSecurityHandlerFactory)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum Algorithm
|
enum Algorithm
|
||||||
@ -432,6 +434,11 @@ public:
|
|||||||
/// \param generator Random number generator
|
/// \param generator Random number generator
|
||||||
/// \param size Target size
|
/// \param size Target size
|
||||||
static QByteArray generateRandomByteArray(QRandomGenerator& generator, int size);
|
static QByteArray generateRandomByteArray(QRandomGenerator& generator, int size);
|
||||||
|
|
||||||
|
/// Validates security settings
|
||||||
|
/// \param settings Settings
|
||||||
|
/// \param[out] errorMessage Error message
|
||||||
|
static bool validate(const SecuritySettings& settings, QString* errorMessage);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="copyrightLabel">
|
<widget class="QLabel" name="copyrightLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string><html><head/><body><p><span style=" font-weight:600;">PdfForQtViewer</span></p><p>Copyright 2018-2020 Jakub Melka. All rights reserved.</p><p>THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</p></body></html></string>
|
<string><html><head/><body><p><span style=" font-weight:600;">PdfForQtViewer</span></p><p>Copyright 2018-2021 Jakub Melka. All rights reserved.</p><p>THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
#include "pdfutils.h"
|
#include "pdfutils.h"
|
||||||
#include "pdfsecurityhandler.h"
|
#include "pdfsecurityhandler.h"
|
||||||
|
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
namespace pdfviewer
|
namespace pdfviewer
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -191,6 +193,13 @@ void PDFEncryptionSettingsDialog::accept()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString errorMessage;
|
||||||
|
if (!pdf::PDFSecurityHandlerFactory::validate(settings, &errorMessage))
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, tr("Error"), errorMessage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_updatedSecurityHandler = pdf::PDFSecurityHandlerFactory::createSecurityHandler(settings);
|
m_updatedSecurityHandler = pdf::PDFSecurityHandlerFactory::createSecurityHandler(settings);
|
||||||
|
|
||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
|
@ -47,6 +47,7 @@ SOURCES += \
|
|||||||
pdftoolcertstore.cpp \
|
pdftoolcertstore.cpp \
|
||||||
pdftoolcolorprofiles.cpp \
|
pdftoolcolorprofiles.cpp \
|
||||||
pdftooldecrypt.cpp \
|
pdftooldecrypt.cpp \
|
||||||
|
pdftoolencrypt.cpp \
|
||||||
pdftoolfetchimages.cpp \
|
pdftoolfetchimages.cpp \
|
||||||
pdftoolfetchtext.cpp \
|
pdftoolfetchtext.cpp \
|
||||||
pdftoolinfo.cpp \
|
pdftoolinfo.cpp \
|
||||||
@ -80,6 +81,7 @@ HEADERS += \
|
|||||||
pdftoolcertstore.h \
|
pdftoolcertstore.h \
|
||||||
pdftoolcolorprofiles.h \
|
pdftoolcolorprofiles.h \
|
||||||
pdftooldecrypt.h \
|
pdftooldecrypt.h \
|
||||||
|
pdftoolencrypt.h \
|
||||||
pdftoolfetchimages.h \
|
pdftoolfetchimages.h \
|
||||||
pdftoolfetchtext.h \
|
pdftoolfetchtext.h \
|
||||||
pdftoolinfo.h \
|
pdftoolinfo.h \
|
||||||
|
@ -324,6 +324,15 @@ void PDFToolAbstractApplication::initializeCommandLineParser(QCommandLineParser*
|
|||||||
{
|
{
|
||||||
parser->addPositionalArgument("certificate", "Certificate file");
|
parser->addPositionalArgument("certificate", "Certificate file");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (optionFlags.testFlag(Encrypt))
|
||||||
|
{
|
||||||
|
parser->addOption(QCommandLineOption("enc-algorithm", "Encryption algorithm (valid values: rc4|aes-128|aes-256).", "encryption algorithm", "aes-256"));
|
||||||
|
parser->addOption(QCommandLineOption("enc-contents", "Encryption scope (valid values: all|all-except-metadata|only-embedded-files).", "encryption contents", "all"));
|
||||||
|
parser->addOption(QCommandLineOption("enc-user-password", "User password (for document reading).", "user password"));
|
||||||
|
parser->addOption(QCommandLineOption("enc-owner-password", "Owner password.", "owner password"));
|
||||||
|
parser->addOption(QCommandLineOption("enc-permissions", "Document permissions (flags represented as a number).", "permissions"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PDFToolOptions PDFToolAbstractApplication::getOptions(QCommandLineParser* parser) const
|
PDFToolOptions PDFToolAbstractApplication::getOptions(QCommandLineParser* parser) const
|
||||||
@ -896,6 +905,59 @@ PDFToolOptions PDFToolAbstractApplication::getOptions(QCommandLineParser* parser
|
|||||||
options.certificateStoreInstallCertificateFile = positionalArguments.isEmpty() ? QString() : positionalArguments.front();
|
options.certificateStoreInstallCertificateFile = positionalArguments.isEmpty() ? QString() : positionalArguments.front();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (optionFlags.testFlag(Encrypt))
|
||||||
|
{
|
||||||
|
QString encryptionAlgorithm = parser->value("enc-algorithm");
|
||||||
|
if (encryptionAlgorithm == "rc4")
|
||||||
|
{
|
||||||
|
options.encryptionAlgorithm = pdf::PDFSecurityHandlerFactory::Algorithm::RC4;
|
||||||
|
}
|
||||||
|
else if (encryptionAlgorithm == "aes-128")
|
||||||
|
{
|
||||||
|
options.encryptionAlgorithm = pdf::PDFSecurityHandlerFactory::Algorithm::AES_128;
|
||||||
|
}
|
||||||
|
else if (encryptionAlgorithm == "aes-256")
|
||||||
|
{
|
||||||
|
options.encryptionAlgorithm = pdf::PDFSecurityHandlerFactory::Algorithm::AES_256;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!encryptionAlgorithm.isEmpty())
|
||||||
|
{
|
||||||
|
PDFConsole::writeError(PDFToolTranslationContext::tr("Unknown encryption algorithm '%1'. Defaulting to AES-256 encryption.").arg(encryptionAlgorithm), options.outputCodec);
|
||||||
|
}
|
||||||
|
|
||||||
|
options.encryptionAlgorithm = pdf::PDFSecurityHandlerFactory::Algorithm::AES_256;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString encryptionContents = parser->value("enc-contents");
|
||||||
|
if (encryptionContents == "all")
|
||||||
|
{
|
||||||
|
options.encryptionContents = pdf::PDFSecurityHandlerFactory::EncryptContents::All;
|
||||||
|
}
|
||||||
|
else if (encryptionContents == "all-except-metadata")
|
||||||
|
{
|
||||||
|
options.encryptionContents = pdf::PDFSecurityHandlerFactory::EncryptContents::AllExceptMetadata;
|
||||||
|
}
|
||||||
|
else if (encryptionContents == "only-embedded-files")
|
||||||
|
{
|
||||||
|
options.encryptionContents = pdf::PDFSecurityHandlerFactory::EncryptContents::EmbeddedFiles;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!encryptionContents.isEmpty())
|
||||||
|
{
|
||||||
|
PDFConsole::writeError(PDFToolTranslationContext::tr("Unknown encryption contents mode '%1'. Defaulting to encrypt all contents.").arg(encryptionContents), options.outputCodec);
|
||||||
|
}
|
||||||
|
|
||||||
|
options.encryptionContents = pdf::PDFSecurityHandlerFactory::EncryptContents::All;
|
||||||
|
}
|
||||||
|
|
||||||
|
options.encryptionUserPassword = parser->value("enc-user-password");
|
||||||
|
options.encryptionOwnerPassword = parser->value("enc-owner-password");
|
||||||
|
options.encryptionPermissions = parser->value("enc-permissions").toUInt();
|
||||||
|
}
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,6 +146,13 @@ struct PDFToolOptions
|
|||||||
// For option 'CertStoreInstall'
|
// For option 'CertStoreInstall'
|
||||||
QString certificateStoreInstallCertificateFile;
|
QString certificateStoreInstallCertificateFile;
|
||||||
|
|
||||||
|
// For option 'Encrypt'
|
||||||
|
pdf::PDFSecurityHandlerFactory::Algorithm encryptionAlgorithm = pdf::PDFSecurityHandlerFactory::Algorithm::AES_256;
|
||||||
|
pdf::PDFSecurityHandlerFactory::EncryptContents encryptionContents = pdf::PDFSecurityHandlerFactory::EncryptContents::All;
|
||||||
|
QString encryptionUserPassword;
|
||||||
|
QString encryptionOwnerPassword;
|
||||||
|
uint32_t encryptionPermissions = 0;
|
||||||
|
|
||||||
/// Returns page range. If page range is invalid, then \p errorMessage is empty.
|
/// Returns page range. If page range is invalid, then \p errorMessage is empty.
|
||||||
/// \param pageCount Page count
|
/// \param pageCount Page count
|
||||||
/// \param[out] errorMessage Error message
|
/// \param[out] errorMessage Error message
|
||||||
@ -194,7 +201,8 @@ public:
|
|||||||
ErrorPermissions,
|
ErrorPermissions,
|
||||||
ErrorNoText,
|
ErrorNoText,
|
||||||
ErrorCOM,
|
ErrorCOM,
|
||||||
ErrorSAPI
|
ErrorSAPI,
|
||||||
|
ErrorEncryptionSettings
|
||||||
};
|
};
|
||||||
|
|
||||||
enum StandardString
|
enum StandardString
|
||||||
@ -229,6 +237,7 @@ public:
|
|||||||
Optimize = 0x00100000, ///< Settings for Optimize tool
|
Optimize = 0x00100000, ///< Settings for Optimize tool
|
||||||
CertStore = 0x00200000, ///< Settings for certificate store tool
|
CertStore = 0x00200000, ///< Settings for certificate store tool
|
||||||
CertStoreInstall = 0x00400000, ///< Settings for certificate store install certificate tool
|
CertStoreInstall = 0x00400000, ///< Settings for certificate store install certificate tool
|
||||||
|
Encrypt = 0x00800000, ///< Encryption settings
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(Options, Option)
|
Q_DECLARE_FLAGS(Options, Option)
|
||||||
|
|
||||||
|
98
PdfTool/pdftoolencrypt.cpp
Normal file
98
PdfTool/pdftoolencrypt.cpp
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
// Copyright (C) 2021 Jakub Melka
|
||||||
|
//
|
||||||
|
// This file is part of Pdf4Qt.
|
||||||
|
//
|
||||||
|
// Pdf4Qt is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// with the written consent of the copyright owner, any later version.
|
||||||
|
//
|
||||||
|
// Pdf4Qt is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// 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 "pdftoolencrypt.h"
|
||||||
|
#include "pdfdocumentbuilder.h"
|
||||||
|
#include "pdfdocumentwriter.h"
|
||||||
|
|
||||||
|
namespace pdftool
|
||||||
|
{
|
||||||
|
|
||||||
|
static PDFToolEncryptApplication s_encryptApplication;
|
||||||
|
|
||||||
|
QString PDFToolEncryptApplication::getStandardString(StandardString standardString) const
|
||||||
|
{
|
||||||
|
switch (standardString)
|
||||||
|
{
|
||||||
|
case Command:
|
||||||
|
return "encrypt";
|
||||||
|
|
||||||
|
case Name:
|
||||||
|
return PDFToolTranslationContext::tr("Encrypt");
|
||||||
|
|
||||||
|
case Description:
|
||||||
|
return PDFToolTranslationContext::tr("Encrypt the document (with only owner access only).");
|
||||||
|
|
||||||
|
default:
|
||||||
|
Q_ASSERT(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
int PDFToolEncryptApplication::execute(const PDFToolOptions& options)
|
||||||
|
{
|
||||||
|
pdf::PDFSecurityHandlerFactory::SecuritySettings settings;
|
||||||
|
settings.algorithm = options.encryptionAlgorithm;
|
||||||
|
settings.encryptContents = options.encryptionContents;
|
||||||
|
settings.userPassword = options.encryptionUserPassword;
|
||||||
|
settings.ownerPassword = options.encryptionOwnerPassword;
|
||||||
|
settings.permissions = options.encryptionPermissions;
|
||||||
|
|
||||||
|
QString errorMessage;
|
||||||
|
if (!pdf::PDFSecurityHandlerFactory::validate(settings, &errorMessage))
|
||||||
|
{
|
||||||
|
PDFConsole::writeError(errorMessage, options.outputCodec);
|
||||||
|
return ErrorEncryptionSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
pdf::PDFSecurityHandlerPointer securityHandler = pdf::PDFSecurityHandlerFactory::createSecurityHandler(settings);
|
||||||
|
|
||||||
|
pdf::PDFDocument document;
|
||||||
|
QByteArray sourceData;
|
||||||
|
if (!readDocument(options, document, &sourceData, true))
|
||||||
|
{
|
||||||
|
if (readDocument(options, document, &sourceData, false))
|
||||||
|
{
|
||||||
|
PDFConsole::writeError(PDFToolTranslationContext::tr("Authorization as owner failed. Encryption change is not permitted if authorized as user only."), options.outputCodec);
|
||||||
|
}
|
||||||
|
return ErrorDocumentReading;
|
||||||
|
}
|
||||||
|
|
||||||
|
pdf::PDFDocumentBuilder builder(&document);
|
||||||
|
builder.setSecurityHandler(qMove(securityHandler));
|
||||||
|
document = builder.build();
|
||||||
|
|
||||||
|
pdf::PDFDocumentWriter writer(nullptr);
|
||||||
|
pdf::PDFOperationResult result = writer.write(options.document, &document, true);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
PDFConsole::writeError(result.getErrorMessage(), options.outputCodec);
|
||||||
|
return ErrorDocumentWriting;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ExitSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFToolAbstractApplication::Options PDFToolEncryptApplication::getOptionsFlags() const
|
||||||
|
{
|
||||||
|
return ConsoleFormat | OpenDocument | Encrypt;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace pdftool
|
36
PdfTool/pdftoolencrypt.h
Normal file
36
PdfTool/pdftoolencrypt.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright (C) 2021 Jakub Melka
|
||||||
|
//
|
||||||
|
// This file is part of Pdf4Qt.
|
||||||
|
//
|
||||||
|
// Pdf4Qt is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// with the written consent of the copyright owner, any later version.
|
||||||
|
//
|
||||||
|
// Pdf4Qt is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// 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 PDFTOOLENCRYPT_H
|
||||||
|
#define PDFTOOLENCRYPT_H
|
||||||
|
|
||||||
|
#include "pdftoolabstractapplication.h"
|
||||||
|
|
||||||
|
namespace pdftool
|
||||||
|
{
|
||||||
|
|
||||||
|
class PDFToolEncryptApplication : public PDFToolAbstractApplication
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual QString getStandardString(StandardString standardString) const override;
|
||||||
|
virtual int execute(const PDFToolOptions& options) override;
|
||||||
|
virtual Options getOptionsFlags() const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace pdftool
|
||||||
|
|
||||||
|
#endif // PDFTOOLENCRYPT_H
|
Reference in New Issue
Block a user