diff options
Diffstat (limited to 'eaaf_core_utils/src/main')
2 files changed, 275 insertions, 0 deletions
| diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreFactory.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreFactory.java new file mode 100644 index 00000000..af184050 --- /dev/null +++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreFactory.java @@ -0,0 +1,216 @@ +package at.gv.egiz.eaaf.core.impl.credential; + +import java.io.IOException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Security; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; + +import javax.annotation.Nonnull; +import javax.annotation.PostConstruct; + +import at.asitplus.hsmfacade.provider.HsmFacadeProvider; +import at.asitplus.hsmfacade.provider.RemoteKeyStoreLoadParameter; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.exceptions.EaafFactoryException; +import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType; +import at.gv.egiz.eaaf.core.impl.utils.FileUtils; +import at.gv.egiz.eaaf.core.impl.utils.KeyStoreUtils; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class EaafKeyStoreFactory { + +  public static final String CONFIG_PROP_HSM_FACADE_HOST = "security.hsmfacade.host"; +  public static final String CONFIG_PROP_HSM_FACADE_PORT = "security.hsmfacade.port"; +  public static final String CONFIG_PROP_HSM_FACADE_SSLTRUST = "security.hsmfacade.trustedsslcert"; +  public static final String CONFIG_PROP_HSM_FACADE_CLIENT_USERNAME = "security.hsmfacade.username"; +  public static final String CONFIG_PROP_HSM_FACADE_CLIENT_PASSWORD = "security.hsmfacade.password"; +  public static final String CONFIG_PROP_HSM_FACADE_HSM_NAME = "security.hsmfacade.hsmname"; + +  public static final String ERRORCODE_00 = "internal.keystore.00"; +  public static final String ERRORCODE_01 = "internal.keystore.01"; +  public static final String ERRORCODE_02 = "internal.keystore.02"; +  public static final String ERRORCODE_03 = "internal.keystore.03"; +  public static final String ERRORCODE_04 = "internal.keystore.04"; +  public static final String ERRORCODE_05 = "internal.keystore.05"; +  public static final String ERRORCODE_06 = "internal.keystore.06"; + +  @Autowired private IConfiguration basicConfig; +  @Autowired private ResourceLoader resourceLoader; + +  private boolean isHsmFacadeInitialized = false; + + + +  public KeyStore buildNewKeyStore(KeyStoreConfiguration config) throws EaafException { +    log.trace("Starting KeyStore generation based on configuration object ... "); +    if (KeyStoreType.SOFTWARE.equals(config.getKeyStoreType())) { +      return getKeyStoreFromFileSystem(config); + +    } else if (KeyStoreType.HSMFACADE.equals(config.getKeyStoreType())) { +      if (isHsmFacadeInitialized) { +       getKeyStoreFromHsmFacade(config); + +      } else { +        log.error("HSMFacade can NOT be used for KeyStore: {} because {} is not initialized", +            config.getFriendlyName()); +        throw new EaafConfigurationException(ERRORCODE_00, +            new Object[]{config.getFriendlyName()}); + +      } + +    } else if (KeyStoreType.PKCS11.equals(config.getKeyStoreType())) { +      log.warn("KeyStoreType: {} is NOT supported", config.getKeyStoreType()); +      throw new EaafConfigurationException(ERRORCODE_02, +          new Object[]{config.getFriendlyName(), config.getKeyStoreType()}); + +    } else { +      log.warn("KeyStoreType: {} is unrecognized", config.getKeyStoreType()); +      throw new EaafConfigurationException(ERRORCODE_01, +          new Object[]{config.getFriendlyName()}); + +    } +    return null; +  } + +  @PostConstruct +  private void initialize() throws EaafException { + +    final String hsmFacadeHost = basicConfig.getBasicConfiguration(CONFIG_PROP_HSM_FACADE_HOST); +    if (StringUtils.isNotEmpty(hsmFacadeHost)) { +      log.debug("Find host for HSMFacade. Starting crypto provider initialization ... "); +      try { +        final int port = Integer.valueOf( +            getConfigurationParameter(CONFIG_PROP_HSM_FACADE_PORT)); +        final String clientUsername = +            getConfigurationParameter(CONFIG_PROP_HSM_FACADE_CLIENT_USERNAME); +        final String clientPassword = +            getConfigurationParameter(CONFIG_PROP_HSM_FACADE_CLIENT_PASSWORD); +        final String hsmName = +            getConfigurationParameter(CONFIG_PROP_HSM_FACADE_HSM_NAME); + +        final HsmFacadeProvider provider = HsmFacadeProvider.Companion.getInstance(); +        provider.init(getHsmFacadeTrustSslCertificate(), clientUsername, clientPassword, hsmFacadeHost, port, hsmName); +        Security.addProvider(provider); +        isHsmFacadeInitialized = true; +        log.info("HSM Facade is initialized. {} can provide KeyStores based on remote HSM", +            EaafKeyStoreFactory.class.getSimpleName()); + +      } catch (final EaafException e) { +        throw e; + +      } catch (final Exception e) { +        log.error("HSM Facade initialization FAILED with an generic error.", e); +        throw new EaafConfigurationException(ERRORCODE_03, new Object[] {e.getMessage()}, e); +      } + +    } else { +        log.info("HSM Facade is not configurated. {} can only provide software keystores", +            EaafKeyStoreFactory.class.getSimpleName()); + +    } + +  } + +  private KeyStore getKeyStoreFromFileSystem(KeyStoreConfiguration config) throws EaafConfigurationException { +    try { +      final String keyStorePath = config.getKeyStoreFilePath(); +      final String keyStorePassword = config.getKeyStorePassword(); + +      //TODO: check config + +      final String absKeyStorePath = FileUtils.makeAbsoluteUrl(keyStorePath, basicConfig.getConfigurationRootDirectory()); +      final Resource ressource = resourceLoader.getResource(absKeyStorePath); +      if (!ressource.exists()) { +        throw new EaafConfigurationException(ERRORCODE_05, +            new Object[] {CONFIG_PROP_HSM_FACADE_SSLTRUST, +                "File not found at: " + absKeyStorePath}); + +      } + +      return KeyStoreUtils.loadKeyStore(ressource.getInputStream(), keyStorePassword); + +    } catch (KeyStoreException | IOException e) { +      log.error("Software KeyStore initialization FAILED with an generic error.", e); +      throw new EaafConfigurationException(ERRORCODE_03, new Object[] {e.getMessage()}, e); + +    } +  } + +  private KeyStore getKeyStoreFromHsmFacade(KeyStoreConfiguration config) throws EaafFactoryException, EaafConfigurationException { +    final String keyStoreName = config.getKeyStoreName(); +    if (StringUtils.isEmpty(keyStoreName)) { +      throw new EaafConfigurationException(ERRORCODE_06, +          new Object[] {config.getFriendlyName(), "No KeyStore name"}); + +    } + +    try { +      final KeyStore keyStore = KeyStore.getInstance("RemoteKeyStore", "HsmFacade"); +      keyStore.load(new RemoteKeyStoreLoadParameter(keyStoreName)); +      return keyStore; + +      } catch (NoSuchAlgorithmException | CertificateException | IOException | +          KeyStoreException | NoSuchProviderException e) { +        log.error("Can not initialize KeyStore: {} with reason: {}", +            config.getFriendlyName(), e.getMessage()); +        throw new EaafFactoryException(ERRORCODE_06, +            new Object[] {config.getFriendlyName(), e.getMessage()}, e); + +      } +  } + +  private X509Certificate getHsmFacadeTrustSslCertificate() throws EaafConfigurationException { +    try { +      final String certFilePath = getConfigurationParameter(CONFIG_PROP_HSM_FACADE_SSLTRUST); + +    final String absolutCertFilePath = FileUtils.makeAbsoluteUrl( +        certFilePath, basicConfig.getConfigurationRootDirectory()); +    final Resource certFile = resourceLoader.getResource(absolutCertFilePath); + +    if (!certFile.exists()) { +      throw new EaafConfigurationException(ERRORCODE_05, +          new Object[] {CONFIG_PROP_HSM_FACADE_SSLTRUST, +              "File not found at: " + absolutCertFilePath }); + +    } + +    return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(certFile.getInputStream()); + +    } catch (final EaafConfigurationException e) { +      throw e; + +    } catch (CertificateException | IOException e) { +      log.error("Can not load trusted server-certificate for HSM-Facade. Reason: {}", e.getMessage()); +      throw new EaafConfigurationException(ERRORCODE_05, +          new Object[] {CONFIG_PROP_HSM_FACADE_SSLTRUST, e.getMessage()}, e); + +    } +  } + +  @Nonnull +  private String getConfigurationParameter(@Nonnull String configParamKey) +      throws EaafConfigurationException{ +    final String configValue = basicConfig.getBasicConfiguration(configParamKey); +    if (StringUtils.isEmpty(configValue)) { +      throw new EaafConfigurationException(ERRORCODE_04, new Object[] {configParamKey}); + +    } + +    return configValue; +  } + +} diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/KeyStoreConfiguration.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/KeyStoreConfiguration.java new file mode 100644 index 00000000..c8489ac0 --- /dev/null +++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/KeyStoreConfiguration.java @@ -0,0 +1,59 @@ +package at.gv.egiz.eaaf.core.impl.credential; + +import lombok.Getter; + +@Getter +public class KeyStoreConfiguration { + +  private String friendlyName; + +  private KeyStoreType keyStoreType; + +  private String keyStoreName; + +  private String keyStoreFilePath; + +  private String keyStorePassword; + + +  public enum KeyStoreType { +    SOFTWARE("software"), HSMFACADE("hsmfacade"), PKCS11("pkcs11"); + +    private final String keyStoreType; + +    KeyStoreType(final String keyStoreType) { +      this.keyStoreType = keyStoreType; +    } + +    /** +     * Get Type of this KeyStore. +     * +     * @return +     */ +    public String getKeyStoreType() { +      return this.keyStoreType; +    } + +    /** +     * Get KeyStore type from String representation. +     * +     * @param s Config parameter +     * @return +     */ +    public static KeyStoreType fromString(final String s) { +      try { +        return KeyStoreType.valueOf(s.toUpperCase()); + +      } catch (IllegalArgumentException | NullPointerException e) { +        return null; +      } +    } + +    @Override +    public String toString() { +      return getKeyStoreType(); + +    } + +  } +} | 
