diff options
author | Caolán McNamara <caolanm@redhat.com> | 2012-05-28 10:35:31 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2012-06-01 22:22:35 +0100 |
commit | acc613a3236c61c8272bde1eadca5d8bf25f98f1 (patch) | |
tree | 594d3fa14decfdb3daa13ff6005a4a7abc7cddd8 /package | |
parent | 159435291bb6e36f1525c4718dc2f8bec86c0545 (diff) |
unwind manifest xml parser and follow tag hierarchy model
so we validate that each tag is inside the right parent
Change-Id: Ibc82aeaf6b409ef2fed7de0cd8f15c164da65e53
Diffstat (limited to 'package')
-rw-r--r-- | package/source/manifest/ManifestImport.cxx | 356 | ||||
-rw-r--r-- | package/source/manifest/ManifestImport.hxx | 8 |
2 files changed, 212 insertions, 152 deletions
diff --git a/package/source/manifest/ManifestImport.cxx b/package/source/manifest/ManifestImport.cxx index 5e9a310c2a26..f8590fe42a25 100644 --- a/package/source/manifest/ManifestImport.cxx +++ b/package/source/manifest/ManifestImport.cxx @@ -123,177 +123,229 @@ void SAL_CALL ManifestImport::endDocument( ) { } -// --------------------------------------------------- -void SAL_CALL ManifestImport::startElement( const OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs ) - throw( xml::sax::SAXException, uno::RuntimeException ) +void ManifestImport::doFileEntry(StringHashMap &rConvertedAttribs) + throw( uno::RuntimeException ) { - StringHashMap aConvertedAttribs; - ::rtl::OUString aConvertedName = PushNameAndNamespaces( aName, xAttribs, aConvertedAttribs ); + aSequence.realloc ( PKG_SIZE_ENCR_MNFST ); - if ( aConvertedName == sFileEntryElement ) + // Put full-path property first for MBA + aSequence[nNumProperty].Name = sFullPathProperty; + aSequence[nNumProperty++].Value <<= rConvertedAttribs[sFullPathAttribute]; + aSequence[nNumProperty].Name = sMediaTypeProperty; + aSequence[nNumProperty++].Value <<= rConvertedAttribs[sMediaTypeAttribute]; + + OUString sVersion = rConvertedAttribs[sVersionAttribute]; + if ( sVersion.getLength() ) { - aSequence.realloc ( PKG_SIZE_ENCR_MNFST ); + aSequence[nNumProperty].Name = sVersionProperty; + aSequence[nNumProperty++].Value <<= sVersion; + } - // Put full-path property first for MBA - aSequence[nNumProperty].Name = sFullPathProperty; - aSequence[nNumProperty++].Value <<= aConvertedAttribs[sFullPathAttribute]; - aSequence[nNumProperty].Name = sMediaTypeProperty; - aSequence[nNumProperty++].Value <<= aConvertedAttribs[sMediaTypeAttribute]; + OUString sSize = rConvertedAttribs[sSizeAttribute]; + if ( sSize.getLength() ) + { + sal_Int32 nSize; + nSize = sSize.toInt32(); + aSequence[nNumProperty].Name = sSizeProperty; + aSequence[nNumProperty++].Value <<= nSize; + } +} - OUString sVersion = aConvertedAttribs[sVersionAttribute]; - if ( sVersion.getLength() ) +void ManifestImport::doEncryptionData(StringHashMap &rConvertedAttribs) + throw( uno::RuntimeException ) +{ + // If this element exists, then this stream is encrypted and we need + // to import the initialisation vector, salt and iteration count used + nDerivedKeySize = 0; + OUString aString = rConvertedAttribs[sChecksumTypeAttribute]; + if ( !bIgnoreEncryptData ) + { + if ( aString.equals( sSHA1_1k_Name ) || aString.equals( sSHA1_1k_URL ) ) + { + aSequence[nNumProperty].Name = sDigestAlgProperty; + aSequence[nNumProperty++].Value <<= xml::crypto::DigestID::SHA1_1K; + } + else if ( aString.equals( sSHA256_1k_URL ) ) { - aSequence[nNumProperty].Name = sVersionProperty; - aSequence[nNumProperty++].Value <<= sVersion; + aSequence[nNumProperty].Name = sDigestAlgProperty; + aSequence[nNumProperty++].Value <<= xml::crypto::DigestID::SHA256_1K; } + else + bIgnoreEncryptData = sal_True; - OUString sSize = aConvertedAttribs[sSizeAttribute]; - if ( sSize.getLength() ) + if ( !bIgnoreEncryptData ) { - sal_Int32 nSize; - nSize = sSize.toInt32(); - aSequence[nNumProperty].Name = sSizeProperty; - aSequence[nNumProperty++].Value <<= nSize; + aString = rConvertedAttribs[sChecksumAttribute]; + uno::Sequence < sal_Int8 > aDecodeBuffer; + ::sax::Converter::decodeBase64(aDecodeBuffer, aString); + aSequence[nNumProperty].Name = sDigestProperty; + aSequence[nNumProperty++].Value <<= aDecodeBuffer; } } - else if ( aStack.size() > 1 ) +} + +void ManifestImport::doAlgorithm(StringHashMap &rConvertedAttribs) + throw( uno::RuntimeException ) +{ + if ( !bIgnoreEncryptData ) { - ManifestStack::reverse_iterator aIter = aStack.rbegin(); - ++aIter; + OUString aString = rConvertedAttribs[sAlgorithmNameAttribute]; + if ( aString.equals( sBlowfish_Name ) || aString.equals( sBlowfish_URL ) ) + { + aSequence[nNumProperty].Name = sEncryptionAlgProperty; + aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::BLOWFISH_CFB_8; + } + else if ( aString.equals( sAES256_URL ) ) + { + aSequence[nNumProperty].Name = sEncryptionAlgProperty; + aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING; + OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 32, "Unexpected derived key length!" ); + nDerivedKeySize = 32; + } + else if ( aString.equals( sAES192_URL ) ) + { + aSequence[nNumProperty].Name = sEncryptionAlgProperty; + aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING; + OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 24, "Unexpected derived key length!" ); + nDerivedKeySize = 24; + } + else if ( aString.equals( sAES128_URL ) ) + { + aSequence[nNumProperty].Name = sEncryptionAlgProperty; + aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING; + OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 16, "Unexpected derived key length!" ); + nDerivedKeySize = 16; + } + else + bIgnoreEncryptData = sal_True; - if ( aIter->m_aConvertedName.equals( sFileEntryElement ) ) + if ( !bIgnoreEncryptData ) { - if ( aConvertedName.equals( sEncryptionDataElement ) ) - { - // If this element exists, then this stream is encrypted and we need - // to import the initialisation vector, salt and iteration count used - nDerivedKeySize = 0; - OUString aString = aConvertedAttribs[sChecksumTypeAttribute]; - if ( !bIgnoreEncryptData ) - { - if ( aString.equals( sSHA1_1k_Name ) || aString.equals( sSHA1_1k_URL ) ) - { - aSequence[nNumProperty].Name = sDigestAlgProperty; - aSequence[nNumProperty++].Value <<= xml::crypto::DigestID::SHA1_1K; - } - else if ( aString.equals( sSHA256_1k_URL ) ) - { - aSequence[nNumProperty].Name = sDigestAlgProperty; - aSequence[nNumProperty++].Value <<= xml::crypto::DigestID::SHA256_1K; - } - else - bIgnoreEncryptData = sal_True; - - if ( !bIgnoreEncryptData ) - { - aString = aConvertedAttribs[sChecksumAttribute]; - uno::Sequence < sal_Int8 > aDecodeBuffer; - ::sax::Converter::decodeBase64(aDecodeBuffer, aString); - aSequence[nNumProperty].Name = sDigestProperty; - aSequence[nNumProperty++].Value <<= aDecodeBuffer; - } - } - } + aString = rConvertedAttribs[sInitialisationVectorAttribute]; + uno::Sequence < sal_Int8 > aDecodeBuffer; + ::sax::Converter::decodeBase64(aDecodeBuffer, aString); + aSequence[nNumProperty].Name = sInitialisationVectorProperty; + aSequence[nNumProperty++].Value <<= aDecodeBuffer; } - else if ( aIter->m_aConvertedName.equals( sEncryptionDataElement ) ) + } +} + +void ManifestImport::doKeyDerivation(StringHashMap &rConvertedAttribs) + throw( uno::RuntimeException ) +{ + if ( !bIgnoreEncryptData ) + { + OUString aString = rConvertedAttribs[sKeyDerivationNameAttribute]; + if ( aString.equals( sPBKDF2_Name ) || aString.equals( sPBKDF2_URL ) ) { - if ( aConvertedName == sAlgorithmElement ) - { - if ( !bIgnoreEncryptData ) - { - OUString aString = aConvertedAttribs[sAlgorithmNameAttribute]; - if ( aString.equals( sBlowfish_Name ) || aString.equals( sBlowfish_URL ) ) - { - aSequence[nNumProperty].Name = sEncryptionAlgProperty; - aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::BLOWFISH_CFB_8; - } - else if ( aString.equals( sAES256_URL ) ) - { - aSequence[nNumProperty].Name = sEncryptionAlgProperty; - aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING; - OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 32, "Unexpected derived key length!" ); - nDerivedKeySize = 32; - } - else if ( aString.equals( sAES192_URL ) ) - { - aSequence[nNumProperty].Name = sEncryptionAlgProperty; - aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING; - OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 24, "Unexpected derived key length!" ); - nDerivedKeySize = 24; - } - else if ( aString.equals( sAES128_URL ) ) - { - aSequence[nNumProperty].Name = sEncryptionAlgProperty; - aSequence[nNumProperty++].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING; - OSL_ENSURE( !nDerivedKeySize || nDerivedKeySize == 16, "Unexpected derived key length!" ); - nDerivedKeySize = 16; - } - else - bIgnoreEncryptData = sal_True; - - if ( !bIgnoreEncryptData ) - { - aString = aConvertedAttribs[sInitialisationVectorAttribute]; - uno::Sequence < sal_Int8 > aDecodeBuffer; - ::sax::Converter::decodeBase64(aDecodeBuffer, aString); - aSequence[nNumProperty].Name = sInitialisationVectorProperty; - aSequence[nNumProperty++].Value <<= aDecodeBuffer; - } - } - } - else if ( aConvertedName == sKeyDerivationElement ) + aString = rConvertedAttribs[sSaltAttribute]; + uno::Sequence < sal_Int8 > aDecodeBuffer; + ::sax::Converter::decodeBase64(aDecodeBuffer, aString); + aSequence[nNumProperty].Name = sSaltProperty; + aSequence[nNumProperty++].Value <<= aDecodeBuffer; + + aString = rConvertedAttribs[sIterationCountAttribute]; + aSequence[nNumProperty].Name = sIterationCountProperty; + aSequence[nNumProperty++].Value <<= aString.toInt32(); + + aString = rConvertedAttribs[sKeySizeAttribute]; + if ( aString.getLength() ) { - if ( !bIgnoreEncryptData ) - { - OUString aString = aConvertedAttribs[sKeyDerivationNameAttribute]; - if ( aString.equals( sPBKDF2_Name ) || aString.equals( sPBKDF2_URL ) ) - { - aString = aConvertedAttribs[sSaltAttribute]; - uno::Sequence < sal_Int8 > aDecodeBuffer; - ::sax::Converter::decodeBase64(aDecodeBuffer, aString); - aSequence[nNumProperty].Name = sSaltProperty; - aSequence[nNumProperty++].Value <<= aDecodeBuffer; - - aString = aConvertedAttribs[sIterationCountAttribute]; - aSequence[nNumProperty].Name = sIterationCountProperty; - aSequence[nNumProperty++].Value <<= aString.toInt32(); - - aString = aConvertedAttribs[sKeySizeAttribute]; - if ( aString.getLength() ) - { - sal_Int32 nKey = aString.toInt32(); - OSL_ENSURE( !nDerivedKeySize || nKey == nDerivedKeySize , "Provided derived key length differs from the expected one!" ); - nDerivedKeySize = nKey; - } - else if ( !nDerivedKeySize ) - nDerivedKeySize = 16; - else if ( nDerivedKeySize != 16 ) - OSL_ENSURE( sal_False, "Default derived key length differs from the expected one!" ); - - aSequence[nNumProperty].Name = sDerivedKeySizeProperty; - aSequence[nNumProperty++].Value <<= nDerivedKeySize; - } - else - bIgnoreEncryptData = sal_True; - } - } - else if ( aConvertedName == sStartKeyAlgElement ) - { - OUString aString = aConvertedAttribs[sStartKeyAlgNameAttribute]; - if ( aString.equals( sSHA256_URL ) ) - { - aSequence[nNumProperty].Name = sStartKeyAlgProperty; - aSequence[nNumProperty++].Value <<= xml::crypto::DigestID::SHA256; - } - else if ( aString.equals( sSHA1_Name ) || aString.equals( sSHA1_URL ) ) - { - aSequence[nNumProperty].Name = sStartKeyAlgProperty; - aSequence[nNumProperty++].Value <<= xml::crypto::DigestID::SHA1; - } - else - bIgnoreEncryptData = sal_True; + sal_Int32 nKey = aString.toInt32(); + OSL_ENSURE( !nDerivedKeySize || nKey == nDerivedKeySize , "Provided derived key length differs from the expected one!" ); + nDerivedKeySize = nKey; } + else if ( !nDerivedKeySize ) + nDerivedKeySize = 16; + else if ( nDerivedKeySize != 16 ) + OSL_ENSURE( sal_False, "Default derived key length differs from the expected one!" ); + + aSequence[nNumProperty].Name = sDerivedKeySizeProperty; + aSequence[nNumProperty++].Value <<= nDerivedKeySize; + } + else + bIgnoreEncryptData = sal_True; + } +} + +void ManifestImport::doStartKeyAlg(StringHashMap &rConvertedAttribs) + throw( uno::RuntimeException ) +{ + OUString aString = rConvertedAttribs[sStartKeyAlgNameAttribute]; + if ( aString.equals( sSHA256_URL ) ) + { + aSequence[nNumProperty].Name = sStartKeyAlgProperty; + aSequence[nNumProperty++].Value <<= xml::crypto::DigestID::SHA256; + } + else if ( aString.equals( sSHA1_Name ) || aString.equals( sSHA1_URL ) ) + { + aSequence[nNumProperty].Name = sStartKeyAlgProperty; + aSequence[nNumProperty++].Value <<= xml::crypto::DigestID::SHA1; + } + else + bIgnoreEncryptData = sal_True; +} + +// --------------------------------------------------- +void SAL_CALL ManifestImport::startElement( const OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs ) + throw( xml::sax::SAXException, uno::RuntimeException ) +{ + StringHashMap aConvertedAttribs; + ::rtl::OUString aConvertedName = PushNameAndNamespaces( aName, xAttribs, aConvertedAttribs ); + + size_t nLevel = aStack.size(); + + assert(nLevel >= 1); + + switch (nLevel) + { + case 1: + { + if (!aConvertedName.equalsAscii(ELEMENT_MANIFEST)) //manifest:manifest + aStack.back().m_bValid = false; + break; + } + case 2: + { + if (aConvertedName == sFileEntryElement) //manifest:file-entry + doFileEntry(aConvertedAttribs); + else + aStack.back().m_bValid = false; + break; + } + case 3: + { + ManifestStack::reverse_iterator aIter = aStack.rbegin(); + ++aIter; + + if (!aIter->m_bValid) + aStack.back().m_bValid = false; + else if (aConvertedName.equals(sEncryptionDataElement)) //manifest:encryption-data + doEncryptionData(aConvertedAttribs); + else + aStack.back().m_bValid = false; + break; + } + case 4: + { + ManifestStack::reverse_iterator aIter = aStack.rbegin(); + ++aIter; + + if (!aIter->m_bValid) + aStack.back().m_bValid = false; + else if (aConvertedName.equals(sAlgorithmElement)) //manifest:algorithm, + doAlgorithm(aConvertedAttribs); + else if (aConvertedName.equals(sKeyDerivationElement)) //manifest:key-derivation, + doKeyDerivation(aConvertedAttribs); + else if (aConvertedName.equals(sStartKeyAlgElement)) //manifest:start-key-generation + doStartKeyAlg(aConvertedAttribs); + else + aStack.back().m_bValid = false; + break; } + default: + aStack.back().m_bValid = false; + break; } } diff --git a/package/source/manifest/ManifestImport.hxx b/package/source/manifest/ManifestImport.hxx index 1c646a7952a6..5681f4598ed4 100644 --- a/package/source/manifest/ManifestImport.hxx +++ b/package/source/manifest/ManifestImport.hxx @@ -46,10 +46,12 @@ struct ManifestScopeEntry { ::rtl::OUString m_aConvertedName; StringHashMap m_aNamespaces; + bool m_bValid; ManifestScopeEntry( const ::rtl::OUString& aConvertedName, const StringHashMap& aNamespaces ) : m_aConvertedName( aConvertedName ) , m_aNamespaces( aNamespaces ) + , m_bValid( true ) {} ~ManifestScopeEntry() @@ -148,6 +150,12 @@ public: throw(::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); virtual void SAL_CALL setDocumentLocator( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XLocator >& xLocator ) throw(::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); +private: + void doFileEntry(StringHashMap &rConvertedAttribs) throw(::com::sun::star::uno::RuntimeException); + void doEncryptionData(StringHashMap &rConvertedAttribs) throw(::com::sun::star::uno::RuntimeException); + void doAlgorithm(StringHashMap &rConvertedAttribs) throw(::com::sun::star::uno::RuntimeException); + void doKeyDerivation(StringHashMap &rConvertedAttribs) throw(::com::sun::star::uno::RuntimeException); + void doStartKeyAlg(StringHashMap &rConvertedAttribs) throw(::com::sun::star::uno::RuntimeException); }; #endif |