blob: c83228b802a344def55f58145e770cd07cf8415c [file] [log] [blame]
/*
* Copyright 2003-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package wssec;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.apache.axis.AxisFault;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.client.AxisClient;
import org.apache.axis.configuration.NullProvider;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.axis.security.WSDoAllReceiver;
import org.apache.ws.axis.security.WSDoAllSender;
import org.apache.ws.security.WSPasswordCallback;
import org.apache.ws.security.components.crypto.BouncyCastle;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.handler.WSHandlerConstants;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
/**
* <dl>
* <dt><b>Title: </b><dd>WS Security Hooks Test Case</dd>
* <p>
* <dt><b>Description: </b><dd>Test Case to verify the load...Crypto hooks work properly.
* Also tests the setKeyStore method of Merlin </dd>
* </dl>
*
* @see org.apache.ws.security.components.crypto.Merlin#setKeyStore
* @see org.apache.ws.axis.security.WSDoAllReceiver#loadSignatureCrypto
* @see org.apache.ws.axis.security.WSDoAllReceiver#loadDecryptionCrypto
* @see org.apache.ws.axis.security.WSDoAllSender#loadSignatureCrypto
* @see org.apache.ws.axis.security.WSDoAllSender#loadEncryptionCrypto
*
* @author <a href="mailto:jasone@greenrivercomputing.com>Jason Essington</a>
* @version $Revision$
*/
public class TestWSSecurityHooks extends TestCase implements CallbackHandler
{
private static Log log = LogFactory.getLog(TestWSSecurityHooks.class);
private static final String soapMessage = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+
"<soapenv:Envelope " +
"xmlns:soapenv=\"http://www.w3.org/2003/05/soap-envelope\" " +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
"<soapenv:Header>" +
"</soapenv:Header>" +
"<soapenv:Body>" +
"<ns1:echo " +
"xmlns:ns1=\"http://org.apache.wss4j.wssec/TESTCASE\" " +
"soapenv:encodingStyle=\"http://www.w3.org/2003/05/soap-encoding\">" +
"<inStr xsi:type=\"xsd:string\">ECHO ECHo ECho Echo echo echO ecHO eCHO ECHO</inStr>" +
"</ns1:echo>" +
"</soapenv:Body>" +
"</soapenv:Envelope>";
KeyStore keystore = null;
MessageContext mc = null;
public TestWSSecurityHooks(String name) {
super(name);
}
protected void setUp() throws Exception {
AxisClient tmpEngine = new AxisClient(new NullProvider());
mc = new MessageContext(tmpEngine);
mc.setCurrentMessage(getSOAPMessage(soapMessage));
mc.setProperty(WSHandlerConstants.PW_CALLBACK_REF, this);
keystore = loadKeyStore();
}
public static Test suite() {
return new TestSuite(TestWSSecurityHooks.class);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(suite());
}
//
//
// Tests
//
//
public void testCryptoHook() throws Exception {
assertNotNull("", keystore);
Crypto crypto = new TestCryptoImpl(keystore);
assertNotNull(PrivilegedAccessor.getValue(crypto, "keystore"));
}
public void testSenderLoadSignatureHook() throws Exception {
TestSenderImpl sender = new TestSenderImpl();
// we have to coerce a value into this field or we'll get a bunch of NPEs when calling decodeSignatureParameter
PrivilegedAccessor.setValue(sender, "msgContext", mc);
PrivilegedAccessor.invokeMethod(sender, "decodeSignatureParameter", new Object[] {});
assertNotNull(PrivilegedAccessor.getValue(sender, "sigCrypto"));
}
public void testSenderLoadEncryptionHook() throws Exception {
TestSenderImpl sender = new TestSenderImpl();
// decodeEcnryptionParameter() is rather insistant on having a user (anyUser)
sender.setOption(WSHandlerConstants.ENCRYPTION_USER, "anyUserWillDo");
// we have to coerce a value into this field or we'll get a bunch of NPEs when calling decodeSignatureParameter
PrivilegedAccessor.setValue(sender, "msgContext", mc);
PrivilegedAccessor.invokeMethod(sender, "decodeEncryptionParameter", new Object[] {});
assertNotNull(PrivilegedAccessor.getValue(sender, "encCrypto"));
}
public void testReceiverLoadSignatureHook() throws Exception {
TestReceiverImpl receiver = new TestReceiverImpl();
PrivilegedAccessor.invokeMethod(receiver, "decodeSignatureParameter", new Object[] {});
assertNotNull(PrivilegedAccessor.getValue(receiver, "sigCrypto"));
}
public void testReceiverLoadDecryptionHook() throws Exception {
TestReceiverImpl receiver = new TestReceiverImpl();
PrivilegedAccessor.invokeMethod(receiver, "decodeDecryptionParameter", new Object[] {});
assertNotNull(PrivilegedAccessor.getValue(receiver, "decCrypto"));
}
public void testRoundTripWithHooks() throws Exception {
// Setup our sender to Encrypt and Sign a soap message
TestSenderImpl sender = new TestSenderImpl();
sender.setOption(WSHandlerConstants.ACTOR, "test");
sender.setOption(WSHandlerConstants.USER, "16c73ab6-b892-458f-abf5-2f875f74882e");
sender.setOption(WSHandlerConstants.ACTION, "Encrypt Signature");
sender.setOption(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
sender.setOption(WSHandlerConstants.ENC_KEY_ID, "X509KeyIdentifier");
sender.invoke(mc);
// Make sure that at least SOMETHING happened
String soapPart = mc.getCurrentMessage().getSOAPPartAsString();
assertNotSame("The message has not been Encrypted or Signed", soapPart, soapMessage);
// Prepare the message context for the response
Message message = getSOAPMessage(soapPart);
mc.setPastPivot(true);
mc.setCurrentMessage(message);
// Setup our receiver for the decryption / signature validation
TestReceiverImpl receiver = new TestReceiverImpl();
receiver.setOption(WSHandlerConstants.ACTOR, "test");
receiver.setOption(WSHandlerConstants.ACTION, "Encrypt Signature");
receiver.invoke(mc);
}
//
//
// Test Utility Classes
//
//
/**
* This is a subclass of Merlin that uses the setKeyStore() method rather than the
* load(is) method to set the private keystore field.
*/
public class TestCryptoImpl extends BouncyCastle {
TestCryptoImpl(KeyStore ks) throws Exception {
super(null);
assertNotNull(ks);
setKeyStore(ks);
}
}
/**
* Subclass of WSDoAllReceiver that creates the Crypto's directly
*/
public class TestReceiverImpl extends WSDoAllReceiver
{
protected Crypto loadDecryptionCrypto() throws AxisFault {
try {
return new TestCryptoImpl(keystore);
} catch(Exception e) {
fail("Failed to create a Crypto instance.");
throw new AxisFault("Failed to create a Crypto instance.", e);
}
}
protected Crypto loadSignatureCrypto() throws AxisFault {
try {
return new TestCryptoImpl(keystore);
} catch(Exception e) {
fail("Failed to create a Crypto instance.");
throw new AxisFault("Failed to create a Crypto instance.", e);
}
}
}
/**
* Subclass of WSDoAllSender that creates the Crypto's directly
*/
public class TestSenderImpl extends WSDoAllSender
{
protected Crypto loadEncryptionCrypto() throws AxisFault {
try {
return new TestCryptoImpl(keystore);
} catch(Exception e) {
fail("Failed to create a Crypto instance.");
throw new AxisFault("Failed to create a Crypto instance.", e);
}
}
protected Crypto loadSignatureCrypto() throws AxisFault {
try {
return new TestCryptoImpl(keystore);
} catch(Exception e) {
fail("Failed to create a Crypto instance.");
throw new AxisFault("Failed to create a Crypto instance.", e);
}
}
}
//
//
// test utility methods
//
//
protected Message getSOAPMessage(String message) throws Exception {
InputStream in = new ByteArrayInputStream(message.getBytes());
Message msg = new Message(in);
msg.setMessageContext(mc);
return msg;
}
protected KeyStore loadKeyStore() throws Exception {
KeyStore ks = null;
FileInputStream is = null;
is = new FileInputStream("keys/x509.PFX.MSFT");
ks = KeyStore.getInstance("pkcs12");
String password = "security";
ks.load(is, password.toCharArray());
return ks;
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof WSPasswordCallback) {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
pc.setPassword("security");
} else {
throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
}
}
}
}