diff options
Diffstat (limited to 'package/source/zippackage/ZipPackageStream.cxx')
-rw-r--r-- | package/source/zippackage/ZipPackageStream.cxx | 406 |
1 files changed, 274 insertions, 132 deletions
diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx index 06a4413492c1..06dc3edf82dd 100644 --- a/package/source/zippackage/ZipPackageStream.cxx +++ b/package/source/zippackage/ZipPackageStream.cxx @@ -17,7 +17,7 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). + * ( a copy is included in the LICENSE file that accompanied this code ). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see @@ -26,7 +26,7 @@ * ************************************************************************/ -// MARKER(update_precomp.py): autogen include statement, do not remove +// MARKER( update_precomp.py ): autogen include statement, do not remove #include "precompiled_package.hxx" #include <com/sun/star/packages/zip/ZipConstants.hpp> #include <com/sun/star/embed/StorageFormats.hpp> @@ -35,6 +35,8 @@ #include <com/sun/star/io/XOutputStream.hpp> #include <com/sun/star/io/XStream.hpp> #include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/xml/crypto/DigestID.hpp> +#include <com/sun/star/xml/crypto/CipherID.hpp> #include <ZipPackageStream.hxx> @@ -67,21 +69,25 @@ const ::com::sun::star::uno::Sequence < sal_Int8 >& ZipPackageStream::static_get } ZipPackageStream::ZipPackageStream ( ZipPackage & rNewPackage, - const Reference< XMultiServiceFactory >& xFactory, + const uno::Reference< XMultiServiceFactory >& xFactory, sal_Bool bAllowRemoveOnInsert ) : m_xFactory( xFactory ) -, rZipPackage(rNewPackage) +, rZipPackage( rNewPackage ) , bToBeCompressed ( sal_True ) , bToBeEncrypted ( sal_False ) , bHaveOwnKey ( sal_False ) , bIsEncrypted ( sal_False ) -, xEncryptionData ( ) +, m_nImportedStartKeyAlgorithm( 0 ) +, m_nImportedEncryptionAlgorithm( 0 ) +, m_nImportedChecksumAlgorithm( 0 ) +, m_nImportedDerivedKeySize( 0 ) , m_nStreamMode( PACKAGE_STREAM_NOTSET ) , m_nMagicalHackPos( 0 ) , m_nMagicalHackSize( 0 ) , m_bHasSeekable( sal_False ) , m_bCompressedIsSetFromOutside( sal_False ) , m_bFromManifest( sal_False ) +, m_bUseWinEncoding( false ) { OSL_ENSURE( m_xFactory.is(), "No factory is provided to ZipPackageStream!\n" ); @@ -108,7 +114,7 @@ ZipPackageStream::~ZipPackageStream( void ) { } -void ZipPackageStream::setZipEntryOnLoading( const ZipEntry &rInEntry) +void ZipPackageStream::setZipEntryOnLoading( const ZipEntry &rInEntry ) { aEntry.nVersion = rInEntry.nVersion; aEntry.nFlag = rInEntry.nFlag; @@ -138,7 +144,7 @@ void ZipPackageStream::CloseOwnStreamIfAny() } //-------------------------------------------------------------------------- -uno::Reference< io::XInputStream >& ZipPackageStream::GetOwnSeekStream() +uno::Reference< io::XInputStream > ZipPackageStream::GetOwnSeekStream() { if ( !m_bHasSeekable && xStream.is() ) { @@ -147,10 +153,10 @@ uno::Reference< io::XInputStream >& ZipPackageStream::GetOwnSeekStream() // is accessed before commit it MUST be wrapped. // Wrap the stream in case it is not seekable xStream = ::comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( xStream, m_xFactory ); - Reference< io::XSeekable > xSeek( xStream, UNO_QUERY ); + uno::Reference< io::XSeekable > xSeek( xStream, UNO_QUERY ); if ( !xSeek.is() ) throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "The stream must support XSeekable!" ) ), - Reference< XInterface >() ); + uno::Reference< XInterface >() ); m_bHasSeekable = sal_True; } @@ -164,18 +170,18 @@ uno::Reference< io::XInputStream > ZipPackageStream::GetRawEncrStreamNoHeaderCop if ( m_nStreamMode != PACKAGE_STREAM_RAW || !GetOwnSeekStream().is() ) throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); - if ( !xEncryptionData.is() ) + if ( m_xBaseEncryptionData.is() ) throw ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Encrypted stream without encryption data!\n" ) ), - Reference< XInterface >() ); + uno::Reference< XInterface >() ); uno::Reference< io::XSeekable > xSeek( GetOwnSeekStream(), UNO_QUERY ); if ( !xSeek.is() ) throw ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "The stream must be seekable!\n" ) ), - Reference< XInterface >() ); + uno::Reference< XInterface >() ); // skip header - xSeek->seek( n_ConstHeaderSize + xEncryptionData->aInitVector.getLength() + - xEncryptionData->aSalt.getLength() + xEncryptionData->aDigest.getLength() ); + xSeek->seek( n_ConstHeaderSize + getInitialisationVector().getLength() + + getSalt().getLength() + getDigest().getLength() ); // create temporary stream uno::Reference < io::XOutputStream > xTempOut( @@ -195,17 +201,95 @@ uno::Reference< io::XInputStream > ZipPackageStream::GetRawEncrStreamNoHeaderCop } //-------------------------------------------------------------------------- -Reference< io::XInputStream > ZipPackageStream::TryToGetRawFromDataStream( sal_Bool bAddHeaderForEncr ) +sal_Int32 ZipPackageStream::GetEncryptionAlgorithm() const { - if ( m_nStreamMode != PACKAGE_STREAM_DATA || !GetOwnSeekStream().is() || (bAddHeaderForEncr && !bToBeEncrypted) ) + 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; + if ( m_xBaseEncryptionData.is() ) + xResult = new EncryptionData( + *m_xBaseEncryptionData, + GetEncryptionKey( bUseWinEncoding ), + GetEncryptionAlgorithm(), + m_nImportedChecksumAlgorithm ? m_nImportedChecksumAlgorithm : rZipPackage.GetChecksumAlgID(), + m_nImportedDerivedKeySize ? m_nImportedDerivedKeySize : rZipPackage.GetDefaultDerivedKeySize(), + GetStartKeyGenID() ); + + return xResult; +} + +//-------------------------------------------------------------------------- +void ZipPackageStream::SetBaseEncryptionData( const ::rtl::Reference< BaseEncryptionData >& xData ) +{ + m_xBaseEncryptionData = xData; +} + +//-------------------------------------------------------------------------- +uno::Sequence< sal_Int8 > ZipPackageStream::GetEncryptionKey( bool bUseWinEncoding ) +{ + uno::Sequence< sal_Int8 > aResult; + sal_Int32 nKeyGenID = GetStartKeyGenID(); + bUseWinEncoding = ( bUseWinEncoding || m_bUseWinEncoding ); + + if ( bHaveOwnKey && m_aStorageEncryptionKeys.getLength() ) + { + ::rtl::OUString aNameToFind; + if ( nKeyGenID == xml::crypto::DigestID::SHA256 ) + aNameToFind = PACKAGE_ENCRYPTIONDATA_SHA256UTF8; + else if ( nKeyGenID == xml::crypto::DigestID::SHA1 ) + { + aNameToFind = bUseWinEncoding ? PACKAGE_ENCRYPTIONDATA_SHA1MS1252 : PACKAGE_ENCRYPTIONDATA_SHA1UTF8; + } + else + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No expected key is provided!" ) ), uno::Reference< uno::XInterface >() ); + + for ( sal_Int32 nInd = 0; nInd < m_aStorageEncryptionKeys.getLength(); nInd++ ) + if ( m_aStorageEncryptionKeys[nInd].Name.equals( aNameToFind ) ) + m_aStorageEncryptionKeys[nInd].Value >>= aResult; + + // empty keys are not allowed here + // so it is not important whether there is no key, or the key is empty, it is an error + if ( !aResult.getLength() ) + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No expected key is provided!" ) ), uno::Reference< uno::XInterface >() ); + } + else + aResult = m_aEncryptionKey; + + if ( !aResult.getLength() || !bHaveOwnKey ) + aResult = rZipPackage.GetEncryptionKey(); + + return aResult; +} + +//-------------------------------------------------------------------------- +sal_Int32 ZipPackageStream::GetStartKeyGenID() +{ + // generally should all the streams use the same Start Key + // but if raw copy without password takes place, we should preserve the imported algorithm + return m_nImportedStartKeyAlgorithm ? m_nImportedStartKeyAlgorithm : rZipPackage.GetStartKeyGenID(); +} + +//-------------------------------------------------------------------------- +uno::Reference< io::XInputStream > ZipPackageStream::TryToGetRawFromDataStream( sal_Bool bAddHeaderForEncr ) +{ + if ( m_nStreamMode != PACKAGE_STREAM_DATA || !GetOwnSeekStream().is() || ( bAddHeaderForEncr && !bToBeEncrypted ) ) throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); Sequence< sal_Int8 > aKey; if ( bToBeEncrypted ) { - aKey = ( !xEncryptionData.is() || !bHaveOwnKey ) ? rZipPackage.getEncryptionKey() : - xEncryptionData->aKey; + aKey = GetEncryptionKey(); if ( !aKey.getLength() ) throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); } @@ -221,7 +305,7 @@ Reference< io::XInputStream > ZipPackageStream::TryToGetRawFromDataStream( sal_B // create a package based on it ZipPackage* pPackage = new ZipPackage( m_xFactory ); - Reference< XSingleServiceFactory > xPackageAsFactory( static_cast< XSingleServiceFactory* >( pPackage ) ); + uno::Reference< XSingleServiceFactory > xPackageAsFactory( static_cast< XSingleServiceFactory* >( pPackage ) ); if ( !xPackageAsFactory.is() ) throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); @@ -230,14 +314,14 @@ Reference< io::XInputStream > ZipPackageStream::TryToGetRawFromDataStream( sal_B pPackage->initialize( aArgs ); // create a new package stream - Reference< XDataSinkEncrSupport > xNewPackStream( xPackageAsFactory->createInstance(), UNO_QUERY ); + uno::Reference< XDataSinkEncrSupport > xNewPackStream( xPackageAsFactory->createInstance(), UNO_QUERY ); if ( !xNewPackStream.is() ) throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); xNewPackStream->setDataStream( static_cast< io::XInputStream* >( new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() ) ) ); - Reference< XPropertySet > xNewPSProps( xNewPackStream, UNO_QUERY ); + uno::Reference< XPropertySet > xNewPSProps( xNewPackStream, UNO_QUERY ); if ( !xNewPSProps.is() ) throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); @@ -246,26 +330,26 @@ Reference< io::XInputStream > ZipPackageStream::TryToGetRawFromDataStream( sal_B xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) ), makeAny( bToBeCompressed ) ); if ( bToBeEncrypted ) { - xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptionKey" ) ), makeAny( aKey ) ); + xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ENCRYPTION_KEY_PROPERTY ) ), makeAny( aKey ) ); xNewPSProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Encrypted" ) ), makeAny( sal_True ) ); } // insert a new stream in the package - Reference< XUnoTunnel > xTunnel; + uno::Reference< XUnoTunnel > xTunnel; Any aRoot = pPackage->getByHierarchicalName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ) ); aRoot >>= xTunnel; - Reference< container::XNameContainer > xRootNameContainer( xTunnel, UNO_QUERY ); + uno::Reference< container::XNameContainer > xRootNameContainer( xTunnel, UNO_QUERY ); if ( !xRootNameContainer.is() ) throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); - Reference< XUnoTunnel > xNPSTunnel( xNewPackStream, UNO_QUERY ); + uno::Reference< XUnoTunnel > xNPSTunnel( xNewPackStream, UNO_QUERY ); xRootNameContainer->insertByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "dummy" ) ), makeAny( xNPSTunnel ) ); // commit the temporary package pPackage->commitChanges(); // get raw stream from the temporary package - Reference< io::XInputStream > xInRaw; + uno::Reference< io::XInputStream > xInRaw; if ( bAddHeaderForEncr ) xInRaw = xNewPackStream->getRawStream(); else @@ -286,12 +370,12 @@ Reference< io::XInputStream > ZipPackageStream::TryToGetRawFromDataStream( sal_B xTempSeek->seek( 0 ); // close raw stream, package stream and folder - xInRaw = Reference< io::XInputStream >(); - xNewPSProps = Reference< XPropertySet >(); - xNPSTunnel = Reference< XUnoTunnel >(); - xNewPackStream = Reference< XDataSinkEncrSupport >(); - xTunnel = Reference< XUnoTunnel >(); - xRootNameContainer = Reference< container::XNameContainer >(); + xInRaw = uno::Reference< io::XInputStream >(); + xNewPSProps = uno::Reference< XPropertySet >(); + xNPSTunnel = uno::Reference< XUnoTunnel >(); + xNewPackStream = uno::Reference< XDataSinkEncrSupport >(); + xTunnel = uno::Reference< XUnoTunnel >(); + xRootNameContainer = uno::Reference< container::XNameContainer >(); // return the stream representing the first temporary file return xTempIn; @@ -317,7 +401,7 @@ sal_Bool ZipPackageStream::ParsePackageRawStream() sal_Bool bOk = sal_False; - rtl::Reference < EncryptionData > xTempEncrData; + ::rtl::Reference< BaseEncryptionData > xTempEncrData; sal_Int32 nMagHackSize = 0; Sequence < sal_Int8 > aHeader ( 4 ); @@ -333,17 +417,25 @@ sal_Bool ZipPackageStream::ParsePackageRawStream() if ( nHeader == n_ConstHeader ) { // this is one of our god-awful, but extremely devious hacks, everyone cheer - xTempEncrData = new EncryptionData; + xTempEncrData = new BaseEncryptionData; ::rtl::OUString aMediaType; - if ( ZipFile::StaticFillData ( xTempEncrData, nMagHackSize, aMediaType, GetOwnSeekStream() ) ) + sal_Int32 nEncAlgorithm = 0; + sal_Int32 nChecksumAlgorithm = 0; + sal_Int32 nDerivedKeySize = 0; + sal_Int32 nStartKeyGenID = 0; + if ( ZipFile::StaticFillData( xTempEncrData, nEncAlgorithm, nChecksumAlgorithm, nDerivedKeySize, nStartKeyGenID, nMagHackSize, aMediaType, GetOwnSeekStream() ) ) { // We'll want to skip the data we've just read, so calculate how much we just read // and remember it - m_nMagicalHackPos = n_ConstHeaderSize + xTempEncrData->aSalt.getLength() - + xTempEncrData->aInitVector.getLength() - + xTempEncrData->aDigest.getLength() + m_nMagicalHackPos = n_ConstHeaderSize + xTempEncrData->m_aSalt.getLength() + + xTempEncrData->m_aInitVector.getLength() + + xTempEncrData->m_aDigest.getLength() + aMediaType.getLength() * sizeof( sal_Unicode ); + m_nImportedEncryptionAlgorithm = nEncAlgorithm; + m_nImportedChecksumAlgorithm = nChecksumAlgorithm; + m_nImportedDerivedKeySize = nDerivedKeySize; + m_nImportedStartKeyAlgorithm = nStartKeyGenID; m_nMagicalHackSize = nMagHackSize; sMediaType = aMediaType; @@ -362,7 +454,7 @@ sal_Bool ZipPackageStream::ParsePackageRawStream() return sal_False; } - xEncryptionData = xTempEncrData; + m_xBaseEncryptionData = xTempEncrData; SetIsEncrypted ( sal_True ); // it's already compressed and encrypted bToBeEncrypted = bToBeCompressed = sal_False; @@ -384,11 +476,12 @@ void ZipPackageStream::SetPackageMember( sal_Bool bNewValue ) // XActiveDataSink //-------------------------------------------------------------------------- -void SAL_CALL ZipPackageStream::setInputStream( const Reference< io::XInputStream >& aStream ) - throw(RuntimeException) +void SAL_CALL ZipPackageStream::setInputStream( const uno::Reference< io::XInputStream >& aStream ) + throw( RuntimeException ) { // if seekable access is required the wrapping will be done on demand xStream = aStream; + m_nImportedEncryptionAlgorithm = 0; m_bHasSeekable = sal_False; SetPackageMember ( sal_False ); aEntry.nTime = -1; @@ -396,94 +489,100 @@ void SAL_CALL ZipPackageStream::setInputStream( const Reference< io::XInputStrea } //-------------------------------------------------------------------------- -Reference< io::XInputStream > SAL_CALL ZipPackageStream::getRawData() - throw(RuntimeException) +uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getRawData() + throw( RuntimeException ) { try { - if (IsPackageMember()) + if ( IsPackageMember() ) { - if ( xEncryptionData.is() && !bHaveOwnKey ) - xEncryptionData->aKey = rZipPackage.getEncryptionKey(); - return rZipPackage.getZipFile().getRawData( aEntry, xEncryptionData, bIsEncrypted, rZipPackage.GetSharedMutexRef() ); + return rZipPackage.getZipFile().getRawData( aEntry, GetEncryptionData(), bIsEncrypted, rZipPackage.GetSharedMutexRef() ); } else if ( GetOwnSeekStream().is() ) { return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() ); } else - return Reference < io::XInputStream > (); + return uno::Reference < io::XInputStream > (); } - catch (ZipException &)//rException) + catch ( ZipException & )//rException ) { - OSL_FAIL( "ZipException thrown");//rException.Message); - return Reference < io::XInputStream > (); + OSL_FAIL( "ZipException thrown" );//rException.Message); + return uno::Reference < io::XInputStream > (); } - catch (Exception &) + catch ( Exception & ) { - OSL_FAIL( "Exception is thrown during stream wrapping!\n"); - return Reference < io::XInputStream > (); + OSL_FAIL( "Exception is thrown during stream wrapping!\n" ); + return uno::Reference < io::XInputStream > (); } } //-------------------------------------------------------------------------- -Reference< io::XInputStream > SAL_CALL ZipPackageStream::getInputStream( ) - throw(RuntimeException) +uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getInputStream() + throw( RuntimeException ) { try { - if (IsPackageMember()) + if ( IsPackageMember() ) { - if ( xEncryptionData.is() && !bHaveOwnKey ) - xEncryptionData->aKey = rZipPackage.getEncryptionKey(); - return rZipPackage.getZipFile().getInputStream( aEntry, xEncryptionData, bIsEncrypted, rZipPackage.GetSharedMutexRef() ); + return rZipPackage.getZipFile().getInputStream( aEntry, GetEncryptionData(), bIsEncrypted, rZipPackage.GetSharedMutexRef() ); } else if ( GetOwnSeekStream().is() ) { return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() ); } else - return Reference < io::XInputStream > (); + return uno::Reference < io::XInputStream > (); } - catch (ZipException &)//rException) + catch ( ZipException & )//rException ) { - OSL_FAIL( "ZipException thrown");//rException.Message); - return Reference < io::XInputStream > (); + OSL_FAIL( "ZipException thrown" );//rException.Message); + return uno::Reference < io::XInputStream > (); } - catch (Exception &) + catch ( Exception & ) { - OSL_FAIL( "Exception is thrown during stream wrapping!\n"); - return Reference < io::XInputStream > (); + OSL_FAIL( "Exception is thrown during stream wrapping!\n" ); + return uno::Reference < io::XInputStream > (); } } // XDataSinkEncrSupport //-------------------------------------------------------------------------- -Reference< io::XInputStream > SAL_CALL ZipPackageStream::getDataStream() +uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getDataStream() throw ( packages::WrongPasswordException, io::IOException, RuntimeException ) { // There is no stream attached to this object if ( m_nStreamMode == PACKAGE_STREAM_NOTSET ) - return Reference< io::XInputStream >(); + return uno::Reference< io::XInputStream >(); // this method can not be used together with old approach if ( m_nStreamMode == PACKAGE_STREAM_DETECT ) throw packages::zip::ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); - if ( xEncryptionData.is() && !bHaveOwnKey ) - xEncryptionData->aKey = rZipPackage.getEncryptionKey(); - - if (IsPackageMember()) + if ( IsPackageMember() ) { - if ( xEncryptionData.is() && !bHaveOwnKey ) - xEncryptionData->aKey = rZipPackage.getEncryptionKey(); - - return rZipPackage.getZipFile().getDataStream( aEntry, xEncryptionData, bIsEncrypted, rZipPackage.GetSharedMutexRef() ); + uno::Reference< io::XInputStream > xResult; + try + { + xResult = rZipPackage.getZipFile().getDataStream( aEntry, GetEncryptionData(), bIsEncrypted, rZipPackage.GetSharedMutexRef() ); + } + catch( packages::WrongPasswordException& ) + { + // workaround for the encrypted documents generated with the old OOo1.x bug. + if ( rZipPackage.GetStartKeyGenID() == xml::crypto::DigestID::SHA1 && !m_bUseWinEncoding ) + { + xResult = rZipPackage.getZipFile().getDataStream( aEntry, GetEncryptionData( true ), bIsEncrypted, rZipPackage.GetSharedMutexRef() ); + m_bUseWinEncoding = true; + } + else + throw; + } + return xResult; } else if ( m_nStreamMode == PACKAGE_STREAM_RAW ) - return ZipFile::StaticGetDataFromRawStream( GetOwnSeekStream(), xEncryptionData ); + return ZipFile::StaticGetDataFromRawStream( m_xFactory, GetOwnSeekStream(), GetEncryptionData() ); else if ( GetOwnSeekStream().is() ) { return new WrapStreamForShare( GetOwnSeekStream(), rZipPackage.GetSharedMutexRef() ); @@ -493,25 +592,25 @@ Reference< io::XInputStream > SAL_CALL ZipPackageStream::getDataStream() } //-------------------------------------------------------------------------- -Reference< io::XInputStream > SAL_CALL ZipPackageStream::getRawStream() +uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getRawStream() throw ( packages::NoEncryptionException, io::IOException, uno::RuntimeException ) { // There is no stream attached to this object if ( m_nStreamMode == PACKAGE_STREAM_NOTSET ) - return Reference< io::XInputStream >(); + return uno::Reference< io::XInputStream >(); // this method can not be used together with old approach if ( m_nStreamMode == PACKAGE_STREAM_DETECT ) throw packages::zip::ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); - if (IsPackageMember()) + if ( IsPackageMember() ) { - if ( !bIsEncrypted || !xEncryptionData.is() ) + if ( !bIsEncrypted || !GetEncryptionData().is() ) throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); - return rZipPackage.getZipFile().getWrappedRawStream( aEntry, xEncryptionData, sMediaType, rZipPackage.GetSharedMutexRef() ); + return rZipPackage.getZipFile().getWrappedRawStream( aEntry, GetEncryptionData(), sMediaType, rZipPackage.GetSharedMutexRef() ); } else if ( GetOwnSeekStream().is() ) { @@ -528,7 +627,7 @@ Reference< io::XInputStream > SAL_CALL ZipPackageStream::getRawStream() //-------------------------------------------------------------------------- -void SAL_CALL ZipPackageStream::setDataStream( const Reference< io::XInputStream >& aStream ) +void SAL_CALL ZipPackageStream::setDataStream( const uno::Reference< io::XInputStream >& aStream ) throw ( io::IOException, RuntimeException ) { @@ -537,21 +636,21 @@ void SAL_CALL ZipPackageStream::setDataStream( const Reference< io::XInputStream } //-------------------------------------------------------------------------- -void SAL_CALL ZipPackageStream::setRawStream( const Reference< io::XInputStream >& aStream ) +void SAL_CALL ZipPackageStream::setRawStream( const uno::Reference< io::XInputStream >& aStream ) throw ( packages::EncryptionNotAllowedException, packages::NoRawFormatException, io::IOException, - RuntimeException) + RuntimeException ) { // wrap the stream in case it is not seekable - Reference< io::XInputStream > xNewStream = ::comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( aStream, m_xFactory ); - Reference< io::XSeekable > xSeek( xNewStream, UNO_QUERY ); + uno::Reference< io::XInputStream > xNewStream = ::comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( aStream, m_xFactory ); + uno::Reference< io::XSeekable > xSeek( xNewStream, UNO_QUERY ); if ( !xSeek.is() ) throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "The stream must support XSeekable!" ) ), - Reference< XInterface >() ); + uno::Reference< XInterface >() ); xSeek->seek( 0 ); - Reference< io::XInputStream > xOldStream = xStream; + uno::Reference< io::XInputStream > xOldStream = xStream; xStream = xNewStream; if ( !ParsePackageRawStream() ) { @@ -574,15 +673,15 @@ uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getPlainRawStream( { // There is no stream attached to this object if ( m_nStreamMode == PACKAGE_STREAM_NOTSET ) - return Reference< io::XInputStream >(); + return uno::Reference< io::XInputStream >(); // this method can not be used together with old approach if ( m_nStreamMode == PACKAGE_STREAM_DETECT ) throw packages::zip::ZipIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); - if (IsPackageMember()) + if ( IsPackageMember() ) { - return rZipPackage.getZipFile().getRawData( aEntry, xEncryptionData, bIsEncrypted, rZipPackage.GetSharedMutexRef() ); + return rZipPackage.getZipFile().getRawData( aEntry, GetEncryptionData(), bIsEncrypted, rZipPackage.GetSharedMutexRef() ); } else if ( GetOwnSeekStream().is() ) { @@ -595,14 +694,14 @@ uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getPlainRawStream( return TryToGetRawFromDataStream( sal_False ); } - return Reference< io::XInputStream >(); + return uno::Reference< io::XInputStream >(); } // XUnoTunnel //-------------------------------------------------------------------------- sal_Int64 SAL_CALL ZipPackageStream::getSomething( const Sequence< sal_Int8 >& aIdentifier ) - throw(RuntimeException) + throw( RuntimeException ) { sal_Int64 nMe = 0; if ( aIdentifier.getLength() == 16 && @@ -614,18 +713,18 @@ sal_Int64 SAL_CALL ZipPackageStream::getSomething( const Sequence< sal_Int8 >& a // XPropertySet //-------------------------------------------------------------------------- void SAL_CALL ZipPackageStream::setPropertyValue( const OUString& aPropertyName, const Any& aValue ) - throw(beans::UnknownPropertyException, beans::PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) + throw( beans::UnknownPropertyException, beans::PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException ) { - if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("MediaType"))) + if ( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" )) ) { if ( rZipPackage.getFormat() != embed::StorageFormats::PACKAGE && rZipPackage.getFormat() != embed::StorageFormats::OFOPXML ) throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); if ( aValue >>= sMediaType ) { - if (sMediaType.getLength() > 0) + if ( sMediaType.getLength() > 0 ) { - if ( sMediaType.indexOf (OUString( RTL_CONSTASCII_USTRINGPARAM ( "text" ) ) ) != -1 + if ( sMediaType.indexOf ( OUString( RTL_CONSTASCII_USTRINGPARAM ( "text" ) ) ) != -1 || sMediaType.equals( OUString( RTL_CONSTASCII_USTRINGPARAM ( "application/vnd.sun.star.oleobject" ) ) ) ) bToBeCompressed = sal_True; else if ( !m_bCompressedIsSetFromOutside ) @@ -634,18 +733,18 @@ void SAL_CALL ZipPackageStream::setPropertyValue( const OUString& aPropertyName, } else throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "MediaType must be a string!\n" ) ), - Reference< XInterface >(), + uno::Reference< XInterface >(), 2 ); } - else if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Size") ) ) + else if ( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Size" ) ) ) { if ( !( aValue >>= aEntry.nSize ) ) throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for Size property!\n" ) ), - Reference< XInterface >(), + uno::Reference< XInterface >(), 2 ); } - else if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Encrypted") ) ) + else if ( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Encrypted" ) ) ) { if ( rZipPackage.getFormat() != embed::StorageFormats::PACKAGE ) throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); @@ -656,25 +755,25 @@ void SAL_CALL ZipPackageStream::setPropertyValue( const OUString& aPropertyName, // In case of new raw stream, the stream must not be encrypted on storing if ( bEnc && m_nStreamMode == PACKAGE_STREAM_RAW ) throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Raw stream can not be encrypted on storing" ) ), - Reference< XInterface >(), + uno::Reference< XInterface >(), 2 ); bToBeEncrypted = bEnc; - if ( bToBeEncrypted && !xEncryptionData.is()) - xEncryptionData = new EncryptionData; + if ( bToBeEncrypted && !m_xBaseEncryptionData.is() ) + m_xBaseEncryptionData = new BaseEncryptionData; } else throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for Encrypted property!\n" ) ), - Reference< XInterface >(), + uno::Reference< XInterface >(), 2 ); } - else if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("EncryptionKey") ) ) + else if ( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ENCRYPTION_KEY_PROPERTY ) ) ) { if ( rZipPackage.getFormat() != embed::StorageFormats::PACKAGE ) throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); - Sequence < sal_Int8 > aNewKey; + uno::Sequence< sal_Int8 > aNewKey; if ( !( aValue >>= aNewKey ) ) { @@ -685,31 +784,69 @@ void SAL_CALL ZipPackageStream::setPropertyValue( const OUString& aPropertyName, Sequence < sal_Int8 > aSequence ( nPathLength ); sal_Int8 *pArray = aSequence.getArray(); const sal_Unicode *pChar = sTempString.getStr(); - for ( sal_Int16 i = 0; i < nPathLength; i++) - pArray[i] = static_cast < const sal_Int8 > (pChar[i]); + for ( sal_Int16 i = 0; i < nPathLength; i++ ) + pArray[i] = static_cast < const sal_Int8 > ( pChar[i] ); aNewKey = aSequence; } else throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for EncryptionKey property!\n" ) ), - Reference< XInterface >(), + uno::Reference< XInterface >(), 2 ); } if ( aNewKey.getLength() ) { - if ( !xEncryptionData.is()) - xEncryptionData = new EncryptionData; + if ( !m_xBaseEncryptionData.is() ) + m_xBaseEncryptionData = new BaseEncryptionData; + + m_aEncryptionKey = aNewKey; + // In case of new raw stream, the stream must not be encrypted on storing + bHaveOwnKey = sal_True; + if ( m_nStreamMode != PACKAGE_STREAM_RAW ) + bToBeEncrypted = sal_True; + } + else + { + bHaveOwnKey = sal_False; + m_aEncryptionKey.realloc( 0 ); + } + + m_aStorageEncryptionKeys.realloc( 0 ); + } + else if ( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( STORAGE_ENCRYPTION_KEYS_PROPERTY ) ) ) + { + if ( rZipPackage.getFormat() != embed::StorageFormats::PACKAGE ) + throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); + + uno::Sequence< beans::NamedValue > aKeys; + if ( !( aValue >>= aKeys ) ) + { + throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for StorageEncryptionKeys property!\n" ) ), + uno::Reference< XInterface >(), + 2 ); + } + + if ( aKeys.getLength() ) + { + if ( !m_xBaseEncryptionData.is() ) + m_xBaseEncryptionData = new BaseEncryptionData; + + m_aStorageEncryptionKeys = aKeys; - xEncryptionData->aKey = aNewKey; // In case of new raw stream, the stream must not be encrypted on storing bHaveOwnKey = sal_True; if ( m_nStreamMode != PACKAGE_STREAM_RAW ) bToBeEncrypted = sal_True; } else + { bHaveOwnKey = sal_False; + m_aStorageEncryptionKeys.realloc( 0 ); + } + + m_aEncryptionKey.realloc( 0 ); } - else if (aPropertyName.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "Compressed" ) ) ) + else if ( aPropertyName.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "Compressed" ) ) ) { sal_Bool bCompr = sal_False; @@ -718,7 +855,7 @@ void SAL_CALL ZipPackageStream::setPropertyValue( const OUString& aPropertyName, // In case of new raw stream, the stream must not be encrypted on storing if ( bCompr && m_nStreamMode == PACKAGE_STREAM_RAW ) throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Raw stream can not be encrypted on storing" ) ), - Reference< XInterface >(), + uno::Reference< XInterface >(), 2 ); bToBeCompressed = bCompr; @@ -726,7 +863,7 @@ void SAL_CALL ZipPackageStream::setPropertyValue( const OUString& aPropertyName, } else throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong type for Compressed property!\n" ) ), - Reference< XInterface >(), + uno::Reference< XInterface >(), 2 ); } else @@ -735,37 +872,42 @@ void SAL_CALL ZipPackageStream::setPropertyValue( const OUString& aPropertyName, //-------------------------------------------------------------------------- Any SAL_CALL ZipPackageStream::getPropertyValue( const OUString& PropertyName ) - throw(beans::UnknownPropertyException, WrappedTargetException, RuntimeException) + throw( beans::UnknownPropertyException, WrappedTargetException, RuntimeException ) { Any aAny; - if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ) + if ( PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ) { aAny <<= sMediaType; return aAny; } - else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Size" ) ) ) + else if ( PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Size" ) ) ) { aAny <<= aEntry.nSize; return aAny; } - else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Encrypted" ) ) ) + else if ( PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Encrypted" ) ) ) { aAny <<= ( m_nStreamMode == PACKAGE_STREAM_RAW ) ? sal_True : bToBeEncrypted; return aAny; } - else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "WasEncrypted" ) ) ) + else if ( PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "WasEncrypted" ) ) ) { aAny <<= bIsEncrypted; return aAny; } - else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Compressed" ) ) ) + else if ( PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Compressed" ) ) ) { aAny <<= bToBeCompressed; return aAny; } - else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "EncryptionKey" ) ) ) + else if ( PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ENCRYPTION_KEY_PROPERTY ) ) ) + { + aAny <<= m_aEncryptionKey; + return aAny; + } + else if ( PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( STORAGE_ENCRYPTION_KEYS_PROPERTY ) ) ) { - aAny <<= !xEncryptionData.is() ? Sequence < sal_Int8 > () : xEncryptionData->aKey; + aAny <<= m_aStorageEncryptionKeys; return aAny; } else @@ -773,30 +915,30 @@ Any SAL_CALL ZipPackageStream::getPropertyValue( const OUString& PropertyName ) } //-------------------------------------------------------------------------- -void ZipPackageStream::setSize (const sal_Int32 nNewSize) +void ZipPackageStream::setSize ( const sal_Int32 nNewSize ) { - if (aEntry.nCompressedSize != nNewSize ) + if ( aEntry.nCompressedSize != nNewSize ) aEntry.nMethod = DEFLATED; aEntry.nSize = nNewSize; } //-------------------------------------------------------------------------- OUString ZipPackageStream::getImplementationName() - throw (RuntimeException) + throw ( RuntimeException ) { return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "ZipPackageStream" ) ); } //-------------------------------------------------------------------------- Sequence< OUString > ZipPackageStream::getSupportedServiceNames() - throw (RuntimeException) + throw ( RuntimeException ) { - Sequence< OUString > aNames(1); + Sequence< OUString > aNames( 1 ); aNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.packages.PackageStream" ) ); return aNames; } //-------------------------------------------------------------------------- sal_Bool SAL_CALL ZipPackageStream::supportsService( OUString const & rServiceName ) - throw (RuntimeException) + throw ( RuntimeException ) { return rServiceName == getSupportedServiceNames()[0]; } |