/[packages]/updates/5/libreoffice/current/SOURCES/0001-implement-CryptoAPI-RC4-SHA1-encryption-scheme-for-x.patch
ViewVC logotype

Contents of /updates/5/libreoffice/current/SOURCES/0001-implement-CryptoAPI-RC4-SHA1-encryption-scheme-for-x.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1188168 - (show annotations) (download)
Sat Dec 30 21:57:44 2017 UTC (6 years, 3 months ago) by luigiwalser
File size: 57208 byte(s)
5.1.6 (sync with f24)
1 From e0c5d650ecf94b30b66584bdd9367dcacc0a6e94 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
3 Date: Thu, 20 Oct 2016 11:19:58 +0100
4 Subject: [PATCH] implement CryptoAPI RC4+SHA1 encryption scheme for xls import
5
6 there might be other variants out there in practice, but this
7 works for default encrypted xls of excel 2013
8
9 (cherry picked from commit 1473ce030314027c01c98f513407ed0897328585)
10
11 contains...
12
13 be more c++y
14
15 (cherry picked from commit fcf7f503b64b2cf7dbef019fb43dde033e3538e8)
16
17 hash len is 20 for xls cryptoapi configuration
18
19 (cherry picked from commit 491884350ce74f36044b3348bd66356ad1c234af)
20
21 clarify hash lengths a bit more
22
23 (cherry picked from commit 8db1b13e721683d0263925c8e0300dd86a022814)
24
25 hash len isn't going to change depending on who implements it
26
27 (cherry picked from commit fcc846e8f29839eaace7e1d28746abea8f4b598a)
28
29 move some useful header information to mscodec for reuse
30
31 (cherry picked from commit fc514cbf30be1613fdf4d4b7c12cbd55ca08b9b0)
32
33 rework things in light of now available documentation
34
35 (cherry picked from commit 3fabbd0a22219464545f933fc28c869a6fa89546)
36
37 split MSCodec_Std97 into a baseclass MSCodec97
38
39 (cherry picked from commit 06916c839b16866b47235306d2db50850df0ad7c)
40
41 6e06b8578959b8147043179db57e875b1d98d57d
42 66cea4b9efb82d29e6c052ac11a6f2eaca823ce0
43 ee585cba4acad74c11d083085153e2af96c8894f
44 c7adf3ed3c8279cc93a06975d6fb337210d1af87
45 f5f75e27191017a8c6a3929e2a70d21840f157c6
46 a3c41a048169c78684800def94e53fc9f3201e30
47 91c0e1d1d95fbd1c68966650e7ac7d23276bcbe3
48
49 Change-Id: I673b00e111a734bc626ba3d3f6ecf9692f1ce7db
50 ---
51 filter/source/msfilter/mscodec.cxx | 206 +++++++++++++++++++---------
52 include/filter/msfilter/mscodec.hxx | 215 ++++++++++++++++++++++++------
53 include/oox/crypto/CryptTools.hxx | 3 -
54 include/oox/crypto/Standard2007Engine.hxx | 76 ++---------
55 oox/source/crypto/CryptTools.cxx | 14 +-
56 oox/source/crypto/DocumentDecryption.cxx | 22 +--
57 oox/source/crypto/Standard2007Engine.cxx | 67 ++++------
58 sc/source/filter/excel/xicontent.cxx | 106 ++++++++++++---
59 sc/source/filter/excel/xistream.cxx | 70 ++++++----
60 sc/source/filter/inc/xistream.hxx | 67 ++++++++--
61 sc/source/filter/inc/xlcontent.hxx | 2 -
62 11 files changed, 553 insertions(+), 295 deletions(-)
63
64 diff --git a/filter/source/msfilter/mscodec.cxx b/filter/source/msfilter/mscodec.cxx
65 index 87dbf70..ade583a 100644
66 --- a/filter/source/msfilter/mscodec.cxx
67 +++ b/filter/source/msfilter/mscodec.cxx
68 @@ -247,28 +247,37 @@ void MSCodec_Xor95::Skip( sal_Size nBytes )
69 mnOffset = (mnOffset + nBytes) & 0x0F;
70 }
71
72 +MSCodec97::MSCodec97(size_t nHashLen)
73 + : m_nHashLen(nHashLen)
74 + , m_hCipher(rtl_cipher_create(rtl_Cipher_AlgorithmARCFOUR, rtl_Cipher_ModeStream))
75 + , m_aDigestValue(nHashLen, 0)
76 +{
77 + assert(m_hCipher != nullptr);
78 + (void)memset (m_pDocId, 0, sizeof(m_pDocId));
79 +}
80
81 -
82 -MSCodec_Std97::MSCodec_Std97 ()
83 +MSCodec_Std97::MSCodec_Std97()
84 + : MSCodec97(RTL_DIGEST_LENGTH_MD5)
85 {
86 - m_hCipher = rtl_cipher_create (
87 - rtl_Cipher_AlgorithmARCFOUR, rtl_Cipher_ModeStream);
88 - OSL_ASSERT(m_hCipher != nullptr);
89 + m_hDigest = rtl_digest_create(rtl_Digest_AlgorithmMD5);
90 + assert(m_hDigest != nullptr);
91 +}
92
93 - m_hDigest = rtl_digest_create (
94 - rtl_Digest_AlgorithmMD5);
95 - OSL_ASSERT(m_hDigest != nullptr);
96 +MSCodec_CryptoAPI::MSCodec_CryptoAPI()
97 + : MSCodec97(RTL_DIGEST_LENGTH_SHA1)
98 +{
99 +}
100
101 - (void)memset (m_pDigestValue, 0, sizeof(m_pDigestValue));
102 - (void)memset (m_pDocId, 0, sizeof(m_pDocId));
103 +MSCodec97::~MSCodec97()
104 +{
105 + (void)memset(m_aDigestValue.data(), 0, m_aDigestValue.size());
106 + (void)memset(m_pDocId, 0, sizeof(m_pDocId));
107 + rtl_cipher_destroy(m_hCipher);
108 }
109
110 -MSCodec_Std97::~MSCodec_Std97 ()
111 +MSCodec_Std97::~MSCodec_Std97()
112 {
113 - (void)memset (m_pDigestValue, 0, sizeof(m_pDigestValue));
114 - (void)memset (m_pDocId, 0, sizeof(m_pDocId));
115 - rtl_digest_destroy (m_hDigest);
116 - rtl_cipher_destroy (m_hCipher);
117 + rtl_digest_destroy(m_hDigest);
118 }
119
120 #if DEBUG_MSO_ENCRYPTION_STD97
121 @@ -285,7 +294,7 @@ static inline void lcl_PrintDigest(const sal_uInt8* /*pDigest*/, const char* /*m
122 }
123 #endif
124
125 -bool MSCodec_Std97::InitCodec( const uno::Sequence< beans::NamedValue >& aData )
126 +bool MSCodec97::InitCodec( const uno::Sequence< beans::NamedValue >& aData )
127 {
128 #if DEBUG_MSO_ENCRYPTION_STD97
129 fprintf(stdout, "MSCodec_Std97::InitCodec: --begin\n");fflush(stdout);
130 @@ -294,16 +303,17 @@ bool MSCodec_Std97::InitCodec( const uno::Sequence< beans::NamedValue >& aData )
131
132 ::comphelper::SequenceAsHashMap aHashData( aData );
133 uno::Sequence< sal_Int8 > aKey = aHashData.getUnpackedValueOrDefault("STD97EncryptionKey", uno::Sequence< sal_Int8 >() );
134 -
135 - if ( aKey.getLength() == RTL_DIGEST_LENGTH_MD5 )
136 + const size_t nKeyLen = aKey.getLength();
137 + if (nKeyLen == m_nHashLen)
138 {
139 - (void)memcpy( m_pDigestValue, aKey.getConstArray(), RTL_DIGEST_LENGTH_MD5 );
140 + assert(m_aDigestValue.size() == m_nHashLen);
141 + (void)memcpy(m_aDigestValue.data(), aKey.getConstArray(), m_nHashLen);
142 uno::Sequence< sal_Int8 > aUniqueID = aHashData.getUnpackedValueOrDefault("STD97UniqueID", uno::Sequence< sal_Int8 >() );
143 if ( aUniqueID.getLength() == 16 )
144 {
145 (void)memcpy( m_pDocId, aUniqueID.getConstArray(), 16 );
146 bResult = true;
147 - lcl_PrintDigest(m_pDigestValue, "digest value");
148 + lcl_PrintDigest(m_aDigestValue.data(), "digest value");
149 lcl_PrintDigest(m_pDocId, "DocId value");
150 }
151 else
152 @@ -315,10 +325,11 @@ bool MSCodec_Std97::InitCodec( const uno::Sequence< beans::NamedValue >& aData )
153 return bResult;
154 }
155
156 -uno::Sequence< beans::NamedValue > MSCodec_Std97::GetEncryptionData()
157 +uno::Sequence< beans::NamedValue > MSCodec97::GetEncryptionData()
158 {
159 ::comphelper::SequenceAsHashMap aHashData;
160 - aHashData[ OUString( "STD97EncryptionKey" ) ] <<= uno::Sequence< sal_Int8 >( reinterpret_cast<sal_Int8*>(m_pDigestValue), RTL_DIGEST_LENGTH_MD5 );
161 + assert(m_aDigestValue.size() == m_nHashLen);
162 + aHashData[ OUString( "STD97EncryptionKey" ) ] <<= uno::Sequence< sal_Int8 >( reinterpret_cast<sal_Int8*>(m_aDigestValue.data()), m_nHashLen );
163 aHashData[ OUString( "STD97UniqueID" ) ] <<= uno::Sequence< sal_Int8 >( reinterpret_cast<sal_Int8*>(m_pDocId), 16 );
164
165 return aHashData.getAsConstNamedValueList();
166 @@ -334,26 +345,51 @@ void MSCodec_Std97::InitKey (
167 uno::Sequence< sal_Int8 > aKey = ::comphelper::DocPasswordHelper::GenerateStd97Key(pPassData, pDocId);
168 // Fill raw digest of above updates into DigestValue.
169
170 - if ( aKey.getLength() == sizeof(m_pDigestValue) )
171 - (void)memcpy ( m_pDigestValue, aKey.getConstArray(), sizeof(m_pDigestValue) );
172 + const size_t nKeyLen = aKey.getLength();
173 + if (m_aDigestValue.size() == nKeyLen)
174 + (void)memcpy(m_aDigestValue.data(), aKey.getConstArray(), m_aDigestValue.size());
175 else
176 - memset( m_pDigestValue, 0, sizeof(m_pDigestValue) );
177 + memset(m_aDigestValue.data(), 0, m_aDigestValue.size());
178 +
179 + lcl_PrintDigest(m_aDigestValue.data(), "digest value");
180 +
181 + (void)memcpy (m_pDocId, pDocId, 16);
182 +
183 + lcl_PrintDigest(m_pDocId, "DocId value");
184 +}
185 +
186 +void MSCodec_CryptoAPI::InitKey (
187 + const sal_uInt16 pPassData[16],
188 + const sal_uInt8 pDocId[16])
189 +{
190 + sal_uInt32 saltSize = 16;
191 +
192 + // Prepare initial data -> salt + password (in 16-bit chars)
193 + std::vector<sal_uInt8> initialData(pDocId, pDocId + saltSize);
194 +
195 + // Fill PassData into KeyData.
196 + for (sal_Int32 nInd = 0; nInd < 16 && pPassData[nInd]; ++nInd)
197 + {
198 + initialData.push_back(sal::static_int_cast<sal_uInt8>((pPassData[nInd] >> 0) & 0xff));
199 + initialData.push_back(sal::static_int_cast<sal_uInt8>((pPassData[nInd] >> 8) & 0xff));
200 + }
201 +
202 + // calculate SHA1 hash of initialData
203 + rtl_digest_SHA1(initialData.data(), initialData.size(), m_aDigestValue.data(), m_aDigestValue.size());
204
205 - lcl_PrintDigest(m_pDigestValue, "digest value");
206 + lcl_PrintDigest(m_aDigestValue.data(), "digest value");
207
208 (void)memcpy (m_pDocId, pDocId, 16);
209
210 lcl_PrintDigest(m_pDocId, "DocId value");
211 }
212
213 -bool MSCodec_Std97::VerifyKey (
214 - const sal_uInt8 pSaltData[16],
215 - const sal_uInt8 pSaltDigest[16])
216 +bool MSCodec97::VerifyKey(const sal_uInt8* pSaltData, const sal_uInt8* pSaltDigest)
217 {
218 // both the salt data and salt digest (hash) come from the document being imported.
219
220 #if DEBUG_MSO_ENCRYPTION_STD97
221 - fprintf(stdout, "MSCodec_Std97::VerifyKey: \n");
222 + fprintf(stdout, "MSCodec97::VerifyKey: \n");
223 lcl_PrintDigest(pSaltData, "salt data");
224 lcl_PrintDigest(pSaltDigest, "salt hash");
225 #endif
226 @@ -361,35 +397,42 @@ bool MSCodec_Std97::VerifyKey (
227
228 if (InitCipher(0))
229 {
230 - sal_uInt8 pDigest[RTL_DIGEST_LENGTH_MD5];
231 - GetDigestFromSalt(pSaltData, pDigest);
232 + std::vector<sal_uInt8> aDigest(m_nHashLen);
233 + GetDigestFromSalt(pSaltData, aDigest.data());
234
235 - sal_uInt8 pBuffer[16];
236 + std::vector<sal_uInt8> aBuffer(m_nHashLen);
237 // Decode original SaltDigest into Buffer.
238 - rtl_cipher_decode (
239 - m_hCipher, pSaltDigest, 16, pBuffer, sizeof(pBuffer));
240 + rtl_cipher_decode(m_hCipher, pSaltDigest, m_nHashLen, aBuffer.data(), m_nHashLen);
241
242 // Compare Buffer with computed Digest.
243 - result = (memcmp (pBuffer, pDigest, sizeof(pDigest)) == 0);
244 + result = (memcmp(aBuffer.data(), aDigest.data(), m_nHashLen) == 0);
245
246 // Erase Buffer and Digest arrays.
247 - rtl_secureZeroMemory (pBuffer, sizeof(pBuffer));
248 - rtl_secureZeroMemory (pDigest, sizeof(pDigest));
249 + rtl_secureZeroMemory(aBuffer.data(), m_nHashLen);
250 + rtl_secureZeroMemory(aDigest.data(), m_nHashLen);
251 }
252
253 return result;
254 }
255
256 -bool MSCodec_Std97::InitCipher (sal_uInt32 nCounter)
257 +void MSCodec_CryptoAPI::GetDigestFromSalt(const sal_uInt8* pSaltData, sal_uInt8* pDigest)
258 +{
259 + std::vector<sal_uInt8> verifier(16);
260 + rtl_cipher_decode(m_hCipher,
261 + pSaltData, 16, verifier.data(), verifier.size());
262 +
263 + rtl_digest_SHA1(verifier.data(), verifier.size(), pDigest, RTL_DIGEST_LENGTH_SHA1);
264 +}
265 +
266 +bool MSCodec_Std97::InitCipher(sal_uInt32 nCounter)
267 {
268 - rtlCipherError result;
269 sal_uInt8 pKeyData[64]; // 512-bit message block
270
271 // Initialize KeyData array.
272 (void)memset (pKeyData, 0, sizeof(pKeyData));
273
274 // Fill 40 bit of DigestValue into [0..4].
275 - (void)memcpy (pKeyData, m_pDigestValue, 5);
276 + (void)memcpy (pKeyData, m_aDigestValue.data(), 5);
277
278 // Fill counter into [5..8].
279 pKeyData[ 5] = sal_uInt8((nCounter >> 0) & 0xff);
280 @@ -407,7 +450,7 @@ bool MSCodec_Std97::InitCipher (sal_uInt32 nCounter)
281 m_hDigest, pKeyData, RTL_DIGEST_LENGTH_MD5);
282
283 // Initialize Cipher with KeyData (for decoding).
284 - result = rtl_cipher_init (
285 + rtlCipherError result = rtl_cipher_init (
286 m_hCipher, rtl_Cipher_DirectionBoth,
287 pKeyData, RTL_DIGEST_LENGTH_MD5, nullptr, 0);
288
289 @@ -417,12 +460,30 @@ bool MSCodec_Std97::InitCipher (sal_uInt32 nCounter)
290 return (result == rtl_Cipher_E_None);
291 }
292
293 -bool MSCodec_Std97::CreateSaltDigest( const sal_uInt8 nSaltData[16], sal_uInt8 nSaltDigest[16] )
294 +bool MSCodec_CryptoAPI::InitCipher(sal_uInt32 nCounter)
295 +{
296 + // data = hash + iterator (4bytes)
297 + std::vector<sal_uInt8> aKeyData(m_aDigestValue);
298 + aKeyData.push_back(sal_uInt8((nCounter >> 0) & 0xff));
299 + aKeyData.push_back(sal_uInt8((nCounter >> 8) & 0xff));
300 + aKeyData.push_back(sal_uInt8((nCounter >> 16) & 0xff));
301 + aKeyData.push_back(sal_uInt8((nCounter >> 24) & 0xff));
302 +
303 + std::vector<sal_uInt8> hash(RTL_DIGEST_LENGTH_SHA1);
304 + rtl_digest_SHA1(aKeyData.data(), aKeyData.size(), hash.data(), RTL_DIGEST_LENGTH_SHA1);
305 +
306 + rtlCipherError result =
307 + rtl_cipher_init(m_hCipher, rtl_Cipher_DirectionDecode,
308 + hash.data(), ENCRYPT_KEY_SIZE_AES_128/8, nullptr, 0);
309 +
310 + return (result == rtl_Cipher_E_None);
311 +}
312 +
313 +void MSCodec_Std97::CreateSaltDigest( const sal_uInt8 nSaltData[16], sal_uInt8 nSaltDigest[16] )
314 {
315 #if DEBUG_MSO_ENCRYPTION_STD97
316 lcl_PrintDigest(nSaltData, "salt data");
317 #endif
318 - bool result = false;
319
320 if (InitCipher(0))
321 {
322 @@ -434,35 +495,29 @@ bool MSCodec_Std97::CreateSaltDigest( const sal_uInt8 nSaltData[16], sal_uInt8 n
323
324 (void)memcpy(nSaltDigest, pDigest, 16);
325 }
326 -
327 - return result;
328 }
329
330 -bool MSCodec_Std97::Encode (
331 - const void *pData, sal_Size nDatLen,
332 - sal_uInt8 *pBuffer, sal_Size nBufLen)
333 +bool MSCodec97::Encode (
334 + const void *pData, std::size_t nDatLen,
335 + sal_uInt8 *pBuffer, std::size_t nBufLen)
336 {
337 - rtlCipherError result;
338 -
339 - result = rtl_cipher_encode (
340 + rtlCipherError result = rtl_cipher_encode(
341 m_hCipher, pData, nDatLen, pBuffer, nBufLen);
342
343 return (result == rtl_Cipher_E_None);
344 }
345
346 -bool MSCodec_Std97::Decode (
347 - const void *pData, sal_Size nDatLen,
348 - sal_uInt8 *pBuffer, sal_Size nBufLen)
349 +bool MSCodec97::Decode (
350 + const void *pData, std::size_t nDatLen,
351 + sal_uInt8 *pBuffer, std::size_t nBufLen)
352 {
353 - rtlCipherError result;
354 -
355 - result = rtl_cipher_decode (
356 + rtlCipherError result = rtl_cipher_decode(
357 m_hCipher, pData, nDatLen, pBuffer, nBufLen);
358
359 return (result == rtl_Cipher_E_None);
360 }
361
362 -bool MSCodec_Std97::Skip( sal_Size nDatLen )
363 +bool MSCodec97::Skip(std::size_t nDatLen)
364 {
365 sal_uInt8 pnDummy[ 1024 ];
366 sal_Size nDatLeft = nDatLen;
367 @@ -478,7 +533,7 @@ bool MSCodec_Std97::Skip( sal_Size nDatLen )
368 return bResult;
369 }
370
371 -void MSCodec_Std97::GetDigestFromSalt( const sal_uInt8 pSaltData[16], sal_uInt8 pDigest[16] )
372 +void MSCodec_Std97::GetDigestFromSalt(const sal_uInt8* pSaltData, sal_uInt8* pDigest)
373 {
374 sal_uInt8 pBuffer[64];
375 sal_uInt8 pDigestLocal[16];
376 @@ -537,12 +592,41 @@ void MSCodec_Std97::GetEncryptKey (
377 }
378 }
379
380 -void MSCodec_Std97::GetDocId( sal_uInt8 pDocId[16] )
381 +void MSCodec97::GetDocId( sal_uInt8 pDocId[16] )
382 {
383 if ( sizeof( m_pDocId ) == 16 )
384 (void)memcpy( pDocId, m_pDocId, 16 );
385 }
386
387 +EncryptionStandardHeader::EncryptionStandardHeader()
388 +{
389 + flags = 0;
390 + sizeExtra = 0;
391 + algId = 0;
392 + algIdHash = 0;
393 + keyBits = 0;
394 + providedType = 0;
395 + reserved1 = 0;
396 + reserved2 = 0;
397 +}
398 +
399 +EncryptionVerifierAES::EncryptionVerifierAES()
400 + : saltSize(SALT_LENGTH)
401 + , encryptedVerifierHashSize(SHA1_HASH_LENGTH)
402 +{
403 + memset(salt, 0, sizeof(salt));
404 + memset(encryptedVerifier, 0, sizeof(encryptedVerifier));
405 + memset(encryptedVerifierHash, 0, sizeof(encryptedVerifierHash));
406 +}
407 +
408 +EncryptionVerifierRC4::EncryptionVerifierRC4()
409 + : saltSize(SALT_LENGTH)
410 + , encryptedVerifierHashSize(SHA1_HASH_LENGTH)
411 +{
412 + memset(salt, 0, sizeof(salt));
413 + memset(encryptedVerifier, 0, sizeof(encryptedVerifier));
414 + memset(encryptedVerifierHash, 0, sizeof(encryptedVerifierHash));
415 +}
416
417
418 }
419 diff --git a/include/filter/msfilter/mscodec.hxx b/include/filter/msfilter/mscodec.hxx
420 index 4f5676b..4ab6c9b 100644
421 --- a/include/filter/msfilter/mscodec.hxx
422 +++ b/include/filter/msfilter/mscodec.hxx
423 @@ -26,6 +26,12 @@
424 #include <rtl/cipher.h>
425 #include <rtl/digest.h>
426 #include <filter/msfilter/msfilterdllapi.h>
427 +#include <sal/types.h>
428 +#include <vector>
429 +
430 +namespace com { namespace sun { namespace star {
431 + namespace beans { struct NamedValue; }
432 +} } }
433
434 namespace msfilter {
435
436 @@ -172,20 +178,11 @@ public:
437 virtual void Decode( sal_uInt8* pnData, sal_Size nBytes ) override;
438 };
439
440 -
441 -
442 -
443 -/** Encodes and decodes data from protected MSO 97+ documents.
444 -
445 - This is a wrapper class around low level cryptographic functions from RTL.
446 - Implementation is based on the wvDecrypt package by Caolan McNamara:
447 - http://www.csn.ul.ie/~caolan/docs/wvDecrypt.html
448 - */
449 -class MSFILTER_DLLPUBLIC MSCodec_Std97
450 +class MSFILTER_DLLPUBLIC MSCodec97
451 {
452 public:
453 - explicit MSCodec_Std97();
454 - ~MSCodec_Std97();
455 + MSCodec97(size_t nHashLen);
456 + virtual ~MSCodec97();
457
458 /** Initializes the algorithm with the encryption data.
459
460 @@ -193,7 +190,7 @@ public:
461 The sequence contains the necessary data to initialize
462 the codec.
463 */
464 - bool InitCodec( const css::uno::Sequence< css::beans::NamedValue >& aData );
465 + bool InitCodec(const css::uno::Sequence< css::beans::NamedValue >& aData);
466
467 /** Retrieves the encryption data
468
469 @@ -203,7 +200,6 @@ public:
470 */
471 css::uno::Sequence< css::beans::NamedValue > GetEncryptionData();
472
473 -
474 /** Initializes the algorithm with the specified password and document ID.
475
476 @param pPassData
477 @@ -212,9 +208,9 @@ public:
478 @param pDocId
479 Unique document identifier read from or written to the file.
480 */
481 - void InitKey(
482 - const sal_uInt16 pPassData[ 16 ],
483 - const sal_uInt8 pDocId[ 16 ] );
484 + virtual void InitKey(const sal_uInt16 pPassData[16],
485 + const sal_uInt8 pDocId[16]) = 0;
486 +
487
488 /** Verifies the validity of the password using the passed salt data.
489
490 @@ -230,9 +226,9 @@ public:
491 @return
492 true = Test was successful.
493 */
494 - bool VerifyKey(
495 - const sal_uInt8 pSaltData[ 16 ],
496 - const sal_uInt8 pSaltDigest[ 16 ] );
497 + bool VerifyKey(const sal_uInt8* pSaltData, const sal_uInt8* pSaltDigest);
498 +
499 + virtual void GetDigestFromSalt(const sal_uInt8* pSaltData, sal_uInt8* pDigest) = 0;
500
501 /** Rekeys the codec using the specified counter.
502
503 @@ -249,11 +245,7 @@ public:
504 @param nCounter
505 Block counter used to rekey the cipher.
506 */
507 - bool InitCipher( sal_uInt32 nCounter );
508 -
509 - /** Creates an MD5 digest of salt digest. */
510 - bool CreateSaltDigest(
511 - const sal_uInt8 nSaltData[16], sal_uInt8 nSaltDigest[16] );
512 + virtual bool InitCipher(sal_uInt32 nCounter) = 0;
513
514 /** Encodes a block of memory.
515
516 @@ -277,9 +269,8 @@ public:
517 @return
518 true = Encoding was successful (no error occurred).
519 */
520 - bool Encode(
521 - const void* pData, sal_Size nDatLen,
522 - sal_uInt8* pBuffer, sal_Size nBufLen );
523 + bool Encode(const void* pData, std::size_t nDatLen,
524 + sal_uInt8* pBuffer, std::size_t nBufLen);
525
526 /** Decodes a block of memory.
527
528 @@ -303,9 +294,8 @@ public:
529 @return
530 true = Decoding was successful (no error occurred).
531 */
532 - bool Decode(
533 - const void* pData, sal_Size nDatLen,
534 - sal_uInt8* pBuffer, sal_Size nBufLen );
535 + bool Decode(const void* pData, std::size_t nDatLen,
536 + sal_uInt8* pBuffer, std::size_t nBufLen);
537
538 /** Lets the cipher skip a specific amount of bytes.
539
540 @@ -319,7 +309,66 @@ public:
541 @param nDatLen
542 Number of bytes to be skipped (cipher "seeks" forward).
543 */
544 - bool Skip( sal_Size nDatLen );
545 + bool Skip(std::size_t nDatLen);
546 +
547 + /* allows to get the unique document id from the codec
548 + */
549 + void GetDocId( sal_uInt8 pDocId[16] );
550 +
551 +private:
552 + MSCodec97(const MSCodec97&) = delete;
553 + MSCodec97& operator=(const MSCodec97&) = delete;
554 +
555 +protected:
556 + size_t m_nHashLen;
557 + rtlCipher m_hCipher;
558 + sal_uInt8 m_pDocId[16];
559 + std::vector<sal_uInt8> m_aDigestValue;
560 +};
561 +
562 +/** Encodes and decodes data from protected MSO 97+ documents.
563 +
564 + This is a wrapper class around low level cryptographic functions from RTL.
565 + Implementation is based on the wvDecrypt package by Caolan McNamara:
566 + http://www.csn.ul.ie/~caolan/docs/wvDecrypt.html
567 + */
568 +class MSFILTER_DLLPUBLIC MSCodec_Std97 : public MSCodec97
569 +{
570 +public:
571 + MSCodec_Std97();
572 + virtual ~MSCodec_Std97() override;
573 +
574 + /** Initializes the algorithm with the specified password and document ID.
575 +
576 + @param pPassData
577 + Wide character array containing the password. Must be zero
578 + terminated, which results in a maximum length of 15 characters.
579 + @param pDocId
580 + Unique document identifier read from or written to the file.
581 + */
582 + virtual void InitKey(const sal_uInt16 pPassData[16],
583 + const sal_uInt8 pDocId[16]) override;
584 +
585 + /** Rekeys the codec using the specified counter.
586 +
587 + After reading a specific amount of data the cipher algorithm needs to
588 + be rekeyed using a counter that counts the data blocks.
589 +
590 + The block size is for example 512 Bytes for Word files and 1024 Bytes
591 + for Excel files.
592 +
593 + @precond
594 + The codec must be initialized with InitKey() before this function
595 + can be used.
596 +
597 + @param nCounter
598 + Block counter used to rekey the cipher.
599 + */
600 + virtual bool InitCipher(sal_uInt32 nCounter) override;
601 +
602 + /** Creates an MD5 digest of salt digest. */
603 + void CreateSaltDigest(
604 + const sal_uInt8 nSaltData[16], sal_uInt8 nSaltDigest[16] );
605
606 /** Gets salt data and salt digest.
607
608 @@ -339,22 +388,108 @@ public:
609 sal_uInt8 pSaltData[16],
610 sal_uInt8 pSaltDigest[16]);
611
612 - /* allows to get the unique document id from the codec
613 - */
614 - void GetDocId( sal_uInt8 pDocId[16] );
615 -
616 - void GetDigestFromSalt( const sal_uInt8 pSaltData[16], sal_uInt8 pDigest[16] );
617 + virtual void GetDigestFromSalt(const sal_uInt8* pSaltData, sal_uInt8* pDigest) override;
618
619 private:
620 MSCodec_Std97( const MSCodec_Std97& ) = delete;
621 MSCodec_Std97& operator=( const MSCodec_Std97& ) = delete;
622
623 - rtlCipher m_hCipher;
624 rtlDigest m_hDigest;
625 - sal_uInt8 m_pDigestValue[ RTL_DIGEST_LENGTH_MD5 ];
626 - sal_uInt8 m_pDocId[16];
627 };
628
629 +class MSFILTER_DLLPUBLIC MSCodec_CryptoAPI : public MSCodec97
630 +{
631 +public:
632 + MSCodec_CryptoAPI();
633 +
634 + virtual void InitKey(const sal_uInt16 pPassData[16],
635 + const sal_uInt8 pDocId[16]) override;
636 + virtual bool InitCipher(sal_uInt32 nCounter) override;
637 + virtual void GetDigestFromSalt(const sal_uInt8* pSaltData, sal_uInt8* pDigest) override;
638 +};
639 +
640 +const sal_uInt32 ENCRYPTINFO_CRYPTOAPI = 0x00000004;
641 +const sal_uInt32 ENCRYPTINFO_DOCPROPS = 0x00000008;
642 +const sal_uInt32 ENCRYPTINFO_EXTERNAL = 0x00000010;
643 +const sal_uInt32 ENCRYPTINFO_AES = 0x00000020;
644 +
645 +const sal_uInt32 ENCRYPT_ALGO_AES128 = 0x0000660E;
646 +const sal_uInt32 ENCRYPT_ALGO_AES192 = 0x0000660F;
647 +const sal_uInt32 ENCRYPT_ALGO_AES256 = 0x00006610;
648 +const sal_uInt32 ENCRYPT_ALGO_RC4 = 0x00006801;
649 +
650 +const sal_uInt32 ENCRYPT_HASH_SHA1 = 0x00008004;
651 +
652 +const sal_uInt32 ENCRYPT_KEY_SIZE_AES_128 = 0x00000080;
653 +const sal_uInt32 ENCRYPT_KEY_SIZE_AES_192 = 0x000000C0;
654 +const sal_uInt32 ENCRYPT_KEY_SIZE_AES_256 = 0x00000100;
655 +
656 +const sal_uInt32 ENCRYPT_PROVIDER_TYPE_AES = 0x00000018;
657 +const sal_uInt32 ENCRYPT_PROVIDER_TYPE_RC4 = 0x00000001;
658 +
659 +// version of encryption info used in MS Office 1997 (major = 1, minor = 1)
660 +const sal_uInt32 VERSION_INFO_1997_FORMAT = 0x00010001;
661 +// version of encryption info used in MS Office 2007 (major = 3, minor = 2)
662 +const sal_uInt32 VERSION_INFO_2007_FORMAT = 0x00020003;
663 +// version of encryption info used in MS Office 2007 SP2 and older (major = 4, minor = 2)
664 +const sal_uInt32 VERSION_INFO_2007_FORMAT_SP2 = 0x00020004;
665 +
666 +// version of encryption info - agile (major = 4, minor = 4)
667 +const sal_uInt32 VERSION_INFO_AGILE = 0x00040004;
668 +
669 +const sal_uInt32 SALT_LENGTH = 16;
670 +const sal_uInt32 ENCRYPTED_VERIFIER_LENGTH = 16;
671 +const sal_uInt32 SHA1_HASH_LENGTH = RTL_DIGEST_LENGTH_SHA1; // 20
672 +const sal_uInt32 SHA256_HASH_LENGTH = 32;
673 +const sal_uInt32 SHA512_HASH_LENGTH = 64;
674 +
675 +struct MSFILTER_DLLPUBLIC EncryptionStandardHeader
676 +{
677 + sal_uInt32 flags;
678 + sal_uInt32 sizeExtra; // 0
679 + sal_uInt32 algId; // if flag AES && CRYPTOAPI this defaults to 128-bit AES
680 + sal_uInt32 algIdHash; // 0: determine by flags - defaults to SHA-1 if not external
681 + sal_uInt32 keyBits; // key size in bits: 0 (determine by flags), 128, 192, 256
682 + sal_uInt32 providedType; // AES or RC4
683 + sal_uInt32 reserved1; // 0
684 + sal_uInt32 reserved2; // 0
685 +
686 + EncryptionStandardHeader();
687 +};
688 +
689 +struct MSFILTER_DLLPUBLIC EncryptionVerifierAES
690 +{
691 + sal_uInt32 saltSize; // must be 0x00000010
692 + sal_uInt8 salt[SALT_LENGTH]; // random generated salt value
693 + sal_uInt8 encryptedVerifier[ENCRYPTED_VERIFIER_LENGTH]; // randomly generated verifier value
694 + sal_uInt32 encryptedVerifierHashSize; // actually written hash size - depends on algorithm
695 + sal_uInt8 encryptedVerifierHash[SHA256_HASH_LENGTH]; // verifier value hash - itself also encrypted
696 +
697 + EncryptionVerifierAES();
698 +};
699 +
700 +struct MSFILTER_DLLPUBLIC EncryptionVerifierRC4
701 +{
702 + sal_uInt32 saltSize; // must be 0x00000010
703 + sal_uInt8 salt[SALT_LENGTH]; // random generated salt value
704 + sal_uInt8 encryptedVerifier[ENCRYPTED_VERIFIER_LENGTH]; // randomly generated verifier value
705 + sal_uInt32 encryptedVerifierHashSize; // actually written hash size - depends on algorithm
706 + sal_uInt8 encryptedVerifierHash[SHA1_HASH_LENGTH]; // verifier value hash - itself also encrypted
707 +
708 + EncryptionVerifierRC4();
709 +};
710 +
711 +struct MSFILTER_DLLPUBLIC StandardEncryptionInfo
712 +{
713 + EncryptionStandardHeader header;
714 + EncryptionVerifierAES verifier;
715 +};
716 +
717 +struct MSFILTER_DLLPUBLIC RC4EncryptionInfo
718 +{
719 + EncryptionStandardHeader header;
720 + EncryptionVerifierRC4 verifier;
721 +};
722
723
724 } // namespace msfilter
725 diff --git a/include/oox/crypto/CryptTools.hxx b/include/oox/crypto/CryptTools.hxx
726 index 898c47d..dc91ad9 100644
727 --- a/include/oox/crypto/CryptTools.hxx
728 +++ b/include/oox/crypto/CryptTools.hxx
729 @@ -126,9 +126,6 @@ public:
730 SHA512
731 };
732
733 - static const sal_uInt32 DIGEST_LENGTH_SHA1;
734 - static const sal_uInt32 DIGEST_LENGTH_SHA512;
735 -
736 private:
737 DigestType meType;
738
739 diff --git a/include/oox/crypto/Standard2007Engine.hxx b/include/oox/crypto/Standard2007Engine.hxx
740 index 5e5a6fc..10cac82 100644
741 --- a/include/oox/crypto/Standard2007Engine.hxx
742 +++ b/include/oox/crypto/Standard2007Engine.hxx
743 @@ -13,75 +13,23 @@
744
745 #include <oox/crypto/CryptTools.hxx>
746 #include <oox/crypto/CryptoEngine.hxx>
747 +#include <filter/msfilter/mscodec.hxx>
748 +#include <oox/crypto/CryptoEngine.hxx>
749 +#include <rtl/digest.h>
750 +#include <rtl/ustring.hxx>
751 +#include <sal/types.h>
752
753 namespace oox {
754 -namespace core {
755 -
756 -const sal_uInt32 ENCRYPTINFO_CRYPTOAPI = 0x00000004;
757 -const sal_uInt32 ENCRYPTINFO_DOCPROPS = 0x00000008;
758 -const sal_uInt32 ENCRYPTINFO_EXTERNAL = 0x00000010;
759 -const sal_uInt32 ENCRYPTINFO_AES = 0x00000020;
760 -
761 -const sal_uInt32 ENCRYPT_ALGO_AES128 = 0x0000660E;
762 -const sal_uInt32 ENCRYPT_ALGO_AES192 = 0x0000660F;
763 -const sal_uInt32 ENCRYPT_ALGO_AES256 = 0x00006610;
764 -const sal_uInt32 ENCRYPT_ALGO_RC4 = 0x00006801;
765 -
766 -const sal_uInt32 ENCRYPT_HASH_SHA1 = 0x00008004;
767 -
768 -const sal_uInt32 ENCRYPT_KEY_SIZE_AES_128 = 0x00000080;
769 -const sal_uInt32 ENCRYPT_KEY_SIZE_AES_192 = 0x000000C0;
770 -const sal_uInt32 ENCRYPT_KEY_SIZE_AES_256 = 0x00000100;
771 + class BinaryXInputStream;
772 + class BinaryXOutputStream;
773 +}
774
775 -const sal_uInt32 ENCRYPT_PROVIDER_TYPE_AES = 0x00000018;
776 -const sal_uInt32 ENCRYPT_PROVIDER_TYPE_RC4 = 0x00000001;
777 -
778 -// version of encryption info used in MS Office 2007 (major = 3, minor = 2)
779 -const sal_uInt32 VERSION_INFO_2007_FORMAT = 0x00020003;
780 -// version of encryption info used in MS Office 2007 SP2 and older (major = 4, minor = 2)
781 -const sal_uInt32 VERSION_INFO_2007_FORMAT_SP2 = 0x00020004;
782 -
783 -// version of encryption info - agile (major = 4, minor = 4)
784 -const sal_uInt32 VERSION_INFO_AGILE = 0x00040004;
785 -
786 -const sal_uInt32 SALT_LENGTH = 16;
787 -const sal_uInt32 ENCRYPTED_VERIFIER_LENGTH = 16;
788 -const sal_uInt32 ENCRYPTED_VERIFIER_HASH_LENGTH = 32;
789 -
790 -struct EncryptionStandardHeader
791 -{
792 - sal_uInt32 flags;
793 - sal_uInt32 sizeExtra; // 0
794 - sal_uInt32 algId; // if flag AES && CRYPTOAPI this defaults to 128-bit AES
795 - sal_uInt32 algIdHash; // 0: determine by flags - defaults to SHA-1 if not external
796 - sal_uInt32 keyBits; // key size in bits: 0 (determine by flags), 128, 192, 256
797 - sal_uInt32 providedType; // AES or RC4
798 - sal_uInt32 reserved1; // 0
799 - sal_uInt32 reserved2; // 0
800 -
801 - EncryptionStandardHeader();
802 -};
803 -
804 -struct EncryptionVerifierAES
805 -{
806 - sal_uInt32 saltSize; // must be 0x00000010
807 - sal_uInt8 salt[SALT_LENGTH]; // random generated salt value
808 - sal_uInt8 encryptedVerifier[ENCRYPTED_VERIFIER_LENGTH]; // randomly generated verifier value
809 - sal_uInt32 encryptedVerifierHashSize; // actually written hash size - depends on algorithm
810 - sal_uInt8 encryptedVerifierHash[ENCRYPTED_VERIFIER_HASH_LENGTH]; // verifier value hash - itself also encrypted
811 -
812 - EncryptionVerifierAES();
813 -};
814 -
815 -struct StandardEncryptionInfo
816 -{
817 - EncryptionStandardHeader header;
818 - EncryptionVerifierAES verifier;
819 -};
820 +namespace oox {
821 +namespace core {
822
823 class Standard2007Engine : public CryptoEngine
824 {
825 - StandardEncryptionInfo mInfo;
826 + msfilter::StandardEncryptionInfo mInfo;
827
828 bool generateVerifier();
829 bool calculateEncryptionKey(const OUString& rPassword);
830 @@ -90,7 +38,7 @@ public:
831 Standard2007Engine();
832 virtual ~Standard2007Engine();
833
834 - StandardEncryptionInfo& getInfo() { return mInfo;}
835 + msfilter::StandardEncryptionInfo& getInfo() { return mInfo;}
836
837 virtual bool generateEncryptionKey(const OUString& rPassword) override;
838
839 diff --git a/oox/source/crypto/CryptTools.cxx b/oox/source/crypto/CryptTools.cxx
840 index f21b0e1..9b1d50b 100644
841 --- a/oox/source/crypto/CryptTools.cxx
842 +++ b/oox/source/crypto/CryptTools.cxx
843 @@ -9,6 +9,7 @@
844 */
845
846 #include "oox/crypto/CryptTools.hxx"
847 +#include <filter/msfilter/mscodec.hxx>
848 #include <com/sun/star/uno/RuntimeException.hpp>
849
850 namespace oox {
851 @@ -196,15 +197,6 @@ sal_uInt32 Encrypt::update(vector<sal_uInt8>& output, vector<sal_uInt8>& input,
852
853 // Digest
854
855 -#if USE_TLS_OPENSSL
856 -const sal_uInt32 Digest::DIGEST_LENGTH_SHA1 = SHA_DIGEST_LENGTH;
857 -const sal_uInt32 Digest::DIGEST_LENGTH_SHA512 = SHA512_DIGEST_LENGTH;
858 -#endif
859 -#if USE_TLS_NSS
860 -const sal_uInt32 Digest::DIGEST_LENGTH_SHA1 = SHA1_LENGTH;
861 -const sal_uInt32 Digest::DIGEST_LENGTH_SHA512 = SHA512_LENGTH;
862 -#endif
863 -
864 namespace
865 {
866
867 @@ -275,9 +267,9 @@ sal_uInt32 Digest::getLength()
868 switch(meType)
869 {
870 case SHA1:
871 - return DIGEST_LENGTH_SHA1;
872 + return msfilter::SHA1_HASH_LENGTH;
873 case SHA512:
874 - return DIGEST_LENGTH_SHA512;
875 + return msfilter::SHA512_HASH_LENGTH;
876 default:
877 break;
878 }
879 diff --git a/oox/source/crypto/DocumentDecryption.cxx b/oox/source/crypto/DocumentDecryption.cxx
880 index 8dcf4ca..80054b3 100644
881 --- a/oox/source/crypto/DocumentDecryption.cxx
882 +++ b/oox/source/crypto/DocumentDecryption.cxx
883 @@ -235,7 +235,7 @@ bool DocumentDecryption::readAgileEncryptionInfo(Reference< XInputStream >& xInp
884 info.cipherAlgorithm == "AES" &&
885 info.cipherChaining == "ChainingModeCBC" &&
886 info.hashAlgorithm == "SHA1" &&
887 - info.hashSize == 20)
888 + info.hashSize == msfilter::SHA1_HASH_LENGTH)
889 {
890 return true;
891 }
892 @@ -245,7 +245,7 @@ bool DocumentDecryption::readAgileEncryptionInfo(Reference< XInputStream >& xInp
893 info.cipherAlgorithm == "AES" &&
894 info.cipherChaining == "ChainingModeCBC" &&
895 info.hashAlgorithm == "SHA512" &&
896 - info.hashSize == 64 )
897 + info.hashSize == msfilter::SHA512_HASH_LENGTH)
898 {
899 return true;
900 }
901 @@ -257,10 +257,10 @@ bool DocumentDecryption::readStandard2007EncryptionInfo(BinaryInputStream& rStre
902 {
903 Standard2007Engine* engine = new Standard2007Engine();
904 mEngine.reset(engine);
905 - StandardEncryptionInfo& info = engine->getInfo();
906 + msfilter::StandardEncryptionInfo& info = engine->getInfo();
907
908 info.header.flags = rStream.readuInt32();
909 - if( getFlag( info.header.flags, ENCRYPTINFO_EXTERNAL ) )
910 + if( getFlag( info.header.flags, msfilter::ENCRYPTINFO_EXTERNAL ) )
911 return false;
912
913 sal_uInt32 nHeaderSize = rStream.readuInt32();
914 @@ -291,18 +291,18 @@ bool DocumentDecryption::readStandard2007EncryptionInfo(BinaryInputStream& rStre
915 return false;
916
917 // check flags and algorithm IDs, required are AES128 and SHA-1
918 - if( !getFlag( info.header.flags , ENCRYPTINFO_CRYPTOAPI ) )
919 + if( !getFlag( info.header.flags, msfilter::ENCRYPTINFO_CRYPTOAPI ) )
920 return false;
921
922 - if( !getFlag( info.header.flags, ENCRYPTINFO_AES ) )
923 + if( !getFlag( info.header.flags, msfilter::ENCRYPTINFO_AES ) )
924 return false;
925
926 // algorithm ID 0 defaults to AES128 too, if ENCRYPTINFO_AES flag is set
927 - if( info.header.algId != 0 && info.header.algId != ENCRYPT_ALGO_AES128 )
928 + if( info.header.algId != 0 && info.header.algId != msfilter::ENCRYPT_ALGO_AES128 )
929 return false;
930
931 // hash algorithm ID 0 defaults to SHA-1 too
932 - if( info.header.algIdHash != 0 && info.header.algIdHash != ENCRYPT_HASH_SHA1 )
933 + if( info.header.algIdHash != 0 && info.header.algIdHash != msfilter::ENCRYPT_HASH_SHA1 )
934 return false;
935
936 if( info.verifier.encryptedVerifierHashSize != 20 )
937 @@ -326,12 +326,12 @@ bool DocumentDecryption::readEncryptionInfo()
938
939 switch (aVersion)
940 {
941 - case VERSION_INFO_2007_FORMAT:
942 - case VERSION_INFO_2007_FORMAT_SP2:
943 + case msfilter::VERSION_INFO_2007_FORMAT:
944 + case msfilter::VERSION_INFO_2007_FORMAT_SP2:
945 mCryptoType = STANDARD_2007; // Set encryption info format
946 bResult = readStandard2007EncryptionInfo( aBinaryInputStream );
947 break;
948 - case VERSION_INFO_AGILE:
949 + case msfilter::VERSION_INFO_AGILE:
950 mCryptoType = AGILE; // Set encryption info format
951 aBinaryInputStream.skip(4);
952 bResult = readAgileEncryptionInfo( xEncryptionInfo );
953 diff --git a/oox/source/crypto/Standard2007Engine.cxx b/oox/source/crypto/Standard2007Engine.cxx
954 index 299d251..68df963 100644
955 --- a/oox/source/crypto/Standard2007Engine.cxx
956 +++ b/oox/source/crypto/Standard2007Engine.cxx
957 @@ -38,27 +38,6 @@ static const OUString lclCspName = "Microsoft Enhanced RSA and AES Cryptographic
958
959 } // namespace
960
961 -EncryptionStandardHeader::EncryptionStandardHeader()
962 -{
963 - flags = 0;
964 - sizeExtra = 0;
965 - algId = 0;
966 - algIdHash = 0;
967 - keyBits = 0;
968 - providedType = 0;
969 - reserved1 = 0;
970 - reserved2 = 0;
971 -}
972 -
973 -EncryptionVerifierAES::EncryptionVerifierAES() :
974 - saltSize(SALT_LENGTH),
975 - encryptedVerifierHashSize(Digest::DIGEST_LENGTH_SHA1)
976 -{
977 - memset(salt, 0, sizeof(salt));
978 - memset(encryptedVerifier, 0, sizeof(encryptedVerifier));
979 - memset(encryptedVerifierHash, 0, sizeof(encryptedVerifierHash));
980 -}
981 -
982 Standard2007Engine::Standard2007Engine() :
983 CryptoEngine()
984 {}
985 @@ -72,23 +51,23 @@ bool Standard2007Engine::generateVerifier()
986 if (mKey.size() != 16)
987 return false;
988
989 - vector<sal_uInt8> verifier(ENCRYPTED_VERIFIER_LENGTH);
990 - vector<sal_uInt8> encryptedVerifier(ENCRYPTED_VERIFIER_LENGTH);
991 + vector<sal_uInt8> verifier(msfilter::ENCRYPTED_VERIFIER_LENGTH);
992 + vector<sal_uInt8> encryptedVerifier(msfilter::ENCRYPTED_VERIFIER_LENGTH);
993
994 lclRandomGenerateValues(&verifier[0], verifier.size());
995
996 vector<sal_uInt8> iv;
997 Encrypt aEncryptorVerifier(mKey, iv, Crypto::AES_128_ECB);
998 - if (aEncryptorVerifier.update(encryptedVerifier, verifier) != ENCRYPTED_VERIFIER_LENGTH)
999 + if (aEncryptorVerifier.update(encryptedVerifier, verifier) != msfilter::ENCRYPTED_VERIFIER_LENGTH)
1000 return false;
1001 std::copy(encryptedVerifier.begin(), encryptedVerifier.end(), mInfo.verifier.encryptedVerifier);
1002
1003 - vector<sal_uInt8> hash(RTL_DIGEST_LENGTH_SHA1, 0);
1004 - mInfo.verifier.encryptedVerifierHashSize = RTL_DIGEST_LENGTH_SHA1;
1005 + vector<sal_uInt8> hash(msfilter::SHA1_HASH_LENGTH, 0);
1006 + mInfo.verifier.encryptedVerifierHashSize = msfilter::SHA1_HASH_LENGTH;
1007 Digest::sha1(hash, verifier);
1008 - hash.resize(ENCRYPTED_VERIFIER_HASH_LENGTH, 0);
1009 + hash.resize(msfilter::SHA256_HASH_LENGTH, 0);
1010
1011 - vector<sal_uInt8> encryptedHash(ENCRYPTED_VERIFIER_HASH_LENGTH, 0);
1012 + vector<sal_uInt8> encryptedHash(msfilter::SHA256_HASH_LENGTH, 0);
1013
1014 Encrypt aEncryptorHash(mKey, iv, Crypto::AES_128_ECB);
1015 aEncryptorHash.update(encryptedHash, hash, hash.size());
1016 @@ -115,13 +94,13 @@ bool Standard2007Engine::calculateEncryptionKey(const OUString& rPassword)
1017 initialData.begin() + saltSize);
1018
1019 // use "hash" vector for result of sha1 hashing
1020 - vector<sal_uInt8> hash(Digest::DIGEST_LENGTH_SHA1, 0);
1021 + vector<sal_uInt8> hash(msfilter::SHA1_HASH_LENGTH, 0);
1022
1023 // calculate SHA1 hash of initialData
1024 Digest::sha1(hash, initialData);
1025
1026 // data = iterator (4bytes) + hash
1027 - vector<sal_uInt8> data(Digest::DIGEST_LENGTH_SHA1 + 4, 0);
1028 + vector<sal_uInt8> data(msfilter::SHA1_HASH_LENGTH + 4, 0);
1029
1030 for (sal_Int32 i = 0; i < 50000; ++i)
1031 {
1032 @@ -130,7 +109,7 @@ bool Standard2007Engine::calculateEncryptionKey(const OUString& rPassword)
1033 Digest::sha1(hash, data);
1034 }
1035 std::copy(hash.begin(), hash.end(), data.begin() );
1036 - std::fill(data.begin() + Digest::DIGEST_LENGTH_SHA1, data.end(), 0 );
1037 + std::fill(data.begin() + msfilter::SHA1_HASH_LENGTH, data.end(), 0 );
1038
1039 Digest::sha1(hash, data);
1040
1041 @@ -152,16 +131,16 @@ bool Standard2007Engine::generateEncryptionKey(const OUString& password)
1042
1043 calculateEncryptionKey(password);
1044
1045 - vector<sal_uInt8> encryptedVerifier(ENCRYPTED_VERIFIER_LENGTH);
1046 + vector<sal_uInt8> encryptedVerifier(msfilter::ENCRYPTED_VERIFIER_LENGTH);
1047 std::copy(
1048 mInfo.verifier.encryptedVerifier,
1049 - mInfo.verifier.encryptedVerifier + ENCRYPTED_VERIFIER_LENGTH,
1050 + mInfo.verifier.encryptedVerifier + msfilter::ENCRYPTED_VERIFIER_LENGTH,
1051 encryptedVerifier.begin());
1052
1053 - vector<sal_uInt8> encryptedHash(ENCRYPTED_VERIFIER_HASH_LENGTH);
1054 + vector<sal_uInt8> encryptedHash(msfilter::SHA256_HASH_LENGTH);
1055 std::copy(
1056 mInfo.verifier.encryptedVerifierHash,
1057 - mInfo.verifier.encryptedVerifierHash + ENCRYPTED_VERIFIER_HASH_LENGTH,
1058 + mInfo.verifier.encryptedVerifierHash + msfilter::SHA256_HASH_LENGTH,
1059 encryptedHash.begin());
1060
1061 vector<sal_uInt8> verifier(encryptedVerifier.size(), 0);
1062 @@ -170,7 +149,7 @@ bool Standard2007Engine::generateEncryptionKey(const OUString& password)
1063 vector<sal_uInt8> verifierHash(encryptedHash.size(), 0);
1064 Decrypt::aes128ecb(verifierHash, encryptedHash, mKey);
1065
1066 - vector<sal_uInt8> hash(RTL_DIGEST_LENGTH_SHA1, 0);
1067 + vector<sal_uInt8> hash(msfilter::SHA1_HASH_LENGTH, 0);
1068 Digest::sha1(hash, verifier);
1069
1070 return std::equal( hash.begin(), hash.end(), verifierHash.begin() );
1071 @@ -200,11 +179,11 @@ bool Standard2007Engine::decrypt(
1072
1073 bool Standard2007Engine::writeEncryptionInfo(const OUString& password, BinaryXOutputStream& rStream)
1074 {
1075 - mInfo.header.flags = ENCRYPTINFO_AES | ENCRYPTINFO_CRYPTOAPI;
1076 - mInfo.header.algId = ENCRYPT_ALGO_AES128;
1077 - mInfo.header.algIdHash = ENCRYPT_HASH_SHA1;
1078 - mInfo.header.keyBits = ENCRYPT_KEY_SIZE_AES_128;
1079 - mInfo.header.providedType = ENCRYPT_PROVIDER_TYPE_AES;
1080 + mInfo.header.flags = msfilter::ENCRYPTINFO_AES | msfilter::ENCRYPTINFO_CRYPTOAPI;
1081 + mInfo.header.algId = msfilter::ENCRYPT_ALGO_AES128;
1082 + mInfo.header.algIdHash = msfilter::ENCRYPT_HASH_SHA1;
1083 + mInfo.header.keyBits = msfilter::ENCRYPT_KEY_SIZE_AES_128;
1084 + mInfo.header.providedType = msfilter::ENCRYPT_PROVIDER_TYPE_AES;
1085
1086 lclRandomGenerateValues(mInfo.verifier.salt, mInfo.verifier.saltSize);
1087 const sal_Int32 keyLength = mInfo.header.keyBits / 8;
1088 @@ -218,11 +197,11 @@ bool Standard2007Engine::writeEncryptionInfo(const OUString& password, BinaryXOu
1089 if (!generateVerifier())
1090 return false;
1091
1092 - rStream.WriteUInt32(VERSION_INFO_2007_FORMAT);
1093 + rStream.WriteUInt32(msfilter::VERSION_INFO_2007_FORMAT);
1094
1095 sal_uInt32 cspNameSize = (lclCspName.getLength() * 2) + 2;
1096
1097 - sal_uInt32 encryptionHeaderSize = static_cast<sal_uInt32>(sizeof(EncryptionStandardHeader));
1098 + sal_uInt32 encryptionHeaderSize = static_cast<sal_uInt32>(sizeof(msfilter::EncryptionStandardHeader));
1099
1100 rStream.WriteUInt32( mInfo.header.flags );
1101 sal_uInt32 headerSize = encryptionHeaderSize + cspNameSize;
1102 @@ -232,7 +211,7 @@ bool Standard2007Engine::writeEncryptionInfo(const OUString& password, BinaryXOu
1103 rStream.writeUnicodeArray(lclCspName);
1104 rStream.WriteUInt16(0);
1105
1106 - sal_uInt32 encryptionVerifierSize = static_cast<sal_uInt32>(sizeof(EncryptionVerifierAES));
1107 + sal_uInt32 encryptionVerifierSize = static_cast<sal_uInt32>(sizeof(msfilter::EncryptionVerifierAES));
1108 rStream.writeMemory(&mInfo.verifier, encryptionVerifierSize);
1109
1110 return true;
1111 diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx
1112 index 3e48f35..8c2622d 100644
1113 --- a/sc/source/filter/excel/xicontent.cxx
1114 +++ b/sc/source/filter/excel/xicontent.cxx
1115 @@ -62,6 +62,7 @@
1116 #include <memory>
1117 #include <utility>
1118 #include <o3tl/make_unique.hxx>
1119 +#include <oox/helper/helper.hxx>
1120
1121 using ::com::sun::star::uno::Sequence;
1122 using ::std::unique_ptr;
1123 @@ -1090,21 +1091,80 @@ XclImpDecrypterRef lclReadFilepass8_Standard( XclImpStream& rStrm )
1124 OSL_ENSURE( rStrm.GetRecLeft() == 48, "lclReadFilepass8 - wrong record size" );
1125 if( rStrm.GetRecLeft() == 48 )
1126 {
1127 - sal_uInt8 pnSalt[ 16 ];
1128 - sal_uInt8 pnVerifier[ 16 ];
1129 - sal_uInt8 pnVerifierHash[ 16 ];
1130 - rStrm.Read( pnSalt, 16 );
1131 - rStrm.Read( pnVerifier, 16 );
1132 - rStrm.Read( pnVerifierHash, 16 );
1133 - xDecr.reset( new XclImpBiff8Decrypter( pnSalt, pnVerifier, pnVerifierHash ) );
1134 + std::vector<sal_uInt8> aSalt(16);
1135 + std::vector<sal_uInt8> aVerifier(16);
1136 + std::vector<sal_uInt8> aVerifierHash(16);
1137 + rStrm.Read(aSalt.data(), 16);
1138 + rStrm.Read(aVerifier.data(), 16);
1139 + rStrm.Read(aVerifierHash.data(), 16);
1140 + xDecr.reset(new XclImpBiff8StdDecrypter(aSalt, aVerifier, aVerifierHash));
1141 }
1142 return xDecr;
1143 }
1144
1145 -XclImpDecrypterRef lclReadFilepass8_Strong( XclImpStream& /*rStrm*/ )
1146 +XclImpDecrypterRef lclReadFilepass8_Strong(XclImpStream& rStream)
1147 {
1148 - // not supported
1149 - return XclImpDecrypterRef();
1150 + //Its possible there are other variants in existance but these
1151 + //are the defaults I get with Excel 2013
1152 + XclImpDecrypterRef xDecr;
1153 +
1154 + msfilter::RC4EncryptionInfo info;
1155 +
1156 + info.header.flags = rStream.ReaduInt32();
1157 + if (oox::getFlag( info.header.flags, msfilter::ENCRYPTINFO_EXTERNAL))
1158 + return xDecr;
1159 +
1160 + sal_uInt32 nHeaderSize = rStream.ReaduInt32();
1161 + sal_uInt32 actualHeaderSize = sizeof(info.header);
1162 +
1163 + if( (nHeaderSize < actualHeaderSize) )
1164 + return xDecr;
1165 +
1166 + info.header.flags = rStream.ReaduInt32();
1167 + info.header.sizeExtra = rStream.ReaduInt32();
1168 + info.header.algId = rStream.ReaduInt32();
1169 + info.header.algIdHash = rStream.ReaduInt32();
1170 + info.header.keyBits = rStream.ReaduInt32();
1171 + info.header.providedType = rStream.ReaduInt32();
1172 + info.header.reserved1 = rStream.ReaduInt32();
1173 + info.header.reserved2 = rStream.ReaduInt32();
1174 +
1175 + rStream.Ignore(nHeaderSize - actualHeaderSize);
1176 +
1177 + info.verifier.saltSize = rStream.ReaduInt32();
1178 + if (info.verifier.saltSize != 16)
1179 + return xDecr;
1180 + rStream.Read(&info.verifier.salt, sizeof(info.verifier.salt));
1181 + rStream.Read(&info.verifier.encryptedVerifier, sizeof(info.verifier.encryptedVerifier));
1182 +
1183 + info.verifier.encryptedVerifierHashSize = rStream.ReaduInt32();
1184 + if (info.verifier.encryptedVerifierHashSize != RTL_DIGEST_LENGTH_SHA1)
1185 + return xDecr;
1186 + rStream.Read(&info.verifier.encryptedVerifierHash, info.verifier.encryptedVerifierHashSize);
1187 +
1188 + // check flags and algorithm IDs, required are AES128 and SHA-1
1189 + if (!oox::getFlag(info.header.flags, msfilter::ENCRYPTINFO_CRYPTOAPI))
1190 + return xDecr;
1191 +
1192 + if (oox::getFlag(info.header.flags, msfilter::ENCRYPTINFO_AES))
1193 + return xDecr;
1194 +
1195 + if (info.header.algId != msfilter::ENCRYPT_ALGO_RC4)
1196 + return xDecr;
1197 +
1198 + // hash algorithm ID 0 defaults to SHA-1 too
1199 + if (info.header.algIdHash != 0 && info.header.algIdHash != msfilter::ENCRYPT_HASH_SHA1)
1200 + return xDecr;
1201 +
1202 + xDecr.reset(new XclImpBiff8CryptoAPIDecrypter(
1203 + std::vector<sal_uInt8>(info.verifier.salt,
1204 + info.verifier.salt + SAL_N_ELEMENTS(info.verifier.salt)),
1205 + std::vector<sal_uInt8>(info.verifier.encryptedVerifier,
1206 + info.verifier.encryptedVerifier + SAL_N_ELEMENTS(info.verifier.encryptedVerifier)),
1207 + std::vector<sal_uInt8>(info.verifier.encryptedVerifierHash,
1208 + info.verifier.encryptedVerifierHash + SAL_N_ELEMENTS(info.verifier.encryptedVerifierHash))));
1209 +
1210 + return xDecr;
1211 }
1212
1213 XclImpDecrypterRef lclReadFilepass8( XclImpStream& rStrm )
1214 @@ -1121,20 +1181,22 @@ XclImpDecrypterRef lclReadFilepass8( XclImpStream& rStrm )
1215
1216 case EXC_FILEPASS_BIFF8:
1217 {
1218 - rStrm.Ignore( 2 );
1219 - sal_uInt16 nSubMode(0);
1220 - nSubMode = rStrm.ReaduInt16();
1221 - switch( nSubMode )
1222 + sal_uInt32 nVersion = rStrm.ReaduInt32();
1223 + if (nVersion == msfilter::VERSION_INFO_1997_FORMAT)
1224 {
1225 - case EXC_FILEPASS_BIFF8_STD:
1226 - xDecr = lclReadFilepass8_Standard( rStrm );
1227 - break;
1228 - case EXC_FILEPASS_BIFF8_STRONG:
1229 - xDecr = lclReadFilepass8_Strong( rStrm );
1230 - break;
1231 - default:
1232 - OSL_FAIL( "lclReadFilepass8 - unknown BIFF8 encryption sub mode" );
1233 + //A Version structure where Version.vMajor MUST be 0x0001,
1234 + //and Version.vMinor MUST be 0x0001.
1235 + xDecr = lclReadFilepass8_Standard(rStrm);
1236 }
1237 + else if (nVersion == msfilter::VERSION_INFO_2007_FORMAT ||
1238 + nVersion == msfilter::VERSION_INFO_2007_FORMAT_SP2)
1239 + {
1240 + //Version.vMajor MUST be 0x0002, 0x0003 or 0x0004 and
1241 + //Version.vMinor MUST be 0x0002.
1242 + xDecr = lclReadFilepass8_Strong(rStrm);
1243 + }
1244 + else
1245 + OSL_FAIL("lclReadFilepass8 - unknown BIFF8 encryption sub mode");
1246 }
1247 break;
1248
1249 diff --git a/sc/source/filter/excel/xistream.cxx b/sc/source/filter/excel/xistream.cxx
1250 index a5eda2c..7bc231e 100644
1251 --- a/sc/source/filter/excel/xistream.cxx
1252 +++ b/sc/source/filter/excel/xistream.cxx
1253 @@ -192,28 +192,50 @@ sal_uInt16 XclImpBiff5Decrypter::OnRead( SvStream& rStrm, sal_uInt8* pnData, sal
1254 return nRet;
1255 }
1256
1257 -XclImpBiff8Decrypter::XclImpBiff8Decrypter( sal_uInt8 pnSalt[ 16 ],
1258 - sal_uInt8 pnVerifier[ 16 ], sal_uInt8 pnVerifierHash[ 16 ] ) :
1259 - maSalt( pnSalt, pnSalt + 16 ),
1260 - maVerifier( pnVerifier, pnVerifier + 16 ),
1261 - maVerifierHash( pnVerifierHash, pnVerifierHash + 16 )
1262 +XclImpBiff8Decrypter::XclImpBiff8Decrypter(const std::vector<sal_uInt8>& rSalt,
1263 + const std::vector<sal_uInt8>& rVerifier,
1264 + const std::vector<sal_uInt8>& rVerifierHash)
1265 + : maSalt(rSalt)
1266 + , maVerifier(rVerifier)
1267 + , maVerifierHash(rVerifierHash)
1268 + , mpCodec(nullptr)
1269 {
1270 }
1271
1272 -XclImpBiff8Decrypter::XclImpBiff8Decrypter( const XclImpBiff8Decrypter& rSrc ) :
1273 - XclImpDecrypter( rSrc ),
1274 - maEncryptionData( rSrc.maEncryptionData ),
1275 - maSalt( rSrc.maSalt ),
1276 - maVerifier( rSrc.maVerifier ),
1277 - maVerifierHash( rSrc.maVerifierHash )
1278 +XclImpBiff8Decrypter::XclImpBiff8Decrypter(const XclImpBiff8Decrypter& rSrc)
1279 + : XclImpDecrypter(rSrc)
1280 + , maEncryptionData(rSrc.maEncryptionData)
1281 + , maSalt(rSrc.maSalt)
1282 + , maVerifier(rSrc.maVerifier)
1283 + , maVerifierHash(rSrc.maVerifierHash)
1284 + , mpCodec(nullptr)
1285 {
1286 - if( IsValid() )
1287 - maCodec.InitCodec( maEncryptionData );
1288 }
1289
1290 -XclImpBiff8Decrypter* XclImpBiff8Decrypter::OnClone() const
1291 +XclImpBiff8StdDecrypter::XclImpBiff8StdDecrypter(const XclImpBiff8StdDecrypter& rSrc)
1292 + : XclImpBiff8Decrypter(rSrc)
1293 {
1294 - return new XclImpBiff8Decrypter( *this );
1295 + mpCodec = &maCodec;
1296 + if (IsValid())
1297 + maCodec.InitCodec(maEncryptionData);
1298 +}
1299 +
1300 +XclImpBiff8StdDecrypter* XclImpBiff8StdDecrypter::OnClone() const
1301 +{
1302 + return new XclImpBiff8StdDecrypter(*this);
1303 +}
1304 +
1305 +XclImpBiff8CryptoAPIDecrypter::XclImpBiff8CryptoAPIDecrypter(const XclImpBiff8CryptoAPIDecrypter& rSrc)
1306 + : XclImpBiff8Decrypter(rSrc)
1307 +{
1308 + mpCodec = &maCodec;
1309 + if (IsValid())
1310 + maCodec.InitCodec(maEncryptionData);
1311 +}
1312 +
1313 +XclImpBiff8CryptoAPIDecrypter* XclImpBiff8CryptoAPIDecrypter::OnClone() const
1314 +{
1315 + return new XclImpBiff8CryptoAPIDecrypter(*this);
1316 }
1317
1318 uno::Sequence< beans::NamedValue > XclImpBiff8Decrypter::OnVerifyPassword( const OUString& rPassword )
1319 @@ -232,9 +254,9 @@ uno::Sequence< beans::NamedValue > XclImpBiff8Decrypter::OnVerifyPassword( const
1320 *aIt = static_cast< sal_uInt16 >( *pcChar );
1321
1322 // init codec
1323 - maCodec.InitKey( &aPassVect.front(), &maSalt.front() );
1324 - if ( maCodec.VerifyKey( &maVerifier.front(), &maVerifierHash.front() ) )
1325 - maEncryptionData = maCodec.GetEncryptionData();
1326 + mpCodec->InitKey( &aPassVect.front(), &maSalt.front() );
1327 + if ( mpCodec->VerifyKey( &maVerifier.front(), &maVerifierHash.front() ) )
1328 + maEncryptionData = mpCodec->GetEncryptionData();
1329 }
1330
1331 return maEncryptionData;
1332 @@ -247,9 +269,9 @@ bool XclImpBiff8Decrypter::OnVerifyEncryptionData( const uno::Sequence< beans::N
1333 if( rEncryptionData.getLength() )
1334 {
1335 // init codec
1336 - maCodec.InitCodec( rEncryptionData );
1337 + mpCodec->InitCodec( rEncryptionData );
1338
1339 - if ( maCodec.VerifyKey( &maVerifier.front(), &maVerifierHash.front() ) )
1340 + if ( mpCodec->VerifyKey( &maVerifier.front(), &maVerifierHash.front() ) )
1341 maEncryptionData = rEncryptionData;
1342 }
1343
1344 @@ -269,13 +291,13 @@ void XclImpBiff8Decrypter::OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos,
1345 /* Rekey cipher, if block changed or if previous offset in same block. */
1346 if( (nNewBlock != nOldBlock) || (nNewOffset < nOldOffset) )
1347 {
1348 - maCodec.InitCipher( nNewBlock );
1349 + mpCodec->InitCipher( nNewBlock );
1350 nOldOffset = 0; // reset nOldOffset for next if() statement
1351 }
1352
1353 /* Seek to correct offset. */
1354 if( nNewOffset > nOldOffset )
1355 - maCodec.Skip( nNewOffset - nOldOffset );
1356 + mpCodec->Skip( nNewOffset - nOldOffset );
1357 }
1358 }
1359
1360 @@ -293,9 +315,9 @@ sal_uInt16 XclImpBiff8Decrypter::OnRead( SvStream& rStrm, sal_uInt8* pnData, sal
1361 // read the block from stream
1362 nRet = nRet + static_cast< sal_uInt16 >( rStrm.Read( pnCurrData, nDecBytes ) );
1363 // decode the block inplace
1364 - maCodec.Decode( pnCurrData, nDecBytes, pnCurrData, nDecBytes );
1365 + mpCodec->Decode( pnCurrData, nDecBytes, pnCurrData, nDecBytes );
1366 if( GetOffset( rStrm.Tell() ) == 0 )
1367 - maCodec.InitCipher( GetBlock( rStrm.Tell() ) );
1368 + mpCodec->InitCipher( GetBlock( rStrm.Tell() ) );
1369
1370 pnCurrData += nDecBytes;
1371 nBytesLeft = nBytesLeft - nDecBytes;
1372 diff --git a/sc/source/filter/inc/xistream.hxx b/sc/source/filter/inc/xistream.hxx
1373 index d5fc51a..56d32d7 100644
1374 --- a/sc/source/filter/inc/xistream.hxx
1375 +++ b/sc/source/filter/inc/xistream.hxx
1376 @@ -119,16 +119,7 @@ private:
1377 /** Decrypts BIFF8 stream contents using the given document identifier. */
1378 class XclImpBiff8Decrypter : public XclImpDecrypter
1379 {
1380 -public:
1381 - explicit XclImpBiff8Decrypter( sal_uInt8 pnSalt[ 16 ],
1382 - sal_uInt8 pnVerifier[ 16 ], sal_uInt8 pnVerifierHash[ 16 ] );
1383 -
1384 private:
1385 - /** Private copy c'tor for OnClone(). */
1386 - explicit XclImpBiff8Decrypter( const XclImpBiff8Decrypter& rSrc );
1387 -
1388 - /** Implementation of cloning this object. */
1389 - virtual XclImpBiff8Decrypter* OnClone() const override;
1390 /** Implements password verification and initialization of the decoder. */
1391 virtual css::uno::Sequence< css::beans::NamedValue >
1392 OnVerifyPassword( const OUString& rPassword ) override;
1393 @@ -143,12 +134,62 @@ private:
1394 /** Returns the block offset corresponding to the passed stream position. */
1395 static sal_uInt16 GetOffset( sal_Size nStrmPos );
1396
1397 +protected:
1398 + explicit XclImpBiff8Decrypter(const std::vector<sal_uInt8>& rSalt,
1399 + const std::vector<sal_uInt8>& rVerifier,
1400 + const std::vector<sal_uInt8>& rVerifierHash);
1401 +
1402 + explicit XclImpBiff8Decrypter(const XclImpBiff8Decrypter& rSrc);
1403 +
1404 + css::uno::Sequence< css::beans::NamedValue > maEncryptionData;
1405 + std::vector< sal_uInt8 > maSalt;
1406 + std::vector< sal_uInt8 > maVerifier;
1407 + std::vector< sal_uInt8 > maVerifierHash;
1408 + msfilter::MSCodec97* mpCodec; /// Crypto algorithm implementation.
1409 +};
1410 +
1411 +class XclImpBiff8StdDecrypter : public XclImpBiff8Decrypter
1412 +{
1413 +public:
1414 + explicit XclImpBiff8StdDecrypter(const std::vector<sal_uInt8>& rSalt,
1415 + const std::vector<sal_uInt8>& rVerifier,
1416 + const std::vector<sal_uInt8>& rVerifierHash)
1417 + : XclImpBiff8Decrypter(rSalt, rVerifier, rVerifierHash)
1418 + {
1419 + mpCodec = &maCodec;
1420 + }
1421 +
1422 +private:
1423 + /** Private copy c'tor for OnClone(). */
1424 + explicit XclImpBiff8StdDecrypter(const XclImpBiff8StdDecrypter& rSrc);
1425 +
1426 + /** Implementation of cloning this object. */
1427 + virtual XclImpBiff8StdDecrypter* OnClone() const override;
1428 +
1429 private:
1430 ::msfilter::MSCodec_Std97 maCodec; /// Crypto algorithm implementation.
1431 - css::uno::Sequence< css::beans::NamedValue > maEncryptionData;
1432 - ::std::vector< sal_uInt8 > maSalt;
1433 - ::std::vector< sal_uInt8 > maVerifier;
1434 - ::std::vector< sal_uInt8 > maVerifierHash;
1435 +};
1436 +
1437 +class XclImpBiff8CryptoAPIDecrypter : public XclImpBiff8Decrypter
1438 +{
1439 +public:
1440 + explicit XclImpBiff8CryptoAPIDecrypter(const std::vector<sal_uInt8>& rSalt,
1441 + const std::vector<sal_uInt8>& rVerifier,
1442 + const std::vector<sal_uInt8>& rVerifierHash)
1443 + : XclImpBiff8Decrypter(rSalt, rVerifier, rVerifierHash)
1444 + {
1445 + mpCodec = &maCodec;
1446 + }
1447 +
1448 +private:
1449 + /** Private copy c'tor for OnClone(). */
1450 + explicit XclImpBiff8CryptoAPIDecrypter(const XclImpBiff8CryptoAPIDecrypter& rSrc);
1451 +
1452 + /** Implementation of cloning this object. */
1453 + virtual XclImpBiff8CryptoAPIDecrypter* OnClone() const override;
1454 +
1455 +private:
1456 + ::msfilter::MSCodec_CryptoAPI maCodec; /// Crypto algorithm implementation.
1457 };
1458
1459 // Stream
1460 diff --git a/sc/source/filter/inc/xlcontent.hxx b/sc/source/filter/inc/xlcontent.hxx
1461 index 6bb7b0b..ec94750 100644
1462 --- a/sc/source/filter/inc/xlcontent.hxx
1463 +++ b/sc/source/filter/inc/xlcontent.hxx
1464 @@ -39,8 +39,6 @@ const sal_uInt16 EXC_ID_FILEPASS = 0x002F;
1465
1466 const sal_uInt16 EXC_FILEPASS_BIFF5 = 0x0000;
1467 const sal_uInt16 EXC_FILEPASS_BIFF8 = 0x0001;
1468 -const sal_uInt16 EXC_FILEPASS_BIFF8_STD = 0x0001;
1469 -const sal_uInt16 EXC_FILEPASS_BIFF8_STRONG = 0x0002;
1470
1471 // (0x00FC, 0x00FF) SST, EXTSST -----------------------------------------------
1472
1473 --
1474 2.7.4
1475

  ViewVC Help
Powered by ViewVC 1.1.30