You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by di...@apache.org on 2003/10/14 14:04:28 UTC
cvs commit: ws-axis/contrib/wss4j/src/org/apache/ws/security WSConstants.java WSSecurityDecryptionHandler.java WSSecurityEncryptionHandler.java WSSecurityEngine.java WSSecurityException.java WSSecuritySigningHandler.java WSSecurityVerifyHandler.java errors.properties
dims 2003/10/14 05:04:28
Added: contrib/wss4j/src/org/apache/ws/security WSConstants.java
WSSecurityDecryptionHandler.java
WSSecurityEncryptionHandler.java
WSSecurityEngine.java WSSecurityException.java
WSSecuritySigningHandler.java
WSSecurityVerifyHandler.java errors.properties
Log:
******* WORK IN PROGRESS *******
Initial check-in of my sandbox for ws-security related code.
Revision Changes Path
1.1 ws-axis/contrib/wss4j/src/org/apache/ws/security/WSConstants.java
Index: WSConstants.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ws.security;
/** Constants in WS-Security spec. */
public interface WSConstants {
public static final String WSSE_NS = "http://schemas.xmlsoap.org/ws/2002/07/secext";
public static final String WSSE_PREFIX = "wsse";
public static final String WSSE_LN = "Security";
public static final String WSU_NS = "http://schemas.xmlsoap.org/ws/2002/07/utility";
public static final String WSU_PREFIX = "wsu";
public static final String SIG_NS = "http://www.w3.org/2000/09/xmldsig#";
public static final String SIG_LN = "Signature";
public static final String ENC_NS = "http://www.w3.org/2001/04/xmlenc#";
public static final String ENC_PREFIX = "xenc";
public static final String SOAP_NS = "http://schemas.xmlsoap.org/soap/envelope/";
public static final String SOAP_SEC_NS = "http://schemas.xmlsoap.org/soap/security/2000-12";
public static final String XMLNS_NS = "http://www.w3.org/2000/xmlns/";
}
1.1 ws-axis/contrib/wss4j/src/org/apache/ws/security/WSSecurityDecryptionHandler.java
Index: WSSecurityDecryptionHandler.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ws.security;
import org.apache.axis.AxisFault;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.handlers.BasicHandler;
import org.apache.axis.message.SOAPHeaderElement;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.security.util.AxisUtil;
import org.w3c.dom.Document;
/**
* Axis Handler for Decrypting WS-Security soap messages.
* <p>
* @author Davanum Srinivas (dims@yahoo.com).
*/
public class WSSecurityDecryptionHandler extends BasicHandler {
private static Log log = LogFactory.getLog(WSSecurityDecryptionHandler.class);
private static final WSSecurityEngine secEngine = new WSSecurityEngine();
/**
* invoke is called by Axis when a message is handled.
* <p>
* @param msgContext message context.
* @throws AxisFault
*/
public void invoke(MessageContext msgContext) throws AxisFault {
try {
log.info("Starting Server verification");
Message sm = msgContext.getRequestMessage();
// Mark the Header as processed.
SOAPHeaderElement headerElement = sm.getSOAPEnvelope().getHeaderByName(WSConstants.WSSE_NS, WSConstants.WSSE_LN);
if (headerElement != null) {
headerElement.setProcessed(true);
}
Document doc = secEngine.decryptMessage(sm.getSOAPEnvelope());
AxisUtil.updateSOAPMessage(doc, sm);
log.info("The decryption is done");
} catch (Exception e) {
e.printStackTrace();
log.info("The decryption is NOT done");
throw AxisFault.makeFault(e);
}
}
}
1.1 ws-axis/contrib/wss4j/src/org/apache/ws/security/WSSecurityEncryptionHandler.java
Index: WSSecurityEncryptionHandler.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ws.security;
import org.apache.axis.AxisFault;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.handlers.BasicHandler;
import org.apache.axis.message.SOAPEnvelope;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.security.message.WSEnvelopeBuilder2;
/**
* Axis Handler for Encrypting soap envelopes using WS-Security.
* <p>
* @author Davanum Srinivas (dims@yahoo.com).
*/
public class WSSecurityEncryptionHandler extends BasicHandler {
static Log log = LogFactory.getLog(WSSecurityEncryptionHandler.class.getName());
static final WSSecurityEngine secEngine = new WSSecurityEngine();
/**
* method called by Axis when a soap message needs to be signed.
* <p>
* @param msgContext
* @throws AxisFault
*/
public void invoke(MessageContext msgContext) throws AxisFault {
try {
Message requestMessage = msgContext.getRequestMessage();
WSEnvelopeBuilder2 builder = new WSEnvelopeBuilder2();
SOAPEnvelope unsignedEnvelope = requestMessage.getSOAPEnvelope();
SOAPEnvelope signedEnvelope = (SOAPEnvelope) builder.build(unsignedEnvelope);
requestMessage = new Message(signedEnvelope);
msgContext.setCurrentMessage(requestMessage);
} catch (Exception e) {
throw AxisFault.makeFault(e);
}
}
}
1.1 ws-axis/contrib/wss4j/src/org/apache/ws/security/WSSecurityEngine.java
Index: WSSecurityEngine.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ws.security;
import org.apache.axis.AxisFault;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.components.crypto.CryptoFactory;
import org.apache.ws.security.message.EnvelopeIdResolver;
import org.apache.ws.security.message.token.*;
import org.apache.ws.security.util.AxisUtil;
import org.apache.ws.security.util.WSSecurityUtil;
import org.apache.xml.security.encryption.XMLCipher;
import org.apache.xml.security.exceptions.Base64DecodingException;
import org.apache.xml.security.keys.KeyInfo;
import org.apache.xml.security.keys.content.X509Data;
import org.apache.xml.security.keys.content.x509.XMLX509Certificate;
import org.apache.xml.security.signature.SignedInfo;
import org.apache.xml.security.signature.XMLSignature;
import org.apache.xml.security.utils.Base64;
import org.w3c.dom.*;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeaderElement;
import java.io.ByteArrayInputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.security.cert.X509Certificate;
import java.util.Hashtable;
import java.util.Map;
/**
* WS-Security Engine.
* <p>
* @author Davanum Srinivas (dims@yahoo.com).
*/
public class WSSecurityEngine {
private static Log log = LogFactory.getLog(WSSecurityEngine.class.getName());
private static final Class[] constructorType = {org.w3c.dom.Element.class};
private static Map tokenImpl = new Hashtable();
private static boolean sigCheck = true;
private static WSSecurityEngine engine = null;
static {
org.apache.xml.security.Init.init();
tokenImpl.put(PKIPathSecurity.TYPE, PKIPathSecurity.class);
tokenImpl.put(X509Security.TYPE, X509Security.class);
}
/**
* Singleton instance of security engine.
* <p>
* @return ws-security engine.
*/
public synchronized static WSSecurityEngine getInstance() {
if (engine == null) {
engine = new WSSecurityEngine();
}
return engine;
}
/**
* handles the signature element.
* <p>
* @param element DOM Element.
* @return whether the verification was ok.
* @throws Exception Thrown when there is a problem with the signature.
*/
public boolean handleSignatureElement(Element element) throws Exception {
normalize(element);
element.removeAttributeNS(WSConstants.XMLNS_NS, "xenc");
XMLSignature sig = new XMLSignature(element, null);
sig.addResourceResolver(EnvelopeIdResolver.getInstance());
SignedInfo info = sig.getSignedInfo();
return verifyXMLSignature(sig);
}
/**
* get an array of certificates from the key info.
* <p>
* @param info KeyInfo.
* @return array of X509Certificate certificates.
* @throws Exception Thrown when there is a problem in getting the certificates.
*/
protected X509Certificate[] getCertificatesX509Data(KeyInfo info) throws Exception {
int len = info.lengthX509Data();
if (len != 1) {
throw new WSSecurityException(WSSecurityException.FAILURE, "invalidX509Data", new Object[]{new Integer(len)});
}
X509Data data = info.itemX509Data(0);
int certLen = data.lengthCertificate();
if (certLen <= 0) {
throw new WSSecurityException(WSSecurityException.FAILURE, "invalidCertData", new Object[]{new Integer(certLen)});
}
X509Certificate[] certs = new X509Certificate[certLen];
XMLX509Certificate xmlCert;
ByteArrayInputStream input;
for (int i = 0; i < certLen; i++) {
xmlCert = data.itemCertificate(i);
input = new ByteArrayInputStream(xmlCert.getCertificateBytes());
certs[i] = CryptoFactory.getInstance().loadCertificate(input);
}
return certs;
}
/**
* get certificates from the token reference.
* <p>
* @param elem
* @return
* @throws Exception
*/
protected X509Certificate[] getCertificatesTokenReference(Element elem) throws Exception {
SecurityTokenReference secRef = new SecurityTokenReference(elem);
Reference ref = secRef.getReference();
if (ref == null) {
throw new WSSecurityException(WSSecurityException.INVALID_SECURITY, "noReference");
}
String uri = ref.getURI();
log.debug("Token reference uri: " + uri);
if (uri == null) {
throw new WSSecurityException(WSSecurityException.INVALID_SECURITY, "badReferenceURI");
}
Element tokElement = WSSecurityUtil.getElementById(elem.getOwnerDocument(), uri);
if (tokElement == null) {
throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE, "noToken", new Object[]{uri});
}
BinarySecurity token = createSecurityToken(tokElement);
if (token instanceof PKIPathSecurity) {
return ((PKIPathSecurity) token).getX509Certificates(true);
} else if (token instanceof X509Security) {
X509Certificate cert = ((X509Security) token).getX509Certificate();
X509Certificate[] certs = new X509Certificate[1];
certs[0] = cert;
if (certs == null) {
throw new WSSecurityException(WSSecurityException.FAILURE, "invalidCertData", new Object[]{new Integer(0)});
}
return certs;
} else {
throw new WSSecurityException(WSSecurityException.UNSUPPORTED_SECURITY_TOKEN, "unhandledToken", new Object[]{token.getClass().getName()});
}
}
/**
* verify the ws-security signature.
* <p>
* @param sig
* @return
* @throws Exception
*/
public boolean verifyXMLSignature(XMLSignature sig) throws Exception {
log.debug("Verify XML Signature");
X509Certificate[] certs = null;
KeyInfo info = sig.getKeyInfo();
if (info.containsX509Data()) {
certs = getCertificatesX509Data(info);
} else {
Node node = WSSecurityUtil.getDirectChild(info.getElement(), SecurityTokenReference.TOKEN.getLocalPart(), SecurityTokenReference.TOKEN.getNamespaceURI());
if (node == null) {
throw new WSSecurityException(WSSecurityException.INVALID_SECURITY, "unsupportedKeyInfo", null);
} else {
certs = getCertificatesTokenReference((Element) node);
}
}
certs[0].checkValidity();
if (sigCheck && !sig.checkSignatureValue(certs[0])) {
throw new WSSecurityException(WSSecurityException.FAILED_CHECK);
}
return false;
}
/**
* process the security header given the soap envelope.
* <p>
* @param env
* @param actor
* @return
* @throws Exception
*/
public Document processSecurityHeader(SOAPEnvelope env, String actor) throws Exception {
if (actor == null) {
actor = "";
}
// check if there are any WS-Security headers
SOAPHeaderElement he = WSSecurityUtil.getSecurityHeader(env, actor);
if (he == null) {
return null;
}
log.info("Found WS-Security header(s)");
// convert env to DOM and iterate through the WS-Security elements in it
Document doc = AxisUtil.toDocument(env);
NodeList list = doc.getElementsByTagNameNS(WSConstants.WSSE_NS, WSConstants.WSSE_LN);
int len = list.getLength();
Element elem = null;
Attr attr = null;
String headerActor = null;
for (int i = 0; i < len; i++) {
elem = (Element) list.item(i);
attr = elem.getAttributeNodeNS(WSConstants.SOAP_NS, "actor");
if (attr != null) {
headerActor = attr.getValue();
}
if ((headerActor == null) || (headerActor.length() == 0) || headerActor.equalsIgnoreCase(actor) || headerActor.equals("http://schemas.xmlsoap.org/soap/actor/next")) {
processSecurityHeader(elem, headerActor);
}
}
return doc;
}
/**
* process the security header given the DOM Element.
* <p>
* @param securityHeader
* @param actor
* @throws Exception
*/
public void processSecurityHeader(Element securityHeader, String actor) throws Exception {
log.info("Processing WS-Security header for '" + actor + "' actor.");
NodeList list = securityHeader.getChildNodes();
int len = list.getLength();
Node elem;
for (int i = 0; i < len; i++) {
elem = list.item(i);
if (WSConstants.SIG_NS.equalsIgnoreCase(elem.getNamespaceURI()) && WSConstants.SIG_LN.equalsIgnoreCase(elem.getLocalName())) {
// found SignedInfo element
log.info("Found signature element");
handleSignatureElement((Element) elem);
} else {
log.debug(elem.getLocalName() + " " + elem.getNamespaceURI());
}
}
}
/**
* Replaces all Text nodes that start with "\n " or "\n\n" with
* "\n" This is only used by signature callback.
* There is a bug somewhere in serliazation/deserialization code
* that appends spaces to \n Text nodes for no reason breaking
* the signature stuff.
* <p>
* @param node
*/
public static void normalize(Node node) {
if (node.getNodeType() == Node.TEXT_NODE) {
String data = ((Text) node).getData();
if ((data.length() > 1) && (data.charAt(0) == 10) && ((data.charAt(1) == 10) || (data.charAt(1) == 32))) {
((Text) node).setData("\n");
}
}
for (Node currentChild = node.getFirstChild(); currentChild != null; currentChild = currentChild.getNextSibling()) {
normalize(currentChild);
}
}
/**
* TODO: Put description here.
* <p>
* @param element
* @return
* @throws WSSecurityException
*/
public BinarySecurity createSecurityToken(Element element) throws WSSecurityException {
BinarySecurity token = new BinarySecurity(element);
QName type = token.getValueType();
Class clazz = (Class) tokenImpl.get(type);
if (clazz == null) {
throw new WSSecurityException(WSSecurityException.UNSUPPORTED_SECURITY_TOKEN, "unsupportedBinaryTokenType", new Object[]{type});
}
try {
Constructor constructor = clazz.getConstructor(constructorType);
if (constructor == null) {
throw new WSSecurityException(WSSecurityException.FAILURE, "invalidConstructor", new Object[]{clazz});
}
return (BinarySecurity) constructor.newInstance(new Object[]{element});
} catch (InvocationTargetException e) {
Throwable ee = e.getTargetException();
if (ee instanceof WSSecurityException) {
throw (WSSecurityException) ee;
} else {
throw new WSSecurityException(WSSecurityException.FAILURE, null, null, e);
}
} catch (NoSuchMethodException e) {
throw new WSSecurityException(WSSecurityException.FAILURE, null, null, e);
} catch (InstantiationException e) {
throw new WSSecurityException(WSSecurityException.FAILURE, null, null, e);
} catch (IllegalAccessException e) {
throw new WSSecurityException(WSSecurityException.FAILURE, null, null, e);
}
}
public Document decryptMessage(SOAPEnvelope soapEnvelope) throws Exception {
Document doc = AxisUtil.toDocument(soapEnvelope);
Element envelope = doc.getDocumentElement();
envelope.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:" + WSConstants.ENC_PREFIX, WSConstants.ENC_NS);
Element nsContext = WSSecurityUtil.createNamespaceContext(doc);
Element wsseSecurity = WSSecurityUtil.findWsseSecurityHeaderBlock(doc, envelope, true);
Element xencEncryptedKey = (Element) WSSecurityUtil.selectSingleNode(wsseSecurity, "xenc:EncryptedKey", nsContext);
if (xencEncryptedKey == null) {
throw new AxisFault("Message wsse:SecurityHeader does not contain xenc:EncryptedKey");
}
Element xencCipherValue = (Element) WSSecurityUtil.selectSingleNode(xencEncryptedKey, "xenc:CipherData/xenc:CipherValue", nsContext);
if (xencCipherValue == null) {
throw new AxisFault("Message xenc:EncryptedKey does not contain xenc:CipherData/xenc:CipherValue");
}
byte[] encryptedBytes = getDecodedBase64EncodedData(xencCipherValue);
Cipher cipher = Cipher.getInstance("RSA");
Crypto crypto = CryptoFactory.getInstance();
if (crypto == null) {
throw new Exception("no credentials");
}
cipher.init(Cipher.DECRYPT_MODE, crypto.getPrivateKey());
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
DESedeKeySpec keySpec = new DESedeKeySpec(decryptedBytes);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
SecretKey symmetricKey = keyFactory.generateSecret(keySpec);
XMLCipher xmlCipher = XMLCipher.getInstance(WSConstants.ENC_NS + "tripledes-cbc");
xmlCipher.init(XMLCipher.DECRYPT_MODE, symmetricKey);
Element firstChild = (Element) WSSecurityUtil.selectSingleNode(envelope, "env:Body/*", nsContext);
xmlCipher.doFinal(doc, firstChild);
wsseSecurity.getParentNode().removeChild(wsseSecurity);
return doc;
}
/**
* TODO: Put description here.
* <p>
* @param element
* @return
* @throws Exception
*/
public static byte[] getDecodedBase64EncodedData(Element element) throws Exception {
StringBuffer sb = new StringBuffer();
NodeList children = element.getChildNodes();
int iMax = children.getLength();
for (int i = 0; i < iMax; i++) {
Node curr = children.item(i);
if (curr.getNodeType() == 3)
sb.append(((Text) curr).getData());
}
String encodedData = sb.toString();
try {
return Base64.decode(encodedData);
} catch (Base64DecodingException e) {
throw new Exception("Unable to decode Base64 encoded data", e);
}
}
}
1.1 ws-axis/contrib/wss4j/src/org/apache/ws/security/WSSecurityException.java
Index: WSSecurityException.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ws.security;
import java.rmi.RemoteException;
import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
/**
* Exception class for WS-Security.
* <p>
* @author Davanum Srinivas (dims@yahoo.com).
*/
public class WSSecurityException extends RemoteException {
public static final int FAILURE = 0;
public static final int UNSUPPORTED_SECURITY_TOKEN = 1;
public static final int UNSUPPORTED_ALGORITHM = 2;
public static final int INVALID_SECURITY = 3;
public static final int INVALID_SECURITY_TOKEN = 4;
public static final int FAILED_AUTHENTICATION = 5;
public static final int FAILED_CHECK = 6;
public static final int SECURITY_TOKEN_UNAVAILABLE = 7;
private static ResourceBundle resources;
static {
try {
resources = ResourceBundle.getBundle("org.apache.ws.security.errors");
} catch (MissingResourceException e) {
throw new RuntimeException(e.getMessage());
}
}
private int errorCode;
/**
* Constructor.
* <p>
* @param errorCode
* @param msgId
* @param args
* @param exception
*/
public WSSecurityException(int errorCode, String msgId, Object[] args, Throwable exception) {
super(getMessage(errorCode, msgId, args), exception);
this.errorCode = errorCode;
}
/**
* Constructor.
* <p>
* @param errorCode
* @param msgId
* @param args
*/
public WSSecurityException(int errorCode, String msgId, Object[] args) {
super(getMessage(errorCode, msgId, args));
this.errorCode = errorCode;
}
/**
* Constructor.
* <p>
* @param errorCode
* @param msgId
*/
public WSSecurityException(int errorCode, String msgId) {
this(errorCode, msgId, null);
}
/**
* Constructor.
* <p>
* @param errorCode
*/
public WSSecurityException(int errorCode) {
this(errorCode, null, null);
}
/**
* Get the error code.
* <p>
* @return TODO: Put description of return value here.
*/
public int getErrorCode() {
return this.errorCode;
}
/**
* get the message from resource bundle.
* <p>
* @param errorCode
* @param msgId
* @param args
* @return TODO: Put description of return value here.
*/
private static String getMessage(int errorCode, String msgId, Object[] args) {
String msg = null;
try {
msg = resources.getString(String.valueOf(errorCode));
if (msgId != null) {
return msg += (" (" + MessageFormat.format(resources.getString(msgId), args) + ")");
}
} catch (MissingResourceException e) {
throw new RuntimeException("Undefined '" + msgId + "' resource property");
}
return msg;
}
}
1.1 ws-axis/contrib/wss4j/src/org/apache/ws/security/WSSecuritySigningHandler.java
Index: WSSecuritySigningHandler.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ws.security;
import org.apache.axis.AxisFault;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.handlers.BasicHandler;
import org.apache.axis.message.SOAPEnvelope;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.security.message.WSEnvelopeBuilder;
/**
* Axis Handler for adding WS-Security signature to soap envelopes.
* <p>
* @author Davanum Srinivas (dims@yahoo.com).
*/
public class WSSecuritySigningHandler extends BasicHandler {
static Log log = LogFactory.getLog(WSSecuritySigningHandler.class.getName());
static final WSSecurityEngine secEngine = new WSSecurityEngine();
/**
* method called by Axis when a soap message needs to be signed.
* <p>
* @param msgContext
* @throws AxisFault
*/
public void invoke(MessageContext msgContext) throws AxisFault {
try {
Message requestMessage = msgContext.getRequestMessage();
SOAPEnvelope unsignedEnvelope = requestMessage.getSOAPEnvelope();
WSEnvelopeBuilder builder = new WSEnvelopeBuilder();
/*
String user = "srida01";
builder.setUserInfo(user, user);
*/
SOAPEnvelope signedEnvelope = (SOAPEnvelope) builder.build(unsignedEnvelope);
requestMessage = new Message(signedEnvelope);
msgContext.setCurrentMessage(requestMessage);
} catch (Exception e) {
throw AxisFault.makeFault(e);
}
}
}
1.1 ws-axis/contrib/wss4j/src/org/apache/ws/security/WSSecurityVerifyHandler.java
Index: WSSecurityVerifyHandler.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ws.security;
import org.apache.axis.AxisFault;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.handlers.BasicHandler;
import org.apache.axis.message.SOAPHeaderElement;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
/**
* Axis Handler for verifying WS-Security soap messages.
* <p>
* @author Davanum Srinivas (dims@yahoo.com).
*/
public class WSSecurityVerifyHandler extends BasicHandler {
private static Log log = LogFactory.getLog(WSSecurityVerifyHandler.class);
private static final WSSecurityEngine secEngine = new WSSecurityEngine();
/**
* invoke is called by Axis when a message is handled.
* <p>
* @param msgContext message context.
* @throws AxisFault
*/
public void invoke(MessageContext msgContext) throws AxisFault {
try {
log.info("Starting Server verification");
Message inMsg = msgContext.getRequestMessage();
// Mark the Header as processed.
SOAPHeaderElement headerElement = inMsg.getSOAPEnvelope().getHeaderByName(WSConstants.WSSE_NS, WSConstants.WSSE_LN);
if (headerElement != null) {
headerElement.setProcessed(true);
}
Document doc = secEngine.processSecurityHeader(inMsg.getSOAPEnvelope(), "");
if (doc == null) {
throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE);
}
log.info("The signature is valid");
} catch (Exception e) {
e.printStackTrace();
log.info("The signature is NOT valid");
throw AxisFault.makeFault(e);
}
}
}
1.1 ws-axis/contrib/wss4j/src/org/apache/ws/security/errors.properties
Index: errors.properties
===================================================================
## defines error code - str message mapping
0 = General security error
1 = An unsupported token was provided
2 = An unsupported signature or encryption algorithm was used
3 = An error was discovered processing the <wsse:Security> header.
4 = An invalid security token was provided
5 = The security token could not be authenticated or authorized
6 = The signature or decryption was invalid
7 = Referenced security token could not be retrieved.
## detailed error msgs
noToken = Reference \"{0}\"
noReference = <Reference> token could not be retrieved
badReferenceURI = Reference URI is null
unhandledToken = Security token supported by currently not handled \"{0}\"
unsupportedBinaryTokenType = Token type \"{0}\"
invalidConstructor = Token impl. class \"{0}\" does not provide appropriate constructor
invalidValueType = Bad ValueType \"{0}\"
unsupportedKeyInfo = Unsupported KeyInfo type
invalidX509Data = Unexpected number of X509Data: {0}
invalidCertData = Unexpected number of certificates: {0}
invalidDataRef = Cannot handle multiple data references
noEncryptedData = Referenced encrypted data could not be retrieved. Reference \"{0}\"
badElement = Bad element, expected \"{0}\" while got \"{1}\"