fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / package / source / manifest / ManifestExport.cxx
blob1ecb093c3e2b4ef7e11d80fb3081034d3b91661e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
22 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
23 #include <com/sun/star/xml/sax/XAttributeList.hpp>
24 #include <com/sun/star/xml/crypto/DigestID.hpp>
25 #include <com/sun/star/xml/crypto/CipherID.hpp>
26 #include <com/sun/star/beans/PropertyValue.hpp>
27 #include <com/sun/star/uno/RuntimeException.hpp>
29 #include <ManifestDefines.hxx>
30 #include <ManifestExport.hxx>
31 #include <sax/tools/converter.hxx>
33 #include <rtl/ustrbuf.hxx>
34 #include <comphelper/documentconstants.hxx>
35 #include <comphelper/attributelist.hxx>
37 using namespace ::com::sun::star;
40 ManifestExport::ManifestExport( uno::Reference< xml::sax::XDocumentHandler > xHandler, const uno::Sequence< uno::Sequence < beans::PropertyValue > >& rManList )
42 const OUString sFileEntryElement ( ELEMENT_FILE_ENTRY );
43 const OUString sManifestElement ( ELEMENT_MANIFEST );
44 const OUString sEncryptionDataElement( ELEMENT_ENCRYPTION_DATA );
45 const OUString sAlgorithmElement ( ELEMENT_ALGORITHM );
46 const OUString sStartKeyGenerationElement ( ELEMENT_START_KEY_GENERATION );
47 const OUString sKeyDerivationElement ( ELEMENT_KEY_DERIVATION );
49 const OUString sCdataAttribute ( ATTRIBUTE_CDATA );
50 const OUString sMediaTypeAttribute ( ATTRIBUTE_MEDIA_TYPE );
51 const OUString sVersionAttribute ( ATTRIBUTE_VERSION );
52 const OUString sFullPathAttribute ( ATTRIBUTE_FULL_PATH );
53 const OUString sSizeAttribute ( ATTRIBUTE_SIZE );
54 const OUString sKeySizeAttribute ( ATTRIBUTE_KEY_SIZE );
55 const OUString sSaltAttribute ( ATTRIBUTE_SALT );
56 const OUString sInitialisationVectorAttribute ( ATTRIBUTE_INITIALISATION_VECTOR );
57 const OUString sIterationCountAttribute ( ATTRIBUTE_ITERATION_COUNT );
58 const OUString sAlgorithmNameAttribute ( ATTRIBUTE_ALGORITHM_NAME );
59 const OUString sStartKeyGenerationNameAttribute ( ATTRIBUTE_START_KEY_GENERATION_NAME );
60 const OUString sKeyDerivationNameAttribute ( ATTRIBUTE_KEY_DERIVATION_NAME );
61 const OUString sChecksumTypeAttribute ( ATTRIBUTE_CHECKSUM_TYPE );
62 const OUString sChecksumAttribute ( ATTRIBUTE_CHECKSUM);
64 const OUString sFullPathProperty ( "FullPath" );
65 const OUString sVersionProperty ( "Version" );
66 const OUString sMediaTypeProperty ( "MediaType" );
67 const OUString sIterationCountProperty ( "IterationCount" );
68 const OUString sDerivedKeySizeProperty ( "DerivedKeySize" );
69 const OUString sSaltProperty ( "Salt" );
70 const OUString sInitialisationVectorProperty( "InitialisationVector" );
71 const OUString sSizeProperty ( "Size" );
72 const OUString sDigestProperty ( "Digest" );
73 const OUString sEncryptionAlgProperty ( "EncryptionAlgorithm" );
74 const OUString sStartKeyAlgProperty ( "StartKeyAlgorithm" );
75 const OUString sDigestAlgProperty ( "DigestAlgorithm" );
77 const OUString sWhiteSpace ( " " );
79 const OUString sSHA256_URL ( SHA256_URL );
80 const OUString sSHA1_Name ( SHA1_NAME );
82 const OUString sSHA1_1k_Name ( SHA1_1K_NAME );
83 const OUString sSHA256_1k_URL ( SHA256_1K_URL );
85 const OUString sBlowfish_Name ( BLOWFISH_NAME );
86 const OUString sAES256_URL ( AES256_URL );
88 const OUString sPBKDF2_Name ( PBKDF2_NAME );
90 ::comphelper::AttributeList * pRootAttrList = new ::comphelper::AttributeList;
91 const uno::Sequence < beans::PropertyValue > *pSequence = rManList.getConstArray();
92 const sal_uInt32 nManLength = rManList.getLength();
94 // find the mediatype of the document if any
95 OUString aDocMediaType;
96 OUString aDocVersion;
97 for (sal_uInt32 nInd = 0; nInd < nManLength ; nInd++ )
99 OUString aMediaType;
100 OUString aPath;
101 OUString aVersion;
103 const beans::PropertyValue *pValue = pSequence[nInd].getConstArray();
104 for (sal_uInt32 j = 0, nNum = pSequence[nInd].getLength(); j < nNum; j++, pValue++)
106 if (pValue->Name.equals (sMediaTypeProperty) )
108 pValue->Value >>= aMediaType;
110 else if (pValue->Name.equals (sFullPathProperty) )
112 pValue->Value >>= aPath;
114 else if (pValue->Name.equals (sVersionProperty) )
116 pValue->Value >>= aVersion;
119 if ( !aPath.isEmpty() && !aMediaType.isEmpty() && !aVersion.isEmpty() )
120 break;
123 if ( aPath == "/" )
125 aDocMediaType = aMediaType;
126 aDocVersion = aVersion;
127 break;
131 sal_Bool bProvideDTD = sal_False;
132 sal_Bool bAcceptNonemptyVersion = sal_False;
133 sal_Bool bStoreStartKeyGeneration = sal_False;
134 if ( !aDocMediaType.isEmpty() )
136 if ( aDocMediaType == MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII
137 || aDocMediaType == MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII
138 || aDocMediaType == MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII
139 || aDocMediaType == MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII
140 || aDocMediaType == MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII
141 || aDocMediaType == MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII
142 || aDocMediaType == MIMETYPE_OASIS_OPENDOCUMENT_CHART_ASCII
143 || aDocMediaType == MIMETYPE_OASIS_OPENDOCUMENT_DATABASE_ASCII
144 || aDocMediaType == MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII
145 || aDocMediaType == MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII
146 || aDocMediaType == MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII
147 || aDocMediaType == MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII
148 || aDocMediaType == MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII
149 || aDocMediaType == MIMETYPE_OASIS_OPENDOCUMENT_CHART_TEMPLATE_ASCII
150 || aDocMediaType == MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII )
153 // oasis format
154 pRootAttrList->AddAttribute ( ATTRIBUTE_XMLNS,
155 sCdataAttribute,
156 MANIFEST_OASIS_NAMESPACE );
157 bAcceptNonemptyVersion = sal_True;
158 if ( aDocVersion.compareTo( ODFVER_012_TEXT ) >= 0 )
160 // this is ODF12 generation, let encrypted streams contain start-key-generation entry
161 bStoreStartKeyGeneration = sal_True;
162 pRootAttrList->AddAttribute ( sVersionAttribute, sCdataAttribute, aDocVersion );
165 else
167 // even if it is no SO6 format the namespace must be specified
168 // thus SO6 format is used as default one
169 pRootAttrList->AddAttribute ( ATTRIBUTE_XMLNS,
170 sCdataAttribute,
171 MANIFEST_NAMESPACE );
173 bProvideDTD = sal_True;
177 uno::Reference < xml::sax::XAttributeList > xRootAttrList (pRootAttrList);
179 xHandler->startDocument();
180 uno::Reference < xml::sax::XExtendedDocumentHandler > xExtHandler ( xHandler, uno::UNO_QUERY );
181 if ( xExtHandler.is() && bProvideDTD )
183 OUString aDocType ( MANIFEST_DOCTYPE );
184 xExtHandler->unknown ( aDocType );
185 xHandler->ignorableWhitespace ( sWhiteSpace );
187 xHandler->startElement( sManifestElement, xRootAttrList );
189 for (sal_uInt32 i = 0 ; i < nManLength ; i++)
191 ::comphelper::AttributeList *pAttrList = new ::comphelper::AttributeList;
192 const beans::PropertyValue *pValue = pSequence[i].getConstArray();
193 OUString aString;
194 const uno::Any *pVector = NULL, *pSalt = NULL, *pIterationCount = NULL, *pDigest = NULL, *pDigestAlg = NULL, *pEncryptAlg = NULL, *pStartKeyAlg = NULL, *pDerivedKeySize = NULL;
195 for (sal_uInt32 j = 0, nNum = pSequence[i].getLength(); j < nNum; j++, pValue++)
197 if (pValue->Name.equals (sMediaTypeProperty) )
199 pValue->Value >>= aString;
200 pAttrList->AddAttribute ( sMediaTypeAttribute, sCdataAttribute, aString );
202 else if (pValue->Name.equals (sVersionProperty) )
204 pValue->Value >>= aString;
205 // the version is stored only if it is not empty
206 if ( bAcceptNonemptyVersion && !aString.isEmpty() )
207 pAttrList->AddAttribute ( sVersionAttribute, sCdataAttribute, aString );
209 else if (pValue->Name.equals (sFullPathProperty) )
211 pValue->Value >>= aString;
212 pAttrList->AddAttribute ( sFullPathAttribute, sCdataAttribute, aString );
214 else if (pValue->Name.equals (sSizeProperty) )
216 sal_Int64 nSize = 0;
217 pValue->Value >>= nSize;
218 OUStringBuffer aBuffer;
219 aBuffer.append ( nSize );
220 pAttrList->AddAttribute ( sSizeAttribute, sCdataAttribute, aBuffer.makeStringAndClear() );
222 else if (pValue->Name.equals (sInitialisationVectorProperty) )
223 pVector = &pValue->Value;
224 else if (pValue->Name.equals (sSaltProperty) )
225 pSalt = &pValue->Value;
226 else if (pValue->Name.equals (sIterationCountProperty) )
227 pIterationCount = &pValue->Value;
228 else if (pValue->Name.equals ( sDigestProperty ) )
229 pDigest = &pValue->Value;
230 else if (pValue->Name.equals ( sDigestAlgProperty ) )
231 pDigestAlg = &pValue->Value;
232 else if (pValue->Name.equals ( sEncryptionAlgProperty ) )
233 pEncryptAlg = &pValue->Value;
234 else if (pValue->Name.equals ( sStartKeyAlgProperty ) )
235 pStartKeyAlg = &pValue->Value;
236 else if (pValue->Name.equals ( sDerivedKeySizeProperty ) )
237 pDerivedKeySize = &pValue->Value;
240 xHandler->ignorableWhitespace ( sWhiteSpace );
241 uno::Reference < xml::sax::XAttributeList > xAttrList ( pAttrList );
242 xHandler->startElement( sFileEntryElement , xAttrList);
243 if ( pVector && pSalt && pIterationCount && pDigest && pDigestAlg && pEncryptAlg && pStartKeyAlg && pDerivedKeySize )
245 // ==== Encryption Data
246 ::comphelper::AttributeList * pNewAttrList = new ::comphelper::AttributeList;
247 uno::Reference < xml::sax::XAttributeList > xNewAttrList (pNewAttrList);
248 OUStringBuffer aBuffer;
249 uno::Sequence < sal_Int8 > aSequence;
251 xHandler->ignorableWhitespace ( sWhiteSpace );
253 // ==== Digest
254 OUString sChecksumType;
255 sal_Int32 nDigestAlgID = 0;
256 *pDigestAlg >>= nDigestAlgID;
257 if ( nDigestAlgID == xml::crypto::DigestID::SHA256_1K )
258 sChecksumType = sSHA256_1k_URL;
259 else if ( nDigestAlgID == xml::crypto::DigestID::SHA1_1K )
260 sChecksumType = sSHA1_1k_Name;
261 else
262 throw uno::RuntimeException( OSL_LOG_PREFIX "Unexpected digest algorithm is provided!", uno::Reference< uno::XInterface >() );
264 pNewAttrList->AddAttribute ( sChecksumTypeAttribute, sCdataAttribute, sChecksumType );
265 *pDigest >>= aSequence;
266 ::sax::Converter::encodeBase64(aBuffer, aSequence);
267 pNewAttrList->AddAttribute ( sChecksumAttribute, sCdataAttribute, aBuffer.makeStringAndClear() );
269 xHandler->startElement( sEncryptionDataElement , xNewAttrList);
271 // ==== Algorithm
272 pNewAttrList = new ::comphelper::AttributeList;
273 xNewAttrList = pNewAttrList;
275 sal_Int32 nEncAlgID = 0;
276 sal_Int32 nDerivedKeySize = 0;
277 *pEncryptAlg >>= nEncAlgID;
278 *pDerivedKeySize >>= nDerivedKeySize;
280 OUString sEncAlgName;
281 if ( nEncAlgID == xml::crypto::CipherID::AES_CBC_W3C_PADDING )
283 OSL_ENSURE( nDerivedKeySize, "Unexpected key size is provided!" );
284 if ( nDerivedKeySize != 32 )
285 throw uno::RuntimeException( OSL_LOG_PREFIX "Unexpected key size is provided!", uno::Reference< uno::XInterface >() );
287 sEncAlgName = sAES256_URL;
289 else if ( nEncAlgID == xml::crypto::CipherID::BLOWFISH_CFB_8 )
291 sEncAlgName = sBlowfish_Name;
293 else
294 throw uno::RuntimeException( OSL_LOG_PREFIX "Unexpected encryption algorithm is provided!", uno::Reference< uno::XInterface >() );
296 pNewAttrList->AddAttribute ( sAlgorithmNameAttribute, sCdataAttribute, sEncAlgName );
298 *pVector >>= aSequence;
299 ::sax::Converter::encodeBase64(aBuffer, aSequence);
300 pNewAttrList->AddAttribute ( sInitialisationVectorAttribute, sCdataAttribute, aBuffer.makeStringAndClear() );
302 xHandler->ignorableWhitespace ( sWhiteSpace );
303 xHandler->startElement( sAlgorithmElement , xNewAttrList);
304 xHandler->ignorableWhitespace ( sWhiteSpace );
305 xHandler->endElement( sAlgorithmElement );
307 // ==== Key Derivation
308 pNewAttrList = new ::comphelper::AttributeList;
309 xNewAttrList = pNewAttrList;
311 pNewAttrList->AddAttribute ( sKeyDerivationNameAttribute, sCdataAttribute, sPBKDF2_Name );
313 if ( bStoreStartKeyGeneration )
315 aBuffer.append( nDerivedKeySize );
316 pNewAttrList->AddAttribute ( sKeySizeAttribute, sCdataAttribute, aBuffer.makeStringAndClear() );
319 sal_Int32 nCount = 0;
320 *pIterationCount >>= nCount;
321 aBuffer.append (nCount);
322 pNewAttrList->AddAttribute ( sIterationCountAttribute, sCdataAttribute, aBuffer.makeStringAndClear() );
324 *pSalt >>= aSequence;
325 ::sax::Converter::encodeBase64(aBuffer, aSequence);
326 pNewAttrList->AddAttribute ( sSaltAttribute, sCdataAttribute, aBuffer.makeStringAndClear() );
328 xHandler->ignorableWhitespace ( sWhiteSpace );
329 xHandler->startElement( sKeyDerivationElement , xNewAttrList);
330 xHandler->ignorableWhitespace ( sWhiteSpace );
331 xHandler->endElement( sKeyDerivationElement );
333 // we have to store start-key-generation element as the last one to workaround the parsing problem
334 // in OOo3.1 and older versions
335 if ( bStoreStartKeyGeneration )
337 // ==== Start Key Generation
338 pNewAttrList = new ::comphelper::AttributeList;
339 xNewAttrList = pNewAttrList;
341 OUString sStartKeyAlg;
342 OUString sStartKeySize;
343 sal_Int32 nStartKeyAlgID = 0;
344 *pStartKeyAlg >>= nStartKeyAlgID;
345 if ( nStartKeyAlgID == xml::crypto::DigestID::SHA256 )
347 sStartKeyAlg = sSHA256_URL;
348 aBuffer.append( (sal_Int32)32 );
349 sStartKeySize = aBuffer.makeStringAndClear();
351 else if ( nStartKeyAlgID == xml::crypto::DigestID::SHA1 )
353 sStartKeyAlg = sSHA1_Name;
354 aBuffer.append( (sal_Int32)20 );
355 sStartKeySize = aBuffer.makeStringAndClear();
357 else
358 throw uno::RuntimeException( OSL_LOG_PREFIX "Unexpected start key algorithm is provided!", uno::Reference< uno::XInterface >() );
360 pNewAttrList->AddAttribute ( sStartKeyGenerationNameAttribute, sCdataAttribute, sStartKeyAlg );
361 pNewAttrList->AddAttribute ( sKeySizeAttribute, sCdataAttribute, sStartKeySize );
363 xHandler->ignorableWhitespace ( sWhiteSpace );
364 xHandler->startElement( sStartKeyGenerationElement , xNewAttrList);
365 xHandler->ignorableWhitespace ( sWhiteSpace );
366 xHandler->endElement( sStartKeyGenerationElement );
369 xHandler->ignorableWhitespace ( sWhiteSpace );
370 xHandler->endElement( sEncryptionDataElement );
372 xHandler->ignorableWhitespace ( sWhiteSpace );
373 xHandler->endElement( sFileEntryElement );
375 xHandler->ignorableWhitespace ( sWhiteSpace );
376 xHandler->endElement( sManifestElement );
377 xHandler->endDocument();
380 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */