< Day Day Up > |
The XML Signature ElementsSo 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 ElementAs 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 CanonicalizationCanonicalization 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:
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):
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.0Following 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):
Canonicalization Subtleties: Exclusive CanonicalizationAlthough 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 ElementSignatureMethod 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 ElementWhile 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.
The Transform ElementTransforms 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 TransformAny 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 TransformBase-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 TransformThe XPath Filtering Transform allows you take advantage of the powerful XPath language [2] . See Chapter 2 for more information on XPath.
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 TransformThe 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 TransformIt 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 TransformThe 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 ElementThe 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 ElementThe 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 ElementAt 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 ElementWe 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:
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
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:
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 ElementIn 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:
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 ElementThe 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 ElementThe 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
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:
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:
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. KeyNameThe 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. KeyValueThe 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 . RetrievalMethodThe 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. X509DataThe 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. PGPDataThe 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.
SPKIDataThe 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 > |