org.ejbca.core.protocol.cmp.EndEntityCertAuthModuleTest.java Source code

Java tutorial

Introduction

Here is the source code for org.ejbca.core.protocol.cmp.EndEntityCertAuthModuleTest.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.cmp;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.KeyPair;
import java.security.Principal;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.ejb.ObjectNotFoundException;
import javax.security.auth.x500.X500Principal;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DEROutputStream;
import org.bouncycastle.asn1.cmp.CMPCertificate;
import org.bouncycastle.asn1.cmp.ErrorMsgContent;
import org.bouncycastle.asn1.cmp.PKIBody;
import org.bouncycastle.asn1.cmp.PKIMessage;
import org.bouncycastle.asn1.crmf.CertReqMessages;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.ReasonFlags;
import org.bouncycastle.jce.X509KeyUsage;
import org.cesecore.CaTestUtils;
import org.cesecore.CesecoreException;
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.CA;
import org.cesecore.certificates.ca.CADoesntExistsException;
import org.cesecore.certificates.ca.CaSessionRemote;
import org.cesecore.certificates.certificate.InternalCertificateStoreSessionRemote;
import org.cesecore.certificates.certificateprofile.CertificateProfile;
import org.cesecore.certificates.certificateprofile.CertificateProfileConstants;
import org.cesecore.certificates.certificateprofile.CertificateProfileExistsException;
import org.cesecore.certificates.certificateprofile.CertificateProfileSessionRemote;
import org.cesecore.certificates.crl.RevokedCertInfo;
import org.cesecore.certificates.endentity.EndEntityConstants;
import org.cesecore.certificates.endentity.EndEntityInformation;
import org.cesecore.certificates.endentity.EndEntityType;
import org.cesecore.certificates.endentity.EndEntityTypes;
import org.cesecore.certificates.util.AlgorithmConstants;
import org.cesecore.configuration.GlobalConfigurationSession;
import org.cesecore.configuration.GlobalConfigurationSessionRemote;
import org.cesecore.keys.util.KeyTools;
import org.cesecore.keys.util.PublicKeyWrapper;
import org.cesecore.mock.authentication.tokens.TestX509CertificateAuthenticationToken;
import org.cesecore.roles.RoleData;
import org.cesecore.roles.RoleNotFoundException;
import org.cesecore.roles.access.RoleAccessSessionRemote;
import org.cesecore.roles.management.RoleManagementSession;
import org.cesecore.roles.management.RoleManagementSessionRemote;
import org.cesecore.util.CertTools;
import org.cesecore.util.CryptoProviderTools;
import org.cesecore.util.EjbRemoteHelper;
import org.ejbca.config.CmpConfiguration;
import org.ejbca.core.EjbcaException;
import org.ejbca.core.ejb.ra.EndEntityExistsException;
import org.ejbca.core.ejb.ra.EndEntityManagementSessionRemote;
import org.ejbca.core.ejb.ra.raadmin.EndEntityProfileSessionRemote;
import org.ejbca.core.model.SecConst;
import org.ejbca.core.model.approval.WaitingForApprovalException;
import org.ejbca.core.model.authorization.AccessRulesConstants;
import org.ejbca.core.model.ra.raadmin.EndEntityProfile;
import org.ejbca.core.model.ra.raadmin.EndEntityProfileExistsException;
import org.ejbca.core.model.ra.raadmin.UserDoesntFullfillEndEntityProfile;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 * System tests for EndEntityCertificateAuthenticationModule
 * 
 * @version $Id$
 *
 */

public class EndEntityCertAuthModuleTest extends CmpTestCase {

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

    private final static String RA1_ALIAS = "EECertAuthModTestRA1ConfAlias";
    private final static String RA2_ALIAS = "EECertAuthModTestRA2ConfAlias";
    private final static String CA1 = "EECertAuthModTestRA1CA1";
    private final static String CA2 = "EECertAuthModTestRA2CA2";
    private final static String CP1 = "EECertAuthModTestRA1CP1";
    private final static String CP2 = "EECertAuthModTestRA2CP2";
    private final static String EEP1 = "EECertAuthModTestRA1EEP1";
    private final static String EEP2 = "EECertAuthModTestRA2EEP2";
    private final static String AUTH_PARAM_CA = "EECertAuthModTestAuthCA";
    private final static String RA1_ADMIN_ROLE = "EECertAuthModTestRA1AdminRole";
    private final static String RA2_ADMIN_ROLE = "ECertAuthModTestRA2AdminRole";
    private final static String RA1_ADMIN = "EECertAuthModTestRA1Admin";
    private final static String RA2_ADMIN = "EECertAuthModTestRA2Admin";

    private final CmpConfiguration cmpConfiguration;
    private final byte[] nonce;
    private final byte[] transid;
    private static CA ca1;
    private static CA ca2;
    private static CA adminca;
    private Certificate ra1admincert;
    private Certificate ra2admincert;
    private KeyPair ra1adminkeys;
    private KeyPair ra2adminkeys;

    private static final GlobalConfigurationSession globalConfigurationSession = EjbRemoteHelper.INSTANCE
            .getRemoteSession(GlobalConfigurationSessionRemote.class);
    private static final CaSessionRemote caSession = EjbRemoteHelper.INSTANCE
            .getRemoteSession(CaSessionRemote.class);
    private static final RoleManagementSession roleManagementSession = EjbRemoteHelper.INSTANCE
            .getRemoteSession(RoleManagementSessionRemote.class);
    private static final RoleAccessSessionRemote roleAccessSession = EjbRemoteHelper.INSTANCE
            .getRemoteSession(RoleAccessSessionRemote.class);
    private static final InternalCertificateStoreSessionRemote internalCertStoreSession = EjbRemoteHelper.INSTANCE
            .getRemoteSession(InternalCertificateStoreSessionRemote.class, EjbRemoteHelper.MODULE_TEST);

