[Libreoffice-commits] core.git: comphelper/qa comphelper/source include/comphelper sc/source

Eike Rathke erack at redhat.com
Mon Feb 26 19:07:19 UTC 2018


 comphelper/qa/unit/test_hash.cxx             |    5 ++--
 comphelper/source/misc/docpasswordhelper.cxx |    8 +++----
 comphelper/source/misc/hash.cxx              |   28 ++++++++++++++-----------
 include/comphelper/docpasswordhelper.hxx     |   21 +++++++++++-------
 include/comphelper/hash.hxx                  |   30 ++++++++++++++++++---------
 sc/source/core/data/tabprotection.cxx        |    2 -
 6 files changed, 58 insertions(+), 36 deletions(-)

New commits:
commit 5a1fabb9969772242f2c2aef34b10bed17adebb6
Author: Eike Rathke <erack at redhat.com>
Date:   Mon Feb 26 19:58:12 2018 +0100

    Introduce enum comphelper::Hash::IterCount instead of bool
    
    Clarifies intention, and with IterCount::NONE prepared to handle
    something like old PBKDF1, if anything actually used that. See
    https://tools.ietf.org/html/rfc8018#section-5.1 where iteration
    count is not part of the re-hash.
    
    Change-Id: I5f97ca7a91f611eced8ced0a0c64961c04535d36

diff --git a/comphelper/qa/unit/test_hash.cxx b/comphelper/qa/unit/test_hash.cxx
index 5d2ece34dc83..29ef2b884f28 100644
--- a/comphelper/qa/unit/test_hash.cxx
+++ b/comphelper/qa/unit/test_hash.cxx
@@ -99,7 +99,7 @@ void TestHash::testSHA512_NoSaltNoSpin()
     const char* const pInput = "";
     std::vector<unsigned char> calculate_hash =
         comphelper::Hash::calculateHash( reinterpret_cast<const unsigned char*>(pInput), 0,
-                nullptr, 0, 0, false, comphelper::HashType::SHA512);
+                nullptr, 0, 0, comphelper::Hash::IterCount::NONE, comphelper::HashType::SHA512);
     CPPUNIT_ASSERT_EQUAL(size_t(64), calculate_hash.size());
     std::string aStr("cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e");
     CPPUNIT_ASSERT_EQUAL(aStr, tostring(calculate_hash));
@@ -112,7 +112,8 @@ void TestHash::testSHA512_saltspin()
     const OUString aPass("pwd");
     const OUString aAlgo("SHA-512");
     const OUString aSalt("876MLoKTq42+/DLp415iZQ==");
-    const OUString aHash = comphelper::DocPasswordHelper::GetOoxHashAsBase64( aPass, aSalt, 100000, false, aAlgo);
+    const OUString aHash = comphelper::DocPasswordHelper::GetOoxHashAsBase64( aPass, aSalt, 100000,
+            comphelper::Hash::IterCount::APPEND, 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 5dfd25575d91..8a35c33ca92d 100644
--- a/comphelper/source/misc/docpasswordhelper.cxx
+++ b/comphelper/source/misc/docpasswordhelper.cxx
@@ -263,7 +263,7 @@ css::uno::Sequence<sal_Int8> DocPasswordHelper::GetOoxHashAsSequence(
         const rtl::OUString& rPassword,
         const rtl::OUString& rSaltValue,
         sal_uInt32 nSpinCount,
-        bool bPrependNotAppend,
+        comphelper::Hash::IterCount eIterCount,
         const rtl::OUString& rAlgorithmName)
 {
     comphelper::HashType eType;
@@ -287,7 +287,7 @@ css::uno::Sequence<sal_Int8> DocPasswordHelper::GetOoxHashAsSequence(
     }
 
     std::vector<unsigned char> hash( comphelper::Hash::calculateHash( rPassword, aSaltVec, nSpinCount,
-                bPrependNotAppend, eType));
+                eIterCount, eType));
 
     return comphelper::containerToSequence<sal_Int8>( hash);
 }
@@ -296,11 +296,11 @@ OUString DocPasswordHelper::GetOoxHashAsBase64(
         const rtl::OUString& rPassword,
         const rtl::OUString& rSaltValue,
         sal_uInt32 nSpinCount,
-        bool bPrependNotAppend,
+        comphelper::Hash::IterCount eIterCount,
         const rtl::OUString& rAlgorithmName)
 {
     css::uno::Sequence<sal_Int8> aSeq( GetOoxHashAsSequence( rPassword, rSaltValue, nSpinCount,
-                bPrependNotAppend, rAlgorithmName));
+                eIterCount, rAlgorithmName));
 
     OUStringBuffer aBuf;
     comphelper::Base64::encode( aBuf, aSeq);
