Yes, you can secure your Web services documents, Part 2

XML Signature ensures your XML documents' integrity

1 2 3 Page 3
Page 3 of 3

Remember, we set the ID of the signed elements in preparing an enveloping signature. The ID is used to refer to the corresponding Object that wraps the signed data. During verification, somebody must resolve that ID and get the actual signed resource—IDResolver does just that. AdHocIDResolver is a simple implementation of IDResolver that proves sufficient for our examples.

The method verify() returns an instance of Validity, which lets you check each Reference's validity (more than one can exist). To check whether the signature itself is valid, that is, that SignedInfo and all its inside References are valid, use this call:

boolean isValid = val.getCoreValidity();

Now, what if you don't have a java.security.Key to pass to verify()? In all our previous examples, we didn't pass a key, but a certificate, which contains the key. The certificate is contained inside the signature's KeyInfo element.

So ideally, you should have another resolver that resolves KeyInfo to a java.security.Key. And if the signature already contains a KeyInfo, you'd want a method smart enough to realize that, extract the key, and verify the signature with it.

That's why I came up with a resolver (I call it a KeyInfoResolver, to be exact) for this article's downloadable sample. With this resolver help's, the helper class I've written allows you to just use one line of code to verify an XML signature:

   Validity val = XMLSignature.verify(sigElement);

XMLSignature.verify() uses a KeyInfoResolver instance (Note: this differs from KeyInfoResolver in XML Encryption); specifically, it uses a class that I named ever-so-unimaginatively KeyAndCertKeyInfoResolver.

This class knows how to get a key out of a KeyInfo if it's just a simple key or a certificate chain—which proves sufficient for many cases, including our examples. The class even knows how to validate a certificate chain if you pass it a KeyInfo containing the signer's certificate and a certificate chain that goes to the trust anchor (that is, the self-issued root certificate). Here's what the class's resolve() method looks like:

   public Key resolve(KeyInfo keyInfo)
      throws 
      KeyInfoResolvingException {
      Key extractedKey = keyInfo.getKeyValue();
      // This is good, assume this one
      if(extractedKey != null) {
         return extractedKey;
      } else {
        
         // Else check if there are
         // certificates there. The code below
         // assumes there's only one X509Data;
         // if there are more, just use the first.
         KeyInfo.X509Data[] x509Data = keyInfo.getX509Data();
         if (x509Data != null && x509Data.length > 0) {
            KeyInfo.X509Data x509DataItem = x509Data[0];
    
            // Get certificates
            X509Certificate[] certs = x509DataItem.getCertificates();
            if (certs == null || certs.length <= 0) {
               throw new KeyInfoResolvingException(
                 "No certificate in X509Data!");
            }
            // Get CRL for checking
            X509CRL crl = x509DataItem.getCRL();
            // verifyCertificates
            extractedKey = verifyCertificatesAndExtractKey(certs, crl);
         } else {
            // No key, no X509Data, give up
            throw new KeyInfoResolvingException(
              "This resolver doesn't know how to handle this KeyInfo.");
         }
      }        
      return extractedKey;
   }

Things to look forward to

In this article, you learned about XML Signature and the problems that accompany the flexibility of an XML-aware digital signature mechanism, as well as those problems' solutions. You also saw what XML Signatures look like, with all the variations in the coupling of the signature and signed data. You also learned how to easily generate XML Signatures with IBM's XSS; just look at the snippets sprinkled throughout the article, download the source bundle, and play around with it.

As of now, XML Signature is already more developed than its cousin XML Encryption. The official Java API for XML Signature should be coming out soon, so be on the look out. JavaOne 2002 featured a high-level overview of the API, and from the look of it, I gather it will be quite easy to learn and use. For example, the API features a class called XMLSignatureMarshaller, which converts XML Signatures to/from XML. If this is not the template feature we've come to know, I don't know what is. The API also includes Transforms, URIDereferencer, and so on, whose names, after reading this article, should clue you in to their functionalities.

Last but not least, XML Signature operates under the assumption that key distribution and registration has already been handled. This article's examples are trivial—we created the key and then used it to verify the signatures. In the real world, things are definitely more complicated. Keys must be registered and distributed properly, and trust relationships must be established. XKMS (XML Key Management Specification), related to Java Specification Request 104, tries to address these issues. In any case, many new and interesting things are emerging from XML security, and with its strong tie to Web services security, you can bet an official Java API will follow soon.

Ray Djajadinata first encountered Java in 1995 when he saw Duke cartwheeling inside the HotJava browser. He then wrote introductory Java articles for a local programming magazine and explored the language further while still using C++ at work. In 1999, he switched to Java at work as well, and he's been hooked ever since. Currently he's a senior technical manager at eXtropia, an open Web technology company. He likes eXtropia because the company encourages employees to embrace new technologies. He also gets to work on cool products like the eXtropia Digital Signing application, which triggered his research about the topic of this series.

Learn more about this topic

1 2 3 Page 3
Page 3 of 3