1*06b3ce53SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*06b3ce53SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*06b3ce53SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*06b3ce53SAndrew Rist * distributed with this work for additional information 6*06b3ce53SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*06b3ce53SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*06b3ce53SAndrew Rist * "License"); you may not use this file except in compliance 9*06b3ce53SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*06b3ce53SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*06b3ce53SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*06b3ce53SAndrew Rist * software distributed under the License is distributed on an 15*06b3ce53SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*06b3ce53SAndrew Rist * KIND, either express or implied. See the License for the 17*06b3ce53SAndrew Rist * specific language governing permissions and limitations 18*06b3ce53SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*06b3ce53SAndrew Rist *************************************************************/ 21*06b3ce53SAndrew Rist 22*06b3ce53SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_xmlsecurity.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <xmlsecurity/documentsignaturehelper.hxx> 28cdf0e10cSrcweir 29cdf0e10cSrcweir #include <com/sun/star/container/XNameAccess.hpp> 30cdf0e10cSrcweir #include <com/sun/star/lang/XComponent.hpp> 31cdf0e10cSrcweir #include <com/sun/star/lang/DisposedException.hpp> 32cdf0e10cSrcweir #include <com/sun/star/embed/XStorage.hpp> 33cdf0e10cSrcweir #include <com/sun/star/embed/ElementModes.hpp> 34cdf0e10cSrcweir #include "com/sun/star/beans/XPropertySet.hpp" 35cdf0e10cSrcweir 36cdf0e10cSrcweir #include "comphelper/documentconstants.hxx" 37cdf0e10cSrcweir #include <tools/debug.hxx> 38cdf0e10cSrcweir #include "rtl/uri.hxx" 39cdf0e10cSrcweir 40cdf0e10cSrcweir using namespace ::com::sun::star::uno; 41cdf0e10cSrcweir //using namespace ::com::sun::star; 42cdf0e10cSrcweir namespace css = ::com::sun::star; 43cdf0e10cSrcweir using rtl::OUString; 44cdf0e10cSrcweir 45cdf0e10cSrcweir 46cdf0e10cSrcweir namespace 47cdf0e10cSrcweir { 48cdf0e10cSrcweir ::rtl::OUString getElement(::rtl::OUString const & version, ::sal_Int32 * index) 49cdf0e10cSrcweir { 50cdf0e10cSrcweir while (*index < version.getLength() && version[*index] == '0') { 51cdf0e10cSrcweir ++*index; 52cdf0e10cSrcweir } 53cdf0e10cSrcweir return version.getToken(0, '.', *index); 54cdf0e10cSrcweir } 55cdf0e10cSrcweir 56cdf0e10cSrcweir 57cdf0e10cSrcweir 58cdf0e10cSrcweir // Return 1 if version1 is greater then version 2, 0 if they are equal 59cdf0e10cSrcweir //and -1 if version1 is less version 2 60cdf0e10cSrcweir int compareVersions( 61cdf0e10cSrcweir ::rtl::OUString const & version1, ::rtl::OUString const & version2) 62cdf0e10cSrcweir { 63cdf0e10cSrcweir for (::sal_Int32 i1 = 0, i2 = 0; i1 >= 0 || i2 >= 0;) { 64cdf0e10cSrcweir ::rtl::OUString e1(getElement(version1, &i1)); 65cdf0e10cSrcweir ::rtl::OUString e2(getElement(version2, &i2)); 66cdf0e10cSrcweir if (e1.getLength() < e2.getLength()) { 67cdf0e10cSrcweir return -1; 68cdf0e10cSrcweir } else if (e1.getLength() > e2.getLength()) { 69cdf0e10cSrcweir return 1; 70cdf0e10cSrcweir } else if (e1 < e2) { 71cdf0e10cSrcweir return -1; 72cdf0e10cSrcweir } else if (e1 > e2) { 73cdf0e10cSrcweir return 1; 74cdf0e10cSrcweir } 75cdf0e10cSrcweir } 76cdf0e10cSrcweir return 0; 77cdf0e10cSrcweir } 78cdf0e10cSrcweir } 79cdf0e10cSrcweir //If the OOo 3.0 mode is used then we exclude 80cdf0e10cSrcweir //'mimetype' and all content of 'META-INF'. 81cdf0e10cSrcweir //If the argument 'bSigning' is true then the element list is created for a signing 82cdf0e10cSrcweir //operation in which case we use the latest signing algorithm. That is all elements 83cdf0e10cSrcweir //we find in the zip storage are added to the list. We do not support the old signatures 84cdf0e10cSrcweir //which did not contain all files. 85cdf0e10cSrcweir //If 'bSigning' is false, then we validate. If the user enabled validating according to OOo 3.0 86cdf0e10cSrcweir //then mimetype and all content of META-INF must be excluded. 87cdf0e10cSrcweir void ImplFillElementList( 88cdf0e10cSrcweir std::vector< rtl::OUString >& rList, const Reference < css::embed::XStorage >& rxStore, 89cdf0e10cSrcweir const ::rtl::OUString rRootStorageName, const bool bRecursive, 90cdf0e10cSrcweir const DocumentSignatureAlgorithm mode) 91cdf0e10cSrcweir { 92cdf0e10cSrcweir ::rtl::OUString aMetaInfName( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ); 93cdf0e10cSrcweir ::rtl::OUString sMimeTypeName (RTL_CONSTASCII_USTRINGPARAM("mimetype")); 94cdf0e10cSrcweir ::rtl::OUString aSep( RTL_CONSTASCII_USTRINGPARAM( "/" ) ); 95cdf0e10cSrcweir 96cdf0e10cSrcweir Reference < css::container::XNameAccess > xElements( rxStore, UNO_QUERY ); 97cdf0e10cSrcweir Sequence< ::rtl::OUString > aElements = xElements->getElementNames(); 98cdf0e10cSrcweir sal_Int32 nElements = aElements.getLength(); 99cdf0e10cSrcweir const ::rtl::OUString* pNames = aElements.getConstArray(); 100cdf0e10cSrcweir 101cdf0e10cSrcweir for ( sal_Int32 n = 0; n < nElements; n++ ) 102cdf0e10cSrcweir { 103cdf0e10cSrcweir if (mode != OOo3_2Document 104cdf0e10cSrcweir && (pNames[n] == aMetaInfName 105cdf0e10cSrcweir || pNames[n] == sMimeTypeName)) 106cdf0e10cSrcweir { 107cdf0e10cSrcweir continue; 108cdf0e10cSrcweir } 109cdf0e10cSrcweir else 110cdf0e10cSrcweir { 111cdf0e10cSrcweir ::rtl::OUString sEncName = ::rtl::Uri::encode( 112cdf0e10cSrcweir pNames[n], rtl_UriCharClassRelSegment, 113cdf0e10cSrcweir rtl_UriEncodeStrict, RTL_TEXTENCODING_UTF8); 114cdf0e10cSrcweir if (sEncName.getLength() == 0 && pNames[n].getLength() != 0) 115cdf0e10cSrcweir throw css::uno::Exception(::rtl::OUString( 116cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("Failed to encode element name of XStorage")), 0); 117cdf0e10cSrcweir 118cdf0e10cSrcweir if ( rxStore->isStreamElement( pNames[n] ) ) 119cdf0e10cSrcweir { 120cdf0e10cSrcweir //Exclude documentsignatures.xml! 121cdf0e10cSrcweir if (pNames[n].equals( 122cdf0e10cSrcweir DocumentSignatureHelper::GetDocumentContentSignatureDefaultStreamName())) 123cdf0e10cSrcweir continue; 124cdf0e10cSrcweir ::rtl::OUString aFullName( rRootStorageName + sEncName ); 125cdf0e10cSrcweir rList.push_back(aFullName); 126cdf0e10cSrcweir } 127cdf0e10cSrcweir else if ( bRecursive && rxStore->isStorageElement( pNames[n] ) ) 128cdf0e10cSrcweir { 129cdf0e10cSrcweir Reference < css::embed::XStorage > xSubStore = rxStore->openStorageElement( pNames[n], css::embed::ElementModes::READ ); 130cdf0e10cSrcweir rtl::OUString aFullRootName( rRootStorageName + sEncName + aSep ); 131cdf0e10cSrcweir ImplFillElementList(rList, xSubStore, aFullRootName, bRecursive, mode); 132cdf0e10cSrcweir } 133cdf0e10cSrcweir } 134cdf0e10cSrcweir } 135cdf0e10cSrcweir } 136cdf0e10cSrcweir 137cdf0e10cSrcweir 138cdf0e10cSrcweir bool DocumentSignatureHelper::isODFPre_1_2(const ::rtl::OUString & sVersion) 139cdf0e10cSrcweir { 140cdf0e10cSrcweir //The property version exists only if the document is at least version 1.2 141cdf0e10cSrcweir //That is, if the document has version 1.1 and sVersion is empty. 142cdf0e10cSrcweir //The constant is defined in comphelper/documentconstants.hxx 143cdf0e10cSrcweir if (compareVersions(sVersion, ODFVER_012_TEXT) == -1) 144cdf0e10cSrcweir return true; 145cdf0e10cSrcweir return false; 146cdf0e10cSrcweir } 147cdf0e10cSrcweir 148cdf0e10cSrcweir bool DocumentSignatureHelper::isOOo3_2_Signature(const SignatureInformation & sigInfo) 149cdf0e10cSrcweir { 150cdf0e10cSrcweir ::rtl::OUString sManifestURI(RTL_CONSTASCII_USTRINGPARAM("META-INF/manifest.xml")); 151cdf0e10cSrcweir bool bOOo3_2 = false; 152cdf0e10cSrcweir typedef ::std::vector< SignatureReferenceInformation >::const_iterator CIT; 153cdf0e10cSrcweir for (CIT i = sigInfo.vSignatureReferenceInfors.begin(); 154cdf0e10cSrcweir i < sigInfo.vSignatureReferenceInfors.end(); i++) 155cdf0e10cSrcweir { 156cdf0e10cSrcweir if (i->ouURI.equals(sManifestURI)) 157cdf0e10cSrcweir { 158cdf0e10cSrcweir bOOo3_2 = true; 159cdf0e10cSrcweir break; 160cdf0e10cSrcweir } 161cdf0e10cSrcweir } 162cdf0e10cSrcweir return bOOo3_2; 163cdf0e10cSrcweir } 164cdf0e10cSrcweir 165cdf0e10cSrcweir DocumentSignatureAlgorithm 166cdf0e10cSrcweir DocumentSignatureHelper::getDocumentAlgorithm( 167cdf0e10cSrcweir const ::rtl::OUString & sODFVersion, const SignatureInformation & sigInfo) 168cdf0e10cSrcweir { 169cdf0e10cSrcweir OSL_ASSERT(sODFVersion.getLength()); 170cdf0e10cSrcweir DocumentSignatureAlgorithm mode = OOo3_2Document; 171cdf0e10cSrcweir if (!isOOo3_2_Signature(sigInfo)) 172cdf0e10cSrcweir { 173cdf0e10cSrcweir if (isODFPre_1_2(sODFVersion)) 174cdf0e10cSrcweir mode = OOo2Document; 175cdf0e10cSrcweir else 176cdf0e10cSrcweir mode = OOo3_0Document; 177cdf0e10cSrcweir } 178cdf0e10cSrcweir return mode; 179cdf0e10cSrcweir } 180cdf0e10cSrcweir 181cdf0e10cSrcweir //The function creates a list of files which are to be signed or for which 182cdf0e10cSrcweir //the signature is to be validated. The strings are UTF8 encoded URIs which 183cdf0e10cSrcweir //contain '/' as path separators. 184cdf0e10cSrcweir // 185cdf0e10cSrcweir //The algorithm how document signatures are created and validated has 186cdf0e10cSrcweir //changed over time. The change affects only which files within the document 187cdf0e10cSrcweir //are changed. Document signatures created by OOo 2.x only used particular files. Since 188cdf0e10cSrcweir //OOo 3.0 everything except "mimetype" and "META-INF" are signed. As of OOo 3.2 everything 189cdf0e10cSrcweir //except META-INF/documentsignatures.xml is signed. 190cdf0e10cSrcweir //Signatures are validated according to the algorithm which was then used for validation. 191cdf0e10cSrcweir //That is, when validating a signature which was created by OOo 3.0, then mimetype and 192cdf0e10cSrcweir //META-INF are not used. 193cdf0e10cSrcweir // 194cdf0e10cSrcweir //When a signature is created then we always use the latest algorithm. That is, we use 195cdf0e10cSrcweir //that of OOo 3.2 196cdf0e10cSrcweir std::vector< rtl::OUString > 197cdf0e10cSrcweir DocumentSignatureHelper::CreateElementList( 198cdf0e10cSrcweir const Reference < css::embed::XStorage >& rxStore, 199cdf0e10cSrcweir const ::rtl::OUString /*rRootStorageName*/, DocumentSignatureMode eMode, 200cdf0e10cSrcweir const DocumentSignatureAlgorithm mode) 201cdf0e10cSrcweir { 202cdf0e10cSrcweir std::vector< rtl::OUString > aElements; 203cdf0e10cSrcweir ::rtl::OUString aSep( RTL_CONSTASCII_USTRINGPARAM( "/" ) ); 204cdf0e10cSrcweir 205cdf0e10cSrcweir switch ( eMode ) 206cdf0e10cSrcweir { 207cdf0e10cSrcweir case SignatureModeDocumentContent: 208cdf0e10cSrcweir { 209cdf0e10cSrcweir if (mode == OOo2Document) //that is, ODF 1.0, 1.1 210cdf0e10cSrcweir { 211cdf0e10cSrcweir // 1) Main content 212cdf0e10cSrcweir ImplFillElementList(aElements, rxStore, ::rtl::OUString(), false, mode); 213cdf0e10cSrcweir 214cdf0e10cSrcweir // 2) Pictures... 215cdf0e10cSrcweir rtl::OUString aSubStorageName( rtl::OUString::createFromAscii( "Pictures" ) ); 216cdf0e10cSrcweir try 217cdf0e10cSrcweir { 218cdf0e10cSrcweir Reference < css::embed::XStorage > xSubStore = rxStore->openStorageElement( aSubStorageName, css::embed::ElementModes::READ ); 219cdf0e10cSrcweir ImplFillElementList(aElements, xSubStore, aSubStorageName+aSep, true, mode); 220cdf0e10cSrcweir } 221cdf0e10cSrcweir catch(css::io::IOException& ) 222cdf0e10cSrcweir { 223cdf0e10cSrcweir ; // Doesn't have to exist... 224cdf0e10cSrcweir } 225cdf0e10cSrcweir // 3) OLE.... 226cdf0e10cSrcweir aSubStorageName = rtl::OUString::createFromAscii( "ObjectReplacements" ); 227cdf0e10cSrcweir try 228cdf0e10cSrcweir { 229cdf0e10cSrcweir Reference < css::embed::XStorage > xSubStore = rxStore->openStorageElement( aSubStorageName, css::embed::ElementModes::READ ); 230cdf0e10cSrcweir ImplFillElementList(aElements, xSubStore, aSubStorageName+aSep, true, mode); 231cdf0e10cSrcweir xSubStore.clear(); 232cdf0e10cSrcweir 233cdf0e10cSrcweir // Object folders... 234cdf0e10cSrcweir rtl::OUString aMatchStr( rtl::OUString::createFromAscii( "Object " ) ); 235cdf0e10cSrcweir Reference < css::container::XNameAccess > xElements( rxStore, UNO_QUERY ); 236cdf0e10cSrcweir Sequence< ::rtl::OUString > aElementNames = xElements->getElementNames(); 237cdf0e10cSrcweir sal_Int32 nElements = aElementNames.getLength(); 238cdf0e10cSrcweir const ::rtl::OUString* pNames = aElementNames.getConstArray(); 239cdf0e10cSrcweir for ( sal_Int32 n = 0; n < nElements; n++ ) 240cdf0e10cSrcweir { 241cdf0e10cSrcweir if ( ( pNames[n].match( aMatchStr ) ) && rxStore->isStorageElement( pNames[n] ) ) 242cdf0e10cSrcweir { 243cdf0e10cSrcweir Reference < css::embed::XStorage > xTmpSubStore = rxStore->openStorageElement( pNames[n], css::embed::ElementModes::READ ); 244cdf0e10cSrcweir ImplFillElementList(aElements, xTmpSubStore, pNames[n]+aSep, true, mode); 245cdf0e10cSrcweir } 246cdf0e10cSrcweir } 247cdf0e10cSrcweir } 248cdf0e10cSrcweir catch( com::sun::star::io::IOException& ) 249cdf0e10cSrcweir { 250cdf0e10cSrcweir ; // Doesn't have to exist... 251cdf0e10cSrcweir } 252cdf0e10cSrcweir } 253cdf0e10cSrcweir else 254cdf0e10cSrcweir { 255cdf0e10cSrcweir // Everything except META-INF 256cdf0e10cSrcweir ImplFillElementList(aElements, rxStore, ::rtl::OUString(), true, mode); 257cdf0e10cSrcweir } 258cdf0e10cSrcweir } 259cdf0e10cSrcweir break; 260cdf0e10cSrcweir case SignatureModeMacros: 261cdf0e10cSrcweir { 262cdf0e10cSrcweir // 1) Macros 263cdf0e10cSrcweir rtl::OUString aSubStorageName( rtl::OUString::createFromAscii( "Basic" ) ); 264cdf0e10cSrcweir try 265cdf0e10cSrcweir { 266cdf0e10cSrcweir Reference < css::embed::XStorage > xSubStore = rxStore->openStorageElement( aSubStorageName, css::embed::ElementModes::READ ); 267cdf0e10cSrcweir ImplFillElementList(aElements, xSubStore, aSubStorageName+aSep, true, mode); 268cdf0e10cSrcweir } 269cdf0e10cSrcweir catch( com::sun::star::io::IOException& ) 270cdf0e10cSrcweir { 271cdf0e10cSrcweir ; // Doesn't have to exist... 272cdf0e10cSrcweir } 273cdf0e10cSrcweir 274cdf0e10cSrcweir // 2) Dialogs 275cdf0e10cSrcweir aSubStorageName = rtl::OUString::createFromAscii( "Dialogs") ; 276cdf0e10cSrcweir try 277cdf0e10cSrcweir { 278cdf0e10cSrcweir Reference < css::embed::XStorage > xSubStore = rxStore->openStorageElement( aSubStorageName, css::embed::ElementModes::READ ); 279cdf0e10cSrcweir ImplFillElementList(aElements, xSubStore, aSubStorageName+aSep, true, mode); 280cdf0e10cSrcweir } 281cdf0e10cSrcweir catch( com::sun::star::io::IOException& ) 282cdf0e10cSrcweir { 283cdf0e10cSrcweir ; // Doesn't have to exist... 284cdf0e10cSrcweir } 285cdf0e10cSrcweir // 3) Scripts 286cdf0e10cSrcweir aSubStorageName = rtl::OUString::createFromAscii( "Scripts") ; 287cdf0e10cSrcweir try 288cdf0e10cSrcweir { 289cdf0e10cSrcweir Reference < css::embed::XStorage > xSubStore = rxStore->openStorageElement( aSubStorageName, css::embed::ElementModes::READ ); 290cdf0e10cSrcweir ImplFillElementList(aElements, xSubStore, aSubStorageName+aSep, true, mode); 291cdf0e10cSrcweir } 292cdf0e10cSrcweir catch( css::io::IOException& ) 293cdf0e10cSrcweir { 294cdf0e10cSrcweir ; // Doesn't have to exist... 295cdf0e10cSrcweir } 296cdf0e10cSrcweir } 297cdf0e10cSrcweir break; 298cdf0e10cSrcweir case SignatureModePackage: 299cdf0e10cSrcweir { 300cdf0e10cSrcweir // Everything except META-INF 301cdf0e10cSrcweir ImplFillElementList(aElements, rxStore, ::rtl::OUString(), true, mode); 302cdf0e10cSrcweir } 303cdf0e10cSrcweir break; 304cdf0e10cSrcweir } 305cdf0e10cSrcweir 306cdf0e10cSrcweir return aElements; 307cdf0e10cSrcweir } 308cdf0e10cSrcweir 309cdf0e10cSrcweir SignatureStreamHelper DocumentSignatureHelper::OpenSignatureStream( 310cdf0e10cSrcweir const Reference < css::embed::XStorage >& rxStore, sal_Int32 nOpenMode, DocumentSignatureMode eDocSigMode ) 311cdf0e10cSrcweir { 312cdf0e10cSrcweir sal_Int32 nSubStorageOpenMode = css::embed::ElementModes::READ; 313cdf0e10cSrcweir if ( nOpenMode & css::embed::ElementModes::WRITE ) 314cdf0e10cSrcweir nSubStorageOpenMode = css::embed::ElementModes::WRITE; 315cdf0e10cSrcweir 316cdf0e10cSrcweir SignatureStreamHelper aHelper; 317cdf0e10cSrcweir 318cdf0e10cSrcweir try 319cdf0e10cSrcweir { 320cdf0e10cSrcweir ::rtl::OUString aSIGStoreName( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ); 321cdf0e10cSrcweir aHelper.xSignatureStorage = rxStore->openStorageElement( aSIGStoreName, nSubStorageOpenMode ); 322cdf0e10cSrcweir if ( aHelper.xSignatureStorage.is() ) 323cdf0e10cSrcweir { 324cdf0e10cSrcweir ::rtl::OUString aSIGStreamName; 325cdf0e10cSrcweir if ( eDocSigMode == SignatureModeDocumentContent ) 326cdf0e10cSrcweir aSIGStreamName = DocumentSignatureHelper::GetDocumentContentSignatureDefaultStreamName(); 327cdf0e10cSrcweir else if ( eDocSigMode == SignatureModeMacros ) 328cdf0e10cSrcweir aSIGStreamName = DocumentSignatureHelper::GetScriptingContentSignatureDefaultStreamName(); 329cdf0e10cSrcweir else 330cdf0e10cSrcweir aSIGStreamName = DocumentSignatureHelper::GetPackageSignatureDefaultStreamName(); 331cdf0e10cSrcweir 332cdf0e10cSrcweir aHelper.xSignatureStream = aHelper.xSignatureStorage->openStreamElement( aSIGStreamName, nOpenMode ); 333cdf0e10cSrcweir } 334cdf0e10cSrcweir } 335cdf0e10cSrcweir catch(css::io::IOException& ) 336cdf0e10cSrcweir { 337cdf0e10cSrcweir // Doesn't have to exist... 338cdf0e10cSrcweir DBG_ASSERT( nOpenMode == css::embed::ElementModes::READ, "Error creating signature stream..." ); 339cdf0e10cSrcweir } 340cdf0e10cSrcweir 341cdf0e10cSrcweir return aHelper; 342cdf0e10cSrcweir } 343cdf0e10cSrcweir 344cdf0e10cSrcweir //sElementList contains all files which are expected to be signed. Only those files must me signed, 345cdf0e10cSrcweir //no more, no less. 346cdf0e10cSrcweir //The DocumentSignatureAlgorithm indicates if the document was created with OOo 2.x. Then 347cdf0e10cSrcweir //the uri s in the Reference elements in the signature, were not properly encoded. 348cdf0e10cSrcweir // For example: <Reference URI="ObjectReplacements/Object 1"> 349cdf0e10cSrcweir bool DocumentSignatureHelper::checkIfAllFilesAreSigned( 350cdf0e10cSrcweir const ::std::vector< ::rtl::OUString > & sElementList, 351cdf0e10cSrcweir const SignatureInformation & sigInfo, 352cdf0e10cSrcweir const DocumentSignatureAlgorithm alg) 353cdf0e10cSrcweir { 354cdf0e10cSrcweir // Can only be valid if ALL streams are signed, which means real stream count == signed stream count 355cdf0e10cSrcweir unsigned int nRealCount = 0; 356cdf0e10cSrcweir for ( int i = sigInfo.vSignatureReferenceInfors.size(); i; ) 357cdf0e10cSrcweir { 358cdf0e10cSrcweir const SignatureReferenceInformation& rInf = sigInfo.vSignatureReferenceInfors[--i]; 359cdf0e10cSrcweir // There is also an extra entry of type TYPE_SAMEDOCUMENT_REFERENCE because of signature date. 360cdf0e10cSrcweir if ( ( rInf.nType == TYPE_BINARYSTREAM_REFERENCE ) || ( rInf.nType == TYPE_XMLSTREAM_REFERENCE ) ) 361cdf0e10cSrcweir { 362cdf0e10cSrcweir ::rtl::OUString sReferenceURI = rInf.ouURI; 363cdf0e10cSrcweir if (alg == OOo2Document) 364cdf0e10cSrcweir { 365cdf0e10cSrcweir //Comparing URIs is a difficult. Therefore we kind of normalize 366cdf0e10cSrcweir //it before comparing. We assume that our URI do not have a leading "./" 367cdf0e10cSrcweir //and fragments at the end (...#...) 368cdf0e10cSrcweir sReferenceURI = ::rtl::Uri::encode( 369cdf0e10cSrcweir sReferenceURI, rtl_UriCharClassPchar, 370cdf0e10cSrcweir rtl_UriEncodeCheckEscapes, RTL_TEXTENCODING_UTF8); 371cdf0e10cSrcweir } 372cdf0e10cSrcweir 373cdf0e10cSrcweir //find the file in the element list 374cdf0e10cSrcweir typedef ::std::vector< ::rtl::OUString >::const_iterator CIT; 375cdf0e10cSrcweir for (CIT aIter = sElementList.begin(); aIter < sElementList.end(); aIter++) 376cdf0e10cSrcweir { 377cdf0e10cSrcweir ::rtl::OUString sElementListURI = *aIter; 378cdf0e10cSrcweir if (alg == OOo2Document) 379cdf0e10cSrcweir { 380cdf0e10cSrcweir sElementListURI = 381cdf0e10cSrcweir ::rtl::Uri::encode( 382cdf0e10cSrcweir sElementListURI, rtl_UriCharClassPchar, 383cdf0e10cSrcweir rtl_UriEncodeCheckEscapes, RTL_TEXTENCODING_UTF8); 384cdf0e10cSrcweir } 385cdf0e10cSrcweir if (sElementListURI.equals(sReferenceURI)) 386cdf0e10cSrcweir { 387cdf0e10cSrcweir nRealCount++; 388cdf0e10cSrcweir break; 389cdf0e10cSrcweir } 390cdf0e10cSrcweir } 391cdf0e10cSrcweir } 392cdf0e10cSrcweir } 393cdf0e10cSrcweir return sElementList.size() == nRealCount; 394cdf0e10cSrcweir } 395cdf0e10cSrcweir 396cdf0e10cSrcweir /*Compares the Uri which are obtained from CreateElementList with 397cdf0e10cSrcweir the path obtained from the manifest.xml. 398cdf0e10cSrcweir Returns true if both strings are equal. 399cdf0e10cSrcweir */ 400cdf0e10cSrcweir bool DocumentSignatureHelper::equalsReferenceUriManifestPath( 401cdf0e10cSrcweir const OUString & rUri, const OUString & rPath) 402cdf0e10cSrcweir { 403cdf0e10cSrcweir bool retVal = false; 404cdf0e10cSrcweir //split up the uri and path into segments. Both are separated by '/' 405cdf0e10cSrcweir std::vector<OUString> vUriSegments; 406cdf0e10cSrcweir sal_Int32 nIndex = 0; 407cdf0e10cSrcweir do 408cdf0e10cSrcweir { 409cdf0e10cSrcweir OUString aToken = rUri.getToken( 0, '/', nIndex ); 410cdf0e10cSrcweir vUriSegments.push_back(aToken); 411cdf0e10cSrcweir } 412cdf0e10cSrcweir while (nIndex >= 0); 413cdf0e10cSrcweir 414cdf0e10cSrcweir std::vector<OUString> vPathSegments; 415cdf0e10cSrcweir nIndex = 0; 416cdf0e10cSrcweir do 417cdf0e10cSrcweir { 418cdf0e10cSrcweir OUString aToken = rPath.getToken( 0, '/', nIndex ); 419cdf0e10cSrcweir vPathSegments.push_back(aToken); 420cdf0e10cSrcweir } 421cdf0e10cSrcweir while (nIndex >= 0); 422cdf0e10cSrcweir 423cdf0e10cSrcweir //Now compare each segment of the uri with its counterpart from the path 424cdf0e10cSrcweir if (vUriSegments.size() == vPathSegments.size()) 425cdf0e10cSrcweir { 426cdf0e10cSrcweir retVal = true; 427cdf0e10cSrcweir typedef std::vector<OUString>::const_iterator CIT; 428cdf0e10cSrcweir for (CIT i = vUriSegments.begin(), j = vPathSegments.begin(); 429cdf0e10cSrcweir i != vUriSegments.end(); i++, j++) 430cdf0e10cSrcweir { 431cdf0e10cSrcweir //Decode the uri segment, so that %20 becomes ' ', etc. 432cdf0e10cSrcweir OUString sDecUri = ::rtl::Uri::decode( 433cdf0e10cSrcweir *i, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8); 434cdf0e10cSrcweir if (!sDecUri.equals(*j)) 435cdf0e10cSrcweir { 436cdf0e10cSrcweir retVal = false; 437cdf0e10cSrcweir break; 438cdf0e10cSrcweir } 439cdf0e10cSrcweir } 440cdf0e10cSrcweir } 441cdf0e10cSrcweir 442cdf0e10cSrcweir return retVal; 443cdf0e10cSrcweir } 444cdf0e10cSrcweir 445cdf0e10cSrcweir ::rtl::OUString DocumentSignatureHelper::GetDocumentContentSignatureDefaultStreamName() 446cdf0e10cSrcweir { 447cdf0e10cSrcweir return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "documentsignatures.xml" ) ); 448cdf0e10cSrcweir } 449cdf0e10cSrcweir 450cdf0e10cSrcweir ::rtl::OUString DocumentSignatureHelper::GetScriptingContentSignatureDefaultStreamName() 451cdf0e10cSrcweir { 452cdf0e10cSrcweir return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "macrosignatures.xml" ) ); 453cdf0e10cSrcweir } 454cdf0e10cSrcweir 455cdf0e10cSrcweir ::rtl::OUString DocumentSignatureHelper::GetPackageSignatureDefaultStreamName() 456cdf0e10cSrcweir { 457cdf0e10cSrcweir return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "packagesignatures.xml" ) ); 458cdf0e10cSrcweir } 459