xmlsecurityengine/xmlsec/src/xmlsec_enveloped.c
changeset 0 e35f40988205
child 24 74f0b3eb154c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xmlsecurityengine/xmlsec/src/xmlsec_enveloped.c	Thu Dec 17 09:29:21 2009 +0200
@@ -0,0 +1,154 @@
+/** 
+ * XML Security Library (http://www.aleksey.com/xmlsec).
+ *
+ * Enveloped transform.
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ * 
+ * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
+ * Portion Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 
+ */
+#include "xmlsec_globals.h"
+ 
+#include <stdlib.h>
+#include <string.h>
+
+#include <libxml2_tree.h>
+#include <libxml2_xpath.h>
+#include <libxml2_xpathinternals.h>
+
+#include "xmlsec_xmlsec.h"
+#include "xmlsec_xmltree.h"
+#include "xmlsec_keys.h"
+#include "xmlsec_transforms.h"
+#include "xmlsec_errors.h"
+
+/**************************************************************************
+ *
+ *  Enveloped transform 
+ *
+ *************************************************************************/
+static int 	xmlSecTransformEnvelopedExecute		(xmlSecTransformPtr transform,
+							 int last, 
+							 xmlSecTransformCtxPtr transformCtx);
+
+
+static xmlSecTransformKlass xmlSecTransformEnvelopedKlass = {
+    /* klass/object sizes */
+    sizeof(xmlSecTransformKlass),		/* xmlSecSize klassSize */
+    sizeof(xmlSecTransform),			/* xmlSecSize objSize */
+
+    xmlSecNameEnveloped,			/* const xmlChar* name; */  
+    xmlSecHrefEnveloped,			/* const xmlChar* href; */
+    xmlSecTransformUsageDSigTransform,		/* xmlSecTransformUsage	usage; */
+    
+    NULL,					/* xmlSecTransformInitializeMethod initialize; */
+    NULL,					/* xmlSecTransformFinalizeMethod finalize; */
+    NULL,					/* xmlSecTransformNodeReadMethod readNode; */
+    NULL,					/* xmlSecTransformNodeWriteMethod writeNode; */    
+    NULL,					/* xmlSecTransformSetKeyReqMethod setKeyReq; */
+    NULL,					/* xmlSecTransformSetKeyMethod setKey; */
+    NULL,					/* xmlSecTransformValidateMethod validate; */
+    xmlSecTransformDefaultGetDataType,		/* xmlSecTransformGetDataTypeMethod getDataType; */
+    NULL,					/* xmlSecTransformPushBinMethod pushBin; */
+    NULL,					/* xmlSecTransformPopBinMethod popBin; */
+    xmlSecTransformDefaultPushXml,		/* xmlSecTransformPushXmlMethod pushXml; */
+    xmlSecTransformDefaultPopXml,		/* xmlSecTransformPopXmlMethod popXml; */
+    xmlSecTransformEnvelopedExecute,		/* xmlSecTransformExecuteMethod execute; */
+
+    NULL,					/* void* reserved0; */
+    NULL,					/* void* reserved1; */
+};
+
+/**
+ * xmlSecTransformEnvelopedGetKlass:
+ *
+ * The enveloped transform klass (http://www.w3.org/TR/xmldsig-core/#sec-EnvelopedSignature):
+ *
+ * An enveloped signature transform T removes the whole Signature element 
+ * containing T from the digest calculation of the Reference element 
+ * containing T. The entire string of characters used by an XML processor 
+ * to match the Signature with the XML production element is removed. 
+ * The output of the transform is equivalent to the output that would 
+ * result from replacing T with an XPath transform containing the following 
+ * XPath parameter element:
+ *
+ * <XPath xmlns:dsig="&dsig;">
+ *   count(ancestor-or-self::dsig:Signature |
+ *   here()/ancestor::dsig:Signature[1]) >
+ *   count(ancestor-or-self::dsig:Signature)</XPath>
+ *    
+ * The input and output requirements of this transform are identical to 
+ * those of the XPath transform, but may only be applied to a node-set from 
+ * its parent XML document. Note that it is not necessary to use an XPath 
+ * expression evaluator to create this transform. However, this transform 
+ * MUST produce output in exactly the same manner as the XPath transform 
+ * parameterized by the XPath expression above.
+ *
+ * Returns enveloped transform id.
+ */
+EXPORT_C
+xmlSecTransformId 
+xmlSecTransformEnvelopedGetKlass(void) {
+    return(&xmlSecTransformEnvelopedKlass);
+}
+
+static int
+xmlSecTransformEnvelopedExecute(xmlSecTransformPtr transform, int last, 
+				 xmlSecTransformCtxPtr transformCtx) {
+    xmlNodePtr node;
+    xmlSecNodeSetPtr children;
+
+    xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformEnvelopedId), -1);
+    xmlSecAssert2(transform->hereNode != NULL, -1);
+    xmlSecAssert2(transform->outNodes == NULL, -1);
+    xmlSecAssert2(last != 0, -1);
+    xmlSecAssert2(transformCtx != NULL, -1);
+    
+    if((transform->inNodes != NULL) && (transform->inNodes->doc != transform->hereNode->doc)) {
+	xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+		    NULL,
+		    XMLSEC_ERRORS_R_TRANSFORM_SAME_DOCUMENT_REQUIRED,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+	return(-1);
+    }
+    
+    /* find signature node and get all its children in the nodes set */
+    node = xmlSecFindParent(transform->hereNode, xmlSecNodeSignature, xmlSecDSigNs);
+    if(node == NULL) {
+	xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+		    xmlSecErrorsSafeString(xmlSecNodeSignature),
+		    XMLSEC_ERRORS_R_NODE_NOT_FOUND,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+	return(-1);
+    }
+    
+    children = xmlSecNodeSetGetChildren(node->doc, node, 1, 1);
+    if(children == NULL) {
+	xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+		    "xmlSecNodeSetGetChildren",
+		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+		    "node=%s",
+		    xmlSecErrorsSafeString(xmlSecNodeGetName(node)));
+	return(-1);
+    }
+
+    /* intersect <dsig:Signature/> node children with input nodes (if exist) */
+    transform->outNodes = xmlSecNodeSetAdd(transform->inNodes, children, xmlSecNodeSetIntersection);
+    if(transform->outNodes == NULL) {
+	xmlSecError(XMLSEC_ERRORS_HERE,
+		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+		    "xmlSecNodeSetAdd",		    
+		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+	xmlSecNodeSetDestroy(children);
+	return(-1);
+    }
+    
+    return(0);
+}
+