org.ejbca.core.protocol.ws.EjbcaWSTest.java Source code

Java tutorial

Introduction

Here is the source code for org.ejbca.core.protocol.ws.EjbcaWSTest.java

Source

/*************************************************************************
 *                                                                       *
 *  EJBCA Community: The OpenSource Certificate Authority                *
 *                                                                       *
 *  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.ejbca.core.protocol.ws;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;

import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.security.KeyManagementException;
import java.security.KeyPair;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.Set;
import java.util.TimeZone;

import org.apache.commons.lang.time.FastDateFormat;
import org.apache.log4j.Logger;
import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.cesecore.CaTestUtils;
import org.cesecore.ErrorCode;
import org.cesecore.authentication.tokens.AuthenticationSubject;
import org.cesecore.authentication.tokens.AuthenticationToken;
import org.cesecore.authorization.AuthorizationDeniedException;
import org.cesecore.authorization.control.StandardRules;
import org.cesecore.authorization.rules.AccessRuleData;
import org.cesecore.authorization.rules.AccessRuleState;
import org.cesecore.authorization.user.AccessMatchType;
import org.cesecore.authorization.user.AccessUserAspectData;
import org.cesecore.authorization.user.matchvalues.X500PrincipalAccessMatchValue;
import org.cesecore.certificates.ca.CADoesntExistsException;
import org.cesecore.certificates.ca.CAInfo;
import org.cesecore.certificates.ca.CaSessionRemote;
import org.cesecore.certificates.ca.catoken.CAToken;
import org.cesecore.certificates.ca.catoken.CATokenConstants;
import org.cesecore.certificates.certificate.CertificateStoreSessionRemote;
import org.cesecore.certificates.certificateprofile.CertificateProfile;
import org.cesecore.certificates.certificateprofile.CertificateProfileConstants;
import org.cesecore.certificates.certificateprofile.CertificateProfileSessionRemote;
import org.cesecore.certificates.crl.RevokedCertInfo;
import org.cesecore.certificates.endentity.EndEntityInformation;
import org.cesecore.certificates.endentity.EndEntityType;
import org.cesecore.certificates.endentity.EndEntityTypes;
import org.cesecore.certificates.endentity.ExtendedInformation;
import org.cesecore.certificates.util.AlgorithmConstants;
import org.cesecore.configuration.CesecoreConfigurationProxySessionRemote;
import org.cesecore.configuration.GlobalConfigurationSessionRemote;
import org.cesecore.keys.token.CryptoToken;
import org.cesecore.keys.token.CryptoTokenInfo;
import org.cesecore.keys.token.CryptoTokenManagementSessionRemote;
import org.cesecore.keys.token.CryptoTokenTestUtils;
import org.cesecore.keys.token.KeyPairInfo;
import org.cesecore.keys.token.SoftCryptoToken;
import org.cesecore.keys.util.KeyTools;
import org.cesecore.mock.authentication.SimpleAuthenticationProviderSessionRemote;
import org.cesecore.roles.RoleData;
import org.cesecore.roles.access.RoleAccessSessionRemote;
import org.cesecore.roles.management.RoleManagementSessionRemote;
import org.cesecore.util.Base64;
import org.cesecore.util.CeSecoreNameStyle;
import org.cesecore.util.CertTools;
import org.cesecore.util.EjbRemoteHelper;
import org.ejbca.config.GlobalConfiguration;
import org.ejbca.core.EjbcaException;
import org.ejbca.core.ejb.approval.ApprovalExecutionSessionRemote;
import org.ejbca.core.ejb.approval.ApprovalSessionRemote;
import org.ejbca.core.ejb.ca.CaTestCase;
import org.ejbca.core.ejb.ca.caadmin.CAAdminSessionRemote;
import org.ejbca.core.ejb.hardtoken.HardTokenSessionRemote;
import org.ejbca.core.ejb.ra.EndEntityAccessSessionRemote;
import org.ejbca.core.ejb.ra.EndEntityManagementSessionRemote;
import org.ejbca.core.model.SecConst;
import org.ejbca.core.model.approval.ApprovalDataVO;
import org.ejbca.core.model.approval.approvalrequests.RevocationApprovalTest;
import org.ejbca.core.model.hardtoken.HardTokenConstants;
import org.ejbca.core.model.ra.NotFoundException;
import org.ejbca.core.protocol.ws.client.gen.AlreadyRevokedException_Exception;
import org.ejbca.core.protocol.ws.client.gen.ApprovalException_Exception;
import org.ejbca.core.protocol.ws.client.gen.CertificateResponse;
import org.ejbca.core.protocol.ws.client.gen.EjbcaException_Exception;
import org.ejbca.core.protocol.ws.client.gen.HardTokenDataWS;
import org.ejbca.core.protocol.ws.client.gen.IllegalQueryException_Exception;
import org.ejbca.core.protocol.ws.client.gen.KeyStore;
import org.ejbca.core.protocol.ws.client.gen.PinDataWS;
import org.ejbca.core.protocol.ws.client.gen.RevokeStatus;
import org.ejbca.core.protocol.ws.client.gen.TokenCertificateRequestWS;
import org.ejbca.core.protocol.ws.client.gen.TokenCertificateResponseWS;
import org.ejbca.core.protocol.ws.client.gen.UserDataVOWS;
import org.ejbca.core.protocol.ws.client.gen.UserMatch;
import org.ejbca.core.protocol.ws.client.gen.WaitingForApprovalException_Exception;
import org.ejbca.core.protocol.ws.common.CertificateHelper;
import org.ejbca.core.protocol.ws.common.KeyStoreHelper;
import org.ejbca.util.KeyValuePair;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

/**
 * This test uses remote EJB calls to setup the environment.
 * 
 * @version $Id: EjbcaWSTest.java 20992 2015-03-25 10:05:53Z mikekushner $
 */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class EjbcaWSTest extends CommonEjbcaWS {

    private static final Logger log = Logger.getLogger(EjbcaWSTest.class);

    public final static String WS_ADMIN_ROLENAME = "WsTEstRole";
    public final static String WS_TEST_ROLENAME = "WsTestRoleMgmt";
    private final static String WS_TEST_CERTIFICATE_PROFILE_NAME = "WSTESTPROFILE";

    private final ApprovalExecutionSessionRemote approvalExecutionSession = EjbRemoteHelper.INSTANCE
            .getRemoteSession(ApprovalExecutionSessionRemote.class);
    private final ApprovalSessionRemote approvalSession = EjbRemoteHelper.INSTANCE
            .getRemoteSession(ApprovalSessionRemote.class);
    private final CAAdminSessionRemote caAdminSessionRemote = EjbRemoteHelper.INSTANCE
            .getRemoteSession(CAAdminSessionRemote.class);
    private final CaSessionRemote caSession = EjbRemoteHelper.INSTANCE.getRemoteSession(CaSessionRemote.class);
    private final CertificateProfileSessionRemote certificateProfileSession = EjbRemoteHelper.INSTANCE
            .getRemoteSession(CertificateProfileSessionRemote.class);
    private final CertificateStoreSessionRemote certificateStoreSession = EjbRemoteHelper.INSTANCE
            .getRemoteSession(CertificateStoreSessionRemote.class);
    private final CesecoreConfigurationProxySessionRemote cesecoreConfigurationProxySession = EjbRemoteHelper.INSTANCE
            .getRemoteSession(CesecoreConfigurationProxySessionRemote.class, EjbRemoteHelper.MODULE_TEST);
    private final CryptoTokenManagementSessionRemote cryptoTokenManagementSession = EjbRemoteHelper.INSTANCE
            .getRemoteSession(CryptoTokenManagementSessionRemote.class, EjbRemoteHelper.MODULE_TEST);
    private final EndEntityAccessSessionRemote endEntityAccessSession = EjbRemoteHelper.INSTANCE
            .getRemoteSession(EndEntityAccessSessionRemote.class);
    private final EndEntityManagementSessionRemote endEntityManagementSession = EjbRemoteHelper.INSTANCE
            .getRemoteSession(EndEntityManagementSessionRemote.class);
    private final GlobalConfigurationSessionRemote globalConfigurationSession = EjbRemoteHelper.INSTANCE
            .getRemoteSession(GlobalConfigurationSessionRemote.class);
    private final HardTokenSessionRemote hardTokenSessionRemote = EjbRemoteHelper.INSTANCE
            .getRemoteSession(HardTokenSessionRemote.class);
    private final SimpleAuthenticationProviderSessionRemote simpleAuthenticationProvider = EjbRemoteHelper.INSTANCE
            .getRemoteSession(SimpleAuthenticationProviderSessionRemote.class, EjbRemoteHelper.MODULE_TEST);
    private final RoleAccessSessionRemote roleAccessSession = EjbRemoteHelper.INSTANCE
            .getRemoteSession(RoleAccessSessionRemote.class);
    private final RoleManagementSessionRemote roleManagementSession = EjbRemoteHelper.INSTANCE
            .getRemoteSession(RoleManagementSessionRemote.class);

    private static String originalForbiddenChars;
    private final static SecureRandom secureRandom;
    private final static String forbiddenCharsKey = "forbidden.characters";
    static {
        try {
            secureRandom = SecureRandom.getInstance("SHA1PRNG");
        } catch (NoSuchAlgorithmException e) {
            throw new Error(e);
        }
    }

    @BeforeClass
    public static void beforeClass() throws Exception {
        adminBeforeClass();
        setupAccessRights(WS_ADMIN_ROLENAME);
        CesecoreConfigurationProxySessionRemote cesecoreConfigurationProxySession = EjbRemoteHelper.INSTANCE
                .getRemoteSession(CesecoreConfigurationProxySessionRemote.class, EjbRemoteHelper.MODULE_TEST);
        originalForbiddenChars = cesecoreConfigurationProxySession.getConfigurationValue(forbiddenCharsKey);
    }

    @Before
    public void setUpAdmin() throws Exception {
        adminSetUpAdmin();
    }

    @AfterClass
    public static void afterClass() throws Exception {
        cleanUpAdmins(WS_ADMIN_ROLENAME);
        cleanUpAdmins(WS_TEST_ROLENAME);
        CesecoreConfigurationProxySessionRemote cesecoreConfigurationProxySession = EjbRemoteHelper.INSTANCE
                .getRemoteSession(CesecoreConfigurationProxySessionRemote.class, EjbRemoteHelper.MODULE_TEST);
        cesecoreConfigurationProxySession.setConfigurationValue(forbiddenCharsKey, originalForbiddenChars);
        CertificateProfileSessionRemote certificateProfileSession = EjbRemoteHelper.INSTANCE
                .getRemoteSession(CertificateProfileSessionRemote.class);
        certificateProfileSession.removeCertificateProfile(intAdmin, WS_TEST_CERTIFICATE_PROFILE_NAME);
    }

    @Override
    public String getRoleName() {
        return WS_TEST_ROLENAME;
    }

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

    /** This test is not a WebService test, but for simplicity it re-uses the created administrator certificate in order to connect to the
     * EJBCA Admin Web and verify returned security headers.
     * @throws IOException 
     * @throws CertificateException 
     * @throws KeyStoreException 
     * @throws NoSuchAlgorithmException 
     * @throws KeyManagementException 
     * @throws UnrecoverableKeyException 
     */
    @Test
    public void testAdminWebSecurityHeaders() throws UnrecoverableKeyException, KeyManagementException,
            NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException {
        HttpURLConnection con = super.getHttpsURLConnection(
                "https://" + hostname + ":" + httpsPort + "/ejbca/adminweb/index.jsp");
        String xframe = con.getHeaderField("X-FRAME-OPTIONS");
        String csp = con.getHeaderField("content-security-policy");
        String xcsp = con.getHeaderField("x-content-security-policy");
        con.disconnect();
        assertNotNull("Admin web page should return X-FRAME-OPTIONS header", xframe);
        assertNotNull("Admin web page should return content-security-policy header", csp);
        assertNotNull("Admin web page should return x-content-security-policy header", xcsp);
        assertEquals("Admin web page should return X-FRAME-OPTIONS SAMEORIGIN", "SAMEORIGIN", xframe);
        assertEquals(
                "Admin web page should return csp default-src 'none'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self'; frame-src 'self'; form-action 'self'; plugin-types application/pdf; reflected-xss block",
                "default-src 'none'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self'; frame-src 'self'; form-action 'self'; reflected-xss block",
                csp);
        assertEquals(
                "Admin web page should return xcsp default-src 'none'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self'; frame-src 'self'; form-action 'self'; plugin-types application/pdf; reflected-xss block",
                "default-src 'none'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self'; frame-src 'self'; form-action 'self'; reflected-xss block",
                xcsp);
    }

    @Test
    public void test01EditUser() throws Exception {
        super.editUser();
    }

    @Test
    public void test02FindUser() throws Exception {
        findUser();
    }

    @Test
    public void test03_1GeneratePkcs10() throws Exception {
        generatePkcs10();
    }

    @Test
    public void test03_2GenerateCrmf() throws Exception {
        generateCrmf();
    }

    @Test
    public void test03_3GenerateSpkac() throws Exception {
        generateSpkac();
    }

    @Test
    public void test03_4GeneratePkcs10Request() throws Exception {
        generatePkcs10Request();
    }

    @Test
    public void test03_5CertificateRequest() throws Exception {
        certificateRequest();
    }

    @Test
    public void test03_6EnforcementOfUniquePublicKeys() throws Exception {
        enforcementOfUniquePublicKeys();
    }

    @Test
    public void test03_6EnforcementOfUniqueSubjectDN() throws Exception {
        enforcementOfUniqueSubjectDN();
    }

    @Test
    public void test03_7ThrowAwayConfiguration() throws Exception {
        certificateRequestThrowAway();
    }

    @Test
    public void test04GeneratePkcs12() throws Exception {
        generatePkcs12();
    }

    @Test
    public void test05FindCerts() throws Exception {
        findCerts();
    }

    @Test
    public void test060RevokeCert() throws Exception {
        revokeCert();
    }

    @Test
    public void test061RevokeCertBackdated() throws Exception {
        revokeCertBackdated();
    }

    @Test
    public void test07RevokeToken() throws Exception {
        revokeToken();
    }

    @Test
    public void test08CheckRevokeStatus() throws Exception {
        checkRevokeStatus();
    }

    @Test
    public void test09Utf8EditUser() throws Exception {
        utf8EditUser();
    }

    @Test
    public void test10GetLastCertChain() throws Exception {
        getLastCertChain();
    }

    @Test
    public void test11RevokeUser() throws Exception {
        revokeUser();
    }

    @Test
    public void test12IsAuthorized() throws Exception {
        // This is a superadmin keystore, improve in the future
        isAuthorized(true);
    }

    @Test
    public void test13genTokenCertificates() throws Exception {
        genTokenCertificates(false);
    }

    @Test
    public void test14getExistsHardToken() throws Exception {
        getExistsHardToken();
    }

    @Test
    public void test15getHardTokenData() throws Exception {
        getHardTokenData("12345678", false);
    }

    @Test
    public void test16getHardTokenDatas() throws Exception {
        getHardTokenDatas();
    }

    @Test
    public void test17CustomLog() throws Exception {
        customLog();
    }

    @Test
    public void test18GetCertificate() throws Exception {
        getCertificate();
    }

    @Test
    public void test19RevocationApprovals() throws Exception {
        log.trace(">test19RevocationApprovals");
        final String APPROVINGADMINNAME = "superadmin";
        final String TOKENSERIALNUMBER = "42424242";
        final String TOKENUSERNAME = "WSTESTTOKENUSER3";
        final String ERRORNOTSENTFORAPPROVAL = "The request was never sent for approval.";
        final String ERRORNOTSUPPORTEDSUCCEEDED = "Reactivation of users is not supported, but succeeded anyway.";

        // Generate random username and CA name
        String randomPostfix = Integer.toString(secureRandom.nextInt(999999));
        String caname = "wsRevocationCA" + randomPostfix;
        String username = "wsRevocationUser" + randomPostfix;
        int cryptoTokenId = 0;
        int caID = -1;
        try {
            cryptoTokenId = CryptoTokenTestUtils.createCryptoTokenForCA(intAdmin, caname, "1024");
            final CAToken catoken = CaTestUtils.createCaToken(cryptoTokenId,
                    AlgorithmConstants.SIGALG_SHA1_WITH_RSA, AlgorithmConstants.SIGALG_SHA1_WITH_RSA);
            caID = RevocationApprovalTest.createApprovalCA(intAdmin, caname, CAInfo.REQ_APPROVAL_REVOCATION,
                    caAdminSessionRemote, caSession, catoken);
            X509Certificate adminCert = (X509Certificate) certificateStoreSession
                    .findCertificatesByUsername(APPROVINGADMINNAME).iterator().next();
            Set<X509Certificate> credentials = new HashSet<X509Certificate>();
            credentials.add(adminCert);
            Set<Principal> principals = new HashSet<Principal>();
            principals.add(adminCert.getSubjectX500Principal());
            AuthenticationToken approvingAdmin = simpleAuthenticationProvider
                    .authenticate(new AuthenticationSubject(principals, credentials));
            //AuthenticationToken approvingAdmin = new X509CertificateAuthenticationToken(principals, credentials);
            //Admin approvingAdmin = new Admin(adminCert, APPROVINGADMINNAME, null);
            try {
                X509Certificate cert = createUserAndCert(username, caID);
                String issuerdn = cert.getIssuerDN().toString();
                String serno = cert.getSerialNumber().toString(16);
                // revoke via WS and verify response
                try {
                    ejbcaraws.revokeCert(issuerdn, serno, RevokedCertInfo.REVOCATION_REASON_CERTIFICATEHOLD);
                    assertTrue(ERRORNOTSENTFORAPPROVAL, false);
                } catch (WaitingForApprovalException_Exception e1) {
                }
                try {
                    ejbcaraws.revokeCert(issuerdn, serno, RevokedCertInfo.REVOCATION_REASON_CERTIFICATEHOLD);
                    assertTrue(ERRORNOTSENTFORAPPROVAL, false);
                } catch (ApprovalException_Exception e1) {
                }
                RevokeStatus revokestatus = ejbcaraws.checkRevokationStatus(issuerdn, serno);
                assertNotNull(revokestatus);
                assertTrue(revokestatus.getReason() == RevokedCertInfo.NOT_REVOKED);
                // Approve revocation and verify success
                approveRevocation(intAdmin, approvingAdmin, username,
                        RevokedCertInfo.REVOCATION_REASON_CERTIFICATEHOLD,
                        ApprovalDataVO.APPROVALTYPE_REVOKECERTIFICATE, certificateStoreSession, approvalSession,
                        approvalExecutionSession, caID);
                // Try to unrevoke certificate
                try {
                    ejbcaraws.revokeCert(issuerdn, serno, RevokedCertInfo.NOT_REVOKED);
                    assertTrue(ERRORNOTSENTFORAPPROVAL, false);
                } catch (WaitingForApprovalException_Exception e) {
                }
                try {
                    ejbcaraws.revokeCert(issuerdn, serno, RevokedCertInfo.NOT_REVOKED);
                    assertTrue(ERRORNOTSENTFORAPPROVAL, false);
                } catch (ApprovalException_Exception e) {
                }
                // Approve revocation and verify success
                approveRevocation(intAdmin, approvingAdmin, username, RevokedCertInfo.NOT_REVOKED,
                        ApprovalDataVO.APPROVALTYPE_REVOKECERTIFICATE, certificateStoreSession, approvalSession,
                        approvalExecutionSession, caID);
                // Revoke user
                try {
                    ejbcaraws.revokeUser(username, RevokedCertInfo.REVOCATION_REASON_CERTIFICATEHOLD, false);
                    assertTrue(ERRORNOTSENTFORAPPROVAL, false);
                } catch (WaitingForApprovalException_Exception e) {
                }
                try {
                    ejbcaraws.revokeUser(username, RevokedCertInfo.REVOCATION_REASON_CERTIFICATEHOLD, false);
                    assertTrue(ERRORNOTSENTFORAPPROVAL, false);
                } catch (ApprovalException_Exception e) {
                }
                // Approve revocation and verify success
                approveRevocation(intAdmin, approvingAdmin, username,
                        RevokedCertInfo.REVOCATION_REASON_CERTIFICATEHOLD,
                        ApprovalDataVO.APPROVALTYPE_REVOKEENDENTITY, certificateStoreSession, approvalSession,
                        approvalExecutionSession, caID);
                // Try to reactivate user
                try {
                    ejbcaraws.revokeUser(username, RevokedCertInfo.NOT_REVOKED, false);
                    assertTrue(ERRORNOTSUPPORTEDSUCCEEDED, false);
                } catch (AlreadyRevokedException_Exception e) {
                }
            } finally {
                endEntityManagementSession.deleteUser(intAdmin, username);
            }
            try {
                // Create a hard token issued by this CA
                createHardToken(TOKENUSERNAME, caname, TOKENSERIALNUMBER);
                assertTrue(ejbcaraws.existsHardToken(TOKENSERIALNUMBER));
                // Revoke token
                try {
                    ejbcaraws.revokeToken(TOKENSERIALNUMBER, RevokedCertInfo.REVOCATION_REASON_CERTIFICATEHOLD);
                    assertTrue(ERRORNOTSENTFORAPPROVAL, false);
                } catch (WaitingForApprovalException_Exception e) {
                }
                try {
                    ejbcaraws.revokeToken(TOKENSERIALNUMBER, RevokedCertInfo.REVOCATION_REASON_CERTIFICATEHOLD);
                    assertTrue(ERRORNOTSENTFORAPPROVAL, false);
                } catch (ApprovalException_Exception e) {
                }
                // Approve actions and verify success
                approveRevocation(intAdmin, approvingAdmin, TOKENUSERNAME,
                        RevokedCertInfo.REVOCATION_REASON_CERTIFICATEHOLD,
                        ApprovalDataVO.APPROVALTYPE_REVOKECERTIFICATE, certificateStoreSession, approvalSession,
                        approvalExecutionSession, caID);
            } finally {
                hardTokenSessionRemote.removeHardToken(intAdmin, TOKENSERIALNUMBER);
            }
        } finally {
            // Nuke CA
            try {
                caAdminSessionRemote.revokeCA(intAdmin, caID, RevokedCertInfo.REVOCATION_REASON_UNSPECIFIED);
            } finally {
                caSession.removeCA(intAdmin, caID);
                CryptoTokenTestUtils.removeCryptoToken(intAdmin, cryptoTokenId);
            }
        }
        log.trace("<test19RevocationApprovals");
    }

    @Test
    public void test20KeyRecoverNewest() throws Exception {
        keyRecover();
    }

    @Test
    public void test20bKeyRecoverAny() throws Exception {
        keyRecoverAny();
    }

    @Test
    public void test21GetAvailableCAs() throws Exception {
        getAvailableCAs();
    }

    @Test
    public void test22GetAuthorizedEndEntityProfiles() throws Exception {
        getAuthorizedEndEntityProfiles();
    }

    @Test
    public void test23GetAvailableCertificateProfiles() throws Exception {
        getAvailableCertificateProfiles();
    }

    @Test
    public void test24GetAvailableCAsInProfile() throws Exception {
        getAvailableCAsInProfile();
    }

    @Test
    public void test25CreateandGetCRL() throws Exception {
        createAndGetCRL();
    }

    @Test
    public void test27EjbcaVersion() throws Exception {
        ejbcaVersion();
    }

    @Test
    public void test29ErrorOnEditUser() throws Exception {
        errorOnEditUser();
    }

    @Test
    public void test30ErrorOnGeneratePkcs10() throws Exception {
        errorOnGeneratePkcs10();
    }

    @Test
    public void test31ErrorOnGeneratePkcs12() throws Exception {
        errorOnGeneratePkcs12();
    }

    @Test
    public void test32OperationOnNonexistingCA() throws Exception {
        operationOnNonexistingCA();
    }

    @Test
    public void test33CheckQueueLength() throws Exception {
        checkQueueLength();
    }

    /** In EJBCA 4.0.0 we changed the date format to ISO 8601. This verifies the that we still accept old requests, but returns UserDataVOWS objects using the new DateFormat 
     * @throws AuthorizationDeniedException */
    @Test
    public void test36EjbcaWsHelperTimeFormatConversion()
            throws CADoesntExistsException, ClassCastException, EjbcaException, AuthorizationDeniedException {
        log.trace(">test36EjbcaWsHelperTimeFormatConversion()");
        final Date nowWithOutSeconds = new Date((new Date().getTime() / 60000) * 60000); // To avoid false negatives.. we will loose precision when we convert back and forth..
        final String oldTimeFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT, Locale.US)
                .format(nowWithOutSeconds);
        final String newTimeFormatStorage = FastDateFormat
                .getInstance("yyyy-MM-dd HH:mm", TimeZone.getTimeZone("UTC")).format(nowWithOutSeconds);
        final String newTimeFormatRequest = FastDateFormat
                .getInstance("yyyy-MM-dd HH:mm:ssZZ", TimeZone.getTimeZone("CEST")).format(nowWithOutSeconds);
        final String newTimeFormatResponse = FastDateFormat
                .getInstance("yyyy-MM-dd HH:mm:ssZZ", TimeZone.getTimeZone("UTC")).format(nowWithOutSeconds);
        final String relativeTimeFormat = "0123:12:31";
        log.debug("oldTimeFormat=" + oldTimeFormat);
        log.debug("newTimeFormatStorage=" + newTimeFormatStorage);
        log.debug("newTimeFormatRequest=" + newTimeFormatRequest);
        // Convert from UserDataVOWS with US Locale DateFormat to endEntityInformation
        final org.ejbca.core.protocol.ws.objects.UserDataVOWS userDataVoWs = new org.ejbca.core.protocol.ws.objects.UserDataVOWS(
                "username", "password", false, "CN=User U", "CA1", null, null, 10, "P12", "EMPTY", "ENDUSER", null);
        userDataVoWs.setStartTime(oldTimeFormat);
        userDataVoWs.setEndTime(oldTimeFormat);
        final EndEntityInformation endEntityInformation1 = EjbcaWSHelper.convertUserDataVOWS(userDataVoWs, 1, 2, 3,
                4, 5);
        assertEquals("CUSTOM_STARTTIME in old format was not correctly handled (VOWS to VO).", newTimeFormatStorage,
                endEntityInformation1.getExtendedinformation().getCustomData(ExtendedInformation.CUSTOM_STARTTIME));
        assertEquals("CUSTOM_ENDTIME in old format was not correctly handled (VOWS to VO).", newTimeFormatStorage,
                endEntityInformation1.getExtendedinformation().getCustomData(ExtendedInformation.CUSTOM_ENDTIME));
        // Convert from UserDataVOWS with standard DateFormat to endEntityInformation
        userDataVoWs.setStartTime(newTimeFormatRequest);
        userDataVoWs.setEndTime(newTimeFormatRequest);
        final EndEntityInformation endEntityInformation2 = EjbcaWSHelper.convertUserDataVOWS(userDataVoWs, 1, 2, 3,
                4, 5);
        assertEquals("ExtendedInformation.CUSTOM_STARTTIME in new format was not correctly handled.",
                newTimeFormatStorage,
                endEntityInformation2.getExtendedinformation().getCustomData(ExtendedInformation.CUSTOM_STARTTIME));
        assertEquals("ExtendedInformation.CUSTOM_ENDTIME in new format was not correctly handled.",
                newTimeFormatStorage,
                endEntityInformation2.getExtendedinformation().getCustomData(ExtendedInformation.CUSTOM_ENDTIME));
        // Convert from UserDataVOWS with relative date format to endEntityInformation
        userDataVoWs.setStartTime(relativeTimeFormat);
        userDataVoWs.setEndTime(relativeTimeFormat);
        final EndEntityInformation endEntityInformation3 = EjbcaWSHelper.convertUserDataVOWS(userDataVoWs, 1, 2, 3,
                4, 5);
        assertEquals("ExtendedInformation.CUSTOM_STARTTIME in relative format was not correctly handled.",
                relativeTimeFormat,
                endEntityInformation3.getExtendedinformation().getCustomData(ExtendedInformation.CUSTOM_STARTTIME));
        assertEquals("ExtendedInformation.CUSTOM_ENDTIME in relative format was not correctly handled.",
                relativeTimeFormat,
                endEntityInformation3.getExtendedinformation().getCustomData(ExtendedInformation.CUSTOM_ENDTIME));
        // Convert from endEntityInformation with standard DateFormat to UserDataVOWS
        final org.ejbca.core.protocol.ws.objects.UserDataVOWS userDataVoWs1 = EjbcaWSHelper
                .convertEndEntityInformation(endEntityInformation1, "CA1", "EEPROFILE", "CERTPROFILE",
                        "HARDTOKENISSUER", "P12");
        // We expect that the server will respond using UTC
        assertEquals("CUSTOM_STARTTIME in new format was not correctly handled (VO to VOWS).",
                newTimeFormatResponse, userDataVoWs1.getStartTime());
        assertEquals("CUSTOM_ENDTIME in new format was not correctly handled (VO to VOWS).", newTimeFormatResponse,
                userDataVoWs1.getEndTime());
        // Convert from EndEntityInformation with relative date format to UserDataVOWS
        final org.ejbca.core.protocol.ws.objects.UserDataVOWS userDataVoWs3 = EjbcaWSHelper
                .convertEndEntityInformation(endEntityInformation3, "CA1", "EEPROFILE", "CERTPROFILE",
                        "HARDTOKENISSUER", "P12");
        assertEquals("CUSTOM_STARTTIME in relative format was not correctly handled (VO to VOWS).",
                relativeTimeFormat, userDataVoWs3.getStartTime());
        assertEquals("CUSTOM_ENDTIME in relative format was not correctly handled (VO to VOWS).",
                relativeTimeFormat, userDataVoWs3.getEndTime());
        // Try some invalid start time date format
        userDataVoWs.setStartTime("12:32 2011-02-28"); // Invalid
        userDataVoWs.setEndTime("2011-02-28 12:32:00+00:00"); // Valid
        try {
            EjbcaWSHelper.convertUserDataVOWS(userDataVoWs, 1, 2, 3, 4, 5);
            fail("Conversion of illegal time format did not generate exception.");
        } catch (EjbcaException e) {
            assertEquals("Unexpected error code in exception.", ErrorCode.FIELD_VALUE_NOT_VALID, e.getErrorCode());
        }
        // Try some invalid end time date format
        userDataVoWs.setStartTime("2011-02-28 12:32:00+00:00"); // Valid
        userDataVoWs.setEndTime("12:32 2011-02-28"); // Invalid
        try {
            EjbcaWSHelper.convertUserDataVOWS(userDataVoWs, 1, 2, 3, 4, 5);
            fail("Conversion of illegal time format did not generate exception.");
        } catch (EjbcaException e) {
            assertEquals("Unexpected error code in exception.", ErrorCode.FIELD_VALUE_NOT_VALID, e.getErrorCode());
        }
        log.trace("<test36EjbcaWsHelperTimeFormatConversion()");
    }

    /**
     * Simulate a simple SQL injection by sending the illegal char "'".
     * 
     * @throws Exception
     */
    @Test
    public void test40EvilFind01() throws Exception {
        log.trace(">testEvilFind01()");
        UserMatch usermatch = new UserMatch();
        usermatch.setMatchwith(org.ejbca.util.query.UserMatch.MATCH_WITH_USERNAME);
        usermatch.setMatchtype(org.ejbca.util.query.UserMatch.MATCH_TYPE_EQUALS);
        usermatch.setMatchvalue("A' OR '1=1");
        try {
            List<UserDataVOWS> userdatas = ejbcaraws.findUser(usermatch);
            fail("SQL injection did not cause an error! " + userdatas.size());
        } catch (IllegalQueryException_Exception e) {
            // NOPMD, this should be thrown and we ignore it because we fail if
            // it is not thrown
        }
        log.trace("<testEvilFind01()");
    }

    /**
     * Use single transaction method for requesting KeyStore with special
     * characters in the certificate SubjectDN.
     */
    @Test
    public void test41CertificateRequestWithSpecialChars01() throws Exception {
        long rnd = secureRandom.nextLong();
        testCertificateRequestWithSpecialChars("CN=test" + rnd + ", O=foo\\+bar\\\"\\,, C=SE",
                "CN=test" + rnd + ",O=foo\\+bar\\\"\\,,C=SE");
    }

    /**
     * Use single transaction method for requesting KeyStore with special
     * characters in the certificate SubjectDN.
     */
    @Test
    public void test42CertificateRequestWithSpecialChars02() throws Exception {
        long rnd = secureRandom.nextLong();
        testCertificateRequestWithSpecialChars("CN=test" + rnd + ",O=foo/bar\\;123, C=SE",
                "CN=test" + rnd + ",O=foo/bar/123,C=SE");
    }

    /**
     * Use single transaction method for requesting KeyStore with special
     * characters in the certificate SubjectDN.
     */
    @Test
    public void test43CertificateRequestWithSpecialChars03() throws Exception {
        long rnd = secureRandom.nextLong();
        testCertificateRequestWithSpecialChars("CN=test" + rnd + ", O=foo+bar\\+123, C=SE",
                "CN=test" + rnd + ",O=foo\\+bar\\+123,C=SE");
    }

    /**
     * Use single transaction method for requesting KeyStore with special
     * characters in the certificate SubjectDN.
     */
    @Test
    public void test44CertificateRequestWithSpecialChars04() throws Exception {
        long rnd = secureRandom.nextLong();
        testCertificateRequestWithSpecialChars("CN=test" + rnd + ", O=foo\\=bar, C=SE",
                "CN=test" + rnd + ",O=foo\\=bar,C=SE");
    }

    /**
     * Use single transaction method for requesting KeyStore with special
     * characters in the certificate SubjectDN.
     */
    @Test
    public void test45CertificateRequestWithSpecialChars05() throws Exception {
        long rnd = secureRandom.nextLong();
        testCertificateRequestWithSpecialChars("CN=test" + rnd + ", O=\"foo=bar, C=SE\"",
                "CN=test" + rnd + ",O=foo\\=bar\\, C\\=SE");
    }

    /**
     * Use single transaction method for requesting KeyStore with special
     * characters in the certificate SubjectDN.
     */
    @Test
    public void test46CertificateRequestWithSpecialChars06() throws Exception {
        long rnd = secureRandom.nextLong();
        testCertificateRequestWithSpecialChars("CN=test" + rnd + ", O=\"foo+b\\+ar, C=SE\"",
                "CN=test" + rnd + ",O=foo\\+b\\+ar\\, C\\=SE");
    }

    /**
     * Use single transaction method for requesting KeyStore with special
     * characters in the certificate SubjectDN.
     */
    @Test
    public void test47CertificateRequestWithSpecialChars07() throws Exception {
        long rnd = secureRandom.nextLong();
        testCertificateRequestWithSpecialChars("CN=test" + rnd + ", O=\\\"foo+b\\+ar\\, C=SE\\\"",
                "CN=test" + rnd + ",O=\\\"foo\\+b\\+ar\\, C\\=SE\\\"");
    }

    /**
     * Test that all but one default certificate forbidden characters are substituted
     * with '/'.
     * The one not tested is the null character ('\0'). It is not tested since
     * it is not a valid xml character so the WS protocol can not handle it.
     */
    @Test
    public void test48CertificateRequestWithForbiddenCharsDefault() throws Exception {
        long rnd = secureRandom.nextLong();
        cesecoreConfigurationProxySession.setConfigurationValue(forbiddenCharsKey, null);
        testCertificateRequestWithSpecialChars("CN=test" + rnd + ",O=|\n|\r|;|A|!|`|?|$|~|, C=SE",
                "CN=test" + rnd + ",O=|/|/|/|A|/|/|/|/|/|,C=SE");
    }

    /**
     * Same as {@link #test48CertificateRequestWithForbiddenCharsDefault()} but setting
     * default values in config.
     */
    @Test
    public void test49CertificateRequestWithForbiddenCharsDefinedAsDefault() throws Exception {
        long rnd = secureRandom.nextLong();
        cesecoreConfigurationProxySession.setConfigurationValue(forbiddenCharsKey, "\n\r;!\u0000%`?$~");
        testCertificateRequestWithSpecialChars("CN=test" + rnd + ",O=|\n|\r|;|A|!|`|?|$|~|, C=SE",
                "CN=test" + rnd + ",O=|/|/|/|A|/|/|/|/|/|,C=SE");
    }

    /**
     * Test to define some forbidden chars.
     */
    @Test
    public void test50CertificateRequestWithForbiddenCharsDefinedBogus() throws Exception {
        long rnd = secureRandom.nextLong();
        cesecoreConfigurationProxySession.setConfigurationValue(forbiddenCharsKey, "tset");
        try {
            testCertificateRequestWithSpecialChars("CN=test" + rnd + ",O=|\n|\r|;|A|!|`|?|$|~|, C=SE",
                    "CN=////" + rnd + ",O=|\n|\r|\\;|A|!|`|?|$|~|,C=SE");
        } finally {
            // we must remove this bogus settings otherwise next setupAdmin() will fail
            cesecoreConfigurationProxySession.setConfigurationValue(forbiddenCharsKey, "");
        }
    }

    /**
     * Test that no forbidden chars work
     */
    @Test
    public void test51CertificateRequestWithNoForbiddenChars() throws Exception {
        long rnd = secureRandom.nextLong();
        cesecoreConfigurationProxySession.setConfigurationValue(forbiddenCharsKey, "");
        testCertificateRequestWithSpecialChars("CN=test" + rnd + ",O=|\n|\r|;|A|!|`|?|$|~|, C=SE",
                "CN=test" + rnd + ",O=|\n|\r|\\;|A|!|`|?|$|~|,C=SE");
    }

    /**
     * Tests that the provided cardnumber is stored in the EndEntityInformation 
     * and that when querying for EndEntityInformation the cardnumber is 
     * returned.
     * @throws Exception in case of error
     */
    @Test
    public void test48CertificateRequestWithCardNumber() throws Exception {
        String userName = "wsRequestCardNumber" + new SecureRandom().nextLong();

        // Generate a CSR
        KeyPair keys = KeyTools.genKeys("1024", AlgorithmConstants.KEYALGORITHM_RSA);
        PKCS10CertificationRequest pkcs10 = CertTools.genPKCS10CertificationRequest("SHA256WithRSA",
                CertTools.stringToBcX500Name("CN=NOUSED"), keys.getPublic(), new DERSet(), keys.getPrivate(), null);
        final String csr = new String(Base64.encode(pkcs10.toASN1Structure().getEncoded()));

        // Set some user data
        final UserDataVOWS userData = new UserDataVOWS();
        userData.setUsername(userName);
        userData.setPassword(PASSWORD);
        userData.setClearPwd(true);
        userData.setSubjectDN("CN=test" + secureRandom.nextLong() + ", UID=" + userName + ", O=Test, C=SE");
        userData.setCaName(getAdminCAName());
        userData.setEmail(null);
        userData.setSubjectAltName(null);
        userData.setStatus(UserDataVOWS.STATUS_NEW);
        userData.setTokenType(UserDataVOWS.TOKEN_TYPE_P12);
        userData.setEndEntityProfileName("EMPTY");
        userData.setCertificateProfileName("ENDUSER");

        // Set the card number
        userData.setCardNumber("1234fa");

        // Issue a certificate
        CertificateResponse response = ejbcaraws.certificateRequest(userData, csr,
                CertificateHelper.CERT_REQ_TYPE_PKCS10, null, CertificateHelper.RESPONSETYPE_CERTIFICATE);
        assertNotNull("null response", response);

        // Check that the cardnumber was stored in the EndEntityInformation
        EndEntityInformation endEntity = endEntityAccessSession.findUser(intAdmin, userName);
        assertEquals("stored cardnumber ejb", "1234fa", endEntity.getCardNumber());

        // Check that the cardnumber is also available when querying using WS
        UserMatch criteria = new UserMatch();
        criteria.setMatchtype(UserMatch.MATCH_TYPE_EQUALS);
        criteria.setMatchwith(UserMatch.MATCH_WITH_USERNAME);
        criteria.setMatchvalue(userName);
        UserDataVOWS user = ejbcaraws.findUser(criteria).get(0);
        assertEquals("stored cardnumber ws", "1234fa", user.getCardNumber());
    }

    @Test
    public void test52GetProfileFromID() throws Exception {
        getEndEntityProfileFromID();
        getCertificateProfileFromID();
    }

    @Test
    public void test53CertificateRequestWithoutDnOverrideFromEndEntityInformation() throws Exception {
        final long rnd = Math.abs(secureRandom.nextLong());
        testCertificateRequestWithEeiDnOverride(false, true,
                "L=locality,OU=OU1,JURISDICTIONLOCALITY=jlocality,CN=rox" + rnd
                        + ".primekey.se,C=SE,ST=Sthlm,OU=OU2,O=PrimeKey,JURISDICTIONCOUNTRY=SE,SN=12345,BUSINESSCATEGORY=Private Organization",
                "JurisdictionCountry=SE,JurisdictionLocality=jlocality,BusinessCategory=Private Organization,CN=rox"
                        + rnd + ".primekey.se,SN=12345,OU=OU2,OU=OU1,O=PrimeKey,L=locality,ST=Sthlm,C=SE");
    }

    @Test
    public void test54SoftTokenRequestWithoutDnOverrideFromEndEntityInformation() throws Exception {
        final long rnd = Math.abs(secureRandom.nextLong());
        testCertificateRequestWithEeiDnOverride(false, false,
                "L=locality,OU=OU1,JURISDICTIONLOCALITY=jlocality,CN=rox" + rnd
                        + ".primekey.se,C=SE,ST=Sthlm,OU=OU2,O=PrimeKey,JURISDICTIONCOUNTRY=SE,SN=12345,BUSINESSCATEGORY=Private Organization",
                "JurisdictionCountry=SE,JurisdictionLocality=jlocality,BusinessCategory=Private Organization,CN=rox"
                        + rnd + ".primekey.se,SN=12345,OU=OU2,OU=OU1,O=PrimeKey,L=locality,ST=Sthlm,C=SE");
    }

    @Test
    public void test55CertificateRequestWithDnOverrideFromEndEntityInformation() throws Exception {
        final long rnd = Math.abs(secureRandom.nextLong());
        testCertificateRequestWithEeiDnOverride(true, true,
                "L=locality,OU=OU1,JURISDICTIONLOCALITY=jlocality,CN=rox" + rnd
                        + ".primekey.se,C=SE,ST=Sthlm,OU=OU2,O=PrimeKey,JURISDICTIONCOUNTRY=SE,SN=12345,BUSINESSCATEGORY=Private Organization",
                "L=locality,OU=OU1,JurisdictionLocality=jlocality,CN=rox" + rnd
                        + ".primekey.se,C=SE,ST=Sthlm,OU=OU2,O=PrimeKey,JurisdictionCountry=SE,SN=12345,BusinessCategory=Private Organization");
    }

    @Test
    public void test56SoftTokenRequestWithDnOverrideFromEndEntityInformation() throws Exception {
        final long rnd = Math.abs(secureRandom.nextLong());
        testCertificateRequestWithEeiDnOverride(true, false,
                "L=locality,OU=OU1,JURISDICTIONLOCALITY=jlocality,CN=rox" + rnd
                        + ".primekey.se,C=SE,ST=Sthlm,OU=OU2,O=PrimeKey,JURISDICTIONCOUNTRY=SE,SN=12345,BUSINESSCATEGORY=Private Organization",
                "L=locality,OU=OU1,JurisdictionLocality=jlocality,CN=rox" + rnd
                        + ".primekey.se,C=SE,ST=Sthlm,OU=OU2,O=PrimeKey,JurisdictionCountry=SE,SN=12345,BusinessCategory=Private Organization");
    }

    @Test
    public void test57CertificateRequestWithDnOverrideFromEndEntityInformation() throws Exception {
        cesecoreConfigurationProxySession.setConfigurationValue(forbiddenCharsKey, "\n\r;!\u0000%`?$~");
        final long rnd = Math.abs(secureRandom.nextLong());
        testCertificateRequestWithEeiDnOverride(true, true,
                "L=locality,OU=OU1, JURISDICTIONLOCALITY= jlocality ,CN=,CN=rox" + rnd
                        + ".primekey.se;C=SE,ST=Sthlm\n,OU=OU2 ,O=PrimeKey,JURISDICTIONCOUNTRY=SE+SN=12345,BUSINESSCATEGORY=Private Organization",
                "L=locality,OU=OU1,JurisdictionLocality=jlocality,CN=rox" + rnd
                        + ".primekey.se/C\\=SE,ST=Sthlm/,OU=OU2,O=PrimeKey,JurisdictionCountry=SE\\+SN\\=12345,BusinessCategory=Private Organization");
    }

    @Test
    public void test58SoftTokenRequestWithDnOverrideFromEndEntityInformation() throws Exception {
        cesecoreConfigurationProxySession.setConfigurationValue(forbiddenCharsKey, "\n\r;!\u0000%`?$~");
        final long rnd = Math.abs(secureRandom.nextLong());
        testCertificateRequestWithEeiDnOverride(true, false,
                "L=locality,OU=OU1, JURISDICTIONLOCALITY= jlocality ,CN=,CN=rox" + rnd
                        + ".primekey.se;C=SE,ST=Sthlm\n,OU=OU2 ,O=PrimeKey,JURISDICTIONCOUNTRY=SE+SN=12345,BUSINESSCATEGORY=Private Organization",
                "L=locality,OU=OU1,JurisdictionLocality=jlocality,CN=rox" + rnd
                        + ".primekey.se/C\\=SE,ST=Sthlm/,OU=OU2,O=PrimeKey,JurisdictionCountry=SE\\+SN\\=12345,BusinessCategory=Private Organization");
    }

    /* This is apparently allowed but puts the system in a world of pain, since other functions are not adapted to handle an empty subjectDN
    @Test
    public void test59CertificateRequestWithoutDnOverrideFromEndEntityInformation() throws Exception {
    try {
        testCertificateRequestWithEeiDnOverride(false, true, "", "");
        fail("Was able to provide an empty subjectDN.");
    } catch (EjbcaException_Exception e) {
        log.error(e.getMessage(), e);
    }
    }
        
    @Test
    public void test60CertificateRequestWithDnOverrideFromEndEntityInformation() throws Exception {
    try {
        testCertificateRequestWithEeiDnOverride(true, true, "", "");
        fail("Was able to provide an empty subjectDN.");
    } catch (EjbcaException_Exception e) {
        log.error(e.getMessage(), e);
    }
    }
        
    @Test
    public void test61SoftTokenRequestWithoutDnOverrideFromEndEntityInformation() throws Exception {
    try {
        testCertificateRequestWithEeiDnOverride(false, false, "", "");
        fail("Was able to provide an empty subjectDN.");
    } catch (EjbcaException_Exception e) {
        log.error(e.getMessage(), e);
    }
    }
        
    @Test
    public void test62SoftTokenRequestWithDnOverrideFromEndEntityInformation() throws Exception {
    try {
        testCertificateRequestWithEeiDnOverride(true, false, "", "");
        fail("Was able to provide an empty subjectDN.");
    } catch (EjbcaException_Exception e) {
        log.error(e.getMessage(), e);
    }
    }
    */

    @Test
    public void test70CreateSoftCryptoToken() throws Exception {
        log.trace(">test70CreateSoftCryptoToken()");

        // If this is community edition, then this method is not supported and the test is skipped
        boolean methodSupported = true;
        try {
            ejbcaraws.createCryptoToken(null, null, null, false, null);
        } catch (EjbcaException_Exception e) {
            if (e.getFaultInfo().getErrorCode().getInternalErrorCode()
                    .equals(ErrorCode.UNSUPPORTED_METHOD.getInternalErrorCode())) {
                methodSupported = false;
            }
        }
        assumeTrue(methodSupported);

        String ctname = "NewTestCryptoTokenThroughWS";

        // Remove any residues from earlier test runs
        Integer ctid = cryptoTokenManagementSession.getIdFromName(ctname);
        if (ctid != null) {
            cryptoTokenManagementSession.deleteCryptoToken(intAdmin, ctid.intValue());
        }

        try {
            ArrayList<KeyValuePair> cryptotokenProperties = new ArrayList<KeyValuePair>();
            cryptotokenProperties
                    .add(new KeyValuePair(CryptoToken.ALLOW_EXTRACTABLE_PRIVATE_KEY, Boolean.toString(false)));
            cryptotokenProperties.add(new KeyValuePair(SoftCryptoToken.NODEFAULTPWD, Boolean.TRUE.toString()));

            ejbcaraws.createCryptoToken(ctname, "SoftCryptoToken", "1234", false, cryptotokenProperties);
            ctid = cryptoTokenManagementSession.getIdFromName(ctname);
            assertNotNull("Creating a new SoftCryptoToken failed", ctid);
            CryptoTokenInfo token = cryptoTokenManagementSession.getCryptoTokenInfo(intAdmin, ctid.intValue());

            Properties ctproperties = token.getCryptoTokenProperties();
            assertEquals(3, ctproperties.keySet().size());
            assertTrue(ctproperties.containsKey(SoftCryptoToken.NODEFAULTPWD));
            assertEquals(ctproperties.getProperty(SoftCryptoToken.NODEFAULTPWD), Boolean.TRUE.toString());

            assertEquals("SoftCryptoToken", token.getType());
            assertFalse(Boolean.getBoolean(
                    (String) token.getCryptoTokenProperties().get(CryptoToken.ALLOW_EXTRACTABLE_PRIVATE_KEY)));
            assertTrue(token.isActive());
            cryptoTokenManagementSession.deactivate(intAdmin, ctid.intValue());
            assertFalse(cryptoTokenManagementSession.isCryptoTokenStatusActive(intAdmin, ctid.intValue()));
            cryptoTokenManagementSession.activate(intAdmin, ctid.intValue(), "1234".toCharArray());
            assertTrue(cryptoTokenManagementSession.isCryptoTokenStatusActive(intAdmin, ctid.intValue()));
        } finally {
            ctid = cryptoTokenManagementSession.getIdFromName(ctname);
            if (ctid != null) {
                cryptoTokenManagementSession.deleteCryptoToken(intAdmin, ctid.intValue());
            }
        }
        log.trace("<test70CreateSoftCryptoToken()");
    }

    @Test
    public void test71GenerateCryptoTokenKeys() throws Exception {
        log.trace(">test71GenerateCryptoTokenKeys()");

        // If this is community edition, then this method is not supported and the test is skipped
        boolean methodSupported = true;
        try {
            ejbcaraws.generateCryptoTokenKeys(null, null, null);
        } catch (EjbcaException_Exception e) {
            if (e.getFaultInfo().getErrorCode().getInternalErrorCode()
                    .equals(ErrorCode.UNSUPPORTED_METHOD.getInternalErrorCode())) {
                methodSupported = false;
            }
        }
        assumeTrue(methodSupported);

        String ctname = "NewTestCryptoTokenThroughWS";

        // Remove any residues from earlier test runs
        Integer ctid = cryptoTokenManagementSession.getIdFromName(ctname);
        if (ctid != null) {
            cryptoTokenManagementSession.deleteCryptoToken(intAdmin, ctid.intValue());
        }

        try {
            ArrayList<KeyValuePair> cryptotokenProperties = new ArrayList<KeyValuePair>();
            cryptotokenProperties
                    .add(new KeyValuePair(CryptoToken.ALLOW_EXTRACTABLE_PRIVATE_KEY, Boolean.toString(false)));
            cryptotokenProperties.add(new KeyValuePair(SoftCryptoToken.NODEFAULTPWD, Boolean.TRUE.toString()));
            ejbcaraws.createCryptoToken(ctname, "SoftCryptoToken", "1234", false, cryptotokenProperties);
            ctid = cryptoTokenManagementSession.getIdFromName(ctname);

            String keyAlias = "testWSGeneratedKeys";
            ejbcaraws.generateCryptoTokenKeys(ctname, keyAlias, "RSA1024");
            List<String> keyAliases = cryptoTokenManagementSession.getKeyPairAliases(intAdmin, ctid.intValue());
            assertTrue(keyAliases.contains(keyAlias));
            KeyPairInfo keyInfo = cryptoTokenManagementSession.getKeyPairInfo(intAdmin, ctid.intValue(), keyAlias);
            assertEquals("RSA", keyInfo.getKeyAlgorithm());
            assertEquals("1024", keyInfo.getKeySpecification());
        } finally {
            ctid = cryptoTokenManagementSession.getIdFromName(ctname);
            if (ctid != null) {
                cryptoTokenManagementSession.deleteCryptoToken(intAdmin, ctid.intValue());
            }
        }
        log.trace("<test71GenerateCryptoTokenKeys()");
    }

    @Test
    public void test72CreateCA() throws Exception {
        log.trace(">test72CreateCA()");

        // It this is community edition, then this method is not supported and the test is skipped
        boolean methodSupported = true;
        try {
            ejbcaraws.createCA(null, null, null, 0L, null, null, 0, null, null, null);
        } catch (EjbcaException_Exception e) {
            if (e.getFaultInfo().getErrorCode().getInternalErrorCode()
                    .equals(ErrorCode.UNSUPPORTED_METHOD.getInternalErrorCode())) {
                methodSupported = false;
            }
        }
        assumeTrue(methodSupported);

        String caname = "NewTestCAThroughWS";
        String ctname = caname + "CryptoToken";

        // Remove any residues from earlier test runs
        if (caSession.existsCa(caname)) {
            int caid = caSession.getCAInfo(intAdmin, caname).getCAId();
            caSession.removeCA(intAdmin, caid);
        }

        Integer ctid = cryptoTokenManagementSession.getIdFromName(ctname);
        if (ctid != null) {
            cryptoTokenManagementSession.deleteCryptoToken(intAdmin, ctid.intValue());
        }

        try {
            // create cryptotoken
            ArrayList<KeyValuePair> cryptotokenProperties = new ArrayList<KeyValuePair>();
            cryptotokenProperties
                    .add(new KeyValuePair(CryptoToken.ALLOW_EXTRACTABLE_PRIVATE_KEY, Boolean.toString(false)));
            cryptotokenProperties.add(new KeyValuePair(SoftCryptoToken.NODEFAULTPWD, Boolean.TRUE.toString()));
            ejbcaraws.createCryptoToken(ctname, "SoftCryptoToken", "1234", true, cryptotokenProperties);
            ctid = cryptoTokenManagementSession.getIdFromName(ctname);

            // generate keys
            final String decKeyAlias = CAToken.SOFTPRIVATEDECKEYALIAS;
            ejbcaraws.generateCryptoTokenKeys(ctname, decKeyAlias, "RSA1024");
            final String signKeyAlias = CAToken.SOFTPRIVATESIGNKEYALIAS;
            ejbcaraws.generateCryptoTokenKeys(ctname, signKeyAlias, "RSA1024");
            final String testKeyAlias = "test72CreateCATestKey";
            ejbcaraws.generateCryptoTokenKeys(ctname, testKeyAlias, "secp256r1");

            // construct the ca token properties
            final ArrayList<KeyValuePair> purposeKeyMapping = new ArrayList<KeyValuePair>();
            purposeKeyMapping.add(
                    new KeyValuePair(CATokenConstants.CAKEYPURPOSE_DEFAULT_STRING, CAToken.SOFTPRIVATEDECKEYALIAS));
            purposeKeyMapping.add(new KeyValuePair(CATokenConstants.CAKEYPURPOSE_CERTSIGN_STRING,
                    CAToken.SOFTPRIVATESIGNKEYALIAS));
            purposeKeyMapping.add(new KeyValuePair(CATokenConstants.CAKEYPURPOSE_CRLSIGN_STRING,
                    CAToken.SOFTPRIVATESIGNKEYALIAS));
            purposeKeyMapping.add(new KeyValuePair(CATokenConstants.CAKEYPURPOSE_TESTKEY_STRING, testKeyAlias));

            // Try to create a CA signed by an external CA. It should fail.
            try {
                ejbcaraws.createCA(caname, "CN=" + caname, "x509", 3L, null, "SHA256WithRSA",
                        CAInfo.SIGNEDBYEXTERNALCA, ctname, purposeKeyMapping, null);
                fail("It was possible to create a CA signed by an external CA");
            } catch (EjbcaException_Exception e) {
                if (!e.getFaultInfo().getErrorCode().getInternalErrorCode()
                        .equals(ErrorCode.SIGNED_BY_EXTERNAL_CA_NOT_SUPPORTED.getInternalErrorCode())) {
                    throw e;
                }
            }

            // Try to create a CA that already exists. It should fail
            String existingTestCA = "WSCreateCATestTestingExistingCA";
            CaTestCase.createTestCA(existingTestCA);
            try {
                ejbcaraws.createCA(existingTestCA, caSession.getCAInfo(intAdmin, existingTestCA).getSubjectDN(),
                        "x509", 3L, null, "SHA256WithRSA", CAInfo.SELFSIGNED, ctname, purposeKeyMapping, null);
                fail("It was possible to create a CA even though the CA already exists");
            } catch (EjbcaException_Exception e) {
                if (!e.getFaultInfo().getErrorCode().getInternalErrorCode()
                        .equals(ErrorCode.CA_ALREADY_EXISTS.getInternalErrorCode())) {
                    throw e;
                }
                caSession.removeCA(intAdmin, caSession.getCAInfo(intAdmin, existingTestCA).getCAId());
            }

            // Try to create a CA. It should succeed (Happy path test)
            ejbcaraws.createCA(caname, "CN=" + caname, "x509", 3L, null, "SHA256WithRSA", CAInfo.SELFSIGNED, ctname,
                    purposeKeyMapping, null);

            // Verify the new CA's parameters
            CAInfo cainfo = caSession.getCAInfo(intAdmin, caname);
            assertNotNull(cainfo);
            assertEquals(caname, cainfo.getName());
            assertEquals("CN=" + caname, cainfo.getSubjectDN());
            assertEquals(CertificateProfileConstants.CERTPROFILE_FIXED_ROOTCA, cainfo.getCertificateProfileId());
            assertEquals(CAInfo.SELFSIGNED, cainfo.getSignedBy());
            assertEquals(CAInfo.CATYPE_X509, cainfo.getCAType());

        } finally {
            if (caSession.existsCa(caname)) {
                int caid = caSession.getCAInfo(intAdmin, caname).getCAId();
                caSession.removeCA(intAdmin, caid);
            }

            ctid = cryptoTokenManagementSession.getIdFromName(ctname);
            if (ctid != null) {
                cryptoTokenManagementSession.deleteCryptoToken(intAdmin, ctid.intValue());
            }
        }
        log.trace("<test72CreateCA()");
    }

    @Test
    public void test73ManageSubjectInRole() throws Exception {
        log.trace(">test73AddSubjectToRole()");

        // It this is community edition, then this method is not supported and the test is skipped
        boolean methodSupported = true;
        try {
            ejbcaraws.addSubjectToRole(null, null, null, null, null);
        } catch (EjbcaException_Exception e) {
            if (e.getFaultInfo().getErrorCode().getInternalErrorCode()
                    .equals(ErrorCode.UNSUPPORTED_METHOD.getInternalErrorCode())) {
                methodSupported = false;
            }
        }
        assumeTrue(methodSupported);

        String rolename = "TestWSNewAccessRole";
        String testAdminUsername = "newWsAdminUserName";

        // Remove any residues from earlier test runs
        RoleData role = roleAccessSession.findRole(rolename);
        if (role != null) {
            roleManagementSession.remove(intAdmin, role);
        }

        try {
            CAInfo cainfo = caSession.getCAInfo(intAdmin, getAdminCAName());
            assertNotNull("No CA with name " + getAdminCAName() + " was found.", cainfo);

            // Create/update the admin end entity and issue its certificate
            EndEntityInformation adminUser = endEntityAccessSession.findUser(intAdmin, testAdminUsername);
            if (adminUser == null) {
                adminUser = new EndEntityInformation();
                adminUser.setUsername(testAdminUsername);
                adminUser.setPassword("foo123");
                adminUser.setDN("CN=" + testAdminUsername);
                adminUser.setCAId(cainfo.getCAId());
                adminUser.setEmail(null);
                adminUser.setSubjectAltName(null);
                adminUser.setStatus(UserDataVOWS.STATUS_NEW);
                adminUser.setTokenType(SecConst.TOKEN_SOFT_JKS);
                adminUser.setEndEntityProfileId(SecConst.EMPTY_ENDENTITYPROFILE);
                adminUser.setCertificateProfileId(CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER);
                adminUser.setType(new EndEntityType(EndEntityTypes.ENDUSER, EndEntityTypes.ADMINISTRATOR));
                log.info("Adding new user: " + adminUser.getUsername());
                endEntityManagementSession.addUser(intAdmin, adminUser, true);
            } else {
                adminUser.setStatus(UserDataVOWS.STATUS_NEW);
                adminUser.setPassword("foo123");
                log.info("Changing user: " + adminUser.getUsername());
                endEntityManagementSession.changeUser(intAdmin, adminUser, true);
            }
            BatchCreateTool.createUser(intAdmin, "p12", adminUser.getUsername());
            adminUser = endEntityAccessSession.findUser(intAdmin, testAdminUsername);

            // Create a new role
            log.info("Creating new role: " + rolename);
            role = roleManagementSession.create(intAdmin, rolename);

            // Set access rules for the new role
            final List<AccessRuleData> accessRules = new ArrayList<AccessRuleData>();
            accessRules.add(new AccessRuleData(rolename, StandardRules.ROLE_ROOT.resource(),
                    AccessRuleState.RULE_ACCEPT, true));
            role = roleManagementSession.addAccessRulesToRole(intAdmin, role, accessRules);

            // Verify that there are no admins from the start
            assertTrue(role.getAccessUsers().size() == 0);

            // Add adminUser to a non-existing role. It should fail
            try {
                ejbcaraws.addSubjectToRole("NoneExistingRole", getAdminCAName(),
                        X500PrincipalAccessMatchValue.WITH_FULLDN.name(), AccessMatchType.TYPE_EQUALCASE.name(),
                        adminUser.getCertificateDN());
                fail("Succeeded in adding subject to a non-existing role");
            } catch (EjbcaException_Exception e) {
                if (!e.getFaultInfo().getErrorCode().getInternalErrorCode()
                        .equals(ErrorCode.ROLE_DOES_NOT_EXIST.getInternalErrorCode())) {
                    throw e;
                }
            }

            // Add adminUser to the new role. It should succeed
            ejbcaraws.addSubjectToRole(rolename, getAdminCAName(), X500PrincipalAccessMatchValue.WITH_FULLDN.name(),
                    AccessMatchType.TYPE_EQUALCASE.name(), adminUser.getCertificateDN());
            role = roleAccessSession.findRole(rolename);

            // Verify the admin data
            Collection<AccessUserAspectData> admins = role.getAccessUsers().values();
            assertTrue(admins.size() == 1);
            AccessUserAspectData addedAdmin = admins.iterator().next();
            assertEquals(cainfo.getCAId(), addedAdmin.getCaId().intValue());
            assertEquals(AccessMatchType.TYPE_EQUALCASE.getNumericValue(), addedAdmin.getMatchType());
            assertEquals(adminUser.getCertificateDN(), addedAdmin.getMatchValue());
            assertEquals(X500PrincipalAccessMatchValue.WITH_FULLDN.getNumericValue(), addedAdmin.getMatchWith());

            // Remove adminUser specified by a non-existing CA. It should fail
            try {
                ejbcaraws.removeSubjectFromRole(rolename, "NoneExistingCA",
                        X500PrincipalAccessMatchValue.WITH_FULLDN.name(), AccessMatchType.TYPE_EQUALCASE.name(),
                        adminUser.getCertificateDN());
                fail("Succeeded in adding subject to a non-existing role");
            } catch (EjbcaException_Exception e) {
                if (!e.getFaultInfo().getErrorCode().getInternalErrorCode()
                        .equals(ErrorCode.CA_NOT_EXISTS.getInternalErrorCode())) {
                    throw e;
                }
            }

            // Remove adminUser from the new role. It should succeed
            ejbcaraws.removeSubjectFromRole(rolename, getAdminCAName(),
                    X500PrincipalAccessMatchValue.WITH_FULLDN.name(), AccessMatchType.TYPE_EQUALCASE.name(),
                    adminUser.getCertificateDN());
            role = roleAccessSession.findRole(rolename);
            assertTrue(role.getAccessUsers().values().size() == 0);

        } finally {
            endEntityManagementSession.revokeAndDeleteUser(intAdmin, testAdminUsername,
                    RevokedCertInfo.REVOCATION_REASON_PRIVILEGESWITHDRAWN);
            if (roleAccessSession.findRole(rolename) != null) {
                roleManagementSession.remove(intAdmin, roleAccessSession.findRole(rolename));
            }
        }
        log.trace("<test73AddSubjectToRole()");
    }

    @Test
    public void test74GetExpiredCerts() throws Exception {
        log.trace(">test74GetExpiredCert()");
        getExpiredCerts();
        log.trace("<test74GetExpiredCert()");
    }

    private void testCertificateRequestWithEeiDnOverride(boolean allowDNOverrideByEndEntityInformation,
            boolean useCsr, String requestedSubjectDN, String expectedSubjectDN) throws Exception {
        if (certificateProfileSession.getCertificateProfileId(WS_TEST_CERTIFICATE_PROFILE_NAME) != 0) {
            certificateProfileSession.removeCertificateProfile(intAdmin, WS_TEST_CERTIFICATE_PROFILE_NAME);
        }
        CertificateProfile profile = new CertificateProfile(CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER);
        profile.setAllowDNOverrideByEndEntityInformation(allowDNOverrideByEndEntityInformation);
        certificateProfileSession.addCertificateProfile(intAdmin, WS_TEST_CERTIFICATE_PROFILE_NAME, profile);
        //This test will fail if EEP limitations are enabled
        GlobalConfiguration originalConfiguration = (GlobalConfiguration) globalConfigurationSession
                .getCachedConfiguration(GlobalConfiguration.GLOBAL_CONFIGURATION_ID);
        GlobalConfiguration globalConfiguration = (GlobalConfiguration) globalConfigurationSession
                .getCachedConfiguration(GlobalConfiguration.GLOBAL_CONFIGURATION_ID);
        globalConfiguration.setEnableEndEntityProfileLimitations(false);
        globalConfigurationSession.saveConfiguration(intAdmin, globalConfiguration);
        try {
            String userName = "eeiDnOverride" + secureRandom.nextLong();
            final UserDataVOWS userData = new UserDataVOWS();
            userData.setUsername(userName);
            userData.setPassword(PASSWORD);
            userData.setClearPwd(true);
            userData.setSubjectDN(requestedSubjectDN);
            userData.setCaName(getAdminCAName());
            userData.setEmail(null);
            userData.setSubjectAltName(null);
            userData.setStatus(UserDataVOWS.STATUS_NEW);
            userData.setTokenType(UserDataVOWS.TOKEN_TYPE_P12);
            userData.setEndEntityProfileName("EMPTY");
            userData.setCertificateProfileName(WS_TEST_CERTIFICATE_PROFILE_NAME);
            final X509Certificate cert;
            if (useCsr) {
                KeyPair keys = KeyTools.genKeys("1024", AlgorithmConstants.KEYALGORITHM_RSA);
                PKCS10CertificationRequest pkcs10 = CertTools.genPKCS10CertificationRequest("SHA256WithRSA",
                        CertTools.stringToBcX500Name("CN=NOUSED"), keys.getPublic(), new DERSet(),
                        keys.getPrivate(), null);
                final String csr = new String(Base64.encode(pkcs10.toASN1Structure().getEncoded()));
                CertificateResponse response = ejbcaraws.certificateRequest(userData, csr,
                        CertificateHelper.CERT_REQ_TYPE_PKCS10, null, CertificateHelper.RESPONSETYPE_CERTIFICATE);
                cert = response.getCertificate();
            } else {
                KeyStore ksenv = ejbcaraws.softTokenRequest(userData, null, "1024",
                        AlgorithmConstants.KEYALGORITHM_RSA);
                java.security.KeyStore keyStore = KeyStoreHelper.getKeyStore(ksenv.getKeystoreData(), "PKCS12",
                        PASSWORD);
                assertNotNull(keyStore);
                Enumeration<String> en = keyStore.aliases();
                String alias = en.nextElement();
                if (!keyStore.isKeyEntry(alias)) {
                    alias = en.nextElement();
                }
                cert = (X509Certificate) keyStore.getCertificate(alias);
            }
            final List<Certificate> certificates = Arrays.asList(new Certificate[] { cert });
            log.info(certificates.size() + " certs.\n"
                    + new String(CertTools.getPemFromCertificateChain(certificates)));
            X500Name x500name = new JcaX509CertificateHolder(cert).getSubject();
            String resultingSubjectDN = CeSecoreNameStyle.INSTANCE.toString(x500name);
            log.debug("x500name:           " + resultingSubjectDN);
            assertEquals("Unexpected transformation.", expectedSubjectDN, resultingSubjectDN);
            try {
                endEntityManagementSession.deleteUser(intAdmin, userName);
            } catch (NotFoundException e) {
                // Ignore
            }
        } finally {
            if (certificateProfileSession.getCertificateProfileId(WS_TEST_CERTIFICATE_PROFILE_NAME) != 0) {
                certificateProfileSession.removeCertificateProfile(intAdmin, WS_TEST_CERTIFICATE_PROFILE_NAME);
            }
            globalConfigurationSession.saveConfiguration(intAdmin, originalConfiguration);
        }
    }

    private void testCertificateRequestWithSpecialChars(String requestedSubjectDN, String expectedSubjectDN)
            throws Exception {
        String userName = "wsSpecialChars" + secureRandom.nextLong();
        final UserDataVOWS userData = new UserDataVOWS();
        userData.setUsername(userName);
        userData.setPassword(PASSWORD);
        userData.setClearPwd(true);
        userData.setSubjectDN(requestedSubjectDN);
        userData.setCaName(getAdminCAName());
        userData.setEmail(null);
        userData.setSubjectAltName(null);
        userData.setStatus(UserDataVOWS.STATUS_NEW);
        userData.setTokenType(UserDataVOWS.TOKEN_TYPE_P12);
        userData.setEndEntityProfileName("EMPTY");
        userData.setCertificateProfileName("ENDUSER");

        KeyStore ksenv = ejbcaraws.softTokenRequest(userData, null, "1024", AlgorithmConstants.KEYALGORITHM_RSA);
        java.security.KeyStore keyStore = KeyStoreHelper.getKeyStore(ksenv.getKeystoreData(), "PKCS12", PASSWORD);
        assertNotNull(keyStore);
        Enumeration<String> en = keyStore.aliases();
        String alias = en.nextElement();
        if (!keyStore.isKeyEntry(alias)) {
            alias = en.nextElement();
        }
        X509Certificate cert = (X509Certificate) keyStore.getCertificate(alias);

        String resultingSubjectDN = cert.getSubjectDN().toString();
        assertEquals(requestedSubjectDN + " was transformed into " + resultingSubjectDN + " (not the expected "
                + expectedSubjectDN + ")", expectedSubjectDN, resultingSubjectDN);
        try {
            endEntityManagementSession.deleteUser(intAdmin, userName);
        } catch (NotFoundException e) {
            // Ignore
        }
    }

    /**
     * Creates a "hardtoken" with certficates.
     */
    private void createHardToken(String username, String caName, String serialNumber) throws Exception {
        GlobalConfiguration gc = (GlobalConfiguration) globalConfigurationSession
                .getCachedConfiguration(GlobalConfiguration.GLOBAL_CONFIGURATION_ID);
        boolean originalProfileSetting = gc.getEnableEndEntityProfileLimitations();
        gc.setEnableEndEntityProfileLimitations(false);
        globalConfigurationSession.saveConfiguration(intAdmin, gc);
        if (certificateProfileSession.getCertificateProfileId(WS_TEST_CERTIFICATE_PROFILE_NAME) != 0) {
            certificateProfileSession.removeCertificateProfile(intAdmin, WS_TEST_CERTIFICATE_PROFILE_NAME);
        }
        CertificateProfile profile = new CertificateProfile(CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER);
        profile.setAllowValidityOverride(true);
        certificateProfileSession.addCertificateProfile(intAdmin, WS_TEST_CERTIFICATE_PROFILE_NAME, profile);
        UserDataVOWS tokenUser1 = new UserDataVOWS();
        tokenUser1.setUsername(username);
        tokenUser1.setPassword(PASSWORD);
        tokenUser1.setClearPwd(true);
        tokenUser1.setSubjectDN("CN=" + username);
        tokenUser1.setCaName(caName);
        tokenUser1.setEmail(null);
        tokenUser1.setSubjectAltName(null);
        tokenUser1.setStatus(UserDataVOWS.STATUS_NEW);
        tokenUser1.setTokenType(UserDataVOWS.TOKEN_TYPE_USERGENERATED);
        tokenUser1.setEndEntityProfileName("EMPTY");
        tokenUser1.setCertificateProfileName("ENDUSER");
        KeyPair basickeys = KeyTools.genKeys("1024", AlgorithmConstants.KEYALGORITHM_RSA);
        PKCS10CertificationRequest basicpkcs10 = CertTools.genPKCS10CertificationRequest("SHA256WithRSA",
                CertTools.stringToBcX500Name("CN=NOTUSED"), basickeys.getPublic(), new DERSet(),
                basickeys.getPrivate(), null);
        ArrayList<TokenCertificateRequestWS> requests = new ArrayList<TokenCertificateRequestWS>();
        TokenCertificateRequestWS tokenCertReqWS = new TokenCertificateRequestWS();
        tokenCertReqWS.setCAName(caName);
        tokenCertReqWS.setCertificateProfileName(WS_TEST_CERTIFICATE_PROFILE_NAME);
        tokenCertReqWS.setValidityIdDays("1");
        tokenCertReqWS.setPkcs10Data(basicpkcs10.getEncoded());
        tokenCertReqWS.setType(HardTokenConstants.REQUESTTYPE_PKCS10_REQUEST);
        requests.add(tokenCertReqWS);
        tokenCertReqWS = new TokenCertificateRequestWS();
        tokenCertReqWS.setCAName(caName);
        tokenCertReqWS.setCertificateProfileName("ENDUSER");
        tokenCertReqWS.setKeyalg("RSA");
        tokenCertReqWS.setKeyspec("1024");
        tokenCertReqWS.setType(HardTokenConstants.REQUESTTYPE_KEYSTORE_REQUEST);
        requests.add(tokenCertReqWS);
        HardTokenDataWS hardTokenDataWS = new HardTokenDataWS();
        hardTokenDataWS.setLabel(HardTokenConstants.LABEL_PROJECTCARD);
        hardTokenDataWS.setTokenType(HardTokenConstants.TOKENTYPE_SWEDISHEID);
        hardTokenDataWS.setHardTokenSN(serialNumber);
        PinDataWS basicPinDataWS = new PinDataWS();
        basicPinDataWS.setType(HardTokenConstants.PINTYPE_BASIC);
        basicPinDataWS.setInitialPIN("1234");
        basicPinDataWS.setPUK("12345678");
        PinDataWS signaturePinDataWS = new PinDataWS();
        signaturePinDataWS.setType(HardTokenConstants.PINTYPE_SIGNATURE);
        signaturePinDataWS.setInitialPIN("5678");
        signaturePinDataWS.setPUK("23456789");
        hardTokenDataWS.getPinDatas().add(basicPinDataWS);
        hardTokenDataWS.getPinDatas().add(signaturePinDataWS);
        List<TokenCertificateResponseWS> responses = ejbcaraws.genTokenCertificates(tokenUser1, requests,
                hardTokenDataWS, true, false);
        assertTrue(responses.size() == 2);
        certificateProfileSession.removeCertificateProfile(intAdmin, WS_TEST_CERTIFICATE_PROFILE_NAME);
        gc.setEnableEndEntityProfileLimitations(originalProfileSetting);
        globalConfigurationSession.saveConfiguration(intAdmin, gc);
    } // createHardToken

    /**
     * Create a user a generate cert.
     */
    private X509Certificate createUserAndCert(String username, int caID) throws Exception {
        EndEntityInformation userdata = new EndEntityInformation(username, "CN=" + username, caID, null, null,
                new EndEntityType(EndEntityTypes.ENDUSER), SecConst.EMPTY_ENDENTITYPROFILE,
                CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER, SecConst.TOKEN_SOFT_P12, 0, null);
        userdata.setPassword(PASSWORD);
        endEntityManagementSession.addUser(intAdmin, userdata, true);
        File tmpfile = File.createTempFile("ejbca", "p12");
        BatchCreateTool.createAllNew(intAdmin, tmpfile.getParent());
        Collection<Certificate> userCerts = certificateStoreSession.findCertificatesByUsername(username);
        assertTrue(userCerts.size() == 1);
        return (X509Certificate) userCerts.iterator().next();
    }

}