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:[EMAIL PROTECTED]] Sent: Thursday, December 19, 2002 4:50 AM To: Moultrie, Ferrell (ISSAtlanta) Cc: [EMAIL PROTECTED] Subject: Re: [xmlsec] enhancement to xmlsec Hi, Ferrell! I like this idea but might I propose to add a new argument "--node-xpath" instead of changing the meaning of the old one? I just don't like this tricky "if 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 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. > 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. > For example, "--node-name //Module[2]" would select the 2nd Module >element in the document skeletonized below: ><?xml version="1.0" encoding="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 > > > > >----------------------------------------------------------------------- - > >306a307 > > >>char *nodeXPath = NULL; >> >> >388,395c389,400 >< nodeName = strrchr(argv[++pos], ':'); >< if(nodeName != NULL) { >< *(nodeName++) = '\0'; >< nodeNs = argv[pos]; >< } else { >< nodeName = argv[pos]; >< nodeNs = NULL; >< } >--- > > >> if (argv[++pos][0] == '/') { /* absolute XPath specification? */ >> nodeXPath = argv[pos]; >> } else { >> nodeName = strrchr(argv[pos], ':'); >> if(nodeName != NULL) { >> *(nodeName++) = '\0'; >> nodeNs = argv[pos]; >> } else { >> nodeName = argv[pos]; >> nodeNs = NULL; >> } >> } >> >> >1245a1251,1281 > > >>/* 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 = NULL; >> if(nodeId != NULL) { >> xmlAttrPtr attr; >> attr = xmlGetID(doc, BAD_CAST nodeId); >> cur = (attr != NULL) ? attr->parent : NULL; >> } else if(nodeXPath != NULL) { >> xmlNodeSetPtr pNodeList = NULL; >> xmlXPathContextPtr pCtx = NULL; >> xmlXPathObjectPtr pXPathObj = NULL; >> pCtx = xmlXPathNewContext(doc); >> pXPathObj = xmlXPathEval(BAD_CAST nodeXPath, pCtx); >> if (pXPathObj != NULL) { >> pNodeList = pXPathObj->nodesetval; >> } >> if (pNodeList != NULL && pNodeList->nodeNr > 0) { >> cur = pNodeList->nodeTab[0]; >> } >> xmlXPathFreeContext(pCtx); >> xmlXPathFreeObject(pXPathObj); >> } else if(nodeName != NULL) { >> cur = xmlSecFindNode(xmlDocGetRootElement(doc), BAD_CAST nodeName, BAD_CAST nodeNs); >> } else { >> cur = xmlDocGetRootElement(doc); >> } >> return cur; /* can be NULL .. caller must check */ >>} /* of findBaseNode() */ >> >> >> >1248a1285 > > >> xmlNodePtr cur; >> >> >1255,1256c1292,1301 >< signNode = xmlSecFindNode(xmlDocGetRootElement(doc), >< BAD_CAST "Signature", xmlSecDSigNs); >--- > > >> /** >> * What do we want to sign? >> */ >> cur = findBaseNode(doc); >> if (cur == NULL) { >> fprintf(stderr,"Error: failed to find specified node\n"); >> return(-1); >> } >> signNode = xmlSecFindNode(cur, BAD_CAST "Signature", xmlSecDSigNs); >> >> >1258,1259c1303,1304 >< fprintf(stderr,"Error: failed to find Signature node\n"); >< return(-1); >--- > > >> fprintf(stderr,"Error: failed to find Signature node\n"); >> return(-1); >> >> >1310a1356 > > >> xmlNodePtr cur; >> >> >1313,1315c1359,1368 >< >< signNode = xmlSecFindNode(xmlDocGetRootElement(doc), >< BAD_CAST "Signature", xmlSecDSigNs); >--- > > >> /** >> * What do we want to verify? >> */ >> cur = findBaseNode(doc); >> if (cur == NULL) { >> fprintf(stderr,"Error: failed to find specified node\n"); >> return(-1); >> } >> signNode = xmlSecFindNode(cur, BAD_CAST "Signature", xmlSecDSigNs); >> >> >1317,1318c1370,1371 >< fprintf(stderr,"Error: failed to find Signature node\n"); >< return(-1); >--- > > >> fprintf(stderr,"Error: failed to find Signature node\n"); >> return(-1); >> >> >1414,1424c1467,1468 >< if(nodeId != NULL) { >< xmlAttrPtr attr; >< >< attr = xmlGetID(doc, BAD_CAST nodeId); >< cur = (attr != NULL) ? attr->parent : NULL; >< } else if(nodeName != NULL) { >< cur = xmlSecFindNode(xmlDocGetRootElement(doc), BAD_CAST nodeName, BAD_CAST nodeNs); >< } else { >< cur = xmlDocGetRootElement(doc); >< } >< >--- > > >> cur = findBaseNode(doc); >> >> >> >1498c1542,1547 >< cur = xmlSecFindNode(xmlDocGetRootElement(doc), BAD_CAST "EncryptedData", xmlSecEncNs); >--- > > >> cur = findBaseNode(doc); >> if (cur == NULL) { >> fprintf(stderr,"Error: failed to find specified node\n"); >> return(-1); >> } >> cur = xmlSecFindNode(cur, BAD_CAST "EncryptedData", xmlSecEncNs); >> >> > > _______________________________________________ xmlsec mailing list [EMAIL PROTECTED] http://www.aleksey.com/mailman/listinfo/xmlsec
