The XML Signature Elements

 <  Day Day Up  >  

The XML Signature Elements

So far, we have discussed the XML Signature element and its schema at a high level and reviewed the processing steps necessary to create and verify a Signature. In the process, we have glossed over a lot of the specifics; now let's discuss each element in more detail.

The SignedInfo Element

As we mentioned, the SignedInfo element contains all the information about what is digitally signed. As shown in Listing 4.12, the SignedInfo element contains three children elements ” CanonicalizationMethod , SignatureMethod , and zero or more Reference elements.

Listing 4.12. XML Shorthand Schema for the <SignedInfo> Element
 <SignedInfo>     <CanonicalizationMethod/>     <SignatureMethod/>     (<Reference URI? >          (<Transforms>)?          <DigestMethod>          <DigestValue>     </Reference>)+ </SignedInfo> 

We describe each of these three elements in turn , starting with CanonicalizationMethod .

The CanonicalizationMethod Element and Canonicalization

Canonicalization is quite a mouthful and is often abbreviated as C14N (14 letters bracketed by the C and the N ). The concept behind canonicalization is straightforward, but you wouldn't know this to look at the amount of discussion and work it has engendered. The W3C has published multiple specifications on canonicalization and the subtle issues surrounding it. It continues to be a well-discussed subject (a recent google search on canonicalization located 35,500 hits). Let's look at this topic at its simplest level first and then determine where the more subtle issues arise.

As we discussed in Chapter 3, if even a single bit changes in a document that is being signed, the digest (hash) will not be the same, and Signature/Reference validation will fail. With XML, in particular, certain differences may exist between an XML document or XML fragment that has nothing to do with the underlying meaning of the XML but is introduced simply because of the operating system or a difference in the way an XML parser resolves the XML. For example, a file created on a Windows operating system or one created on a Unix operating system typically ends a line of text with different ASCII character sequences. Another example is that the whitespace outside the tags of an XML element might be handled slightly differently among different XML parsers. From an XML language definition standpoint, these whitespace differences mean nothing and are ignored.

Note

Normally, whitespace outside elements is ignored by XML parsers. The one exception to this rule is for elements that have been declared "mixed." Such elements can contain content as well as other elements.


As we mentioned, however, any difference between the resulting XML at signature time and the resulting XML that is resolved at validation time will result in the Signature validation failing. Canonicalization is the strategy used to deal with this issue.

Canonicalization normalizes the XML so that, regardless of inconsequential physical differences in the XML, two logically equivalent XML documents will become physically, bit-to-bit equivalent. This is a critical requirement for digital signatures to work.

The following simple scenario illustrates the issue. Say that Bob is creating an XML Signature over the XML structure in Listing 4.13.

Listing 4.13. An XML Structure to be Signed
 <GroceryList>     <GroceryStore>Safeway</GroceryStore>     <Item Category="produce">Lettuce</Item>     <Item Category="produce">Tomato</Item>     <Item Category="meat">Bacon</Item> </GroceryList> 

Now, say that Bob created this XML document on a Windows platform. Hidden within Bob's hypothetical XML document is whitespace in the form of spaces, tabs, and end-of-line characters. His document actually looks like Listing 4.14 (hidden characters are bold and delimited by + in this example).

Listing 4.14. The GroceryList XML Structure with Embedded Whitespace from Windows
  +t+  <GroceryList>  +c-r++l-f+   +t++t+  <GroceryStore>Safeway</GroceryStore>  +sp++c-r++l-f+   +t++t+  <Item Category="produce">Lettuce</Item>  +sp++c-r++l-f+   +t++t+  <Item Category="produce">Tomato</Item>  +c-r++l-f+   +t++t+  <Item Category="meat">Bacon</Item>  +c-r++l-f+   +t+  </GroceryList>  +c-r++l-f+  

Note

In this and the following two examples, we had to refer to the hidden characters with abbreviations due to space considerations. Refer to the following legend to understand these abbreviations:

c-r

carriage -return

l-f

line-feed

sp

space

t

tab



Now say this document is emailed to Alice, who is running on a Unix platform and needs to validate this document. One difference between the Windows and Unix environments is the extra carriage return put in by Windows. As a convenience to Alice, when she opens her emails, the reader software converts the carriage returns and linefeeds to single linefeeds. So, now the XML document looks like Listing 4.15.

Listing 4.15. The GroceryList XML Structure with Embedded Whitespace from Unix
  +t+  <GroceryList>+  l-f  + +  t  ++  t  +<GroceryStore>Safeway</GroceryStore>  +sp+  +  l-f  + +  tb  ++  t  +<Item Category="produce">Lettuce</Item>  +sp+  +  l-f  + +  t  ++  t  +<Item Category="produce">Tomato</Item>+  l-f  + +  t  ++  t  +<Item Category="meat">Bacon</Item>+  l-f  + +  t  +</GroceryList>+  l  -  f  + 

