Supporting Digital Signatures Within SOAP Messages (cont.)

Client SOAP Processing
The client identifies the Web service interface description to which it is submitting a request. This can be done either through a UDDI browser, which is part of the SOAP client-side toolkit or through verbal/written communication with the service provider, if it is an internal enterprise application. Once the service endpoint is identified, the client generates the stub files through the use of the SOAP toolkit generator. The client writes the code to invoke the SOAP request, providing the necessary data, such as service endpoint URL and method argument values. The following code shows how to do this:

Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(new 
java.net.URL("http://localhost:8080/axis/servlet/AxisServlet));
	SOAPEnvelope env = new SOAPEnvelope();
// XMLUtils.StringToElement() creates an XML Element for the given 
// (namespace, elementName, textValue) combination
SOAPBodyElement sbe = new SOAPBodyElement(XMLUtils.StringToElement(
"http://localhost:8080/MyService", "methodName", ""));
env.addBodyElement(sbe);
	// Invoke service
	call.invoke(env);	
// Get response
MessageContext mc = call.getMessageContext();
Message response = mc.getResponseMessage();

Next, add the logic to sign the SOAP body element. The key gains access to the SOAP body element. Once the body element has been extracted from the SOAP document, it becomes the input for the XML-Signature document processing. The following code sample does this using Apache Axis and XML Security packages.

// SOAPEnvelope has already been created and is stored in env
// Actually add the SOAP signature header
env.addMapping(new Mapping
("http://schemas.xmlsoap.org/soap/security/2000-12", 
"SOAP-SEC"));
env.addAttribute(Constants.URI_SOAP_ENV, "actor", "some-uri");
env.addAttribute(Constants.URI_SOAP_ENV, "mustUnderstand", "1");
SOAPHeader header = new SOAPHeader(
XMLUtils.StringToElement(SOAPSECNS, "Signature", ""));
env.addHeader(header);

// Get the SOAPEnvelope as a XML Document so we can extract the SOAP
// Signature element just added for use in creating the XML Signature.
StringWriter writer = new StringWriter();
SerializationContext serializeContext = 
new SerializationContextImpl(writer, null);
env.output(serializeContext);
writer.close();

Reader reader = new StringReader(writer.getBuffer().toString());
Document doc = XMLUtils.newDocument(new InputSource(reader));

// Get the Signature Element from the Header
Element soapHeaderElement = (Element) 
((Element) doc.getFirstChild
()).getElementsByTagNameNS("*", "Header").item(0);
Element soapSignatureElement = 
(Element)soapHeaderElement.getElementsByTagNameNS
("*", "Signature").item(0);

	// http://xml-security is the base-uri, which needs 
	??to be unique within document
XMLSignature sig = new XMLSignature(doc, "http://xml-security",
XMLSignature.ALGO_ID_SIGNATURE_DSA);

// Add SOAP Body to XML Signature and sign.
soapSignatureElement.appendChild(sig.getElement());
// Neat trick: since the XMLSignature is actually a part of the
// SOAP XML document, the SOAP body is referenced as a URI fragment
sig.addDocument("#Body");

Most of the commercial cryptographic toolkits provide APIs for generating an XML-Signature document, given the data to sign, the private key, and the public key/certificate. The following code shows how to do this (again, assuming Apache Axis and Apache XML Security toolkits). For simplicity, the code retrieves the private key from a key store. This is not recommended for deployment scenarios with high security needs since the key store provides minimal protection for the private key.

// Extract the private key & certificate from the key store 
KeyStore ks = KeyStore.getInstance("JKS");
FileInputStream fis = new FileInputStream("keyStoreFileName");
            ks.load(fis, "keyStorePassword".toCharArray());
       	PrivateKey privateKey = (PrivateKey) ks.getKey
		("privateKeyAlias",
		                    "privateKeyPass".toCharArray());
X509Certificate cert =
                    (X509Certificate) ks.getCertificate
					("certificateAlias");
	
// Add the digital certificate and public key to XML 
//Signature document. Assumption is XMLSignature document 
//was created earlier. See above code sample
       sig.addKeyInfo(cert);
       sig.addKeyInfo(cert.getPublicKey());
	// Sign the XML Signature document with our private key
       sig.sign(privateKey);

	// Transform XML Signature Document
       Canonicalizer c14n = 
       		Canonicalizer.getInstance
			(Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);
	// Assumption is Document was extracted from SOAP Envelope earlier
byte[] canonicalMessage = c14n.canonicalizeDocument(doc);

	// Create a Deserializer for the XML Signature document
InputSource is = new InputSource(new 
java.io.ByteArrayInputStream(canonicalMessage)); 
AxisClient tmpEngine = new AxisClient(new NullProvider());
// env is SOAPEnvelope instance
DeserializationContextImpl dser = new DeserializationContextImpl(
is, new MessageContext(tmpEngine), Message.REQUEST, env);
dser.parse();

Now the SOAP document, a single XML document, is ready for transport to the server.


Putting It All Together

Server Signature Processing

Introduction What You Will Need on the Server-Side
Putting It All Together Client SOAP Processing
Server Signature Processing Code Sample


 




 TALK BACK
With all the kvetching about Web services security, are digital signatures just the thing that business need to finally embrace Web services? Or is this just a sad drop in the bucket? Tell us what you think about the potential for digitally signed SOAP messages in security.internet.
Click here to Join
An Overview of the Technologies Used

Available SOAP Toolkits

Open Source Java Cryptography Extension (JCE) Implementations

Leading Web/Servlet Engines

Public Key Infrastucture (PKI) Vendors

The XML Key Management Specification

UDDI.org

WebServices.org

Java Zone

Web Development Zone

DevX Special Report: Winning with Web Services

More Web Services Articles





 
Sponsored Links

Advertising Info  |   Member Services  |   Contact Us  |   Help  |   Feedback  |   Site Map
Jupiterweb networks

internet.comearthweb.comDevx.comClickZ

Search Jupiterweb:

Jupitermedia Corporation has four divisions:
JupiterWeb, JupiterResearch, JupiterEvents, and JupiterImages

Copyright 2004 Jupitermedia Corporation All Rights Reserved.
Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

Jupitermedia Corporate Info | Newsletters | Tech Jobs | E-mail Offers

Copyright Information/Privacy Statement