Hi,
I think I have found a bug in XPath/Xpath-Filter2 reference evaluation. The bug is reproducable with the xmlsec command line utility, using the attached input files.
The  problem is that the whole document is included in the reference digest.

The command line:
xmlsec1 --sign --store-references --print-debug --id-attr:id "urn:test.global":ToBeSigned --privkey-pem signkey.pem --pubkey-cert-pem signcert.crt tobesigned.xml

After some debugging sessions I found, that the problem arises when the libxml2 xpath evaluation returns an empty nodeset in the form: the xmlXPathObject's type is XPATH_NODESET and the nodesetval pointer is NULL. (Sometimes empty nodesets are returned  with a non-null nodesetval pointer, but nodesetval->nodeNr=0)
I have managed to correct the handlig of such empty nodesets by two small modification:
in nodeset.c: in function xmlSecNodeSetOneContains the default value of the variable  int in_nodes_set has to be set to 0:
-------------------
xmlSecNodeSetOneContains(xmlSecNodeSetPtr nset, xmlNodePtr node, xmlNodePtr parent) {
    int in_nodes_set = 0;
     ...
-------------------
By this NULL nodes pointers in xmlSecNodeSet nodesets are handled correctly. But this arises another problem: when using an xpointer in the corresponding reference,
the initial xmlSecNodeSetPtr nodeset's nodes pointer is set to NULL, with type xmlSecNodeSetNormal. This defines an empty nodeset, so the initial nodeset has to be changed.
In transforms.c in function xmlSecTransformCtxExecute has to be created with type xmlSecNodeSetInvert instead of xmlSecNodeSetNormal, which means the whole document:
-------------------
xmlSecTransformCtxExecute(xmlSecTransformCtxPtr ctx, xmlDocPtr doc) {
    int ret;

    xmlSecAssert2(ctx != NULL, -1);
    xmlSecAssert2(ctx->result == NULL, -1);
    xmlSecAssert2(ctx->status == xmlSecTransformStatusNone, -1);
    xmlSecAssert2(doc != NULL, -1);

    if((ctx->uri == NULL) || (xmlStrlen(ctx->uri) == 0)) {
        xmlSecNodeSetPtr nodes;

        if((ctx->xptrExpr != NULL) && (xmlStrlen(ctx->xptrExpr) > 0)){
            /* our xpointer transform takes care of providing correct nodes set */
            nodes = xmlSecNodeSetCreate(doc, NULL, xmlSecNodeSetInvert);
  ...
-------------------
This way xpath evaluation seems correct. Of course my modifications require more evaluation.

Steingart Ferenc

fejlesztő, programtervező matematikus
Tel: 06 1 345 7974
Email: [email protected]
Web: http://www.cardinal.hu

-----BEGIN CERTIFICATE-----
MIIB0jCCATugAwIBAgIBAjANBgkqhkiG9w0BAQUFADARMQ8wDQYDVQQDEwZSb290
Q0EwHhcNMTExMTAxMTA0NTAwWhcNMTIxMTAxMTA0NTAwWjASMRAwDgYDVQQDEwdF
bmRVc2VyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCt3xos6OM/TWKWEVTV
cPuCZcBVxxDaBmDoL0bJ+je4eSykaOJvkZIYD2c8geq0QHESAZz/Zc0o96ixQ1hv
QTJFo1zzJfvjdrjAmdhypFSXtYeM833RMQuBPMrhVfRL2s3XNwZ70eZQsU3Cpukk
CHUHWgCx78lgSVSW2Qlf6jfxuwIDAQABozkwNzAJBgNVHRMEAjAAMB0GA1UdDgQW
BBSBuyuZhfQzPwgUpwbOBW1aYDOEHzALBgNVHQ8EBAMCBPAwDQYJKoZIhvcNAQEF
BQADgYEAGxMU5p8sqsxuK0UPrNC7MQskx3XAZznXStytkwr4+S8l/kqMJmbVEYpZ
VMdIgo3XhM5hDhs3QMMOxD5PQmTSeNxeXafVBpN9js24b1soi40zdzKzvXkbgVor
o902tS7cspBph1J73zqG5iuRZL/64iC9DM2NW4njrvJJtTTEzO8=
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAK3fGizo4z9NYpYR
VNVw+4JlwFXHENoGYOgvRsn6N7h5LKRo4m+RkhgPZzyB6rRAcRIBnP9lzSj3qLFD
WG9BMkWjXPMl++N2uMCZ2HKkVJe1h4zzfdExC4E8yuFV9Evazdc3BnvR5lCxTcKm
6SQIdQdaALHvyWBJVJbZCV/qN/G7AgMBAAECgYEAlpHoJxAfC4jGYVLs9lH7XHcl
UqMrUsPHVArs8KiBbH1zTYWO4jNcIv3j1yBi0mokAQXoobvVKS8fpTK++Mmq7/n6
VxoG1k+RFapuhWyLzk6GkabCpk8CmuKs/XbyFJG7YqKl3giZqV7uOiRNFmw7Z4ZP
aahQ3I/ylTtcppapCdECQQDYhb39/eICNlPtpB0Y8S64ld/7Fr3az4wOwQ3hJALI
GjngQa9DHH4Ul3RAnabIPAubLqx89RT/TLvoh1rVVPDXAkEAzZKc9rVotk4hhtP1
lEKDp19I5ij3q3bU8M0/Kbi7l2gPDazYHK/sI9hpSjuZbYBxYrd/oGA9LRNsopvU
jLOVvQJAGclLyDz9NqA7vJiH8pl+o/MNerzJnY6MMpGhUofUYPpmnCOWeNqi1Vb4
PF3KKBymkTOszTDu8Dy2QEomcjOsfwJAVo1ZKwJcMQ2aThMl/aM3nRugLM+o33dr
1msEIgPWb7vvQpm4b/Od38W5JvkK8zC2DJMn2BVNDJJ2Fcy4Y/kknQJACbJNn4Ez
zKG8RN+ZABnvOSqQEdAcWoawwXJeoEC9RSKOuC4J2fQKgog4cQNdLkVNBvLFDP8n
akn64aUpEk7RYQ==
-----END PRIVATE KEY-----
<Document xmlns="urn:test.global" xmlns:glob="urn:test.global" xmlns:excl="urn:test.excludefromsig">
  <ToBeSigned id="123456">
    <Multiple>
      <Data>Lorem ipsum</Data>
      <excl:NotToBeSigned>
        <ToBeSignedAgain>
          <Data>dolor sit amet</Data>
        </ToBeSignedAgain>
      </excl:NotToBeSigned>
    </Multiple>
    <Multiple>
      <Data>consectetur adipisicing elit</Data>
      <excl:NotToBeSigned>
        <ToBeSignedAgain>
          <Data>sed do eiusmod tempor incididunt</Data>
        </ToBeSignedAgain>
      </excl:NotToBeSigned>
    </Multiple>
  </ToBeSigned>
  <dsig:Signature
   xmlns:dsig="http://www.w3.org/2000/09/xmldsig#";
   xmlns:dsig-xpath="http://www.w3.org/2002/06/xmldsig-filter2";>
    <dsig:SignedInfo>
      <dsig:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"; />
      <dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"; />
      <dsig:Reference URI="#123456">
        <dsig:Transforms>
          <dsig:Transform 
           Algorithm="http://www.w3.org/2002/06/xmldsig-filter2";>
            <dsig-xpath:XPath Filter="subtract">/glob:Document/glob:ToBeSigned/glob:Multiple/excl:*</dsig-xpath:XPath>
            <dsig-xpath:XPath Filter="union">/glob:Document/glob:ToBeSigned/Multiple/excl:*/*[namespace-uri()!="urn:test.excludefromsig"]</dsig-xpath:XPath>
          </dsig:Transform>
        </dsig:Transforms>
        <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"; />
        <dsig:DigestValue></dsig:DigestValue>
      </dsig:Reference>
    </dsig:SignedInfo>
    <dsig:SignatureValue/>
  </dsig:Signature>
</Document>
_______________________________________________
xmlsec mailing list
[email protected]
http://www.aleksey.com/mailman/listinfo/xmlsec

Reply via email to