xref: /aoo42x/main/oox/inc/oox/core/binarycodec.hxx (revision a893be29)
1e3508121SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3e3508121SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4e3508121SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5e3508121SAndrew Rist  * distributed with this work for additional information
6e3508121SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7e3508121SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8e3508121SAndrew Rist  * "License"); you may not use this file except in compliance
9e3508121SAndrew Rist  * with the License.  You may obtain a copy of the License at
10e3508121SAndrew Rist  *
11e3508121SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12e3508121SAndrew Rist  *
13e3508121SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14e3508121SAndrew Rist  * software distributed under the License is distributed on an
15e3508121SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16e3508121SAndrew Rist  * KIND, either express or implied.  See the License for the
17e3508121SAndrew Rist  * specific language governing permissions and limitations
18e3508121SAndrew Rist  * under the License.
19e3508121SAndrew Rist  *
20e3508121SAndrew Rist  *************************************************************/
21e3508121SAndrew Rist 
22e3508121SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #ifndef OOX_CORE_BINARYCODEC_HXX
25cdf0e10cSrcweir #define OOX_CORE_BINARYCODEC_HXX
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <com/sun/star/uno/Sequence.hxx>
28cdf0e10cSrcweir #include <com/sun/star/beans/NamedValue.hpp>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include <rtl/cipher.h>
31cdf0e10cSrcweir #include <rtl/digest.h>
32cdf0e10cSrcweir 
33cdf0e10cSrcweir namespace oox { class AttributeList; }
34cdf0e10cSrcweir 
35cdf0e10cSrcweir namespace oox {
36cdf0e10cSrcweir namespace core {
37cdf0e10cSrcweir 
38cdf0e10cSrcweir // ============================================================================
39cdf0e10cSrcweir 
40cdf0e10cSrcweir class CodecHelper
41cdf0e10cSrcweir {
42cdf0e10cSrcweir public:
43cdf0e10cSrcweir     /** Returns the password hash if it is in the required 16-bit limit. */
44cdf0e10cSrcweir     static sal_uInt16   getPasswordHash( const AttributeList& rAttribs, sal_Int32 nElement );
45cdf0e10cSrcweir 
46cdf0e10cSrcweir private:
47cdf0e10cSrcweir                         CodecHelper();
48cdf0e10cSrcweir                         ~CodecHelper();
49cdf0e10cSrcweir };
50cdf0e10cSrcweir 
51cdf0e10cSrcweir // ============================================================================
52cdf0e10cSrcweir 
53cdf0e10cSrcweir /** Encodes and decodes data from/to protected MS Office documents.
54cdf0e10cSrcweir 
55cdf0e10cSrcweir     Implements a simple XOR encoding/decoding algorithm used in MS Office
56cdf0e10cSrcweir     versions up to MSO 95.
57cdf0e10cSrcweir  */
58cdf0e10cSrcweir class BinaryCodec_XOR
59cdf0e10cSrcweir {
60cdf0e10cSrcweir public:
61cdf0e10cSrcweir     /** Enumerates codec types supported by this XOR codec implementation. */
62cdf0e10cSrcweir     enum CodecType
63cdf0e10cSrcweir     {
64cdf0e10cSrcweir         CODEC_WORD,     /// MS Word XOR codec.
65cdf0e10cSrcweir         CODEC_EXCEL     /// MS Excel XOR codec.
66cdf0e10cSrcweir     };
67cdf0e10cSrcweir 
68cdf0e10cSrcweir public:
69cdf0e10cSrcweir     /** Default constructor.
70cdf0e10cSrcweir 
71cdf0e10cSrcweir         Two-step construction in conjunction with the initKey() and verifyKey()
72cdf0e10cSrcweir         functions allows to try to initialize with different passwords (e.g.
73cdf0e10cSrcweir         built-in default password used for Excel workbook protection).
74cdf0e10cSrcweir      */
75cdf0e10cSrcweir     explicit            BinaryCodec_XOR( CodecType eCodecType );
76cdf0e10cSrcweir 
77cdf0e10cSrcweir                         ~BinaryCodec_XOR();
78cdf0e10cSrcweir 
79cdf0e10cSrcweir     /** Initializes the algorithm with the specified password.
80cdf0e10cSrcweir 
81cdf0e10cSrcweir         @param pnPassData
82cdf0e10cSrcweir             Character array containing the password. Must be zero terminated,
83cdf0e10cSrcweir             which results in a maximum length of 15 characters.
84cdf0e10cSrcweir      */
85cdf0e10cSrcweir     void                initKey( const sal_uInt8 pnPassData[ 16 ] );
86cdf0e10cSrcweir 
87cdf0e10cSrcweir     /** Initializes the algorithm with the encryption data.
88cdf0e10cSrcweir 
89cdf0e10cSrcweir         @param aData
90cdf0e10cSrcweir             The sequence contains the necessary data to initialize
91cdf0e10cSrcweir             the codec.
92cdf0e10cSrcweir      */
93cdf0e10cSrcweir     bool                initCodec( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aData );
94cdf0e10cSrcweir 
95cdf0e10cSrcweir     /** Retrieves the encryption data
96cdf0e10cSrcweir 
97cdf0e10cSrcweir         @return
98cdf0e10cSrcweir             The sequence contains the necessary data to initialize
99cdf0e10cSrcweir             the codec.
100cdf0e10cSrcweir      */
101cdf0e10cSrcweir     ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > getEncryptionData();
102cdf0e10cSrcweir 
103cdf0e10cSrcweir     /** Verifies the validity of the password using the passed key and hash.
104cdf0e10cSrcweir 
105cdf0e10cSrcweir         @precond
106cdf0e10cSrcweir             The codec must be initialized with the initKey() function before
107cdf0e10cSrcweir             this function can be used.
108cdf0e10cSrcweir 
109cdf0e10cSrcweir         @param nKey
110cdf0e10cSrcweir             Password key value read from the file.
111cdf0e10cSrcweir         @param nHash
112cdf0e10cSrcweir             Password hash value read from the file.
113cdf0e10cSrcweir 
114cdf0e10cSrcweir         @return
115cdf0e10cSrcweir             True = test was successful.
116cdf0e10cSrcweir      */
117cdf0e10cSrcweir     bool                verifyKey( sal_uInt16 nKey, sal_uInt16 nHash ) const;
118cdf0e10cSrcweir 
119cdf0e10cSrcweir     /** Reinitializes the codec to start a new memory block.
120cdf0e10cSrcweir 
121cdf0e10cSrcweir         Resets the internal key offset to 0.
122cdf0e10cSrcweir 
123cdf0e10cSrcweir         @precond
124cdf0e10cSrcweir             The codec must be initialized with the initKey() function before
125cdf0e10cSrcweir             this function can be used.
126cdf0e10cSrcweir      */
127cdf0e10cSrcweir     void                startBlock();
128cdf0e10cSrcweir 
129cdf0e10cSrcweir     /** Decodes a block of memory.
130cdf0e10cSrcweir 
131cdf0e10cSrcweir         @precond
132cdf0e10cSrcweir             The codec must be initialized with the initKey() function before
133cdf0e10cSrcweir             this function can be used.
134cdf0e10cSrcweir 
135cdf0e10cSrcweir         @param pnDestData
136cdf0e10cSrcweir             Destination buffer. Will contain the decrypted data afterwards.
137cdf0e10cSrcweir         @param pnSrcData
138cdf0e10cSrcweir             Encrypted data block.
139cdf0e10cSrcweir         @param nBytes
140cdf0e10cSrcweir             Size of the passed data blocks. pnDestData and pnSrcData must be of
141cdf0e10cSrcweir             this size.
142cdf0e10cSrcweir 
143cdf0e10cSrcweir         @return
144*a893be29SPedro Giffuni             True = decoding was successful (no error occurred).
145cdf0e10cSrcweir     */
146cdf0e10cSrcweir     bool                decode(
147cdf0e10cSrcweir                             sal_uInt8* pnDestData,
148cdf0e10cSrcweir                             const sal_uInt8* pnSrcData,
149cdf0e10cSrcweir                             sal_Int32 nBytes );
150cdf0e10cSrcweir 
151cdf0e10cSrcweir     /** Lets the cipher skip a specific amount of bytes.
152cdf0e10cSrcweir 
153cdf0e10cSrcweir         This function sets the cipher to the same state as if the specified
154cdf0e10cSrcweir         amount of data has been decoded with one or more calls of decode().
155cdf0e10cSrcweir 
156cdf0e10cSrcweir         @precond
157cdf0e10cSrcweir             The codec must be initialized with the initKey() function before
158cdf0e10cSrcweir             this function can be used.
159cdf0e10cSrcweir 
160cdf0e10cSrcweir         @param nBytes
161cdf0e10cSrcweir             Number of bytes to be skipped (cipher "seeks" forward).
162cdf0e10cSrcweir 
163cdf0e10cSrcweir         @return
164*a893be29SPedro Giffuni             True = skip was successful (no error occurred).
165cdf0e10cSrcweir      */
166cdf0e10cSrcweir     bool                skip( sal_Int32 nBytes );
167cdf0e10cSrcweir 
168cdf0e10cSrcweir private:
169cdf0e10cSrcweir     CodecType           meCodecType;        /// Codec type.
170cdf0e10cSrcweir     sal_uInt8           mpnKey[ 16 ];       /// Encryption key.
171cdf0e10cSrcweir     sal_Int32           mnOffset;           /// Key offset.
172cdf0e10cSrcweir     sal_uInt16          mnBaseKey;          /// Base key from password.
173cdf0e10cSrcweir     sal_uInt16          mnHash;             /// Hash value from password.
174cdf0e10cSrcweir };
175cdf0e10cSrcweir 
176cdf0e10cSrcweir // ============================================================================
177cdf0e10cSrcweir 
178cdf0e10cSrcweir /** Encodes and decodes data from protected MSO 97+ documents.
179cdf0e10cSrcweir 
180cdf0e10cSrcweir     This is a wrapper class around low level cryptographic functions from RTL.
181cdf0e10cSrcweir     Implementation is based on the wvDecrypt package by Caolan McNamara:
182cdf0e10cSrcweir     http://www.csn.ul.ie/~caolan/docs/wvDecrypt.html
183cdf0e10cSrcweir  */
184cdf0e10cSrcweir class BinaryCodec_RCF
185cdf0e10cSrcweir {
186cdf0e10cSrcweir public:
187cdf0e10cSrcweir     /** Default constructor.
188cdf0e10cSrcweir 
189cdf0e10cSrcweir         Two-step construction in conjunction with the initKey() and verifyKey()
190cdf0e10cSrcweir         functions allows to try to initialize with different passwords (e.g.
191cdf0e10cSrcweir         built-in default password used for Excel workbook protection).
192cdf0e10cSrcweir      */
193cdf0e10cSrcweir     explicit            BinaryCodec_RCF();
194cdf0e10cSrcweir 
195cdf0e10cSrcweir                         ~BinaryCodec_RCF();
196cdf0e10cSrcweir 
197cdf0e10cSrcweir     /** Initializes the algorithm with the encryption data.
198cdf0e10cSrcweir 
199cdf0e10cSrcweir         @param aData
200cdf0e10cSrcweir             The sequence contains the necessary data to initialize
201cdf0e10cSrcweir             the codec.
202cdf0e10cSrcweir      */
203cdf0e10cSrcweir     bool            initCodec( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aData );
204cdf0e10cSrcweir 
205cdf0e10cSrcweir     /** Retrieves the encryption data
206cdf0e10cSrcweir 
207cdf0e10cSrcweir         @return
208cdf0e10cSrcweir             The sequence contains the necessary data to initialize
209cdf0e10cSrcweir             the codec.
210cdf0e10cSrcweir      */
211cdf0e10cSrcweir     ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > getEncryptionData();
212cdf0e10cSrcweir 
213cdf0e10cSrcweir     /** Initializes the algorithm with the specified password and document ID.
214cdf0e10cSrcweir 
215cdf0e10cSrcweir         @param pnPassData
216cdf0e10cSrcweir             Unicode character array containing the password. Must be zero
217cdf0e10cSrcweir             terminated, which results in a maximum length of 15 characters.
218cdf0e10cSrcweir         @param pnSalt
219cdf0e10cSrcweir             Random salt data block read from or written to the file.
220cdf0e10cSrcweir      */
221cdf0e10cSrcweir     void                initKey(
222cdf0e10cSrcweir                             const sal_uInt16 pnPassData[ 16 ],
223cdf0e10cSrcweir                             const sal_uInt8 pnSalt[ 16 ] );
224cdf0e10cSrcweir 
225cdf0e10cSrcweir     /** Verifies the validity of the password using the passed salt data.
226cdf0e10cSrcweir 
227cdf0e10cSrcweir         @precond
228cdf0e10cSrcweir             The codec must be initialized with the initKey() function before
229cdf0e10cSrcweir             this function can be used.
230cdf0e10cSrcweir 
231cdf0e10cSrcweir         @param pnVerifier
232cdf0e10cSrcweir             Verifier block read from the file.
233cdf0e10cSrcweir         @param pnVerifierHash
234cdf0e10cSrcweir             Verifier hash read from the file.
235cdf0e10cSrcweir 
236cdf0e10cSrcweir         @return
237cdf0e10cSrcweir             True = test was successful.
238cdf0e10cSrcweir      */
239cdf0e10cSrcweir     bool                verifyKey(
240cdf0e10cSrcweir                             const sal_uInt8 pnVerifier[ 16 ],
241cdf0e10cSrcweir                             const sal_uInt8 pnVerifierHash[ 16 ] );
242cdf0e10cSrcweir 
243cdf0e10cSrcweir     /** Rekeys the codec using the specified counter.
244cdf0e10cSrcweir 
245cdf0e10cSrcweir         After reading a specific amount of data the cipher algorithm needs to
246cdf0e10cSrcweir         be rekeyed using a counter that counts the data blocks.
247cdf0e10cSrcweir 
248cdf0e10cSrcweir         The block size is for example 512 bytes for MS Word files and 1024
249cdf0e10cSrcweir         bytes for MS Excel files.
250cdf0e10cSrcweir 
251cdf0e10cSrcweir         @precond
252cdf0e10cSrcweir             The codec must be initialized with the initKey() function before
253cdf0e10cSrcweir             this function can be used.
254cdf0e10cSrcweir 
255cdf0e10cSrcweir         @param nCounter
256cdf0e10cSrcweir             Block counter used to rekey the cipher.
257cdf0e10cSrcweir      */
258cdf0e10cSrcweir     bool                startBlock( sal_Int32 nCounter );
259cdf0e10cSrcweir 
260cdf0e10cSrcweir     /** Decodes a block of memory.
261cdf0e10cSrcweir 
262cdf0e10cSrcweir         @see rtl_cipher_decode()
263cdf0e10cSrcweir 
264cdf0e10cSrcweir         @precond
265cdf0e10cSrcweir             The codec must be initialized with the initKey() function before
266cdf0e10cSrcweir             this function can be used.
267cdf0e10cSrcweir 
268cdf0e10cSrcweir         @param pnDestData
269cdf0e10cSrcweir             Destination buffer. Will contain the decrypted data afterwards.
270cdf0e10cSrcweir         @param pnSrcData
271cdf0e10cSrcweir             Encrypted data block.
272cdf0e10cSrcweir         @param nBytes
273cdf0e10cSrcweir             Size of the passed data blocks. pnDestData and pnSrcData must be of
274cdf0e10cSrcweir             this size.
275cdf0e10cSrcweir 
276cdf0e10cSrcweir         @return
277*a893be29SPedro Giffuni             True = decoding was successful (no error occurred).
278cdf0e10cSrcweir     */
279cdf0e10cSrcweir     bool                decode(
280cdf0e10cSrcweir                             sal_uInt8* pnDestData,
281cdf0e10cSrcweir                             const sal_uInt8* pnSrcData,
282cdf0e10cSrcweir                             sal_Int32 nBytes );
283cdf0e10cSrcweir 
284cdf0e10cSrcweir     /** Lets the cipher skip a specific amount of bytes.
285cdf0e10cSrcweir 
286cdf0e10cSrcweir         This function sets the cipher to the same state as if the specified
287cdf0e10cSrcweir         amount of data has been decoded with one or more calls of decode().
288cdf0e10cSrcweir 
289cdf0e10cSrcweir         @precond
290cdf0e10cSrcweir             The codec must be initialized with the initKey() function before
291cdf0e10cSrcweir             this function can be used.
292cdf0e10cSrcweir 
293cdf0e10cSrcweir         @param nBytes
294cdf0e10cSrcweir             Number of bytes to be skipped (cipher "seeks" forward).
295cdf0e10cSrcweir 
296cdf0e10cSrcweir         @return
297*a893be29SPedro Giffuni             True = skip was successful (no error occurred).
298cdf0e10cSrcweir      */
299cdf0e10cSrcweir     bool                skip( sal_Int32 nBytes );
300cdf0e10cSrcweir 
301cdf0e10cSrcweir private:
302cdf0e10cSrcweir     void                InitKeyImpl(
303cdf0e10cSrcweir                             const sal_uInt8 pKeyData[64],
304cdf0e10cSrcweir                             const sal_uInt8 pUnique[16] );
305cdf0e10cSrcweir 
306cdf0e10cSrcweir     rtlCipher           mhCipher;
307cdf0e10cSrcweir     rtlDigest           mhDigest;
308cdf0e10cSrcweir     sal_uInt8           mpnDigestValue[ RTL_DIGEST_LENGTH_MD5 ];
309cdf0e10cSrcweir     sal_uInt8           mpnUnique[16];
310cdf0e10cSrcweir };
311cdf0e10cSrcweir 
312cdf0e10cSrcweir // ============================================================================
313cdf0e10cSrcweir 
314cdf0e10cSrcweir } // namespace core
315cdf0e10cSrcweir } // namespace oox
316cdf0e10cSrcweir 
317cdf0e10cSrcweir #endif
318