All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cesecore.keybind.InternalKeyBindingFactory Maven / Gradle / Ivy

/*************************************************************************
 *                                                                       *
 *  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.cesecore.keybind;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.log4j.Logger;
import org.cesecore.keybind.impl.AuthenticationKeyBinding;
import org.cesecore.keybind.impl.OcspKeyBinding;
import org.cesecore.util.ui.DynamicUiProperty;

/**
 * Factory class with an internal registry of known implementations.
 * 
 * @version $Id: InternalKeyBindingFactory.java 23648 2016-06-09 15:19:55Z mikekushner $
 */
public enum InternalKeyBindingFactory {
    INSTANCE;

    private final Logger log = Logger.getLogger(InternalKeyBindingFactory.class);
    private final Map aliasToImplementationMap = new HashMap();
    private final Map implementationToAliasMap = new HashMap();
    private final Map>> implementationPropertiesMap = new HashMap>>();

    private InternalKeyBindingFactory() {
        addImplementation(OcspKeyBinding.class);
        addImplementation(AuthenticationKeyBinding.class);
        // Use ServiceLoader framework to find additional available implementations
        // We add these after the built in ones, so the built in implementations can be overridden
        // TODO the above when we need to
    }

    public boolean existsTypeAlias(String alias) {
        return aliasToImplementationMap.containsKey(alias);
    }

    /**
     * Creates a new InternalKeyBinding instance.
     * 
     * @param type is the alias of the registered InternalKeyBinding's type
     * @param id is the unique identifier of this InternalKeyBinding
     * @param name is the unique name that this InternalKeyBinding will be given
     * @param status the initial status to give the InternalKeyBinding
     * @param certificateId is the certificate fingerprint (lower case) matching the mapped key pair or null
     * @param cryptoTokenId is the CryptoToken id of the container where the mapped key pair is stored
     * @param keyPairAlias is the alias of the mapped key pair in the specified CryptoToken (may not be null)
     * @param dataMap is a Map of implementation specific properties for this type of IntenalKeyBinding
     * @return a new InternalKeyBinding instance
     */
    public InternalKeyBinding create(final String type, final int id, final String name, final InternalKeyBindingStatus status,
            final String certificateId, final int cryptoTokenId, final String keyPairAlias, final LinkedHashMap dataMap) {
        final String implementationClassName = aliasToImplementationMap.get(type);
        InternalKeyBinding internalKeyBinding = null;
        if (implementationClassName == null) {
            log.error("Unable to create Signer. Implementation for type '" + type + "' not found.");
        } else {
            try {
                internalKeyBinding = (InternalKeyBinding) Class.forName(implementationClassName).newInstance();
                // Ensure that fingerprint is lower case, to match items in the database
                final String certFp;
                if (certificateId != null) {
                    certFp = certificateId.toLowerCase(Locale.ENGLISH);
                } else {
                    certFp = null;
                }
                internalKeyBinding.init(id, name, status, certFp, cryptoTokenId, keyPairAlias, dataMap);
            } catch (InstantiationException e) {
                log.error("Unable to create InternalKeyBinding. Could not be instantiate implementation '" + implementationClassName + "'.", e);
            } catch (IllegalAccessException e) {
                log.error("Unable to create InternalKeyBinding. Not allowed to instantiate implementation '" + implementationClassName + "'.", e);
            } catch (ClassNotFoundException e) {
                log.error("Unable to create InternalKeyBinding. Could not find implementation '" + implementationClassName + "'.", e);
            }
        }
        return internalKeyBinding;
    }

    /** @return the registered alias for the provided Signer or "null" if this is an unknown implementation. */
    public String getTypeFromImplementation(final InternalKeyBinding internalKeyBinding) {
        return String.valueOf(implementationToAliasMap.get(internalKeyBinding.getClass().getName()));
    }

    private void addImplementation(final Class c) {
        String alias = null;
        List implementationPropertyKeys = null;
        Map> implementationProperties = null;
        try {
            final InternalKeyBinding temporaryInstance = c.newInstance();
            alias = temporaryInstance.getImplementationAlias();
            implementationProperties = temporaryInstance.getCopyOfProperties();
            implementationPropertyKeys = new ArrayList();
            for (String name : implementationProperties.keySet()) {
                implementationPropertyKeys.add(name);
            }
        } catch (InstantiationException e) {
            log.error("Unable to create InternalKeyBinding. Could not be instantiate implementation '" + c.getName() + "'.", e);
        } catch (IllegalAccessException e) {
            log.error("Unable to create InternalKeyBinding. Not allowed to instantiate implementation '" + c.getName() + "'.", e);
        }
        if (alias != null) {
            aliasToImplementationMap.put(alias, c.getName());
            implementationToAliasMap.put(c.getName(), alias);
            implementationPropertiesMap.put(alias, Collections.unmodifiableMap((implementationProperties)));
        }
    }

    public Map>> getAvailableTypesAndProperties() {
        return Collections.unmodifiableMap(implementationPropertiesMap);
    }

    /**
     * Method to be used from an external environment (such as the CLI) where contextual information about a key binding 
     * implementation is not available. Will presume that all key binding properties were entered as strings, will return a
     * data wrapper that contains a map of properly casted values, and information about any values which were either unknown
     * or of an incorrect format.  
     * 
     * @param alias the alias of the key binding type to check for
     * @param propertiesMap the inputed properties, as strings
     * @return a wrapper class that contains the correctly casted values, and information about any values that were invalid.
     */
    public InternalKeyBindingPropertyValidationWrapper validateProperties(String alias, Map propertiesMap) {
        InternalKeyBindingPropertyValidationWrapper result = new InternalKeyBindingPropertyValidationWrapper();
        Map> implementationProperties =  implementationPropertiesMap.get(alias);
        for (String key : propertiesMap.keySet()) {
            if(!implementationProperties.containsKey(key)) {
                result.addUnknownProperty(key);
                continue;
            }
            DynamicUiProperty property = implementationProperties.get(key);
            String value = propertiesMap.get(key);
            Serializable recastValue = property.valueOf(value);
            if(recastValue == null) {
                result.addInvalidValue(key, property.getType());
                continue;
            }
            result.addProperty(key, recastValue);
        }
        return result;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy