[xmlsec] enhancement to xmlsec

Moultrie, Ferrell (ISSAtlanta) FMoultrie@iss.net
Thu, 19 Dec 2002 11:29:45 -0500


Aleksey:
  Done. I didn't think the overload was particularly troublesome since
the XPath syntax was clearly different from a node-name but the approach
you suggested is cleaner and without ambiguity. I'm attaching diffs
against 0.0.10 as before plus an additional diff (-b) which is smaller
and removes some (possibly gratuitous) white-space editing I'd done
while implementing the code. Your choice as to which to check-in.
Ferrell

-----Original Message-----
From: Aleksey Sanin [mailto:aleksey@aleksey.com]=20
Sent: Thursday, December 19, 2002 4:50 AM
To: Moultrie, Ferrell (ISSAtlanta)
Cc: xmlsec@aleksey.com
Subject: Re: [xmlsec] enhancement to xmlsec


Hi, Ferrell!

I like this idea but might I propose to add a new argument=20
"--node-xpath" instead of
changing the meaning of the old one? I just don't like this tricky "if=20
argument starts with slash..."
part because I 'll be the first one who will forget about this :)
Will you mind to make this change, please? And I'll be happy to commit=20
it to CVS :)

Thanks,
Aleksey


Moultrie,  (ISSAtlanta) wrote:

