summaryrefslogtreecommitdiff
path: root/package
diff options
context:
space:
mode:
Diffstat (limited to 'package')
-rw-r--r--package/inc/EncryptionData.hxx5
-rw-r--r--package/inc/ZipPackageStream.hxx5
-rw-r--r--package/source/zipapi/ZipFile.cxx11
-rw-r--r--package/source/zipapi/sha1context.cxx52
-rw-r--r--package/source/zipapi/sha1context.hxx26
-rw-r--r--package/source/zippackage/ZipPackageStream.cxx32
6 files changed, 111 insertions, 20 deletions
diff --git a/package/inc/EncryptionData.hxx b/package/inc/EncryptionData.hxx
index 0add43f143de..c7c6ffb3555e 100644
--- a/package/inc/EncryptionData.hxx
+++ b/package/inc/EncryptionData.hxx
@@ -50,14 +50,16 @@ public:
sal_Int32 m_nCheckAlg;
sal_Int32 m_nDerivedKeySize;
sal_Int32 m_nStartKeyGenID;
+ bool m_bTryWrongSHA1;
- EncryptionData( const BaseEncryptionData& aData, const css::uno::Sequence< sal_Int8 >& aKey, sal_Int32 nEncAlg, sal_Int32 nCheckAlg, sal_Int32 nDerivedKeySize, sal_Int32 nStartKeyGenID )
+ EncryptionData(const BaseEncryptionData& aData, const css::uno::Sequence< sal_Int8 >& aKey, sal_Int32 nEncAlg, sal_Int32 nCheckAlg, sal_Int32 nDerivedKeySize, sal_Int32 nStartKeyGenID, bool const bTryWrongSHA1)
: BaseEncryptionData( aData )
, m_aKey( aKey )
, m_nEncAlg( nEncAlg )
, m_nCheckAlg( nCheckAlg )
, m_nDerivedKeySize( nDerivedKeySize )
, m_nStartKeyGenID( nStartKeyGenID )
+ , m_bTryWrongSHA1(bTryWrongSHA1)
{}
EncryptionData( const EncryptionData& aData )
@@ -67,6 +69,7 @@ public:
, m_nCheckAlg( aData.m_nCheckAlg )
, m_nDerivedKeySize( aData.m_nDerivedKeySize )
, m_nStartKeyGenID( aData.m_nStartKeyGenID )
+ , m_bTryWrongSHA1(aData.m_bTryWrongSHA1)
{}
};
diff --git a/package/inc/ZipPackageStream.hxx b/package/inc/ZipPackageStream.hxx
index 4620b5da64f2..67428c086948 100644
--- a/package/inc/ZipPackageStream.hxx
+++ b/package/inc/ZipPackageStream.hxx
@@ -83,9 +83,10 @@ public:
bool IsFromManifest() const { return m_bFromManifest; }
void SetFromManifest( bool bValue ) { m_bFromManifest = bValue; }
- ::rtl::Reference< EncryptionData > GetEncryptionData( bool bWinEncoding = false );
+ enum class Bugs { None, WinEncodingWrongSHA1, WrongSHA1 };
+ ::rtl::Reference<EncryptionData> GetEncryptionData(Bugs bugs = Bugs::WrongSHA1);
- css::uno::Sequence< sal_Int8 > GetEncryptionKey( bool bWinEncoding = false );
+ css::uno::Sequence<sal_Int8> GetEncryptionKey(Bugs bugs = Bugs::WrongSHA1);
sal_Int32 GetStartKeyGenID();
diff --git a/package/source/zipapi/ZipFile.cxx b/package/source/zipapi/ZipFile.cxx
index de4c1a364acd..3d4abb65a8f9 100644
--- a/package/source/zipapi/ZipFile.cxx
+++ b/package/source/zipapi/ZipFile.cxx
@@ -144,7 +144,16 @@ uno::Reference< xml::crypto::XDigestContext > ZipFile::StaticGetDigestContextFor
xDigestContext.set( xDigestContextSupplier->getDigestContext( xEncryptionData->m_nCheckAlg, uno::Sequence< beans::NamedValue >() ), uno::UNO_SET_THROW );
}
else if ( xEncryptionData->m_nCheckAlg == xml::crypto::DigestID::SHA1_1K )
- xDigestContext.set( SHA1DigestContext::Create(), uno::UNO_SET_THROW );
+ {
+ if (xEncryptionData->m_bTryWrongSHA1)
+ {
+ xDigestContext.set(StarOfficeSHA1DigestContext::Create(), uno::UNO_SET_THROW);
+ }
+ else
+ {
+ xDigestContext.set(CorrectSHA1DigestContext::Create(), uno::UNO_SET_THROW);
+ }
+ }
return xDigestContext;
}
diff --git a/package/source/zipapi/sha1context.cxx b/package/source/zipapi/sha1context.cxx
index f24064616edb..af3123e2dbd0 100644
--- a/package/source/zipapi/sha1context.cxx
+++ b/package/source/zipapi/sha1context.cxx
@@ -19,6 +19,7 @@
#include <sal/config.h>
+#include <comphelper/hash.hxx>
#include <com/sun/star/lang/DisposedException.hpp>
#include <rtl/digest.h>
#include <rtl/ref.hxx>
@@ -28,9 +29,9 @@
using namespace ::com::sun::star;
// static
-uno::Reference< xml::crypto::XDigestContext > SHA1DigestContext::Create()
+uno::Reference<xml::crypto::XDigestContext> StarOfficeSHA1DigestContext::Create()
{
- ::rtl::Reference< SHA1DigestContext > xResult = new SHA1DigestContext();
+ ::rtl::Reference<StarOfficeSHA1DigestContext> xResult = new StarOfficeSHA1DigestContext();
xResult->m_pDigest = rtl_digest_createSHA1();
if ( !xResult->m_pDigest )
throw uno::RuntimeException("Can not create cipher!" );
@@ -38,7 +39,7 @@ uno::Reference< xml::crypto::XDigestContext > SHA1DigestContext::Create()
return uno::Reference< xml::crypto::XDigestContext >( xResult.get() );
}
-SHA1DigestContext::~SHA1DigestContext()
+StarOfficeSHA1DigestContext::~StarOfficeSHA1DigestContext()
{
if ( m_pDigest )
{
@@ -47,7 +48,7 @@ SHA1DigestContext::~SHA1DigestContext()
}
}
-void SAL_CALL SHA1DigestContext::updateDigest( const uno::Sequence< ::sal_Int8 >& aData )
+void SAL_CALL StarOfficeSHA1DigestContext::updateDigest(const uno::Sequence<::sal_Int8>& aData)
{
::osl::MutexGuard aGuard( m_aMutex );
if ( !m_pDigest )
@@ -62,7 +63,7 @@ void SAL_CALL SHA1DigestContext::updateDigest( const uno::Sequence< ::sal_Int8 >
}
}
-uno::Sequence< ::sal_Int8 > SAL_CALL SHA1DigestContext::finalizeDigestAndDispose()
+uno::Sequence<::sal_Int8> SAL_CALL StarOfficeSHA1DigestContext::finalizeDigestAndDispose()
{
::osl::MutexGuard aGuard( m_aMutex );
if ( !m_pDigest )
@@ -83,4 +84,45 @@ uno::Sequence< ::sal_Int8 > SAL_CALL SHA1DigestContext::finalizeDigestAndDispose
return aResult;
}
+uno::Reference<xml::crypto::XDigestContext> CorrectSHA1DigestContext::Create()
+{
+ return new CorrectSHA1DigestContext();
+}
+
+struct CorrectSHA1DigestContext::Impl
+{
+ ::osl::Mutex m_Mutex;
+ ::comphelper::Hash m_Hash{::comphelper::HashType::SHA1};
+ bool m_bDisposed{false};
+};
+
+CorrectSHA1DigestContext::CorrectSHA1DigestContext()
+ : m_pImpl(new Impl)
+{
+}
+
+CorrectSHA1DigestContext::~CorrectSHA1DigestContext()
+{
+}
+
+void SAL_CALL CorrectSHA1DigestContext::updateDigest(const uno::Sequence<::sal_Int8>& rData)
+{
+ ::osl::MutexGuard aGuard(m_pImpl->m_Mutex);
+ if (m_pImpl->m_bDisposed)
+ throw lang::DisposedException();
+
+ m_pImpl->m_Hash.update(reinterpret_cast<unsigned char const*>(rData.getConstArray()), rData.getLength());
+}
+
+uno::Sequence<::sal_Int8> SAL_CALL CorrectSHA1DigestContext::finalizeDigestAndDispose()
+{
+ ::osl::MutexGuard aGuard(m_pImpl->m_Mutex);
+ if (m_pImpl->m_bDisposed)
+ throw lang::DisposedException();
+
+ m_pImpl->m_bDisposed = true;
+ std::vector<unsigned char> const sha1(m_pImpl->m_Hash.finalize());
+ return uno::Sequence<sal_Int8>(reinterpret_cast<sal_Int8 const*>(sha1.data()), sha1.size());
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/package/source/zipapi/sha1context.hxx b/package/source/zipapi/sha1context.hxx
index ef9c433082d3..436dfcccbf7c 100644
--- a/package/source/zipapi/sha1context.hxx
+++ b/package/source/zipapi/sha1context.hxx
@@ -24,18 +24,19 @@
#include <cppuhelper/implbase.hxx>
#include <osl/mutex.hxx>
-class SHA1DigestContext : public cppu::WeakImplHelper< css::xml::crypto::XDigestContext >
+class StarOfficeSHA1DigestContext
+ : public cppu::WeakImplHelper<css::xml::crypto::XDigestContext>
{
::osl::Mutex m_aMutex;
void* m_pDigest;
- SHA1DigestContext()
+ StarOfficeSHA1DigestContext()
: m_pDigest( nullptr )
{}
public:
- virtual ~SHA1DigestContext() override;
+ virtual ~StarOfficeSHA1DigestContext() override;
static css::uno::Reference< css::xml::crypto::XDigestContext > Create();
@@ -44,6 +45,25 @@ public:
};
+class CorrectSHA1DigestContext
+ : public cppu::WeakImplHelper<css::xml::crypto::XDigestContext>
+{
+ struct Impl;
+ std::unique_ptr<Impl> m_pImpl;
+
+ CorrectSHA1DigestContext();
+
+public:
+
+ virtual ~CorrectSHA1DigestContext() override;
+
+ static css::uno::Reference<css::xml::crypto::XDigestContext> Create();
+
+ virtual void SAL_CALL updateDigest(const css::uno::Sequence<::sal_Int8>& rData) override;
+ virtual css::uno::Sequence<::sal_Int8> SAL_CALL finalizeDigestAndDispose() override;
+
+};
+
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx
index bd914b663406..c9e987aec1bd 100644
--- a/package/source/zippackage/ZipPackageStream.cxx
+++ b/package/source/zippackage/ZipPackageStream.cxx
@@ -198,26 +198,27 @@ sal_Int32 ZipPackageStream::GetBlockSize() const
return GetEncryptionAlgorithm() == css::xml::crypto::CipherID::AES_CBC_W3C_PADDING ? 16 : 8;
}
-::rtl::Reference< EncryptionData > ZipPackageStream::GetEncryptionData( bool bUseWinEncoding )
+::rtl::Reference<EncryptionData> ZipPackageStream::GetEncryptionData(Bugs const bugs)
{
::rtl::Reference< EncryptionData > xResult;
if ( m_xBaseEncryptionData.is() )
xResult = new EncryptionData(
*m_xBaseEncryptionData,
- GetEncryptionKey( bUseWinEncoding ),
+ GetEncryptionKey(bugs),
GetEncryptionAlgorithm(),
m_nImportedChecksumAlgorithm ? m_nImportedChecksumAlgorithm : m_rZipPackage.GetChecksumAlgID(),
m_nImportedDerivedKeySize ? m_nImportedDerivedKeySize : m_rZipPackage.GetDefaultDerivedKeySize(),
- GetStartKeyGenID() );
+ GetStartKeyGenID(),
+ bugs != Bugs::None);
return xResult;
}
-uno::Sequence< sal_Int8 > ZipPackageStream::GetEncryptionKey( bool bUseWinEncoding )
+uno::Sequence<sal_Int8> ZipPackageStream::GetEncryptionKey(Bugs const bugs)
{
uno::Sequence< sal_Int8 > aResult;
sal_Int32 nKeyGenID = GetStartKeyGenID();
- bUseWinEncoding = ( bUseWinEncoding || m_bUseWinEncoding );
+ bool const bUseWinEncoding = (bugs == Bugs::WinEncodingWrongSHA1 || m_bUseWinEncoding);
if ( m_bHaveOwnKey && m_aStorageEncryptionKeys.getLength() )
{
@@ -226,7 +227,11 @@ uno::Sequence< sal_Int8 > ZipPackageStream::GetEncryptionKey( bool bUseWinEncodi
aNameToFind = PACKAGE_ENCRYPTIONDATA_SHA256UTF8;
else if ( nKeyGenID == xml::crypto::DigestID::SHA1 )
{
- aNameToFind = bUseWinEncoding ? OUString(PACKAGE_ENCRYPTIONDATA_SHA1MS1252) : OUString(PACKAGE_ENCRYPTIONDATA_SHA1UTF8);
+ aNameToFind = bUseWinEncoding
+ ? OUString(PACKAGE_ENCRYPTIONDATA_SHA1MS1252)
+ : (bugs == Bugs::WrongSHA1)
+ ? OUString(PACKAGE_ENCRYPTIONDATA_SHA1UTF8)
+ : OUString(PACKAGE_ENCRYPTIONDATA_SHA1CORRECT);
}
else
throw uno::RuntimeException(THROW_WHERE "No expected key is provided!" );
@@ -1007,12 +1012,23 @@ uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getDataStream()
uno::Reference< io::XInputStream > xResult;
try
{
- xResult = m_rZipPackage.getZipFile().getDataStream( aEntry, GetEncryptionData(), m_bIsEncrypted, m_rZipPackage.GetSharedMutexRef() );
+ xResult = m_rZipPackage.getZipFile().getDataStream( aEntry, GetEncryptionData(Bugs::WrongSHA1), m_bIsEncrypted, m_rZipPackage.GetSharedMutexRef() );
}
catch( const packages::WrongPasswordException& )
{
if ( m_rZipPackage.GetStartKeyGenID() == xml::crypto::DigestID::SHA1 )
{
+ SAL_WARN("package", "ZipPackageStream::getDataStream(): SHA1 mismatch, trying fallbacks...");
+ try
+ { // tdf#114939 try without legacy StarOffice SHA1 bug
+ xResult = m_rZipPackage.getZipFile().getDataStream( aEntry, GetEncryptionData(Bugs::None), m_bIsEncrypted, m_rZipPackage.GetSharedMutexRef() );
+ return xResult;
+ }
+ catch (const packages::WrongPasswordException&)
+ {
+ /* ignore and try next... */
+ }
+
try
{
// rhbz#1013844 / fdo#47482 workaround for the encrypted
@@ -1035,7 +1051,7 @@ uno::Reference< io::XInputStream > SAL_CALL ZipPackageStream::getDataStream()
// workaround for the encrypted documents generated with the old OOo1.x bug.
if ( !m_bUseWinEncoding )
{
- xResult = m_rZipPackage.getZipFile().getDataStream( aEntry, GetEncryptionData( true ), m_bIsEncrypted, m_rZipPackage.GetSharedMutexRef() );
+ xResult = m_rZipPackage.getZipFile().getDataStream( aEntry, GetEncryptionData(Bugs::WinEncodingWrongSHA1), m_bIsEncrypted, m_rZipPackage.GetSharedMutexRef() );
m_bUseWinEncoding = true;
}
else