org.signserver.module.xmlsigner.AnySignerTest.java Source code

Java tutorial

Introduction

Here is the source code for org.signserver.module.xmlsigner.AnySignerTest.java

Source

/*************************************************************************
 *                                                                       *
 *  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.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.*;
import java.util.Collection;
import org.bouncycastle.jce.ECKeyUtil;
import org.bouncycastle.jce.PKCS10CertificationRequest;
import org.bouncycastle.util.encoders.Hex;
import org.ejbca.util.Base64;
import org.junit.After;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
import org.signserver.common.Base64SignerCertReqData;
import org.signserver.common.KeyTestResult;
import org.signserver.common.PKCS10CertReqInfo;
import org.signserver.common.SignServerUtil;
import org.signserver.testutils.ModulesTestCase;
import org.signserver.testutils.TestingSecurityManager;
import org.junit.Before;
import org.junit.Test;
import org.signserver.common.util.PathUtil;
import org.signserver.ejb.interfaces.IWorkerSession;

/**
 * Tests for any Signer.
 *
 * Can be used for testing key generation, key testing, csr generation etc.
 * 
 * @author Markus Kils
 * @version $Id: AnySignerTest.java 5723 2015-02-17 23:22:00Z netmackan $
 */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class AnySignerTest extends ModulesTestCase {

    private static final int WORKERID = 5803;
    private static final int[] WORKERS = new int[] { WORKERID };

    private static File signserverhome;

    private static File keystoreFile;

    private final IWorkerSession workerSession = getWorkerSession();

    @Before
    public void setUp() throws Exception {
        SignServerUtil.installBCProvider();
        signserverhome = PathUtil.getAppHome();
    }

    @After
    public void tearDown() throws Exception {
        TestingSecurityManager.remove();
    }

    @Test
    public void test00SetupDatabase() throws Exception {
        addDummySigner(WORKERID, "TestXMLSignerKeystore2", true);

        final File newKeystore = new File(signserverhome, "tmp" + File.separator + "empty-testkeystore.p12");
        if (newKeystore.exists()) {
            assertTrue(newKeystore.delete());
        }

        KeyStore keystore = KeyStore.getInstance("PKCS12", "BC");
        keystore.load(null, null);
        keystore.store(new FileOutputStream(newKeystore), "foo123".toCharArray());

        assertTrue("Exists new keystore: " + newKeystore.getAbsolutePath(), newKeystore.exists());

        // Update path to keystore file
        workerSession.setWorkerProperty(WORKERID, "KEYSTOREPATH", newKeystore.getAbsolutePath());
        workerSession.reloadConfiguration(WORKERID);

        keystoreFile = newKeystore;
    }

    @Test
    public void test01GenerateKey() throws Exception {

        final char[] authCode = "foo123".toCharArray();
        final String newKeyAlias = "newkey0001";

        final String actualNewAlias = workerSession.generateSignerKey(WORKERID, "RSA", "2048", newKeyAlias,
                authCode);

        assertEquals("alias", newKeyAlias, actualNewAlias);

        final Collection<KeyTestResult> results = workerSession.testKey(WORKERID, newKeyAlias, authCode);
        final KeyTestResult result = results.iterator().next();
        assertEquals("alias in result", newKeyAlias, result.getAlias());
        assertTrue("test result", result.isSuccess());

        final KeyStore keyStore = KeyStore.getInstance("PKCS12");
        keyStore.load(new FileInputStream(keystoreFile), authCode);
        final PublicKey pubKey = keyStore.getCertificate(newKeyAlias).getPublicKey();
        final byte[] pubKeyBytes = pubKey.getEncoded();
        final String expectedKeyHash = createKeyHash(pubKeyBytes);
        final String actualKeyHash = result.getPublicKeyHash();

        assertEquals("key hash", expectedKeyHash, actualKeyHash);

        // Set new key as NEXTCERTSIGNKEY
        workerSession.setWorkerProperty(WORKERID, "NEXTCERTSIGNKEY", newKeyAlias);
        workerSession.reloadConfiguration(WORKERID);

        // Generate CSR
        final PKCS10CertReqInfo certReqInfo = new PKCS10CertReqInfo("SHA1WithRSA", "CN=test01GenerateKey,C=SE",
                null);
        Base64SignerCertReqData data = (Base64SignerCertReqData) workerSession.getCertificateRequest(WORKERID,
                certReqInfo, false, false);
        byte[] reqBytes = data.getBase64CertReq();
        final PKCS10CertificationRequest req = new PKCS10CertificationRequest(Base64.decode(reqBytes));

        final PublicKey actualPubKey = req.getPublicKey();

        assertEquals("key in request", pubKey, actualPubKey);

        // Test that the DN is in the correct order
        String actualDN = req.getCertificationRequestInfo().getSubject().toString();
        assertTrue("dn: " + actualDN, actualDN.startsWith("CN=test01GenerateKey") && actualDN.endsWith("C=SE"));
    }

    /**
     * Test key generation of a ECDSA curve.
     * @throws Exception in case of error
     */
    @Test
    public void test02GenerateKeyECDSA() throws Exception {

        final char[] authCode = "foo123".toCharArray();
        final String newKeyAlias = "newkey0002";

        final String actualNewAlias = workerSession.generateSignerKey(WORKERID, "ECDSA", "secp256r1", newKeyAlias,
                authCode);

        assertEquals("alias", newKeyAlias, actualNewAlias);

        final Collection<KeyTestResult> results = workerSession.testKey(WORKERID, newKeyAlias, authCode);
        final KeyTestResult result = results.iterator().next();
        assertEquals("alias in result", newKeyAlias, result.getAlias());
        assertTrue("test result", result.isSuccess());

        final KeyStore keyStore = KeyStore.getInstance("PKCS12");
        keyStore.load(new FileInputStream(keystoreFile), authCode);
        final PublicKey pubKey = keyStore.getCertificate(newKeyAlias).getPublicKey();
        final byte[] pubKeyBytes = pubKey.getEncoded();
        final String expectedKeyHash = createKeyHash(pubKeyBytes);
        final String actualKeyHash = result.getPublicKeyHash();

        assertEquals("keyAlg", "EC", pubKey.getAlgorithm());

        assertEquals("key hash", expectedKeyHash, actualKeyHash);

        // Set new key as NEXTCERTSIGNKEY
        workerSession.setWorkerProperty(WORKERID, "NEXTCERTSIGNKEY", newKeyAlias);
        workerSession.reloadConfiguration(WORKERID);

        // Generate CSR
        final PKCS10CertReqInfo certReqInfo = new PKCS10CertReqInfo("SHA1WithECDSA", "CN=test02GenerateKey", null);
        Base64SignerCertReqData data = (Base64SignerCertReqData) workerSession.getCertificateRequest(WORKERID,
                certReqInfo, false, false);
        byte[] reqBytes = data.getBase64CertReq();
        final PKCS10CertificationRequest req = new PKCS10CertificationRequest(Base64.decode(reqBytes));

        final PublicKey actualPubKey = req.getPublicKey();

        assertEquals("key in request", pubKey, actualPubKey);
    }

    @Test
    public void test03GenerateRequestNamedCurve() throws Exception {

        final boolean explicitEcc = false;

        // Generate CSR
        final PKCS10CertReqInfo certReqInfo = new PKCS10CertReqInfo("SHA1WithECDSA", "CN=test02GenerateKey", null);
        Base64SignerCertReqData data = (Base64SignerCertReqData) workerSession.getCertificateRequest(WORKERID,
                certReqInfo, explicitEcc, false);
        byte[] reqBytes = data.getBase64CertReq();
        final PKCS10CertificationRequest req = new PKCS10CertificationRequest(Base64.decode(reqBytes));

        final PublicKey actualPubKey = req.getPublicKey();
        final PublicKey afterConvert = ECKeyUtil.publicToExplicitParameters(actualPubKey, "BC");

        // The following assertion assumes that publicToExplicitParameters
        // returns a new/different PublicKey instance if it was not already
        // converted and if it already was explicit the same instance was
        // returned

        // Not the same object
        assertNotSame("Not converted to explicit", actualPubKey.hashCode(), afterConvert.hashCode());
    }

    @Test
    public void test04GenerateRequestExplicitParams() throws Exception {
        final boolean explicitEcc = true;

        // Generate CSR
        final PKCS10CertReqInfo certReqInfo = new PKCS10CertReqInfo("SHA1WithECDSA", "CN=test02GenerateKey", null);
        Base64SignerCertReqData data = (Base64SignerCertReqData) workerSession.getCertificateRequest(WORKERID,
                certReqInfo, explicitEcc, false);
        byte[] reqBytes = data.getBase64CertReq();
        final PKCS10CertificationRequest req = new PKCS10CertificationRequest(Base64.decode(reqBytes));

        final PublicKey actualPubKey = req.getPublicKey();
        final PublicKey afterConvert = ECKeyUtil.publicToExplicitParameters(actualPubKey, "BC");

        // The following assertion assumes that publicToExplicitParameters
        // returns a new/different PublicKey instance if it was not already
        // converted and if it already was explicit the same instance was
        // returned

        // The same object
        assertTrue("Not converted to explicit", actualPubKey.hashCode() == afterConvert.hashCode());
    }

    @Test
    public void test99TearDownDatabase() throws Exception {
        for (int workerId : WORKERS) {
            removeWorker(workerId);
        }
    }

    public static String createKeyHash(byte[] key) {
        try {
            final MessageDigest md = MessageDigest.getInstance("SHA1", "BC");
            final String res = new String(Hex.encode(md.digest(key)));
            md.reset();
            return res;
        } catch (NoSuchProviderException ex) {
            final String message = "Nu such provider trying to hash public key";
            throw new RuntimeException(message, ex);
        } catch (NoSuchAlgorithmException ex) {
            final String message = "Nu such algorithm trying to hash public key";
            throw new RuntimeException(message, ex);
        }
    }
}