Are these two XML documents different? Not semantically. But, from a classic digital signature perspective, any change to the underlying bits would break the signature. If Bob had digitally signed this XML using a traditional digital signing approach, the digital signature validation would fail verification (although the email reader could get around this problem by validating the signature before doing any convenience manipulation of the document). It is clear, however, that logically these two XML documents are identical, and they should compare equally. This is where canonicalization comes into play. There needs to be a common way to format XML regardless of platform so that, no matter what underlying physical changes have occurred, two semantically identical XML documents will be considered physically identical. This is not limited to physical changes, but also to certain syntactic changes where XML gives you options that do not change the underlying logical equivalence. We come back to this topic soon because this is the place where some of the difficulties of canonicalization lie.

Let's return to our simple Bob and Alice scenario with the concept of canonicalization. This time, before signing the XML document, Bob (or more accurately, the tool that he is using to create the XML Signature) canonicalizes the XML. Here are some simple rules for canonicalization for this example (note that these are not the canonicalization rules for XML Signature, just some simple rules for this example):

  • Change carriage returns/linefeeds into single carriage returns.

  • Strip any whitespace (tabs or spaces) that appears outside tags.

Applying these rules to the preceding XML document creates the structure in Listing 4.16.

Listing 4.16. The GroceryList XML Structure After Canonicalization
 <GroceryList>+  l-f  + <GroceryStore>Safeway</GroceryStore>+  l-f  + <Item Category="produce">Lettuce</Item>+  l-f  + <Item Category="produce">Tomato</Item>+  l-f  + <Item Category="meat">Bacon</Item>+  l-f  + </GroceryList>+l-f+ 

These examples might not be pretty to look at, but canonicalization is not for human consumption; it is to feed directly into the Digest algorithm. This canonicalized output is not stored anywhere . It is not in the Signature element, and the XML information being referenced is not changed.

The purpose of the CanonicalizationMethod element in the SignedInfo block is to provide the name of the canonicalization algorithm that Bob employed when digitally signing the XML. Alice's XML Signature processing engine will read the CanonicalizationMethod and apply the same canonicalization algorithm on the XML that might have been subtly changed by her operating system. Consequently, due to the canonicalization, the same XML will result, and the signature will be verified correctly.

The CanonicalizationMethod algorithm attribute is applied to the SignedInfo element. It is also a type of Transform that can be used as a Transform element with References that we will talk more about later.

