vcl/inc/pdf/IPDFEncryptor.hxx | 91 ++++++++++++++++++++++++++++++++++++++++ vcl/inc/pdf/PDFEncryptor.hxx | 33 ++------------ vcl/source/pdf/PDFEncryptor.cxx | 4 + 3 files changed, 100 insertions(+), 28 deletions(-)
New commits: commit 4860c446e5cf7007f866f588d574eb96b473318e Author: Tomaž Vajngerl <[email protected]> AuthorDate: Mon Nov 11 15:36:13 2024 +0100 Commit: Miklos Vajna <[email protected]> CommitDate: Tue Dec 3 09:04:26 2024 +0100 pdf: introduce IPDFEncryptor interface Change-Id: I9cc0413f6c0af3be6ef83f4dbcf8dcf73b992f92 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176452 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/vcl/inc/pdf/IPDFEncryptor.hxx b/vcl/inc/pdf/IPDFEncryptor.hxx new file mode 100644 index 000000000000..b0f180ad944b --- /dev/null +++ b/vcl/inc/pdf/IPDFEncryptor.hxx @@ -0,0 +1,91 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#pragma once + +#include <rtl/ustring.hxx> +#include <vector> + +namespace vcl +{ +struct PDFEncryptionProperties; +} + +namespace com::sun::star::beans +{ +class XMaterialHolder; +} + +namespace com::sun::star::uno +{ +template <typename> class Reference; +} + +namespace vcl::pdf +{ +/** Interface for encrypting the PDF content + * + * This interface makes it possible to have multiple versions and + * revisions of PDF encryption, but all using the same interface, + * so the implementation details are hidden from the outside. This + * also makes it easier to add new implementations in the future as + * we only need to write a new implementation of this interface. + */ +class IPDFEncryptor +{ +public: + virtual ~IPDFEncryptor() {} + + /** PDF encryption version */ + virtual sal_Int32 getVersion() = 0; + /** PDF encryption revision */ + virtual sal_Int32 getRevision() = 0; + + /** the numerical value of the access permissions, according to PDF spec, must be signed */ + virtual sal_Int32 getAccessPermissions() = 0; + + /** Encrypted access permission + * + * Depending on the encryption revision this may not be available. In that + * case we can expect empty content. + */ + virtual std::vector<sal_uInt8> getEncryptedAccessPermissions() + { + return std::vector<sal_uInt8>(); + } + + /** Length of the key in bits (i.e. 256 = 256bits) */ + virtual sal_Int32 getKeyLength() = 0; + + /** Prepares the encryption when the password is entered */ + virtual bool prepareEncryption( + const css::uno::Reference<css::beans::XMaterialHolder>& xEncryptionMaterialHolder, + PDFEncryptionProperties& rProperties) + = 0; + + /** Set up the keys and does a sanity check */ + virtual void setupKeysAndCheck(PDFEncryptionProperties& rProperties) = 0; + + /** Setup before we start encrypting - remembers the key */ + virtual void setupEncryption(std::vector<sal_uInt8> const& rEncryptionKey, sal_Int32 nObject) + = 0; + + virtual void enableStreamEncryption() = 0; + virtual void disableStreamEncryption() = 0; + virtual bool isStreamEncryptionEnabled() = 0; + + /** Encrypts the input and stores into the output */ + virtual void encrypt(const void* pInput, sal_uInt64 nInputSize, sal_uInt8* pOutput, + sal_uInt64 nOutputsSize) + = 0; +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/pdf/PDFEncryptor.hxx b/vcl/inc/pdf/PDFEncryptor.hxx index f6182be7f93c..9b74a6206c6e 100644 --- a/vcl/inc/pdf/PDFEncryptor.hxx +++ b/vcl/inc/pdf/PDFEncryptor.hxx @@ -10,10 +10,10 @@ #pragma once -#include <string_view> #include <rtl/cipher.h> #include <rtl/ustring.hxx> #include <vector> +#include <pdf/IPDFEncryptor.hxx> namespace vcl { @@ -31,30 +31,6 @@ template <typename> class Reference; namespace vcl::pdf { -class EncryptionHashTransporter; - -class IPDFEncryptor -{ -public: - virtual ~IPDFEncryptor() {} - virtual sal_Int32 getAccessPermissions() = 0; - virtual sal_Int32 getKeyLength() = 0; - virtual bool prepareEncryption( - const css::uno::Reference<css::beans::XMaterialHolder>& xEncryptionMaterialHolder, - PDFEncryptionProperties& rProperties) - = 0; - virtual void setupKeysAndCheck(PDFEncryptionProperties& rProperties) = 0; - - virtual void setupEncryption(std::vector<sal_uInt8> const& rEncryptionKey, sal_Int32 nObject) - = 0; - virtual void enableStreamEncryption() = 0; - virtual void disableStreamEncryption() = 0; - virtual bool isStreamEncryptionEnabled() = 0; - virtual void encrypt(const void* pInput, sal_uInt64 nInputSize, sal_uInt8* pOutput, - sal_uInt64 nOutputsSize) - = 0; -}; - class PDFEncryptor : public IPDFEncryptor { private: @@ -70,12 +46,15 @@ private: /* set to true if the following stream must be encrypted, used inside writeBuffer() */ bool m_bEncryptThisStream = false; + /* used to cipher the stream data and for password management */ + rtlCipher m_aCipher = nullptr; + public: PDFEncryptor(); virtual ~PDFEncryptor(); - /* used to cipher the stream data and for password management */ - rtlCipher m_aCipher = nullptr; + sal_Int32 getVersion() override { return 2; }; + sal_Int32 getRevision() override { return 3; }; sal_Int32 getAccessPermissions() override { return m_nAccessPermissions; } sal_Int32 getKeyLength() override { return m_nKeyLength; } diff --git a/vcl/source/pdf/PDFEncryptor.cxx b/vcl/source/pdf/PDFEncryptor.cxx index 16b88ec160b0..d97e671247de 100644 --- a/vcl/source/pdf/PDFEncryptor.cxx +++ b/vcl/source/pdf/PDFEncryptor.cxx @@ -364,13 +364,15 @@ bool PDFEncryptor::prepareEncryption( = EncryptionHashTransporter::getEncHashTransporter(xEncryptionMaterialHolder); if (pTransporter) { - sal_Int32 nKeyLength = 0, nRC4KeyLength = 0; + sal_Int32 nKeyLength = 0; + sal_Int32 nRC4KeyLength = 0; sal_Int32 nAccessPermissions = computeAccessPermissions(rProperties, nKeyLength, nRC4KeyLength); rProperties.OValue = pTransporter->getOValue(); bSuccess = computeUDictionaryValue(pTransporter, rProperties, nKeyLength, nAccessPermissions); } + if (!bSuccess) { rProperties.OValue.clear();
