diff options
Diffstat (limited to 'package')
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 >() ); } |