Java tutorial
/* * HSM Proxy Project. * Copyright (C) 2013 FedICT. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version * 3.0 as published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, see * http://www.gnu.org/licenses/. */ package test.integ.be.fedict.hsm.ws; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.net.URL; import java.security.KeyPair; import java.security.cert.X509Certificate; import java.util.List; import javax.xml.crypto.dsig.DigestMethod; import javax.xml.crypto.dsig.SignatureMethod; import javax.xml.ws.Binding; import javax.xml.ws.BindingProvider; import javax.xml.ws.handler.Handler; import javax.xml.ws.handler.soap.SOAPHandler; import javax.xml.ws.handler.soap.SOAPMessageContext; import javax.xml.ws.soap.SOAPFaultException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.client.HttpClient; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.impl.client.DefaultHttpClient; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.jboss.shrinkwrap.resolver.api.maven.Maven; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import test.integ.be.fedict.hsm.HSMProxyTestCredential; import test.integ.be.fedict.hsm.model.security.SecurityTest; import be.fedict.hsm.entity.SecurityAuditEntity; import be.fedict.hsm.model.security.SecurityAuditGeneratorBean; import be.fedict.hsm.ws.DigitalSignatureServiceFactory; import be.fedict.hsm.ws.impl.LoggingSOAPHandler; import be.fedict.hsm.ws.impl.WSSecurityCrypto; import be.fedict.hsm.ws.impl.WSSecuritySOAPHandler; import be.fedict.hsm.ws.jaxb.dss.ObjectFactory; import be.fedict.hsm.ws.jaxb.dss.SignRequest; import be.fedict.hsm.ws.jaxws.DigitalSignatureService; import be.fedict.hsm.ws.jaxws.DigitalSignatureServicePortType; @RunWith(Arquillian.class) @RunAsClient public class WebServiceSecurityTest { private static final Log LOG = LogFactory.getLog(WebServiceSecurityTest.class); @ArquillianResource private URL baseURL; @Deployment public static WebArchive createTestArchive() { WebArchive war = ShrinkWrap.create(WebArchive.class, "test.war") .addAsLibraries(Maven.resolver().resolve("org.apache.ws.security:wss4j:1.6.9").withTransitivity() .as(JavaArchive.class)) .addAsLibraries(Maven.resolver().resolve("org.apache.santuario:xmlsec:jar:1.5.2").withTransitivity() .as(JavaArchive.class)) .addAsLibraries(Maven.resolver().resolve("commons-codec:commons-codec:1.8").withoutTransitivity() .as(JavaArchive.class)) .addPackages(true, DigitalSignatureServicePortType.class.getPackage(), SecurityAuditEntity.class.getPackage()) .addClasses(DigitalSignatureServiceTestPort.class, LoggingSOAPHandler.class, WSSecuritySOAPHandler.class, WSSecurityCrypto.class, SecurityAuditGeneratorBean.class, SecurityAuditTestController.class) .addPackages(true, ObjectFactory.class.getPackage(), be.fedict.hsm.ws.jaxb.xmldsig.ObjectFactory.class.getPackage(), be.fedict.hsm.ws.jaxb.hsm.ObjectFactory.class.getPackage(), be.fedict.hsm.ws.jaxb.saml.ObjectFactory.class.getPackage()) .addAsResource(WebServiceSecurityTest.class.getResource("/test-security-hsm-proxy-ws-handlers.xml"), "/test-security-hsm-proxy-ws-handlers.xml") .addAsWebInfResource(WebServiceSecurityTest.class.getResource("/test-security-web.xml"), "/web.xml") .addAsResource(SecurityTest.class.getResource("/test-persistence.xml"), "META-INF/persistence.xml"); return war; } @Before public void setUp() throws Exception { resetSecurityAuditRecords(); } @Test public void testDeployment() throws Exception { // empty } @Test public void testMissingWSSecurityHeader() throws Exception { DigitalSignatureServicePortType dssPort = getPort(); ObjectFactory objectFactory = new ObjectFactory(); SignRequest signRequest = objectFactory.createSignRequest(); try { dssPort.sign(signRequest); fail(); } catch (SOAPFaultException e) { LOG.debug("expected exception: " + e.getMessage()); // expected } assertEquals(1, getNumberOfSecurityAuditRecords()); } @Test public void testEmptyWSSecurityHeader() throws Exception { DigitalSignatureServicePortType dssPort = getPort(); WSSecurityTestSOAPHandler securityTestSOAPHandler = new WSSecurityTestSOAPHandler(); addSOAPHandler(securityTestSOAPHandler, dssPort); ObjectFactory objectFactory = new ObjectFactory(); SignRequest signRequest = objectFactory.createSignRequest(); int auditCountBefore = getNumberOfSecurityAuditRecords(); LOG.debug("number of security audit records before invocation: " + auditCountBefore); try { dssPort.sign(signRequest); fail(); } catch (SOAPFaultException e) { LOG.debug("expected exception: " + e.getMessage()); // expected } int auditCountAfter = getNumberOfSecurityAuditRecords(); LOG.debug("number of security audit records after invocation: " + auditCountAfter); assertEquals(1, getNumberOfSecurityAuditRecords()); } @Test public void testWSSecurityTimestampOnly() throws Exception { DigitalSignatureServicePortType dssPort = getPort(); WSSecurityTestSOAPHandler securityTestSOAPHandler = new WSSecurityTestSOAPHandler(); securityTestSOAPHandler.addTimestamp(true); addSOAPHandler(securityTestSOAPHandler, dssPort); ObjectFactory objectFactory = new ObjectFactory(); SignRequest signRequest = objectFactory.createSignRequest(); try { dssPort.sign(signRequest); fail(); } catch (SOAPFaultException e) { LOG.debug("expected exception: " + e.getMessage()); // expected } assertEquals(1, getNumberOfSecurityAuditRecords()); } @Test public void testWSSecurityTS_BST() throws Exception { DigitalSignatureServicePortType dssPort = getPort(); KeyPair keyPair = HSMProxyTestCredential.generateKeyPair(); X509Certificate certificate = HSMProxyTestCredential.generateSelfSignedCertificate(keyPair); WSSecurityTestSOAPHandler securityTestSOAPHandler = new WSSecurityTestSOAPHandler(); securityTestSOAPHandler.addTimestamp(true); securityTestSOAPHandler.addBinarySecurityToken(certificate); addSOAPHandler(securityTestSOAPHandler, dssPort); ObjectFactory objectFactory = new ObjectFactory(); SignRequest signRequest = objectFactory.createSignRequest(); try { dssPort.sign(signRequest); fail(); } catch (SOAPFaultException e) { LOG.debug("expected exception: " + e.getMessage()); // expected } assertEquals(1, getNumberOfSecurityAuditRecords()); } @Test public void testWSSecurityTS_BST_Signature() throws Exception { DigitalSignatureServicePortType dssPort = getPort(); KeyPair keyPair = HSMProxyTestCredential.generateKeyPair(); X509Certificate certificate = HSMProxyTestCredential.generateSelfSignedCertificate(keyPair); WSSecurityTestSOAPHandler securityTestSOAPHandler = new WSSecurityTestSOAPHandler(); securityTestSOAPHandler.addTimestamp(true); securityTestSOAPHandler.addBinarySecurityToken(certificate); securityTestSOAPHandler.addSignature(keyPair.getPrivate()); addSOAPHandler(securityTestSOAPHandler, dssPort); ObjectFactory objectFactory = new ObjectFactory(); SignRequest signRequest = objectFactory.createSignRequest(); try { dssPort.sign(signRequest); fail(); } catch (SOAPFaultException e) { LOG.debug("expected exception: " + e.getMessage()); // expected } assertEquals(1, getNumberOfSecurityAuditRecords()); } @Test public void testWSSecurityTS_BST_Signature_ProtectTokens() throws Exception { DigitalSignatureServicePortType dssPort = getPort(); KeyPair keyPair = HSMProxyTestCredential.generateKeyPair(); X509Certificate certificate = HSMProxyTestCredential.generateSelfSignedCertificate(keyPair); WSSecurityTestSOAPHandler securityTestSOAPHandler = new WSSecurityTestSOAPHandler(); securityTestSOAPHandler.addTimestamp(true); securityTestSOAPHandler.addBinarySecurityToken(certificate); securityTestSOAPHandler.setSignBinarySecurityToken(true); securityTestSOAPHandler.addSignature(keyPair.getPrivate()); addSOAPHandler(securityTestSOAPHandler, dssPort); ObjectFactory objectFactory = new ObjectFactory(); SignRequest signRequest = objectFactory.createSignRequest(); dssPort.sign(signRequest); } @Test public void testWSSecurity_SHA1DigestAlgoFails() throws Exception { DigitalSignatureServicePortType dssPort = getPort(); KeyPair keyPair = HSMProxyTestCredential.generateKeyPair(); X509Certificate certificate = HSMProxyTestCredential.generateSelfSignedCertificate(keyPair); WSSecurityTestSOAPHandler securityTestSOAPHandler = new WSSecurityTestSOAPHandler(); securityTestSOAPHandler.addTimestamp(true); securityTestSOAPHandler.addBinarySecurityToken(certificate); securityTestSOAPHandler.addSignature(keyPair.getPrivate()); securityTestSOAPHandler.setDigestAlgorithm(DigestMethod.SHA1); addSOAPHandler(securityTestSOAPHandler, dssPort); ObjectFactory objectFactory = new ObjectFactory(); SignRequest signRequest = objectFactory.createSignRequest(); try { dssPort.sign(signRequest); fail(); } catch (SOAPFaultException e) { LOG.debug("expected exception: " + e.getMessage()); // expected } assertEquals(1, getNumberOfSecurityAuditRecords()); } @Test public void testWSSecurity_RSASHA1SignatureAlgoFails() throws Exception { DigitalSignatureServicePortType dssPort = getPort(); KeyPair keyPair = HSMProxyTestCredential.generateKeyPair(); X509Certificate certificate = HSMProxyTestCredential.generateSelfSignedCertificate(keyPair); WSSecurityTestSOAPHandler securityTestSOAPHandler = new WSSecurityTestSOAPHandler(); securityTestSOAPHandler.addTimestamp(true); securityTestSOAPHandler.addBinarySecurityToken(certificate); securityTestSOAPHandler.addSignature(keyPair.getPrivate()); securityTestSOAPHandler.setSignatureAlgorithm(SignatureMethod.RSA_SHA1); addSOAPHandler(securityTestSOAPHandler, dssPort); ObjectFactory objectFactory = new ObjectFactory(); SignRequest signRequest = objectFactory.createSignRequest(); try { dssPort.sign(signRequest); fail(); } catch (SOAPFaultException e) { LOG.debug("expected exception: " + e.getMessage()); // expected } assertEquals(1, getNumberOfSecurityAuditRecords()); } @Test public void testWSSecurityUnsignedBodyFails() throws Exception { DigitalSignatureServicePortType dssPort = getPort(); KeyPair keyPair = HSMProxyTestCredential.generateKeyPair(); X509Certificate certificate = HSMProxyTestCredential.generateSelfSignedCertificate(keyPair); WSSecurityTestSOAPHandler securityTestSOAPHandler = new WSSecurityTestSOAPHandler(); securityTestSOAPHandler.addTimestamp(true); securityTestSOAPHandler.addBinarySecurityToken(certificate); securityTestSOAPHandler.addSignature(keyPair.getPrivate()); securityTestSOAPHandler.setSignBody(false); addSOAPHandler(securityTestSOAPHandler, dssPort); ObjectFactory objectFactory = new ObjectFactory(); SignRequest signRequest = objectFactory.createSignRequest(); try { dssPort.sign(signRequest); fail(); } catch (SOAPFaultException e) { LOG.debug("expected exception: " + e.getMessage()); // expected } assertEquals(1, getNumberOfSecurityAuditRecords()); } @Test public void testWSSecurityClientWSSecurity() throws Exception { DigitalSignatureServicePortType dssPort = getPort(); KeyPair keyPair = HSMProxyTestCredential.generateKeyPair(); X509Certificate certificate = HSMProxyTestCredential.generateSelfSignedCertificate(keyPair); be.fedict.hsm.client.WSSecuritySOAPHandler securityTestSOAPHandler = new be.fedict.hsm.client.WSSecuritySOAPHandler( keyPair.getPrivate(), certificate); addSOAPHandler(securityTestSOAPHandler, dssPort); ObjectFactory objectFactory = new ObjectFactory(); SignRequest signRequest = objectFactory.createSignRequest(); dssPort.sign(signRequest); } private void addSOAPHandler(SOAPHandler<SOAPMessageContext> soapHandler, DigitalSignatureServicePortType dssPort) { BindingProvider bindingProvider = (BindingProvider) dssPort; Binding binding = bindingProvider.getBinding(); List<Handler> handlerChain = binding.getHandlerChain(); handlerChain.clear(); handlerChain.add(soapHandler); handlerChain.add(new LoggingSOAPHandler()); binding.setHandlerChain(handlerChain); } private DigitalSignatureServicePortType getPort() { DigitalSignatureService digitalSignatureService = DigitalSignatureServiceFactory.getInstance(); DigitalSignatureServicePortType dssPort = digitalSignatureService.getDigitalSignatureServicePort(); BindingProvider bindingProvider = (BindingProvider) dssPort; String location = this.baseURL.toString() + "dss"; LOG.debug("location: " + location); bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, location); Binding binding = bindingProvider.getBinding(); List<Handler> handlerChain = binding.getHandlerChain(); handlerChain.add(new LoggingSOAPHandler()); binding.setHandlerChain(handlerChain); return dssPort; } private int getNumberOfSecurityAuditRecords() throws Exception { HttpClient httpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(this.baseURL + "rest/audit/count"); ResponseHandler<String> responseHandler = new BasicResponseHandler(); String responseBody = httpClient.execute(httpGet, responseHandler); LOG.debug("response: " + responseBody); int count = Integer.parseInt(responseBody); return count; } private void resetSecurityAuditRecords() throws Exception { HttpClient httpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(this.baseURL + "rest/audit/reset"); httpClient.execute(httpGet); } }