    public EndEntityCertAuthModuleTest() throws Exception {
        nonce = CmpMessageHelper.createSenderNonce();
        transid = CmpMessageHelper.createSenderNonce();

        int keyusage = X509KeyUsage.digitalSignature + X509KeyUsage.keyCertSign + X509KeyUsage.cRLSign;
        adminca = CaTestUtils.createTestX509CA("CN=" + AUTH_PARAM_CA, "foo123".toCharArray(), false, keyusage);
        if (!caSession.existsCa(adminca.getCAId())) {
            caSession.addCA(ADMIN, adminca);
        }

        ra1adminkeys = KeyTools.genKeys("512", AlgorithmConstants.KEYALGORITHM_RSA);
        AuthenticationToken ra1admin = createAdminToken(ra1adminkeys, RA1_ADMIN, "CN=" + RA1_ADMIN,
                adminca.getCAId(), SecConst.EMPTY_ENDENTITYPROFILE,
                CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER);
        ra1admincert = getCertFromAuthenticationToken(ra1admin);

        ra2adminkeys = KeyTools.genKeys("512", AlgorithmConstants.KEYALGORITHM_RSA);
        AuthenticationToken ra2admin = createAdminToken(ra2adminkeys, RA2_ADMIN, "CN=" + RA2_ADMIN,
                adminca.getCAId(), SecConst.EMPTY_ENDENTITYPROFILE,
                CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER);
        ra2admincert = getCertFromAuthenticationToken(ra2admin);

        cmpConfiguration = (CmpConfiguration) globalConfigurationSession
                .getCachedConfiguration(CmpConfiguration.CMP_CONFIGURATION_ID);
    }

    @BeforeClass
    public static void beforeClass() throws Exception {
        CryptoProviderTools.installBCProviderIfNotAvailable();
    }

