summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Voytenko <mav@openoffice.org>2010-11-04 17:56:39 +0100
committerMikhail Voytenko <mav@openoffice.org>2010-11-04 17:56:39 +0100
commit3460624e393c6cd754dae0ca17eb9cda44343f30 (patch)
tree14df27d99828c3630cca5f226a40767c115393ba
parent08c1547f62328e8d1f922171313825d0055522c4 (diff)
pl08: #163778# use EncryptionData from MediaDescriptor
-rw-r--r--filter/inc/filter/msfilter/mscodec.hxx67
-rw-r--r--filter/source/msfilter/mscodec.cxx133
-rw-r--r--oox/inc/oox/core/binarycodec.hxx50
-rw-r--r--oox/inc/oox/core/filterbase.hxx7
-rw-r--r--oox/inc/oox/xls/biffcodec.hxx21
-rw-r--r--oox/source/core/binarycodec.cxx111
-rw-r--r--[-rwxr-xr-x]oox/source/core/filterbase.cxx4
-rw-r--r--oox/source/core/filterdetect.cxx109
-rw-r--r--oox/source/xls/biffcodec.cxx92
9 files changed, 415 insertions, 179 deletions
diff --git a/filter/inc/filter/msfilter/mscodec.hxx b/filter/inc/filter/msfilter/mscodec.hxx
index 7bad8af6b788..60e3adf1d5ba 100644
--- a/filter/inc/filter/msfilter/mscodec.hxx
+++ b/filter/inc/filter/msfilter/mscodec.hxx
@@ -28,8 +28,11 @@
#ifndef SVX_MSCODEC_HXX
#define SVX_MSCODEC_HXX
-#include "rtl/cipher.h"
-#include "rtl/digest.h"
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/beans/NamedValue.hpp>
+
+#include <rtl/cipher.h>
+#include <rtl/digest.h>
#include "filter/msfilter/msfilterdllapi.h"
namespace msfilter {
@@ -52,6 +55,23 @@ public:
*/
void InitKey( const sal_uInt8 pnPassData[ 16 ] );
+ /** Initializes the algorithm with the encryption data.
+
+ @param aData
+ The sequence contains the necessary data to initialize
+ the codec.
+ */
+ sal_Bool InitCodec( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aData );
+
+ /** Retrieves the encryption data
+
+ @return
+ The sequence contains the necessary data to initialize
+ the codec.
+ */
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GetEncryptionData();
+
+
/** Verifies the validity of the password using the passed key and hash.
@precond
@@ -105,16 +125,6 @@ public:
*/
void Skip( sal_Size nBytes );
- // static -----------------------------------------------------------------
-
- /** Calculates the 16-bit hash value for the given password.
-
- The password data may be longer than 16 bytes. The array does not need
- to be terminated with a NULL byte (but it can without invalidating the
- result).
- */
- static sal_uInt16 GetHash( const sal_uInt8* pnPassData, sal_Size nSize );
-
protected:
sal_uInt8 mpnKey[ 16 ]; /// Encryption key.
sal_Size mnOffset; /// Key offset.
@@ -185,17 +195,34 @@ public:
explicit MSCodec_Std97();
~MSCodec_Std97();
+ /** Initializes the algorithm with the encryption data.
+
+ @param aData
+ The sequence contains the necessary data to initialize
+ the codec.
+ */
+ sal_Bool InitCodec( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aData );
+
+ /** Retrieves the encryption data
+
+ @return
+ The sequence contains the necessary data to initialize
+ the codec.
+ */
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GetEncryptionData();
+
+
/** Initializes the algorithm with the specified password and document ID.
@param pPassData
Wide character array containing the password. Must be zero
terminated, which results in a maximum length of 15 characters.
- @param pUnique
+ @param pDocId
Unique document identifier read from or written to the file.
*/
void InitKey(
const sal_uInt16 pPassData[ 16 ],
- const sal_uInt8 pUnique[ 16 ] );
+ const sal_uInt8 pDocId[ 16 ] );
/** Verifies the validity of the password using the passed salt data.
@@ -320,16 +347,26 @@ public:
sal_uInt8 pSaltData[16],
sal_uInt8 pSaltDigest[16]);
-private:
+ /* allows to get the unique document id from the codec
+ */
+ void GetDocId( sal_uInt8 pDocId[16] );
+
void GetDigestFromSalt( const sal_uInt8 pSaltData[16], sal_uInt8 pDigest[16] );
private:
+ void InitKeyImpl(
+ const sal_uInt8 pKeyData[64],
+ const sal_uInt8 pDocId[16] );
+
+
+private:
MSFILTER_DLLPRIVATE MSCodec_Std97( const MSCodec_Std97& );
MSFILTER_DLLPRIVATE MSCodec_Std97& operator=( const MSCodec_Std97& );
rtlCipher m_hCipher;
rtlDigest m_hDigest;
sal_uInt8 m_pDigestValue[ RTL_DIGEST_LENGTH_MD5 ];
+ sal_uInt8 m_pDocId[16];
};
// ============================================================================
diff --git a/filter/source/msfilter/mscodec.cxx b/filter/source/msfilter/mscodec.cxx
index de17da6bde59..626a91ff4262 100644
--- a/filter/source/msfilter/mscodec.cxx
+++ b/filter/source/msfilter/mscodec.cxx
@@ -34,12 +34,16 @@
#include <string.h>
#include <tools/solar.h>
+#include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/docpasswordhelper.hxx>
+
#define DEBUG_MSO_ENCRYPTION_STD97 0
#if DEBUG_MSO_ENCRYPTION_STD97
#include <stdio.h>
#endif
+using namespace ::com::sun::star;
namespace msfilter {
@@ -169,6 +173,37 @@ void MSCodec_Xor95::InitKey( const sal_uInt8 pnPassData[ 16 ] )
}
}
+sal_Bool MSCodec_Xor95::InitCodec( const uno::Sequence< beans::NamedValue >& aData )
+{
+ sal_Bool bResult = sal_False;
+
+ ::comphelper::SequenceAsHashMap aHashData( aData );
+ uno::Sequence< sal_Int8 > aKey = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95EncryptionKey" ) ), uno::Sequence< sal_Int8 >() );
+
+ if ( aKey.getLength() == 16 )
+ {
+ (void)memcpy( mpnKey, aKey.getConstArray(), 16 );
+ bResult = sal_True;
+
+ mnKey = (sal_uInt16)aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95BaseKey" ) ), (sal_Int16)0 );
+ mnHash = (sal_uInt16)aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95PasswordHash" ) ), (sal_Int16)0 );
+ }
+ else
+ OSL_ENSURE( sal_False, "Unexpected key size!\n" );
+
+ return bResult;
+}
+
+uno::Sequence< beans::NamedValue > MSCodec_Xor95::GetEncryptionData()
+{
+ ::comphelper::SequenceAsHashMap aHashData;
+ aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95EncryptionKey" ) ) ] <<= uno::Sequence<sal_Int8>( (sal_Int8*)mpnKey, 16 );
+ aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95BaseKey" ) ) ] <<= (sal_Int16)mnKey;
+ aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95PasswordHash" ) ) ] <<= (sal_Int16)mnHash;
+
+ return aHashData.getAsConstNamedValueList();
+}
+
bool MSCodec_Xor95::VerifyKey( sal_uInt16 nKey, sal_uInt16 nHash ) const
{
return (nKey == mnKey) && (nHash == mnHash);
@@ -218,11 +253,6 @@ void MSCodec_Xor95::Skip( sal_Size nBytes )
mnOffset = (mnOffset + nBytes) & 0x0F;
}
-sal_uInt16 MSCodec_Xor95::GetHash( const sal_uInt8* pnPassData, sal_Size nSize )
-{
- return lclGetHash( pnPassData, nSize );
-}
-
// ============================================================================
MSCodec_Std97::MSCodec_Std97 ()
@@ -236,11 +266,13 @@ MSCodec_Std97::MSCodec_Std97 ()
OSL_ASSERT(m_hDigest != 0);
(void)memset (m_pDigestValue, 0, sizeof(m_pDigestValue));
+ (void)memset (m_pDocId, 0, sizeof(m_pDocId));
}
MSCodec_Std97::~MSCodec_Std97 ()
{
(void)memset (m_pDigestValue, 0, sizeof(m_pDigestValue));
+ (void)memset (m_pDocId, 0, sizeof(m_pDocId));
rtl_digest_destroy (m_hDigest);
rtl_cipher_destroy (m_hCipher);
}
@@ -276,65 +308,58 @@ static void lcl_PrintDigest(const sal_uInt8* /*pDigest*/, const char* /*msg*/)
}
#endif
-void MSCodec_Std97::InitKey (
- const sal_uInt16 pPassData[16],
- const sal_uInt8 pUnique[16])
+sal_Bool MSCodec_Std97::InitCodec( const uno::Sequence< beans::NamedValue >& aData )
{
-#if DEBUG_MSO_ENCRYPTION_STD97
- fprintf(stdout, "MSCodec_Std97::InitKey: --begin\n");fflush(stdout);
-#endif
- sal_uInt8 pKeyData[64];
- int i, n;
-
- // Fill PassData into KeyData.
- (void)memset (pKeyData, 0, sizeof(pKeyData));
- lcl_PrintKeyData(pKeyData, "initial");
- for (i = 0, n = 16; (i < n) && pPassData[i]; i++)
- {
- pKeyData[2*i ] = sal::static_int_cast< sal_uInt8 >(
- (pPassData[i] >> 0) & 0xff);
- pKeyData[2*i + 1] = sal::static_int_cast< sal_uInt8 >(
- (pPassData[i] >> 8) & 0xff);
- }
- pKeyData[2*i] = 0x80;
- pKeyData[ 56] = sal::static_int_cast< sal_uInt8 >(i << 4);
+ sal_Bool bResult = sal_False;
- lcl_PrintKeyData(pKeyData, "password data");
+ ::comphelper::SequenceAsHashMap aHashData( aData );
+ uno::Sequence< sal_Int8 > aKey = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97EncryptionKey" ) ), uno::Sequence< sal_Int8 >() );
- // Fill raw digest of KeyData into KeyData.
- (void)rtl_digest_updateMD5 (
- m_hDigest, pKeyData, sizeof(pKeyData));
- (void)rtl_digest_rawMD5 (
- m_hDigest, pKeyData, RTL_DIGEST_LENGTH_MD5);
-
- lcl_PrintKeyData(pKeyData, "raw digest of key data");
-
- // Update digest with KeyData and Unique.
- for (i = 0; i < 16; i++)
+ if ( aKey.getLength() == RTL_DIGEST_LENGTH_MD5 )
{
- rtl_digest_updateMD5 (m_hDigest, pKeyData, 5);
- rtl_digest_updateMD5 (m_hDigest, pUnique, 16);
+ (void)memcpy( m_pDigestValue, aKey.getConstArray(), RTL_DIGEST_LENGTH_MD5 );
+ uno::Sequence< sal_Int8 > aUniqueID = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97UniqueID" ) ), uno::Sequence< sal_Int8 >() );
+ if ( aUniqueID.getLength() == 16 )
+ {
+ (void)memcpy( m_pDocId, aUniqueID.getConstArray(), 16 );
+ bResult = sal_True;
+ }
+ else
+ OSL_ENSURE( sal_False, "Unexpected document ID!\n" );
}
+ else
+ OSL_ENSURE( sal_False, "Unexpected key size!\n" );
- // Update digest with padding.
- pKeyData[16] = 0x80;
- (void)memset (pKeyData + 17, 0, sizeof(pKeyData) - 17);
- pKeyData[56] = 0x80;
- pKeyData[57] = 0x0a;
+ return bResult;
+}
- lcl_PrintKeyData(pKeyData, "update digest with padding");
+uno::Sequence< beans::NamedValue > MSCodec_Std97::GetEncryptionData()
+{
+ ::comphelper::SequenceAsHashMap aHashData;
+ aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97EncryptionKey" ) ) ] <<= uno::Sequence< sal_Int8 >( (sal_Int8*)m_pDigestValue, RTL_DIGEST_LENGTH_MD5 );
+ aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97UniqueID" ) ) ] <<= uno::Sequence< sal_Int8 >( (sal_Int8*)m_pDocId, 16 );
- rtl_digest_updateMD5 (
- m_hDigest, &(pKeyData[16]), sizeof(pKeyData) - 16);
+ return aHashData.getAsConstNamedValueList();
+}
+void MSCodec_Std97::InitKey (
+ const sal_uInt16 pPassData[16],
+ const sal_uInt8 pDocId[16])
+{
+#if DEBUG_MSO_ENCRYPTION_STD97
+ fprintf(stdout, "MSCodec_Std97::InitKey: --begin\n");fflush(stdout);
+#endif
+ uno::Sequence< sal_Int8 > aKey = ::comphelper::DocPasswordHelper::GenerateStd97Key( pPassData, uno::Sequence< sal_Int8 >( (sal_Int8*)pDocId, 16 ) );
// Fill raw digest of above updates into DigestValue.
- rtl_digest_rawMD5 (
- m_hDigest, m_pDigestValue, sizeof(m_pDigestValue));
+
+ if ( aKey.getLength() == sizeof(m_pDigestValue) )
+ (void)memcpy ( m_pDigestValue, aKey.getConstArray(), sizeof(m_pDigestValue) );
+ else
+ memset( m_pDigestValue, 0, sizeof(m_pDigestValue) );
lcl_PrintDigest(m_pDigestValue, "digest value");
- // Erase KeyData array and leave.
- (void)memset (pKeyData, 0, sizeof(pKeyData));
+ (void)memcpy (m_pDocId, pDocId, 16);
}
bool MSCodec_Std97::VerifyKey (
@@ -528,6 +553,12 @@ void MSCodec_Std97::GetEncryptKey (
}
}
+void MSCodec_Std97::GetDocId( sal_uInt8 pDocId[16] )
+{
+ if ( sizeof( m_pDocId ) == 16 )
+ (void)memcpy( pDocId, m_pDocId, 16 );
+}
+
// ============================================================================
} // namespace svx
diff --git a/oox/inc/oox/core/binarycodec.hxx b/oox/inc/oox/core/binarycodec.hxx
index 8abafffa2481..ce57e190f088 100644
--- a/oox/inc/oox/core/binarycodec.hxx
+++ b/oox/inc/oox/core/binarycodec.hxx
@@ -28,6 +28,9 @@
#ifndef OOX_CORE_BINARYCODEC_HXX
#define OOX_CORE_BINARYCODEC_HXX
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/beans/NamedValue.hpp>
+
#include <rtl/cipher.h>
#include <rtl/digest.h>
@@ -85,6 +88,22 @@ public:
*/
void initKey( const sal_uInt8 pnPassData[ 16 ] );
+ /** Initializes the algorithm with the encryption data.
+
+ @param aData
+ The sequence contains the necessary data to initialize
+ the codec.
+ */
+ bool initCodec( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aData );
+
+ /** Retrieves the encryption data
+
+ @return
+ The sequence contains the necessary data to initialize
+ the codec.
+ */
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > getEncryptionData();
+
/** Verifies the validity of the password using the passed key and hash.
@precond
@@ -150,16 +169,6 @@ public:
*/
bool skip( sal_Int32 nBytes );
- // static -----------------------------------------------------------------
-
- /** Calculates the 16-bit hash value for the given password.
-
- The password data may be longer than 16 bytes. The array does not need
- to be terminated with a null byte (but it can without invalidating the
- result).
- */
- static sal_uInt16 getHash( const sal_uInt8* pnPassData, sal_Int32 nSize );
-
private:
CodecType meCodecType; /// Codec type.
sal_uInt8 mpnKey[ 16 ]; /// Encryption key.
@@ -189,6 +198,22 @@ public:
~BinaryCodec_RCF();
+ /** Initializes the algorithm with the encryption data.
+
+ @param aData
+ The sequence contains the necessary data to initialize
+ the codec.
+ */
+ bool initCodec( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aData );
+
+ /** Retrieves the encryption data
+
+ @return
+ The sequence contains the necessary data to initialize
+ the codec.
+ */
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > getEncryptionData();
+
/** Initializes the algorithm with the specified password and document ID.
@param pnPassData
@@ -278,9 +303,14 @@ public:
bool skip( sal_Int32 nBytes );
private:
+ void InitKeyImpl(
+ const sal_uInt8 pKeyData[64],
+ const sal_uInt8 pUnique[16] );
+
rtlCipher mhCipher;
rtlDigest mhDigest;
sal_uInt8 mpnDigestValue[ RTL_DIGEST_LENGTH_MD5 ];
+ sal_uInt8 mpnUnique[16];
};
// ============================================================================
diff --git a/oox/inc/oox/core/filterbase.hxx b/oox/inc/oox/core/filterbase.hxx
index 1757b2be4334..9d9b8dcca515 100644
--- a/oox/inc/oox/core/filterbase.hxx
+++ b/oox/inc/oox/core/filterbase.hxx
@@ -31,6 +31,7 @@
#include <memory>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/document/XImporter.hpp>
#include <com/sun/star/document/XExporter.hpp>
#include <com/sun/star/document/XFilter.hpp>
@@ -194,9 +195,9 @@ public:
/** Returns a helper for the handling of OLE obejcts. */
::oox::ole::OleObjectHelper& getOleObjectHelper() const;
- /** Requests a password from the media descriptor or from the user. On
- success, the password will be inserted into the media descriptor. */
- ::rtl::OUString requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) const;
+ /** Requests the encryption data from the media descriptor or from the user. On
+ success, the encryption data will be inserted into the media descriptor. */
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > requestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ) const;
/** Imports the raw binary data from the specified stream.
@return True, if the data could be imported from the stream. */
diff --git a/oox/inc/oox/xls/biffcodec.hxx b/oox/inc/oox/xls/biffcodec.hxx
index 21b3e82006fd..c1c040de095b 100644
--- a/oox/inc/oox/xls/biffcodec.hxx
+++ b/oox/inc/oox/xls/biffcodec.hxx
@@ -52,10 +52,9 @@ public:
/** Derived classes return a clone of the decoder for usage in new streams. */
inline BiffDecoderBase* clone() { return implClone(); }
- /** Implementation of the ::comphelper::IDocPasswordVerifier interface,
- calls the new virtual function implVerify(). */
- virtual ::comphelper::DocPasswordVerifierResult
- verifyPassword( const ::rtl::OUString& rPassword );
+ /** Implementation of the ::comphelper::IDocPasswordVerifier interface. */
+ virtual ::comphelper::DocPasswordVerifierResult verifyPassword( const ::rtl::OUString& rPassword, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& o_rEncryptionData );
+ virtual ::comphelper::DocPasswordVerifierResult verifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& o_rEncryptionData );
/** Returns true, if the decoder has been initialized correctly. */
inline bool isValid() const { return mbValid; }
@@ -73,7 +72,8 @@ private:
/** Derived classes implement password verification and initialization of
the decoder. */
- virtual bool implVerify( const ::rtl::OUString& rPassword ) = 0;
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > implVerifyPassword( const ::rtl::OUString& rPassword ) = 0;
+ virtual bool implVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData ) = 0;
/** Implementation of decryption of a memory block. */
virtual void implDecode(
@@ -104,7 +104,9 @@ private:
virtual BiffDecoder_XOR* implClone();
/** Implements password verification and initialization of the decoder. */
- virtual bool implVerify( const ::rtl::OUString& rPassword );
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > implVerifyPassword( const ::rtl::OUString& rPassword );
+ virtual bool implVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData );
+
/** Implementation of decryption of a memory block. */
virtual void implDecode(
@@ -115,7 +117,7 @@ private:
private:
::oox::core::BinaryCodec_XOR maCodec; /// Cipher algorithm implementation.
- ::std::vector< sal_uInt8 > maPassword;
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > maEncryptionData;
sal_uInt16 mnKey;
sal_uInt16 mnHash;
};
@@ -139,7 +141,8 @@ private:
virtual BiffDecoder_RCF* implClone();
/** Implements password verification and initialization of the decoder. */
- virtual bool implVerify( const ::rtl::OUString& rPassword );
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > implVerifyPassword( const ::rtl::OUString& rPassword );
+ virtual bool implVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData );
/** Implementation of decryption of a memory block. */
virtual void implDecode(
@@ -150,7 +153,7 @@ private:
private:
::oox::core::BinaryCodec_RCF maCodec; /// Cipher algorithm implementation.
- ::std::vector< sal_uInt16 > maPassword;
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > maEncryptionData;
::std::vector< sal_uInt8 > maSalt;
::std::vector< sal_uInt8 > maVerifier;
::std::vector< sal_uInt8 > maVerifierHash;
diff --git a/oox/source/core/binarycodec.cxx b/oox/source/core/binarycodec.cxx
index 6127524c2aae..954f623f1f91 100644
--- a/oox/source/core/binarycodec.cxx
+++ b/oox/source/core/binarycodec.cxx
@@ -30,6 +30,11 @@
#include <string.h>
#include "oox/helper/attributelist.hxx"
+#include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/docpasswordhelper.hxx>
+
+using namespace ::com::sun::star;
+
namespace oox {
namespace core {
@@ -176,6 +181,37 @@ void BinaryCodec_XOR::initKey( const sal_uInt8 pnPassData[ 16 ] )
}
}
+bool BinaryCodec_XOR::initCodec( const uno::Sequence< beans::NamedValue >& aData )
+{
+ bool bResult = sal_False;
+
+ ::comphelper::SequenceAsHashMap aHashData( aData );
+ uno::Sequence< sal_Int8 > aKey = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95EncryptionKey" ) ), uno::Sequence< sal_Int8 >() );
+
+ if ( aKey.getLength() == 16 )
+ {
+ (void)memcpy( mpnKey, aKey.getConstArray(), 16 );
+ bResult = sal_True;
+
+ mnBaseKey = (sal_uInt16)aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95BaseKey" ) ), (sal_Int16)0 );
+ mnHash = (sal_uInt16)aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95PasswordHash" ) ), (sal_Int16)0 );
+ }
+ else
+ OSL_ENSURE( sal_False, "Unexpected key size!\n" );
+
+ return bResult;
+}
+
+uno::Sequence< beans::NamedValue > BinaryCodec_XOR::getEncryptionData()
+{
+ ::comphelper::SequenceAsHashMap aHashData;
+ aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95EncryptionKey" ) ) ] <<= uno::Sequence<sal_Int8>( (sal_Int8*)mpnKey, 16 );
+ aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95BaseKey" ) ) ] <<= (sal_Int16)mnBaseKey;
+ aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XOR95PasswordHash" ) ) ] <<= (sal_Int16)mnHash;
+
+ return aHashData.getAsConstNamedValueList();
+}
+
bool BinaryCodec_XOR::verifyKey( sal_uInt16 nKey, sal_uInt16 nHash ) const
{
return (nKey == mnBaseKey) && (nHash == mnHash);
@@ -230,11 +266,6 @@ bool BinaryCodec_XOR::skip( sal_Int32 nBytes )
return true;
}
-sal_uInt16 BinaryCodec_XOR::getHash( const sal_uInt8* pnPassData, sal_Int32 nSize )
-{
- return lclGetHash( pnPassData, nSize );
-}
-
// ============================================================================
BinaryCodec_RCF::BinaryCodec_RCF()
@@ -246,56 +277,62 @@ BinaryCodec_RCF::BinaryCodec_RCF()
OSL_ENSURE( mhDigest != 0, "BinaryCodec_RCF::BinaryCodec_RCF - cannot create digest" );
(void)memset( mpnDigestValue, 0, sizeof( mpnDigestValue ) );
+ (void)memset (mpnUnique, 0, sizeof(mpnUnique));
}
BinaryCodec_RCF::~BinaryCodec_RCF()
{
(void)memset( mpnDigestValue, 0, sizeof( mpnDigestValue ) );
+ (void)memset (mpnUnique, 0, sizeof(mpnUnique));
rtl_digest_destroy( mhDigest );
rtl_cipher_destroy( mhCipher );
}
-void BinaryCodec_RCF::initKey( const sal_uInt16 pnPassData[ 16 ], const sal_uInt8 pnSalt[ 16 ] )
+bool BinaryCodec_RCF::initCodec( const uno::Sequence< beans::NamedValue >& aData )
{
- // create little-endian key data array from password data
- sal_uInt8 pnKeyData[ 64 ];
- (void)memset( pnKeyData, 0, sizeof( pnKeyData ) );
+ bool bResult = sal_False;
- const sal_uInt16* pnCurrPass = pnPassData;
- const sal_uInt16* pnPassEnd = pnPassData + 16;
- sal_uInt8* pnCurrKey = pnKeyData;
- size_t nPassSize = 0;
- for( ; (pnCurrPass < pnPassEnd) && (*pnCurrPass != 0); ++pnCurrPass, ++nPassSize )
+ ::comphelper::SequenceAsHashMap aHashData( aData );
+ uno::Sequence< sal_Int8 > aKey = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97EncryptionKey" ) ), uno::Sequence< sal_Int8 >() );
+
+ if ( aKey.getLength() == RTL_DIGEST_LENGTH_MD5 )
{
- *pnCurrKey++ = static_cast< sal_uInt8 >( *pnCurrPass );
- *pnCurrKey++ = static_cast< sal_uInt8 >( *pnCurrPass >> 8 );
+ (void)memcpy( mpnDigestValue, aKey.getConstArray(), RTL_DIGEST_LENGTH_MD5 );
+ uno::Sequence< sal_Int8 > aUniqueID = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97UniqueID" ) ), uno::Sequence< sal_Int8 >() );
+ if ( aUniqueID.getLength() == 16 )
+ {
+ (void)memcpy( mpnUnique, aUniqueID.getConstArray(), 16 );
+ bResult = sal_False;
+ }
+ else
+ OSL_ENSURE( sal_False, "Unexpected document ID!\n" );
}
- pnKeyData[ 2 * nPassSize ] = 0x80;
- pnKeyData[ 56 ] = static_cast< sal_uInt8 >( nPassSize << 4 );
+ else
+ OSL_ENSURE( sal_False, "Unexpected key size!\n" );
- // fill raw digest of key data into key data
- (void)rtl_digest_updateMD5( mhDigest, pnKeyData, sizeof( pnKeyData ) );
- (void)rtl_digest_rawMD5( mhDigest, pnKeyData, RTL_DIGEST_LENGTH_MD5 );
+ return bResult;
+}
- // update digest with key data and passed salt data
- for( size_t nIndex = 0; nIndex < 16; ++nIndex )
- {
- rtl_digest_updateMD5( mhDigest, pnKeyData, 5 );
- rtl_digest_updateMD5( mhDigest, pnSalt, 16 );
- }
+uno::Sequence< beans::NamedValue > BinaryCodec_RCF::getEncryptionData()
+{
+ ::comphelper::SequenceAsHashMap aHashData;
+ aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97EncryptionKey" ) ) ] <<= uno::Sequence< sal_Int8 >( (sal_Int8*)mpnDigestValue, RTL_DIGEST_LENGTH_MD5 );
+ aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97UniqueID" ) ) ] <<= uno::Sequence< sal_Int8 >( (sal_Int8*)mpnUnique, 16 );
- // update digest with padding
- pnKeyData[ 16 ] = 0x80;
- (void)memset( pnKeyData + 17, 0, sizeof( pnKeyData ) - 17 );
- pnKeyData[ 56 ] = 0x80;
- pnKeyData[ 57 ] = 0x0A;
- rtl_digest_updateMD5( mhDigest, pnKeyData + 16, sizeof( pnKeyData ) - 16 );
+ return aHashData.getAsConstNamedValueList();
+}
- // fill raw digest of above updates into digest value
- rtl_digest_rawMD5( mhDigest, mpnDigestValue, sizeof( mpnDigestValue ) );
+void BinaryCodec_RCF::initKey( const sal_uInt16 pnPassData[ 16 ], const sal_uInt8 pnSalt[ 16 ] )
+{
+ uno::Sequence< sal_Int8 > aKey = ::comphelper::DocPasswordHelper::GenerateStd97Key( pnPassData, uno::Sequence< sal_Int8 >( (sal_Int8*)pnSalt, 16 ) );
+ // Fill raw digest of above updates into DigestValue.
- // erase key data array and leave
- (void)memset( pnKeyData, 0, sizeof( pnKeyData ) );
+ if ( aKey.getLength() == sizeof(mpnDigestValue) )
+ (void)memcpy ( mpnDigestValue, (const sal_uInt8*)aKey.getConstArray(), sizeof(mpnDigestValue) );
+ else
+ memset( mpnDigestValue, 0, sizeof(mpnDigestValue) );
+
+ (void)memcpy( mpnUnique, pnSalt, 16 );
}
bool BinaryCodec_RCF::verifyKey( const sal_uInt8 pnVerifier[ 16 ], const sal_uInt8 pnVerifierHash[ 16 ] )
diff --git a/oox/source/core/filterbase.cxx b/oox/source/core/filterbase.cxx
index 9b7b00988dd0..6d2b98454444 100755..100644
--- a/oox/source/core/filterbase.cxx
+++ b/oox/source/core/filterbase.cxx
@@ -67,6 +67,8 @@ using ::comphelper::MediaDescriptor;
using ::comphelper::SequenceAsHashMap;
using ::oox::ole::OleObjectHelper;
+using namespace ::com::sun::star;
+
namespace oox {
namespace core {
@@ -399,7 +401,7 @@ OleObjectHelper& FilterBase::getOleObjectHelper() const
return *mxImpl->mxOleObjHelper;
}
-OUString FilterBase::requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) const
+uno::Sequence< beans::NamedValue > FilterBase::requestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ) const
{
::std::vector< OUString > aDefaultPasswords;
aDefaultPasswords.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) );
diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx
index 00244c224778..53d8809330d9 100644
--- a/oox/source/core/filterdetect.cxx
+++ b/oox/source/core/filterdetect.cxx
@@ -65,6 +65,8 @@ using ::com::sun::star::xml::sax::XLocator;
using ::comphelper::MediaDescriptor;
using ::comphelper::SequenceAsHashMap;
+using namespace ::com::sun::star;
+
namespace oox {
namespace core {
@@ -366,7 +368,49 @@ void lclDeriveKey( const sal_uInt8* pnHash, sal_uInt32 nHashLen, sal_uInt8* pnKe
// ----------------------------------------------------------------------------
-bool lclGenerateEncryptionKey( const PackageEncryptionInfo& rEncrInfo, const OUString& rPassword, sal_uInt8* pnKey, sal_uInt32 nRequiredKeyLen )
+bool lclCheckEncryptionData( const sal_uInt8* pnKey, sal_uInt32 nKeySize, const sal_uInt8* pnVerifier, sal_uInt32 nVerifierSize, const sal_uInt8* pnVerifierHash, sal_uInt32 nVerifierHashSize )
+{
+ bool bResult = false;
+
+ // the only currently supported algorithm needs key size 128
+ if ( nKeySize == 16 && nVerifierSize == 16 && nVerifierHashSize == 32 )
+ {
+ // check password
+ EVP_CIPHER_CTX aes_ctx;
+ EVP_CIPHER_CTX_init( &aes_ctx );
+ EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, pnKey, 0 );
+ EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 );
+ int nOutLen = 0;
+ sal_uInt8 pnTmpVerifier[ 16 ];
+ (void) memset( pnTmpVerifier, 0, sizeof(pnTmpVerifier) );
+
+ /*int*/ EVP_DecryptUpdate( &aes_ctx, pnTmpVerifier, &nOutLen, pnVerifier, nVerifierSize );
+ EVP_CIPHER_CTX_cleanup( &aes_ctx );
+
+ EVP_CIPHER_CTX_init( &aes_ctx );
+ EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, pnKey, 0 );
+ EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 );
+ sal_uInt8 pnTmpVerifierHash[ 32 ];
+ (void) memset( pnTmpVerifierHash, 0, sizeof(pnTmpVerifierHash) );
+
+ /*int*/ EVP_DecryptUpdate( &aes_ctx, pnTmpVerifierHash, &nOutLen, pnVerifierHash, nVerifierHashSize );
+ EVP_CIPHER_CTX_cleanup( &aes_ctx );
+
+ rtlDigest aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 );
+ rtlDigestError aError = rtl_digest_update( aDigest, pnTmpVerifier, sizeof( pnTmpVerifier ) );
+ sal_uInt8 pnSha1Hash[ RTL_DIGEST_LENGTH_SHA1 ];
+ aError = rtl_digest_get( aDigest, pnSha1Hash, RTL_DIGEST_LENGTH_SHA1 );
+ rtl_digest_destroy( aDigest );
+
+ bResult = ( memcmp( pnSha1Hash, pnTmpVerifierHash, RTL_DIGEST_LENGTH_SHA1 ) == 0 );
+ }
+
+ return bResult;
+}
+
+// ----------------------------------------------------------------------------
+
+uno::Sequence< beans::NamedValue > lclGenerateEncryptionKey( const PackageEncryptionInfo& rEncrInfo, const OUString& rPassword, sal_uInt8* pnKey, sal_uInt32 nRequiredKeyLen )
{
size_t nBufferSize = rEncrInfo.mnSaltSize + 2 * rPassword.getLength();
sal_uInt8* pnBuffer = new sal_uInt8[ nBufferSize ];
@@ -405,30 +449,19 @@ bool lclGenerateEncryptionKey( const PackageEncryptionInfo& rEncrInfo, const OUS
lclDeriveKey( pnHash, RTL_DIGEST_LENGTH_SHA1, pnKey, nRequiredKeyLen );
delete[] pnHash;
- // check password
- EVP_CIPHER_CTX aes_ctx;
- EVP_CIPHER_CTX_init( &aes_ctx );
- EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, pnKey, 0 );
- EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 );
- int nOutLen = 0;
- sal_uInt8 pnVerifier[ 16 ] = { 0 };
- /*int*/ EVP_DecryptUpdate( &aes_ctx, pnVerifier, &nOutLen, rEncrInfo.mpnEncrVerifier, sizeof( rEncrInfo.mpnEncrVerifier ) );
- EVP_CIPHER_CTX_cleanup( &aes_ctx );
-
- EVP_CIPHER_CTX_init( &aes_ctx );
- EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, pnKey, 0 );
- EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 );
- sal_uInt8 pnVerifierHash[ 32 ] = { 0 };
- /*int*/ EVP_DecryptUpdate( &aes_ctx, pnVerifierHash, &nOutLen, rEncrInfo.mpnEncrVerifierHash, sizeof( rEncrInfo.mpnEncrVerifierHash ) );
- EVP_CIPHER_CTX_cleanup( &aes_ctx );
+ uno::Sequence< beans::NamedValue > aResult;
+ if ( lclCheckEncryptionData( pnKey, nRequiredKeyLen, rEncrInfo.mpnEncrVerifier, sizeof( rEncrInfo.mpnEncrVerifier ), rEncrInfo.mpnEncrVerifierHash, sizeof( rEncrInfo.mpnEncrVerifierHash ) ) )
+ {
+ ::comphelper::SequenceAsHashMap aEncryptionData;
+ aEncryptionData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AES128EncryptionKey" ) ) ] <<= uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( pnKey ), nRequiredKeyLen );
+ aEncryptionData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AES128EncryptionSalt" ) ) ] <<= uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( rEncrInfo.mpnSalt ), rEncrInfo.mnSaltSize );
+ aEncryptionData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AES128EncryptionVerifier" ) ) ] <<= uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( rEncrInfo.mpnEncrVerifier ), sizeof( rEncrInfo.mpnEncrVerifier ) );
+ aEncryptionData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AES128EncryptionVerifierHash" ) ) ] <<= uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( rEncrInfo.mpnEncrVerifierHash ), sizeof( rEncrInfo.mpnEncrVerifierHash ) );
- aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 );
- aError = rtl_digest_update( aDigest, pnVerifier, sizeof( pnVerifier ) );
- sal_uInt8 pnSha1Hash[ RTL_DIGEST_LENGTH_SHA1 ];
- aError = rtl_digest_get( aDigest, pnSha1Hash, RTL_DIGEST_LENGTH_SHA1 );
- rtl_digest_destroy( aDigest );
+ aResult = aEncryptionData.getAsConstNamedValueList();
+ }
- return memcmp( pnSha1Hash, pnVerifierHash, RTL_DIGEST_LENGTH_SHA1 ) == 0;
+ return aResult;
}
// the password verifier ------------------------------------------------------
@@ -438,8 +471,8 @@ class PasswordVerifier : public ::comphelper::IDocPasswordVerifier
public:
explicit PasswordVerifier( const PackageEncryptionInfo& rEncryptInfo );
- virtual ::comphelper::DocPasswordVerifierResult
- verifyPassword( const OUString& rPassword );
+ virtual ::comphelper::DocPasswordVerifierResult verifyPassword( const ::rtl::OUString& rPassword, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& o_rEncryptionData );
+ virtual ::comphelper::DocPasswordVerifierResult verifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData );
inline const sal_uInt8* getKey() const { return &maKey.front(); }
@@ -454,13 +487,31 @@ PasswordVerifier::PasswordVerifier( const PackageEncryptionInfo& rEncryptInfo )
{
}
-::comphelper::DocPasswordVerifierResult PasswordVerifier::verifyPassword( const OUString& rPassword )
+::comphelper::DocPasswordVerifierResult PasswordVerifier::verifyPassword( const ::rtl::OUString& rPassword, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& o_rEncryptionData )
{
// verifies the password and writes the related decryption key into maKey
- return lclGenerateEncryptionKey( mrEncryptInfo, rPassword, &maKey.front(), maKey.size() ) ?
+ o_rEncryptionData = lclGenerateEncryptionKey( mrEncryptInfo, rPassword, &maKey.front(), maKey.size() );
+ return ( o_rEncryptionData.getLength() > 0 ) ?
::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
}
+::comphelper::DocPasswordVerifierResult PasswordVerifier::verifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData )
+{
+ ::comphelper::SequenceAsHashMap aHashData( rEncryptionData );
+ uno::Sequence< sal_Int8 > aKey = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AES128EncryptionKey" ) ), uno::Sequence< sal_Int8 >() );
+ uno::Sequence< sal_Int8 > aVerifier = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AES128EncryptionVerifier" ) ), uno::Sequence< sal_Int8 >() );
+ uno::Sequence< sal_Int8 > aVerifierHash = aHashData.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AES128EncryptionVerifierHash" ) ), uno::Sequence< sal_Int8 >() );
+
+ return lclCheckEncryptionData(
+ reinterpret_cast< const sal_uInt8* >( aKey.getConstArray() ),
+ aKey.getLength(),
+ reinterpret_cast< const sal_uInt8* >( aVerifier.getConstArray() ),
+ aVerifier.getLength(),
+ reinterpret_cast< const sal_uInt8* >( aVerifierHash.getConstArray() ),
+ aVerifierHash.getLength() )
+ ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
+}
+
} // namespace
// ----------------------------------------------------------------------------
@@ -520,10 +571,10 @@ Reference< XInputStream > FilterDetect::extractUnencryptedPackage( MediaDescript
(according to the verifier), or with an empty string if
user has cancelled the password input dialog. */
PasswordVerifier aVerifier( aEncryptInfo );
- OUString aPassword = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
+ uno::Sequence< beans::NamedValue > aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
aVerifier, rMediaDesc, ::comphelper::DocPasswordRequestType_MS, &aDefaultPasswords );
- if( aPassword.getLength() == 0 )
+ if( aEncryptionData.getLength() == 0 )
{
rMediaDesc[ MediaDescriptor::PROP_ABORTED() ] <<= true;
}
diff --git a/oox/source/xls/biffcodec.cxx b/oox/source/xls/biffcodec.cxx
index 2021c21cb08c..0872dcc654df 100644
--- a/oox/source/xls/biffcodec.cxx
+++ b/oox/source/xls/biffcodec.cxx
@@ -36,6 +36,8 @@ using ::rtl::OUString;
using ::rtl::OStringToOUString;
using ::oox::core::FilterBase;
+using namespace ::com::sun::star;
+
namespace oox {
namespace xls {
@@ -50,9 +52,16 @@ BiffDecoderBase::~BiffDecoderBase()
{
}
-::comphelper::DocPasswordVerifierResult BiffDecoderBase::verifyPassword( const OUString& rPassword )
+::comphelper::DocPasswordVerifierResult BiffDecoderBase::verifyPassword( const ::rtl::OUString& rPassword, uno::Sequence< beans::NamedValue >& o_rEncryptionData )
+{
+ o_rEncryptionData = implVerifyPassword( rPassword );
+ mbValid = ( o_rEncryptionData.getLength() > 0 );
+ return mbValid ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
+}
+
+::comphelper::DocPasswordVerifierResult BiffDecoderBase::verifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData )
{
- mbValid = implVerify( rPassword );
+ mbValid = implVerifyEncryptionData( rEncryptionData );
return mbValid ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
}
@@ -71,7 +80,6 @@ void BiffDecoderBase::decode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData,
BiffDecoder_XOR::BiffDecoder_XOR( sal_uInt16 nKey, sal_uInt16 nHash ) :
maCodec( ::oox::core::BinaryCodec_XOR::CODEC_EXCEL ),
- maPassword( 16 ),
mnKey( nKey ),
mnHash( nHash )
{
@@ -80,12 +88,12 @@ BiffDecoder_XOR::BiffDecoder_XOR( sal_uInt16 nKey, sal_uInt16 nHash ) :
BiffDecoder_XOR::BiffDecoder_XOR( const BiffDecoder_XOR& rDecoder ) :
BiffDecoderBase(), // must be called to prevent compiler warning
maCodec( ::oox::core::BinaryCodec_XOR::CODEC_EXCEL ),
- maPassword( rDecoder.maPassword ),
+ maEncryptionData( rDecoder.maEncryptionData ),
mnKey( rDecoder.mnKey ),
mnHash( rDecoder.mnHash )
{
if( isValid() )
- maCodec.initKey( &maPassword.front() );
+ maCodec.initCodec( maEncryptionData );
}
BiffDecoder_XOR* BiffDecoder_XOR::implClone()
@@ -93,24 +101,40 @@ BiffDecoder_XOR* BiffDecoder_XOR::implClone()
return new BiffDecoder_XOR( *this );
}
-bool BiffDecoder_XOR::implVerify( const OUString& rPassword )
+uno::Sequence< beans::NamedValue > BiffDecoder_XOR::implVerifyPassword( const ::rtl::OUString& rPassword )
{
+ maEncryptionData.realloc( 0 );
+
/* Convert password to a byte string. TODO: this needs some finetuning
according to the spec... */
OString aBytePassword = OUStringToOString( rPassword, osl_getThreadTextEncoding() );
sal_Int32 nLen = aBytePassword.getLength();
if( (0 < nLen) && (nLen < 16) )
{
- // copy byte string to sal_uInt8 array
- maPassword.clear();
- maPassword.resize( 16, 0 );
- memcpy( &maPassword.front(), aBytePassword.getStr(), static_cast< size_t >( nLen ) );
+ // init codec
+ maCodec.initKey( (sal_uInt8*)aBytePassword.getStr() );
+ if ( maCodec.verifyKey( mnKey, mnHash ) )
+ maEncryptionData = maCodec.getEncryptionData();
+ }
+
+ return maEncryptionData;
+}
+
+bool BiffDecoder_XOR::implVerifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData )
+{
+ maEncryptionData.realloc( 0 );
+
+ if( rEncryptionData.getLength() )
+ {
// init codec
- maCodec.initKey( &maPassword.front() );
- return maCodec.verifyKey( mnKey, mnHash );
+ maCodec.initCodec( rEncryptionData );
+
+ if ( maCodec.verifyKey( mnKey, mnHash ) )
+ maEncryptionData = rEncryptionData;
}
- return false;
+
+ return maEncryptionData.getLength();
}
void BiffDecoder_XOR::implDecode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes )
@@ -141,7 +165,6 @@ sal_Int32 lclGetRcfOffset( sal_Int64 nStreamPos )
// ----------------------------------------------------------------------------
BiffDecoder_RCF::BiffDecoder_RCF( sal_uInt8 pnSalt[ 16 ], sal_uInt8 pnVerifier[ 16 ], sal_uInt8 pnVerifierHash[ 16 ] ) :
- maPassword( 16, 0 ),
maSalt( pnSalt, pnSalt + 16 ),
maVerifier( pnVerifier, pnVerifier + 16 ),
maVerifierHash( pnVerifierHash, pnVerifierHash + 16 )
@@ -150,13 +173,13 @@ BiffDecoder_RCF::BiffDecoder_RCF( sal_uInt8 pnSalt[ 16 ], sal_uInt8 pnVerifier[
BiffDecoder_RCF::BiffDecoder_RCF( const BiffDecoder_RCF& rDecoder ) :
BiffDecoderBase(), // must be called to prevent compiler warning
- maPassword( rDecoder.maPassword ),
+ maEncryptionData( rDecoder.maEncryptionData ),
maSalt( rDecoder.maSalt ),
maVerifier( rDecoder.maVerifier ),
maVerifierHash( rDecoder.maVerifierHash )
{
if( isValid() )
- maCodec.initKey( &maPassword.front(), &maSalt.front() );
+ maCodec.initCodec( maEncryptionData );
}
BiffDecoder_RCF* BiffDecoder_RCF::implClone()
@@ -164,27 +187,48 @@ BiffDecoder_RCF* BiffDecoder_RCF::implClone()
return new BiffDecoder_RCF( *this );
}
-bool BiffDecoder_RCF::implVerify( const OUString& rPassword )
+uno::Sequence< beans::NamedValue > BiffDecoder_RCF::implVerifyPassword( const ::rtl::OUString& rPassword )
{
+ maEncryptionData.realloc( 0 );
+
sal_Int32 nLen = rPassword.getLength();
if( (0 < nLen) && (nLen < 16) )
{
// copy string to sal_uInt16 array
- maPassword.clear();
- maPassword.resize( 16, 0 );
+ ::std::vector< sal_uInt16 > aPassVect( 16 );
const sal_Unicode* pcChar = rPassword.getStr();
const sal_Unicode* pcCharEnd = pcChar + nLen;
- ::std::vector< sal_uInt16 >::iterator aIt = maPassword.begin();
+ ::std::vector< sal_uInt16 >::iterator aIt = aPassVect.begin();
for( ; pcChar < pcCharEnd; ++pcChar, ++aIt )
*aIt = static_cast< sal_uInt16 >( *pcChar );
// init codec
- maCodec.initKey( &maPassword.front(), &maSalt.front() );
- return maCodec.verifyKey( &maVerifier.front(), &maVerifierHash.front() );
+ maCodec.initKey( &aPassVect.front(), &maSalt.front() );
+ if ( maCodec.verifyKey( &maVerifier.front(), &maVerifierHash.front() ) )
+ maEncryptionData = maCodec.getEncryptionData();
+ }
+
+ return maEncryptionData;
+}
+
+bool BiffDecoder_RCF::implVerifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData )
+{
+ maEncryptionData.realloc( 0 );
+
+ if( rEncryptionData.getLength() )
+ {
+ // init codec
+ maCodec.initCodec( rEncryptionData );
+
+ if ( maCodec.verifyKey( &maVerifier.front(), &maVerifierHash.front() ) )
+ maEncryptionData = rEncryptionData;
}
- return false;
+
+ return maEncryptionData.getLength();
}
+
+
void BiffDecoder_RCF::implDecode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes )
{
sal_uInt8* pnCurrDest = pnDestData;
@@ -316,7 +360,7 @@ bool BiffCodecHelper::importFilePass( BiffInputStream& rStrm )
mxDecoder = implReadFilePass( rStrm, getBiff() );
// request and verify a password (decoder implements IDocPasswordVerifier)
if( mxDecoder.get() )
- getBaseFilter().requestPassword( *mxDecoder );
+ getBaseFilter().requestEncryptionData( *mxDecoder );
// correct password is indicated by isValid() function of decoder
return mxDecoder.get() && mxDecoder->isValid();
}