Package org.cesecore.core.ejb.ca.store

Source Code of org.cesecore.core.ejb.ca.store.CertificateProfileSessionBean

/*************************************************************************
*                                                                       *
*  EJBCA: 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.cesecore.core.ejb.ca.store;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.Map.Entry;

import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.log4j.Logger;
import org.cesecore.core.ejb.log.LogSessionLocal;
import org.ejbca.core.ejb.JndiHelper;
import org.ejbca.core.ejb.authorization.AuthorizationSessionLocal;
import org.ejbca.core.ejb.ca.caadmin.CertificateProfileData;
import org.ejbca.core.ejb.ca.store.CertificateProfileCache;
import org.ejbca.core.model.InternalResources;
import org.ejbca.core.model.SecConst;
import org.ejbca.core.model.ca.certificateprofiles.CACertificateProfile;
import org.ejbca.core.model.ca.certificateprofiles.CertificateProfile;
import org.ejbca.core.model.ca.certificateprofiles.CertificateProfileExistsException;
import org.ejbca.core.model.ca.certificateprofiles.EndUserCertificateProfile;
import org.ejbca.core.model.ca.certificateprofiles.HardTokenAuthCertificateProfile;
import org.ejbca.core.model.ca.certificateprofiles.HardTokenAuthEncCertificateProfile;
import org.ejbca.core.model.ca.certificateprofiles.HardTokenEncCertificateProfile;
import org.ejbca.core.model.ca.certificateprofiles.HardTokenSignCertificateProfile;
import org.ejbca.core.model.ca.certificateprofiles.OCSPSignerCertificateProfile;
import org.ejbca.core.model.ca.certificateprofiles.RootCACertificateProfile;
import org.ejbca.core.model.ca.certificateprofiles.ServerCertificateProfile;
import org.ejbca.core.model.log.Admin;
import org.ejbca.core.model.log.LogConstants;

/** Bean managing certificate profiles.
*
* @version $Id: CertificateProfileSessionBean.java 11661 2011-04-01 11:59:59Z jeklund $
*/
@Stateless(mappedName = JndiHelper.APP_JNDI_PREFIX + "CertificateProfileSessionRemote")
@TransactionAttribute(TransactionAttributeType.SUPPORTS)
public class CertificateProfileSessionBean implements CertificateProfileSessionLocal, CertificateProfileSessionRemote {

    private static final Logger LOG = Logger.getLogger(CertificateProfileSessionBean.class);

    /** Internal localization of logs and errors */
    private static final InternalResources INTRES = InternalResources.getInstance();

    /** Cache of certificate profiles and id-name mappings */
    private static final CertificateProfileCache profileCache = new CertificateProfileCache();

    @PersistenceContext(unitName = "ejbca")
    private EntityManager entityManager;

