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)
|
||||
{
|
||||
if (!PDFEncoding::canConvertToEncoding(textString, PDFEncoding::Encoding::PDFDoc))
|
||||
if (!PDFEncoding::canConvertToEncoding(textString, PDFEncoding::Encoding::PDFDoc, nullptr))
|
||||
{
|
||||
// Use unicode encoding
|
||||
QByteArray ba;
|
||||
|
@@ -2132,7 +2132,7 @@ QString PDFEncoding::convert(const QByteArray& stream, PDFEncoding::Encoding enc
|
||||
return result;
|
||||
}
|
||||
|
||||
QByteArray PDFEncoding::convertToEncoding(const QString& string, PDFEncoding::Encoding encoding)
|
||||
QByteArray PDFEncoding::convertToEncoding(const QString& string, Encoding encoding)
|
||||
{
|
||||
QByteArray result;
|
||||
|
||||
@@ -2160,11 +2160,12 @@ QByteArray PDFEncoding::convertToEncoding(const QString& string, PDFEncoding::En
|
||||
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);
|
||||
Q_ASSERT(table);
|
||||
|
||||
bool isConvertible = true;
|
||||
for (QChar character : string)
|
||||
{
|
||||
ushort unicode = character.unicode();
|
||||
@@ -2181,14 +2182,23 @@ bool PDFEncoding::canConvertToEncoding(const QString& string, PDFEncoding::Encod
|
||||
|
||||
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);
|
||||
for (const unsigned char index : stream)
|
||||
@@ -2403,6 +2413,24 @@ QString PDFEncoding::convertSmartFromByteStringToUnicode(const QByteArray& strea
|
||||
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)
|
||||
{
|
||||
if (stream.size() >= 2)
|
||||
|
@@ -75,7 +75,8 @@ public:
|
||||
/// are also present in given encoding).
|
||||
/// \param string String to be tested
|
||||
/// \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
|
||||
/// 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
|
||||
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:
|
||||
/// 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
|
||||
|
@@ -191,19 +191,26 @@ void PDFDecryptOrEncryptObjectVisitor::visitStream(const PDFStream* stream)
|
||||
QByteArray processedData;
|
||||
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)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
processedDictionary.setEntry(PDFInplaceOrMemoryString("Length"), PDFObject::createInteger(processedData.size()));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -212,8 +219,7 @@ void PDFDecryptOrEncryptObjectVisitor::visitStream(const PDFStream* stream)
|
||||
case pdf::PDFDecryptOrEncryptObjectVisitor::Mode::Decrypt:
|
||||
{
|
||||
processedData = *stream->getContent();
|
||||
processedDictionary.removeEntry(PDFSecurityHandler::OBJECT_REFERENCE_DICTIONARY_NAME);
|
||||
processedDictionary.addEntry(PDFInplaceOrMemoryString(PDFSecurityHandler::OBJECT_REFERENCE_DICTIONARY_NAME), PDFObject::createReference(m_reference));
|
||||
processedDictionary.setEntry(PDFInplaceOrMemoryString(PDFSecurityHandler::OBJECT_REFERENCE_DICTIONARY_NAME), PDFObject::createReference(m_reference));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1991,4 +1997,48 @@ QByteArray PDFSecurityHandlerFactory::generateRandomByteArray(QRandomGenerator&
|
||||
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
|
||||
|
@@ -380,6 +380,8 @@ private:
|
||||
/// Factory, which creates security handler based on settings.
|
||||
class Pdf4QtLIBSHARED_EXPORT PDFSecurityHandlerFactory
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(pdf::PDFSecurityHandlerFactory)
|
||||
|
||||
public:
|
||||
|
||||
enum Algorithm
|
||||
@@ -432,6 +434,11 @@ public:
|
||||
/// \param generator Random number generator
|
||||
/// \param size Target 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
|
||||
|
Reference in New Issue
Block a user