summaryrefslogtreecommitdiff
path: root/vcl/source/gdi/pdfwriter_impl.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/gdi/pdfwriter_impl.cxx')
-rw-r--r--vcl/source/gdi/pdfwriter_impl.cxx88
1 files changed, 61 insertions, 27 deletions
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index aa841973df17..56311e7f2791 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -96,7 +96,7 @@
#include <pdf/objectcopier.hxx>
#include <pdf/pdfwriter_impl.hxx>
#include <pdf/PdfConfig.hxx>
-#include <pdf/IPDFEncryptor.hxx>
+#include <pdf/PDFEncryptorR6.hxx>
#include <pdf/PDFEncryptor.hxx>
#include <o3tl/sorted_vector.hxx>
#include <frozen/bits/defines.h>
@@ -143,6 +143,12 @@ void appendHex(sal_Int8 nInt, OStringBuffer& rBuffer)
rBuffer.append( pHexDigits[ nInt & 15 ] );
}
+void appendHexArray(sal_uInt8* pArray, size_t nSize, OStringBuffer& rBuffer)
+{
+ for (size_t i = 0; i < nSize; i++)
+ appendHex(pArray[i], rBuffer);
+}
+
void appendName( std::u16string_view rStr, OStringBuffer& rBuffer )
{
// FIXME i59651 add a check for max length of 127 chars? Per PDF spec 1.4, appendix C.1
@@ -1459,7 +1465,10 @@ PDFWriterImpl::PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext,
if (xEncryptionMaterialHolder.is())
{
- m_pPDFEncryptor.reset(new PDFEncryptor);
+ if (m_aContext.Version == PDFWriter::PDFVersion::PDF_2_0 || m_aContext.Version == PDFWriter::PDFVersion::PDF_A_4)
+ m_pPDFEncryptor.reset(new PDFEncryptorR6);
+ else
+ m_pPDFEncryptor.reset(new PDFEncryptor);
m_pPDFEncryptor->prepareEncryption(xEncryptionMaterialHolder, m_aContext.Encryption);
}
@@ -1618,10 +1627,10 @@ inline void PDFWriterImpl::appendUnicodeTextStringEncrypt( const OUString& rInSt
*pCopy++ = static_cast<sal_uInt8>( aUnChar & 255 );
}
//encrypt in place
- m_pPDFEncryptor->encrypt(m_vEncryptionBuffer.data(), nChars, m_vEncryptionBuffer, nChars);
+ std::vector<sal_uInt8> aNewBuffer(nChars);
+ m_pPDFEncryptor->encrypt(m_vEncryptionBuffer.data(), nChars, aNewBuffer, nChars);
//now append, hexadecimal (appendHex), the encrypted result
- for(int i = 0; i < nChars; i++)
- appendHex( m_vEncryptionBuffer[i], rOutBuffer );
+ appendHexArray(aNewBuffer.data(), aNewBuffer.size(), rOutBuffer);
}
else
PDFWriter::AppendUnicodeTextString(rInString, rOutBuffer);
@@ -1639,7 +1648,7 @@ inline void PDFWriterImpl::appendLiteralStringEncrypt( std::string_view rInStrin
//encrypt the string in a buffer, then append it
enableStringEncryption(nInObjectNumber);
m_pPDFEncryptor->encrypt(rInString.data(), nChars, m_vEncryptionBuffer, nChars);
- appendLiteralString( reinterpret_cast<char*>(m_vEncryptionBuffer.data()), nChars, rOutBuffer );
+ appendLiteralString(reinterpret_cast<char*>(m_vEncryptionBuffer.data()), m_vEncryptionBuffer.size(), rOutBuffer);
}
else
appendLiteralString( rInString.data(), nChars , rOutBuffer );
@@ -1738,34 +1747,42 @@ bool PDFWriterImpl::writeBufferBytes( const void* pBuffer, sal_uInt64 nBytes )
}
sal_uInt64 nWritten;
- if( m_pCodec )
+ sal_uInt64 nActualSize = nBytes;
+
+ // we are compressing the stream
+ if (m_pCodec)
{
m_pCodec->Write( *m_pMemStream, static_cast<const sal_uInt8*>(pBuffer), static_cast<sal_uLong>(nBytes) );
nWritten = nBytes;
}
else
{
+ // is it encrypted?
bool bStreamEncryption = m_pPDFEncryptor && m_pPDFEncryptor->isStreamEncryptionEnabled();
if (bStreamEncryption)
{
- m_vEncryptionBuffer.resize(nBytes);
- m_pPDFEncryptor->encrypt(pBuffer, nBytes, m_vEncryptionBuffer, nBytes);
+ nActualSize = m_pPDFEncryptor->calculateSizeIncludingHeader(nActualSize);
+ m_vEncryptionBuffer.resize(nActualSize);
+ m_pPDFEncryptor->encrypt(pBuffer, nBytes, m_vEncryptionBuffer, nActualSize);
}
const void* pWriteBuffer = bStreamEncryption ? m_vEncryptionBuffer.data() : pBuffer;
- m_DocDigest.update(static_cast<unsigned char const*>(pWriteBuffer), static_cast<sal_uInt32>(nBytes));
+ m_DocDigest.update(static_cast<unsigned char const*>(pWriteBuffer), sal_uInt32(nActualSize));
- if (m_aFile.write(pWriteBuffer, nBytes, nWritten) != osl::File::E_None)
+
+ if (m_aFile.write(pWriteBuffer, nActualSize, nWritten) != osl::File::E_None)
nWritten = 0;
- if( nWritten != nBytes )
+ if (nWritten != nActualSize)
{
m_aFile.close();
m_bOpen = false;
+ return false;
}
+ return true;
}
- return nWritten == nBytes;
+ return nWritten == nActualSize;
}
void PDFWriterImpl::newPage( double nPageWidth, double nPageHeight, PDFWriter::Orientation eOrientation )
@@ -6160,12 +6177,34 @@ sal_Int32 PDFWriterImpl::emitEncrypt()
aWriter.startObject(nObject);
aWriter.startDict();
aWriter.write("/Filter", "/Standard");
- aWriter.write("/V", 2);
- aWriter.write("/Length", 128);
- aWriter.write("/R", 3);
- // emit the owner password, must not be encrypted
- aWriter.writeHexArray("/O", rProperties.OValue.data(), rProperties.OValue.size());
- aWriter.writeHexArray("/U", rProperties.UValue.data(), rProperties.UValue.size());
+ aWriter.write("/V", m_pPDFEncryptor->getVersion());
+ aWriter.write("/Length", m_pPDFEncryptor->getKeyLength() * 8);
+ aWriter.write("/R", m_pPDFEncryptor->getRevision());
+
+ if (m_pPDFEncryptor->getVersion() == 5 && m_pPDFEncryptor->getRevision() == 6)
+ {
+ // emit the owner password, must not be encrypted
+ aWriter.writeHexArray("/U", rProperties.UValue.data(), rProperties.UValue.size());
+ aWriter.writeHexArray("/UE", rProperties.UE.data(), rProperties.UE.size());
+ aWriter.writeHexArray("/O", rProperties.OValue.data(), rProperties.OValue.size());
+ aWriter.writeHexArray("/OE", rProperties.OE.data(), rProperties.OE.size());
+
+ // Encrypted perms
+ std::vector<sal_uInt8> aEncryptedPermissions = m_pPDFEncryptor->getEncryptedAccessPermissions(rProperties.EncryptionKey);
+ aWriter.writeHexArray("/Perms", aEncryptedPermissions.data(), aEncryptedPermissions.size());
+
+ // Write content filter stuff - to select we want AESv3 256bit
+ aWriter.write("/CF", "<</StdCF <</CFM /AESV3 /Length 256>>>>");
+ aWriter.write("/StmF", "/StdCF");
+ aWriter.write("/StrF", "/StdCF");
+ aWriter.write("/EncryptMetadata", " false ");
+ }
+ else
+ {
+ // emit the owner password, must not be encrypted
+ aWriter.writeHexArray("/U", rProperties.UValue.data(), rProperties.UValue.size());
+ aWriter.writeHexArray("/O", rProperties.OValue.data(), rProperties.OValue.size());
+ }
aWriter.write("/P", m_pPDFEncryptor->getAccessPermissions());
aWriter.endDict();
aWriter.endObject();
@@ -9823,15 +9862,10 @@ bool PDFWriterImpl::writeBitmapObject( const BitmapEmit& rObject, bool bMask )
m_vEncryptionBuffer[nChar++] = rColor.GetBlue();
}
//encrypt the colorspace lookup table
- m_pPDFEncryptor->encrypt(m_vEncryptionBuffer.data(), nChar, m_vEncryptionBuffer, nChar);
+ std::vector<sal_uInt8> aOutputBuffer(nChar);
+ m_pPDFEncryptor->encrypt(m_vEncryptionBuffer.data(), nChar, aOutputBuffer, nChar);
//now queue the data for output
- nChar = 0;
- for( sal_uInt16 i = 0; i < pAccess->GetPaletteEntryCount(); i++ )
- {
- appendHex(m_vEncryptionBuffer[nChar++], aLine );
- appendHex(m_vEncryptionBuffer[nChar++], aLine );
- appendHex(m_vEncryptionBuffer[nChar++], aLine );
- }
+ appendHexArray(aOutputBuffer.data(), aOutputBuffer.size(), aLine);
}
else //no encryption requested (PDF/A-1a program flow drops here)
{