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 <vmik...@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 <vmik...@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 <vmik...@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          " "
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to