    @Override
    @Before
    public void setUp() throws Exception {
        super.setUp();

        int keyusage = X509KeyUsage.digitalSignature + X509KeyUsage.keyCertSign + X509KeyUsage.cRLSign;
        ca1 = CaTestUtils.createTestX509CA("CN=" + CA1, null, false, keyusage);
        ca2 = CaTestUtils.createTestX509CA("CN=" + CA2, null, false, keyusage);

        // Add CA, CP and EEP for RA1
        if (!caSession.existsCa(ca1.getCAId())) {
            caSession.addCA(ADMIN, ca1);
        }
        if (certProfileSession.getCertificateProfile(CP1) == null) {
            final CertificateProfile cp = new CertificateProfile(
                    CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER);
            List<Integer> availablecas = new ArrayList<Integer>();
            availablecas.add(ca1.getCAId());
            cp.setAvailableCAs(availablecas);
            try {
                certProfileSession.addCertificateProfile(ADMIN, CP1, cp);
            } catch (CertificateProfileExistsException e) {
                e.printStackTrace();
                fail(e.getMessage());
            }
        }
        int cp1Id = certProfileSession.getCertificateProfileId(CP1);
        if (endEntityProfileSession.getEndEntityProfile(EEP1) == null) {
            final EndEntityProfile eep = new EndEntityProfile(true);
            eep.setValue(EndEntityProfile.AVAILCERTPROFILES, 0, "" + cp1Id);
            eep.setValue(EndEntityProfile.DEFAULTCERTPROFILE, 0, "" + cp1Id);
            eep.setValue(EndEntityProfile.AVAILCAS, 0, "" + ca1.getCAId());
            eep.setValue(EndEntityProfile.DEFAULTCA, 0, "" + ca1.getCAId());
            try {
                endEntityProfileSession.addEndEntityProfile(ADMIN, EEP1, eep);
            } catch (EndEntityProfileExistsException e) {
                e.printStackTrace();
                fail(e.getMessage());
            }
        }
        final int eepId = endEntityProfileSession.getEndEntityProfileId(EEP1);
        // Configure CMP alias for RA1
        cmpConfiguration.addAlias(RA1_ALIAS);
        cmpConfiguration.setRAMode(RA1_ALIAS, true);
        cmpConfiguration.setAuthenticationModule(RA1_ALIAS, CmpConfiguration.AUTHMODULE_ENDENTITY_CERTIFICATE);
        cmpConfiguration.setAuthenticationParameters(RA1_ALIAS, AUTH_PARAM_CA);
        cmpConfiguration.setRAEEProfile(RA1_ALIAS, String.valueOf(eepId));
        cmpConfiguration.setRACertProfile(RA1_ALIAS, CP1);
        cmpConfiguration.setRACAName(RA1_ALIAS, CA1);
        cmpConfiguration.setExtractUsernameComponent(RA1_ALIAS, "CN");
        globalConfigurationSession.saveConfiguration(ADMIN, cmpConfiguration);

        // Add CA, CP and EEP for RA2
        if (!caSession.existsCa(ca2.getCAId())) {
            caSession.addCA(ADMIN, ca2);
        }
        if (certProfileSession.getCertificateProfile(CP2) == null) {
            final CertificateProfile cp = new CertificateProfile(
                    CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER);
            List<Integer> availablecas = new ArrayList<Integer>();
            availablecas.add(ca2.getCAId());
            cp.setAvailableCAs(availablecas);
            try {
                certProfileSession.addCertificateProfile(ADMIN, CP2, cp);
            } catch (CertificateProfileExistsException e) {
                e.printStackTrace();
                fail(e.getMessage());
            }
        }
        final int cp2Id = certProfileSession.getCertificateProfileId(CP2);
        if (endEntityProfileSession.getEndEntityProfile(EEP2) == null) {
            final EndEntityProfile eep = new EndEntityProfile(true);
            eep.setValue(EndEntityProfile.AVAILCERTPROFILES, 0, "" + cp2Id);
            eep.setValue(EndEntityProfile.DEFAULTCERTPROFILE, 0, "" + cp2Id);
            eep.setValue(EndEntityProfile.AVAILCAS, 0, "" + ca2.getCAId());
            eep.setValue(EndEntityProfile.DEFAULTCA, 0, "" + ca2.getCAId());
            try {
                endEntityProfileSession.addEndEntityProfile(ADMIN, EEP2, eep);
            } catch (EndEntityProfileExistsException e) {
                e.printStackTrace();
                fail(e.getMessage());
            }
        }
        final int eep2Id = endEntityProfileSession.getEndEntityProfileId(EEP2);
        // Configure CMP alias for RA2
        cmpConfiguration.addAlias(RA2_ALIAS);
        cmpConfiguration.setRAMode(RA2_ALIAS, true);
        cmpConfiguration.setAuthenticationModule(RA2_ALIAS, CmpConfiguration.AUTHMODULE_ENDENTITY_CERTIFICATE);
        cmpConfiguration.setAuthenticationParameters(RA2_ALIAS, AUTH_PARAM_CA);
        cmpConfiguration.setRAEEProfile(RA2_ALIAS, String.valueOf(eep2Id));
        cmpConfiguration.setRACertProfile(RA2_ALIAS, CP2);
        cmpConfiguration.setRACAName(RA2_ALIAS, CA2);
        cmpConfiguration.setExtractUsernameComponent(RA2_ALIAS, "CN");
        globalConfigurationSession.saveConfiguration(ADMIN, cmpConfiguration);

        // Create AdminRoles for RA1 and RA2
        RoleData ra1role = roleManagementSession.create(ADMIN, RA1_ADMIN_ROLE);
        RoleData ra2role = roleManagementSession.create(ADMIN, RA2_ADMIN_ROLE);

        // Add Admins to roles RA1 and RA2
        List<AccessUserAspectData> accessUsers = new ArrayList<AccessUserAspectData>();
        accessUsers.add(new AccessUserAspectData(RA1_ADMIN_ROLE, adminca.getCAId(),
                X500PrincipalAccessMatchValue.WITH_COMMONNAME, AccessMatchType.TYPE_EQUALCASEINS, RA1_ADMIN));
        roleManagementSession.addSubjectsToRole(ADMIN, ra1role, accessUsers);

        accessUsers = new ArrayList<AccessUserAspectData>();
        accessUsers.add(new AccessUserAspectData(RA2_ADMIN_ROLE, adminca.getCAId(),
                X500PrincipalAccessMatchValue.WITH_COMMONNAME, AccessMatchType.TYPE_EQUALCASEINS, RA2_ADMIN));
        roleManagementSession.addSubjectsToRole(ADMIN, ra2role, accessUsers);

        int eep1id = endEntityProfileSession.getEndEntityProfileId(EEP1);
        // Add access rules to roles
        List<AccessRuleData> accessRules = new ArrayList<AccessRuleData>();
        accessRules.add(new AccessRuleData(RA1_ADMIN_ROLE, AccessRulesConstants.ROLE_ADMINISTRATOR,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA1_ADMIN_ROLE, AccessRulesConstants.REGULAR_VIEWCERTIFICATE,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA1_ADMIN_ROLE, StandardRules.CREATECERT.resource(),
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA1_ADMIN_ROLE, AccessRulesConstants.REGULAR_VIEWENDENTITY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA1_ADMIN_ROLE, AccessRulesConstants.REGULAR_CREATEENDENTITY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA1_ADMIN_ROLE, AccessRulesConstants.REGULAR_EDITENDENTITY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA1_ADMIN_ROLE, AccessRulesConstants.REGULAR_DELETEENDENTITY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA1_ADMIN_ROLE, AccessRulesConstants.REGULAR_REVOKEENDENTITY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA1_ADMIN_ROLE, AccessRulesConstants.REGULAR_VIEWENDENTITYHISTORY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA1_ADMIN_ROLE, StandardRules.CAACCESS.resource() + ca1.getCAId(),
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA1_ADMIN_ROLE, AccessRulesConstants.ENDENTITYPROFILEPREFIX + eep1id,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA1_ADMIN_ROLE,
                AccessRulesConstants.ENDENTITYPROFILEPREFIX + eep1id + AccessRulesConstants.VIEW_END_ENTITY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA1_ADMIN_ROLE,
                AccessRulesConstants.ENDENTITYPROFILEPREFIX + eep1id + AccessRulesConstants.EDIT_END_ENTITY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA1_ADMIN_ROLE,
                AccessRulesConstants.ENDENTITYPROFILEPREFIX + eep1id + AccessRulesConstants.CREATE_END_ENTITY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA1_ADMIN_ROLE,
                AccessRulesConstants.ENDENTITYPROFILEPREFIX + eep1id + AccessRulesConstants.DELETE_END_ENTITY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA1_ADMIN_ROLE,
                AccessRulesConstants.ENDENTITYPROFILEPREFIX + eep1id + AccessRulesConstants.REVOKE_END_ENTITY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA1_ADMIN_ROLE,
                AccessRulesConstants.ENDENTITYPROFILEPREFIX + eep1id + AccessRulesConstants.VIEW_END_ENTITY_HISTORY,
                AccessRuleState.RULE_ACCEPT, false));
        roleManagementSession.addAccessRulesToRole(ADMIN, ra1role, accessRules);

        int eep2id = endEntityProfileSession.getEndEntityProfileId(EEP2);
        accessRules = new ArrayList<AccessRuleData>();
        accessRules.add(new AccessRuleData(RA2_ADMIN_ROLE, AccessRulesConstants.ROLE_ADMINISTRATOR,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA2_ADMIN_ROLE, AccessRulesConstants.REGULAR_VIEWCERTIFICATE,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA2_ADMIN_ROLE, StandardRules.CREATECERT.resource(),
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA2_ADMIN_ROLE, AccessRulesConstants.REGULAR_VIEWENDENTITY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA2_ADMIN_ROLE, AccessRulesConstants.REGULAR_CREATEENDENTITY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA2_ADMIN_ROLE, AccessRulesConstants.REGULAR_EDITENDENTITY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA2_ADMIN_ROLE, AccessRulesConstants.REGULAR_DELETEENDENTITY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA2_ADMIN_ROLE, AccessRulesConstants.REGULAR_REVOKEENDENTITY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA2_ADMIN_ROLE, AccessRulesConstants.REGULAR_VIEWENDENTITYHISTORY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA2_ADMIN_ROLE, StandardRules.CAACCESS.resource() + ca2.getCAId(),
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA2_ADMIN_ROLE, AccessRulesConstants.ENDENTITYPROFILEPREFIX + eep2id,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA2_ADMIN_ROLE,
                AccessRulesConstants.ENDENTITYPROFILEPREFIX + eep2id + AccessRulesConstants.VIEW_END_ENTITY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA2_ADMIN_ROLE,
                AccessRulesConstants.ENDENTITYPROFILEPREFIX + eep2id + AccessRulesConstants.EDIT_END_ENTITY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA2_ADMIN_ROLE,
                AccessRulesConstants.ENDENTITYPROFILEPREFIX + eep2id + AccessRulesConstants.CREATE_END_ENTITY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA2_ADMIN_ROLE,
                AccessRulesConstants.ENDENTITYPROFILEPREFIX + eep2id + AccessRulesConstants.DELETE_END_ENTITY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA2_ADMIN_ROLE,
                AccessRulesConstants.ENDENTITYPROFILEPREFIX + eep2id + AccessRulesConstants.REVOKE_END_ENTITY,
                AccessRuleState.RULE_ACCEPT, false));
        accessRules.add(new AccessRuleData(RA2_ADMIN_ROLE,
                AccessRulesConstants.ENDENTITYPROFILEPREFIX + eep2id + AccessRulesConstants.VIEW_END_ENTITY_HISTORY,
                AccessRuleState.RULE_ACCEPT, false));
        roleManagementSession.addAccessRulesToRole(ADMIN, ra2role, accessRules);
    }