    @EJB
    private AuthorizationSessionLocal authSession;
    @EJB
    private LogSessionLocal logSession;
   
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    @Override
    public void addCertificateProfile(final Admin admin, final int profileid, final String profilename, final CertificateProfile profile)
            throws CertificateProfileExistsException {
        if (isCertificateProfileNameFixed(profilename)) {
            final String msg = INTRES.getLocalizedMessage("store.errorcertprofilefixed", profilename);
            logSession.log(admin, admin.getCaId(), LogConstants.MODULE_CA, new Date(), null, null, LogConstants.EVENT_ERROR_CERTPROFILE,
                    msg);
            throw new CertificateProfileExistsException(msg);
        }

        if (isFreeCertificateProfileId(profileid)) {
            if (CertificateProfileData.findByProfileName(entityManager, profilename) == null) {
                try {
                    entityManager.persist(new CertificateProfileData(Integer.valueOf(profileid), profilename, profile));
                    flushProfileCache();
                    final String msg = INTRES.getLocalizedMessage("store.addedcertprofile", profilename);
                    logSession.log(admin, admin.getCaId(), LogConstants.MODULE_CA, new Date(), null, null,
                            LogConstants.EVENT_INFO_CERTPROFILE, msg);
                } catch (Exception e) {
                    final String msg = INTRES.getLocalizedMessage("store.errorcreatecertprofile", profilename);
                    logSession.log(admin, admin.getCaId(), LogConstants.MODULE_CA, new Date(), null, null,
                            LogConstants.EVENT_ERROR_CERTPROFILE, msg);
                }
            } else {
              final String msg = INTRES.getLocalizedMessage("store.errorcertprofileexists", profilename);
                throw new CertificateProfileExistsException(msg);
            }
        }
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    @Override
    public void addCertificateProfile(final Admin admin, final String profilename, final CertificateProfile profile)
            throws CertificateProfileExistsException {
        addCertificateProfile(admin, findFreeCertificateProfileId(), profilename, profile);
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    @Override
    public void changeCertificateProfile(final Admin admin, final String profilename, final CertificateProfile profile) {
        internalChangeCertificateProfileNoFlushCache(admin, profilename, profile);
        flushProfileCache();
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    @Override
    public void internalChangeCertificateProfileNoFlushCache(final Admin admin, final String profilename, final CertificateProfile profile) {
        final CertificateProfileData pdl = CertificateProfileData.findByProfileName(entityManager, profilename);
        if (pdl == null) {
            final String msg = INTRES.getLocalizedMessage("store.erroreditprofile", profilename);             
            logSession.log(admin, admin.getCaId(), LogConstants.MODULE_CA, new Date(), null, null, LogConstants.EVENT_ERROR_CERTPROFILE, msg);
        } else {
          pdl.setCertificateProfile(profile);
          final String msg = INTRES.getLocalizedMessage("store.editedprofile", profilename);                
          logSession.log(admin, admin.getCaId(), LogConstants.MODULE_CA, new Date(), null, null, LogConstants.EVENT_INFO_CERTPROFILE, msg);
        }
    }

    @Override
    public void flushProfileCache() {
        if (LOG.isTraceEnabled()) {
            LOG.trace(">flushProfileCache");
        }
        profileCache.updateProfileCache(entityManager, true);
        if (LOG.isDebugEnabled()) {
            LOG.debug("Flushed profile cache.");
        }
    }

    @Override
    public Collection<Integer> getAuthorizedCertificateProfileIds(final Admin admin, final int certprofiletype, final Collection<Integer> authorizedCaIds) {
        final ArrayList<Integer> returnval = new ArrayList<Integer>();
        final HashSet<Integer> authorizedcaids = new HashSet<Integer>(authorizedCaIds);

        // Add fixed certificate profiles.
        if (certprofiletype == 0 || certprofiletype == SecConst.CERTTYPE_ENDENTITY || certprofiletype == SecConst.CERTTYPE_HARDTOKEN){
            returnval.add(Integer.valueOf(SecConst.CERTPROFILE_FIXED_ENDUSER));
            returnval.add(Integer.valueOf(SecConst.CERTPROFILE_FIXED_OCSPSIGNER));
            returnval.add(Integer.valueOf(SecConst.CERTPROFILE_FIXED_SERVER));
        }
        if (certprofiletype == 0 || certprofiletype == SecConst.CERTTYPE_SUBCA) {
            returnval.add(Integer.valueOf(SecConst.CERTPROFILE_FIXED_SUBCA));
        }
        if (certprofiletype == 0 || certprofiletype == SecConst.CERTTYPE_ROOTCA) {
            returnval.add(Integer.valueOf(SecConst.CERTPROFILE_FIXED_ROOTCA));
        }
        if (certprofiletype == 0 || certprofiletype == SecConst.CERTTYPE_HARDTOKEN) {
            returnval.add(Integer.valueOf(SecConst.CERTPROFILE_FIXED_HARDTOKENAUTH));
            returnval.add(Integer.valueOf(SecConst.CERTPROFILE_FIXED_HARDTOKENAUTHENC));
            returnval.add(Integer.valueOf(SecConst.CERTPROFILE_FIXED_HARDTOKENENC));
            returnval.add(Integer.valueOf(SecConst.CERTPROFILE_FIXED_HARDTOKENSIGN));
        }
        for (final Entry<Integer,CertificateProfile> cpEntry : profileCache.getProfileCache(entityManager).entrySet()) {
          final CertificateProfile profile = cpEntry.getValue();
          // Check if all profiles available CAs exists in authorizedcaids.
          if (certprofiletype == 0 || certprofiletype == profile.getType() || (profile.getType() == SecConst.CERTTYPE_ENDENTITY &&
                  certprofiletype == SecConst.CERTTYPE_HARDTOKEN)) {
            boolean allexists = true;
            for (final Integer nextcaid : profile.getAvailableCAs()) {
              if (nextcaid.intValue() == CertificateProfile.ANYCA) {
                allexists = true;
                break;
              }
              if (!authorizedcaids.contains(nextcaid)) {
                allexists = false;
                break;
              }
            }
            if (allexists) {
              returnval.add(cpEntry.getKey());
            }
          }
        }
        return returnval;
    }
   
    @Override
    public CertificateProfile getCertificateProfile(final Admin admin, final int id) {
        if (LOG.isTraceEnabled()) {
            LOG.trace(">getCertificateProfile(" + id + ")");
        }
        CertificateProfile returnval = null;
        if (id < SecConst.FIXED_CERTIFICATEPROFILE_BOUNDRY) {
            switch (id) {
            case SecConst.CERTPROFILE_FIXED_ENDUSER:
                returnval = new EndUserCertificateProfile();
                break;
            case SecConst.CERTPROFILE_FIXED_SUBCA:
                returnval = new CACertificateProfile();
                break;
            case SecConst.CERTPROFILE_FIXED_ROOTCA:
                returnval = new RootCACertificateProfile();
                break;
            case SecConst.CERTPROFILE_FIXED_OCSPSIGNER:
                returnval = new OCSPSignerCertificateProfile();
                break;
            case SecConst.CERTPROFILE_FIXED_SERVER:
                returnval = new ServerCertificateProfile();
                break;
            case SecConst.CERTPROFILE_FIXED_HARDTOKENAUTH:
                returnval = new HardTokenAuthCertificateProfile();
                break;
            case SecConst.CERTPROFILE_FIXED_HARDTOKENAUTHENC:
                returnval = new HardTokenAuthEncCertificateProfile();
                break;
            case SecConst.CERTPROFILE_FIXED_HARDTOKENENC:
                returnval = new HardTokenEncCertificateProfile();
                break;
            case SecConst.CERTPROFILE_FIXED_HARDTOKENSIGN:
                returnval = new HardTokenSignCertificateProfile();
                break;
            default:
                returnval = new EndUserCertificateProfile();
            }
        } else {
        // We need to clone the profile, otherwise the cache contents will be modifyable from the outside
          final CertificateProfile cprofile = profileCache.getProfileCache(entityManager).get(Integer.valueOf(id));
        try {
          if (cprofile != null) {
            returnval = (CertificateProfile)cprofile.clone();
          }
        } catch (CloneNotSupportedException e) {
          LOG.error("Should never happen: ", e);
          throw new RuntimeException(e);
        }
        }
        if (LOG.isTraceEnabled()) {
            LOG.trace("<getCertificateProfile(" + id + "): " + (returnval == null ? "null" : "not null"));
        }
        return returnval;
    }

    @Override
    public CertificateProfile getCertificateProfile(final Admin admin, final String profilename) {
        final Integer id = profileCache.getNameIdMapCache(entityManager).get(profilename);
        if (id == null) {
            return null;
        } else {
            return getCertificateProfile(admin, id);
        }
    }

    @Override
    public Map<Integer, String> getCertificateProfileIdToNameMap(final Admin admin) {
        if (LOG.isTraceEnabled()) {
            LOG.trace("><getCertificateProfileIdToNameMap");
        }
        return profileCache.getIdNameMapCache(entityManager);
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    @Override
    public void cloneCertificateProfile(final Admin admin, final String orgprofilename, final String newprofilename,
            final Collection<Integer> authorizedCaIds) throws CertificateProfileExistsException {
        CertificateProfile profile = null;
        if (isCertificateProfileNameFixed(newprofilename)) {
            final String msg = INTRES.getLocalizedMessage("store.errorcertprofilefixed", newprofilename);
            logSession.log(admin, admin.getCaId(), LogConstants.MODULE_CA, new Date(), null, null, LogConstants.EVENT_ERROR_CERTPROFILE,
                    msg);
            throw new CertificateProfileExistsException(msg);
        }
        try {
            profile = (CertificateProfile) getCertificateProfile(admin, orgprofilename).clone();
            boolean issuperadmin = false;
            issuperadmin = authSession.isAuthorizedNoLog(admin, "/super_administrator");
            if (!issuperadmin && profile.isApplicableToAnyCA()) {
                // Not superadministrator, do not use ANYCA;
                profile.setAvailableCAs(authorizedCaIds);
            }
            if (CertificateProfileData.findByProfileName(entityManager, newprofilename) == null) {
                entityManager.persist(new CertificateProfileData(findFreeCertificateProfileId(), newprofilename, profile));
                flushProfileCache();
                final String msg = INTRES.getLocalizedMessage("store.addedprofilewithtempl", newprofilename, orgprofilename);
                logSession.log(admin, admin.getCaId(), LogConstants.MODULE_CA, new Date(), null, null, LogConstants.EVENT_INFO_CERTPROFILE, msg);
            } else {
                final String msg = INTRES.getLocalizedMessage("store.erroraddprofilewithtempl", newprofilename, orgprofilename);
                logSession.log(admin, admin.getCaId(), LogConstants.MODULE_CA, new Date(), null, null,
                        LogConstants.EVENT_ERROR_CERTPROFILE, msg);
                throw new CertificateProfileExistsException();
            }
        } catch (CloneNotSupportedException f) {
            throw new EJBException(f); // If this happens it's a programming error. Throw an exception!
        }
    }

    @Override
    public int getCertificateProfileId(final Admin admin, final String certificateprofilename) {
        if (LOG.isTraceEnabled()) {
            LOG.trace(">getCertificateProfileId: " + certificateprofilename);
        }
        int returnval = 0;
        final Integer id = profileCache.getNameIdMapCache(entityManager).get(certificateprofilename);
        if (id != null) {
            returnval = id.intValue();
        }
        if (LOG.isTraceEnabled()) {
            LOG.trace("<getCertificateProfileId: " + certificateprofilename + "): " + returnval);
        }
        return returnval;
    }

    @Override
    public String getCertificateProfileName(final Admin admin, final int id) {
        if (LOG.isTraceEnabled()) {
            LOG.trace(">getCertificateProfileName: " + id);
        }
        final String returnval = profileCache.getIdNameMapCache(entityManager).get(Integer.valueOf(id));
        if (LOG.isTraceEnabled()) {
            LOG.trace("<getCertificateProfileName: " + id + "): " + returnval);
        }
        return returnval;
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    @Override
    public void renameCertificateProfile(final Admin admin, final String oldprofilename, final String newprofilename)
            throws CertificateProfileExistsException {
        if (isCertificateProfileNameFixed(newprofilename)) {
            final String msg = INTRES.getLocalizedMessage("store.errorcertprofilefixed", newprofilename);
            logSession.log(admin, admin.getCaId(), LogConstants.MODULE_CA, new Date(), null, null, LogConstants.EVENT_ERROR_CERTPROFILE,
                    msg);
            throw new CertificateProfileExistsException(msg);
        }
        if (isCertificateProfileNameFixed(oldprofilename)) {
            final String msg = INTRES.getLocalizedMessage("store.errorcertprofilefixed", oldprofilename);
            logSession.log(admin, admin.getCaId(), LogConstants.MODULE_CA, new Date(), null, null, LogConstants.EVENT_ERROR_CERTPROFILE,
                    msg);
            throw new CertificateProfileExistsException(msg);
        }
        if (CertificateProfileData.findByProfileName(entityManager, newprofilename) == null) {
            final CertificateProfileData pdl = CertificateProfileData.findByProfileName(entityManager, oldprofilename);
            if (pdl == null) {
                final String msg = INTRES.getLocalizedMessage("store.errorrenameprofile", oldprofilename, newprofilename);
                logSession.log(admin, admin.getCaId(), LogConstants.MODULE_CA, new Date(), null, null,
                        LogConstants.EVENT_ERROR_CERTPROFILE, msg);
            } else {
                pdl.setCertificateProfileName(newprofilename);
                flushProfileCache();
                final String msg = INTRES.getLocalizedMessage("store.renamedprofile", oldprofilename, newprofilename);
                logSession.log(admin, admin.getCaId(), LogConstants.MODULE_CA, new Date(), null, null, LogConstants.EVENT_INFO_CERTPROFILE, msg);
            }
        } else {
            final String msg = INTRES.getLocalizedMessage("store.errorcertprofileexists", newprofilename);
            logSession.log(admin, admin.getCaId(), LogConstants.MODULE_CA, new Date(), null, null, LogConstants.EVENT_ERROR_CERTPROFILE, msg);
            throw new CertificateProfileExistsException();
        }
    }

    /*
     * This method will read all Certificate Profiles and as a side-effect upgrade them if the version if changed for upgrade.
     * Can have a side-effect of upgrading a profile, therefore the Required transaction setting.
     */
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    @Override
    public void initializeAndUpgradeProfiles(final Admin admin) {
        final Collection<CertificateProfileData> result = CertificateProfileData.findAll(entityManager);
        final Iterator<CertificateProfileData> iter = result.iterator();
        while(iter.hasNext()) {
                final CertificateProfileData pdata = iter.next();
                final String name = pdata.getCertificateProfileName();
                pdata.upgradeProfile();
                final float version = pdata.getCertificateProfile().getVersion();
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Loaded certificate profile: "+name+" with version "+version);                 
                }
        }
        flushProfileCache();
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    @Override
    public void removeCertificateProfile(final Admin admin, final String profilename) {
        try {
          final CertificateProfileData pdl = CertificateProfileData.findByProfileName(entityManager, profilename);
          if (pdl == null) {
            if (LOG.isDebugEnabled()) {
              LOG.debug("Trying to remove a certificate profile that does not exist: "+profilename);                   
            }
          } else {
            entityManager.remove(pdl);
            flushProfileCache();
            final String msg = INTRES.getLocalizedMessage("store.removedprofile", profilename);               
            logSession.log(admin, admin.getCaId(), LogConstants.MODULE_CA, new Date(), null, null, LogConstants.EVENT_INFO_CERTPROFILE, msg);                 
          }
        } catch (Exception e) {
            LOG.error("Error was caught when trying to remove certificate profile " + profilename, e);
          final String msg = INTRES.getLocalizedMessage("store.errorremoveprofile", profilename);                   
          logSession.log(admin, admin.getCaId(), LogConstants.MODULE_CA, new Date(), null, null, LogConstants.EVENT_ERROR_CERTPROFILE, msg);
        }
    }

    @Override
    public boolean existsCAInCertificateProfiles(final Admin admin, final int caid) {
      for (final Entry<Integer,CertificateProfile> cpEntry : profileCache.getProfileCache(entityManager).entrySet()) {
        final CertificateProfile certProfile = cpEntry.getValue();
        if (certProfile.getType() == CertificateProfile.TYPE_ENDENTITY) {
          for (Integer availableCaId : certProfile.getAvailableCAs()) {
            if (availableCaId.intValue() == caid) {
              if (LOG.isDebugEnabled()) {
                LOG.debug("CA exists in certificate profile " + cpEntry.getKey().toString());
              }
              return true;
            }
          }
        }
      }
      return false;
    }

    @Override
    public boolean existsPublisherInCertificateProfiles(final Admin admin, final int publisherid) {
      for (final Entry<Integer,CertificateProfile> cpEntry : profileCache.getProfileCache(entityManager).entrySet()) {
        for (Integer availablePublisherId : cpEntry.getValue().getPublisherList()) {
          if (availablePublisherId.intValue() == publisherid) {
                    if (LOG.isDebugEnabled()) {
                      LOG.debug("Publisher exists in certificate profile " + cpEntry.getKey().toString());
                    }
                    return true;
          }
        }
      }
      return false;
    }

    private boolean isCertificateProfileNameFixed(final String profilename) {
        if (profilename.equals(EndUserCertificateProfile.CERTIFICATEPROFILENAME)) {
            return true;
        }
        if (profilename.equals(CACertificateProfile.CERTIFICATEPROFILENAME)) {
            return true;
        }
        if (profilename.equals(RootCACertificateProfile.CERTIFICATEPROFILENAME)) {
            return true;
        }
        if (profilename.equals(OCSPSignerCertificateProfile.CERTIFICATEPROFILENAME)) {
            return true;
        }
        if (profilename.equals(ServerCertificateProfile.CERTIFICATEPROFILENAME)) {
            return true;
        }
        return false;
    }

    @Override
    public int findFreeCertificateProfileId() {
        final Random random = new Random(new Date().getTime());
        int id = random.nextInt();
        boolean foundfree = false;
        while (!foundfree) {
            if (id > SecConst.FIXED_CERTIFICATEPROFILE_BOUNDRY) {
                if (CertificateProfileData.findById(entityManager, Integer.valueOf(id)) == null) {
                    foundfree = true;
                }
            } else {
                id = random.nextInt();
            }
        }
        return id;
    }

    private boolean isFreeCertificateProfileId(final int id) {
        boolean foundfree = false;
        if ( (id > SecConst.FIXED_CERTIFICATEPROFILE_BOUNDRY) && (CertificateProfileData.findById(entityManager, Integer.valueOf(id)) == null) ) {
          foundfree = true;
        }
        return foundfree;
    }

}
TOP

Related Classes of org.cesecore.core.ejb.ca.store.CertificateProfileSessionBean

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.