>Aleksey:
>  My xml documents that I'm signing/verifying contain repeated nodes of
>the same name so any beyond the first node are not addressable by the
>--node-name construct supported by xmlsec. Additionally, I'm not using
a
>dtd so the --node-id doesn't help me out either. Finally, the
>sign/verify code accept the --node-id/--node-name arguments but ignore
>them, always signing/verifying the first Signature node found.=20
>  To solve the above issues, I'm attaching suggested changes (relative
>to 0.0.10) that allow the --node-name argument to contain an absolute
>XPath expression to locate the section of the document to be
>signed/verified/etc. If the argument starts with a '/' character, it is
>processed as an XPath expression, otherwise it is just a ns:node-name
as
>before. This shouldn't break anything but allows much greater
>flexibility in using xmlsec with complex xml structures.=20
>  For example, "--node-name //Module[2]" would select the 2nd Module
>element in the document skeletonized below:
><?xml version=3D"1.0" encoding=3D"UTF-8"?>
><Keys>
>  <Modules>
>    <Module> first module element including <sig:Signature/> </Module>
>    <Module> second module element including <sig:Signature/> </Module>
>    <Module> third module element including <sig:Signature/> </Module>
>  </Modules>
></Keys>
>  Using either "--node-name //Module[1]" or "--node-name Module" would
>select the first occurance (note node-name format works just as it did
>before).
>  While I could have obviously written a new utility to handle manual
>signing of my test documents, it seems much better to add this
>functionality to the xmlsec application where it could easily be reused
>by others. I'm attaching the diff's -- let me know if you need another
>format, or, a full copy of the xmlsec.c file before/after my changes.
>  I have rather thoroughly tested the digital signature
>creation/verification but haven't tested encryption/decryption -- but
>since it now uses a common routine, what could go wrong, right? (:>)
>Thanks!
>  Ferrell
>
>
> =20
>
>-----------------------------------------------------------------------
-
>
>306a307
> =20
>
>>char *nodeXPath =3D NULL;
>>   =20
>>
>388,395c389,400
>< 		nodeName =3D strrchr(argv[++pos], ':');
>< 		if(nodeName !=3D NULL) {
>< 		    *(nodeName++) =3D '\0';
>< 		    nodeNs =3D argv[pos];
>< 		} else {
>< 		    nodeName =3D argv[pos];
>< 		    nodeNs =3D NULL;
>< 		}
>---
> =20
>
>>			if (argv[++pos][0] =3D=3D '/') { /* absolute XPath
specification? */=20
>>				nodeXPath =3D argv[pos];
>>			} else {
>>				nodeName =3D strrchr(argv[pos], ':');
>>				if(nodeName !=3D NULL) {
>>				    *(nodeName++) =3D '\0';
>>				    nodeNs =3D argv[pos];
>>				} else {
>>				    nodeName =3D argv[pos];
>>				    nodeNs =3D NULL;
>>				}
>>			}
>>   =20
>>
>1245a1251,1281
> =20
>
>>/* Function to find base node for operation as specified by user using
either
>> * DTD Id, XPath abs expression, NodeName, or default to root node */
>>xmlNodePtr findBaseNode(xmlDocPtr doc) {
>>	xmlNodePtr cur =3D NULL;
>>	if(nodeId !=3D NULL) {
>>	    xmlAttrPtr attr;
>>	    attr =3D xmlGetID(doc, BAD_CAST nodeId);
>>	    cur =3D (attr !=3D NULL) ? attr->parent : NULL;
>>	} else if(nodeXPath !=3D NULL) {
>>		xmlNodeSetPtr pNodeList =3D NULL;
>>		xmlXPathContextPtr pCtx =3D NULL;
>>		xmlXPathObjectPtr pXPathObj =3D NULL;
>>		pCtx =3D xmlXPathNewContext(doc);
>>		pXPathObj =3D xmlXPathEval(BAD_CAST nodeXPath, pCtx);
>>		if (pXPathObj !=3D NULL) {
>>			pNodeList =3D pXPathObj->nodesetval;
>>		}
>>		if (pNodeList !=3D NULL && pNodeList->nodeNr > 0) {=20
>>			cur =3D pNodeList->nodeTab[0];
>>		}
>>		xmlXPathFreeContext(pCtx);
>>		xmlXPathFreeObject(pXPathObj);
>>	} else if(nodeName !=3D NULL) {
>>		cur =3D xmlSecFindNode(xmlDocGetRootElement(doc), BAD_CAST
nodeName, BAD_CAST nodeNs);
>>	} else {
>>	    cur =3D xmlDocGetRootElement(doc);
>>	}
>>	return cur; /* can be NULL .. caller must check */
>>} /* of findBaseNode() */
>>
>>   =20
>>
>1248a1285
> =20
>
>>	xmlNodePtr cur;
>>   =20
>>
>1255,1256c1292,1301
><     signNode =3D xmlSecFindNode(xmlDocGetRootElement(doc),=20
>< 			      BAD_CAST "Signature", xmlSecDSigNs);
>---
> =20
>
>>	/**
>>	 * What do we want to sign?
>>	 */   =20
>>	cur =3D findBaseNode(doc);
>>	if (cur =3D=3D NULL) {=20
>>		fprintf(stderr,"Error: failed to find specified
node\n");
>>		return(-1);
>>	}
>>	signNode =3D xmlSecFindNode(cur, BAD_CAST "Signature",
xmlSecDSigNs);
>>   =20
>>
>1258,1259c1303,1304
><         fprintf(stderr,"Error: failed to find Signature node\n");
>< 	return(-1);
>---
> =20
>
>>		fprintf(stderr,"Error: failed to find Signature
node\n");
>>		return(-1);
>>   =20
>>
>1310a1356
> =20
>
>>	xmlNodePtr cur;
>>   =20
>>
>1313,1315c1359,1368
><     	   =20
><     signNode =3D xmlSecFindNode(xmlDocGetRootElement(doc),=20
>< 			      BAD_CAST "Signature", xmlSecDSigNs);
>---
> =20
>
>>	/**
>>	 * What do we want to verify?
>>	 */   =20
>>	cur =3D findBaseNode(doc);
>>	if (cur =3D=3D NULL) {=20
>>		fprintf(stderr,"Error: failed to find specified
node\n");
>>		return(-1);
>>	}
>>	signNode =3D xmlSecFindNode(cur, BAD_CAST "Signature",
xmlSecDSigNs);
>>   =20
>>
>1317,1318c1370,1371
><         fprintf(stderr,"Error: failed to find Signature node\n");
>< 	return(-1);
>---
> =20
>
>>		fprintf(stderr,"Error: failed to find Signature
node\n");
>>		return(-1);
>>   =20
>>
>1414,1424c1467,1468
>< 	if(nodeId !=3D NULL) {
>< 	    xmlAttrPtr attr;
>< 	   =20
>< 	    attr =3D xmlGetID(doc, BAD_CAST nodeId);
>< 	    cur =3D (attr !=3D NULL) ? attr->parent : NULL;
>< 	} else if(nodeName !=3D NULL) {
>< 	    cur =3D xmlSecFindNode(xmlDocGetRootElement(doc), BAD_CAST
nodeName, BAD_CAST nodeNs);
>< 	} else {
>< 	    cur =3D xmlDocGetRootElement(doc);
>< 	}
>< =09
>---
> =20
>
>>	cur =3D findBaseNode(doc);
>>
>>   =20
>>
>1498c1542,1547
><     cur =3D xmlSecFindNode(xmlDocGetRootElement(doc), BAD_CAST
"EncryptedData", xmlSecEncNs);
>---
> =20
>
>>	cur =3D findBaseNode(doc);
>>	if (cur =3D=3D NULL) {=20
>>		fprintf(stderr,"Error: failed to find specified
node\n");
>>		return(-1);
>>	}
>>    cur =3D xmlSecFindNode(cur, BAD_CAST "EncryptedData", =
xmlSecEncNs);
>>   =20
>>
>=1A
>