    @After
    public void restore() throws Exception {

        CmpConfiguration cmpconf = (CmpConfiguration) globalConfigurationSession
                .getCachedConfiguration(CmpConfiguration.CMP_CONFIGURATION_ID);
        cmpconf.removeAlias(RA1_ALIAS);
        cmpconf.removeAlias(RA2_ALIAS);
        globalConfigurationSession.saveConfiguration(ADMIN, cmpconf);

        roleManagementSession.remove(ADMIN, roleAccessSession.findRole(RA1_ADMIN_ROLE));
        log.debug("Removed role: " + RA1_ADMIN_ROLE);
        roleManagementSession.remove(ADMIN, roleAccessSession.findRole(RA2_ADMIN_ROLE));
        log.debug("Removed role: " + RA2_ADMIN_ROLE);

        EndEntityManagementSessionRemote eeManagementSession = EjbRemoteHelper.INSTANCE
                .getRemoteSession(EndEntityManagementSessionRemote.class);
        if (eeManagementSession.existsUser(RA1_ADMIN)) {
            eeManagementSession.revokeAndDeleteUser(ADMIN, RA1_ADMIN, ReasonFlags.unused);
            internalCertStoreSession.removeCertificate(CertTools.getFingerprintAsString(ra1admincert));
            log.debug("Removed and revoked EndEntity: " + RA1_ADMIN);
        }
        if (eeManagementSession.existsUser(RA2_ADMIN)) {
            eeManagementSession.revokeAndDeleteUser(ADMIN, RA2_ADMIN, ReasonFlags.unused);
            internalCertStoreSession.removeCertificate(CertTools.getFingerprintAsString(ra2admincert));
            log.debug("Removed and revoked EndEntity: " + RA2_ADMIN);
        }

        EndEntityProfileSessionRemote eeProfileSession = EjbRemoteHelper.INSTANCE
                .getRemoteSession(EndEntityProfileSessionRemote.class);
        if (eeProfileSession.getEndEntityProfile(EEP1) != null) {
            eeProfileSession.removeEndEntityProfile(ADMIN, EEP1);
            log.debug("Removed EndEntityProfile: " + EEP1);
        }
        if (eeProfileSession.getEndEntityProfile(EEP2) != null) {
            eeProfileSession.removeEndEntityProfile(ADMIN, EEP2);
            log.debug("Removed EndEntityProfile: " + EEP2);
        }

        CertificateProfileSessionRemote certProfSession = EjbRemoteHelper.INSTANCE
                .getRemoteSession(CertificateProfileSessionRemote.class);
        if (certProfileSession.getCertificateProfile(CP1) != null) {
            certProfSession.removeCertificateProfile(ADMIN, CP1);
            log.debug("Removed CertificateProfile: " + CP1);
        }
        if (certProfileSession.getCertificateProfile(CP2) != null) {
            certProfSession.removeCertificateProfile(ADMIN, CP2);
            log.debug("Removed CertificateProfile: " + CP2);
        }

        if (caSession.existsCa(AUTH_PARAM_CA)) {
            caSession.removeCA(ADMIN, adminca.getCAId());
            log.debug("Removed CA: " + AUTH_PARAM_CA);
        }
        if (caSession.existsCa(CA1)) {
            caSession.removeCA(ADMIN, ca1.getCAId());
            log.debug("Removed CA: " + CA1);
        }
        if (caSession.existsCa(CA2)) {
            caSession.removeCA(ADMIN, ca2.getCAId());
            log.debug("Removed CA: " + CA2);
        }

    }

