Line data Source code
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 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef SVX_MSCODEC_HXX
21 : #define SVX_MSCODEC_HXX
22 :
23 : #include <com/sun/star/uno/Sequence.hxx>
24 : #include <com/sun/star/beans/NamedValue.hpp>
25 :
26 : #include <rtl/cipher.h>
27 : #include <rtl/digest.h>
28 : #include "filter/msfilter/msfilterdllapi.h"
29 :
30 : namespace msfilter {
31 :
32 : // ============================================================================
33 :
34 : /** Encodes and decodes data from protected MSO 95- documents.
35 : */
36 : class MSFILTER_DLLPUBLIC MSCodec_Xor95
37 : {
38 : public:
39 : explicit MSCodec_Xor95(int nRotateDistance);
40 : virtual ~MSCodec_Xor95();
41 :
42 : /** Initializes the algorithm with the specified password.
43 :
44 : @param pPassData
45 : Character array containing the password. Must be zero terminated,
46 : which results in a maximum length of 15 characters.
47 : */
48 : void InitKey( const sal_uInt8 pnPassData[ 16 ] );
49 :
50 : /** Initializes the algorithm with the encryption data.
51 :
52 : @param aData
53 : The sequence contains the necessary data to initialize
54 : the codec.
55 : */
56 : sal_Bool InitCodec( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aData );
57 :
58 : /** Retrieves the encryption data
59 :
60 : @return
61 : The sequence contains the necessary data to initialize
62 : the codec.
63 : */
64 : ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GetEncryptionData();
65 :
66 :
67 : /** Verifies the validity of the password using the passed key and hash.
68 :
69 : @precond
70 : The codec must be initialized with InitKey() before this function
71 : can be used.
72 :
73 : @param nKey
74 : Password key value read from the file.
75 : @param nHash
76 : Password hash value read from the file.
77 :
78 : @return
79 : true = Test was successful.
80 : */
81 : bool VerifyKey( sal_uInt16 nKey, sal_uInt16 nHash ) const;
82 :
83 : /** Reinitializes the codec to start a new memory block.
84 :
85 : Resets the internal key offset to 0.
86 :
87 : @precond
88 : The codec must be initialized with InitKey() before this function
89 : can be used.
90 : */
91 : void InitCipher();
92 :
93 : /** Decodes a block of memory inplace.
94 :
95 : @precond
96 : The codec must be initialized with InitKey() before this function
97 : can be used.
98 :
99 : @param pnData
100 : Encrypted data block. Will contain the decrypted data afterwards.
101 : @param nBytes
102 : Size of the passed data block.
103 : */
104 : virtual void Decode( sal_uInt8* pnData, sal_Size nBytes )=0;
105 :
106 : /** Lets the cipher skip a specific amount of bytes.
107 :
108 : This function sets the cipher to the same state as if the specified
109 : amount of data has been decoded with one or more calls of Decode().
110 :
111 : @precond
112 : The codec must be initialized with InitKey() before this function
113 : can be used.
114 :
115 : @param nBytes
116 : Number of bytes to be skipped (cipher "seeks" forward).
117 : */
118 : void Skip( sal_Size nBytes );
119 :
120 : protected:
121 : sal_uInt8 mpnKey[ 16 ]; /// Encryption key.
122 : sal_Size mnOffset; /// Key offset.
123 :
124 : private:
125 : MSFILTER_DLLPRIVATE MSCodec_Xor95( const MSCodec_Xor95& );
126 : MSFILTER_DLLPRIVATE MSCodec_Xor95& operator=( const MSCodec_Xor95& );
127 :
128 : sal_uInt16 mnKey; /// Base key from password.
129 : sal_uInt16 mnHash; /// Hash value from password.
130 : int mnRotateDistance;
131 : };
132 :
133 : /** Encodes and decodes data from protected MSO XLS 95- documents.
134 : */
135 0 : class MSFILTER_DLLPUBLIC MSCodec_XorXLS95 : public MSCodec_Xor95
136 : {
137 : public:
138 0 : explicit MSCodec_XorXLS95() : MSCodec_Xor95(2) {}
139 :
140 : /** Decodes a block of memory inplace.
141 :
142 : @precond
143 : The codec must be initialized with InitKey() before this function
144 : can be used.
145 :
146 : @param pnData
147 : Encrypted data block. Will contain the decrypted data afterwards.
148 : @param nBytes
149 : Size of the passed data block.
150 : */
151 : virtual void Decode( sal_uInt8* pnData, sal_Size nBytes );
152 : };
153 :
154 : /** Encodes and decodes data from protected MSO Word 95- documents.
155 : */
156 0 : class MSFILTER_DLLPUBLIC MSCodec_XorWord95 : public MSCodec_Xor95
157 : {
158 : public:
159 0 : explicit MSCodec_XorWord95() : MSCodec_Xor95(7) {}
160 :
161 : /** Decodes a block of memory inplace.
162 :
163 : @precond
164 : The codec must be initialized with InitKey() before this function
165 : can be used.
166 :
167 : @param pnData
168 : Encrypted data block. Will contain the decrypted data afterwards.
169 : @param nBytes
170 : Size of the passed data block.
171 : */
172 : virtual void Decode( sal_uInt8* pnData, sal_Size nBytes );
173 : };
174 :
175 :
176 : // ============================================================================
177 :
178 : /** Encodes and decodes data from protected MSO 97+ documents.
179 :
180 : This is a wrapper class around low level cryptographic functions from RTL.
181 : Implementation is based on the wvDecrypt package by Caolan McNamara:
182 : http://www.csn.ul.ie/~caolan/docs/wvDecrypt.html
183 : */
184 : class MSFILTER_DLLPUBLIC MSCodec_Std97
185 : {
186 : public:
187 : explicit MSCodec_Std97();
188 : ~MSCodec_Std97();
189 :
190 : /** Initializes the algorithm with the encryption data.
191 :
192 : @param aData
193 : The sequence contains the necessary data to initialize
194 : the codec.
195 : */
196 : sal_Bool InitCodec( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aData );
197 :
198 : /** Retrieves the encryption data
199 :
200 : @return
201 : The sequence contains the necessary data to initialize
202 : the codec.
203 : */
204 : ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GetEncryptionData();
205 :
206 :
207 : /** Initializes the algorithm with the specified password and document ID.
208 :
209 : @param pPassData
210 : Wide character array containing the password. Must be zero
211 : terminated, which results in a maximum length of 15 characters.
212 : @param pDocId
213 : Unique document identifier read from or written to the file.
214 : */
215 : void InitKey(
216 : const sal_uInt16 pPassData[ 16 ],
217 : const sal_uInt8 pDocId[ 16 ] );
218 :
219 : /** Verifies the validity of the password using the passed salt data.
220 :
221 : @precond
222 : The codec must be initialized with InitKey() before this function
223 : can be used.
224 :
225 : @param pSaltData
226 : Salt data block read from the file.
227 : @param pSaltDigest
228 : Salt digest read from the file.
229 :
230 : @return
231 : true = Test was successful.
232 : */
233 : bool VerifyKey(
234 : const sal_uInt8 pSaltData[ 16 ],
235 : const sal_uInt8 pSaltDigest[ 16 ] );
236 :
237 : /** Rekeys the codec using the specified counter.
238 :
239 : After reading a specific amount of data the cipher algorithm needs to
240 : be rekeyed using a counter that counts the data blocks.
241 :
242 : The block size is for example 512 Bytes for Word files and 1024 Bytes
243 : for Excel files.
244 :
245 : @precond
246 : The codec must be initialized with InitKey() before this function
247 : can be used.
248 :
249 : @param nCounter
250 : Block counter used to rekey the cipher.
251 : */
252 : bool InitCipher( sal_uInt32 nCounter );
253 :
254 : /** Creates an MD5 digest of salt digest. */
255 : bool CreateSaltDigest(
256 : const sal_uInt8 nSaltData[16], sal_uInt8 nSaltDigest[16] );
257 :
258 : /** Encodes a block of memory.
259 :
260 : @see rtl_cipher_encode()
261 :
262 : @precond
263 : The codec must be initialized with InitKey() before this function
264 : can be used. The destination buffer must be able to take all
265 : unencoded data from the source buffer (usually this means it must be
266 : as long as or longer than the source buffer).
267 :
268 : @param pData
269 : Unencrypted source data block.
270 : @param nDatLen
271 : Size of the passed source data block.
272 : @param pBuffer
273 : Destination buffer for the encrypted data.
274 : @param nBufLen
275 : Size of the destination buffer.
276 :
277 : @return
278 : true = Encoding was successful (no error occurred).
279 : */
280 : bool Encode(
281 : const void* pData, sal_Size nDatLen,
282 : sal_uInt8* pBuffer, sal_Size nBufLen );
283 :
284 : /** Decodes a block of memory.
285 :
286 : @see rtl_cipher_decode()
287 :
288 : @precond
289 : The codec must be initialized with InitKey() before this function
290 : can be used. The destination buffer must be able to take all
291 : encoded data from the source buffer (usually this means it must be
292 : as long as or longer than the source buffer).
293 :
294 : @param pData
295 : Encrypted source data block.
296 : @param nDatLen
297 : Size of the passed source data block.
298 : @param pBuffer
299 : Destination buffer for the decrypted data.
300 : @param nBufLen
301 : Size of the destination buffer.
302 :
303 : @return
304 : true = Decoding was successful (no error occurred).
305 : */
306 : bool Decode(
307 : const void* pData, sal_Size nDatLen,
308 : sal_uInt8* pBuffer, sal_Size nBufLen );
309 :
310 : /** Lets the cipher skip a specific amount of bytes.
311 :
312 : This function sets the cipher to the same state as if the specified
313 : amount of data has been decoded with one or more calls of Decode().
314 :
315 : @precond
316 : The codec must be initialized with InitKey() before this function
317 : can be used.
318 :
319 : @param nDatLen
320 : Number of bytes to be skipped (cipher "seeks" forward).
321 : */
322 : bool Skip( sal_Size nDatLen );
323 :
324 : /** Gets salt data and salt digest.
325 :
326 : @precond
327 : The codec must be initialized with InitKey() before this function
328 : can be used.
329 :
330 : @param pSalt
331 : Salt, a random number.
332 : @param pSaltData
333 : Salt data block generated from the salt.
334 : @param pSaltDigest
335 : Salt digest generated from the salt.
336 : */
337 : void GetEncryptKey (
338 : const sal_uInt8 pSalt[16],
339 : sal_uInt8 pSaltData[16],
340 : sal_uInt8 pSaltDigest[16]);
341 :
342 : /* allows to get the unique document id from the codec
343 : */
344 : void GetDocId( sal_uInt8 pDocId[16] );
345 :
346 : void GetDigestFromSalt( const sal_uInt8 pSaltData[16], sal_uInt8 pDigest[16] );
347 :
348 : private:
349 : void InitKeyImpl(
350 : const sal_uInt8 pKeyData[64],
351 : const sal_uInt8 pDocId[16] );
352 :
353 :
354 : private:
355 : MSFILTER_DLLPRIVATE MSCodec_Std97( const MSCodec_Std97& );
356 : MSFILTER_DLLPRIVATE MSCodec_Std97& operator=( const MSCodec_Std97& );
357 :
358 : rtlCipher m_hCipher;
359 : rtlDigest m_hDigest;
360 : sal_uInt8 m_pDigestValue[ RTL_DIGEST_LENGTH_MD5 ];
361 : sal_uInt8 m_pDocId[16];
362 : };
363 :
364 : // ============================================================================
365 :
366 : } // namespace msfilter
367 :
368 : #endif
369 :
370 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|