/** * 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-2016 Aleksey Sanin . All Rights Reserved. */ #include "globals.h" #include #include #include #include #include #include #include #include #include #include /************************************************************************** * * 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. */ 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); }