import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.apache.xerces.parsers.DOMParser;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import com.ibm.xml.enc.AlgorithmFactoryExtn;
import com.ibm.xml.enc.EncryptionContext;
import java.io.InputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.ByteArrayInputStream;
import java.util.Vector;
import org.apache.xpath.XPathAPI;
public class WSSMessage
{
private Document wssMessage = null;
WSSMessage(String wssMessageString) {
/*
* The incoming string is supposed to be a valid and well-formed SOAP document.
* If it is not a SOAP document, throw InvalidSOAPMessage exception and return.
* If it is a valid SOAP message, load it into a DOM document.
* The WSSMessage string may or may not contain
* a WSS security header and XMLDS / XENC tags.
* Parse WSS Security header and XMLDS/XENC tags to:
* 1. Load all tokens into a list of Token objects.
* 2. Load all the ds:Signature elements into a list of Signature objects.
* Each Signature object also needs a Token associated with the Signature.
* So detect which Token object corresponds to a Signature object
* and pass on the Token to the Signature constructor.
* 3. Load all the xenc:EncryptedData elements into a list of EncryptedData objects.
* Each EncryptedData object also needs a Token associated with it.
* So detect which Token object corresponds to an Encrypteddata object
* and pass on the Token to the EncryptedData constructor.
*/
DOMParser dp = new DOMParser();
InputStream byteData = null;
byteData = new ByteArrayInputStream (wssMessageString.getBytes());
try
{
dp.parse ( new InputSource ( byteData ) );
}
catch ( Exception e )
{
System.out.println ( "Exception in parsing the document..." );
e.printStackTrace();
}
wssMessage = dp.getDocument();
}//WSSMessage
public Document getWSSDocument() {
return wssMessage;
}//getWSSDocument()
public boolean addToken(Token token) {
/*
* Prepend the token to the WSS security header.
*/
return false;
}//addToken
public String addId(String XPathExpression, String wsuId) {
/*
* If any of the two parameters of this method is null, return null.
* Apply the XPathExpression XPath filter to the WSS message
* to come up with a single element.
* If the XPath expression results in more than one element, return null.
* Add an attribute named wsu:Id to the element.
* The value of the wsu:Id attribute should be wsuId.
* @ return wsuId.
*/
return null;
}//addID
public EncryptedData encryptElement(
String wsuElementID,
Token token,
String wsuEncryptedElementID,
String encryptionAlgo
) {
/*
* Find the element in the WSS message whose wsu:Id attribute matches with
* wsuElementID.
* XML encrypt the element using encryptionAlgo and key wrapped inside
* the token object.
* @ return the resulting EncryptedData object.
*/
Element root = wssMessage.getDocumentElement();
String xpathString = "//*[@Id=\"" + wsuElementID + "\"]";
Element plainTextElement = null;
try {
plainTextElement = (Element)XPathAPI.selectSingleNode(root, xpathString);
}//try
catch ( Exception e ) {
System.out.println ( "Exception in getting the plainTextElement." );
e.printStackTrace();
}//catch
return new EncryptedData (
encrypt (
root,
plainTextElement,//getElementByWSUId ( root, wsuElementID ),
token,
wsuEncryptedElementID,
encryptionAlgo
),
wsuEncryptedElementID,
token,
this
);
}//encryptElement
public EncryptedData encryptElementWithXPath (
String XPathExpression,
Token token,
String wsuEncryptedElementID,
String encryptionAlgo
) {
/*
* Find an element in the WSS message by applying
* XPathExpression on the WSS message.
* XML encrypt the element using cryptographic algorithm and key wrapped inside
* the token object.
* @ return the resulting EncryptedData object.
*/
Element root = wssMessage.getDocumentElement();
Element plainTextElement = null;
try {
plainTextElement =
(Element)XPathAPI.selectSingleNode(root, XPathExpression);
}
catch ( Exception e ) {
System.out.println ( "Exception in getting the plainTextElement." );
e.printStackTrace();
}
return new EncryptedData (
encrypt (
root,
plainTextElement,
token,
wsuEncryptedElementID,
encryptionAlgo
),
wsuEncryptedElementID,
token,
this
);
}//encryptElementWithXPath
public String sign(
String wsuElementID,
Token token,
String wsuSignatureID,
String digestAlgo,
String signatureAlgo,
String canonicalizationAlgo
) {
/*
* Find the element in the WSS message whose
* wsu:Id attribute matches with wsuElementID.
* XML sign the element using signatureAlgo and key wrapped inside
* the token object.
* Wrap the resulting ds:Signature element in a Signature object.
* @ return the Signature object.
*/
return null;
}//sign
public String signWithXPath(
String XPathExpression,
Token token,
String wsuSignatureID,
String digestAlgo,
String signatureAlgo,
String canonicalizationAlgo
) {
/*
* Find an element in the WSS message by applying XPathExpression on the WSS message.
* XML sign the element using cryptographic algorithm and key wrapped inside
* the token object.
* Wrap the resulting ds:Signature element in a Signature object.
* @ return the Signature object.
*/
return null;
}//sign
public Token[] getAllTokens() {
/*
* @ return the list of all tokens associated with the message.
*/
return null;
}//getAllTokens
public String[] getAllSignatures() {
/*
* @ return a list of all signatures associated with this WSS message.
*/
return null;
}//getAllSignatures
public String[] getAllEncryptedData() {
/*
* @ return a list of all EncryptedData structures associated with this WSS message.
*/
return null;
}//EncryptedData()
protected Element encrypt (
Element root,
Element plainTextElement,
Token token,
String wsuEncryptedElementID,
String encryptionAlgo
) {
Element encryptedElement = null;
if ( plainTextElement != null ){
if ( token.getType().equals( "EncryptedKeyToken" ) ) {
EncryptedKeyToken encToken = (EncryptedKeyToken)token;
encryptedElement = encToken.encrypt ( wsuEncryptedElementID, encryptionAlgo, plainTextElement );
String encKey = encToken.getXMLString();
Document sourceDoc = loadDocument ( encKey );
addTokenToWSSEHeader ( sourceDoc, wssMessage );
}//if
else if ( token.getType().equals( "EncryptedKeyTokenWithCrossReference" ) ) {
EncryptedKeyTokenWithCrossReference encTokenRef = (EncryptedKeyTokenWithCrossReference)token;
encryptedElement = encTokenRef.encrypt ( wsuEncryptedElementID, encryptionAlgo, plainTextElement );
String encKey = encTokenRef.getXMLString();
addTokenToWSSEHeader ( loadDocument(encKey), wssMessage );
}//else if
}//if
return encryptedElement;
}//encrypt
private Document loadDocument ( String XMLString ) {
DOMParser dp = new DOMParser();
InputStream byteData = null;
byteData = new ByteArrayInputStream (XMLString.getBytes());
try
{
dp.parse ( new InputSource ( byteData ) );
}catch ( Exception e )
{
System.out.println ( "The XMLString is not loaded." );
e.printStackTrace();
}
return dp.getDocument();
}//loadDocument
private void addTokenToWSSEHeader (
Document sourceDoc,/*token*/
Document targetDoc /*wssMessage*/
) {
try {
Element header = (Element)targetDoc.getElementsByTagNameNS
("http://www.w3.org/2001/12/soap-envelope",
"Header").item(0);
if ( header == null )
{
header = targetDoc.createElementNS
("http://www.w3.org/2001/12/soap-envelope",
"Header" );
header.setAttribute(
"xmlns",
"http://www.w3.org/2001/12/soap-envelope"
);
targetDoc.getDocumentElement().insertBefore(
header,
targetDoc.getDocumentElement().getFirstChild()
);
}//if
Element wsseSecurity = (Element)header.getElementsByTagNameNS
("http://schemas.xmlsoap.org/ws/2003/06/secext",
"Security").item(0);
if ( wsseSecurity == null )
{
wsseSecurity = targetDoc.createElementNS
("http://schemas.xmlsoap.org/ws/2003/06/secext",
"Security" );
wsseSecurity.setAttribute(
"xmlns",
"http://schemas.xmlsoap.org/ws/2003/06/secext"
);
header.insertBefore(
wsseSecurity,
header.getFirstChild()
);
}//if of wsseSecurity
Element sourceDocEl = sourceDoc.getDocumentElement();
Element wsseSecFirstEl = (Element) wsseSecurity.getFirstChild();
wsseSecurity.insertBefore (
(Element) targetDoc.importNode(sourceDocEl, true),
wsseSecFirstEl );
}
catch ( Exception e ) {
System.out.println ( "Exception in the addTokenToWSSEHeader..." );
e.printStackTrace();
}//catch
}//addTokenToWSSEHeader
}//WSSClient