diff --git a/comphelper/source/misc/hash.cxx b/comphelper/source/misc/hash.cxx
index 8d709daa75f7..b07fd66c0628 100644
--- a/comphelper/source/misc/hash.cxx
+++ b/comphelper/source/misc/hash.cxx
@@ -157,7 +157,7 @@ std::vector<unsigned char> Hash::calculateHash(
         const unsigned char* pInput, size_t nLength,
         const unsigned char* pSalt, size_t nSaltLen,
         sal_uInt32 nSpinCount,
-        bool bPrependNotAppend,
+        IterCount eIterCount,
         HashType eType)
 {
     if (!pSalt)
@@ -188,21 +188,25 @@ std::vector<unsigned char> Hash::calculateHash(
         // https://msdn.microsoft.com/en-us/library/dd924776 and
         // https://msdn.microsoft.com/en-us/library/dd925430
         // say the iteration is prepended to the hash.
-        const size_t nIterPos = (bPrependNotAppend ? 0 : hash.size());
-        const size_t nHashPos = (bPrependNotAppend ? 4 : 0);
-        std::vector<unsigned char> data( hash.size() + 4, 0);
+        const size_t nAddIter = (eIterCount == IterCount::NONE ? 0 : 4);
+        const size_t nIterPos = (eIterCount == IterCount::APPEND ? hash.size() : 0);
+        const size_t nHashPos = (eIterCount == IterCount::PREPEND ? nAddIter : 0);
+        std::vector<unsigned char> data( hash.size() + nAddIter, 0);
         for (sal_uInt32 i = 0; i < nSpinCount; ++i)
         {
             std::copy( hash.begin(), hash.end(), data.begin() + nHashPos);
+            if (nAddIter)
+            {
 #ifdef OSL_BIGENDIAN
-            sal_uInt32 be = i;
-            sal_uInt8* p = reinterpret_cast<sal_uInt8*>(&be);
-            std::swap( p[0], p[3] );
-            std::swap( p[1], p[2] );
-            memcpy( data.data() + nIterPos, &be, 4);
+                sal_uInt32 be = i;
+                sal_uInt8* p = reinterpret_cast<sal_uInt8*>(&be);
+                std::swap( p[0], p[3] );
+                std::swap( p[1], p[2] );
+                memcpy( data.data() + nIterPos, &be, nAddIter);
 #else
-            memcpy( data.data() + nIterPos, &i, 4);
+                memcpy( data.data() + nIterPos, &i, nAddIter);
 #endif
+            }
             /* TODO: isn't there something better than
              * creating/finalizing/destroying on each iteration? */
             Hash aReHash(eType);
@@ -218,7 +222,7 @@ std::vector<unsigned char> Hash::calculateHash(
         const OUString& rPassword,
         const std::vector<unsigned char>& rSaltValue,
         sal_uInt32 nSpinCount,
-        bool bPrependNotAppend,
+        IterCount eIterCount,
         HashType eType)
 {
     const unsigned char* pPassBytes = reinterpret_cast<const unsigned char*>(rPassword.getStr());
@@ -240,7 +244,7 @@ std::vector<unsigned char> Hash::calculateHash(
     }
 #endif
     return calculateHash( pPassBytes, nPassBytesLen, rSaltValue.data(), rSaltValue.size(), nSpinCount,
-            bPrependNotAppend, eType);
+            eIterCount, eType);
 }
 
 }
diff --git a/include/comphelper/docpasswordhelper.hxx b/include/comphelper/docpasswordhelper.hxx
index 30243c347884..e37a6c71de22 100644
--- a/include/comphelper/docpasswordhelper.hxx
+++ b/include/comphelper/docpasswordhelper.hxx
@@ -24,6 +24,7 @@
 #include <comphelper/comphelperdllapi.h>
 #include <vector>
 #include <comphelper/docpasswordrequest.hxx>
+#include <comphelper/hash.hxx>
 
 namespace com { namespace sun { namespace star { namespace task { class XInteractionHandler; } } } }
 namespace com { namespace sun { namespace star { namespace beans { struct PropertyValue; } } } }
@@ -194,12 +195,14 @@ public:
         @param  nSpinCount
                 If >0 the number of repeated iterations.
 
-        @param  bPrependNotAppend
-                If <FALSE/>, append spin count in iterations as per
+        @param  eIterCount
+                If Hash::IterCount::APPEND, append iteration count as per
                 https://msdn.microsoft.com/en-us/library/dd920692
-                If <TRUE/>, prepend spin count in iterations as per
+                If Hash::IterCount::PREPEND, prepend iteration count as per
                 https://msdn.microsoft.com/en-us/library/dd924776 and
                 https://msdn.microsoft.com/en-us/library/dd925430
+                If Hash::IterCount::NONE, do not add the iteration count to hash
+                iterations.
 
         @param  rAlgorithmName
                 One of "SHA-512", "SHA-256", ... as listed for AlgorithmName in
@@ -216,7 +219,7 @@ public:
             const rtl::OUString& rPassword,
             const rtl::OUString& rSaltValue,
             sal_uInt32 nSpinCount,
-            bool bPrependNotAppend,
+            comphelper::Hash::IterCount eIterCount,
             const rtl::OUString& rAlgorithmName);
 
 
