From 384954795c4f3c0641f4b0eb7cff6f27ebfbb5de Mon Sep 17 00:00:00 2001 From: Eike Rathke Date: Mon, 26 Feb 2018 12:14:03 +0100 Subject: Move convenience abstractions to DocPasswordHelper, tdf#104250 follow-up Change-Id: If0775ccf14b631918e51342a767412948e812c87 --- comphelper/qa/unit/test_hash.cxx | 3 +- comphelper/source/misc/docpasswordhelper.cxx | 48 ++++++++++++++++++++++ comphelper/source/misc/hash.cxx | 46 ---------------------- include/comphelper/docpasswordhelper.hxx | 59 ++++++++++++++++++++++++++++ include/comphelper/hash.hxx | 51 +----------------------- sc/source/core/data/tabprotection.cxx | 3 +- 6 files changed, 112 insertions(+), 98 deletions(-) diff --git a/comphelper/qa/unit/test_hash.cxx b/comphelper/qa/unit/test_hash.cxx index e15b906c190f..11dcbd0bd10f 100644 --- a/comphelper/qa/unit/test_hash.cxx +++ b/comphelper/qa/unit/test_hash.cxx @@ -8,6 +8,7 @@ */ #include +#include #include #include @@ -111,7 +112,7 @@ void TestHash::testSHA512_saltspin() const OUString aPass("pwd"); const OUString aAlgo("SHA-512"); const OUString aSalt("876MLoKTq42+/DLp415iZQ=="); - const OUString aHash = comphelper::Hash::calculateHashBase64( aPass, aSalt, 100000, aAlgo); + const OUString aHash = comphelper::DocPasswordHelper::GetOoxHashAsBase64( aPass, aSalt, 100000, aAlgo); const OUString aStr("5l3mgNHXpWiFaBPv5Yso1Xd/UifWvQWmlDnl/hsCYbFT2sJCzorjRmBCQ/3qeDu6Q/4+GIE8a1DsdaTwYh1q2g=="); CPPUNIT_ASSERT_EQUAL(aStr, aHash); } diff --git a/comphelper/source/misc/docpasswordhelper.cxx b/comphelper/source/misc/docpasswordhelper.cxx index 81e1e996816f..e6055b29cebc 100644 --- a/comphelper/source/misc/docpasswordhelper.cxx +++ b/comphelper/source/misc/docpasswordhelper.cxx @@ -23,6 +23,9 @@ #include #include +#include +#include +#include #include #include #include @@ -256,6 +259,51 @@ Sequence< sal_Int8 > DocPasswordHelper::GetXLHashAsSequence( } +css::uno::Sequence DocPasswordHelper::GetOoxHashAsSequence( + const rtl::OUString& rPassword, + const rtl::OUString& rSaltValue, + sal_uInt32 nSpinCount, + const rtl::OUString& rAlgorithmName) +{ + comphelper::HashType eType; + if (rAlgorithmName == "SHA-512") + eType = comphelper::HashType::SHA512; + else if (rAlgorithmName == "SHA-256") + eType = comphelper::HashType::SHA256; + else if (rAlgorithmName == "SHA-1") + eType = comphelper::HashType::SHA1; + else if (rAlgorithmName == "MD5") + eType = comphelper::HashType::MD5; + else + return css::uno::Sequence(); + + std::vector aSaltVec; + if (!rSaltValue.isEmpty()) + { + css::uno::Sequence aSaltSeq; + comphelper::Base64::decode( aSaltSeq, rSaltValue); + aSaltVec = comphelper::sequenceToContainer>( aSaltSeq); + } + + std::vector hash( comphelper::Hash::calculateHash( rPassword, aSaltVec, nSpinCount, eType)); + + return comphelper::containerToSequence( hash); +} + +OUString DocPasswordHelper::GetOoxHashAsBase64( + const rtl::OUString& rPassword, + const rtl::OUString& rSaltValue, + sal_uInt32 nSpinCount, + const rtl::OUString& rAlgorithmName) +{ + css::uno::Sequence aSeq( GetOoxHashAsSequence( rPassword, rSaltValue, nSpinCount, rAlgorithmName)); + + OUStringBuffer aBuf; + comphelper::Base64::encode( aBuf, aSeq); + return aBuf.makeStringAndClear(); +} + + /*static*/ uno::Sequence< sal_Int8 > DocPasswordHelper::GenerateRandomByteSequence( sal_Int32 nLength ) { uno::Sequence< sal_Int8 > aResult( nLength ); diff --git a/comphelper/source/misc/hash.cxx b/comphelper/source/misc/hash.cxx index 0a91536347b9..b629d8d17530 100644 --- a/comphelper/source/misc/hash.cxx +++ b/comphelper/source/misc/hash.cxx @@ -8,8 +8,6 @@ */ #include -#include -#include #include #include #include @@ -231,50 +229,6 @@ std::vector Hash::calculateHash( return calculateHash( pPassBytes, nPassBytesLen, rSaltValue.data(), rSaltValue.size(), nSpinCount, eType); } -css::uno::Sequence Hash::calculateHashSequence( - const rtl::OUString& rPassword, - const rtl::OUString& rSaltValue, - sal_uInt32 nSpinCount, - const rtl::OUString& rAlgorithmName) -{ - HashType eType; - if (rAlgorithmName == "SHA-512") - eType = HashType::SHA512; - else if (rAlgorithmName == "SHA-256") - eType = HashType::SHA256; - else if (rAlgorithmName == "SHA-1") - eType = HashType::SHA1; - else if (rAlgorithmName == "MD5") - eType = HashType::MD5; - else - return css::uno::Sequence(); - - std::vector aSaltVec; - if (!rSaltValue.isEmpty()) - { - css::uno::Sequence aSaltSeq; - comphelper::Base64::decode( aSaltSeq, rSaltValue); - aSaltVec = comphelper::sequenceToContainer>( aSaltSeq); - } - - std::vector hash( calculateHash( rPassword, aSaltVec, nSpinCount, eType)); - - return comphelper::containerToSequence( hash); -} - -OUString Hash::calculateHashBase64( - const rtl::OUString& rPassword, - const rtl::OUString& rSaltValue, - sal_uInt32 nSpinCount, - const rtl::OUString& rAlgorithmName) -{ - css::uno::Sequence aSeq( calculateHashSequence( rPassword, rSaltValue, nSpinCount, rAlgorithmName)); - - OUStringBuffer aBuf; - comphelper::Base64::encode( aBuf, aSeq); - return aBuf.makeStringAndClear(); -} - } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/docpasswordhelper.hxx b/include/comphelper/docpasswordhelper.hxx index e420cf3e69af..51ecb7102abd 100644 --- a/include/comphelper/docpasswordhelper.hxx +++ b/include/comphelper/docpasswordhelper.hxx @@ -180,6 +180,65 @@ public: const OUString& aString ); + /** Convenience function to calculate a salted hash with iterations as + specified in https://msdn.microsoft.com/en-us/library/dd920692 for the + OOXML sheetProtection and fileSharing elements. + + @param rPassword + UTF-16LE encoded string without leading BOM character + + @param rSaltValue + Base64 encoded salt that will be decoded and prepended to password + data. + + @param nSpinCount + If >0 the number of repeated iterations. + + @param rAlgorithmName + One of "SHA-512", "SHA-256", ... as listed in + https://msdn.microsoft.com/en-us/library/dd920692 + that have a valid match in HashType. If not, an empty string is + returned. Not all algorithm names are supported. + + @return the raw hash value as sal_Int8 sequence. + */ + static css::uno::Sequence GetOoxHashAsSequence( + const rtl::OUString& rPassword, + const rtl::OUString& rSaltValue, + sal_uInt32 nSpinCount, + const rtl::OUString& rAlgorithmName); + + + /** Convenience function to calculate a salted hash with iterations as + specified in https://msdn.microsoft.com/en-us/library/dd920692 for the + OOXML sheetProtection and fileSharing elements. + + @param rPassword + UTF-16LE encoded string without leading BOM character + + @param rSaltValue + Base64 encoded salt that will be decoded and prepended to password + data. + + @param nSpinCount + If >0 the number of repeated iterations. + + @param rAlgorithmName + One of "SHA-512", "SHA-256", ... as listed in + https://msdn.microsoft.com/en-us/library/dd920692 + that have a valid match in HashType. If not, an empty string is + returned. Not all algorithm names are supported. + + @return the base64 encoded string of the hash value, that can be + compared against a stored base64 encoded hash value. + */ + static rtl::OUString GetOoxHashAsBase64( + const rtl::OUString& rPassword, + const rtl::OUString& rSaltValue, + sal_uInt32 nSpinCount, + const rtl::OUString& rAlgorithmName); + + /** This helper function generates a random sequence of bytes of requested length. */ diff --git a/include/comphelper/hash.hxx b/include/comphelper/hash.hxx index b3e97553060d..a9cda038b748 100644 --- a/include/comphelper/hash.hxx +++ b/include/comphelper/hash.hxx @@ -12,8 +12,6 @@ #include -#include - #include #include @@ -73,7 +71,7 @@ public: /** Convenience function to calculate a salted hash with iterations. @param rPassword - UTF-16LE encoded string without leading BOM character + UTF-16LE encoded string, hashed byte-wise as unsigned char. @param rSaltValue Salt that will be prepended to password data. @@ -84,53 +82,6 @@ public: sal_uInt32 nSpinCount, HashType eType); - /** Convenience function to calculate a salted hash with iterations. - - @param rPassword - UTF-16LE encoded string without leading BOM character - - @param rSaltValue - Base64 encoded salt that will be decoded and prepended to password - data. - - @param rAlgorithmName - One of "SHA-512", "SHA-256", ... as listed in - https://msdn.microsoft.com/en-us/library/dd920692 - that have a valid match in HashType. If not, an empty string is - returned. Not all algorithm names are supported. - - @return the raw hash value as sal_Int8 sequence. - */ - static css::uno::Sequence calculateHashSequence( - const rtl::OUString& rPassword, - const rtl::OUString& rSaltValue, - sal_uInt32 nSpinCount, - const rtl::OUString& rAlgorithmName); - - /** Convenience function to calculate a salted hash with iterations. - - @param rPassword - UTF-16LE encoded string without leading BOM character - - @param rSaltValue - Base64 encoded salt that will be decoded and prepended to password - data. - - @param rAlgorithmName - One of "SHA-512", "SHA-256", ... as listed in - https://msdn.microsoft.com/en-us/library/dd920692 - that have a valid match in HashType. If not, an empty string is - returned. Not all algorithm names are supported. - - @return the base64 encoded string of the hash value, that can be - compared against a stored base64 encoded hash value. - */ - static rtl::OUString calculateHashBase64( - const rtl::OUString& rPassword, - const rtl::OUString& rSaltValue, - sal_uInt32 nSpinCount, - const rtl::OUString& rAlgorithmName); - size_t getLength() const; }; diff --git a/sc/source/core/data/tabprotection.cxx b/sc/source/core/data/tabprotection.cxx index 68e7914dc984..f2aa4d3eb4e8 100644 --- a/sc/source/core/data/tabprotection.cxx +++ b/sc/source/core/data/tabprotection.cxx @@ -94,7 +94,8 @@ bool ScOoxPasswordHash::verifyPassword( const OUString& aPassText ) const if (!hasPassword()) return false; - const OUString aHash( comphelper::Hash::calculateHashBase64( aPassText, maSaltValue, mnSpinCount, maAlgorithmName)); + const OUString aHash( comphelper::DocPasswordHelper::GetOoxHashAsBase64( + aPassText, maSaltValue, mnSpinCount, maAlgorithmName)); if (aHash.isEmpty()) // unsupported algorithm return false; -- cgit