summaryrefslogtreecommitdiff
path: root/comphelper
diff options
context:
space:
mode:
authorMikhail Voytenko <mav@openoffice.org>2010-06-03 00:10:45 +0200
committerMikhail Voytenko <mav@openoffice.org>2010-06-03 00:10:45 +0200
commit386eebb4cfa473de8db4a8337050ff20cce521a9 (patch)
treed3c20eee13f78f9e80d9beadf8b2b8ad77574cbc /comphelper
parent3bc1deabfab6cc1bfe069f6f6b131aee153f9ba9 (diff)
tl78: #i110383# password to modify support for binary types only
Diffstat (limited to 'comphelper')
-rw-r--r--comphelper/inc/comphelper/docpasswordhelper.hxx32
-rw-r--r--comphelper/source/misc/docpasswordhelper.cxx91
2 files changed, 122 insertions, 1 deletions
diff --git a/comphelper/inc/comphelper/docpasswordhelper.hxx b/comphelper/inc/comphelper/docpasswordhelper.hxx
index fd04a82ec563..1a734ebf5518 100644
--- a/comphelper/inc/comphelper/docpasswordhelper.hxx
+++ b/comphelper/inc/comphelper/docpasswordhelper.hxx
@@ -85,8 +85,38 @@ public:
// ------------------------------------------------------------------------
/** This helper function generates the hash code based on the algorithm
+ specified by MS for "Password to modify" feature of Word.
+
+ @param aString
+ The string for which the hash should be calculated
+
+ @return
+ The hash represented by sal_uInt32
+ */
+
+ static sal_uInt32 GetWordHashAsUINT32(
+ const ::rtl::OUString& aString );
+
+ // ------------------------------------------------------------------------
+
+ /** This helper function generates the hash code based on the algorithm
+ specified by MS for "Password to modify" feature of Word.
+
+ @param aString
+ The string for which the hash should be calculated
+
+ @return
+ The hash represented by sequence of bytes in BigEndian form
+ */
+
+ static ::com::sun::star::uno::Sequence< sal_Int8 > GetWordHashAsSequence(
+ const ::rtl::OUString& aString );
+
+ // ------------------------------------------------------------------------
+
+ /** This helper function generates the hash code based on the algorithm
specified by MS for "Password to modify" and passwords related to
- table protection.
+ table protection of Excel.
@param aString
The string for which the hash should be calculated
diff --git a/comphelper/source/misc/docpasswordhelper.cxx b/comphelper/source/misc/docpasswordhelper.cxx
index 5a5d2110deff..5238e33fead6 100644
--- a/comphelper/source/misc/docpasswordhelper.cxx
+++ b/comphelper/source/misc/docpasswordhelper.cxx
@@ -52,6 +52,97 @@ IDocPasswordVerifier::~IDocPasswordVerifier()
}
// ============================================================================
+sal_uInt32 DocPasswordHelper::GetWordHashAsUINT32(
+ const ::rtl::OUString& aUString )
+{
+ static sal_uInt16 pInitialCode[] = {
+ 0xE1F0, // 1
+ 0x1D0F, // 2
+ 0xCC9C, // 3
+ 0x84C0, // 4
+ 0x110C, // 5
+ 0x0E10, // 6
+ 0xF1CE, // 7
+ 0x313E, // 8
+ 0x1872, // 9
+ 0xE139, // 10
+ 0xD40F, // 11
+ 0x84F9, // 12
+ 0x280C, // 13
+ 0xA96A, // 14
+ 0x4EC3 // 15
+ };
+
+ static sal_uInt16 pEncryptionMatrix[15][7] = {
+ { 0xAEFC, 0x4DD9, 0x9BB2, 0x2745, 0x4E8A, 0x9D14, 0x2A09}, // last-14
+ { 0x7B61, 0xF6C2, 0xFDA5, 0xEB6B, 0xC6F7, 0x9DCF, 0x2BBF}, // last-13
+ { 0x4563, 0x8AC6, 0x05AD, 0x0B5A, 0x16B4, 0x2D68, 0x5AD0}, // last-12
+ { 0x0375, 0x06EA, 0x0DD4, 0x1BA8, 0x3750, 0x6EA0, 0xDD40}, // last-11
+ { 0xD849, 0xA0B3, 0x5147, 0xA28E, 0x553D, 0xAA7A, 0x44D5}, // last-10
+ { 0x6F45, 0xDE8A, 0xAD35, 0x4A4B, 0x9496, 0x390D, 0x721A}, // last-9
+ { 0xEB23, 0xC667, 0x9CEF, 0x29FF, 0x53FE, 0xA7FC, 0x5FD9}, // last-8
+ { 0x47D3, 0x8FA6, 0x8FA6, 0x1EDA, 0x3DB4, 0x7B68, 0xF6D0}, // last-7
+ { 0xB861, 0x60E3, 0xC1C6, 0x93AD, 0x377B, 0x6EF6, 0xDDEC}, // last-6
+ { 0x45A0, 0x8B40, 0x06A1, 0x0D42, 0x1A84, 0x3508, 0x6A10}, // last-5
+ { 0xAA51, 0x4483, 0x8906, 0x022D, 0x045A, 0x08B4, 0x1168}, // last-4
+ { 0x76B4, 0xED68, 0xCAF1, 0x85C3, 0x1BA7, 0x374E, 0x6E9C}, // last-3
+ { 0x3730, 0x6E60, 0xDCC0, 0xA9A1, 0x4363, 0x86C6, 0x1DAD}, // last-2
+ { 0x3331, 0x6662, 0xCCC4, 0x89A9, 0x0373, 0x06E6, 0x0DCC}, // last-1
+ { 0x1021, 0x2042, 0x4084, 0x8108, 0x1231, 0x2462, 0x48C4} // last
+ };
+
+ sal_uInt32 nResult = 0;
+ sal_uInt32 nLen = aUString.getLength();
+
+ if ( nLen )
+ {
+ if ( nLen > 15 )
+ nLen = 15;
+
+ sal_uInt16 nHighResult = pInitialCode[nLen - 1];
+ sal_uInt16 nLowResult = 0;
+
+ const sal_Unicode* pStr = aUString.getStr();
+ for ( sal_Int32 nInd = 0; nInd < nLen; nInd++ )
+ {
+ // NO Encoding during conversion!
+ // The specification says that the low byte should be used in case it is not NULL
+ char nHighChar = (char)( pStr[nInd] >> 8 );
+ char nLowChar = (char)( pStr[nInd] & 0xFF );
+ char nChar = nLowChar ? nLowChar : nHighChar;
+
+ for ( int nMatrixInd = 0; nMatrixInd < 7; ++nMatrixInd )
+ {
+ if ( ( nChar & ( 1 << nMatrixInd ) ) != 0 )
+ nHighResult = nHighResult ^ pEncryptionMatrix[15 - nLen + nInd][nMatrixInd];
+ }
+
+ nLowResult = ( ( ( nLowResult >> 14 ) & 0x0001 ) | ( ( nLowResult << 1 ) & 0x7FFF ) ) ^ nChar;
+ }
+
+ nLowResult = ( ( ( nLowResult >> 14 ) & 0x001 ) | ( ( nLowResult << 1 ) & 0x7FF ) ) ^ nLen ^ 0xCE4B;
+
+ nResult = ( nHighResult << 16 ) | nLowResult;
+ }
+
+ return nResult;
+}
+
+// ============================================================================
+Sequence< sal_Int8 > DocPasswordHelper::GetWordHashAsSequence(
+ const ::rtl::OUString& aUString )
+{
+ sal_uInt32 nHash = GetWordHashAsUINT32( aUString );
+ Sequence< sal_Int8 > aResult( 4 );
+ aResult[0] = ( nHash >> 24 );
+ aResult[1] = ( nHash & 0xFF0000 );
+ aResult[2] = ( nHash & 0xFF00 );
+ aResult[3] = ( nHash & 0xFF );
+
+ return aResult;
+}
+
+// ============================================================================
sal_uInt16 DocPasswordHelper::GetXLHashAsUINT16(
const ::rtl::OUString& aUString,
rtl_TextEncoding nEnc )