    /**
     * 1- Sends a CRMF request signed by RA1Admin to RA1. Expected: Success
     * 2- Sends a CRMF request signed by RA2Admin to RA2. Expected: Success
     * 
     * @throws Exception
     */
    @Test
    public void test01RA1SuccessfullCRMF() throws Exception {

        // Send CRMF message signed by RA1Admin to RA1
        String testUsername = "ra1testuser";
        String fingerprintCert = null;
        try {

            final X500Name testUserDN = new X500Name("CN=" + testUsername);
            KeyPair keys = KeyTools.genKeys("512", AlgorithmConstants.KEYALGORITHM_RSA);
            AlgorithmIdentifier pAlg = new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption);
            PKIMessage msg = genCertReq(ca1.getSubjectDN(), testUserDN, keys, ca1.getCACertificate(), nonce,
                    transid, false, null, null, null, null, pAlg, new DEROctetString(nonce));
            assertNotNull("Generating CrmfRequest failed.", msg);

            CMPCertificate[] extraCert = getCMPCert(ra1admincert);
            msg = CmpMessageHelper.buildCertBasedPKIProtection(msg, extraCert, ra1adminkeys.getPrivate(),
                    pAlg.getAlgorithm().getId(), "BC");
            assertNotNull("Signing CMP message failed", msg);
            //******************************************''''''
            final Signature sig = Signature.getInstance(msg.getHeader().getProtectionAlg().getAlgorithm().getId(),
                    "BC");
            sig.initVerify(ra1admincert.getPublicKey());
            sig.update(CmpMessageHelper.getProtectedBytes(msg));
            boolean verified = sig.verify(msg.getProtection().getBytes());
            assertTrue("Signing the message failed.", verified);
            //***************************************************

            final ByteArrayOutputStream bao = new ByteArrayOutputStream();
            final DEROutputStream out = new DEROutputStream(bao);
            out.writeObject(msg);
            final byte[] ba = bao.toByteArray();
            // Send request and receive response
            final byte[] resp = sendCmpHttp(ba, 200, RA1_ALIAS);
            checkCmpResponseGeneral(resp, ca1.getSubjectDN(), testUserDN, ca1.getCACertificate(),
                    msg.getHeader().getSenderNonce().getOctets(), msg.getHeader().getTransactionID().getOctets(),
                    true, null, PKCSObjectIdentifiers.sha1WithRSAEncryption.getId());
            CertReqMessages ir = (CertReqMessages) msg.getBody().getContent();
            Certificate cert = checkCmpCertRepMessage(testUserDN, (X509Certificate) ca1.getCACertificate(), resp,
                    ir.toCertReqMsgArray()[0].getCertReq().getCertReqId().getValue().intValue());
            assertNotNull("CrmfRequest did not return a certificate", cert);
            fingerprintCert = CertTools.getFingerprintAsString(cert);
        } finally {
            internalCertStoreSession.removeCertificate(fingerprintCert);
            endEntityManagementSession.revokeAndDeleteUser(ADMIN, testUsername, ReasonFlags.unused);
        }

        // Send CRMF message signed by RA2Admin to RA2
        testUsername = "ra2testuser";
        try {

            final X500Name testUserDN = new X500Name("CN=" + testUsername);
            KeyPair keys = KeyTools.genKeys("512", AlgorithmConstants.KEYALGORITHM_RSA);
            AlgorithmIdentifier pAlg = new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption);
            PKIMessage msg = genCertReq(ca2.getSubjectDN(), testUserDN, keys, ca2.getCACertificate(), nonce,
                    transid, false, null, null, null, null, pAlg, new DEROctetString(nonce));
            assertNotNull("Generating CrmfRequest failed.", msg);

            CMPCertificate[] extraCert = getCMPCert(ra2admincert);
            msg = CmpMessageHelper.buildCertBasedPKIProtection(msg, extraCert, ra2adminkeys.getPrivate(),
                    pAlg.getAlgorithm().getId(), "BC");
            assertNotNull("Signing CMP message failed.", msg);
            //******************************************''''''
            final Signature sig = Signature.getInstance(msg.getHeader().getProtectionAlg().getAlgorithm().getId(),
                    "BC");
            sig.initVerify(ra2admincert.getPublicKey());
            sig.update(CmpMessageHelper.getProtectedBytes(msg));
            boolean verified = sig.verify(msg.getProtection().getBytes());
            assertTrue("Signing the message failed.", verified);
            //***************************************************