@@ -234,12 +237,14 @@ public:
         @param  nSpinCount
                 If >0 the number of repeated iterations.
 
-        @param  bPrependNotAppend
-                If <FALSE/>, append spin count in iterations as per
+        @param  eIterCount
+                If Hash::IterCount::APPEND, append iteration count as per
                 https://msdn.microsoft.com/en-us/library/dd920692
-                If <TRUE/>, prepend spin count in iterations as per
+                If Hash::IterCount::PREPEND, prepend iteration count as per
                 https://msdn.microsoft.com/en-us/library/dd924776 and
                 https://msdn.microsoft.com/en-us/library/dd925430
+                If Hash::IterCount::NONE, do not add the iteration count to hash
+                iterations.
 
         @param  rAlgorithmName
                 One of "SHA-512", "SHA-256", ... as listed for AlgorithmName in
@@ -257,7 +262,7 @@ public:
             const rtl::OUString& rPassword,
             const rtl::OUString& rSaltValue,
             sal_uInt32 nSpinCount,
-            bool bPrependNotAppend,
+            comphelper::Hash::IterCount eIterCount,
             const rtl::OUString& rAlgorithmName);
 
 
diff --git a/include/comphelper/hash.hxx b/include/comphelper/hash.hxx
index 08ae5fd119a8..52ad5e5cdf1e 100644
--- a/include/comphelper/hash.hxx
+++ b/include/comphelper/hash.hxx
@@ -38,6 +38,13 @@ private:
 
 public:
 
+    enum class IterCount
+    {
+        NONE,       /// Iteration count not added to hash iterations.
+        PREPEND,    /// Iteration count prepended to hash iterations.
+        APPEND      /// Iteration count appended to hash iterations.
+    };
+
     Hash(HashType eType);
     ~Hash();
 
@@ -50,10 +57,6 @@ public:
     /** Calculate hash value with salt (pSalt,nSaltLen) prepended to password
         (pInput,nLength) and repeated iterations run if nSpinCount>0.
 
-        For repeated iterations, each iteration's result plus a 4 byte value
-        (0-based, little endian) containing the number of the iteration
-        appended to the hash value is the input for the next iteration.
-
         This implements the algorithms as specified in
         https://msdn.microsoft.com/en-us/library/dd920692 or
         https://msdn.microsoft.com/en-us/library/dd924776 and
@@ -62,12 +65,21 @@ public:
         @param  pSalt
                 may be nullptr thus no salt prepended
 
-        @param  bPrependNotAppend
-                If <FALSE/>, append spin count in iterations as per
+        @param  nSpinCount
+                If >0, repeat nSpinCount iterations. For each iteration, the
+                previous iteration's result plus a 4 byte value (0-based,
+                little endian) containing the number of the iteration prepended
+                or appended to the hash value is the input for the next
+                iteration.
+
+        @param  eIterCount
+                If IterCount::APPEND, append iteration count as per
                 https://msdn.microsoft.com/en-us/library/dd920692
-                If <TRUE/>, prepend spin count in iterations as per
+                If IterCount::PREPEND, prepend iteration count as per
                 https://msdn.microsoft.com/en-us/library/dd924776 and
                 https://msdn.microsoft.com/en-us/library/dd925430
+                If IterCount::NONE, do not add the iteration count to hash
+                iterations.
 
         @return the raw hash value
      */
@@ -75,7 +87,7 @@ public:
             const unsigned char* pInput, size_t nLength,
             const unsigned char* pSalt, size_t nSaltLen,
             sal_uInt32 nSpinCount,
-            bool bPrependNotAppend,
+            IterCount eIterCount,
             HashType eType);
 
     /** Convenience function to calculate a salted hash with iterations.
@@ -90,7 +102,7 @@ public:
             const rtl::OUString& rPassword,
             const std::vector<unsigned char>& rSaltValue,
             sal_uInt32 nSpinCount,
-            bool bPrependNotAppend,
+            IterCount eIterCount,
             HashType eType);
 
     size_t getLength() const;
diff --git a/sc/source/core/data/tabprotection.cxx b/sc/source/core/data/tabprotection.cxx
index 5edc032ffe06..05b53d16e551 100644
--- a/sc/source/core/data/tabprotection.cxx
+++ b/sc/source/core/data/tabprotection.cxx
@@ -95,7 +95,7 @@ bool ScOoxPasswordHash::verifyPassword( const OUString& aPassText ) const
         return false;
 
     const OUString aHash( comphelper::DocPasswordHelper::GetOoxHashAsBase64(
-                aPassText, maSaltValue, mnSpinCount, false, maAlgorithmName));
+                aPassText, maSaltValue, mnSpinCount, comphelper::Hash::IterCount::APPEND, maAlgorithmName));
     if (aHash.isEmpty())
         // unsupported algorithm
         return false;


More information about the Libreoffice-commits mailing list