mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Decrypt application
This commit is contained in:
@@ -1141,6 +1141,11 @@ void PDFDocumentBuilder::copyAnnotation(PDFObjectReference pageReference, PDFObj
|
||||
appendTo(pageReference, pageAnnots);
|
||||
}
|
||||
|
||||
void PDFDocumentBuilder::setSecurityHandler(PDFSecurityHandlerPointer handler)
|
||||
{
|
||||
m_storage.setSecurityHandler(qMove(handler));
|
||||
}
|
||||
|
||||
PDFObjectReference PDFDocumentBuilder::getCatalogReference() const
|
||||
{
|
||||
if (const PDFDictionary* trailerDictionary = getDictionaryFromObject(m_storage.getTrailerDictionary()))
|
||||
@@ -1582,7 +1587,7 @@ PDFContentStreamBuilder::ContentStream PDFContentStreamBuilder::end(QPainter* pa
|
||||
delete m_buffer;
|
||||
m_buffer = nullptr;
|
||||
|
||||
PDFDocumentReader reader(nullptr, nullptr, false);
|
||||
PDFDocumentReader reader(nullptr, nullptr, false, false);
|
||||
result.document = reader.readFromBuffer(bufferData);
|
||||
|
||||
if (result.document.getCatalog()->getPageCount() > 0)
|
||||
@@ -4288,6 +4293,20 @@ void PDFDocumentBuilder::removeDocumentActions()
|
||||
}
|
||||
|
||||
|
||||
void PDFDocumentBuilder::removeEncryption()
|
||||
{
|
||||
PDFObjectFactory objectBuilder;
|
||||
|
||||
objectBuilder.beginDictionary();
|
||||
objectBuilder.beginDictionaryItem("Encrypt");
|
||||
objectBuilder << PDFObject();
|
||||
objectBuilder.endDictionaryItem();
|
||||
objectBuilder.endDictionary();
|
||||
PDFObject updatedTrailerDictionary = objectBuilder.takeObject();
|
||||
m_storage.updateTrailerDictionary(qMove(updatedTrailerDictionary));
|
||||
}
|
||||
|
||||
|
||||
void PDFDocumentBuilder::removeOutline()
|
||||
{
|
||||
PDFObjectFactory objectBuilder;
|
||||
@@ -4731,14 +4750,6 @@ void PDFDocumentBuilder::setFormFieldValue(PDFObjectReference formField,
|
||||
}
|
||||
|
||||
|
||||
void PDFDocumentBuilder::setLanguage(QLocale locale)
|
||||
{
|
||||
PDFObjectFactory objectBuilder;
|
||||
|
||||
setLanguage(locale.name());
|
||||
}
|
||||
|
||||
|
||||
void PDFDocumentBuilder::setLanguage(QString language)
|
||||
{
|
||||
PDFObjectFactory objectBuilder;
|
||||
@@ -4753,6 +4764,14 @@ void PDFDocumentBuilder::setLanguage(QString language)
|
||||
}
|
||||
|
||||
|
||||
void PDFDocumentBuilder::setLanguage(QLocale locale)
|
||||
{
|
||||
PDFObjectFactory objectBuilder;
|
||||
|
||||
setLanguage(locale.name());
|
||||
}
|
||||
|
||||
|
||||
void PDFDocumentBuilder::setOutline(PDFObjectReference outline)
|
||||
{
|
||||
PDFObjectFactory objectBuilder;
|
||||
@@ -4856,6 +4875,7 @@ void PDFDocumentBuilder::setPageRotation(PDFObjectReference page,
|
||||
mergeTo(page, updatedPageObject);
|
||||
}
|
||||
|
||||
|
||||
void PDFDocumentBuilder::setPageTrimBox(PDFObjectReference page,
|
||||
QRectF box)
|
||||
{
|
||||
|
@@ -421,6 +421,11 @@ public:
|
||||
/// \param annotationReference Annotation reference
|
||||
void copyAnnotation(PDFObjectReference pageReference, PDFObjectReference annotationReference);
|
||||
|
||||
/// Sets security handler to the object storage. Trailer dictionary is not
|
||||
/// updated and so must be updated manually.
|
||||
/// \param handler New security handler
|
||||
void setSecurityHandler(PDFSecurityHandlerPointer handler);
|
||||
|
||||
/* START GENERATED CODE */
|
||||
|
||||
/// Appends a new page after last page.
|
||||
@@ -1185,6 +1190,10 @@ public:
|
||||
void removeDocumentActions();
|
||||
|
||||
|
||||
/// Removes encryption from a document.
|
||||
void removeEncryption();
|
||||
|
||||
|
||||
/// Removes outline tree from document catalog.
|
||||
void removeOutline();
|
||||
|
||||
@@ -1371,11 +1380,6 @@ public:
|
||||
PDFObject value);
|
||||
|
||||
|
||||
/// Set document language.
|
||||
/// \param locale Locale, from which is language determined
|
||||
void setLanguage(QLocale locale);
|
||||
|
||||
|
||||
/// Set document language.
|
||||
/// \param language Document language. It should be a language identifier, as defined in ISO 639
|
||||
/// and ISO 3166. For example, "en-US", where first two letter means language code (en =
|
||||
@@ -1383,6 +1387,11 @@ public:
|
||||
void setLanguage(QString language);
|
||||
|
||||
|
||||
/// Set document language.
|
||||
/// \param locale Locale, from which is language determined
|
||||
void setLanguage(QLocale locale);
|
||||
|
||||
|
||||
/// Set document outline.
|
||||
/// \param outline Document outline root
|
||||
void setOutline(PDFObjectReference outline);
|
||||
|
@@ -34,11 +34,12 @@
|
||||
namespace pdf
|
||||
{
|
||||
|
||||
PDFDocumentReader::PDFDocumentReader(PDFProgress* progress, const std::function<QString(bool*)>& getPasswordCallback, bool permissive) :
|
||||
PDFDocumentReader::PDFDocumentReader(PDFProgress* progress, const std::function<QString(bool*)>& getPasswordCallback, bool permissive, bool authorizeOwnerOnly) :
|
||||
m_result(Result::OK),
|
||||
m_getPasswordCallback(getPasswordCallback),
|
||||
m_progress(progress),
|
||||
m_permissive(permissive)
|
||||
m_permissive(permissive),
|
||||
m_authorizeOwnerOnly(authorizeOwnerOnly)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -375,7 +376,7 @@ PDFDocumentReader::Result PDFDocumentReader::processSecurityHandler(const PDFObj
|
||||
|
||||
// Read the security handler
|
||||
m_securityHandler = PDFSecurityHandler::createSecurityHandler(encryptObject, id);
|
||||
PDFSecurityHandler::AuthorizationResult authorizationResult = m_securityHandler->authenticate(m_getPasswordCallback);
|
||||
PDFSecurityHandler::AuthorizationResult authorizationResult = m_securityHandler->authenticate(m_getPasswordCallback, m_authorizeOwnerOnly);
|
||||
|
||||
if (authorizationResult == PDFSecurityHandler::AuthorizationResult::Cancelled)
|
||||
{
|
||||
|
@@ -40,7 +40,7 @@ class Pdf4QtLIBSHARED_EXPORT PDFDocumentReader
|
||||
Q_DECLARE_TR_FUNCTIONS(pdf::PDFDocumentReader)
|
||||
|
||||
public:
|
||||
explicit PDFDocumentReader(PDFProgress* progress, const std::function<QString(bool*)>& getPasswordCallback, bool permissive);
|
||||
explicit PDFDocumentReader(PDFProgress* progress, const std::function<QString(bool*)>& getPasswordCallback, bool permissive, bool authorizeOwnerOnly);
|
||||
|
||||
constexpr inline PDFDocumentReader(const PDFDocumentReader&) = delete;
|
||||
constexpr inline PDFDocumentReader(PDFDocumentReader&&) = delete;
|
||||
@@ -166,6 +166,10 @@ private:
|
||||
/// Be permissive when reading, tolerate errors and try to fix broken document
|
||||
bool m_permissive;
|
||||
|
||||
/// Authorize as owner only (if owner authorization fails, then whole document
|
||||
/// reading fails)
|
||||
bool m_authorizeOwnerOnly;
|
||||
|
||||
/// Warnings
|
||||
QStringList m_warnings;
|
||||
};
|
||||
|
@@ -369,7 +369,7 @@ PDFSecurityHandlerPointer PDFSecurityHandler::createSecurityHandler(const PDFObj
|
||||
|
||||
if (it == handler.m_cryptFilters.cend())
|
||||
{
|
||||
throw PDFException(PDFTranslationContext::tr("Uknown crypt filter '%1'.").arg(QString::fromLatin1(name)));
|
||||
throw PDFException(PDFTranslationContext::tr("Unknown crypt filter '%1'.").arg(QString::fromLatin1(name)));
|
||||
}
|
||||
|
||||
return it->second;
|
||||
@@ -446,7 +446,7 @@ PDFSecurityHandlerPointer PDFSecurityHandler::createSecurityHandler(const PDFObj
|
||||
return PDFSecurityHandlerPointer(new PDFStandardSecurityHandler(qMove(handler)));
|
||||
}
|
||||
|
||||
PDFSecurityHandler::AuthorizationResult PDFStandardSecurityHandler::authenticate(const std::function<QString(bool*)>& getPasswordCallback)
|
||||
PDFSecurityHandler::AuthorizationResult PDFStandardSecurityHandler::authenticate(const std::function<QString(bool*)>& getPasswordCallback, bool authorizeOwnerOnly)
|
||||
{
|
||||
QByteArray password;
|
||||
bool passwordObtained = true;
|
||||
@@ -478,15 +478,18 @@ PDFSecurityHandler::AuthorizationResult PDFStandardSecurityHandler::authenticate
|
||||
}
|
||||
|
||||
// Try to authorize user password
|
||||
QByteArray fileEncryptionKey = createFileEncryptionKey(password);
|
||||
QByteArray U = createEntryValueU_r234(fileEncryptionKey);
|
||||
|
||||
if (U == m_U)
|
||||
if (!authorizeOwnerOnly)
|
||||
{
|
||||
// We have authorized owner access
|
||||
m_authorizationData.authorizationResult = AuthorizationResult::UserAuthorized;
|
||||
m_authorizationData.fileEncryptionKey = fileEncryptionKey;
|
||||
return AuthorizationResult::UserAuthorized;
|
||||
QByteArray fileEncryptionKey = createFileEncryptionKey(password);
|
||||
QByteArray U = createEntryValueU_r234(fileEncryptionKey);
|
||||
|
||||
if (U == m_U)
|
||||
{
|
||||
// We have authorized user access
|
||||
m_authorizationData.authorizationResult = AuthorizationResult::UserAuthorized;
|
||||
m_authorizationData.fileEncryptionKey = fileEncryptionKey;
|
||||
return AuthorizationResult::UserAuthorized;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -534,7 +537,7 @@ PDFSecurityHandler::AuthorizationResult PDFStandardSecurityHandler::authenticate
|
||||
}
|
||||
|
||||
// Try to authorize user password
|
||||
if (!m_authorizationData.isAuthorized())
|
||||
if (!m_authorizationData.isAuthorized() && !authorizeOwnerOnly)
|
||||
{
|
||||
QByteArray inputData = password + userData.validationSalt;
|
||||
QByteArray hash = createHash_r56(inputData, password, false);
|
||||
@@ -925,7 +928,7 @@ QByteArray PDFStandardSecurityHandler::createUserPasswordFromOwnerPassword(const
|
||||
const int keyByteLength = m_keyLength / 8;
|
||||
if (keyByteLength > MD5_DIGEST_LENGTH)
|
||||
{
|
||||
throw PDFException(PDFTranslationContext::tr("Encryption key length (%1) exceeded maximal value of.").arg(keyByteLength).arg(MD5_DIGEST_LENGTH));
|
||||
throw PDFException(PDFTranslationContext::tr("Encryption key length (%1) exceeded maximal value of %2.").arg(keyByteLength).arg(MD5_DIGEST_LENGTH));
|
||||
}
|
||||
|
||||
if (m_R >= 3)
|
||||
|
@@ -116,8 +116,9 @@ public:
|
||||
/// to cancel the authentication (and \p Cancelled authentication result is returned) or true,
|
||||
/// to try provided password.
|
||||
/// \param getPasswordCallback Callback to get user password
|
||||
/// \param authorizeOwnerOnly Authorize owner only
|
||||
/// \returns Result of authentication
|
||||
virtual AuthorizationResult authenticate(const std::function<QString(bool*)>& getPasswordCallback) = 0;
|
||||
virtual AuthorizationResult authenticate(const std::function<QString(bool*)>& getPasswordCallback, bool authorizeOwnerOnly) = 0;
|
||||
|
||||
/// Decrypts the PDF object. This function works properly only (and only if)
|
||||
/// \p authenticate function returns user/owner authorization code.
|
||||
@@ -188,7 +189,7 @@ class PDFNoneSecurityHandler : public PDFSecurityHandler
|
||||
{
|
||||
public:
|
||||
virtual EncryptionMode getMode() const override { return EncryptionMode::None; }
|
||||
virtual AuthorizationResult authenticate(const std::function<QString(bool*)>&) override { return AuthorizationResult::OwnerAuthorized; }
|
||||
virtual AuthorizationResult authenticate(const std::function<QString(bool*)>&, bool) override { return AuthorizationResult::OwnerAuthorized; }
|
||||
virtual QByteArray decrypt(const QByteArray& data, PDFObjectReference, EncryptionScope) const override { return data; }
|
||||
virtual QByteArray decryptByFilter(const QByteArray& data, const QByteArray&, PDFObjectReference) const override { return data; }
|
||||
virtual bool isMetadataEncrypted() const override { return true; }
|
||||
@@ -202,7 +203,7 @@ class PDFStandardSecurityHandler : public PDFSecurityHandler
|
||||
{
|
||||
public:
|
||||
virtual EncryptionMode getMode() const override { return EncryptionMode::Standard; }
|
||||
virtual AuthorizationResult authenticate(const std::function<QString(bool*)>& getPasswordCallback) 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 bool isMetadataEncrypted() const override { return m_encryptMetadata; }
|
||||
|
Reference in New Issue
Block a user