diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-01-25 15:34:38 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-01-25 18:26:16 +0100 |
commit | 0dac6d1f179c286dd7aea2d9ef7c37db8323fa37 (patch) | |
tree | 06d7e6fcc0de4747f93da7153b45aa624b4f5bb1 | |
parent | 7b6fdcd83b14a271061b70d43273d5c6cf0bb43c (diff) |
xmlsecurity: implement OOXML stream references
With this, if see an URI like:
/_rels/.rels?ContentType=application/vnd.openxmlformats-package.relationships+xml
Then it is properly detected that it's the .rels stream of the _rels
storage, and UriBindingHelper will serve that stream (when looked up by
name later) to libxmlsec.
Change-Id: Iac62cb170c0aa8bb92c40311fb7b248e96c25dde
-rw-r--r-- | xmlsecurity/source/helper/ooxmlsecparser.cxx | 27 | ||||
-rw-r--r-- | xmlsecurity/source/helper/ooxmlsecparser.hxx | 4 | ||||
-rw-r--r-- | xmlsecurity/source/helper/xmlsignaturehelper2.cxx | 22 | ||||
-rw-r--r-- | xmlsecurity/source/helper/xsecctl.hxx | 1 |
4 files changed, 47 insertions, 7 deletions
diff --git a/xmlsecurity/source/helper/ooxmlsecparser.cxx b/xmlsecurity/source/helper/ooxmlsecparser.cxx index 4bc7274b783b..4c930d18ea21 100644 --- a/xmlsecurity/source/helper/ooxmlsecparser.cxx +++ b/xmlsecurity/source/helper/ooxmlsecparser.cxx @@ -19,6 +19,7 @@ OOXMLSecParser::OOXMLSecParser(XSecController* pXSecController) ,m_bInX509Certificate(false) ,m_bInMdssiValue(false) ,m_bInSignatureComments(false) + ,m_bReferenceUnresolved(false) { } @@ -56,7 +57,23 @@ throw (xml::sax::SAXException, uno::RuntimeException, std::exception) OUString aURI = xAttribs->getValueByName("URI"); if (aURI.startsWith("#")) m_pXSecController->addReference(aURI.copy(1)); - // TODO else + else + { + m_aReferenceURI = aURI; + m_bReferenceUnresolved = true; + } + } + else if (rName == "Transform") + { + if (m_bReferenceUnresolved) + { + OUString aAlgorithm = xAttribs->getValueByName("Algorithm"); + if (aAlgorithm == ALGO_RELATIONSHIP) + { + m_pXSecController->addStreamReference(m_aReferenceURI, /*isBinary=*/false); + m_bReferenceUnresolved = false; + } + } } else if (rName == "DigestValue") { @@ -93,7 +110,15 @@ void SAL_CALL OOXMLSecParser::endElement(const OUString& rName) throw (xml::sax: if (rName == "SignedInfo") m_pXSecController->setReferenceCount(); else if (rName == "Reference") + { + if (m_bReferenceUnresolved) + { + // No transform algorithm found, assume binary. + m_pXSecController->addStreamReference(m_aReferenceURI, /*isBinary=*/true); + m_bReferenceUnresolved = false; + } m_pXSecController->setDigestValue(m_aDigestValue); + } else if (rName == "DigestValue") m_bInDigestValue = false; else if (rName == "SignatureValue") diff --git a/xmlsecurity/source/helper/ooxmlsecparser.hxx b/xmlsecurity/source/helper/ooxmlsecparser.hxx index c7ac95368392..73ac0b22be97 100644 --- a/xmlsecurity/source/helper/ooxmlsecparser.hxx +++ b/xmlsecurity/source/helper/ooxmlsecparser.hxx @@ -39,6 +39,10 @@ class OOXMLSecParser: public cppu::WeakImplHelper OUString m_aMdssiValue; bool m_bInSignatureComments; OUString m_aSignatureComments; + /// Last seen <Reference URI="...">. + OUString m_aReferenceURI; + /// Already called addStreamReference() for this reference. + bool m_bReferenceUnresolved; public: OOXMLSecParser(XSecController* pXSecController); diff --git a/xmlsecurity/source/helper/xmlsignaturehelper2.cxx b/xmlsecurity/source/helper/xmlsignaturehelper2.cxx index 40407d586a06..89f6bbc75b65 100644 --- a/xmlsecurity/source/helper/xmlsignaturehelper2.cxx +++ b/xmlsecurity/source/helper/xmlsignaturehelper2.cxx @@ -184,14 +184,19 @@ uno::Reference < io::XInputStream > UriBindingHelper::OpenInputStream( const uno OSL_ASSERT(!rURI.isEmpty()); uno::Reference < io::XInputStream > xInStream; - sal_Int32 nSepPos = rURI.indexOf( '/' ); + OUString aURI(rURI); + // Ignore leading slash, don't attempt to open a storage with name "". + if (aURI.startsWith("/")) + aURI = aURI.copy(1); + + sal_Int32 nSepPos = aURI.indexOf( '/' ); if ( nSepPos == -1 ) { // Cloning because of I can't keep all storage references open // MBA with think about a better API... const OUString sName = ::rtl::Uri::decode( - rURI, rtl_UriDecodeStrict, rtl_UriCharClassRelSegment); - if (sName.isEmpty() && !rURI.isEmpty()) + aURI, rtl_UriDecodeStrict, rtl_UriCharClassRelSegment); + if (sName.isEmpty() && !aURI.isEmpty()) throw uno::Exception("Could not decode URI for stream element.", nullptr); uno::Reference< io::XStream > xStream; @@ -202,12 +207,17 @@ uno::Reference < io::XInputStream > UriBindingHelper::OpenInputStream( const uno } else { + // Ignore query part of the URI. + sal_Int32 nQueryPos = aURI.indexOf('?'); + if (nQueryPos != -1) + aURI = aURI.copy(0, nQueryPos); + const OUString aStoreName = ::rtl::Uri::decode( - rURI.copy( 0, nSepPos ), rtl_UriDecodeStrict, rtl_UriCharClassRelSegment); - if (aStoreName.isEmpty() && !rURI.isEmpty()) + aURI.copy( 0, nSepPos ), rtl_UriDecodeStrict, rtl_UriCharClassRelSegment); + if (aStoreName.isEmpty() && !aURI.isEmpty()) throw uno::Exception("Could not decode URI for stream element.", nullptr); - OUString aElement = rURI.copy( nSepPos+1 ); + OUString aElement = aURI.copy( nSepPos+1 ); uno::Reference < embed::XStorage > xSubStore = rxStore->openStorageElement( aStoreName, embed::ElementModes::READ ); xInStream = OpenInputStream( xSubStore, aElement ); } diff --git a/xmlsecurity/source/helper/xsecctl.hxx b/xmlsecurity/source/helper/xsecctl.hxx index b48b8cd5df27..769e6b2703ef 100644 --- a/xmlsecurity/source/helper/xsecctl.hxx +++ b/xmlsecurity/source/helper/xsecctl.hxx @@ -96,6 +96,7 @@ #define ALGO_C14N "http://www.w3.org/TR/2001/REC-xml-c14n-20010315" #define ALGO_RSASHA1 "http://www.w3.org/2000/09/xmldsig#rsa-sha1" #define ALGO_XMLDSIGSHA1 "http://www.w3.org/2000/09/xmldsig#sha1" +#define ALGO_RELATIONSHIP "http://schemas.openxmlformats.org/package/2006/RelationshipTransform" #define CHAR_FRAGMENT "#" #define CHAR_BLANK " " |