            final ByteArrayOutputStream bao = new ByteArrayOutputStream();
            final DEROutputStream out = new DEROutputStream(bao);
            out.writeObject(msg);
            final byte[] ba = bao.toByteArray();
            // Send request and receive response
            final byte[] resp = sendCmpHttp(ba, 200, RA2_ALIAS);
            checkCmpResponseGeneral(resp, ca2.getSubjectDN(), testUserDN, ca2.getCACertificate(),
                    msg.getHeader().getSenderNonce().getOctets(), msg.getHeader().getTransactionID().getOctets(),
                    true, null, PKCSObjectIdentifiers.sha1WithRSAEncryption.getId());
            CertReqMessages ir = (CertReqMessages) msg.getBody().getContent();
            Certificate cert = checkCmpCertRepMessage(testUserDN, (X509Certificate) ca2.getCACertificate(), resp,
                    ir.toCertReqMsgArray()[0].getCertReq().getCertReqId().getValue().intValue());
            assertNotNull("CrmfRequest did not return a certificate", cert);
            fingerprintCert = CertTools.getFingerprintAsString(cert);
        } finally {
            internalCertStoreSession.removeCertificate(fingerprintCert);
            endEntityManagementSession.revokeAndDeleteUser(ADMIN, testUsername, ReasonFlags.unused);
        }

    }

    /**
     * 1- Sends a CRMF request signed by RA2Admin to RA1. Expected: Fail
     * 2- Sends a CRMF request signed by RA1Admin to RA2. Expected: Fail
     * 
     * @throws Exception
     */
    @Test
    public void test01RA1FailedCRMF() throws Exception {

        // Send CRMF message signed by RA2Admin to RA1
        String testUsername = "ra1testuser";
        X500Name testUserDN = new X500Name("CN=" + testUsername);
        KeyPair keys = KeyTools.genKeys("512", AlgorithmConstants.KEYALGORITHM_RSA);
        AlgorithmIdentifier pAlg = new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption);
        PKIMessage msg = genCertReq(ca1.getSubjectDN(), testUserDN, keys, ca1.getCACertificate(), nonce, transid,
                false, null, null, null, null, pAlg, new DEROctetString(nonce));
        assertNotNull("Generating CrmfRequest failed.", msg);

        CMPCertificate[] extraCert = getCMPCert(ra2admincert);
        msg = CmpMessageHelper.buildCertBasedPKIProtection(msg, extraCert, ra2adminkeys.getPrivate(),
                pAlg.getAlgorithm().getId(), "BC");
        assertNotNull("Signing CMP message failed.", msg);
        //******************************************''''''
        Signature sig = Signature.getInstance(msg.getHeader().getProtectionAlg().getAlgorithm().getId(), "BC");
        sig.initVerify(ra2admincert.getPublicKey());
        sig.update(CmpMessageHelper.getProtectedBytes(msg));
        boolean verified = sig.verify(msg.getProtection().getBytes());
        assertTrue("Signing the message failed.", verified);
        //***************************************************

        ByteArrayOutputStream bao = new ByteArrayOutputStream();
        DEROutputStream out = new DEROutputStream(bao);
        out.writeObject(msg);
        byte[] ba = bao.toByteArray();
        // Send request and receive response
        byte[] resp = sendCmpHttp(ba, 200, RA1_ALIAS);
        checkCmpResponseGeneral(resp, ca1.getSubjectDN(), testUserDN, ca1.getCACertificate(),
                msg.getHeader().getSenderNonce().getOctets(), msg.getHeader().getTransactionID().getOctets(), false,
                null, null);
        ASN1InputStream asn1InputStream = new ASN1InputStream(new ByteArrayInputStream(resp));
        PKIMessage respObject = null;
        try {
            respObject = PKIMessage.getInstance(asn1InputStream.readObject());
        } finally {
            asn1InputStream.close();
        }
        assertNotNull("Reading CMP response failed.", respObject);
        PKIBody body = respObject.getBody();
        assertEquals(PKIBody.TYPE_ERROR, body.getType());
        ErrorMsgContent err = (ErrorMsgContent) body.getContent();
        String errMsg = err.getPKIStatusInfo().getStatusString().getStringAt(0).getString();
        String expectedErrMsg = "'CN=" + RA2_ADMIN + "' is not an authorized administrator.";
        assertEquals(expectedErrMsg, errMsg);

        // Send CRMF message signed by RA1Admin to RA2
        testUsername = "ra2testuser";
        testUserDN = new X500Name("CN=" + testUsername);
        keys = KeyTools.genKeys("512", AlgorithmConstants.KEYALGORITHM_RSA);
        pAlg = new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption);
        msg = genCertReq(ca2.getSubjectDN(), testUserDN, keys, ca2.getCACertificate(), nonce, transid, false, null,
                null, null, null, pAlg, new DEROctetString(nonce));
        assertNotNull("Generating CrmfRequest failed.", msg);

        extraCert = getCMPCert(ra1admincert);
        msg = CmpMessageHelper.buildCertBasedPKIProtection(msg, extraCert, ra1adminkeys.getPrivate(),
                pAlg.getAlgorithm().getId(), "BC");
        assertNotNull("Signing CMP message failed.", msg);
        //******************************************''''''
        sig = Signature.getInstance(msg.getHeader().getProtectionAlg().getAlgorithm().getId(), "BC");
        sig.initVerify(ra1admincert.getPublicKey());
        sig.update(CmpMessageHelper.getProtectedBytes(msg));
        verified = sig.verify(msg.getProtection().getBytes());
        assertTrue("Signing the message failed.", verified);
        //***************************************************

        bao = new ByteArrayOutputStream();
        out = new DEROutputStream(bao);
        out.writeObject(msg);
        ba = bao.toByteArray();
        // Send request and receive response
        resp = sendCmpHttp(ba, 200, RA2_ALIAS);
        checkCmpResponseGeneral(resp, ca2.getSubjectDN(), testUserDN, ca2.getCACertificate(),
                msg.getHeader().getSenderNonce().getOctets(), msg.getHeader().getTransactionID().getOctets(), false,
                null, null);
        asn1InputStream = new ASN1InputStream(new ByteArrayInputStream(resp));
        try {
            respObject = PKIMessage.getInstance(asn1InputStream.readObject());
        } finally {
            asn1InputStream.close();
        }
        assertNotNull("Reading CMP response failed.", respObject);
        body = respObject.getBody();
        assertEquals(PKIBody.TYPE_ERROR, body.getType());
        err = (ErrorMsgContent) body.getContent();
        errMsg = err.getPKIStatusInfo().getStatusString().getStringAt(0).getString();
        expectedErrMsg = "'CN=" + RA1_ADMIN + "' is not an authorized administrator.";
        assertEquals(expectedErrMsg, errMsg);

    }

    /**
     * 1- Sends a revocation request signed by RA2Admin to RA1. Expected: Fail
     * 2- Sends a revocation request signed by RA1Admin to RA1. Expected: Success
     * 
     * @throws Exception
     */
    @Test
    public void test03RevocationRequest() throws Exception {

        String username = "ra1testuser";
        String fingerprintCert = null;
        try {

            // Issue a cert by CA1
            String userDN = "CN=" + username;
            createUser(username, userDN, "foo123", true, ca1.getCAId(),
                    endEntityProfileSession.getEndEntityProfileId(EEP1),
                    certProfileSession.getCertificateProfileId(CP1));
            KeyPair userkeys = KeyTools.genKeys("1024", "RSA");
            Certificate cert = signSession.createCertificate(ADMIN, username, "foo123",
                    new PublicKeyWrapper(userkeys.getPublic()));
            assertNotNull("No certificate to revoke.", cert);
            fingerprintCert = CertTools.getFingerprintAsString(cert);

            AlgorithmIdentifier pAlg = new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption);
            PKIMessage msg = genRevReq(ca1.getSubjectDN(), new X500Name(userDN), CertTools.getSerialNumber(cert),
                    ca1.getCACertificate(), nonce, transid, false, pAlg, null);
            assertNotNull("Generating revocation request failed.", msg);

            // Sign the revocation request with RA2 Admin
            CMPCertificate[] extraCert = getCMPCert(ra2admincert);
            PKIMessage protectedMsg = CmpMessageHelper.buildCertBasedPKIProtection(msg, extraCert,
                    ra2adminkeys.getPrivate(), pAlg.getAlgorithm().getId(), "BC");
            assertNotNull("Signing CMP message failed.", protectedMsg);

            // Send the CMP request to RA1. Expected: Fail
            ByteArrayOutputStream bao = new ByteArrayOutputStream();
            DEROutputStream out = new DEROutputStream(bao);
            out.writeObject(protectedMsg);
            byte[] ba = bao.toByteArray();
            byte[] resp = sendCmpHttp(ba, 200, RA1_ALIAS);
            checkCmpResponseGeneral(resp, ca1.getSubjectDN(), new X500Name(userDN), ca1.getCACertificate(),
                    msg.getHeader().getSenderNonce().getOctets(), msg.getHeader().getTransactionID().getOctets(),
                    false, null, null);
            ASN1InputStream asn1InputStream = new ASN1InputStream(new ByteArrayInputStream(resp));
            final PKIMessage respObject;
            try {
                respObject = PKIMessage.getInstance(asn1InputStream.readObject());
            } finally {
                asn1InputStream.close();
            }
            assertNotNull("Reading CMP response failed.", respObject);
            PKIBody body = respObject.getBody();
            assertEquals(PKIBody.TYPE_ERROR, body.getType());
            ErrorMsgContent err = (ErrorMsgContent) body.getContent();
            String errMsg = err.getPKIStatusInfo().getStatusString().getStringAt(0).getString();
            String expectedErrMsg = "'CN=" + RA2_ADMIN + "' is not an authorized administrator.";
            assertEquals(expectedErrMsg, errMsg);

            // Sign the revocation request with RA1 Admin
            extraCert = getCMPCert(ra1admincert);
            protectedMsg = CmpMessageHelper.buildCertBasedPKIProtection(msg, extraCert, ra1adminkeys.getPrivate(),
                    pAlg.getAlgorithm().getId(), "BC");
            assertNotNull("Signing CMP message failed.", protectedMsg);

            // Send the CMP request to RA1. Expected: Success
            bao = new ByteArrayOutputStream();
            out = new DEROutputStream(bao);
            out.writeObject(protectedMsg);
            ba = bao.toByteArray();
            resp = sendCmpHttp(ba, 200, RA1_ALIAS);
            checkCmpResponseGeneral(resp, ca1.getSubjectDN(), new X500Name(userDN), ca1.getCACertificate(),
                    msg.getHeader().getSenderNonce().getOctets(), msg.getHeader().getTransactionID().getOctets(),
                    true, null, PKCSObjectIdentifiers.sha1WithRSAEncryption.getId());
            int revStatus = checkRevokeStatus(ca1.getSubjectDN(), CertTools.getSerialNumber(cert));
            assertNotEquals("Revocation request failed to revoke the certificate", RevokedCertInfo.NOT_REVOKED,
                    revStatus);
        } finally {
            internalCertStoreSession.removeCertificate(fingerprintCert);
            endEntityManagementSession.revokeAndDeleteUser(ADMIN, username, ReasonFlags.unused);
        }
    }

    /**
     * Sends a revocation request signed by RA2Admin to revoke a certificate issued by a CA RA2Admin is not authorized to. Expected: Fail
     * 
     * @throws Exception
     */
    @Test
    public void test04RevocationRequest() throws Exception {

        String username = "ra1testuser";
        String fingerprintCert = null;
        try {

            // Issue a cert by CA1
            String userDN = "CN=" + username;
            createUser(username, userDN, "foo123", true, ca1.getCAId(),
                    endEntityProfileSession.getEndEntityProfileId(EEP1),
                    certProfileSession.getCertificateProfileId(CP1));
            KeyPair userkeys = KeyTools.genKeys("1024", "RSA");
            Certificate cert = signSession.createCertificate(ADMIN, username, "foo123",
                    new PublicKeyWrapper(userkeys.getPublic()));
            assertNotNull("No certificate to revoke.", cert);
            fingerprintCert = CertTools.getFingerprintAsString(cert);

            AlgorithmIdentifier pAlg = new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption);
            PKIMessage msg = genRevReq(ca1.getSubjectDN(), new X500Name(userDN), CertTools.getSerialNumber(cert),
                    ca1.getCACertificate(), nonce, transid, false, pAlg, null);
            assertNotNull("Generating revocation request failed.", msg);

            // Sign the revocation request with RA2 Admin
            CMPCertificate[] extraCert = getCMPCert(ra2admincert);
            PKIMessage protectedMsg = CmpMessageHelper.buildCertBasedPKIProtection(msg, extraCert,
                    ra2adminkeys.getPrivate(), pAlg.getAlgorithm().getId(), "BC");
            assertNotNull("Signing CMP message failed", protectedMsg);

            // Send the CMP request to RA2. Expected: Fail
            ByteArrayOutputStream bao = new ByteArrayOutputStream();
            DEROutputStream out = new DEROutputStream(bao);
            out.writeObject(protectedMsg);
            byte[] ba = bao.toByteArray();
            byte[] resp = sendCmpHttp(ba, 200, RA2_ALIAS);
            checkCmpResponseGeneral(resp, ca1.getSubjectDN(), new X500Name(userDN), ca1.getCACertificate(),
                    msg.getHeader().getSenderNonce().getOctets(), msg.getHeader().getTransactionID().getOctets(),
                    false, null, null);
            ASN1InputStream asn1InputStream = new ASN1InputStream(new ByteArrayInputStream(resp));
            final PKIMessage respObject;
            try {
                respObject = PKIMessage.getInstance(asn1InputStream.readObject());
            } finally {
                asn1InputStream.close();
            }
            assertNotNull("Reading CMP response failed.", respObject);
            PKIBody body = respObject.getBody();
            assertEquals(PKIBody.TYPE_ERROR, body.getType());
            ErrorMsgContent err = (ErrorMsgContent) body.getContent();
            String errMsg = err.getPKIStatusInfo().getStatusString().getStringAt(0).getString();
            String expectedErrMsg = "'CN=" + RA2_ADMIN + "' is not an authorized administrator.";
            assertEquals(expectedErrMsg, errMsg);

        } finally {
            internalCertStoreSession.removeCertificate(fingerprintCert);
            endEntityManagementSession.revokeAndDeleteUser(ADMIN, username, ReasonFlags.unused);
        }
    }

    private static CMPCertificate[] getCMPCert(Certificate cert) throws CertificateEncodingException, IOException {
        ASN1InputStream ins = new ASN1InputStream(cert.getEncoded());
        ASN1Primitive pcert = ins.readObject();
        ins.close();
        org.bouncycastle.asn1.x509.Certificate c = org.bouncycastle.asn1.x509.Certificate
                .getInstance(pcert.toASN1Primitive());
        CMPCertificate[] res = { new CMPCertificate(c) };
        return res;
    }

    private EndEntityInformation createUser(String username, String subjectDN, String password,
            boolean clearpassword, int _caid, int eepid, int cpid) throws AuthorizationDeniedException,
            UserDoesntFullfillEndEntityProfile, WaitingForApprovalException, EjbcaException, Exception {

        EndEntityInformation user = new EndEntityInformation(username, subjectDN, _caid, null,
                username + "@primekey.se", new EndEntityType(EndEntityTypes.ENDUSER), eepid, cpid,
                SecConst.TOKEN_SOFT_PEM, 0, null);
        user.setPassword(password);
        try {
            endEntityManagementSession.addUser(ADMIN, user, clearpassword);
            log.debug("created user: " + username);
        } catch (EndEntityExistsException e) {
            log.debug("User " + username + " already exists. Setting the user status to NEW");
            endEntityManagementSession.changeUser(ADMIN, user, clearpassword);
            endEntityManagementSession.setUserStatus(ADMIN, username, EndEntityConstants.STATUS_NEW);
            log.debug("Reset status to NEW");
        }

        return user;

    }

    private static X509Certificate getCertFromAuthenticationToken(AuthenticationToken authToken) {
        X509Certificate certificate = null;
        Set<?> inputcreds = authToken.getCredentials();
        if (inputcreds != null) {
            for (Object object : inputcreds) {
                if (object instanceof X509Certificate) {
                    certificate = (X509Certificate) object;
                }
            }
        }
        return certificate;
    }

    private AuthenticationToken createAdminToken(KeyPair keys, String name, String dn, int _caid, int eepid,
            int cpid) throws RoleNotFoundException, AuthorizationDeniedException {
        Set<Principal> principals = new HashSet<Principal>();
        X500Principal p = new X500Principal(dn);
        principals.add(p);
        AuthenticationSubject subject = new AuthenticationSubject(principals, null);
        AuthenticationToken token = createTokenWithCert(name, subject, keys, _caid, eepid, cpid);
        assertNotNull("Failed to create authentication token.", token);
        X509Certificate cert = (X509Certificate) token.getCredentials().iterator().next();
        assertNotNull("Failed to retrieve authentication token certificate.", cert);
        return token;
    }

    private AuthenticationToken createTokenWithCert(String adminName, AuthenticationSubject subject, KeyPair keys,
            int _caid, int eepid, int cpid) {

        // A small check if we have added a "fail" credential to the subject.
        // If we have we will return null, so we can test authentication failure.
        Set<?> usercredentials = subject.getCredentials();
        if ((usercredentials != null) && (usercredentials.size() > 0)) {
            Object o = usercredentials.iterator().next();
            if (o instanceof String) {
                String str = (String) o;
                if (StringUtils.equals("fail", str)) {
                    return null;
                }
            }
        }

        X509Certificate certificate = null;
        // If there was no certificate input, create a self signed
        String dn = "CN=" + adminName;
        // If we have created a subject with an X500Principal we will use this DN to create the dummy certificate.
        {
            Set<Principal> principals = subject.getPrincipals();
            if ((principals != null) && (principals.size() > 0)) {
                Principal p = principals.iterator().next();
                if (p instanceof X500Principal) {
                    X500Principal xp = (X500Principal) p;
                    dn = xp.getName();
                }
            }
        }

        try {
            createUser(adminName, dn, "foo123", true, _caid, eepid, cpid);
        } catch (AuthorizationDeniedException e1) {
            throw new IllegalStateException(e1.getLocalizedMessage(), e1);
        } catch (UserDoesntFullfillEndEntityProfile e1) {
            throw new IllegalStateException(e1.getLocalizedMessage(), e1);
        } catch (WaitingForApprovalException e1) {
            throw new IllegalStateException(e1.getLocalizedMessage(), e1);
        } catch (EjbcaException e1) {
            throw new IllegalStateException(e1.getLocalizedMessage(), e1);
        } catch (Exception e1) {
            throw new IllegalStateException(e1.getLocalizedMessage(), e1);
        }

        try {
            certificate = (X509Certificate) signSession.createCertificate(ADMIN, adminName, "foo123",
                    new PublicKeyWrapper(keys.getPublic()));
        } catch (ObjectNotFoundException e) {
            throw new IllegalStateException(e.getLocalizedMessage(), e);
        } catch (CADoesntExistsException e) {
            throw new IllegalStateException(e.getLocalizedMessage(), e);
        } catch (EjbcaException e) {
            throw new IllegalStateException(e.getLocalizedMessage(), e);
        } catch (AuthorizationDeniedException e) {
            throw new IllegalStateException(e.getLocalizedMessage(), e);
        } catch (CesecoreException e) {
            throw new IllegalStateException(e.getLocalizedMessage(), e);
        }
        assertNotNull("Failed to create a test user certificate", certificate);
        // We cannot use the X509CertificateAuthenticationToken here, since it can only be used internally in a JVM.
        AuthenticationToken result = new TestX509CertificateAuthenticationToken(certificate);
        assertNotNull("Failed to create authentication token.", result);
        return result;
    }

    @Override
    public String getRoleName() {
        return this.getClass().getSimpleName();
    }

}