The initial XML specification contains only one required canonicalization algorithm (http://www.w3.org/TR/2001/REC-xml-c14n-20010315). This version ignores comments, so, for example, you could put XML comments into a SignedInfo section and they would be ignored in the signature. There is also a recommended canonicalization algorithm that includes comments (http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments).

Canonicalization Actions from Canonical XML Version 1.0

Following is a list of the changes that occur to an XML document when it goes through a Canonical XML version 1.0 Transform (you can find the XML Canonicalization specification at http://www.w3.org/TR/2001/REC-xml-c14n-20010315):

  • The document is encoded in UTF-8.

  • Line breaks are normalized to #xA on input, before parsing.

  • Attribute values are normalized, as if by a validating processor.

  • Character and parsed entity references are replaced .

  • CDATA sections are replaced with their character content.

  • The XML declaration and Document Type Definition (DTD) are removed.

  • Empty elements are converted to start-end tag pairs.

  • Whitespace outside the document element and within start and end tags is normalized.

  • All whitespace in character content is retained (excluding characters removed during linefeed normalization).

  • Attribute value delimiters are set to quotation marks (double quotes).

  • Special characters in attribute values and character content are replaced by character references.

  • Superfluous namespace declarations are removed from each element.

  • Default attributes are added to each element.

  • Lexicographic order is imposed on the namespace declarations and attributes of each element.

Canonicalization Subtleties: Exclusive Canonicalization

Although the concept of standardizing the XML before digesting and before verifying is reasonably simple, complex subtleties arise in some specific situations. One of the subtleties became a significant issue as practical implementations of XML Signing were in the early stages of creation. It came up when applying XML Signing to fragments of XML within a larger XML document ”which is the predominant scenario in Web services using SOAP. The issue was primarily related to namespaces. The XML Canonicalization 1.0 specification says that namespaces are to be propagated down to all its descendents. This makes sense because, in the context of the document, these namespaces are implicit, so making them explicit seems like a reasonable strategy. However, when you remove an XML fragment from the context of a document, as in the case of SOAP when you have an XML payload within the overall document, this can cause significant problems.

This issue resulted in the creation of a new canonicalization algorithm called Exclusive Canonicalization (http://www.w3.org/TR/2002/REC-xml-exc-c14n-20020718/). This canonicalization method strives to "exclude ancestor context" as much as is practical. It primarily does this by not propagating the ancestor namespaces down to the children nodes. This canonicalization approach turns out to be the most practical in most circumstances and the one that you should use.

The extensibility of the canonicalization method is a tribute to the XML Signature working group and is what made the advent of the Exclusive Canonicalization method possible. Custom canonicalization methods are also possible; however, you should be extremely careful about using one because the canonicalization algorithm modifies the XML to be signed and verified in a way that is difficult to see. It would not be difficult for a canonicalization algorithm to do something such as modify the XML to have all signatures verified correctly.

To summarize, canonicalization is an important concept that is straightforward but can quickly become complex. (Just search canonicalization on the Net, and you will see what we mean.) Most of the time in Web Services Security, you can use Exclusive Canonicalization and you will be fine. We describe canonicalization further when we discuss the Transform element because, as we mentioned earlier, the CanonicalizationMethod designates which Canonicalization Transform to use over the SignedInfo element.

The SignatureMethod Element

SignatureMethod names the algorithm that will be used for signing and verifying signatures. Two signature algorithms are required: DSAwithSHA1, which is an implementation of the Digital Signature Algorithm (DSA), and HMAC-SHA1. DSAwithSHA1 is a public key strategy (sign with a private key, decrypt with a public key), and HMAC-SHA1 is a shared key hashed message authentication code strategy. This is a little unusual. Digital signatures are typically meant to validate integrity (that the document has not changed) and identity (that a particular individual, device, or process signed the document). Validation of identity is associated with public key cryptography (for example, DSA or RSA), not shared key cryptography. A shared key approach is typically not associated with digital signatures; however, the XML working group wanted to allow for a situation in which the primary purpose for the signature was integrity, and HMAC-SHA1 is an excellent (and fast) way to accomplish this goal.

In addition to the DSA algorithm, RSAwithSHA1 is recommended (but not required). Remember that the DSA algorithm and, consequently, DSA keys can be used only for digital signatures. The RSA public key algorithms can be used for both digital signatures and encryption and are more commonly used than DSA. Most, if not all, XML Signature implementations support RSAwithSHA1.

The following is an example of a SignatureMethod element:

 

 <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1" /> 

The Reference Element

While SignedInfo can be considered the meat of an XML Signature, in turn the Reference element can be considered the meat of SignedInfo .

Tip

When you are reading an XML Signature, which can often be remarkably long, the first place you usually look to get a feel for what is being signed is the Reference element(s). The URI attribute points to what is being signed.


As review, Listing 4.17 is the Reference XML fragment pulled from the Signature shorthand schema shown earlier.

Listing 4.17. XML Shorthand Schema for the <Reference> Element.
 (<Reference URI? >    (<Transforms>)?  <DigestMethod>  <DigestValue> </Reference>)+ 

The objective of the Reference element is to point to a resource to be included in the overall XML Signature. There must be at least one Reference , which stands to reason because you have to be signing something. To say that this element points to the resource is actually oversimplifying because it also can contain Transform elements that manipulate the resource that is being pointed to prior to its being digested. Arguably, most of the power and complexity of XML Signatures come from the Reference element. That power comes from the power of the uniform resource identifier.

See the sidebar titled "The Powerful, Enigmatic, and Confusing Uniform Resource Indentifier (URI)" in Chapter 2 for more information about what a URI is and how to use it. In XML Signature, URIs can show up in a variety of ways; see the sidebar here titled "URI/URL Variants in XML Signature" for a review of the different ways a URI can show up as a Reference URI in an XML Signature.

URI/URL Variants in XML Signature

For XML Signature and most of the XML security standards, you need to understand URIs well. The locator aspect of URIs when referring to XML is quite a bit more involved than the equivalent HTML usage. Let's review the locator type URI options in XML Signature:

  1. Refers to an external XML document. This is straightforward and might look like URI=http://www.mycompany.com/myDocument.xml .

  2. Refers to the current XML document root. It is common, especially with enveloping references to specify the root of the document that contains the Signature element. This looks like URI="" .

  3. Uses the same document reference. If you are referring to an XML element in the same document, you can use a "same document reference," which looks like URI="#PurchaseOrder" .

  4. Uses external document "bare fragment." This is similar to a same document reference, except that it is to a portion of an external XML document. It looks something like URI="http://www.mycompany.com/myDocument.xml#PurchaseOrder" .

  5. Refers to a non-XML file (binary, text, and so on). This is similar to any URL you are already familiar with; it looks like URI="http://www.mycompany.com/myPicture.gif" .

  6. Uses an internal URI with an XPointer argument (this type is recommended but not required, so all toolkits might not support it). It looks like URI="#xpointer(/)" , which refers to the root element. External URIs with XPointer arguments are not recommended.

Another fact to know about URIs is that they can be absolute or relative. An absolute URI is completely spelled out, including all parts of the URI, such as http://www.mycompany.com/ mySignatureExample . A relative URI contains a resource path and name that is meant to be resolved from the BaseURI. The BaseURI, if not made explicit, is the same directory as your current location. For example the relative URI myPicture.gif would look for myPicture.gif in the same directory where the XML document is located. Using relative URIs can provide the advantage of portability by allowing you to move a set of resources around without having to change references.


The Transform Element

Transforms receive the results of dereferencing the Reference URI and alter the results in some way. A Transform algorithm can essentially change anything about the original XML document. Multiple Transforms can appear under a Reference working in a pipeline-type fashion, with the results of one Transform algorithm feeding into the next one. This is an extremely powerful capability but fraught with risk. We discuss this topic later, but the problem is probably obvious: After a Transform occurs, there is no way for a signer or validator to view what has been signed without going through the exact same Transforms in the exact same order. That being said, in some situations Transforms are necessary. You just need to be careful when you use them.

Actually, we already described one type of Transform when we discussed canonicalization algorithms. In the XML Signature specification, five Transforms are mentioned:

  • Canonicalization

  • Base-64

  • XPath Filtering

  • Enveloped Signature Transform

  • XSLT Transform

XML Signature Transforms: Nodeset or Octets?

Remember that Transforms work in a pipeline fashion, taking in the input from the Reference URI or another Transform and outputting to either another Transform or to the final digest algorithm. This brings up a new wrinkle: The results of the Reference URI can be either an XML nodeset or octets (a true 8-bit byte). The digest algorithm needs octets. If only a Reference URI is included and no Transforms, the transformation from an XML nodeset to octets occurs automatically.

When Transforms are being used, however, you sometimes need to be aware of whether a particular Transform algorithm requires a nodeset or octets as input and whether the Transform algorithm outputs an XML nodeset or octets. The Reference URI is always the first input, and there is a basic rule as to whether it will result in an XML nodeset or octets. If it is a same document reference, it will result in an XML nodeset; if it is an external reference, even if the external document is XML, it will be octets. The final Transform must always output octets because that result is required for the digest algorithm. Your tool for converting from an XML nodeset to octets is canonicalization.

Don't sweat this issue too much; most of the conversions are handled for you. Just remember that the digest algorithm needs octets. Therefore, if, after applying one or more Transforms, you end up with an XML nodeset, you may need to add one more Transform, a Canonicalization Transform, to convert the XML nodeset to octets.


Canonicalization Transform

Any canonicalization algorithm that can be used in the CanonicalizationMethod can be used as a Transform. Canonicalization algorithms take XML nodesets as input and output octets.

Base-64 Transform

Base-64 is an algorithm for converting binary data into text, as discussed in Chapter 3. This algorithm maps the binary values to a subset of ASCII values that are human-readable text. See Appendix A for more detailed information on the Base-64 algorithm.

You would use the Base-64 Transform, for example, if the Reference URI were pointing to a GIF image like that in Listing 4.18.

Listing 4.18. A <Reference> URI for a GIF Image Requiring Base-64 Transform
 <Reference URI="myPicture.gif">     <Transform                 Algorithm=http://www.w3.org/2000/09/xmldsig#base64 />     <DigestAlgorithm ... />     <DigestValue ... /> </Reference> 

The Base-64 Transform takes in octets and outputs octets.

XPath Filtering Transform

The XPath Filtering Transform allows you take advantage of the powerful XPath language [2] . See Chapter 2 for more information on XPath.

[2] XPath, XML Path Language (XPath) Version 1.0. W3C Recommendation. J. Clark and S. DeRose. October 1999. http://www.w3.org/TR/1999/REC-xpath-19991116

In addition to the Algorithm attribute, the XPath Filtering Transform adds a child called XPath to the Transform element. This is the place you put the XPath expression that will pull out the piece you want from the XML nodeset that was returned by the Reference URI or the previous Transform. An example of this is shown in Listing 4.19.

Listing 4.19. The <Transform> Element Using Xpath Transform
 <Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">     <XPath xmlns:dsig="&dsig;">       not(ancestor-or-self::dsig:Signature)   </XPath> </Transform> 

You commonly use the XPath Filtering Transform in XML Signatures when you want to sign just a fragment of an XML document. For example, it is not uncommon to want to create a Signature element that is a peer with the element you want to sign. Consider the following document shown in Listing 4.20:

Listing 4.20. An <Order> XML Structure Where <Signature> Needs to be a Peer With <UserAgreement>
 <Order>     <CustomerInformation>         <Name>David Remy</Name>         <Address>123 Somewhere Street</Address>         <City>West Linn</City>         <State>OR</State>         <Country>US</Country>     </CustomerInformation>     <LineItems>         <LineItem Sku="1235">Lime green Umbrella</LineItem>     </LineItems>     <UserAgreement>         I agree to be spammed, pay early and extra,          and enjoy your popup adds.     </UserAgreement>     <Signature>-- Signature of UserAgreement here --</Signature> </Order> 

The requirement here is to create an XML Signature that is a peer (at the same level in the XML tree) of UserAgreement . You can accomplish this by using an XPath Filtering Transform like that used in Listing 4.21.

Listing 4.21. Use of Xpath Filtering to Create an XML Signature at the Peer Level
 <Signature>     <SignedInfo>        <Reference URI="">           <Transforms>            <Transform              Algorithm="http://www.w3.org/TR/1999/REC-xpath-             19991116">  <XPath>   ancestor-or-self:UserAgreement[parent:Order]   </XPath>  </Transform>           </Transforms>        ...       </Reference>     </SignedInfo> </Signature> 

As you can see, the Reference element specifies the current document ( URI="" ), and the Transform element has XPath (http://www.w3.org/TR/1999/REC-xpath-19991116) as its algorithm and a child XPath element. This element contains the XPath expression ancestor-or-self:UserAgreement[parent:Order] , which is a simple way of asking for the UserAgreement element and all its siblings. This particular XPath expression is somewhat brittle because it assumes the UserAgreement element is always a child of Order . XPath would allow a more elaborate expression to pick up a UserAgreement at any level in the document.

The XPath Filtering Transform takes in and outputs an XML nodeset.

Enveloped Signature Transform

The Enveloped Signature Transform is commonly used in XML Signature when the parent element is to be signed. The problem is that the Signature element would be within the information to be signed, so it must be removed before doing the validation. You actually can remove the Signature element by using the XPath Filter Transform described previously, so this Transform is primarily provided for convenience.

Note

The Enveloped Signature Transform is the only Transform (other than the canonicalization Transforms defined by CanonicalizationMethod ) required by the XML Specification. The XPath Filter Transform is recommended, but it is not required. You will find in practice that most, if not all, current XML Signature toolkits support the XPath Filter Transform.


Using the Enveloped Signature Transform is the same as using the XPath Filter Transform with the following expression in Listing 4.22:

Listing 4.22. The XPath Expression Equivalent to the Enveloped Signature Transform
 <XPath>    count(ancestor-or-self::dsig:Signature     here()/ancestor::dsig:Signature[1]) >    count(ancestor-or-self::dsig:Signature) </XPath> 

This XPath expression can a bit difficult to deal with, so having this Transform is convenient . If you are signing a parent element, you should use it. For example, say you want to sign the Order XML document in Listing 4.23 and want the Signature to be the last element within the Order :

Listing 4.23. An <Order> Element Where <Signature> Needs to be the Last Element
 <Order>     <LineItems>         <LineItem sku="00001">Soap on a Rope</LineItem>         <LineItem sku="00002">Cinnamon Shampoo</LineItem>     </LineItems>  <Signature> ... </Signature>  </Order> 

To accomplish this, you must use the Enveloped Signature Transform (or XPath Filtering Transform). The Signature element would then look something like Listing 4.24.

Listing 4.24. The <Signature> Element After the Enveloped Signature Transform
 <Signature>   <SignedInfo>     <CanonicalizationMethod ... />     <SignatureMethod ... />     <Reference  URI=""  >  <Transforms>   <Transform   Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>   </Transforms>  <DigestMethod ... />       <DigestValue>...</DigestValue>     </Reference>   </SignedInfo>   <SignatureValue>...</SignatureValue> </Signature> 

In this example, the Reference URI points to the document itself ( URI="" ), and the Transform algorithm is the Enveloped Signature Transform. If the target of the Signature is not the root of the document, you could use the "same document reference" type for the URI (for example, URI="#someElementID" ) or an XPath Filtering Transform just prior to the Enveloped Signature Transform to reduce the resulting XML fragment to just the nodes you plan to sign.

Similar to the XPath Filtering Transform, the Enveloped Signature Transform takes in and outputs an XML nodeset. The only difference is that an Enveloped Signature Transform must be applied to a nodeset from within its parent document.

XSLT Transform

It is good practice to sign what the signer (a human being) actually sees, especially when the meaning of the signature represents the signer's intent. The visual aspects ”even seemingly insignificant aspects such as a word being bold ”can influence the meaning of a document. If an XML Stylesheet (XSL) is used, you have two choices for how to digitally sign it. One option is to have two Reference URIs: one pointing to the base XML document and the other to the XSL. Another is to use the XSLT Transform. The XSLT Transform simply applies the specific XSL expressions that are included under the Stylesheet element. To refer to an external stylesheet, you can use the xsl:include or xsl:import XSL expressions.

Note

The XSLT Transform requires octets as input, and the output is an octet stream. Also, because different XSLT processors do not necessarily return consistent results, it is a good idea to use a Canonicalization Transform after an XSLT Transform.


XPath Filter 2.0 Transform

The XPath Filter 1.0 Transform described in the preceding section allows for any type of XPath expression to be used. The underlying usage for XPath Filter 1.0 is often either to explicitly include some fragment of a document to be signed or to explicitly exclude some part of the document that could legitimately change without breaking the signature of the document. For example, say you want to have two signatures that are not co-signatures (one signature does not include the other). To do this, you would use an XPath statement to exclude the other signatures (and the Enveloped Signature Transform to exclude the current signature). These are "set" type functions that often require fairly complex XPath statements to accomplish. The XPath Filter 2.0 Transform adds the capability to shortcut these common types of XPath statements by specifying intersection, union, and subtraction. For example, to remove another signature, you would use the following XPath 2.0 filter:

 

 <XPath Filter="  subtract  " xmlns="http://www.w3.org/2002/06/xmldsig-filter2">       id("TheOtherSignature") </XPath> 

On the other hand, if the goal is to sign the other signature, such as when a counter- signature is desired, you might use the following:

 

 <XPath Filter="  intersect  " xmlns="http://www.w3.org/2002/06/xmldsig-filter2">       id("TheOtherSignature") </XPath> 

Using these intersect, subtract, and union set operations can be cleaner than using the equivalent XPath statements, and it is also possible for the Signature processor to work more efficiently . You can find an excellent example of the XPath Filter 2.0 Transform using the three set operators at the following location:

http://www.w3.org/TR/xmldsig-filter2/#sec-Examples

The Reference URI when using the XPath Filter 2.0 Transform must be an XML document. Often, it is the current document URI ( URI="" without comments or URI="#xpointer[/]" with comments). This Transform takes in and returns an XML nodeset.

The DigestMethod Element

The DigestMethod element represents an identifier for the algorithm used to calculate the digest of the Reference URI plus all the Transforms.

Note

The digest algorithm itself must receive its information in the form of octets. Typically, if a conversion is needed from an XML nodeset to octets, it is handled automatically. However, in some cases, an additional Transform may be required to ensure that the input to the digest algorithm is in the form of octets or to ensure that the XML nodeset is canonicalized so that it has the highest likelihood of valid comparison on any platform.


The only required digest algorithm is SHA1, and it is designated by

 

 Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" 

The DigestValue Element

The DigestValue element contains the Base-64 encoded value of the digest. The following DigestValue element is taken from the example we gave near the beginning of the chapter:

 

 <DigestValue>60NvZvtdTB+7UnlLp/H24p7h4bs=</DigestValue> 

The SignatureValue Element

At this point, the SignatureValue element must seem anti-climactic even though it represents the signature itself. The SignatureValue element is the Base-64 encoded resulting value of encrypting a digest of the SignedInfo element. The particular signature method used is defined within the SignatureMethod element itself (for example, RSA-SHA1). Here is an example of a SignatureValue :

 

 <SignatureValue>     hTHQJyd3C6ww/OJz07P4bMOgjqBdznSUOsCh6P+0MpF69w2tln/PFLdx/EP4/VKX </SignatureValue> 

So far, we have reviewed the core aspects of the XML Signature , SignedInfo , and SignatureValue elements. If you understand them well, you have a good basis for understanding and using XML Signatures. The next two elements, Object and KeyInfo , are optional, but in many circumstances, necessary and important elements.

The Object Element

We have not talked much about the Object element, but when we described Enveloping Signatures, we were discussing a function that the Object element facilitates. In the case of an Enveloping Signature, the Reference URI points to an element within the Object element. We further describe this use of the Object element later in the chapter.

The Object element is essentially an element in which you put miscellaneous items other than SignedInfo , SignatureValue , and KeyInfo . It is defined in a way that you can put anything you want into it; however, typically one of three things is included within an Object element:

  • Something you want signed, such as an XML fragment or perhaps a Base-64 encoded binary object. This is to implement the Enveloping Signature concept mentioned previously.

  • A Manifest element (described later).

  • A SignatureProperties element (described later).

Tip

Remember that none of these items are inherently signed and therefore secured by the XML Signature. For these elements to be signed, they must be referred to by one of the Reference URIs in the SignedInfo section of the signature.


Listing 4.25 uses an Object element in the Enveloping Signature scenario.

Listing 4.25. An <Object> Element Used in the Enveloping Signature Scenario
 <Signature>     <SignedInfo>    ...    <Reference  URI="#MyOrder"   Type="http://www.w3.org/2000/09/xmldsig#Object"  >        <DigestMethod                 Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>        <DigestValue>...</DigestValue>    </Reference>  </SignedInfo>  ...  <  Object id="MyOrder"  >         <Order>             <LineItem sku="12348">Web Service Security Book</LineItem>             <LineItem sku="2345">Life as a Geek Book</LineItem>         <Order>  </Object> </Signature> 

Note

In this example, the Object start and end tags would be included in the digest calculation for the Reference. If you do not want the Object tags to be included in the digest calculation, either

  • The Reference URI should point to the element below the Object tag that is to be signed.

    or

  • An XPath statement should exclude the Object tag.


First, notice that the Reference URI points to an ID ( MyOrder ) of an Object element. Also, notice that a Type parameter is included in the Reference to provide information about what the Reference is pointing to. We deferred mentioning this point when describing the Reference element.

The following three Type attributes are mentioned in the XML Signature specification; they all relate to items that can be contained within an Object element or the Object element itself:

  • Object (Type="http://www.w3.org/2000/09/xmldsig#Object") ” The reference is to an Object element.

  • Manifest (Type="http://www.w3.org/2000/09/xmldsig#Manifest") ” The reference is to a Manifest element (see the Manifest Element section next in this chapter for more information on the Manifest element).

  • SignatureProperties (Type="http://www.w3.org/2000/09/xmldsig#SignatureProperties") ” The reference is to a SignatureProperties element (see the Signature Properties section later in this chapter for more information on SignatureProperties ).

The Object element, when used in an Enveloped Signature scenario like this, can also have attributes for MimeType and Encoding . For example, if the enveloped item is a GIF image, your Object tag might look like this:

 

 <Object id="MyGif" MimeType="image/gif" Encoding="base64"> ... a string of base64 characters ... </Object> 

You can have as many Object elements as you want. You typically create a single Object tag for each use. So, for example, if you have a signed Object and you have SignatureProperties (which is always within an Object ), you have two Object elements.

Now let's discuss the two optional children of the Object tag: Manifest and SignatureProperties .

The Manifest Element

In terms of ocean shipping, a manifest is the list of things that the ship has onboard. In that sense, all the References within SignedInfo are a type of manifest because they list what is included in the XML Signature. Similar to SignedInfo , the Manifest element contains a list of Reference elements (exactly like the Reference elements that are children of SignedInfo ). The only difference is that the References referred to in SignedInfo must be validated for the signature to be considered valid. The meaning of a Manifest Reference not validating is left up to you, as the application developer. In other words, you typically have the opportunity to be notified if a problem occurs with validation of the Manifest Reference elements; therefore, you can determine how best to handle the situation.

You might find at least two major uses for the Manifest element:

  • You may want to have more granular control over which References matter and which do not (contextually). For example, you might want it to be okay if two out of three References are valid. You would not be able to accomplish this with SignedInfo alone.

  • For performance reasons, when doing multiple signatures over the same information, you could refer to a Manifest element. The Manifest element would be computed only once, and the References from multiple signatures could point to the one Manifest . This approach could be valuable when multiple signers are signing a contract.

Use of the Manifest element is similar to the Object example described earlier, except that the Manifest element exists at one level below Object , as shown in Listing 4.26.

Listing 4.26. Use of the <Manifest> Element
 <Reference URI="#MyManifest"  Type="http://www.w3.org/2000/09/xmldsig#Manifest"  >       <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>       <DigestValue>. . .</DigestValue>  </Reference>  ...  <Object>       <Manifest Id="MyManifest">           <Reference>               ...           </Reference>            <Reference>                ...           </Reference>       </Manifest>  </Object> 

As we mentioned previously, the Reference elements in Manifest are exactly like the Reference elements in SignedInfo , except that it is up to you to decide what to do if the validation on the DigestValue fails.

The SignatureProperties Element

The SignatureProperties element provides a place to put name value information about the signature itself. For example, you often need to know the time of the signature. This is a classic candidate for a signature property. Listing 4.27 shows this type of usage (it is a slightly edited version from an example in the XML Signature specification).

Listing 4.27. Use of the <SignatureProperties> Element
 <Signature id="MySignature">     <SignedInfo>         ...         <Reference  URI="#AMadeUpTimeStamp"   Type="http://www.w3.org/2000/09/xmldsig#SignatureProperties"  >             <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>             <DigestValue>. . .</DigestValue>         </Reference>     </SignedInfo>     ...     <Object>  <SignatureProperties>   <SignatureProperty Id="AMadeUpTimeStamp" Target="#MySignature">  <timestamp xmlns="http://www.ietf.org/rfcXXXX.txt">                     <date>19990908</date>                     <time>14:34:34:34</time>                 </timestamp>             </SignatureProperty>         </SignatureProperties>     </Object> </Signature> 

Notice that the Reference element points to a specific SignatureProperty within SignatureProperties and specifies a SignatureProperties Type . Also, notice that the Target points back to the Signature that this property is associated with.

That wraps up our discussion of the Object element. It is kind of a quirky element but important in many circumstances.

The KeyInfo Element

The KeyInfo element is perhaps the thorniest element in the XML Signature specification. Its purpose is to give you the key needed to validate the signature or give you information to allow you to look up the key. XML Signature goes out of its way to define a flexible structure for KeyInfo such that

  • It can be omitted completely.

  • It can provide the key in a raw form right in the XML.

  • It can provide the key within a digital certificate.

  • It can give you a variety of types of keys to support different cryptography standards.

  • It can simply provide a name for you to use to look up the key.

As it always seems when discussing PKI and security, things become more difficult as we move closer to the issues of key management and trust.

Because the KeyInfo element allows such a wide variety of options for providing information about the key needed to validate the signature, it consists mostly of optional elements. Listing 4.28 is a shorthand schema for KeyInfo .

Listing 4.28. The Shorthand XML Schema for <KeyInfo>
 (<KeyInfo (id=)?>     (<KeyName>)?     (<KeyValue>)?     (<RetrievalMethod>)?     (<X509Data>)?     (<PGPData>)?     (<SPKIData>)?     (<MgmtData>)? <KeyInfo>)? 

As you can see, everything is optional. This is a clue about the unwieldy nature of this element. Obviously, the XML Signature working group wanted to support as many possible key standards as it could; however, most of the time, you will encounter one of these three scenarios:

  • You will receive an X.509 certificate within the X509Data element. X.509 certificates, issued by a certificate authority, either private or public (such as VeriSign or GeoTrust), are the predominant container for public keys.

  • You will receive one of the X509Data elements that uniquely identify an X.509 certificate in a directory. We discuss these elements briefly later in this section, but examples include X509IssuerSerial and SerialNumber , which together can uniquely identify a certificate. In this case, you use this information to look into a directory to locate the X.509 certificate yourself.

  • You will receive no KeyInfo . In this case, it is expected that you know what the validation key (either public or secret key) should be. For example, if you are in a protocol situation, exchanging multiple messages in a sequence, you may already have knowledge of the key.

As we mentioned earlier, X.509 certificates are the predominant standard for containing public key certificates. Practically every type of security application contains support for them, including Web browsers, Web servers, VPNs, email, and so on. X.509 certificates are ASN.1 structures (see the sidebar "XML Versus ASN.1 Paradigm Shift: A Battle to the Death?" in Chapter 2), and there is a common thread across XML security standards to not force applications to have both ASN.1 and XML parsers. However, X.509 certificates (either directly included or specified via some identifier approach) have two distinct advantages over other methods of providing keys:

  • Most applications, tools, libraries, and environments support X.509 processing.

  • X.509 certificates are digitally signed by a certificate authority in a standard way that leads to trust decisions. We discuss trust issues in depth in Chapter 9, but suffice it to say here that "trusting" that the key really represents the identity you think it does is fundamental to digital signatures. X.509 certificates fit into a relatively mature (although at times overly complex) strategy for establishing that a key is legitimate .

In certain circumstances, you might receive something other than an X.509 certificate or pointer to an X.509 certificate. These situations are most likely to occur when you are working within a known trust domain. In this case, the raw public key may even be provided directly in the KeyInfo structure.

KeyInfo is discussed again in later chapters about XML Encryption (which also uses KeyInfo and adds a few elements) and XKMS. XKMS allows you to pass a KeyInfo element to a "trust engine" to determine whether, based on your own trust policies, you can trust the key located through this KeyInfo .

Now let's examine the possible KeyInfo sub-elements.

KeyName

The KeyName element is simply a name to identify the key. It could be some string agreed upon in advance, or it could represent a unique value used to look up the key in a directory. For example, KeyName could contain an email address or a Distinguished Name (DN) for a digital certificate.

KeyValue

The KeyValue element is the actual key itself embedded in the XML. The format of this element varies based on the type of key. The two types of keys mentioned in the XML specification are DSA and RSA. Each of these has its own elements as children of KeyValue , DSAKeyValue , and RSAKeyValue .

RetrievalMethod

The RetrievalMethod element is used to reference a key that is stored at a separate location. It contains a URI (like the Reference URI) pointing to the key with an optional Type for the type of key information being retrieved. Most of the major KeyInfo elements can be targeted by RetrievalMethod . The valid Type values for remote KeyInfo structures are as follows :

http://www.w3.org/2000/09/xmldsig#DSAKeyValue

http://www.w3.org/2000/09/xmldsig#RSAKeyValue

http://www.w3.org/2000/09/xmldsig#X509Data

http://www.w3.org/2000/09/xmldsig#PGPData

http://www.w3.org/2000/09/xmldsig#SPKIData

http://www.w3.org/2000/09/xmldsig#MgmtData

In addition to these, there is a Type value for a binary X.509 certificate:

http://www.w3.org/2000/09/xmldsig#rawX509Certificate

One use of the RetrievalMethod element is to save space in the XML document because KeyInfo values such as X.509 certificates can be large. If multiple signatures use the same key or perhaps part of a certificate chain, you can store the KeyInfo structure in a standalone element in the document with a unique ID attribute and then refer to it using the same document reference in each Signature element's KeyInfo RetrievalMethod URI attributes.

X509Data

The X509Data element is a commonly used KeyInfo element. The objective of the X509Data element is to provide either an identifier to look up an X.509 certificate or the X.509 certificate itself.

A certificate chain can also be contained in X509Data . The idea is that there would be a set, or chain, of related certificates under X509Data . A certificate chain typically means all the certificates necessary to get to a root certificate. See Chapter 3 for more information about certificate chains and root certificates.

PGPData

The PGPData element is similar to the X509Data element; it can either point you to a PGP key or contain actual key material. It is unlikely that you will use this element for XML Signatures, although it is possible and the specification allows for it. The child element PGPKeyID is a unique ID of the key, and PGPKeyPacket is a structure that can contain a PGP public and/or private key. PGPKeyID and PGPKeyPacket are defined in the OpenPGP standard [3] . The PGPData and SPKIData elements are written flexibly, so elements in a different namespace can add to these elements, or if a PGP XML standard is written, it could replace the PGPData element.

[3] RFC2440: OpenPGP Message Format. J. Callas, L. Donnerhacke, H. Finney, and R. Thayer. November 1998. http://www.ietf.org/rfc/rfc2440.txt

SPKIData

The Simple Public Key Infrastructure (SPKI) was an effort to improve and simplify PKI. It does not have much momentum right now, due to slow commercial acceptance, so you are unlikely to need to use it. The structure of SPKIData is similar to PGPData in the sense that it contains sub-elements to help locate or contain the public key, and it can be extended and replaced by external namespace elements when and if they are defined.

We've now concluded our discussion of KeyInfo and the rest of the XML Signature elements. We will now discuss strategies for actual usage of XML Signature

 <  Day Day Up  >  


Securing Web Services with WS-Security. Demystifying WS-Security, WS-Policy, SAML, XML Signature, and XML Encryption
Securing Web Services with WS-Security: Demystifying WS-Security, WS-Policy, SAML, XML Signature, and XML Encryption
ISBN: 0672326515
EAN: 2147483647
Year: 2004
Pages: 119

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net