/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * */ #include #include #include #include #include #include #include #include #include using namespace css; using namespace css::beans; using namespace css::io; using namespace css::lang; using namespace css::uno; namespace oox::crypto { StrongEncryptionDataSpace::StrongEncryptionDataSpace(const Reference& rxContext) : mxContext(rxContext) , mCryptoEngine(new Standard2007Engine) { } sal_Bool StrongEncryptionDataSpace::generateEncryptionKey(const OUString& rPassword) { if (!mCryptoEngine) return false; return mCryptoEngine->generateEncryptionKey(rPassword); } sal_Bool StrongEncryptionDataSpace::checkDataIntegrity() { if (!mCryptoEngine) return false; return mCryptoEngine->checkDataIntegrity(); } sal_Bool StrongEncryptionDataSpace::decrypt(const Reference& rxInputStream, Reference& rxOutputStream) { if (!mCryptoEngine) return false; BinaryXInputStream aInputStream(rxInputStream, true); BinaryXOutputStream aOutputStream(rxOutputStream, true); mCryptoEngine->decrypt(aInputStream, aOutputStream); rxOutputStream->flush(); return true; } Reference StrongEncryptionDataSpace::getStream(const Sequence& rStreams, std::u16string_view sStreamName) { for (const auto& aStream : rStreams) { if (aStream.Name == sStreamName) { Sequence aSeq; aStream.Value >>= aSeq; Reference aStream2( io::SequenceInputStream::createStreamFromSequence(mxContext, aSeq), UNO_QUERY_THROW); return aStream2; } } return nullptr; } sal_Bool StrongEncryptionDataSpace::readEncryptionInfo(const Sequence& aStreams) { Reference xEncryptionInfo = getStream(aStreams, u"EncryptionInfo"); if (!xEncryptionInfo.is()) return false; BinaryXInputStream aBinaryInputStream(xEncryptionInfo, true); sal_uInt32 aVersion = aBinaryInputStream.readuInt32(); switch (aVersion) { case msfilter::VERSION_INFO_2007_FORMAT: case msfilter::VERSION_INFO_2007_FORMAT_SP2: mCryptoEngine.reset(new Standard2007Engine); break; case msfilter::VERSION_INFO_AGILE: mCryptoEngine.reset(new AgileEngine()); break; default: break; } if (!mCryptoEngine) return false; return mCryptoEngine->readEncryptionInfo(xEncryptionInfo); } sal_Bool StrongEncryptionDataSpace::setupEncryption(const Sequence& rMediaEncData) { if (!mCryptoEngine) return false; OUString sPassword; for (const auto& aParam : rMediaEncData) { if (aParam.Name == "OOXPassword") { aParam.Value >>= sPassword; } } return mCryptoEngine->setupEncryption(sPassword); } Sequence StrongEncryptionDataSpace::createEncryptionData(const OUString& rPassword) { comphelper::SequenceAsHashMap aEncryptionData; aEncryptionData["OOXPassword"] <<= rPassword; aEncryptionData["CryptoType"] <<= OUString("StrongEncryptionDataSpace"); return aEncryptionData.getAsConstNamedValueList(); } Sequence StrongEncryptionDataSpace::encrypt(const Reference& rxInputStream) { if (!mCryptoEngine) return Sequence(); Reference xSeekable(rxInputStream, UNO_QUERY); if (!xSeekable.is()) return Sequence(); sal_uInt32 aLength = xSeekable->getLength(); // check length of the stream Reference xOutputStream( mxContext->getServiceManager()->createInstanceWithContext( "com.sun.star.io.SequenceOutputStream", mxContext), UNO_QUERY); mCryptoEngine->encrypt(rxInputStream, xOutputStream, aLength); comphelper::SequenceAsHashMap aStreams; Reference xEncodedFileSequenceStream(xOutputStream, UNO_QUERY); aStreams["EncryptedPackage"] <<= xEncodedFileSequenceStream->getWrittenBytes(); Reference aEncryptionInfoStream( mxContext->getServiceManager()->createInstanceWithContext( "com.sun.star.io.SequenceOutputStream", mxContext), UNO_QUERY); BinaryXOutputStream rStream(aEncryptionInfoStream, false); mCryptoEngine->writeEncryptionInfo(rStream); aEncryptionInfoStream->flush(); Reference aEncryptionInfoSequenceStream(aEncryptionInfoStream, UNO_QUERY); aStreams["EncryptionInfo"] <<= aEncryptionInfoSequenceStream->getWrittenBytes(); return aStreams.getAsConstNamedValueList(); } OUString SAL_CALL StrongEncryptionDataSpace::getImplementationName() { return "com.sun.star.comp.oox.crypto.StrongEncryptionDataSpace"; } sal_Bool SAL_CALL StrongEncryptionDataSpace::supportsService(const OUString& rServiceName) { return cppu::supportsService(this, rServiceName); } css::uno::Sequence SAL_CALL StrongEncryptionDataSpace::getSupportedServiceNames() { Sequence aServices{ "com.sun.star.packages.PackageEncryption" }; return aServices; } } // namespace oox::crypto extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface* com_sun_star_comp_oox_crypto_StrongEncryptionDataSpace_get_implementation( uno::XComponentContext* pCtx, uno::Sequence const& /*rSeq*/) { return cppu::acquire(new oox::crypto::StrongEncryptionDataSpace(pCtx)); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */