xref: /aoo41x/main/oox/source/xls/biffcodec.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #include "oox/xls/biffcodec.hxx"
29*cdf0e10cSrcweir 
30*cdf0e10cSrcweir #include <osl/thread.h>
31*cdf0e10cSrcweir #include <string.h>
32*cdf0e10cSrcweir #include "oox/core/filterbase.hxx"
33*cdf0e10cSrcweir #include "oox/xls/biffinputstream.hxx"
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir namespace oox {
36*cdf0e10cSrcweir namespace xls {
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir // ============================================================================
39*cdf0e10cSrcweir 
40*cdf0e10cSrcweir using namespace ::com::sun::star::beans;
41*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir using ::oox::core::FilterBase;
44*cdf0e10cSrcweir using ::rtl::OString;
45*cdf0e10cSrcweir using ::rtl::OUString;
46*cdf0e10cSrcweir using ::rtl::OStringToOUString;
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir // ============================================================================
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir BiffDecoderBase::BiffDecoderBase() :
51*cdf0e10cSrcweir     mbValid( false )
52*cdf0e10cSrcweir {
53*cdf0e10cSrcweir }
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir BiffDecoderBase::~BiffDecoderBase()
56*cdf0e10cSrcweir {
57*cdf0e10cSrcweir }
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir ::comphelper::DocPasswordVerifierResult BiffDecoderBase::verifyPassword( const OUString& rPassword, Sequence< NamedValue >& o_rEncryptionData )
60*cdf0e10cSrcweir {
61*cdf0e10cSrcweir     o_rEncryptionData = implVerifyPassword( rPassword );
62*cdf0e10cSrcweir     mbValid = o_rEncryptionData.hasElements();
63*cdf0e10cSrcweir     return mbValid ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
64*cdf0e10cSrcweir }
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir ::comphelper::DocPasswordVerifierResult BiffDecoderBase::verifyEncryptionData( const Sequence< NamedValue >& rEncryptionData )
67*cdf0e10cSrcweir {
68*cdf0e10cSrcweir     mbValid = implVerifyEncryptionData( rEncryptionData );
69*cdf0e10cSrcweir     return mbValid ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
70*cdf0e10cSrcweir }
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir void BiffDecoderBase::decode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes )
73*cdf0e10cSrcweir {
74*cdf0e10cSrcweir     if( pnDestData && pnSrcData && (nBytes > 0) )
75*cdf0e10cSrcweir     {
76*cdf0e10cSrcweir         if( mbValid )
77*cdf0e10cSrcweir             implDecode( pnDestData, pnSrcData, nStreamPos, nBytes );
78*cdf0e10cSrcweir         else
79*cdf0e10cSrcweir             memcpy( pnDestData, pnSrcData, nBytes );
80*cdf0e10cSrcweir     }
81*cdf0e10cSrcweir }
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir // ============================================================================
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir BiffDecoder_XOR::BiffDecoder_XOR( sal_uInt16 nKey, sal_uInt16 nHash ) :
86*cdf0e10cSrcweir     maCodec( ::oox::core::BinaryCodec_XOR::CODEC_EXCEL ),
87*cdf0e10cSrcweir     mnKey( nKey ),
88*cdf0e10cSrcweir     mnHash( nHash )
89*cdf0e10cSrcweir {
90*cdf0e10cSrcweir }
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir BiffDecoder_XOR::BiffDecoder_XOR( const BiffDecoder_XOR& rDecoder ) :
93*cdf0e10cSrcweir     BiffDecoderBase(),  // must be called to prevent compiler warning
94*cdf0e10cSrcweir     maCodec( ::oox::core::BinaryCodec_XOR::CODEC_EXCEL ),
95*cdf0e10cSrcweir     maEncryptionData( rDecoder.maEncryptionData ),
96*cdf0e10cSrcweir     mnKey( rDecoder.mnKey ),
97*cdf0e10cSrcweir     mnHash( rDecoder.mnHash )
98*cdf0e10cSrcweir {
99*cdf0e10cSrcweir     if( isValid() )
100*cdf0e10cSrcweir         maCodec.initCodec( maEncryptionData );
101*cdf0e10cSrcweir }
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir BiffDecoder_XOR* BiffDecoder_XOR::implClone()
104*cdf0e10cSrcweir {
105*cdf0e10cSrcweir     return new BiffDecoder_XOR( *this );
106*cdf0e10cSrcweir }
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir Sequence< NamedValue > BiffDecoder_XOR::implVerifyPassword( const OUString& rPassword )
109*cdf0e10cSrcweir {
110*cdf0e10cSrcweir     maEncryptionData.realloc( 0 );
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir     /*  Convert password to a byte string. TODO: this needs some finetuning
113*cdf0e10cSrcweir         according to the spec... */
114*cdf0e10cSrcweir     OString aBytePassword = OUStringToOString( rPassword, osl_getThreadTextEncoding() );
115*cdf0e10cSrcweir     sal_Int32 nLen = aBytePassword.getLength();
116*cdf0e10cSrcweir     if( (0 < nLen) && (nLen < 16) )
117*cdf0e10cSrcweir     {
118*cdf0e10cSrcweir         // init codec
119*cdf0e10cSrcweir         maCodec.initKey( reinterpret_cast< const sal_uInt8* >( aBytePassword.getStr() ) );
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir         if( maCodec.verifyKey( mnKey, mnHash ) )
122*cdf0e10cSrcweir             maEncryptionData = maCodec.getEncryptionData();
123*cdf0e10cSrcweir     }
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir     return maEncryptionData;
126*cdf0e10cSrcweir }
127*cdf0e10cSrcweir 
128*cdf0e10cSrcweir bool BiffDecoder_XOR::implVerifyEncryptionData( const Sequence< NamedValue >& rEncryptionData )
129*cdf0e10cSrcweir {
130*cdf0e10cSrcweir     maEncryptionData.realloc( 0 );
131*cdf0e10cSrcweir 
132*cdf0e10cSrcweir     if( rEncryptionData.hasElements() )
133*cdf0e10cSrcweir     {
134*cdf0e10cSrcweir         // init codec
135*cdf0e10cSrcweir         maCodec.initCodec( rEncryptionData );
136*cdf0e10cSrcweir 
137*cdf0e10cSrcweir         if( maCodec.verifyKey( mnKey, mnHash ) )
138*cdf0e10cSrcweir             maEncryptionData = rEncryptionData;
139*cdf0e10cSrcweir     }
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir     return maEncryptionData.hasElements();
142*cdf0e10cSrcweir }
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir void BiffDecoder_XOR::implDecode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes )
145*cdf0e10cSrcweir {
146*cdf0e10cSrcweir     maCodec.startBlock();
147*cdf0e10cSrcweir     maCodec.skip( static_cast< sal_Int32 >( (nStreamPos + nBytes) & 0x0F ) );
148*cdf0e10cSrcweir     maCodec.decode( pnDestData, pnSrcData, nBytes );
149*cdf0e10cSrcweir }
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir // ============================================================================
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir namespace {
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir /** Returns the block index of the passed stream position for RCF decryption. */
156*cdf0e10cSrcweir sal_Int32 lclGetRcfBlock( sal_Int64 nStreamPos )
157*cdf0e10cSrcweir {
158*cdf0e10cSrcweir     return static_cast< sal_Int32 >( nStreamPos / BIFF_RCF_BLOCKSIZE );
159*cdf0e10cSrcweir }
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir /** Returns the offset of the passed stream position in a block for RCF decryption. */
162*cdf0e10cSrcweir sal_Int32 lclGetRcfOffset( sal_Int64 nStreamPos )
163*cdf0e10cSrcweir {
164*cdf0e10cSrcweir     return static_cast< sal_Int32 >( nStreamPos % BIFF_RCF_BLOCKSIZE );
165*cdf0e10cSrcweir }
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir } // namespace
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir // ----------------------------------------------------------------------------
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir BiffDecoder_RCF::BiffDecoder_RCF( sal_uInt8 pnSalt[ 16 ], sal_uInt8 pnVerifier[ 16 ], sal_uInt8 pnVerifierHash[ 16 ] ) :
172*cdf0e10cSrcweir     maSalt( pnSalt, pnSalt + 16 ),
173*cdf0e10cSrcweir     maVerifier( pnVerifier, pnVerifier + 16 ),
174*cdf0e10cSrcweir     maVerifierHash( pnVerifierHash, pnVerifierHash + 16 )
175*cdf0e10cSrcweir {
176*cdf0e10cSrcweir }
177*cdf0e10cSrcweir 
178*cdf0e10cSrcweir BiffDecoder_RCF::BiffDecoder_RCF( const BiffDecoder_RCF& rDecoder ) :
179*cdf0e10cSrcweir     BiffDecoderBase(),  // must be called to prevent compiler warning
180*cdf0e10cSrcweir     maEncryptionData( rDecoder.maEncryptionData ),
181*cdf0e10cSrcweir     maSalt( rDecoder.maSalt ),
182*cdf0e10cSrcweir     maVerifier( rDecoder.maVerifier ),
183*cdf0e10cSrcweir     maVerifierHash( rDecoder.maVerifierHash )
184*cdf0e10cSrcweir {
185*cdf0e10cSrcweir     if( isValid() )
186*cdf0e10cSrcweir         maCodec.initCodec( maEncryptionData );
187*cdf0e10cSrcweir }
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir BiffDecoder_RCF* BiffDecoder_RCF::implClone()
190*cdf0e10cSrcweir {
191*cdf0e10cSrcweir     return new BiffDecoder_RCF( *this );
192*cdf0e10cSrcweir }
193*cdf0e10cSrcweir 
194*cdf0e10cSrcweir Sequence< NamedValue > BiffDecoder_RCF::implVerifyPassword( const OUString& rPassword )
195*cdf0e10cSrcweir {
196*cdf0e10cSrcweir     maEncryptionData.realloc( 0 );
197*cdf0e10cSrcweir 
198*cdf0e10cSrcweir     sal_Int32 nLen = rPassword.getLength();
199*cdf0e10cSrcweir     if( (0 < nLen) && (nLen < 16) )
200*cdf0e10cSrcweir     {
201*cdf0e10cSrcweir         // copy string to sal_uInt16 array
202*cdf0e10cSrcweir         ::std::vector< sal_uInt16 > aPassVect( 16 );
203*cdf0e10cSrcweir         const sal_Unicode* pcChar = rPassword.getStr();
204*cdf0e10cSrcweir         const sal_Unicode* pcCharEnd = pcChar + nLen;
205*cdf0e10cSrcweir         ::std::vector< sal_uInt16 >::iterator aIt = aPassVect.begin();
206*cdf0e10cSrcweir         for( ; pcChar < pcCharEnd; ++pcChar, ++aIt )
207*cdf0e10cSrcweir             *aIt = static_cast< sal_uInt16 >( *pcChar );
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir         // init codec
210*cdf0e10cSrcweir         maCodec.initKey( &aPassVect.front(), &maSalt.front() );
211*cdf0e10cSrcweir         if( maCodec.verifyKey( &maVerifier.front(), &maVerifierHash.front() ) )
212*cdf0e10cSrcweir             maEncryptionData = maCodec.getEncryptionData();
213*cdf0e10cSrcweir     }
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir     return maEncryptionData;
216*cdf0e10cSrcweir }
217*cdf0e10cSrcweir 
218*cdf0e10cSrcweir bool BiffDecoder_RCF::implVerifyEncryptionData( const Sequence< NamedValue >& rEncryptionData )
219*cdf0e10cSrcweir {
220*cdf0e10cSrcweir     maEncryptionData.realloc( 0 );
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir     if( rEncryptionData.hasElements() )
223*cdf0e10cSrcweir     {
224*cdf0e10cSrcweir         // init codec
225*cdf0e10cSrcweir         maCodec.initCodec( rEncryptionData );
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir         if( maCodec.verifyKey( &maVerifier.front(), &maVerifierHash.front() ) )
228*cdf0e10cSrcweir             maEncryptionData = rEncryptionData;
229*cdf0e10cSrcweir     }
230*cdf0e10cSrcweir 
231*cdf0e10cSrcweir     return maEncryptionData.hasElements();
232*cdf0e10cSrcweir }
233*cdf0e10cSrcweir 
234*cdf0e10cSrcweir void BiffDecoder_RCF::implDecode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes )
235*cdf0e10cSrcweir {
236*cdf0e10cSrcweir     sal_uInt8* pnCurrDest = pnDestData;
237*cdf0e10cSrcweir     const sal_uInt8* pnCurrSrc = pnSrcData;
238*cdf0e10cSrcweir     sal_Int64 nCurrPos = nStreamPos;
239*cdf0e10cSrcweir     sal_uInt16 nBytesLeft = nBytes;
240*cdf0e10cSrcweir     while( nBytesLeft > 0 )
241*cdf0e10cSrcweir     {
242*cdf0e10cSrcweir         // initialize codec for current stream position
243*cdf0e10cSrcweir         maCodec.startBlock( lclGetRcfBlock( nCurrPos ) );
244*cdf0e10cSrcweir         maCodec.skip( lclGetRcfOffset( nCurrPos ) );
245*cdf0e10cSrcweir 
246*cdf0e10cSrcweir         // decode the block
247*cdf0e10cSrcweir         sal_uInt16 nBlockLeft = static_cast< sal_uInt16 >( BIFF_RCF_BLOCKSIZE - lclGetRcfOffset( nCurrPos ) );
248*cdf0e10cSrcweir         sal_uInt16 nDecBytes = ::std::min( nBytesLeft, nBlockLeft );
249*cdf0e10cSrcweir         maCodec.decode( pnCurrDest, pnCurrSrc, static_cast< sal_Int32 >( nDecBytes ) );
250*cdf0e10cSrcweir 
251*cdf0e10cSrcweir         // prepare for next block
252*cdf0e10cSrcweir         pnCurrDest += nDecBytes;
253*cdf0e10cSrcweir         pnCurrSrc += nDecBytes;
254*cdf0e10cSrcweir         nCurrPos += nDecBytes;
255*cdf0e10cSrcweir         nBytesLeft = nBytesLeft - nDecBytes;
256*cdf0e10cSrcweir     }
257*cdf0e10cSrcweir }
258*cdf0e10cSrcweir 
259*cdf0e10cSrcweir // ============================================================================
260*cdf0e10cSrcweir 
261*cdf0e10cSrcweir namespace {
262*cdf0e10cSrcweir 
263*cdf0e10cSrcweir const sal_uInt16 BIFF_FILEPASS_XOR                  = 0;
264*cdf0e10cSrcweir const sal_uInt16 BIFF_FILEPASS_RCF                  = 1;
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir const sal_uInt16 BIFF_FILEPASS_BIFF8_RCF            = 1;
267*cdf0e10cSrcweir const sal_uInt16 BIFF_FILEPASS_BIFF8_CRYPTOAPI_2003 = 2;
268*cdf0e10cSrcweir const sal_uInt16 BIFF_FILEPASS_BIFF8_CRYPTOAPI_2007 = 3;
269*cdf0e10cSrcweir 
270*cdf0e10cSrcweir // ----------------------------------------------------------------------------
271*cdf0e10cSrcweir 
272*cdf0e10cSrcweir BiffDecoderRef lclReadFilePass_XOR( BiffInputStream& rStrm )
273*cdf0e10cSrcweir {
274*cdf0e10cSrcweir     BiffDecoderRef xDecoder;
275*cdf0e10cSrcweir     OSL_ENSURE( rStrm.getRemaining() == 4, "lclReadFilePass_XOR - wrong record size" );
276*cdf0e10cSrcweir     if( rStrm.getRemaining() == 4 )
277*cdf0e10cSrcweir     {
278*cdf0e10cSrcweir         sal_uInt16 nBaseKey, nHash;
279*cdf0e10cSrcweir         rStrm >> nBaseKey >> nHash;
280*cdf0e10cSrcweir         xDecoder.reset( new BiffDecoder_XOR( nBaseKey, nHash ) );
281*cdf0e10cSrcweir     }
282*cdf0e10cSrcweir     return xDecoder;
283*cdf0e10cSrcweir }
284*cdf0e10cSrcweir 
285*cdf0e10cSrcweir BiffDecoderRef lclReadFilePass_RCF( BiffInputStream& rStrm )
286*cdf0e10cSrcweir {
287*cdf0e10cSrcweir     BiffDecoderRef xDecoder;
288*cdf0e10cSrcweir     OSL_ENSURE( rStrm.getRemaining() == 48, "lclReadFilePass_RCF - wrong record size" );
289*cdf0e10cSrcweir     if( rStrm.getRemaining() == 48 )
290*cdf0e10cSrcweir     {
291*cdf0e10cSrcweir         sal_uInt8 pnSalt[ 16 ];
292*cdf0e10cSrcweir         sal_uInt8 pnVerifier[ 16 ];
293*cdf0e10cSrcweir         sal_uInt8 pnVerifierHash[ 16 ];
294*cdf0e10cSrcweir         rStrm.readMemory( pnSalt, 16 );
295*cdf0e10cSrcweir         rStrm.readMemory( pnVerifier, 16 );
296*cdf0e10cSrcweir         rStrm.readMemory( pnVerifierHash, 16 );
297*cdf0e10cSrcweir         xDecoder.reset( new BiffDecoder_RCF( pnSalt, pnVerifier, pnVerifierHash ) );
298*cdf0e10cSrcweir     }
299*cdf0e10cSrcweir     return xDecoder;
300*cdf0e10cSrcweir }
301*cdf0e10cSrcweir 
302*cdf0e10cSrcweir BiffDecoderRef lclReadFilePass_CryptoApi( BiffInputStream& /*rStrm*/ )
303*cdf0e10cSrcweir {
304*cdf0e10cSrcweir     // not supported
305*cdf0e10cSrcweir     return BiffDecoderRef();
306*cdf0e10cSrcweir }
307*cdf0e10cSrcweir 
308*cdf0e10cSrcweir BiffDecoderRef lclReadFilePassBiff8( BiffInputStream& rStrm )
309*cdf0e10cSrcweir {
310*cdf0e10cSrcweir     BiffDecoderRef xDecoder;
311*cdf0e10cSrcweir     switch( rStrm.readuInt16() )
312*cdf0e10cSrcweir     {
313*cdf0e10cSrcweir         case BIFF_FILEPASS_XOR:
314*cdf0e10cSrcweir             xDecoder = lclReadFilePass_XOR( rStrm );
315*cdf0e10cSrcweir         break;
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir         case BIFF_FILEPASS_RCF:
318*cdf0e10cSrcweir         {
319*cdf0e10cSrcweir             sal_uInt16 nMajor = rStrm.readuInt16();
320*cdf0e10cSrcweir             rStrm.skip( 2 );
321*cdf0e10cSrcweir             switch( nMajor )
322*cdf0e10cSrcweir             {
323*cdf0e10cSrcweir                 case BIFF_FILEPASS_BIFF8_RCF:
324*cdf0e10cSrcweir                     xDecoder = lclReadFilePass_RCF( rStrm );
325*cdf0e10cSrcweir                 break;
326*cdf0e10cSrcweir                 case BIFF_FILEPASS_BIFF8_CRYPTOAPI_2003:
327*cdf0e10cSrcweir                 case BIFF_FILEPASS_BIFF8_CRYPTOAPI_2007:
328*cdf0e10cSrcweir                     xDecoder = lclReadFilePass_CryptoApi( rStrm );
329*cdf0e10cSrcweir                 break;
330*cdf0e10cSrcweir                 default:
331*cdf0e10cSrcweir                     OSL_ENSURE( false, "lclReadFilePassBiff8 - unknown BIFF8 encryption sub mode" );
332*cdf0e10cSrcweir             }
333*cdf0e10cSrcweir         }
334*cdf0e10cSrcweir         break;
335*cdf0e10cSrcweir 
336*cdf0e10cSrcweir         default:
337*cdf0e10cSrcweir             OSL_ENSURE( false, "lclReadFilePassBiff8 - unknown encryption mode" );
338*cdf0e10cSrcweir     }
339*cdf0e10cSrcweir     return xDecoder;
340*cdf0e10cSrcweir }
341*cdf0e10cSrcweir 
342*cdf0e10cSrcweir } // namespace
343*cdf0e10cSrcweir 
344*cdf0e10cSrcweir // ----------------------------------------------------------------------------
345*cdf0e10cSrcweir 
346*cdf0e10cSrcweir BiffCodecHelper::BiffCodecHelper( const WorkbookHelper& rHelper ) :
347*cdf0e10cSrcweir     WorkbookHelper( rHelper )
348*cdf0e10cSrcweir {
349*cdf0e10cSrcweir }
350*cdf0e10cSrcweir 
351*cdf0e10cSrcweir /*static*/ BiffDecoderRef BiffCodecHelper::implReadFilePass( BiffInputStream& rStrm, BiffType eBiff )
352*cdf0e10cSrcweir {
353*cdf0e10cSrcweir     rStrm.enableDecoder( false );
354*cdf0e10cSrcweir     BiffDecoderRef xDecoder = (eBiff == BIFF8) ? lclReadFilePassBiff8( rStrm ) : lclReadFilePass_XOR( rStrm );
355*cdf0e10cSrcweir     rStrm.setDecoder( xDecoder );
356*cdf0e10cSrcweir     return xDecoder;
357*cdf0e10cSrcweir }
358*cdf0e10cSrcweir 
359*cdf0e10cSrcweir bool BiffCodecHelper::importFilePass( BiffInputStream& rStrm )
360*cdf0e10cSrcweir {
361*cdf0e10cSrcweir     OSL_ENSURE( !mxDecoder, "BiffCodecHelper::importFilePass - multiple FILEPASS records" );
362*cdf0e10cSrcweir     mxDecoder = implReadFilePass( rStrm, getBiff() );
363*cdf0e10cSrcweir     // request and verify a password (decoder implements IDocPasswordVerifier)
364*cdf0e10cSrcweir     if( mxDecoder.get() )
365*cdf0e10cSrcweir         getBaseFilter().requestEncryptionData( *mxDecoder );
366*cdf0e10cSrcweir     // correct password is indicated by isValid() function of decoder
367*cdf0e10cSrcweir     return mxDecoder.get() && mxDecoder->isValid();
368*cdf0e10cSrcweir }
369*cdf0e10cSrcweir 
370*cdf0e10cSrcweir void BiffCodecHelper::cloneDecoder( BiffInputStream& rStrm )
371*cdf0e10cSrcweir {
372*cdf0e10cSrcweir     if( mxDecoder.get() )
373*cdf0e10cSrcweir         rStrm.setDecoder( BiffDecoderRef( mxDecoder->clone() ) );
374*cdf0e10cSrcweir }
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir // ============================================================================
377*cdf0e10cSrcweir 
378*cdf0e10cSrcweir } // namespace xls
379*cdf0e10cSrcweir } // namespace oox
380