Security information

This commit is contained in:
Jakub Melka
2019-12-21 15:02:11 +01:00
parent c228cf6d24
commit f2f398e82b
7 changed files with 183 additions and 5 deletions

View File

@ -64,6 +64,18 @@ const PDFDictionary* PDFDocument::getTrailerDictionary() const
return nullptr;
}
QByteArray PDFDocument::getVersion() const
{
QByteArray result = m_catalog.getVersion();
if (result.isEmpty() && m_info.version.isValid())
{
result = QString("%1.%2").arg(m_info.version.major).arg(m_info.version.minor).toLatin1();
}
return result;
}
void PDFDocument::init()
{
initInfo();
@ -164,6 +176,32 @@ void PDFDocument::initInfo()
throw PDFException(tr("Bad format of document info entry in trailer dictionary. Trapping information expected"));
}
}
// Scan for extra items
constexpr const char* PREDEFINED_ITEMS[] = { PDF_DOCUMENT_INFO_ENTRY_TITLE, PDF_DOCUMENT_INFO_ENTRY_AUTHOR, PDF_DOCUMENT_INFO_ENTRY_SUBJECT,
PDF_DOCUMENT_INFO_ENTRY_KEYWORDS, PDF_DOCUMENT_INFO_ENTRY_CREATOR, PDF_DOCUMENT_INFO_ENTRY_PRODUCER,
PDF_DOCUMENT_INFO_ENTRY_CREATION_DATE, PDF_DOCUMENT_INFO_ENTRY_MODIFIED_DATE, PDF_DOCUMENT_INFO_ENTRY_TRAPPED };
for (size_t i = 0; i < infoDictionary->getCount(); ++i)
{
const QByteArray& key = infoDictionary->getKey(i);
if (std::none_of(std::begin(PREDEFINED_ITEMS), std::end(PREDEFINED_ITEMS), [&key](const char* item) { return item == key; }))
{
const PDFObject& value = getObject(infoDictionary->getValue(i));
if (value.isString())
{
const QByteArray& stringValue = value.getString();
QDateTime dateTime = PDFEncoding::convertToDateTime(stringValue);
if (dateTime.isValid())
{
m_info.extra[key] = dateTime;
}
else
{
m_info.extra[key] = PDFEncoding::convertTextString(stringValue);
}
}
}
}
}
else if (!info.isNull()) // Info may be invalid...
{

View File

@ -305,7 +305,9 @@ public:
const PDFObjectStorage& getStorage() const { return m_pdfObjectStorage; }
/// Info about the document. Title, Author, Keywords...
/// Info about the document. Title, Author, Keywords... It also stores "extra"
/// values, which are in info dictionary. They can be either strings, or date
/// time (QString or QDateTime).
struct Info
{
/// Indicates, that document was modified that it includes trapping information.
@ -326,6 +328,8 @@ public:
QDateTime creationDate;
QDateTime modifiedDate;
Trapped trapped = Trapped::Unknown;
PDFVersion version;
std::map<QByteArray, QVariant> extra;
};
/// Returns info about the document (title, author, etc.)
@ -356,13 +360,20 @@ public:
/// Returns the trailer dictionary
const PDFDictionary* getTrailerDictionary() const;
/// Returns version of the PDF document. Version can be taken from catalog,
/// or from PDF file header. Version from catalog has precedence over version from
/// header.
QByteArray getVersion() const;
private:
friend class PDFDocumentReader;
explicit PDFDocument(PDFObjectStorage&& storage) :
explicit PDFDocument(PDFObjectStorage&& storage, PDFVersion version) :
m_pdfObjectStorage(std::move(storage))
{
init();
m_info.version = version;
}
/// Initialize data based on object in the storage.

View File

@ -481,7 +481,7 @@ PDFDocument PDFDocumentReader::readFromBuffer(const QByteArray& buffer)
std::for_each(std::execution::parallel_policy(), objectStreams.cbegin(), objectStreams.cend(), processObjectStream);
PDFObjectStorage storage(std::move(objects), PDFObject(xrefTable.getTrailerDictionary()), std::move(securityHandler));
return PDFDocument(std::move(storage));
return PDFDocument(std::move(storage), m_version);
}
catch (PDFException parserException)
{

View File

@ -92,6 +92,7 @@ public:
enum class AuthorizationResult
{
NoAuthorizationRequired,
UserAuthorized,
OwnerAuthorized,
Failed,
@ -146,6 +147,12 @@ public:
/// Returns true, if metadata are encrypted
virtual bool isMetadataEncrypted() const = 0;
/// Returns result of authorization process
virtual AuthorizationResult getAuthorizationResult() const = 0;
/// Returns version of the encryption
int getVersion() const { return m_V; }
/// Creates a security handler from the object. If object is null, then
/// "None" security handler is created. If error occurs, then exception is thrown.
/// \param encryptionDictionaryObject Encryption dictionary object
@ -185,7 +192,8 @@ public:
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; }
virtual bool isAllowed(Permission) const { return true; }
virtual bool isAllowed(Permission) const override { return true; }
virtual AuthorizationResult getAuthorizationResult() const override { return AuthorizationResult::NoAuthorizationRequired; }
};
/// Specifies the security using standard security handler (see PDF specification
@ -199,6 +207,7 @@ public:
virtual QByteArray decryptByFilter(const QByteArray& data, const QByteArray& filterName, PDFObjectReference reference) const override;
virtual bool isMetadataEncrypted() const override { return m_encryptMetadata; }
virtual bool isAllowed(Permission permission) const { return m_authorizationData.authorizationResult == AuthorizationResult::OwnerAuthorized || (m_permissions & static_cast<uint32_t>(permission)); }
virtual AuthorizationResult getAuthorizationResult() const override { return m_authorizationData.authorizationResult; }
struct AuthorizationData
{