I attached the patch that allows the replaced nodes during encryption
and decryption to be returned in the 'xmlSecEncCtxPtr' structure.
Actually, I added two entries in the 'xmlSecEncCtrPtr' structure :
- nodeReplacementMode, an enum of type
'xmlEncCtxNodeReplacementMode', to define if the nodes will be released
or returned in the second entry,
- a pointer to a xmlNodePtr called 'replacedNodeList' that contains
the list of the nodes that have been replaced.
One additional point, as it's up to the user to release the returned
nodes, I'm not sure if the code I added in the 'xmlSecEncCtxReset'
function to release the node list is necessary, because if someone
releases the node but forget to set the pointer to NULL it will crash.
But if he doesn't release the nodes, and this code is not there we got a
memory leak.
If you could take a look
Thanks,
Frank
Aleksey Sanin a écrit :
Sure, I love patches :) BTW, you can't find any docs about
flags/flags2 in xmlSecEncCtx because they are not used at the moment :)
Just reserved for the future :)
Aleksey
Frank Gross wrote:
Yes I agree, but it would be more efficient if I wouldn't have to do
that. And I have the same problem when I try to encrypt only the
content of an element, where all sub-nodes are removed. Actually, I
try to write an API where you give the node to be encrypted, but the
node passed to my function is still alive, and simply destroying the
nodes inside the library is impossible in my case, because some other
references can point on these nodes.
Therefore may I suggest a request ? Could you add an option in the
'xmlSecEncCtxPtr' structure to specify how the nodes to be replaced
should be handled, and return them in a list in the structure if for
instance the option was set to not releasing them so that the user
can choose to release them by hand or not. And the same kind of
feature when decrypting a node, because in some cases you want to
keep trace of the encrypted node.
My 2 cents contribution that could really help in my case, and allow
the programmer to choose instead of the library.
If you agree I could make a patch, using flags or flags2 in the
'xmlSecEncCtxPtr' structure, and add a new entry of type xmlNodePtr
with the list of nodes that were replaced but not released according
to flags or flags2 value. BTW what is the difference between flags
and flags2 ? Are they used because I didn't find any information in
the documentation ?
Best Regards,
Frank
Aleksey Sanin a écrit :
Well, you can always copy the node yourself before encrypting it.
Aleksey
Frank Gross wrote:
Hi,
I noticed that function 'xmlSecEncCtxXmlEncrypt' releases the node
that was encrypted when replaced by the 'EncryptedData' node.
Does it exist a way to not release that node, and let the user
choose whether he wants to destroy it or not ?
Thanks,
Frank
_______________________________________________
xmlsec mailing list
[email protected]
http://www.aleksey.com/mailman/listinfo/xmlsec
_______________________________________________
xmlsec mailing list
[email protected]
http://www.aleksey.com/mailman/listinfo/xmlsec
diff --exclude-from=./exclude -rc xmlsec1-1.2.11/include/xmlsec/xmlenc.h 1.2.11/src/include/xmlsec/xmlenc.h
*** xmlsec1-1.2.11/include/xmlsec/xmlenc.h Thu Mar 6 18:55:32 2008
--- 1.2.11/src/include/xmlsec/xmlenc.h Thu Mar 13 16:15:18 2008
***************
*** 42,53 ****
--- 42,67 ----
} xmlEncCtxMode;
/**
+ * xmlEncCtxNodeReplacementMode:
+ * @xmlEncCtxNodeRelease: the nodes are released
+ * @xmlEncCtxNodeKeep: the nodes are kept and located in the replacedNodeList
+ *
+ * The #xmlEncCtxNodeReplacementMode mode.
+ */
+ typedef enum {
+ xmlEncCtxNodeRelease = 0,
+ xmlEncCtxNodeKeep
+ } xmlEncCtxNodeReplacementMode;
+
+ /**
* xmlSecEncCtx:
* @userData: the pointer to user data (xmlsec and xmlsec-crypto libraries
* never touches this).
* @flags: the XML Encryption processing flags.
* @flags2: the XML Encryption processing flags.
* @mode: the mode.
+ * @nodeReplacementMode: whether the node replaced during encryption or decryption
+ are kept or released
* @keyInfoReadCtx: the reading key context.
* @keyInfoWriteCtx: the writing key context (not used for signature verification).
* @transformCtx: the transforms processing context.
***************
*** 61,66 ****
--- 75,81 ----
* @resultReplaced: the flag: if set then resulted <enc:EncryptedData/>
* or <enc:EncryptedKey/> node is added to the document.
* @encMethod: the pointer to encryption transform.
+ * @replacedNodeList: the first node of the list of replaced nodes depending on the nodeReplacementMode
* @id: the ID attribute of <enc:EncryptedData/>
* or <enc:EncryptedKey/> node.
* @type: the Type attribute of <enc:EncryptedData/>
***************
*** 87,92 ****
--- 102,108 ----
unsigned int flags;
unsigned int flags2;
xmlEncCtxMode mode;
+ xmlEncCtxNodeReplacementMode nodeReplacementMode;
xmlSecKeyInfoCtx keyInfoReadCtx;
xmlSecKeyInfoCtx keyInfoWriteCtx;
xmlSecTransformCtx transformCtx;
***************
*** 99,105 ****
int resultBase64Encoded;
int resultReplaced;
xmlSecTransformPtr encMethod;
!
/* attributes from EncryptedData or EncryptedKey */
xmlChar* id;
xmlChar* type;
--- 115,122 ----
int resultBase64Encoded;
int resultReplaced;
xmlSecTransformPtr encMethod;
! xmlNodePtr replacedNodeList;
!
/* attributes from EncryptedData or EncryptedKey */
xmlChar* id;
xmlChar* type;
diff --exclude-from=./exclude -rc xmlsec1-1.2.11/include/xmlsec/xmltree.h 1.2.11/src/include/xmlsec/xmltree.h
*** xmlsec1-1.2.11/include/xmlsec/xmltree.h Thu Mar 6 18:55:32 2008
--- 1.2.11/src/include/xmlsec/xmltree.h Thu Mar 13 16:15:18 2008
***************
*** 55,66 ****
const xmlChar *ns);
XMLSEC_EXPORT int xmlSecReplaceNode (xmlNodePtr node,
! xmlNodePtr newNode);
XMLSEC_EXPORT int xmlSecReplaceContent (xmlNodePtr node,
! xmlNodePtr newNode);
XMLSEC_EXPORT int xmlSecReplaceNodeBuffer (xmlNodePtr node,
const xmlSecByte *buffer,
! xmlSecSize size);
XMLSEC_EXPORT void xmlSecAddIDs (xmlDocPtr doc,
xmlNodePtr cur,
--- 55,69 ----
const xmlChar *ns);
XMLSEC_EXPORT int xmlSecReplaceNode (xmlNodePtr node,
! xmlNodePtr newNode,
! xmlNodePtr* replaced);
XMLSEC_EXPORT int xmlSecReplaceContent (xmlNodePtr node,
! xmlNodePtr newNode,
! xmlNodePtr* replaced);
XMLSEC_EXPORT int xmlSecReplaceNodeBuffer (xmlNodePtr node,
const xmlSecByte *buffer,
! xmlSecSize size,
! xmlNodePtr* replaced);
XMLSEC_EXPORT void xmlSecAddIDs (xmlDocPtr doc,
xmlNodePtr cur,
diff --exclude-from=./exclude -rc xmlsec1-1.2.11/src/templates.c 1.2.11/src/src/templates.c
*** xmlsec1-1.2.11/src/templates.c Thu Mar 6 18:55:36 2008
--- 1.2.11/src/src/templates.c Thu Mar 13 16:15:16 2008
***************
*** 1860,1866 ****
return(-1);
}
! ret = xmlSecReplaceContent(transformNode, xmlDocGetRootElement(xsltDoc));
if(ret < 0) {
xmlSecError(XMLSEC_ERRORS_HERE,
NULL,
--- 1860,1866 ----
return(-1);
}
! ret = xmlSecReplaceContent(transformNode, xmlDocGetRootElement(xsltDoc),NULL);
if(ret < 0) {
xmlSecError(XMLSEC_ERRORS_HERE,
NULL,
diff --exclude-from=./exclude -rc xmlsec1-1.2.11/src/xmlenc.c 1.2.11/src/src/xmlenc.c
*** xmlsec1-1.2.11/src/xmlenc.c Thu Mar 6 18:55:36 2008
--- 1.2.11/src/src/xmlenc.c Thu Mar 13 16:22:26 2008
***************
*** 192,197 ****
--- 192,202 ----
encCtx->resultBase64Encoded = 0;
encCtx->resultReplaced = 0;
encCtx->encMethod = NULL;
+ if (encCtx->replacedNodeList) {
+ /* should this by done there or is it up to the user to release the nodes ? */
+ xmlFreeNodeList(encCtx->replacedNodeList);
+ encCtx->replacedNodeList = NULL;
+ }
if(encCtx->encKey != NULL) {
xmlSecKeyDestroy(encCtx->encKey);
encCtx->encKey = NULL;
***************
*** 247,252 ****
--- 252,258 ----
dst->flags2 = src->flags2;
dst->defEncMethodId = src->defEncMethodId;
dst->mode = src->mode;
+ dst->nodeReplacementMode = src->nodeReplacementMode;
ret = xmlSecTransformCtxCopyUserPref(&(dst->transformCtx), &(src->transformCtx));
if(ret < 0) {
***************
*** 450,456 ****
/* now we need to update our original document */
if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncElement)) {
! ret = xmlSecReplaceNode(node, tmpl);
if(ret < 0) {
xmlSecError(XMLSEC_ERRORS_HERE,
NULL,
--- 456,462 ----
/* now we need to update our original document */
if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncElement)) {
! ret = xmlSecReplaceNode(node, tmpl,(encCtx->nodeReplacementMode==xmlEncCtxNodeRelease?NULL:&(encCtx->replacedNodeList)));
if(ret < 0) {
xmlSecError(XMLSEC_ERRORS_HERE,
NULL,
***************
*** 462,468 ****
}
encCtx->resultReplaced = 1;
} else if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncContent)) {
! ret = xmlSecReplaceContent(node, tmpl);
if(ret < 0) {
xmlSecError(XMLSEC_ERRORS_HERE,
NULL,
--- 468,474 ----
}
encCtx->resultReplaced = 1;
} else if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncContent)) {
! ret = xmlSecReplaceContent(node, tmpl,(encCtx->nodeReplacementMode==xmlEncCtxNodeRelease?NULL:&(encCtx->replacedNodeList)));
if(ret < 0) {
xmlSecError(XMLSEC_ERRORS_HERE,
NULL,
***************
*** 589,595 ****
/* replace original node if requested */
if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncElement)) {
! ret = xmlSecReplaceNodeBuffer(node, xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer));
if(ret < 0) {
xmlSecError(XMLSEC_ERRORS_HERE,
NULL,
--- 595,601 ----
/* replace original node if requested */
if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncElement)) {
! ret = xmlSecReplaceNodeBuffer(node, xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer),(encCtx->nodeReplacementMode==xmlEncCtxNodeRelease?NULL:&(encCtx->replacedNodeList)));
if(ret < 0) {
xmlSecError(XMLSEC_ERRORS_HERE,
NULL,
***************
*** 602,608 ****
encCtx->resultReplaced = 1;
} else if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncContent)) {
/* replace the node with the buffer */
! ret = xmlSecReplaceNodeBuffer(node, xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer));
if(ret < 0) {
xmlSecError(XMLSEC_ERRORS_HERE,
NULL,
--- 608,614 ----
encCtx->resultReplaced = 1;
} else if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncContent)) {
/* replace the node with the buffer */
! ret = xmlSecReplaceNodeBuffer(node, xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer),(encCtx->nodeReplacementMode==xmlEncCtxNodeRelease?NULL:&(encCtx->replacedNodeList)));
if(ret < 0) {
xmlSecError(XMLSEC_ERRORS_HERE,
NULL,
diff --exclude-from=./exclude -rc xmlsec1-1.2.11/src/xmltree.c 1.2.11/src/src/xmltree.c
*** xmlsec1-1.2.11/src/xmltree.c Thu Mar 6 18:55:36 2008
--- 1.2.11/src/src/xmltree.c Thu Mar 13 16:39:31 2008
***************
*** 412,424 ****
* xmlSecReplaceNode:
* @node: the current node.
* @newNode: the new node.
*
* Swaps the @node and @newNode in the XML tree.
*
* Returns 0 on success or a negative value if an error occurs.
*/
int
! xmlSecReplaceNode(xmlNodePtr node, xmlNodePtr newNode) {
xmlNodePtr oldNode;
int restoreRoot = 0;
--- 412,425 ----
* xmlSecReplaceNode:
* @node: the current node.
* @newNode: the new node.
+ * @replaced: return the replaced node, or release it if NULL is given
*
* Swaps the @node and @newNode in the XML tree.
*
* Returns 0 on success or a negative value if an error occurs.
*/
int
! xmlSecReplaceNode(xmlNodePtr node, xmlNodePtr newNode,xmlNodePtr* replaced) {
xmlNodePtr oldNode;
int restoreRoot = 0;
***************
*** 448,454 ****
xmlDocSetRootElement(oldNode->doc, newNode);
}
! xmlFreeNode(oldNode);
return(0);
}
--- 449,461 ----
xmlDocSetRootElement(oldNode->doc, newNode);
}
! /* cannot release node because it could be referenced elsewhere */
! if (replaced==NULL) {
! xmlFreeNode(oldNode);
! } else {
! *replaced=oldNode;
! }
!
return(0);
}
***************
*** 456,474 ****
* xmlSecReplaceContent
* @node: the current node.
* @newNode: the new node.
*
* Swaps the content of @node and @newNode.
*
* Returns 0 on success or a negative value if an error occurs.
*/
int
! xmlSecReplaceContent(xmlNodePtr node, xmlNodePtr newNode) {
xmlSecAssert2(node != NULL, -1);
xmlSecAssert2(newNode != NULL, -1);
xmlUnlinkNode(newNode);
xmlSetTreeDoc(newNode, node->doc);
! xmlNodeSetContent(node, NULL);
xmlAddChild(node, newNode);
xmlSetTreeDoc(newNode, node->doc);
--- 463,498 ----
* xmlSecReplaceContent
* @node: the current node.
* @newNode: the new node.
+ * @replaced: return the replaced nodes, or release them if NULL is given
*
* Swaps the content of @node and @newNode.
*
* Returns 0 on success or a negative value if an error occurs.
*/
int
! xmlSecReplaceContent(xmlNodePtr node, xmlNodePtr newNode,xmlNodePtr* replaced) {
xmlSecAssert2(node != NULL, -1);
xmlSecAssert2(newNode != NULL, -1);
xmlUnlinkNode(newNode);
xmlSetTreeDoc(newNode, node->doc);
! /* cannot release nodes because they could be referenced elsewhere */
! if (replaced==NULL) {
! xmlNodeSetContent(node, NULL);
! } else {
! xmlNodePtr n,next,cur;
! *replaced=NULL;
! for (n=node->children;n;n=next) {
! next=n->next;
! if (*replaced==NULL) {
! xmlUnlinkNode(n);
! *replaced=cur=n;
! } else {
! /* n is unlinked in this function */
! xmlAddNextSibling(cur,n);
! }
! }
! }
xmlAddChild(node, newNode);
xmlSetTreeDoc(newNode, node->doc);
***************
*** 479,486 ****
/**
* xmlSecReplaceNodeBuffer:
* @node: the current node.
! * @buffer: the XML data.
* @size: the XML data size.
*
* Swaps the @node and the parsed XML data from the @buffer in the XML tree.
*
--- 503,511 ----
/**
* xmlSecReplaceNodeBuffer:
* @node: the current node.
! * @buffer: the XML data.
* @size: the XML data size.
+ * @replaced: return the replaced nodes, or release them if NULL is given
*
* Swaps the @node and the parsed XML data from the @buffer in the XML tree.
*
***************
*** 488,494 ****
*/
int
xmlSecReplaceNodeBuffer(xmlNodePtr node,
! const xmlSecByte *buffer, xmlSecSize size) {
xmlNodePtr results = NULL;
xmlNodePtr next = NULL;
--- 513,519 ----
*/
int
xmlSecReplaceNodeBuffer(xmlNodePtr node,
! const xmlSecByte *buffer, xmlSecSize size,xmlNodePtr* replaced) {
xmlNodePtr results = NULL;
xmlNodePtr next = NULL;
***************
*** 514,521 ****
/* remove old node */
xmlUnlinkNode(node);
! xmlFreeNode(node);
!
return(0);
}
--- 539,550 ----
/* remove old node */
xmlUnlinkNode(node);
! /* cannot release node because it could be referenced elsewhere */
! if (replaced==NULL) {
! xmlFreeNode(node);
! } else {
! *replaced=node;
! }
return(0);
}
_______________________________________________
xmlsec mailing list
[email protected]
http://www.aleksey.com/mailman/listinfo/xmlsec