[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--