diff -r 000000000000 -r e35f40988205 xmlsecurityengine/xmlsec/src/xmlsec_enveloped.c --- /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 + * Portion Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. + */ +#include "xmlsec_globals.h" + +#include +#include + +#include +#include +#include + +#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: + * + * + * count(ancestor-or-self::dsig:Signature | + * here()/ancestor::dsig:Signature[1]) > + * count(ancestor-or-self::dsig:Signature) + * + * 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 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); +} +