diff options
Diffstat (limited to 'oox/source/core/filterdetect.cxx')
-rw-r--r-- | oox/source/core/filterdetect.cxx | 188 |
1 files changed, 92 insertions, 96 deletions
diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx index cdab111e9898..f836720a48a2 100644 --- a/oox/source/core/filterdetect.cxx +++ b/oox/source/core/filterdetect.cxx @@ -269,9 +269,9 @@ const sal_uInt32 ENCRYPT_HASH_SHA1 = 0x00008004; // ---------------------------------------------------------------------------- -bool lclIsZipPackage( const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm ) +bool lclIsZipPackage( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm ) { - ZipStorage aZipStorage( rxFactory, rxInStrm ); + ZipStorage aZipStorage( rxContext, rxInStrm ); return aZipStorage.isStorage(); } @@ -499,109 +499,106 @@ PasswordVerifier::PasswordVerifier( const PackageEncryptionInfo& rEncryptInfo ) Reference< XInputStream > FilterDetect::extractUnencryptedPackage( MediaDescriptor& rMediaDesc ) const { - Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY ); - if( xFactory.is() ) + // try the plain input stream + Reference< XInputStream > xInStrm( rMediaDesc[ MediaDescriptor::PROP_INPUTSTREAM() ], UNO_QUERY ); + if( !xInStrm.is() || lclIsZipPackage( mxContext, xInStrm ) ) + return xInStrm; + + // check if a temporary file is passed in the 'ComponentData' property + Reference< XStream > xDecrypted( rMediaDesc.getComponentDataEntry( CREATE_OUSTRING( "DecryptedPackage" ) ), UNO_QUERY ); + if( xDecrypted.is() ) { - // try the plain input stream - Reference< XInputStream > xInStrm( rMediaDesc[ MediaDescriptor::PROP_INPUTSTREAM() ], UNO_QUERY ); - if( !xInStrm.is() || lclIsZipPackage( xFactory, xInStrm ) ) - return xInStrm; - - // check if a temporary file is passed in the 'ComponentData' property - Reference< XStream > xDecrypted( rMediaDesc.getComponentDataEntry( CREATE_OUSTRING( "DecryptedPackage" ) ), UNO_QUERY ); - if( xDecrypted.is() ) - { - Reference< XInputStream > xDecrInStrm = xDecrypted->getInputStream(); - if( lclIsZipPackage( xFactory, xDecrInStrm ) ) - return xDecrInStrm; - } + Reference< XInputStream > xDecrInStrm = xDecrypted->getInputStream(); + if( lclIsZipPackage( mxContext, xDecrInStrm ) ) + return xDecrInStrm; + } - // try to decrypt an encrypted OLE package - ::oox::ole::OleStorage aOleStorage( xFactory, xInStrm, false ); - if( aOleStorage.isStorage() ) try + // try to decrypt an encrypted OLE package + ::oox::ole::OleStorage aOleStorage( mxContext, xInStrm, false ); + if( aOleStorage.isStorage() ) try + { + // open the required input streams in the encrypted package + Reference< XInputStream > xEncryptionInfo( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptionInfo" ) ), UNO_SET_THROW ); + Reference< XInputStream > xEncryptedPackage( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptedPackage" ) ), UNO_SET_THROW ); + + // read the encryption info stream + PackageEncryptionInfo aEncryptInfo; + BinaryXInputStream aInfoStrm( xEncryptionInfo, true ); + bool bValidInfo = lclReadEncryptionInfo( aEncryptInfo, aInfoStrm ); + + // check flags and agorithm IDs, requiered are AES128 and SHA-1 + bool bImplemented = bValidInfo && + getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_CRYPTOAPI ) && + getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_AES ) && + // algorithm ID 0 defaults to AES128 too, if ENCRYPTINFO_AES flag is set + ((aEncryptInfo.mnAlgorithmId == 0) || (aEncryptInfo.mnAlgorithmId == ENCRYPT_ALGO_AES128)) && + // hash algorithm ID 0 defaults to SHA-1 too + ((aEncryptInfo.mnAlgorithmIdHash == 0) || (aEncryptInfo.mnAlgorithmIdHash == ENCRYPT_HASH_SHA1)) && + (aEncryptInfo.mnVerifierHashSize == 20); + + if( bImplemented ) { - // open the required input streams in the encrypted package - Reference< XInputStream > xEncryptionInfo( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptionInfo" ) ), UNO_SET_THROW ); - Reference< XInputStream > xEncryptedPackage( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptedPackage" ) ), UNO_SET_THROW ); - - // read the encryption info stream - PackageEncryptionInfo aEncryptInfo; - BinaryXInputStream aInfoStrm( xEncryptionInfo, true ); - bool bValidInfo = lclReadEncryptionInfo( aEncryptInfo, aInfoStrm ); - - // check flags and agorithm IDs, requiered are AES128 and SHA-1 - bool bImplemented = bValidInfo && - getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_CRYPTOAPI ) && - getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_AES ) && - // algorithm ID 0 defaults to AES128 too, if ENCRYPTINFO_AES flag is set - ((aEncryptInfo.mnAlgorithmId == 0) || (aEncryptInfo.mnAlgorithmId == ENCRYPT_ALGO_AES128)) && - // hash algorithm ID 0 defaults to SHA-1 too - ((aEncryptInfo.mnAlgorithmIdHash == 0) || (aEncryptInfo.mnAlgorithmIdHash == ENCRYPT_HASH_SHA1)) && - (aEncryptInfo.mnVerifierHashSize == 20); - - if( bImplemented ) + /* "VelvetSweatshop" is the built-in default encryption + password used by MS Excel for the "workbook protection" + feature with password. Try this first before prompting the + user for a password. */ + ::std::vector< OUString > aDefaultPasswords; + aDefaultPasswords.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) ); + + /* Use the comphelper password helper to request a password. + This helper returns either with the correct password + (according to the verifier), or with an empty string if + user has cancelled the password input dialog. */ + PasswordVerifier aVerifier( aEncryptInfo ); + Sequence< NamedValue > aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword( + aVerifier, rMediaDesc, ::comphelper::DocPasswordRequestType_MS, &aDefaultPasswords ); + + if( aEncryptionData.getLength() == 0 ) { - /* "VelvetSweatshop" is the built-in default encryption - password used by MS Excel for the "workbook protection" - feature with password. Try this first before prompting the - user for a password. */ - ::std::vector< OUString > aDefaultPasswords; - aDefaultPasswords.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) ); - - /* Use the comphelper password helper to request a password. - This helper returns either with the correct password - (according to the verifier), or with an empty string if - user has cancelled the password input dialog. */ - PasswordVerifier aVerifier( aEncryptInfo ); - Sequence< NamedValue > aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword( - aVerifier, rMediaDesc, ::comphelper::DocPasswordRequestType_MS, &aDefaultPasswords ); - - if( aEncryptionData.getLength() == 0 ) - { - rMediaDesc[ MediaDescriptor::PROP_ABORTED() ] <<= true; - } - else + rMediaDesc[ MediaDescriptor::PROP_ABORTED() ] <<= true; + } + else + { + // create temporary file for unencrypted package + Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW ); + Reference< XStream > xTempFile( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW ); + Reference< XOutputStream > xDecryptedPackage( xTempFile->getOutputStream(), UNO_SET_THROW ); + BinaryXOutputStream aDecryptedPackage( xDecryptedPackage, true ); + BinaryXInputStream aEncryptedPackage( xEncryptedPackage, true ); + + EVP_CIPHER_CTX aes_ctx; + EVP_CIPHER_CTX_init( &aes_ctx ); + EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, aVerifier.getKey(), 0 ); + EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 ); + + sal_uInt8 pnInBuffer[ 1024 ]; + sal_uInt8 pnOutBuffer[ 1024 ]; + sal_Int32 nInLen; + int nOutLen; + aEncryptedPackage.skip( 8 ); // decrypted size + while( (nInLen = aEncryptedPackage.readMemory( pnInBuffer, sizeof( pnInBuffer ) )) > 0 ) { - // create temporary file for unencrypted package - Reference< XStream > xTempFile( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW ); - Reference< XOutputStream > xDecryptedPackage( xTempFile->getOutputStream(), UNO_SET_THROW ); - BinaryXOutputStream aDecryptedPackage( xDecryptedPackage, true ); - BinaryXInputStream aEncryptedPackage( xEncryptedPackage, true ); - - EVP_CIPHER_CTX aes_ctx; - EVP_CIPHER_CTX_init( &aes_ctx ); - EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, aVerifier.getKey(), 0 ); - EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 ); - - sal_uInt8 pnInBuffer[ 1024 ]; - sal_uInt8 pnOutBuffer[ 1024 ]; - sal_Int32 nInLen; - int nOutLen; - aEncryptedPackage.skip( 8 ); // decrypted size - while( (nInLen = aEncryptedPackage.readMemory( pnInBuffer, sizeof( pnInBuffer ) )) > 0 ) - { - EVP_DecryptUpdate( &aes_ctx, pnOutBuffer, &nOutLen, pnInBuffer, nInLen ); - aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen ); - } - EVP_DecryptFinal_ex( &aes_ctx, pnOutBuffer, &nOutLen ); + EVP_DecryptUpdate( &aes_ctx, pnOutBuffer, &nOutLen, pnInBuffer, nInLen ); aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen ); + } + EVP_DecryptFinal_ex( &aes_ctx, pnOutBuffer, &nOutLen ); + aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen ); - EVP_CIPHER_CTX_cleanup( &aes_ctx ); - xDecryptedPackage->flush(); - aDecryptedPackage.seekToStart(); + EVP_CIPHER_CTX_cleanup( &aes_ctx ); + xDecryptedPackage->flush(); + aDecryptedPackage.seekToStart(); - // store temp file in media descriptor to keep it alive - rMediaDesc.setComponentDataEntry( CREATE_OUSTRING( "DecryptedPackage" ), Any( xTempFile ) ); + // store temp file in media descriptor to keep it alive + rMediaDesc.setComponentDataEntry( CREATE_OUSTRING( "DecryptedPackage" ), Any( xTempFile ) ); - Reference< XInputStream > xDecrInStrm = xTempFile->getInputStream(); - if( lclIsZipPackage( xFactory, xDecrInStrm ) ) - return xDecrInStrm; - } + Reference< XInputStream > xDecrInStrm = xTempFile->getInputStream(); + if( lclIsZipPackage( mxContext, xDecrInStrm ) ) + return xDecrInStrm; } } - catch( Exception& ) - { - } + } + catch( Exception& ) + { } return Reference< XInputStream >(); @@ -633,7 +630,6 @@ OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& rMediaDescSeq { OUString aFilterName; MediaDescriptor aMediaDesc( rMediaDescSeq ); - Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW ); /* Check that the user has not choosen to abort detection, e.g. by hitting 'Cancel' in the password input dialog. This may happen because this @@ -650,7 +646,7 @@ OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& rMediaDescSeq Reference< XInputStream > xInStrm( extractUnencryptedPackage( aMediaDesc ), UNO_SET_THROW ); // stream must be a ZIP package - ZipStorage aZipStorage( xFactory, xInStrm ); + ZipStorage aZipStorage( mxContext, xInStrm ); if( aZipStorage.isStorage() ) { // create the fast parser, register the XML namespaces, set document handler |