[Libreoffice-commits] core.git: 2 commits - external/libxmlsec xmlsecurity/source
Miklos Vajna
vmiklos at collabora.co.uk
Mon Jan 25 09:27:15 PST 2016
external/libxmlsec/xmlsec1-ooxml.patch.1 | 248 ++++++++++++++++++++--
xmlsecurity/source/helper/ooxmlsecparser.cxx | 27 ++
xmlsecurity/source/helper/ooxmlsecparser.hxx | 4
xmlsecurity/source/helper/xmlsignaturehelper2.cxx | 22 +
xmlsecurity/source/helper/xsecctl.hxx | 1
5 files changed, 273 insertions(+), 29 deletions(-)
New commits:
commit 937eb672f43fd26cea5f7dcf559f9ed3f662b804
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Mon Jan 25 18:08:18 2016 +0100
libxmlsec: canonize in the OOXML RelationshipTransform
This is still a skeleton, but now we canonize the incoming data, not just
eat it and output nothing -> at the end we don't hit an assertion that
the output of the transform chain is nothing.
Change-Id: I28509b8a493c6bf6cdcbb23b95ae7de8947790c1
diff --git a/external/libxmlsec/xmlsec1-ooxml.patch.1 b/external/libxmlsec/xmlsec1-ooxml.patch.1
index 8a1dbe3..af92fbb 100644
--- a/external/libxmlsec/xmlsec1-ooxml.patch.1
+++ b/external/libxmlsec/xmlsec1-ooxml.patch.1
@@ -1,15 +1,15 @@
-From b7fb2699e3c383ae40f29369dc57afbd0d52004c Mon Sep 17 00:00:00 2001
+From 1770428d30a77e7c5e3344687369d83e04201f0b Mon Sep 17 00:00:00 2001
From: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Mon, 25 Jan 2016 09:50:03 +0100
Subject: [PATCH] OOXML Relationship Transform skeleton
---
- include/xmlsec/strings.h | 3 ++
- include/xmlsec/transforms.h | 4 +++
- src/strings.c | 3 ++
- src/transforms.c | 11 ++++++
- src/xpath.c | 82 +++++++++++++++++++++++++++++++++++++++++++++
- 5 files changed, 103 insertions(+)
+ include/xmlsec/strings.h | 3 +
+ include/xmlsec/transforms.h | 4 +
+ src/strings.c | 3 +
+ src/transforms.c | 11 ++
+ src/xpath.c | 279 ++++++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 300 insertions(+)
diff --git a/include/xmlsec/strings.h b/include/xmlsec/strings.h
index 07afb9d..9c72d1b 100644
@@ -77,10 +77,18 @@ index 2ed3fe8..9e5ad27 100644
if(xmlSecTransformIdsRegister(xmlSecTransformXsltId) < 0) {
xmlSecError(XMLSEC_ERRORS_HERE,
diff --git a/src/xpath.c b/src/xpath.c
-index 8b0b4f8..63b02d4 100644
+index 8b0b4f8..ddcd95d 100644
--- a/src/xpath.c
+++ b/src/xpath.c
-@@ -1144,5 +1144,87 @@ xmlSecTransformVisa3DHackExecute(xmlSecTransformPtr transform, int last,
+@@ -17,6 +17,7 @@
+ #include <libxml/xpath.h>
+ #include <libxml/xpathInternals.h>
+ #include <libxml/xpointer.h>
++#include <libxml/c14n.h>
+
+ #include <xmlsec/xmlsec.h>
+ #include <xmlsec/xmltree.h>
+@@ -1144,5 +1145,283 @@ xmlSecTransformVisa3DHackExecute(xmlSecTransformPtr transform, int last,
return(0);
}
@@ -95,8 +103,8 @@ index 8b0b4f8..63b02d4 100644
+
+static int xmlSecRelationshipInitialize (xmlSecTransformPtr transform);
+static void xmlSecRelationshipFinalize (xmlSecTransformPtr transform);
-+static int xmlSecRelationshipReadNode (xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransformCtxPtr transformCtx);
-+static int xmlSecRelationshipExecute (xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx);
++static int xmlSecTransformRelationshipPopBin(xmlSecTransformPtr transform, xmlSecByte* data, xmlSecSize maxDataSize, xmlSecSize* dataSize, xmlSecTransformCtxPtr transformCtx);
++static int xmlSecTransformRelationshipPushXml(xmlSecTransformPtr transform, xmlSecNodeSetPtr nodes, xmlSecTransformCtxPtr transformCtx);
+
+static xmlSecTransformKlass xmlSecRelationshipKlass =
+{
@@ -108,17 +116,17 @@ index 8b0b4f8..63b02d4 100644
+ xmlSecTransformUsageDSigTransform, /* xmlSecAlgorithmUsage usage; */
+ xmlSecRelationshipInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecRelationshipFinalize, /* xmlSecTransformFinalizeMethod finalize; */
-+ xmlSecRelationshipReadNode, /* xmlSecTransformNodeReadMethod readNode; */
++ NULL, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+ NULL, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
+ NULL, /* xmlSecTransformSetKeyMethod setKey; */
+ NULL, /* xmlSecTransformValidateMethod validate; */
+ xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
-+ xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
-+ xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
-+ NULL, /* xmlSecTransformPushXmlMethod pushXml; */
++ NULL, /* xmlSecTransformPushBinMethod pushBin; */
++ xmlSecTransformRelationshipPopBin, /* xmlSecTransformPopBinMethod popBin; */
++ xmlSecTransformRelationshipPushXml, /* xmlSecTransformPushXmlMethod pushXml; */
+ NULL, /* xmlSecTransformPopXmlMethod popXml; */
-+ xmlSecRelationshipExecute, /* xmlSecTransformExecuteMethod execute; */
++ NULL, /* xmlSecTransformExecuteMethod execute; */
+ NULL, /* void* reserved0; */
+ NULL, /* void* reserved1; */
+};
@@ -137,7 +145,7 @@ index 8b0b4f8..63b02d4 100644
+
+ ctx = xmlSecRelationshipGetCtx(transform);
+ xmlSecAssert2(ctx != NULL, -1);
-
++
+ /* initialize context */
+ memset(ctx, 0, sizeof(xmlSecRelationshipCtx));
+ return 0;
@@ -155,18 +163,214 @@ index 8b0b4f8..63b02d4 100644
+
+ if (ctx->parserCtx != NULL)
+ xmlFreeParserCtxt(ctx->parserCtx);
-
++
+ memset(ctx, 0, sizeof(xmlSecRelationshipCtx));
+}
+
-+static int xmlSecRelationshipReadNode(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransformCtxPtr transformCtx)
++static int xmlSecTransformRelationshipPushXml(xmlSecTransformPtr transform, xmlSecNodeSetPtr nodes, xmlSecTransformCtxPtr transformCtx)
+{
-+ return 0;
++ xmlOutputBufferPtr buf;
++ int ret;
++
++ xmlSecAssert2(nodes != NULL, -1);
++ xmlSecAssert2(nodes->doc != NULL, -1);
++ xmlSecAssert2(transformCtx != NULL, -1);
++
++ /* check/update current transform status */
++ switch(transform->status)
++ {
++ case xmlSecTransformStatusNone:
++ transform->status = xmlSecTransformStatusWorking;
++ break;
++ case xmlSecTransformStatusWorking:
++ case xmlSecTransformStatusFinished:
++ return(0);
++ default:
++ xmlSecError(XMLSEC_ERRORS_HERE,
++ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
++ NULL,
++ XMLSEC_ERRORS_R_INVALID_STATUS,
++ "status=%d", transform->status);
++ return(-1);
++ }
++ xmlSecAssert2(transform->status == xmlSecTransformStatusWorking, -1);
++
++ /* prepare output buffer: next transform or ourselves */
++ if(transform->next != NULL)
++ {
++ buf = xmlSecTransformCreateOutputBuffer(transform->next, transformCtx);
++ if(buf == NULL)
++ {
++ xmlSecError(XMLSEC_ERRORS_HERE,
++ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
++ "xmlSecTransformCreateOutputBuffer",
++ XMLSEC_ERRORS_R_XMLSEC_FAILED,
++ XMLSEC_ERRORS_NO_MESSAGE);
++ return(-1);
++ }
++ } else
++ {
++ buf = xmlSecBufferCreateOutputBuffer(&(transform->outBuf));
++ if (buf == NULL)
++ {
++ xmlSecError(XMLSEC_ERRORS_HERE,
++ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
++ "xmlSecBufferCreateOutputBuffer",
++ XMLSEC_ERRORS_R_XMLSEC_FAILED,
++ XMLSEC_ERRORS_NO_MESSAGE);
++ return(-1);
++ }
++ }
+
++ ret = xmlC14NExecute(nodes->doc, (xmlC14NIsVisibleCallback)xmlSecNodeSetContains, nodes, XML_C14N_1_0, NULL, 0, buf);
++ if (ret < 0)
++ {
++ xmlSecError(XMLSEC_ERRORS_HERE,
++ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
++ "xmlC14NExecute",
++ XMLSEC_ERRORS_R_XMLSEC_FAILED,
++ XMLSEC_ERRORS_NO_MESSAGE);
++ xmlOutputBufferClose(buf);
++ return(-1);
++ }
+
++ ret = xmlOutputBufferClose(buf);
++ if (ret < 0)
++ {
++ xmlSecError(XMLSEC_ERRORS_HERE,
++ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
++ "xmlOutputBufferClose",
++ XMLSEC_ERRORS_R_XML_FAILED,
++ XMLSEC_ERRORS_NO_MESSAGE);
++ return(-1);
++ }
++ transform->status = xmlSecTransformStatusFinished;
++ return(0);
+}
+
-+static int xmlSecRelationshipExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx)
++static int xmlSecTransformRelationshipPopBin(xmlSecTransformPtr transform, xmlSecByte* data, xmlSecSize maxDataSize, xmlSecSize* dataSize, xmlSecTransformCtxPtr transformCtx)
+{
-+ return 0;
++ xmlSecBufferPtr out;
++ int ret;
++
++ xmlSecAssert2(data != NULL, -1);
++ xmlSecAssert2(dataSize != NULL, -1);
++ xmlSecAssert2(transformCtx != NULL, -1);
++
++ out = &(transform->outBuf);
++ if (transform->status == xmlSecTransformStatusNone)
++ {
++ xmlOutputBufferPtr buf;
++
++ xmlSecAssert2(transform->inNodes == NULL, -1);
++
++ /* todo: isn't it an error? */
++ if (transform->prev == NULL)
++ {
++ (*dataSize) = 0;
++ transform->status = xmlSecTransformStatusFinished;
++ return(0);
++ }
++
++ /* get xml data from previous transform */
++ ret = xmlSecTransformPopXml(transform->prev, &(transform->inNodes), transformCtx);
++ if (ret < 0)
++ {
++ xmlSecError(XMLSEC_ERRORS_HERE,
++ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
++ "xmlSecTransformPopXml",
++ XMLSEC_ERRORS_R_XMLSEC_FAILED,
++ XMLSEC_ERRORS_NO_MESSAGE);
++ return(-1);
++ }
++
++ /* dump everything to internal buffer */
++ buf = xmlSecBufferCreateOutputBuffer(out);
++ if (buf == NULL)
++ {
++ xmlSecError(XMLSEC_ERRORS_HERE,
++ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
++ "xmlSecBufferCreateOutputBuffer",
++ XMLSEC_ERRORS_R_XMLSEC_FAILED,
++ XMLSEC_ERRORS_NO_MESSAGE);
++ return(-1);
++ }
++
++ ret = xmlC14NExecute(transform->inNodes->doc, (xmlC14NIsVisibleCallback)xmlSecNodeSetContains, transform->inNodes, XML_C14N_1_0, NULL, 0, buf);
++ if (ret < 0)
++ {
++ xmlSecError(XMLSEC_ERRORS_HERE,
++ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
++ "xmlSecTransformC14NExecute",
++ XMLSEC_ERRORS_R_XMLSEC_FAILED,
++ XMLSEC_ERRORS_NO_MESSAGE);
++ xmlOutputBufferClose(buf);
++ return(-1);
++ }
++ ret = xmlOutputBufferClose(buf);
++ if (ret < 0)
++ {
++ xmlSecError(XMLSEC_ERRORS_HERE,
++ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
++ "xmlOutputBufferClose",
++ XMLSEC_ERRORS_R_XML_FAILED,
++ XMLSEC_ERRORS_NO_MESSAGE);
++ return(-1);
++ }
++ transform->status = xmlSecTransformStatusWorking;
++ }
++
++ if (transform->status == xmlSecTransformStatusWorking)
++ {
++ xmlSecSize outSize;
++
++ /* return chunk after chunk */
++ outSize = xmlSecBufferGetSize(out);
++ if (outSize > maxDataSize)
++ {
++ outSize = maxDataSize;
++ }
++ if (outSize > XMLSEC_TRANSFORM_BINARY_CHUNK)
++ {
++ outSize = XMLSEC_TRANSFORM_BINARY_CHUNK;
++ }
++ if (outSize > 0)
++ {
++ xmlSecAssert2(xmlSecBufferGetData(&(transform->outBuf)), -1);
++
++ memcpy(data, xmlSecBufferGetData(&(transform->outBuf)), outSize);
++ ret = xmlSecBufferRemoveHead(&(transform->outBuf), outSize);
++ if (ret < 0)
++ {
++ xmlSecError(XMLSEC_ERRORS_HERE,
++ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
++ "xmlSecBufferRemoveHead",
++ XMLSEC_ERRORS_R_XMLSEC_FAILED,
++ "size=%d", outSize);
++ return(-1);
++ }
++ }
++ else if (xmlSecBufferGetSize(out) == 0)
++ transform->status = xmlSecTransformStatusFinished;
++ (*dataSize) = outSize;
++ }
++ else if (transform->status == xmlSecTransformStatusFinished)
++ {
++ /* the only way we can get here is if there is no output */
++ xmlSecAssert2(xmlSecBufferGetSize(out) == 0, -1);
++ (*dataSize) = 0;
++ }
++ else
++ {
++ xmlSecError(XMLSEC_ERRORS_HERE,
++ xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
++ NULL,
++ XMLSEC_ERRORS_R_INVALID_STATUS,
++ "status=%d", transform->status);
++ return(-1);
++ }
++
++ return(0);
+}
--
2.6.2
commit 0dac6d1f179c286dd7aea2d9ef7c37db8323fa37
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Mon Jan 25 15:34:38 2016 +0100
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
diff --git a/xmlsecurity/source/helper/ooxmlsecparser.cxx b/xmlsecurity/source/helper/ooxmlsecparser.cxx
index 4bc7274..4c930d1 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 c7ac953..73ac0b2 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 40407d5..89f6bbc 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 b48b8cd..769e6b2 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 " "
More information about the Libreoffice-commits
mailing list