1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER( update_precomp.py ): autogen include statement, do not remove 29 #include "precompiled_package.hxx" 30 #include <ManifestImport.hxx> 31 #include <ManifestDefines.hxx> 32 #include <Base64Codec.hxx> 33 34 #include <com/sun/star/xml/sax/XAttributeList.hpp> 35 #include <com/sun/star/xml/crypto/DigestID.hpp> 36 #include <com/sun/star/xml/crypto/CipherID.hpp> 37 #include <com/sun/star/beans/PropertyValue.hpp> 38 39 using namespace com::sun::star::uno; 40 using namespace com::sun::star::beans; 41 using namespace com::sun::star; 42 using namespace rtl; 43 using namespace std; 44 45 // --------------------------------------------------- 46 ManifestImport::ManifestImport( vector < Sequence < PropertyValue > > & rNewManVector ) 47 : nNumProperty ( 0 ) 48 , bIgnoreEncryptData ( sal_False ) 49 , nDerivedKeySize( 0 ) 50 , rManVector ( rNewManVector ) 51 52 , sFileEntryElement ( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_FILE_ENTRY ) ) 53 , sManifestElement ( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_MANIFEST ) ) 54 , sEncryptionDataElement( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_ENCRYPTION_DATA ) ) 55 , sAlgorithmElement ( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_ALGORITHM ) ) 56 , sStartKeyAlgElement ( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_START_KEY_GENERATION ) ) 57 , sKeyDerivationElement( RTL_CONSTASCII_USTRINGPARAM ( ELEMENT_KEY_DERIVATION ) ) 58 59 , sCdataAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CDATA ) ) 60 , sMediaTypeAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_MEDIA_TYPE ) ) 61 , sVersionAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_VERSION ) ) 62 , sFullPathAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_FULL_PATH ) ) 63 , sSizeAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_SIZE ) ) 64 , sSaltAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_SALT ) ) 65 , sInitialisationVectorAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_INITIALISATION_VECTOR ) ) 66 , sIterationCountAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_ITERATION_COUNT ) ) 67 , sKeySizeAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_KEY_SIZE ) ) 68 , sAlgorithmNameAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_ALGORITHM_NAME ) ) 69 , sStartKeyAlgNameAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_START_KEY_GENERATION_NAME ) ) 70 , sKeyDerivationNameAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_KEY_DERIVATION_NAME ) ) 71 , sChecksumAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CHECKSUM ) ) 72 , sChecksumTypeAttribute ( RTL_CONSTASCII_USTRINGPARAM ( ATTRIBUTE_CHECKSUM_TYPE ) ) 73 74 , sFullPathProperty ( RTL_CONSTASCII_USTRINGPARAM ( "FullPath" ) ) 75 , sMediaTypeProperty ( RTL_CONSTASCII_USTRINGPARAM ( "MediaType" ) ) 76 , sVersionProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Version" ) ) 77 , sIterationCountProperty ( RTL_CONSTASCII_USTRINGPARAM ( "IterationCount" ) ) 78 , sDerivedKeySizeProperty ( RTL_CONSTASCII_USTRINGPARAM ( "DerivedKeySize" ) ) 79 , sSaltProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Salt" ) ) 80 , sInitialisationVectorProperty ( RTL_CONSTASCII_USTRINGPARAM ( "InitialisationVector" ) ) 81 , sSizeProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Size" ) ) 82 , sDigestProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Digest" ) ) 83 , sEncryptionAlgProperty ( RTL_CONSTASCII_USTRINGPARAM ( "EncryptionAlgorithm" ) ) 84 , sStartKeyAlgProperty ( RTL_CONSTASCII_USTRINGPARAM ( "StartKeyAlgorithm" ) ) 85 , sDigestAlgProperty ( RTL_CONSTASCII_USTRINGPARAM ( "DigestAlgorithm" ) ) 86 87 , sWhiteSpace ( RTL_CONSTASCII_USTRINGPARAM ( " " ) ) 88 89 , sSHA256_URL ( RTL_CONSTASCII_USTRINGPARAM ( SHA256_URL ) ) 90 , sSHA1_Name ( RTL_CONSTASCII_USTRINGPARAM ( SHA1_NAME ) ) 91 , sSHA1_URL ( RTL_CONSTASCII_USTRINGPARAM ( SHA1_URL ) ) 92 93 , sSHA256_1k_URL ( RTL_CONSTASCII_USTRINGPARAM ( SHA256_1K_URL ) ) 94 , sSHA1_1k_Name ( RTL_CONSTASCII_USTRINGPARAM ( SHA1_1K_NAME ) ) 95 , sSHA1_1k_URL ( RTL_CONSTASCII_USTRINGPARAM ( SHA1_1K_URL ) ) 96 97 , sBlowfish_Name ( RTL_CONSTASCII_USTRINGPARAM ( BLOWFISH_NAME ) ) 98 , sBlowfish_URL ( RTL_CONSTASCII_USTRINGPARAM ( BLOWFISH_URL ) ) 99 , sAES128_URL ( RTL_CONSTASCII_USTRINGPARAM ( AES128_URL ) ) 100 , sAES192_URL ( RTL_CONSTASCII_USTRINGPARAM ( AES192_URL ) ) 101 , sAES256_URL ( RTL_CONSTASCII_USTRINGPARAM ( AES256_URL ) ) 102 103 , sPBKDF2_Name ( RTL_CONSTASCII_USTRINGPARAM ( PBKDF2_NAME ) ) 104 , sPBKDF2_URL ( RTL_CONSTASCII_USTRINGPARAM ( PBKDF2_URL ) ) 105 { 106 aStack.reserve( 10 ); 107 } 108 109 // --------------------------------------------------- 110 ManifestImport::~ManifestImport ( void ) 111 { 112 } 113 114 // --------------------------------------------------- 115 void SAL_CALL ManifestImport::startDocument( ) 116 throw( xml::sax::SAXException, uno::RuntimeException ) 117 { 118 } 119 120 // --------------------------------------------------- 121 void SAL_CALL ManifestImport::endDocument( ) 122 throw( xml::sax::SAXException, uno::RuntimeException ) 123 { 124 } 125 126 // --------------------------------------------------- 127 void SAL_CALL ManifestImport::startElement( const OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs ) 128 throw( xml::sax::SAXException, uno::RuntimeException ) 129 { 130 StringHashMap aConvertedAttribs; 131 ::rtl::OUString aConvertedName = PushNameAndNamespaces( aName, xAttribs, aConvertedAttribs ); 132 133 if ( aConvertedName == sFileEntryElement ) 134 { 135 aSequence.realloc ( PKG_SIZE_ENCR_MNFST ); 136 137 // Put full-path property first for MBA 138 aSequence[nNumProperty].Name = sFullPathProperty; 139 aSequence[nNumProperty++].Value <<= aConvertedAttribs[sFullPathAttribute]; 140 aSequence[nNumProperty].Name = sMediaTypeProperty; 141 aSequence[nNumProperty++].Value <<= aConvertedAttribs[sMediaTypeAttribute]; 142 143 OUString sVersion = aConvertedAttribs[sVersionAttribute]; 144 if ( sVersion.getLength() ) 145 { 146 aSequence[nNumProperty].Name = sVersionProperty; 147 aSequence[nNumProperty++].Value <<= sVersion; 148 } 149 150 OUString sSize = aConvertedAttribs[sSizeAttribute]; 151 if ( sSize.getLength() ) 152 { 153 sal_Int32 nSize; 154 nSize = sSize.toInt32(); 155 aSequence[nNumProperty].Name = sSizeProperty; 156 aSequence[nNumProperty++].Value <<= nSize; 157 } 158 } 159 else if ( aStack.size() > 1 ) 160 { 161 ManifestStack::reverse_iterator aIter = aStack.rbegin(); 162 aIter++; 163 164 if ( aIter->m_aConvertedName.equals( sFileEntryElement ) ) 165 { 166 if ( aConvertedName.equals( sEncryptionDataElement ) ) 167 { 168 // If this element exists, then this stream is encrypted and we need 169 // to import the initialisation vector, salt and iteration count used 170 nDerivedKeySize = 0; 171 OUString aString = aConvertedAttribs[sChecksumTypeAttribute]; 172 if ( !bIgnoreEncryptData ) 173 { 174 if ( aString.equals( sSHA1_1k_Name ) || aString.equals( sSHA1_1k_URL ) ) 175 { 176 aSequence[nNumProperty].Name = sDigestAlgProperty; 177 aSequence[nNumProperty++].Value <<= xml::crypto::DigestID::SHA1_1K; 178 } 179 else if ( aString.equals( sSHA256_1k_URL ) ) 180 { 181 aSequence[nNumProperty].Name = sDigestAlgProperty; 182 aSequence[nNumProperty++].Value <<= xml::crypto::DigestID::SHA256_1K; 183 } 184 else 185 bIgnoreEncryptData = sal_True; 186 187 if ( !bIgnoreEncryptData ) 188 { 189 aString = aConvertedAttribs[sChecksumAttribute]; 190 uno::Sequence < sal_Int8 > aDecodeBuffer; 191 Base64Codec::decodeBase64( aDecodeBuffer, aString ); 192 aSequence[nNumProperty].Name = sDigestProperty; 193 aSequence[nNumProperty++].Value <<= aDecodeBuffer; 194 } 195 } 196 } 197 } 198 else if ( aIter->m_aConvertedName.equals( sEncryptionDataElement ) ) 199 { 200 if ( aConvertedName == sAlgorithmElement ) 201 { 202 if ( !bIgnoreEncryptData ) 203 { 204 OUString aString = aConvertedAttribs[sAlgorithmNameAttribute]; 205 if ( aString.equals( sBlowfish_Name ) || aString.equals( sBlowfish_URL ) ) 206 { 207 aSequence[nNumProperty].Name = sEncryptionAlgProperty; 208 aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::BLOWFISH_CFB_8; 209 } 210 else if ( aString.equals( sAES256_URL ) ) 211 { 212 aSequence[nNumProperty].Name = sEncryptionAlgProperty; 213 aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING; 214 OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 32, "Unexpected derived key length!" ); 215 nDerivedKeySize = 32; 216 } 217 else if ( aString.equals( sAES192_URL ) ) 218 { 219 aSequence[nNumProperty].Name = sEncryptionAlgProperty; 220 aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING; 221 OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 24, "Unexpected derived key length!" ); 222 nDerivedKeySize = 24; 223 } 224 else if ( aString.equals( sAES128_URL ) ) 225 { 226 aSequence[nNumProperty].Name = sEncryptionAlgProperty; 227 aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING; 228 OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 16, "Unexpected derived key length!" ); 229 nDerivedKeySize = 16; 230 } 231 else 232 bIgnoreEncryptData = sal_True; 233 234 if ( !bIgnoreEncryptData ) 235 { 236 aString = aConvertedAttribs[sInitialisationVectorAttribute]; 237 uno::Sequence < sal_Int8 > aDecodeBuffer; 238 Base64Codec::decodeBase64 ( aDecodeBuffer, aString ); 239 aSequence[nNumProperty].Name = sInitialisationVectorProperty; 240 aSequence[nNumProperty++].Value <<= aDecodeBuffer; 241 } 242 } 243 } 244 else if ( aConvertedName == sKeyDerivationElement ) 245 { 246 if ( !bIgnoreEncryptData ) 247 { 248 OUString aString = aConvertedAttribs[sKeyDerivationNameAttribute]; 249 if ( aString.equals( sPBKDF2_Name ) || aString.equals( sPBKDF2_URL ) ) 250 { 251 aString = aConvertedAttribs[sSaltAttribute]; 252 uno::Sequence < sal_Int8 > aDecodeBuffer; 253 Base64Codec::decodeBase64 ( aDecodeBuffer, aString ); 254 aSequence[nNumProperty].Name = sSaltProperty; 255 aSequence[nNumProperty++].Value <<= aDecodeBuffer; 256 257 aString = aConvertedAttribs[sIterationCountAttribute]; 258 aSequence[nNumProperty].Name = sIterationCountProperty; 259 aSequence[nNumProperty++].Value <<= aString.toInt32(); 260 261 aString = aConvertedAttribs[sKeySizeAttribute]; 262 if ( aString.getLength() ) 263 { 264 sal_Int32 nKey = aString.toInt32(); 265 OSL_ENSURE( !nDerivedKeySize || nKey == nDerivedKeySize , "Provided derived key length differs from the expected one!" ); 266 nDerivedKeySize = nKey; 267 } 268 else if ( !nDerivedKeySize ) 269 nDerivedKeySize = 16; 270 else if ( nDerivedKeySize != 16 ) 271 OSL_ENSURE( sal_False, "Default derived key length differs from the expected one!" ); 272 273 aSequence[nNumProperty].Name = sDerivedKeySizeProperty; 274 aSequence[nNumProperty++].Value <<= nDerivedKeySize; 275 } 276 else 277 bIgnoreEncryptData = sal_True; 278 } 279 } 280 else if ( aConvertedName == sStartKeyAlgElement ) 281 { 282 OUString aString = aConvertedAttribs[sStartKeyAlgNameAttribute]; 283 if ( aString.equals( sSHA256_URL ) ) 284 { 285 aSequence[nNumProperty].Name = sStartKeyAlgProperty; 286 aSequence[nNumProperty++].Value <<= xml::crypto::DigestID::SHA256; 287 } 288 else if ( aString.equals( sSHA1_Name ) || aString.equals( sSHA1_URL ) ) 289 { 290 aSequence[nNumProperty].Name = sStartKeyAlgProperty; 291 aSequence[nNumProperty++].Value <<= xml::crypto::DigestID::SHA1; 292 } 293 else 294 bIgnoreEncryptData = sal_True; 295 } 296 } 297 } 298 } 299 300 // --------------------------------------------------- 301 void SAL_CALL ManifestImport::endElement( const OUString& aName ) 302 throw( xml::sax::SAXException, uno::RuntimeException ) 303 { 304 ::rtl::OUString aConvertedName = ConvertName( aName ); 305 if ( !aStack.empty() && aStack.rbegin()->m_aConvertedName.equals( aConvertedName ) ) 306 { 307 if ( aConvertedName.equals( sFileEntryElement ) ) 308 { 309 aSequence.realloc ( nNumProperty ); 310 bIgnoreEncryptData = sal_False; 311 rManVector.push_back ( aSequence ); 312 nNumProperty = 0; 313 } 314 315 aStack.pop_back(); 316 } 317 } 318 319 // --------------------------------------------------- 320 void SAL_CALL ManifestImport::characters( const OUString& /*aChars*/ ) 321 throw( xml::sax::SAXException, uno::RuntimeException ) 322 { 323 } 324 325 // --------------------------------------------------- 326 void SAL_CALL ManifestImport::ignorableWhitespace( const OUString& /*aWhitespaces*/ ) 327 throw( xml::sax::SAXException, uno::RuntimeException ) 328 { 329 } 330 331 // --------------------------------------------------- 332 void SAL_CALL ManifestImport::processingInstruction( const OUString& /*aTarget*/, const OUString& /*aData*/ ) 333 throw( xml::sax::SAXException, uno::RuntimeException ) 334 { 335 } 336 337 // --------------------------------------------------- 338 void SAL_CALL ManifestImport::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& /*xLocator*/ ) 339 throw( xml::sax::SAXException, uno::RuntimeException ) 340 { 341 } 342 343 // --------------------------------------------------- 344 ::rtl::OUString ManifestImport::PushNameAndNamespaces( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs, StringHashMap& o_aConvertedAttribs ) 345 { 346 StringHashMap aNamespaces; 347 ::std::vector< ::std::pair< ::rtl::OUString, ::rtl::OUString > > aAttribsStrs; 348 349 if ( xAttribs.is() ) 350 { 351 sal_Int16 nAttrCount = xAttribs.is() ? xAttribs->getLength() : 0; 352 aAttribsStrs.reserve( nAttrCount ); 353 354 for( sal_Int16 nInd = 0; nInd < nAttrCount; nInd++ ) 355 { 356 ::rtl::OUString aAttrName = xAttribs->getNameByIndex( nInd ); 357 ::rtl::OUString aAttrValue = xAttribs->getValueByIndex( nInd ); 358 if ( aAttrName.getLength() >= 5 359 && aAttrName.compareToAscii( "xmlns", 5 ) == 0 360 && ( aAttrName.getLength() == 5 || aAttrName.getStr()[5] == ( sal_Unicode )':' ) ) 361 { 362 // this is a namespace declaration 363 ::rtl::OUString aNsName( ( aAttrName.getLength() == 5 ) ? ::rtl::OUString() : aAttrName.copy( 6 ) ); 364 aNamespaces[aNsName] = aAttrValue; 365 } 366 else 367 { 368 // this is no namespace declaration 369 aAttribsStrs.push_back( pair< ::rtl::OUString, ::rtl::OUString >( aAttrName, aAttrValue ) ); 370 } 371 } 372 } 373 374 ::rtl::OUString aConvertedName = ConvertNameWithNamespace( aName, aNamespaces ); 375 if ( !aConvertedName.getLength() ) 376 aConvertedName = ConvertName( aName ); 377 378 aStack.push_back( ManifestScopeEntry( aConvertedName, aNamespaces ) ); 379 380 for ( sal_uInt16 nInd = 0; nInd < aAttribsStrs.size(); nInd++ ) 381 { 382 // convert the attribute names on filling 383 o_aConvertedAttribs[ConvertName( aAttribsStrs[nInd].first )] = aAttribsStrs[nInd].second; 384 } 385 386 return aConvertedName; 387 } 388 389 // --------------------------------------------------- 390 ::rtl::OUString ManifestImport::ConvertNameWithNamespace( const ::rtl::OUString& aName, const StringHashMap& aNamespaces ) 391 { 392 ::rtl::OUString aNsAlias; 393 ::rtl::OUString aPureName = aName; 394 395 sal_Int32 nInd = aName.indexOf( ( sal_Unicode )':' ); 396 if ( nInd != -1 && nInd < aName.getLength() ) 397 { 398 aNsAlias = aName.copy( 0, nInd ); 399 aPureName = aName.copy( nInd + 1 ); 400 } 401 402 ::rtl::OUString aResult; 403 404 StringHashMap::const_iterator aIter = aNamespaces.find( aNsAlias ); 405 if ( aIter != aNamespaces.end() 406 && ( aIter->second.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MANIFEST_NAMESPACE ) ) ) 407 || aIter->second.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MANIFEST_OASIS_NAMESPACE ) ) ) ) ) 408 { 409 // no check for manifest.xml consistency currently since the old versions have supported inconsistent documents as well 410 aResult = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MANIFEST_NSPREFIX ) ); 411 aResult += aPureName; 412 } 413 414 return aResult; 415 } 416 417 // --------------------------------------------------- 418 ::rtl::OUString ManifestImport::ConvertName( const ::rtl::OUString& aName ) 419 { 420 ::rtl::OUString aConvertedName; 421 for ( ManifestStack::reverse_iterator aIter = aStack.rbegin(); !aConvertedName.getLength() && aIter != aStack.rend(); aIter++ ) 422 { 423 if ( !aIter->m_aNamespaces.empty() ) 424 aConvertedName = ConvertNameWithNamespace( aName, aIter->m_aNamespaces ); 425 } 426 427 if ( !aConvertedName.getLength() ) 428 aConvertedName = aName; 429 430 return aConvertedName; 431 } 432 433