[xmlsec] External DTD support

Rich Salz rsalz@datapower.com
Wed, 22 Jan 2003 14:12:32 -0500


This is a multi-part message in MIME format.
--------------000507090102080105090603
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

I want to be use the xmlsec application to verify SOAP messages signed 
using WS-Security.  SOAP does not allow DTD's.  The attached patch adds 
a "--dtdfile FILENAME" option to xmlsec, so you can write a DTD that 
identifies ID attributes.  It includes documentation update (it seems 
xmlsec.xml is the place to update; I hope I did it right).

Perhaps more controversial, the patch always allows self-signed 
certificates. That part should, perhaps, be changed to allow self-signed 
certs if they were specified with the "--trusted" flag, but I haven't 
been able to figure out how to do that.

	/r$

--------------000507090102080105090603
Content-Type: text/plain;
 name="dtdpatch.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="dtdpatch.txt"

diff -cr orig/apps/xmlsec.c new/apps/xmlsec.c
*** orig/apps/xmlsec.c	Thu Nov 28 15:32:22 2002
--- new/apps/xmlsec.c	Wed Jan 22 13:02:18 2003
***************
*** 165,170 ****
--- 165,171 ----
      "  --node-name [<namespace-uri>:]<name>\n"
      "                        set the operation start point to the first node \n"
      "                        with given <name> and <namespace> URI\n"
+     "  --dtdfile <file>      Load the specified file as the DTD\n"
      "\n";
      
  static const char helpKeysMngmt[] = 
***************
*** 233,244 ****
  } xmlSecDSigStatus, *xmlSecDSigStatusPtr;
  
  /**
!  * Init/Shutdown
   */
  int  initXmlsec(xmlsecCommand command);
  void shutdownXmlsec(void);
  int app_RAND_load_file(const char *file);
  int app_RAND_write_file(const char *file);
  
  
  /**
--- 234,246 ----
  } xmlSecDSigStatus, *xmlSecDSigStatusPtr;
  
  /**
!  * Init/Shutdown, parsing
   */
  int  initXmlsec(xmlsecCommand command);
  void shutdownXmlsec(void);
  int app_RAND_load_file(const char *file);
  int app_RAND_write_file(const char *file);
+ int findIDnodes(xmlDtdPtr dtd, xmlDocPtr doc);
  
  
  /**
***************
*** 316,321 ****
--- 318,324 ----
      int res = 1;
      xmlsecCommand command = xmlsecCommandNone;
      xmlDocPtr doc = NULL;
+     xmlDtdPtr dtd = NULL;
      int i;
      int pos;
      int ret;
***************
*** 394,399 ****
--- 397,413 ----
  		    nodeNs = NULL;
  		}
  	    }
+         } else if((strcmp(argv[pos], "--dtdfile") == 0) && (pos + 1 < argc)) {
+             if(dtd != NULL){
+                 fprintf(stderr, "Error: DTD already specified\n");
+                 ret = -1;
+             } else {
+                 dtd = xmlParseDTD(NULL, (const xmlChar*)argv[++pos]);
+                 if(dtd == NULL) {
+                     fprintf(stderr, "Could not parse DTD\n");
+                     ret = -1;
+                 }
+             }
  	} else 
  
  	/**
***************
*** 748,753 ****
--- 762,769 ----
  		    printUsage(NULL);
  	    	    goto done;
  		}
+                 if (dtd)
+                     findIDNodes(dtd, doc);
  	
      		switch(command) {
  	    
***************
*** 1793,1798 ****
--- 1809,1821 ----
      }
  
      return 1;
+ }
+ 
+ int findIDNodes(xmlDtdPtr dtd, xmlDocPtr doc) {
+     xmlValidCtxt c = { 0 };
+ 
+     xmlValidateDtd(&c, doc, dtd);
+     return 0;
  }
  
  
diff -cr orig/man/xmlsec.xml new/man/xmlsec.xml
*** orig/man/xmlsec.xml	Mon Oct  7 22:26:04 2002
--- new/man/xmlsec.xml	Wed Jan 22 13:57:31 2003
***************
*** 240,245 ****
--- 240,256 ----
          </varlistentry>
  
          <varlistentry>
+           <term><option>--dtdfile</option> <replaceable>file</replaceable></term>
+           <listitem>
+             <simpara>Instructs the <application>xmlsec</application>
+             program to validate the input document against the
+             DTD specified in <replaceable>file</replaceable>.
+             This is mostly used in order to pick up ID attribute
+             declarations.</simpara>
+           </listitem>
+         </varlistentry>
+ 
+         <varlistentry>
            <term><option>--keys</option> <replaceable>file</replaceable></term>
              <listitem>
                <simpara>Loads keys from XML keys <replaceable>file</replaceable>.</simpara>
***************
*** 361,366 ****
--- 372,387 ----
              </listitem>
          </varlistentry>
          <varlistentry>
+           <term><option>--dtdfile</option> <replaceable>file</replaceable></term>
+           <listitem>
+             <simpara>Instructs the <application>xmlsec</application>
+             program to validate the input document against the
+             DTD specified in <replaceable>file</replaceable>.
+             This is mostly used in order to pick up ID attribute
+             declarations.</simpara>
+           </listitem>
+         </varlistentry>
+         <varlistentry>
            <term><option>--print-result</option></term>
              <listitem>
                <simpara>Prints additional result information.</simpara>
***************
*** 527,532 ****
--- 548,564 ----
          </varlistentry>
  
          <varlistentry>
+           <term><option>--dtdfile</option> <replaceable>file</replaceable></term>
+           <listitem>
+             <simpara>Instructs the <application>xmlsec</application>
+             program to validate the input document against the
+             DTD specified in <replaceable>file</replaceable>.
+             This is mostly used in order to pick up ID attribute
+             declarations.</simpara>
+           </listitem>
+         </varlistentry>
+ 
+         <varlistentry>
            <term><option>--node-name</option> 
  	  <optional>[<replaceable>namespace-uri</replaceable>:]</optional><replaceable>name</replaceable></term>
              <listitem>
***************
*** 655,660 ****
--- 687,703 ----
                <simpara>Instructs the <application>xmlsec</application>
  	      program to decrypt only element with given <replaceable>id</replaceable>.</simpara>
              </listitem>
+         </varlistentry>
+ 
+         <varlistentry>
+           <term><option>--dtdfile</option> <replaceable>file</replaceable></term>
+           <listitem>
+             <simpara>Instructs the <application>xmlsec</application>
+             program to validate the input document against the
+             DTD specified in <replaceable>file</replaceable>.
+             This is mostly used in order to pick up ID attribute
+             declarations.</simpara>
+           </listitem>
          </varlistentry>
  
          <varlistentry>
diff -cr orig/src/x509.c new/src/x509.c
*** orig/src/x509.c	Fri Oct 11 12:24:53 2002
--- new/src/x509.c	Wed Jan 22 13:59:07 2003
***************
*** 1047,1052 ****
--- 1047,1058 ----
  		depth	 = X509_STORE_CTX_get_error_depth(&xsc);
  		X509_STORE_CTX_cleanup (&xsc);  
  
+                 /* Allow self-signed certificates. */
+                 if((err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
+                         || (err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN)) {
+                     ret = 1;
+                 }
+ 
  		if(ret == 1) {
  		    x509Data->verified = cert;
  		    sk_X509_free(certs);

--------------000507090102080105090603--