Coverage Report

Created: 2026-06-30 11:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/oox/source/crypto/StrongEncryptionDataSpace.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 */
10
11
#include <oox/crypto/StrongEncryptionDataSpace.hxx>
12
#include <oox/crypto/AgileEngine.hxx>
13
#include <oox/crypto/Standard2007Engine.hxx>
14
#include <oox/helper/binaryoutputstream.hxx>
15
#include <oox/helper/binaryinputstream.hxx>
16
#include <com/sun/star/io/SequenceInputStream.hpp>
17
#include <com/sun/star/io/XSequenceOutputStream.hpp>
18
19
#include <comphelper/sequenceashashmap.hxx>
20
#include <cppuhelper/supportsservice.hxx>
21
22
using namespace css;
23
using namespace css::beans;
24
using namespace css::io;
25
using namespace css::lang;
26
using namespace css::uno;
27
28
namespace oox::crypto
29
{
30
StrongEncryptionDataSpace::StrongEncryptionDataSpace(const Reference<XComponentContext>& rxContext)
31
5.31k
    : mxContext(rxContext)
32
5.31k
    , mCryptoEngine(new AgileEngine)
33
5.31k
{
34
5.31k
}
35
36
sal_Bool StrongEncryptionDataSpace::generateEncryptionKey(const OUString& rPassword)
37
41
{
38
41
    if (!mCryptoEngine)
39
0
        return false;
40
41
41
    return mCryptoEngine->generateEncryptionKey(rPassword);
42
41
}
43
44
sal_Bool StrongEncryptionDataSpace::checkDataIntegrity()
45
27
{
46
27
    if (!mCryptoEngine)
47
0
        return false;
48
49
27
    return mCryptoEngine->checkDataIntegrity();
50
27
}
51
52
sal_Bool StrongEncryptionDataSpace::decrypt(const Reference<XInputStream>& rxInputStream,
53
                                            Reference<XOutputStream>& rxOutputStream)
54
27
{
55
27
    if (!mCryptoEngine)
56
0
        return false;
57
58
27
    BinaryXInputStream aInputStream(rxInputStream, true);
59
27
    BinaryXOutputStream aOutputStream(rxOutputStream, true);
60
61
27
    mCryptoEngine->decrypt(aInputStream, aOutputStream);
62
63
27
    rxOutputStream->flush();
64
27
    return true;
65
27
}
66
67
Reference<XInputStream> StrongEncryptionDataSpace::getStream(const Sequence<NamedValue>& rStreams,
68
                                                             std::u16string_view sStreamName)
69
5.31k
{
70
5.31k
    for (const auto& aStream : rStreams)
71
35.3k
    {
72
35.3k
        if (aStream.Name == sStreamName)
73
4.83k
        {
74
4.83k
            Sequence<sal_Int8> aSeq;
75
4.83k
            aStream.Value >>= aSeq;
76
4.83k
            Reference<XInputStream> aStream2(
77
4.83k
                io::SequenceInputStream::createStreamFromSequence(mxContext, aSeq),
78
4.83k
                UNO_QUERY_THROW);
79
4.83k
            return aStream2;
80
4.83k
        }
81
35.3k
    }
82
474
    return nullptr;
83
5.31k
}
84
85
sal_Bool StrongEncryptionDataSpace::readEncryptionInfo(const Sequence<NamedValue>& aStreams)
86
5.31k
{
87
5.31k
    Reference<XInputStream> xEncryptionInfo = getStream(aStreams, u"EncryptionInfo");
88
5.31k
    if (!xEncryptionInfo.is())
89
474
        return false;
90
91
4.83k
    BinaryXInputStream aBinaryInputStream(xEncryptionInfo, true);
92
4.83k
    sal_uInt32 aVersion = aBinaryInputStream.readuInt32();
93
94
4.83k
    switch (aVersion)
95
4.83k
    {
96
49
        case msfilter::VERSION_INFO_2007_FORMAT:
97
53
        case msfilter::VERSION_INFO_2007_FORMAT_SP2:
98
53
            mCryptoEngine.reset(new Standard2007Engine);
99
53
            break;
100
4.64k
        case msfilter::VERSION_INFO_AGILE:
101
4.64k
            mCryptoEngine.reset(new AgileEngine());
102
4.64k
            break;
103
141
        default:
104
141
            break;
105
4.83k
    }
106
107
4.83k
    if (!mCryptoEngine)
108
0
        return false;
109
110
4.83k
    return mCryptoEngine->readEncryptionInfo(xEncryptionInfo);
111
4.83k
}
112
113
sal_Bool StrongEncryptionDataSpace::setupEncryption(const Sequence<NamedValue>& rMediaEncData)
114
0
{
115
0
    if (!mCryptoEngine)
116
0
        return false;
117
118
0
    OUString sPassword;
119
0
    for (const auto& aParam : rMediaEncData)
120
0
    {
121
0
        if (aParam.Name == "OOXPassword")
122
0
        {
123
0
            aParam.Value >>= sPassword;
124
0
        }
125
0
    }
126
127
0
    return mCryptoEngine->setupEncryption(sPassword);
128
0
}
129
130
Sequence<NamedValue> StrongEncryptionDataSpace::createEncryptionData(const OUString& rPassword)
131
27
{
132
27
    comphelper::SequenceAsHashMap aEncryptionData;
133
27
    aEncryptionData[u"OOXPassword"_ustr] <<= rPassword;
134
27
    aEncryptionData[u"CryptoType"_ustr] <<= u"StrongEncryptionDataSpace"_ustr;
135
136
27
    return aEncryptionData.getAsConstNamedValueList();
137
27
}
138
139
Sequence<NamedValue>
140
StrongEncryptionDataSpace::encrypt(const Reference<XInputStream>& rxInputStream)
141
0
{
142
0
    if (!mCryptoEngine)
143
0
        return Sequence<NamedValue>();
144
145
0
    Reference<XSeekable> xSeekable(rxInputStream, UNO_QUERY);
146
0
    if (!xSeekable.is())
147
0
        return Sequence<NamedValue>();
148
149
0
    sal_uInt32 aLength = xSeekable->getLength(); // check length of the stream
150
151
0
    Reference<XOutputStream> xOutputStream(
152
0
        mxContext->getServiceManager()->createInstanceWithContext(
153
0
            u"com.sun.star.io.SequenceOutputStream"_ustr, mxContext),
154
0
        UNO_QUERY);
155
156
0
    mCryptoEngine->encrypt(rxInputStream, xOutputStream, aLength);
157
158
0
    comphelper::SequenceAsHashMap aStreams;
159
160
0
    Reference<XSequenceOutputStream> xEncodedFileSequenceStream(xOutputStream, UNO_QUERY);
161
0
    aStreams[u"EncryptedPackage"_ustr] <<= xEncodedFileSequenceStream->getWrittenBytes();
162
163
0
    Reference<XOutputStream> aEncryptionInfoStream(
164
0
        mxContext->getServiceManager()->createInstanceWithContext(
165
0
            u"com.sun.star.io.SequenceOutputStream"_ustr, mxContext),
166
0
        UNO_QUERY);
167
0
    BinaryXOutputStream rStream(aEncryptionInfoStream, false);
168
0
    mCryptoEngine->writeEncryptionInfo(rStream);
169
0
    aEncryptionInfoStream->flush();
170
0
    Reference<XSequenceOutputStream> aEncryptionInfoSequenceStream(aEncryptionInfoStream,
171
0
                                                                   UNO_QUERY);
172
173
0
    aStreams[u"EncryptionInfo"_ustr] <<= aEncryptionInfoSequenceStream->getWrittenBytes();
174
175
0
    return aStreams.getAsConstNamedValueList();
176
0
}
177
178
OUString SAL_CALL StrongEncryptionDataSpace::getImplementationName()
179
0
{
180
0
    return u"com.sun.star.comp.oox.crypto.StrongEncryptionDataSpace"_ustr;
181
0
}
182
183
sal_Bool SAL_CALL StrongEncryptionDataSpace::supportsService(const OUString& rServiceName)
184
0
{
185
0
    return cppu::supportsService(this, rServiceName);
186
0
}
187
188
css::uno::Sequence<OUString> SAL_CALL StrongEncryptionDataSpace::getSupportedServiceNames()
189
0
{
190
0
    Sequence<OUString> aServices{ u"com.sun.star.packages.PackageEncryption"_ustr };
191
0
    return aServices;
192
0
}
193
194
} // namespace oox::crypto
195
196
extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
197
com_sun_star_comp_oox_crypto_StrongEncryptionDataSpace_get_implementation(
198
    uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
199
5.31k
{
200
5.31k
    return cppu::acquire(new oox::crypto::StrongEncryptionDataSpace(pCtx));
201
5.31k
}
202
203
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */