/************************************************************************* * * * SignServer: The OpenSource Automated Signing Server * * * * This software is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or any later version. * * * * See terms of license at gnu.org. * * * *************************************************************************/ package org.signserver.module.xmlsigner; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.security.cert.Certificate; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.apache.log4j.Logger; import org.junit.After; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; import org.signserver.common.*; import org.signserver.testutils.ModulesTestCase; import org.w3c.dom.Document; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; /** * Tests for XMLSigner. * * @author Markus KilÄs * @version $Id: XMLSignerTest.java 3465 2013-05-01 10:24:46Z netmackan $ */ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class XMLSignerTest extends ModulesTestCase { private static final Logger LOG = Logger.getLogger(XMLSignerTest.class); /** WORKERID used in this test case as defined in junittest-part-config.properties */ private static final int WORKERID = 5676; /** WORKERID used in this test case as defined in junittest-part-config.properties */ private static final int WORKERID2 = 5679; private static final int[] WORKERS = new int[] {5676, 5679, 5681, 5682, 5683, 5802, 5803}; private static final String TESTXML1 = "My Data"; @Before public void setUp() throws Exception { SignServerUtil.installBCProvider(); } @Test public void test00SetupDatabase() throws Exception { setProperties(new File(getSignServerHome(), "modules/SignServer-Module-XMLSigner/src/conf/junittest-part-config.properties")); workerSession.reloadConfiguration(WORKERID); // Update path to JKS file workerSession.setWorkerProperty(WORKERID2, "KEYSTOREPATH", new File(getSignServerHome() + File.separator + "res" + File.separator + "test" + File.separator + "xmlsigner4.jks").getAbsolutePath()); workerSession.reloadConfiguration(WORKERID2); } @Test public void test01BasicXmlSignRSA() throws Exception { final int reqid = 13; final GenericSignRequest signRequest = new GenericSignRequest(reqid, TESTXML1.getBytes()); final GenericSignResponse res = (GenericSignResponse) workerSession.process(WORKERID, signRequest, new RequestContext()); final byte[] data = res.getProcessedData(); // Answer to right question assertSame("Request ID", reqid, res.getRequestID()); // Output for manual inspection final FileOutputStream fos = new FileOutputStream(new File(getSignServerHome() + File.separator + "tmp" + File.separator + "signedxml_rsa.xml")); fos.write((byte[]) data); fos.close(); // Check certificate final Certificate signercert = res.getSignerCertificate(); assertNotNull("Signer certificate", signercert); // XML Document checkXmlWellFormed(new ByteArrayInputStream(data)); // Check algorithm assertTrue("Algorithm", usesAlgorithm(new String(data), "http://www.w3.org/2000/09/xmldsig#rsa-sha1")); } @Test public void test02GetStatus() throws Exception { final SignerStatus stat = (SignerStatus) workerSession.getStatus(WORKERID); assertSame("Status", stat.getTokenStatus(), SignerStatus.STATUS_ACTIVE); } @Test public void test03BasicXmlSignDSA() throws Exception { final int reqid = 15; final GenericSignRequest signRequest = new GenericSignRequest(reqid, TESTXML1.getBytes()); final GenericSignResponse res = (GenericSignResponse) workerSession.process(WORKERID2, signRequest, new RequestContext()); final byte[] data = res.getProcessedData(); // Answer to right question assertSame("Request ID", reqid, res.getRequestID()); // Output for manual inspection final FileOutputStream fos = new FileOutputStream( new File(getSignServerHome() + File.separator + "tmp" + File.separator + "signedxml_dsa.xml")); fos.write((byte[]) data); fos.close(); // Check certificate final Certificate signercert = res.getSignerCertificate(); assertNotNull("Signer certificate", signercert); // XML Document checkXmlWellFormed(new ByteArrayInputStream(data)); // Check algorithm assertTrue("Algorithm", usesAlgorithm(new String(data), "http://www.w3.org/2000/09/xmldsig#dsa-sha1")); } @Test public void test99TearDownDatabase() throws Exception { for (int workerId : WORKERS) { removeWorker(workerId); } } private void checkXmlWellFormed(final InputStream input) { try { final DocumentBuilderFactory dBF = DocumentBuilderFactory.newInstance(); final DocumentBuilder builder = dBF.newDocumentBuilder(); final Document doc = builder.parse(input); doc.toString(); } catch (Exception e) { LOG.error("Not well formed XML", e); fail("Not well formed XML: " + e.getMessage()); } } /** * Returns true if the signed XML document uses the specified algorithm. * @param xml * @param algorithm */ private boolean usesAlgorithm(final String xml, final String algorithm) { return xml.contains("Algorithm=\""+algorithm); } }