Files
loongoffice/oox/source/crypto/DocumentEncryption.cxx
Vasily Melenchuk b9353394f4 [MS-OFFCRYPTO] convert oox implementation into UNO service
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>
2020-05-25 10:04:15 +02:00

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: */