[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [Elist Home]
Subject: [ebxml-msg] Whitespace problem with XMLDSIG usage in ebMSS
Hi, This email analyzes a limitation of the way XMLDSIG is currently used in the ebXML Message Service Specification (ebMSS) v1.0.91 and proposes a solution to overcome that limitation. ebMSS dictates how XMLDSIG must be used by conforming MSH implementations. Unfortunately, a signature generated in accordance with the current ebMSS specification is very sensitive to trivial changes in whitespace (space, CR, LF and tab characters) in the xml content. For example, if the xml structure of the eb:To element (in some ebXML envelope) is changed from: <eb:To><eb:PartyId type='some-type'>CompanyA</eb:PartyId></eb:To> to <eb:To> <eb:PartyId type='some-type'>CompanyA</eb:PartyId> </eb:To> a signature created over the first representation becomes invalid. This is because the extra CRLF and other whitespace characters (in the second representation) affect the digest, even though this change in surface representation does not affect the meaning of the message. The soap and ebXML schemas define such whitespace characters as being irrelevant. Both the above examples will validate against the schema. However, the way XMLDSIG is being used in ebMSS, every whitespace character is important. In a way, the signature is being too restrictive to trivial changes in the envelope. A first (and reasonable) reaction would be, should not the canonicalization transform (required by line 1108, ebMSS) already take care of this possiblity? Canonical XML (defined by http://www.w3.org/TR/2001/REC-xml-c14n-20010315), however does not take care of this and (correctly) regards all textual content (whitespace or not) as being significant (meaningful) (section 3.2 of Canonical XML). That is because, without a schema or DTD, it is not possible to know which whitespace is signficant and which is not and the transform described by Canonical XML does not use the DTD or schema to decide whether a particular whitespace character is significant or not. This problem specifically affects intermediary MSHs. It is unreasonable to expect such an MSH to preserve irrelevant whitespace when forwarding an ebXML message. On the other hand, if such whitespace is unintentionally changed, any signature introduced by the sender becomes invalid. This problem can manifest itself even in an MSH that is not an intermediary. An unthinking MSH implementer might pretty print outgoing ebXML messages but performing pretty printing after the signature has been computed would invalidate the signature. If the signature is tolerant of changes in whitespace, pretty printing could be the final step (after signing). Granted, pretty printing is not a requirement but the examples in ebMSS would lead an implementer to believe that ebXML messages should be pretty printed. The proposed solution applies an XMLDSIG transform to the ebXML envelope before signing (and before verification) so that trivial changes in whitespace is eliminated. Of the various transforms XMLDSIG defines, this proposal uses the XSL transform to eliminate insignificant whitespace. ebMSS currently requires the following ds:Transforms element to be used when signing the envelope. <Transforms> <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> <Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116"> <XPath> not(ancestor-or-self::*[@SOAP:actor="urn:oasis:names:tc:ebxml-msg:service:ne xtMSH"] | ancestor-or-self::*[@SOAP:actor="http://schemas.xmlsoap.org/soap/actor/next" ]) </XPath> </Transform> <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> </Transforms> By adding another ds:Transform element, resilience to changes in surface representation can be achieved: <Transforms> <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> <Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116"> <XPath> not(ancestor-or-self::*[@SOAP:actor="urn:oasis:names:tc:ebxml-msg:service:ne xtMSH"] | ancestor-or-self::*[@SOAP:actor="http://schemas.xmlsoap.org/soap/actor/next" ]) </XPath> </Transform> <Transform Algorithm="http://www.w3.org/TR/1999/REC-xslt-19991116"> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:strip-space elements='*'/> <!-- Strip whitespace. --> <xsl:template match='node()|@*'> <!-- The identity transform. --> <xsl:copy> <xsl:apply-templates select='@*'/> <xsl:apply-templates/> </xsl:copy> </xsl:template> </xsl:stylesheet> </Transform> <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> </Transforms> The newly added (XSL) transform instructs the xmldsig processor to apply the inlined stylesheet to the output of the enveloping transform before passing it on to the xpath transform. The stylesheet itself is a simple variation on the identity transform. If an element is specified in <xsl:strip-space> ( '*' specifies all elements), and ALL the text node children of that element are whitespaces, then these whitespace text nodes are stripped (trimmed). In other words, if an element contains non-whitespace textual content interspersed with whitespace, NO whitespace is removed (this last point is elaborated on later). The following example tries to explain. This snippet from some ebXML message: <eb:To> <eb:PartyId type='some-type'>CompanyA</eb:PartyId> </eb:To> <eb:CPAId>CompanyA-CompanyB</eb:CPAId> is transformed to: <eb:To><eb:PartyId type='some-type'>CompanyA</eb:PartyId></eb:To><eb:CPAId>CompanyA-CompanyB</e b:CPAId> Notice that the whitespace contained by eb:To and between eb:To and eb:CPAId has been eliminated. On the other hand, this snippet <eb:Description xml:lang="en-US"> This textual content contains whitespace but is left untouched. </eb:Description> remains unchanged: <eb:Description xml:lang="en-US"> This textual content contains whitespace but is left untouched. </eb:Description> The latter example illustrates the point that if an element contains ANY non-whitespace textual content, NO whitespace is eliminated. Or, in other words, if an element contains non-whitespace textual content, all sibling whitespace is automatically considered significant. This conveniently meets the intuitive requirement that an intermediary MSH should not modify an eb:Description element, even if the modification is limited to whitespace. One limitation of the XSL transform as presented above, is a result of what seems like an XMLDSIG problem and something that the XMLDSIG folks are being made aware of. Specifically, the ds:SignedInfo element (child of ds:Signature) is outside the scope of the above XSL transform (it is not processed by the latter) and hence, ds:SignedInfo is not robust to changes in whitespace. The ds:Signature element structure typically looks like (pardon the verbosity): <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <ds:Reference URI=""> <ds:Transforms> <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> <ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116"> <ds:XPath>not(ancestor-or-self::node()[@SOAP-ENV:actor="urn:oasis:names :tc:ebxml-msg:actor:nextMSH"] | ancestor-or-self::node()[@SOAP-ENV:actor="http://schemas.xmlsoap.org/so ap/actor/next"])</XPath> <ds:/Transform> <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> <ds:/Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <ds:DigestValue>JklY0tWheXRXBlYIbS7pY9bYGdY=</DigestValue> <ds:/Reference> <ds:/SignedInfo> <ds:SignatureValue> fsgBjrgjg7u6+Nxwqa1GTKY3AkvORTygCmoXDMIGveiUkmNZ2L4DDgbD6FhGVNMvKVfzsKxv LRhBV2QW1YsOH+Ot8BpB49lcHdmweMIApbXo0Y+uKe4t73YGE7QAuboLaCQQQ+X++MCu6uzC YVnA3zHTuZiEz+qABxbFRgQg20g= <ds:/SignatureValue> <ds:/Signature> The only processing that the ds:SignedInfo is subject to, prior to verification is the algorithm specified by ds:CanonicalizationMethod (http://www.w3.org/TR/2001/REC-xml-c14n-20010315), which, as discussed earlier in this email, does not make any assumptions regarding whitespace belonging to elements in the xml being canonicalized and hence treats all such whitespace as significant. There is no extensibility mechanism defined by XMLDSIG for introducing an XSL transform to preprocess the ds:SignedInfo element. Because the ds:CanonicalizationMethod algorithm does not eliminate trivial whitespace, ds:SignedInfo is sensitive to changes in whitespace, even if the ebXML message in which it is embedded is robust. The solution to this latter problem is to require MSHs to apply the XSL transform to ds:SignedInfo elements BEFORE signing and BEFORE verifying (that is, before the XMLDSIG implementation gets the envelope). The result is that the signing MSH always creates a ds:SignedInfo element that 'fits on one line with no trivial whitespace'. More precisely, the signing MSH must always create ds:SignedInfo elements that do not contain trivial whitespace anywhere in their subtree. Trivial whitespace is defined as any whitespace that would be stripped by applying the XSL transform: <Transform Algorithm="http://www.w3.org/TR/1999/REC-xslt-19991116"> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:strip-space elements='*'/> <!-- Strip whitespace. --> <xsl:template match='node()|@*'> <!-- The identity transform. --> <xsl:copy> <xsl:apply-templates select='@*'/> <xsl:apply-templates/> </xsl:copy> </xsl:template> </xsl:stylesheet> </Transform> (the same one as before). Using the example above, the signing MSH must generate this: <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo><ds:CanonicalizationMethod ...><ds:SignatureMethod ...><ds:Reference URI="">...<ds:/SignedInfo> <ds:SignatureValue> asgBjrgjg7u6+Nxwqa1GTKY3AkvORTygCmoXDMIGveiUkmNZ2L4DDgbD6FhGVNMvKVfzsKxv LRhBV2QW1YsOH+Ot8BpB49lcHdmweMIApbXo0Y+uKe4t73YGE7QAuboLaCQQQ+X++MCu6uzC YVnA3zHTuZiEz+qABxbFRgQg20g= <ds:/SignatureValue> <ds:/Signature> ('...' is obviously used only to keep the example short). Similarly, the verifying MSH must remove all trivial whitespace (if any exist) belonging to ds:SignedInfo before the envelope is submitted to the XMLDSIG library for verification. How trivial whitespace is removed from ds:SignedInfo is left to the implementation. Implementations might (among other options): - Walk the (normalized) DOM structure rooted at ds:SignedInfo and remove all text nodes that contain only whitespace. - Instantiate a JAXP transformer, initialized with the above XSL transform. By consistently signing over 'flattened' (referring to this process of removing trivial whitespace) ds:SignedInfo elements and then 'flattening' these again before verifying, signatures become robust to changes in whitespace. Even if an intermediary MSH were to pretty print the ebXML envelope and embedded ds:Signature elements, signatures are not invalidated. Thanks for your patience. Comments and feedback greatly appreciated. Regards, Sanjay J. Cherian Sterling Commerce Irving, TX
[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [Elist Home]
Powered by eList eXpress LLC