summaryrefslogtreecommitdiff
path: root/package
diff options
context:
space:
mode:
authorMikhail Voytenko <mav@openoffice.org>2011-03-23 14:13:24 +0100
committerMikhail Voytenko <mav@openoffice.org>2011-03-23 14:13:24 +0100
commit1decd7beffc8333d441b4327649685464e129d26 (patch)
treeb5ea5538ef1984c510bf2d4c51fdaa2d319d9e6f /package
parentb92dc6c03d0876230e3e7f2daa43a3350972f0e9 (diff)
mav60: #164341# fix problems with the new implementation
Diffstat (limited to 'package')
-rw-r--r--package/inc/PackageConstants.hxx7
-rw-r--r--package/inc/ZipFile.hxx4
-rw-r--r--package/inc/ZipOutputStream.hxx4
-rw-r--r--package/inc/ZipPackage.hxx3
-rw-r--r--package/inc/ZipPackageStream.hxx12
-rw-r--r--package/qa/storages/TestHelper.java12
-rw-r--r--package/source/manifest/ManifestExport.cxx6
-rw-r--r--package/source/manifest/ManifestImport.cxx32
-rw-r--r--package/source/manifest/ManifestImport.hxx2
-rw-r--r--package/source/xstor/owriteablestream.cxx4
-rw-r--r--package/source/xstor/xstorage.cxx13
-rw-r--r--package/source/zipapi/MemoryByteGrabber.hxx2
-rw-r--r--package/source/zipapi/XUnbufferedStream.cxx35
-rw-r--r--package/source/zipapi/XUnbufferedStream.hxx1
-rw-r--r--package/source/zipapi/ZipFile.cxx70
-rw-r--r--package/source/zipapi/ZipOutputStream.cxx30
-rw-r--r--package/source/zipapi/blowfishcontext.cxx27
-rw-r--r--package/source/zipapi/blowfishcontext.hxx2
-rw-r--r--package/source/zippackage/ZipPackage.cxx57
-rw-r--r--package/source/zippackage/ZipPackageFolder.cxx15
-rw-r--r--package/source/zippackage/ZipPackageStream.cxx25
21 files changed, 231 insertions, 132 deletions
diff --git a/package/inc/PackageConstants.hxx b/package/inc/PackageConstants.hxx
index 3695f023ec58..90c73edf2ba7 100644
--- a/package/inc/PackageConstants.hxx
+++ b/package/inc/PackageConstants.hxx
@@ -31,7 +31,12 @@
const sal_Int32 n_ConstBufferSize = 32768;
const sal_Int32 n_ConstMaxMemoryStreamSize = 20480;
+
+// by calculation of the digest we read 32 bytes more ( if available )
+// it allows to ignore the padding if the stream is longer than n_ConstDigestDecrypt since we read at least two blocks more;
+// if the stream is shorter or equal the padding will be done successfully
const sal_Int32 n_ConstDigestLength = 1024;
+const sal_Int32 n_ConstDigestDecrypt = 1056; // 1024 + 32
// the constants related to the manifest.xml entries
#define PKG_MNFST_MEDIATYPE 0
@@ -49,7 +54,7 @@ const sal_Int32 n_ConstDigestLength = 1024;
#define PKG_MNFST_DERKEYSIZE 11
#define PKG_SIZE_NOENCR_MNFST 3
-#define PKG_SIZE_ENCR_MNFST 8
+#define PKG_SIZE_ENCR_MNFST 12
// the properties related constants
#define ENCRYPTION_KEY_PROPERTY "EncryptionKey"
diff --git a/package/inc/ZipFile.hxx b/package/inc/ZipFile.hxx
index fcb5d17713c2..915bc26464fd 100644
--- a/package/inc/ZipFile.hxx
+++ b/package/inc/ZipFile.hxx
@@ -162,10 +162,6 @@ public:
::com::sun::star::packages::zip::ZipIOException,
::com::sun::star::uno::RuntimeException );
- static void StaticRemoveW3CPadding(
- const ::rtl::Reference< EncryptionData >& rEncData,
- ::com::sun::star::uno::Sequence< sal_Int8 >& o_rPaddedData );
-
static sal_Bool StaticHasValidPassword (
const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory,
const ::com::sun::star::uno::Sequence< sal_Int8 > &aReadBuffer,
diff --git a/package/inc/ZipOutputStream.hxx b/package/inc/ZipOutputStream.hxx
index b33e7c13a243..48fafb4c4a9c 100644
--- a/package/inc/ZipOutputStream.hxx
+++ b/package/inc/ZipOutputStream.hxx
@@ -49,7 +49,9 @@ protected:
::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > xStream;
::std::vector < ZipEntry * > aZipList;
- ::com::sun::star::uno::Sequence< sal_Int8 > aBuffer;
+
+ ::com::sun::star::uno::Sequence< sal_Int8 > m_aDeflateBuffer;
+
::rtl::OUString sComment;
Deflater aDeflater;
diff --git a/package/inc/ZipPackage.hxx b/package/inc/ZipPackage.hxx
index 3d0ad38f6aac..c9fef60c29c7 100644
--- a/package/inc/ZipPackage.hxx
+++ b/package/inc/ZipPackage.hxx
@@ -90,7 +90,6 @@ protected:
FolderHash m_aRecent;
::rtl::OUString m_aURL;
- bool m_bStartKeyGenerationImported;
sal_Int32 m_nStartKeyGenerationID;
sal_Int32 m_nChecksumDigestID;
sal_Int32 m_nCommonEncryptionID;
@@ -137,7 +136,7 @@ public:
sal_Int32 GetKeyGenID() const { return m_nStartKeyGenerationID; }
sal_Int32 GetEncAlgID() const { return m_nCommonEncryptionID; }
sal_Int32 GetChecksumAlgID() const { return m_nChecksumDigestID; }
- sal_Int32 GetDefaultDerivedKeySize() const { return m_nCommonEncryptionID == ::com::sun::star::xml::crypto::CipherID::AES_CBC ? 32 : 16; }
+ sal_Int32 GetDefaultDerivedKeySize() const { return m_nCommonEncryptionID == ::com::sun::star::xml::crypto::CipherID::AES_CBC_W3C_PADDING ? 32 : 16; }
SotMutexHolderRef GetSharedMutexRef() { return m_aMutexHolder; }
diff --git a/package/inc/ZipPackageStream.hxx b/package/inc/ZipPackageStream.hxx
index 7d22bf71a86d..454ea735d0a0 100644
--- a/package/inc/ZipPackageStream.hxx
+++ b/package/inc/ZipPackageStream.hxx
@@ -64,6 +64,7 @@ protected:
::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > m_aStorageEncryptionKeys;
::com::sun::star::uno::Sequence< sal_Int8 > m_aEncryptionKey;
+ sal_Int32 m_nImportedStartKeyAlgorithm;
sal_Int32 m_nImportedEncryptionAlgorithm;
sal_Int32 m_nImportedChecksumAlgorithm;
sal_Int32 m_nImportedDerivedKeySize;
@@ -80,7 +81,7 @@ protected:
bool m_bUseWinEncoding;
- ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& GetOwnSeekStream();
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > GetOwnSeekStream();
public:
sal_Bool HasOwnKey () const { return bHaveOwnKey;}
@@ -99,11 +100,11 @@ public:
sal_Int32 GetKeyGenID();
- const com::sun::star::uno::Sequence < sal_Int8 >& getInitialisationVector () const
+ const com::sun::star::uno::Sequence < sal_Int8 > getInitialisationVector () const
{ return m_xBaseEncryptionData->m_aInitVector;}
- const com::sun::star::uno::Sequence < sal_Int8 >& getDigest () const
+ const com::sun::star::uno::Sequence < sal_Int8 > getDigest () const
{ return m_xBaseEncryptionData->m_aDigest;}
- const com::sun::star::uno::Sequence < sal_Int8 >& getSalt () const
+ const com::sun::star::uno::Sequence < sal_Int8 > getSalt () const
{ return m_xBaseEncryptionData->m_aSalt;}
sal_Int32 getIterationCount () const
{ return m_xBaseEncryptionData->m_nIterationCount;}
@@ -113,9 +114,12 @@ public:
sal_uInt8 GetStreamMode() const { return m_nStreamMode; }
sal_uInt32 GetMagicalHackPos() const { return m_nMagicalHackPos; }
sal_uInt32 GetMagicalHackSize() const { return m_nMagicalHackSize; }
+ sal_Int32 GetEncryptionAlgorithm() const;
+ sal_Int32 GetBlockSize() const;
void SetToBeCompressed (sal_Bool bNewValue) { bToBeCompressed = bNewValue;}
void SetIsEncrypted (sal_Bool bNewValue) { bIsEncrypted = bNewValue;}
+ void SetImportedStartKeyAlgorithm( sal_Int32 nAlgorithm ) { m_nImportedStartKeyAlgorithm = nAlgorithm; }
void SetImportedEncryptionAlgorithm( sal_Int32 nAlgorithm ) { m_nImportedEncryptionAlgorithm = nAlgorithm; }
void SetImportedChecksumAlgorithm( sal_Int32 nAlgorithm ) { m_nImportedChecksumAlgorithm = nAlgorithm; }
void SetImportedDerivedKeySize( sal_Int32 nSize ) { m_nImportedDerivedKeySize = nSize; }
diff --git a/package/qa/storages/TestHelper.java b/package/qa/storages/TestHelper.java
index dc28786513b1..75efa4e2099b 100644
--- a/package/qa/storages/TestHelper.java
+++ b/package/qa/storages/TestHelper.java
@@ -1435,23 +1435,23 @@ public class TestHelper {
try
{
byte pData[][] = new byte[1][22];
- if ( xHeadRawStream.readBytes( pData, 22 ) != 22 )
+ if ( xHeadRawStream.readBytes( pData, 34 ) != 34 )
{
Error( "Can't read header of encrypted stream '" + sStreamName + "' raw representations!" );
return false;
}
- if ( pData[0][0] != 0x4d || pData[0][1] != 0x47 || pData[0][2] != 0x02 || pData[0][3] != 0x05 )
+ if ( pData[0][0] != 0x4d || pData[0][1] != 0x4d || pData[0][2] != 0x02 || pData[0][3] != 0x05 )
{
Error( "No signature in the header of encrypted stream '" + sStreamName + "' raw representations!" );
return false;
}
int nVariableHeaderLength =
- ( pData[0][14] + pData[0][15] * 0x100 ) // salt length
- + ( pData[0][16] + pData[0][17] * 0x100 ) // iv length
- + ( pData[0][18] + pData[0][19] * 0x100 ) // digest length
- + ( pData[0][20] + pData[0][21] * 0x100 ); // mediatype length
+ ( pData[0][26] + pData[0][27] * 0x100 ) // salt length
+ + ( pData[0][28] + pData[0][29] * 0x100 ) // iv length
+ + ( pData[0][30] + pData[0][31] * 0x100 ) // digest length
+ + ( pData[0][32] + pData[0][33] * 0x100 ); // mediatype length
xHeadRawStream.skipBytes( nVariableHeaderLength );
diff --git a/package/source/manifest/ManifestExport.cxx b/package/source/manifest/ManifestExport.cxx
index e9c23c43daad..068ff48e2c69 100644
--- a/package/source/manifest/ManifestExport.cxx
+++ b/package/source/manifest/ManifestExport.cxx
@@ -292,7 +292,7 @@ ManifestExport::ManifestExport( uno::Reference< xml::sax::XDocumentHandler > xHa
*pDerivedKeySize >>= nDerivedKeySize;
::rtl::OUString sEncAlgName;
- if ( nEncAlgID == xml::crypto::CipherID::AES_CBC )
+ if ( nEncAlgID == xml::crypto::CipherID::AES_CBC_W3C_PADDING )
{
OSL_ENSURE( nDerivedKeySize, "Unexpected key size is provided!" );
if ( nDerivedKeySize != 32 )
@@ -359,13 +359,13 @@ ManifestExport::ManifestExport( uno::Reference< xml::sax::XDocumentHandler > xHa
if ( nStartKeyAlgID == xml::crypto::DigestID::SHA256 )
{
sStartKeyAlg = sSHA256_URL;
- aBuffer.append( (sal_uInt8)32 );
+ aBuffer.append( (sal_Int32)32 );
sStartKeySize = aBuffer.makeStringAndClear();
}
else if ( nStartKeyAlgID == xml::crypto::DigestID::SHA1 )
{
sStartKeyAlg = sSHA1_Name;
- aBuffer.append( (sal_uInt8)20 );
+ aBuffer.append( (sal_Int32)20 );
sStartKeySize = aBuffer.makeStringAndClear();
}
else
diff --git a/package/source/manifest/ManifestImport.cxx b/package/source/manifest/ManifestImport.cxx
index 13e695fea17b..ef17a188afc6 100644
--- a/package/source/manifest/ManifestImport.cxx
+++ b/package/source/manifest/ManifestImport.cxx
@@ -53,6 +53,7 @@ ManifestImport::ManifestImport( vector < Sequence < PropertyValue > > & rNewManV
, sManifestElement ( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_MANIFEST ) )
, sEncryptionDataElement( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_ENCRYPTION_DATA ) )
, sAlgorithmElement ( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_ALGORITHM ) )
+, sStartKeyAlgElement ( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_START_KEY_GENERATION ) )
, sKeyDerivationElement( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_KEY_DERIVATION ) )
, sCdataAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CDATA ) )
@@ -65,6 +66,7 @@ ManifestImport::ManifestImport( vector < Sequence < PropertyValue > > & rNewManV
, sIterationCountAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_ITERATION_COUNT ) )
, sKeySizeAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_KEY_SIZE ) )
, sAlgorithmNameAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_ALGORITHM_NAME ) )
+, sStartKeyAlgNameAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_START_KEY_GENERATION_NAME ) )
, sKeyDerivationNameAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_KEY_DERIVATION_NAME ) )
, sChecksumAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CHECKSUM ) )
, sChecksumTypeAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CHECKSUM_TYPE ) )
@@ -207,22 +209,22 @@ void SAL_CALL ManifestImport::startElement( const OUString& aName, const uno::Re
else if ( aString.equals( sAES256_URL ) )
{
aSequence[nNumProperty].Name = sEncryptionAlgProperty;
- aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::AES_CBC;
- OSL_ENSURE( nDerivedKeySize && nDerivedKeySize != 32, "Unexpected derived key length!" );
+ aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING;
+ OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 32, "Unexpected derived key length!" );
nDerivedKeySize = 32;
}
else if ( aString.equals( sAES192_URL ) )
{
aSequence[nNumProperty].Name = sEncryptionAlgProperty;
- aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::AES_CBC;
- OSL_ENSURE( nDerivedKeySize && nDerivedKeySize != 24, "Unexpected derived key length!" );
+ aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING;
+ OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 24, "Unexpected derived key length!" );
nDerivedKeySize = 24;
}
else if ( aString.equals( sAES128_URL ) )
{
aSequence[nNumProperty].Name = sEncryptionAlgProperty;
- aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::AES_CBC;
- OSL_ENSURE( nDerivedKeySize && nDerivedKeySize != 16, "Unexpected derived key length!" );
+ aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING;
+ OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 16, "Unexpected derived key length!" );
nDerivedKeySize = 16;
}
else
@@ -264,7 +266,7 @@ void SAL_CALL ManifestImport::startElement( const OUString& aName, const uno::Re
}
else if ( !nDerivedKeySize )
nDerivedKeySize = 16;
- else
+ else if ( nDerivedKeySize != 16 )
OSL_ENSURE( sal_False, "Default derived key length differs from the expected one!" );
aSequence[nNumProperty].Name = sDerivedKeySizeProperty;
@@ -274,6 +276,22 @@ void SAL_CALL ManifestImport::startElement( const OUString& aName, const uno::Re
bIgnoreEncryptData = sal_True;
}
}
+ else if ( aConvertedName == sStartKeyAlgElement )
+ {
+ OUString aString = aConvertedAttribs[sStartKeyAlgNameAttribute];
+ if ( aString.equals( sSHA256_URL ) )
+ {
+ aSequence[nNumProperty].Name = sStartKeyAlgProperty;
+ aSequence[nNumProperty++].Value <<= xml::crypto::DigestID::SHA256;
+ }
+ else if ( aString.equals( sSHA1_Name ) || aString.equals( sSHA1_URL ) )
+ {
+ aSequence[nNumProperty].Name = sStartKeyAlgProperty;
+ aSequence[nNumProperty++].Value <<= xml::crypto::DigestID::SHA1;
+ }
+ else
+ bIgnoreEncryptData = sal_True;
+ }
}
}
}
diff --git a/package/source/manifest/ManifestImport.hxx b/package/source/manifest/ManifestImport.hxx
index 4ad81738751e..8c42960c220f 100644
--- a/package/source/manifest/ManifestImport.hxx
+++ b/package/source/manifest/ManifestImport.hxx
@@ -73,6 +73,7 @@ protected:
const ::rtl::OUString sManifestElement;
const ::rtl::OUString sEncryptionDataElement;
const ::rtl::OUString sAlgorithmElement;
+ const ::rtl::OUString sStartKeyAlgElement;
const ::rtl::OUString sKeyDerivationElement;
const ::rtl::OUString sCdataAttribute;
@@ -85,6 +86,7 @@ protected:
const ::rtl::OUString sIterationCountAttribute;
const ::rtl::OUString sKeySizeAttribute;
const ::rtl::OUString sAlgorithmNameAttribute;
+ const ::rtl::OUString sStartKeyAlgNameAttribute;
const ::rtl::OUString sKeyDerivationNameAttribute;
const ::rtl::OUString sChecksumAttribute;
const ::rtl::OUString sChecksumTypeAttribute;
diff --git a/package/source/xstor/owriteablestream.cxx b/package/source/xstor/owriteablestream.cxx
index 6675d5e331a5..2fd6a47c12ff 100644
--- a/package/source/xstor/owriteablestream.cxx
+++ b/package/source/xstor/owriteablestream.cxx
@@ -1313,7 +1313,7 @@ uno::Reference< io::XStream > OWriteStream_Impl::GetStream( sal_Int32 nStreamMod
}
else
{
- SetEncryptionKeyProperty_Impl( xPropertySet, m_aEncryptionData.getAsConstNamedValueList() );
+ SetEncryptionKeyProperty_Impl( xPropertySet, aEncryptionData.getAsConstNamedValueList() );
try {
xResultStream = GetStream_Impl( nStreamMode, bHierarchyAccess );
@@ -1662,7 +1662,7 @@ void OWriteStream_Impl::GetCopyOfLastCommit( uno::Reference< io::XStream >& xTar
else
{
uno::Reference< beans::XPropertySet > xPropertySet( m_xPackageStream, uno::UNO_QUERY );
- SetEncryptionKeyProperty_Impl( xPropertySet, m_aEncryptionData.getAsConstNamedValueList() );
+ SetEncryptionKeyProperty_Impl( xPropertySet, aEncryptionData.getAsConstNamedValueList() );
try {
xDataToCopy = m_xPackageStream->getDataStream();
diff --git a/package/source/xstor/xstorage.cxx b/package/source/xstor/xstorage.cxx
index 3932d10421c4..e3c965e790c3 100644
--- a/package/source/xstor/xstorage.cxx
+++ b/package/source/xstor/xstorage.cxx
@@ -993,7 +993,9 @@ void OStorage_Impl::CopyStorageElement( SotElement_Impl* pElement,
AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Handled exception" ) ) );
// If the common storage password does not allow to open the stream
- // it must be copyed in raw way
+ // it could be copyed in raw way, the problem is that the StartKey should be the same
+ // in the ODF1.2 package, so an invalid package could be produced if the stream
+ // is copied from ODF1.1 package, where it is allowed to have different StartKeys
uno::Reference< embed::XStorageRawAccess > xRawDest( xDest, uno::UNO_QUERY_THROW );
uno::Reference< io::XInputStream > xRawInStream = pElement->m_pStream->GetRawInStream();
xRawDest->insertRawEncrStreamElement( aName, xRawInStream );
@@ -4777,10 +4779,10 @@ void SAL_CALL OStorage::setEncryptionData( const uno::Sequence< beans::NamedValu
m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
uno::Any aCaught( ::cppu::getCaughtException() );
- throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open package!\n" ) ),
- uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
- uno::UNO_QUERY ),
- aCaught );
+ throw lang::WrappedTargetRuntimeException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open package!\n" ) ),
+ uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ),
+ aCaught );
}
uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
@@ -4801,7 +4803,6 @@ void SAL_CALL OStorage::setEncryptionData( const uno::Sequence< beans::NamedValu
throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
}
}
-
}
//____________________________________________________________________________________________________
diff --git a/package/source/zipapi/MemoryByteGrabber.hxx b/package/source/zipapi/MemoryByteGrabber.hxx
index 8a8d96556bae..f27eaf4826ad 100644
--- a/package/source/zipapi/MemoryByteGrabber.hxx
+++ b/package/source/zipapi/MemoryByteGrabber.hxx
@@ -62,7 +62,7 @@ public:
nBytesToRead = mnEnd - mnCurrent;
aData.realloc ( nBytesToRead );
- memcpy ( aData.getArray(), mpBuffer + mnCurrent, nBytesToRead );
+ rtl_copyMemory( aData.getArray(), mpBuffer + mnCurrent, nBytesToRead );
mnCurrent += nBytesToRead;
return nBytesToRead;
}
diff --git a/package/source/zipapi/XUnbufferedStream.cxx b/package/source/zipapi/XUnbufferedStream.cxx
index 67d27468e0c6..e8e16329eccc 100644
--- a/package/source/zipapi/XUnbufferedStream.cxx
+++ b/package/source/zipapi/XUnbufferedStream.cxx
@@ -27,10 +27,13 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_package.hxx"
-#include <XUnbufferedStream.hxx>
-#include <EncryptionData.hxx>
+
#include <com/sun/star/packages/zip/ZipConstants.hpp>
#include <com/sun/star/packages/zip/ZipIOException.hpp>
+#include <com/sun/star/xml/crypto/CipherID.hpp>
+
+#include <XUnbufferedStream.hxx>
+#include <EncryptionData.hxx>
#include <PackageConstants.hxx>
#include <ZipFile.hxx>
#include <EncryptedDataHeader.hxx>
@@ -69,6 +72,7 @@ XUnbufferedStream::XUnbufferedStream(
, mxZipSeek ( xNewZipStream, UNO_QUERY )
, maEntry ( rEntry )
, mxData ( rData )
+, mnBlockSize( 1 )
, maInflater ( sal_True )
, mbRawStream ( nStreamMode == UNBUFF_STREAM_RAW || nStreamMode == UNBUFF_STREAM_WRAPPEDRAW )
, mbWrappedRaw ( nStreamMode == UNBUFF_STREAM_WRAPPEDRAW )
@@ -95,7 +99,11 @@ XUnbufferedStream::XUnbufferedStream(
sal_Bool bMustDecrypt = ( nStreamMode == UNBUFF_STREAM_DATA && bHaveEncryptData && bIsEncrypted ) ? sal_True : sal_False;
if ( bMustDecrypt )
+ {
m_xCipherContext = ZipFile::StaticGetCipher( xFactory, rData, false );
+ mnBlockSize = ( rData->m_nEncAlg == xml::crypto::CipherID::AES_CBC_W3C_PADDING ? 16 : 1 );
+ }
+
if ( bHaveEncryptData && mbWrappedRaw && bIsEncrypted )
{
// if we have the data needed to decrypt it, but didn't want it decrypted (or
@@ -116,13 +124,14 @@ XUnbufferedStream::XUnbufferedStream(
// allows to read package raw stream
XUnbufferedStream::XUnbufferedStream(
- const uno::Reference< lang::XMultiServiceFactory >& xFactory,
+ const uno::Reference< lang::XMultiServiceFactory >& /*xFactory*/,
const Reference < XInputStream >& xRawStream,
const ::rtl::Reference< EncryptionData >& rData )
: maMutexHolder( new SotMutexHolder )
, mxZipStream ( xRawStream )
, mxZipSeek ( xRawStream, UNO_QUERY )
, mxData ( rData )
+, mnBlockSize( 1 )
, maInflater ( sal_True )
, mbRawStream ( sal_False )
, mbWrappedRaw ( sal_False )
@@ -151,7 +160,8 @@ XUnbufferedStream::XUnbufferedStream(
mnZipEnd = mnZipCurrent + mnZipSize;
- m_xCipherContext = ZipFile::StaticGetCipher( xFactory, rData, false );
+ // the raw data will not be decrypted, no need for the cipher
+ // m_xCipherContext = ZipFile::StaticGetCipher( xFactory, rData, false );
}
XUnbufferedStream::~XUnbufferedStream()
@@ -180,7 +190,7 @@ sal_Int32 SAL_CALL XUnbufferedStream::readBytes( Sequence< sal_Int8 >& aData, sa
{
sal_Int16 nHeadRead = static_cast< sal_Int16 >(( nRequestedBytes > mnHeaderToRead ?
mnHeaderToRead : nRequestedBytes ));
- memcpy ( aData.getArray(), maHeader.getConstArray() + maHeader.getLength() - mnHeaderToRead, nHeadRead );
+ rtl_copyMemory ( aData.getArray(), maHeader.getConstArray() + maHeader.getLength() - mnHeaderToRead, nHeadRead );
mnHeaderToRead = mnHeaderToRead - nHeadRead;
if ( nHeadRead < nRequestedBytes )
@@ -242,12 +252,17 @@ sal_Int32 SAL_CALL XUnbufferedStream::readBytes( Sequence< sal_Int8 >& aData, sa
throw ZipIOException( OUString( RTL_CONSTASCII_USTRINGPARAM( "Dictionaries are not supported!" ) ),
Reference< XInterface >() );
- sal_Int32 nDiff = static_cast < sal_Int32 > ( mnZipEnd - mnZipCurrent );
+ sal_Int32 nDiff = static_cast< sal_Int32 >( mnZipEnd - mnZipCurrent );
if ( nDiff > 0 )
{
mxZipSeek->seek ( mnZipCurrent );
- sal_Int32 nToRead = std::min ( nDiff, std::max ( nRequestedBytes, static_cast< sal_Int32 >( 8192 ) ) );
- sal_Int32 nZipRead = mxZipStream->readBytes ( maCompBuffer, nToRead );
+
+ sal_Int32 nToRead = std::max( nRequestedBytes, static_cast< sal_Int32 >( 8192 ) );
+ if ( mnBlockSize > 1 )
+ nToRead = nToRead + mnBlockSize - nToRead % mnBlockSize;
+ nToRead = std::min( nDiff, nToRead );
+
+ sal_Int32 nZipRead = mxZipStream->readBytes( maCompBuffer, nToRead );
if ( nZipRead < nToRead )
throw ZipIOException( OUString( RTL_CONSTASCII_USTRINGPARAM( "No expected data!" ) ),
Reference< XInterface >() );
@@ -268,11 +283,9 @@ sal_Int32 SAL_CALL XUnbufferedStream::readBytes( Sequence< sal_Int8 >& aData, sa
{
sal_Int32 nOldLen = maCompBuffer.getLength();
maCompBuffer.realloc( nOldLen + aSuffix.getLength() );
- memcpy( maCompBuffer.getArray() + nOldLen, aSuffix.getConstArray(), aSuffix.getLength() );
+ rtl_copyMemory( maCompBuffer.getArray() + nOldLen, aSuffix.getConstArray(), aSuffix.getLength() );
}
}
-
- ZipFile::StaticRemoveW3CPadding( mxData, maCompBuffer );
}
maInflater.setInput ( maCompBuffer );
}
diff --git a/package/source/zipapi/XUnbufferedStream.hxx b/package/source/zipapi/XUnbufferedStream.hxx
index f4c6ba250631..f8878c25979a 100644
--- a/package/source/zipapi/XUnbufferedStream.hxx
+++ b/package/source/zipapi/XUnbufferedStream.hxx
@@ -59,6 +59,7 @@ protected:
com::sun::star::uno::Sequence < sal_Int8 > maCompBuffer, maHeader;
ZipEntry maEntry;
::rtl::Reference< EncryptionData > mxData;
+ sal_Int32 mnBlockSize;
::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XCipherContext > m_xCipherContext;
Inflater maInflater;
sal_Bool mbRawStream, mbWrappedRaw, mbFinished;
diff --git a/package/source/zipapi/ZipFile.cxx b/package/source/zipapi/ZipFile.cxx
index 5fbaf7cd025d..03ecc90c17c3 100644
--- a/package/source/zipapi/ZipFile.cxx
+++ b/package/source/zipapi/ZipFile.cxx
@@ -42,7 +42,6 @@
#include <comphelper/processfactory.hxx>
#include <rtl/digest.h>
-#include <string.h> // for memcpy
#include <vector>
#include "blowfishcontext.hxx"
@@ -142,7 +141,7 @@ uno::Reference< xml::crypto::XDigestContext > ZipFile::StaticGetDigestContextFor
xFactory.set( comphelper::getProcessServiceFactory(), uno::UNO_SET_THROW );
uno::Reference< xml::crypto::XDigestContextSupplier > xDigestContextSupplier(
- xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.crypto.SEInitializer" ) ) ),
+ xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.crypto.NSSInitializer" ) ) ),
uno::UNO_QUERY_THROW );
xDigestContext.set( xDigestContextSupplier->getDigestContext( xEncryptionData->m_nCheckAlg, uno::Sequence< beans::NamedValue >() ), uno::UNO_SET_THROW );
@@ -173,14 +172,14 @@ uno::Reference< xml::crypto::XCipherContext > ZipFile::StaticGetCipher( const un
uno::Reference< XInterface >() );
}
- if ( xEncryptionData->m_nEncAlg == xml::crypto::CipherID::AES_CBC )
+ if ( xEncryptionData->m_nEncAlg == xml::crypto::CipherID::AES_CBC_W3C_PADDING )
{
uno::Reference< lang::XMultiServiceFactory > xFactory = xArgFactory;
if ( !xFactory.is() )
xFactory.set( comphelper::getProcessServiceFactory(), uno::UNO_SET_THROW );
uno::Reference< xml::crypto::XCipherContextSupplier > xCipherContextSupplier(
- xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.crypto.SEInitializer" ) ) ),
+ xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.crypto.NSSInitializer" ) ) ),
uno::UNO_QUERY_THROW );
xResult = xCipherContextSupplier->getCipherContext( xEncryptionData->m_nEncAlg, aDerivedKey, xEncryptionData->m_aInitVector, bEncrypt, uno::Sequence< beans::NamedValue >() );
@@ -275,19 +274,19 @@ void ZipFile::StaticFillHeader( const ::rtl::Reference< EncryptionData >& rData,
*(pHeader++) = static_cast< sal_Int8 >(( nMediaTypeLength >> 8 ) & 0xFF);
// Then the salt content
- memcpy ( pHeader, rData->m_aSalt.getConstArray(), nSaltLength );
+ rtl_copyMemory ( pHeader, rData->m_aSalt.getConstArray(), nSaltLength );
pHeader += nSaltLength;
// Then the IV content
- memcpy ( pHeader, rData->m_aInitVector.getConstArray(), nIVLength );
+ rtl_copyMemory ( pHeader, rData->m_aInitVector.getConstArray(), nIVLength );
pHeader += nIVLength;
// Then the digest content
- memcpy ( pHeader, rData->m_aDigest.getConstArray(), nDigestLength );
+ rtl_copyMemory ( pHeader, rData->m_aDigest.getConstArray(), nDigestLength );
pHeader += nDigestLength;
// Then the mediatype itself
- memcpy ( pHeader, aMediaType.getStr(), nMediaTypeLength );
+ rtl_copyMemory ( pHeader, aMediaType.getStr(), nMediaTypeLength );
pHeader += nMediaTypeLength;
}
@@ -349,15 +348,15 @@ sal_Bool ZipFile::StaticFillData ( ::rtl::Reference< BaseEncryptionData > & rDa
if ( nSaltLength == rStream->readBytes ( aBuffer, nSaltLength ) )
{
rData->m_aSalt.realloc ( nSaltLength );
- memcpy ( rData->m_aSalt.getArray(), aBuffer.getConstArray(), nSaltLength );
+ rtl_copyMemory ( rData->m_aSalt.getArray(), aBuffer.getConstArray(), nSaltLength );
if ( nIVLength == rStream->readBytes ( aBuffer, nIVLength ) )
{
rData->m_aInitVector.realloc ( nIVLength );
- memcpy ( rData->m_aInitVector.getArray(), aBuffer.getConstArray(), nIVLength );
+ rtl_copyMemory ( rData->m_aInitVector.getArray(), aBuffer.getConstArray(), nIVLength );
if ( nDigestLength == rStream->readBytes ( aBuffer, nDigestLength ) )
{
rData->m_aDigest.realloc ( nDigestLength );
- memcpy ( rData->m_aDigest.getArray(), aBuffer.getConstArray(), nDigestLength );
+ rtl_copyMemory ( rData->m_aDigest.getArray(), aBuffer.getConstArray(), nDigestLength );
if ( nMediaTypeLength == rStream->readBytes ( aBuffer, nMediaTypeLength ) )
{
@@ -396,8 +395,9 @@ uno::Reference< XInputStream > ZipFile::StaticGetDataFromRawStream( const uno::R
OSL_ENSURE( rData->m_aDigest.getLength(), "Can't detect password correctness without digest!\n" );
if ( rData->m_aDigest.getLength() )
{
- sal_Int32 nSize = sal::static_int_cast< sal_Int32 >( xSeek->getLength() );
- nSize = nSize > n_ConstDigestLength ? n_ConstDigestLength : nSize;
+ sal_Int32 nSize = sal::static_int_cast< sal_Int32 >( xSeek->getLength() );
+ if ( nSize > n_ConstDigestLength + 32 )
+ nSize = n_ConstDigestLength + 32;
// skip header
xSeek->seek( n_ConstHeaderSize + rData->m_aInitVector.getLength() +
@@ -415,44 +415,38 @@ uno::Reference< XInputStream > ZipFile::StaticGetDataFromRawStream( const uno::R
return new XUnbufferedStream( xFactory, xStream, rData );
}
-void ZipFile::StaticRemoveW3CPadding( const ::rtl::Reference< EncryptionData >& rEncData, uno::Sequence< sal_Int8 >& o_rPaddedData )
-{
- sal_Int32 nPaddedDataLen = o_rPaddedData.getLength();
- if ( rEncData->m_nEncAlg == xml::crypto::CipherID::AES_CBC )
- {
- if ( nPaddedDataLen > AES_CBC_BLOCK_SIZE
- && nPaddedDataLen % AES_CBC_BLOCK_SIZE == 1
- && o_rPaddedData[ nPaddedDataLen - 1 ] <= AES_CBC_BLOCK_SIZE )
- {
- o_rPaddedData.realloc( nPaddedDataLen - AES_CBC_BLOCK_SIZE + o_rPaddedData[nPaddedDataLen - 1] );
- }
- else
- {
- OSL_ENSURE( sal_False, "No expected padding is found!" );
- }
- }
-}
-
sal_Bool ZipFile::StaticHasValidPassword( const uno::Reference< lang::XMultiServiceFactory >& xFactory, const Sequence< sal_Int8 > &aReadBuffer, const ::rtl::Reference< EncryptionData > &rData )
{
if ( !rData.is() || !rData->m_aKey.getLength() )
return sal_False;
sal_Bool bRet = sal_False;
- sal_Int32 nSize = aReadBuffer.getLength();
uno::Reference< xml::crypto::XCipherContext > xCipher( StaticGetCipher( xFactory, rData, false ), uno::UNO_SET_THROW );
- uno::Sequence< sal_Int8 > aDecryptBuffer = xCipher->convertWithCipherContext( aReadBuffer );
- uno::Sequence< sal_Int8 > aDecryptBuffer2 = xCipher->finalizeCipherContextAndDispose();
+ uno::Sequence< sal_Int8 > aDecryptBuffer;
+ uno::Sequence< sal_Int8 > aDecryptBuffer2;
+ try
+ {
+ aDecryptBuffer = xCipher->convertWithCipherContext( aReadBuffer );
+ aDecryptBuffer2 = xCipher->finalizeCipherContextAndDispose();
+ }
+ catch( uno::Exception& )
+ {
+ // decryption with padding will throw the exception in finalizing if the buffer represent only part of the stream
+ // it is no problem, actually this is why we read 32 additional bytes ( two of maximal possible encryption blocks )
+ OSL_ENSURE( aReadBuffer.getLength() == n_ConstDigestDecrypt, "Unexpected exception by decryption!" );
+ }
+
if ( aDecryptBuffer2.getLength() )
{
sal_Int32 nOldLen = aDecryptBuffer.getLength();
aDecryptBuffer.realloc( nOldLen + aDecryptBuffer2.getLength() );
- memcpy( aDecryptBuffer.getArray() + nOldLen, aDecryptBuffer2.getArray(), aDecryptBuffer2.getLength() );
+ rtl_copyMemory( aDecryptBuffer.getArray() + nOldLen, aDecryptBuffer2.getArray(), aDecryptBuffer2.getLength() );
}
- StaticRemoveW3CPadding( rData, aDecryptBuffer );
+ if ( aDecryptBuffer.getLength() > n_ConstDigestLength )
+ aDecryptBuffer.realloc( n_ConstDigestLength );
uno::Sequence< sal_Int8 > aDigestSeq;
uno::Reference< xml::crypto::XDigestContext > xDigestContext( StaticGetDigestContextForChecksum( xFactory, rData ), uno::UNO_SET_THROW );
@@ -486,7 +480,9 @@ sal_Bool ZipFile::hasValidPassword ( ZipEntry & rEntry, const ::rtl::Reference<
sal_Int32 nSize = rEntry.nMethod == DEFLATED ? rEntry.nCompressedSize : rEntry.nSize;
// Only want to read enough to verify the digest
- nSize = nSize > n_ConstDigestLength ? n_ConstDigestLength : nSize;
+ if ( nSize > n_ConstDigestDecrypt )
+ nSize = n_ConstDigestDecrypt;
+
Sequence < sal_Int8 > aReadBuffer ( nSize );
xStream->readBytes( aReadBuffer, nSize );
diff --git a/package/source/zipapi/ZipOutputStream.cxx b/package/source/zipapi/ZipOutputStream.cxx
index 8c70558e918d..172cfff463a2 100644
--- a/package/source/zipapi/ZipOutputStream.cxx
+++ b/package/source/zipapi/ZipOutputStream.cxx
@@ -55,7 +55,7 @@ ZipOutputStream::ZipOutputStream( const uno::Reference< lang::XMultiServiceFacto
const uno::Reference < XOutputStream > &xOStream )
: m_xFactory( xFactory )
, xStream(xOStream)
-, aBuffer(n_ConstBufferSize)
+, m_aDeflateBuffer(n_ConstBufferSize)
, aDeflater(DEFAULT_COMPRESSION, sal_True)
, aChucker(xOStream)
, pCurrentEntry(NULL)
@@ -98,7 +98,10 @@ void SAL_CALL ZipOutputStream::putNextEntry( ZipEntry& rEntry,
rEntry.nFlag = 1 << 11;
if (rEntry.nSize == -1 || rEntry.nCompressedSize == -1 ||
rEntry.nCrc == -1)
+ {
+ rEntry.nSize = rEntry.nCompressedSize = 0;
rEntry.nFlag |= 8;
+ }
if (bEncrypt)
{
@@ -148,11 +151,12 @@ void SAL_CALL ZipOutputStream::closeEntry( )
}
else
{
- pEntry->nSize = aDeflater.getTotalIn();
- pEntry->nCompressedSize = aDeflater.getTotalOut();
+ if ( !bEncryptCurrentEntry )
+ {
+ pEntry->nSize = aDeflater.getTotalIn();
+ pEntry->nCompressedSize = aDeflater.getTotalOut();
+ }
pEntry->nCrc = aCRC.getValue();
- if ( bEncryptCurrentEntry )
- pEntry->nSize = pEntry->nCompressedSize;
writeEXT(*pEntry);
}
aDeflater.reset();
@@ -249,12 +253,12 @@ void SAL_CALL ZipOutputStream::finish( )
void ZipOutputStream::doDeflate()
{
- sal_Int32 nLength = aDeflater.doDeflateSegment(aBuffer, 0, aBuffer.getLength());
- sal_Int32 nOldLength = aBuffer.getLength();
+ sal_Int32 nLength = aDeflater.doDeflateSegment(m_aDeflateBuffer, 0, m_aDeflateBuffer.getLength());
+ sal_Int32 nOldLength = m_aDeflateBuffer.getLength();
if ( nLength > 0 )
{
- uno::Sequence< sal_Int8 > aTmpBuffer( aBuffer.getConstArray(), nLength );
+ uno::Sequence< sal_Int8 > aTmpBuffer( m_aDeflateBuffer.getConstArray(), nLength );
if ( bEncryptCurrentEntry && m_xDigestContext.is() && m_xCipherContext.is() )
{
// Need to update our digest before encryption...
@@ -270,10 +274,16 @@ void ZipOutputStream::doDeflate()
uno::Sequence< sal_Int8 > aEncryptionBuffer = m_xCipherContext->convertWithCipherContext( aTmpBuffer );
aChucker.WriteBytes( aEncryptionBuffer );
+
+ // the sizes as well as checksum for encrypted streams is calculated here
+ pCurrentEntry->nCompressedSize += aEncryptionBuffer.getLength();
+ pCurrentEntry->nSize = pCurrentEntry->nCompressedSize;
aCRC.update( aEncryptionBuffer );
}
else
+ {
aChucker.WriteBytes ( aTmpBuffer );
+ }
}
if ( aDeflater.finished() && bEncryptCurrentEntry && m_xDigestContext.is() && m_xCipherContext.is() )
@@ -282,6 +292,10 @@ void ZipOutputStream::doDeflate()
if ( aEncryptionBuffer.getLength() )
{
aChucker.WriteBytes( aEncryptionBuffer );
+
+ // the sizes as well as checksum for encrypted streams is calculated hier
+ pCurrentEntry->nCompressedSize += aEncryptionBuffer.getLength();
+ pCurrentEntry->nSize = pCurrentEntry->nCompressedSize;
aCRC.update( aEncryptionBuffer );
}
}
diff --git a/package/source/zipapi/blowfishcontext.cxx b/package/source/zipapi/blowfishcontext.cxx
index 479497d25a7d..bd6605e2e6e5 100644
--- a/package/source/zipapi/blowfishcontext.cxx
+++ b/package/source/zipapi/blowfishcontext.cxx
@@ -53,6 +53,8 @@ uno::Reference< xml::crypto::XCipherContext > BlowfishCFB8CipherContext::Create(
uno::Reference< XInterface >() );
}
+ xResult->m_bEncrypt = bEncrypt;
+
return uno::Reference< xml::crypto::XCipherContext >( xResult.get() );
}
@@ -73,11 +75,26 @@ uno::Sequence< sal_Int8 > SAL_CALL BlowfishCFB8CipherContext::convertWithCipherC
throw lang::DisposedException();
uno::Sequence< sal_Int8 > aResult( aData.getLength() );
- if ( rtl_Cipher_E_None != rtl_cipher_decode( m_pCipher,
- aData.getConstArray(),
- aData.getLength(),
- reinterpret_cast< sal_uInt8* >( aResult.getArray() ),
- aResult.getLength() ) )
+ rtlCipherError nError = rtl_Cipher_E_None;
+
+ if ( m_bEncrypt )
+ {
+ rtl_cipher_encode( m_pCipher,
+ aData.getConstArray(),
+ aData.getLength(),
+ reinterpret_cast< sal_uInt8* >( aResult.getArray() ),
+ aResult.getLength() );
+ }
+ else
+ {
+ rtl_cipher_decode( m_pCipher,
+ aData.getConstArray(),
+ aData.getLength(),
+ reinterpret_cast< sal_uInt8* >( aResult.getArray() ),
+ aResult.getLength() );
+ }
+
+ if ( rtl_Cipher_E_None != nError )
{
throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "Can not decrypt/encrypt with cipher!\n" ),
uno::Reference< uno::XInterface >() );
diff --git a/package/source/zipapi/blowfishcontext.hxx b/package/source/zipapi/blowfishcontext.hxx
index 4ac75fce2230..49cce2fc0e65 100644
--- a/package/source/zipapi/blowfishcontext.hxx
+++ b/package/source/zipapi/blowfishcontext.hxx
@@ -36,9 +36,11 @@ class BlowfishCFB8CipherContext : public cppu::WeakImplHelper1< ::com::sun::star
{
::osl::Mutex m_aMutex;
void* m_pCipher;
+ bool m_bEncrypt;
BlowfishCFB8CipherContext()
: m_pCipher( NULL )
+ , m_bEncrypt( false )
{}
public:
diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx
index 79848d7e30f4..4b572df03c2f 100644
--- a/package/source/zippackage/ZipPackage.cxx
+++ b/package/source/zippackage/ZipPackage.cxx
@@ -182,7 +182,6 @@ class DummyInputStream : public ::cppu::WeakImplHelper1< XInputStream >
ZipPackage::ZipPackage ( const uno::Reference < XMultiServiceFactory > &xNewFactory )
: m_aMutexHolder( new SotMutexHolder )
-, m_bStartKeyGenerationImported( false )
, m_nStartKeyGenerationID( xml::crypto::DigestID::SHA1 )
, m_nChecksumDigestID( xml::crypto::DigestID::SHA1_1K )
, m_nCommonEncryptionID( xml::crypto::CipherID::BLOWFISH_CFB_8 )
@@ -218,6 +217,8 @@ void ZipPackage::parseManifest()
if ( m_nFormat == embed::StorageFormats::PACKAGE )
{
sal_Bool bManifestParsed = sal_False;
+ bool bStartKeyGenerationImported = false;
+ bool bDifferentStartKeyAlgorithm = false;
const OUString sMeta ( RTL_CONSTASCII_USTRINGPARAM ( "META-INF" ) );
if ( m_xRootFolder->hasByName( sMeta ) )
{
@@ -333,11 +334,9 @@ void ZipPackage::parseManifest()
*pDigestAlg >>= nDigestAlg;
pStream->SetImportedChecksumAlgorithm( nDigestAlg );
- m_nChecksumDigestID = nDigestAlg;
*pEncryptionAlg >>= nEncryptionAlg;
pStream->SetImportedEncryptionAlgorithm( nEncryptionAlg );
- m_nCommonEncryptionID = nEncryptionAlg;
if ( pDerivedKeySize )
*pDerivedKeySize >>= nDerivedKeySize;
@@ -345,18 +344,19 @@ void ZipPackage::parseManifest()
if ( pStartKeyAlg )
*pStartKeyAlg >>= nStartKeyAlg;
- if ( nStartKeyAlg != m_nStartKeyGenerationID && m_bStartKeyGenerationImported )
- throw ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "More than one Start Key Generation algorithm is specified!" ) ), uno::Reference< uno::XInterface >() );
- m_nStartKeyGenerationID = nStartKeyAlg;
- m_bStartKeyGenerationImported = true;
-
+ pStream->SetImportedStartKeyAlgorithm( nStartKeyAlg );
pStream->SetToBeCompressed ( sal_True );
pStream->SetToBeEncrypted ( sal_True );
pStream->SetIsEncrypted ( sal_True );
if ( !m_bHasEncryptedEntries
&& pStream->getName().equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "content.xml" ) ) ) )
+ {
m_bHasEncryptedEntries = sal_True;
+ m_nStartKeyGenerationID = nStartKeyAlg;
+ m_nChecksumDigestID = nDigestAlg;
+ m_nCommonEncryptionID = nEncryptionAlg;
+ }
}
else
m_bHasNonEncryptedEntries = sal_True;
@@ -435,20 +435,30 @@ void ZipPackage::parseManifest()
m_bInconsistent = m_pRootFolder->LookForUnexpectedODF12Streams( ::rtl::OUString() );
- sal_Bool bODF12AndOlder = ( m_pRootFolder->GetVersion().compareTo( ODFVER_012_TEXT ) >= 0 );
- if ( !m_bForceRecovery && bODF12AndOlder && m_bInconsistent )
+ sal_Bool bODF12AndNewer = ( m_pRootFolder->GetVersion().compareTo( ODFVER_012_TEXT ) >= 0 );
+ if ( !m_bForceRecovery && bODF12AndNewer )
{
- // this is an ODF1.2 document that contains streams not referred in the manifest.xml;
- // in case of ODF1.2 documents without version in manifest.xml the property IsInconsistent
- // should be checked later
- throw ZipIOException(
- ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "there are streams not referred in manifest.xml\n" ) ),
- uno::Reference< uno::XInterface >() );
+ if ( m_bInconsistent )
+ {
+ // this is an ODF1.2 document that contains streams not referred in the manifest.xml;
+ // in case of ODF1.2 documents without version in manifest.xml the property IsInconsistent
+ // should be checked later
+ throw ZipIOException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "there are streams not referred in manifest.xml\n" ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+ else if ( bDifferentStartKeyAlgorithm )
+ {
+ // all the streams should be encrypted with the same StartKey in ODF1.2
+ // TODO/LATER: in future the exception should be thrown
+ OSL_ENSURE( false, "ODF1.2 contains different StartKey Algorithms" );
+ // throw ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "More than one Start Key Generation algorithm is specified!" ) ), uno::Reference< uno::XInterface >() );
+ }
}
// in case it is a correct ODF1.2 document, the version must be set
// and the META-INF folder is reserved for package format
- if ( bODF12AndOlder )
+ if ( bODF12AndNewer )
m_xRootFolder->removeByName( sMeta );
}
}
@@ -1017,7 +1027,6 @@ void ZipPackage::WriteMimetypeMagicFile( ZipOutputStream& aZipOut )
}
catch ( ::com::sun::star::io::IOException & r )
{
- VOS_ENSURE( 0, "Error adding mimetype to the ZipOutputStream" );
throw WrappedTargetException(
OUString( RTL_CONSTASCII_USTRINGPARAM ( OSL_LOG_PREFIX "Error adding mimetype to the ZipOutputStream!" ) ),
static_cast < OWeakObject * > ( this ),
@@ -1045,11 +1054,13 @@ void ZipPackage::WriteManifest( ZipOutputStream& aZipOut, const vector< Sequence
// Convert vector into a Sequence
Sequence < Sequence < PropertyValue > > aManifestSequence ( aManList.size() );
- Sequence < PropertyValue > * pSequence = aManifestSequence.getArray();
+ sal_Int32 nInd = 0;
for ( vector < Sequence < PropertyValue > >::const_iterator aIter = aManList.begin(), aEnd = aManList.end();
aIter != aEnd;
- aIter++, pSequence++ )
- *pSequence= ( *aIter );
+ aIter++, nInd++ )
+ {
+ aManifestSequence[nInd] = ( *aIter );
+ }
xWriter->writeManifestSequence ( xManOutStream, aManifestSequence );
sal_Int32 nBufferLength = static_cast < sal_Int32 > ( pBuffer->getPosition() );
@@ -1233,7 +1244,7 @@ uno::Reference< io::XInputStream > ZipPackage::writeTempFile()
if ( m_nFormat == embed::StorageFormats::PACKAGE )
{
- Sequence < PropertyValue > aPropSeq ( PKG_SIZE_NOENCR_MNFST );
+ Sequence < PropertyValue > aPropSeq( PKG_SIZE_NOENCR_MNFST );
aPropSeq [PKG_MNFST_MEDIATYPE].Name = sMediaType;
aPropSeq [PKG_MNFST_MEDIATYPE].Value <<= m_pRootFolder->GetMediaType();
aPropSeq [PKG_MNFST_VERSION].Name = sVersion;
@@ -1779,7 +1790,7 @@ void SAL_CALL ZipPackage::setPropertyValue( const OUString& aPropertyName, const
{
sal_Int32 nID = 0;
if ( !( aAlgorithms[nInd].Value >>= nID )
- || ( nID != xml::crypto::CipherID::AES_CBC && nID != xml::crypto::CipherID::BLOWFISH_CFB_8 ) )
+ || ( nID != xml::crypto::CipherID::AES_CBC_W3C_PADDING && nID != xml::crypto::CipherID::BLOWFISH_CFB_8 ) )
throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected start key generation algorithm is provided!" ) ), uno::Reference< uno::XInterface >(), 2 );
m_nCommonEncryptionID = nID;
diff --git a/package/source/zippackage/ZipPackageFolder.cxx b/package/source/zippackage/ZipPackageFolder.cxx
index d964aab6fe3e..bc8fa227b8af 100644
--- a/package/source/zippackage/ZipPackageFolder.cxx
+++ b/package/source/zippackage/ZipPackageFolder.cxx
@@ -358,7 +358,7 @@ void ZipPackageFolder::saveContents( ::rtl::OUString &rPath, std::vector < uno::
const ::rtl::OUString &rShortName = (*aCI).first;
const ContentInfo &rInfo = *(*aCI).second;
- uno::Sequence < PropertyValue > aPropSet (PKG_SIZE_NOENCR_MNFST);
+ uno::Sequence < PropertyValue > aPropSet( PKG_SIZE_NOENCR_MNFST );
if ( rInfo.bFolder )
pFolder = rInfo.pFolder;
@@ -510,9 +510,10 @@ void ZipPackageFolder::saveContents( ::rtl::OUString &rPath, std::vector < uno::
{
if ( bToBeEncrypted && !bTransportOwnEncrStreamAsRaw )
{
- uno::Sequence < sal_Int8 > aSalt ( 16 ), aVector ( 8 );
+ sal_Int32 nVectorLen = pStream->GetBlockSize();
+ uno::Sequence < sal_Int8 > aSalt ( 16 ), aVector ( nVectorLen );
rtl_random_getBytes ( rRandomPool, aSalt.getArray(), 16 );
- rtl_random_getBytes ( rRandomPool, aVector.getArray(), 8 );
+ rtl_random_getBytes ( rRandomPool, aVector.getArray(), nVectorLen );
sal_Int32 nIterationCount = 1024;
if ( !pStream->HasOwnKey() )
@@ -525,7 +526,7 @@ void ZipPackageFolder::saveContents( ::rtl::OUString &rPath, std::vector < uno::
// last property is digest, which is inserted later if we didn't have
// a magic header
- aPropSet.realloc(PKG_SIZE_ENCR_MNFST);
+ aPropSet.realloc( PKG_SIZE_ENCR_MNFST );
aPropSet[PKG_MNFST_INIVECTOR].Name = sInitialisationVectorProperty;
aPropSet[PKG_MNFST_INIVECTOR].Value <<= pStream->getInitialisationVector();
@@ -550,7 +551,7 @@ void ZipPackageFolder::saveContents( ::rtl::OUString &rPath, std::vector < uno::
aPropSet[PKG_MNFST_ENCALG].Value <<= xEncData->m_nEncAlg;
aPropSet[PKG_MNFST_STARTALG].Name = sStartKeyAlgProperty;
aPropSet[PKG_MNFST_STARTALG].Value <<= pStream->GetKeyGenID();
- aPropSet[PKG_MNFST_DIGESTALG].Name = sDigestProperty;
+ aPropSet[PKG_MNFST_DIGESTALG].Name = sDigestAlgProperty;
aPropSet[PKG_MNFST_DIGESTALG].Value <<= xEncData->m_nCheckAlg;
aPropSet[PKG_MNFST_DERKEYSIZE].Name = sDerivedKeySizeProperty;
aPropSet[PKG_MNFST_DERKEYSIZE].Value <<= xEncData->m_nDerivedKeySize;
@@ -660,12 +661,10 @@ void ZipPackageFolder::saveContents( ::rtl::OUString &rPath, std::vector < uno::
}
catch ( ZipException& )
{
- VOS_ENSURE( 0, "Error writing ZipOutputStream" );
bWritingFailed = sal_True;
}
catch ( IOException& )
{
- VOS_ENSURE( 0, "Error writing ZipOutputStream" );
bWritingFailed = sal_True;
}
@@ -680,7 +679,7 @@ void ZipPackageFolder::saveContents( ::rtl::OUString &rPath, std::vector < uno::
aPropSet[PKG_MNFST_ENCALG].Value <<= xEncData->m_nEncAlg;
aPropSet[PKG_MNFST_STARTALG].Name = sStartKeyAlgProperty;
aPropSet[PKG_MNFST_STARTALG].Value <<= pStream->GetKeyGenID();
- aPropSet[PKG_MNFST_DIGESTALG].Name = sDigestProperty;
+ aPropSet[PKG_MNFST_DIGESTALG].Name = sDigestAlgProperty;
aPropSet[PKG_MNFST_DIGESTALG].Value <<= xEncData->m_nCheckAlg;
aPropSet[PKG_MNFST_DERKEYSIZE].Name = sDerivedKeySizeProperty;
aPropSet[PKG_MNFST_DERKEYSIZE].Value <<= xEncData->m_nDerivedKeySize;
diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx
index 077a29adf91f..5ae56872e252 100644
--- a/package/source/zippackage/ZipPackageStream.cxx
+++ b/package/source/zippackage/ZipPackageStream.cxx
@@ -76,8 +76,10 @@ ZipPackageStream::ZipPackageStream ( ZipPackage & rNewPackage,
, bToBeEncrypted ( sal_False )
, bHaveOwnKey ( sal_False )
, bIsEncrypted ( sal_False )
+, m_nImportedStartKeyAlgorithm( 0 )
, m_nImportedEncryptionAlgorithm( 0 )
, m_nImportedChecksumAlgorithm( 0 )
+, m_nImportedDerivedKeySize( 0 )
, m_nStreamMode( PACKAGE_STREAM_NOTSET )
, m_nMagicalHackPos( 0 )
, m_nMagicalHackSize( 0 )
@@ -141,7 +143,7 @@ void ZipPackageStream::CloseOwnStreamIfAny()
}
//--------------------------------------------------------------------------
-uno::Reference< io::XInputStream >& ZipPackageStream::GetOwnSeekStream()
+uno::Reference< io::XInputStream > ZipPackageStream::GetOwnSeekStream()
{
if ( !m_bHasSeekable && xStream.is() )
{
@@ -198,6 +200,18 @@ uno::Reference< io::XInputStream > ZipPackageStream::GetRawEncrStreamNoHeaderCop
}
//--------------------------------------------------------------------------
+sal_Int32 ZipPackageStream::GetEncryptionAlgorithm() const
+{
+ return m_nImportedEncryptionAlgorithm ? m_nImportedEncryptionAlgorithm : rZipPackage.GetEncAlgID();
+}
+
+//--------------------------------------------------------------------------
+sal_Int32 ZipPackageStream::GetBlockSize() const
+{
+ return GetEncryptionAlgorithm() == ::com::sun::star::xml::crypto::CipherID::AES_CBC_W3C_PADDING ? 16 : 8;
+}
+
+//--------------------------------------------------------------------------
::rtl::Reference< EncryptionData > ZipPackageStream::GetEncryptionData( bool bUseWinEncoding )
{
::rtl::Reference< EncryptionData > xResult;
@@ -205,7 +219,7 @@ uno::Reference< io::XInputStream > ZipPackageStream::GetRawEncrStreamNoHeaderCop
xResult = new EncryptionData(
*m_xBaseEncryptionData,
GetEncryptionKey( bUseWinEncoding ),
- m_nImportedEncryptionAlgorithm ? m_nImportedEncryptionAlgorithm : rZipPackage.GetEncAlgID(),
+ GetEncryptionAlgorithm(),
m_nImportedChecksumAlgorithm ? m_nImportedChecksumAlgorithm : rZipPackage.GetChecksumAlgID(),
m_nImportedDerivedKeySize ? m_nImportedDerivedKeySize : rZipPackage.GetDefaultDerivedKeySize() );
@@ -222,7 +236,7 @@ void ZipPackageStream::SetBaseEncryptionData( const ::rtl::Reference< BaseEncryp
uno::Sequence< sal_Int8 > ZipPackageStream::GetEncryptionKey( bool bUseWinEncoding )
{
uno::Sequence< sal_Int8 > aResult;
- sal_Int32 nKeyGenID = rZipPackage.GetKeyGenID();
+ sal_Int32 nKeyGenID = m_nImportedStartKeyAlgorithm ? m_nImportedStartKeyAlgorithm : rZipPackage.GetKeyGenID();
bUseWinEncoding = ( bUseWinEncoding || m_bUseWinEncoding );
if ( bHaveOwnKey && m_aStorageEncryptionKeys.getLength() )
@@ -886,6 +900,11 @@ Any SAL_CALL ZipPackageStream::getPropertyValue( const OUString& PropertyName )
aAny <<= m_aEncryptionKey;
return aAny;
}
+ else if ( PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( STORAGE_ENCRYPTION_KEYS_PROPERTY ) ) )
+ {
+ aAny <<= m_aStorageEncryptionKeys;
+ return aAny;
+ }
else
throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
}