forked from amazingfate/loongoffice
To permit pluggable crypto services, abstract existing implementation behind an XPackageEncryption API. Previous code already had two halfway-polymorphic classes (agile and standard 2007 engine), so we're not adding much additional layers. As MS crypto always uses OLE storage to wrap content into one single file, current implementation passes all substorage names down into XPackageEncryption APi, so different downstream implementations (e.g. for MS RMS, or Azure AIP) are possible. Because OleStorage classes are internal to LibO core, access is provided via XInput/XOutput stream API function. Change-Id: Icc32a4e0ce215090c3b739f1dcaa0654b36b7f08 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/84436 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
104 lines
3.2 KiB
C++
104 lines
3.2 KiB
C++
/* -*- 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 <oox/crypto/DocumentEncryption.hxx>
|
|
|
|
#include <com/sun/star/io/XInputStream.hpp>
|
|
#include <com/sun/star/io/XOutputStream.hpp>
|
|
#include <com/sun/star/io/XStream.hpp>
|
|
#include <com/sun/star/io/XSeekable.hpp>
|
|
#include <com/sun/star/packages/XPackageEncryption.hpp>
|
|
#include <com/sun/star/uno/XComponentContext.hpp>
|
|
|
|
#include <oox/helper/binaryoutputstream.hxx>
|
|
#include <oox/ole/olestorage.hxx>
|
|
#include <sal/log.hxx>
|
|
|
|
namespace oox::crypto {
|
|
|
|
using namespace css::io;
|
|
using namespace css::uno;
|
|
using namespace css::beans;
|
|
|
|
DocumentEncryption::DocumentEncryption(const Reference< XComponentContext >& rxContext,
|
|
Reference<XStream> const & xDocumentStream,
|
|
oox::ole::OleStorage& rOleStorage,
|
|
const Sequence<NamedValue>& rMediaEncData)
|
|
: mxContext(rxContext)
|
|
, mxDocumentStream(xDocumentStream)
|
|
, mrOleStorage(rOleStorage)
|
|
, mMediaEncData(rMediaEncData)
|
|
{
|
|
// Select engine
|
|
for (int i = 0; i < rMediaEncData.getLength(); i++)
|
|
{
|
|
if (rMediaEncData[i].Name == "CryptoType")
|
|
{
|
|
OUString sCryptoType;
|
|
rMediaEncData[i].Value >>= sCryptoType;
|
|
|
|
if (sCryptoType == "Standard")
|
|
sCryptoType = "StrongEncryptionDataSpace";
|
|
|
|
Sequence<Any> aArguments;
|
|
mxPackageEncryption.set(
|
|
mxContext->getServiceManager()->createInstanceWithArgumentsAndContext(
|
|
"com.sun.star.comp.oox.crypto." + sCryptoType, aArguments, mxContext), css::uno::UNO_QUERY);
|
|
|
|
if (!mxPackageEncryption.is())
|
|
{
|
|
SAL_WARN("oox", "Requested encryption method \"" << sCryptoType << "\" is not supported");
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool DocumentEncryption::encrypt()
|
|
{
|
|
if (!mxPackageEncryption.is())
|
|
return false;
|
|
|
|
Reference<XInputStream> xInputStream (mxDocumentStream->getInputStream(), UNO_SET_THROW);
|
|
Reference<XSeekable> xSeekable(xInputStream, UNO_QUERY);
|
|
|
|
if (!xSeekable.is())
|
|
return false;
|
|
|
|
xSeekable->seek(0); // seek to begin of the document stream
|
|
|
|
if (!mrOleStorage.isStorage())
|
|
return false;
|
|
|
|
mxPackageEncryption->setupEncryption(mMediaEncData);
|
|
|
|
Sequence<NamedValue> aStreams = mxPackageEncryption->encrypt(xInputStream);
|
|
|
|
for (const NamedValue & aStream : std::as_const(aStreams))
|
|
{
|
|
Reference<XOutputStream> xOutputStream(mrOleStorage.openOutputStream(aStream.Name), UNO_SET_THROW);
|
|
BinaryXOutputStream aBinaryOutputStream(xOutputStream, true);
|
|
|
|
css::uno::Sequence<sal_Int8> aStreamSequence;
|
|
aStream.Value >>= aStreamSequence;
|
|
|
|
aBinaryOutputStream.writeData(aStreamSequence);
|
|
|
|
aBinaryOutputStream.close();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
} // namespace oox::crypto
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|