From e2e77ed55687cb92c6f5a273995daf64dedef848 Mon Sep 17 00:00:00 2001 From: Christof Rabensteiner Date: Wed, 26 Jun 2019 08:47:58 +0200 Subject: Protect MsgClient via SSL (ink Client Authentication) - Add Component to create SSLContexts with own Key- and trust store. - Inject SSLContext into HTTP Client. - Add EAAF-Components Core Dependency, which is needed by SSLContextCreator (KeyStoreUtils). Schema Changes in mzs:DeliveryRequest/Config: - Got Rid of mzs:DeliveryRequest/Config/Server. In mzs 1.4.1, Server replaces the result of zkopf query person request. Since this zkopf interface does not exist anymore, Server was removed. - Add ClientType, which holds all parameters needed to connect to a service (Url, SSL params, a.o.). Configuration: - Add default parameters for SSL Clients in application.yaml. - Merge default parameters into incoming mzs:DeliveryRequests. MoaZSException Fixes: - Remove "Extends throwable" from Builder. - Add convenient shorthand init method (message, throwable). Refactor: - Put "determinePath" to FileUtils. - Put string related utility functions into StringUtils. --- .../at/gv/egiz/moazs/preprocess/ConfigUtil.java | 183 ++++++++++++++++++--- 1 file changed, 161 insertions(+), 22 deletions(-) (limited to 'src/main/java/at/gv/egiz/moazs/preprocess/ConfigUtil.java') diff --git a/src/main/java/at/gv/egiz/moazs/preprocess/ConfigUtil.java b/src/main/java/at/gv/egiz/moazs/preprocess/ConfigUtil.java index 3fef4bd..1befd1d 100644 --- a/src/main/java/at/gv/egiz/moazs/preprocess/ConfigUtil.java +++ b/src/main/java/at/gv/egiz/moazs/preprocess/ConfigUtil.java @@ -1,20 +1,37 @@ package at.gv.egiz.moazs.preprocess; +import at.gv.egiz.moazs.util.StringUtils; +import at.gv.zustellung.app2mzs.xsd.ClientType; import at.gv.zustellung.app2mzs.xsd.ConfigType; -import at.gv.zustellung.app2mzs.xsd.ServerType; +import at.gv.zustellung.app2mzs.xsd.KeyStoreType; +import at.gv.zustellung.app2mzs.xsd.SSLType; import org.springframework.lang.Nullable; import org.springframework.stereotype.Component; import java.util.Map; +import static at.gv.zustellung.app2mzs.xsd.ClientType.clientTypeBuilder; import static at.gv.zustellung.app2mzs.xsd.ConfigType.configTypeBuilder; -import static at.gv.zustellung.app2mzs.xsd.ServerType.serverTypeBuilder; +import static at.gv.zustellung.app2mzs.xsd.KeyStoreType.keyStoreTypeBuilder; +import static at.gv.zustellung.app2mzs.xsd.SSLType.SSLTypeBuilder; +import static java.util.stream.Collectors.toMap; @Component public class ConfigUtil { - private static final String TNVZ_REQUEST_KEY = "perform-query-person-request"; - private static final String MSG_URL_KEY = "msg.url"; + public static final String TNVZ_REQUEST_KEY = "perform-query-person-request"; + public static final String MSG_CLIENT_KEY = "msg-client"; + public static final String TNVZ_CLIENT_KEY = "tnvz-client"; + public static final String URL_KEY = "url"; + public static final String SSL_KEY = "ssl"; + public static final String TRUST_ALL_KEY = "trust-all"; + public static final String LAX_HOSTNAME_VERIFICATION_KEY = "lax-hostname-verification"; + public static final String KEYSTORE_KEY = "keystore"; + public static final String TRUSTSTORE_KEY = "truststore"; + public static final String FILENAME_KEY = "filename"; + public static final String FILETYPE_KEY = "filetype"; + public static final String PASSWORD_KEY = "password"; + /** * Convert a map into a Config object. @@ -23,16 +40,74 @@ public class ConfigUtil { * @return Config */ public ConfigType convert(Map values) { - var server = serverTypeBuilder() - .withZUSEUrlID(values.get(MSG_URL_KEY)) - .build(); - Boolean performQueryPersonRequest = values.get(TNVZ_REQUEST_KEY) == null ? null : Boolean.getBoolean(values.get(TNVZ_REQUEST_KEY)); + var msgClientParams = filterMapByPrefix(values, MSG_CLIENT_KEY); + ClientType msgClient = msgClientParams.isEmpty() + ? null : buildClient(msgClientParams); + + var tnvzClientParams = filterMapByPrefix(values, TNVZ_CLIENT_KEY); + ClientType tnvzClient = tnvzClientParams.isEmpty() + ? null : buildClient(tnvzClientParams); + return ConfigType.configTypeBuilder() .withPerformQueryPersonRequest(performQueryPersonRequest) - .withServer(server) + .withMSGClient(msgClient) + .withTNVZClient(tnvzClient) + .build(); + } + + private Map filterMapByPrefix(Map values, String prefix) { + return values.entrySet().stream() + .filter(entry -> entry.getKey().startsWith(prefix)) + .collect(toMap(e -> StringUtils.removePrefix(e.getKey()), Map.Entry::getValue)); + } + + + private ClientType buildClient(Map clientParams) { + + var url = clientParams.get(URL_KEY); + + var sslParams = filterMapByPrefix(clientParams, SSL_KEY); + SSLType ssl = sslParams.isEmpty() + ? null : buildSSL(sslParams); + + return clientTypeBuilder().withURL(url).withSSL(ssl).build(); + + } + + private SSLType buildSSL(Map sslParams) { + + var keyStoreParams = filterMapByPrefix(sslParams, KEYSTORE_KEY); + KeyStoreType keyStore = keyStoreParams.isEmpty() + ? null : buildKeyStore(keyStoreParams); + + var trustStoreParams = filterMapByPrefix(sslParams, TRUSTSTORE_KEY); + KeyStoreType trustStore = trustStoreParams.isEmpty() + ? null : buildKeyStore(trustStoreParams); + + var trustAll = sslParams.get(TRUST_ALL_KEY) == null + ? null : Boolean.getBoolean(sslParams.get(TRUST_ALL_KEY)); + + var laxHostNameVerification = sslParams.get(LAX_HOSTNAME_VERIFICATION_KEY) == null + ? null : Boolean.getBoolean(sslParams.get(LAX_HOSTNAME_VERIFICATION_KEY)); + + return SSLTypeBuilder() + .withKeyStore(keyStore) + .withTrustStore(trustStore) + .withTrustAll(trustAll) + .withLaxHostNameVerification(laxHostNameVerification) + .build(); + + } + + private KeyStoreType buildKeyStore(Map params) { + + return keyStoreTypeBuilder() + .withFileName(params.get(FILENAME_KEY)) + .withFileType(params.get(FILETYPE_KEY)) + .withPassword(params.get(PASSWORD_KEY)) .build(); } @@ -47,32 +122,65 @@ public class ConfigUtil { var builder = configTypeBuilder(fallback); - if(primary.getServer() != null) { - builder.withServer(merge(primary.getServer(), fallback.getServer())); + if (primary.isPerformQueryPersonRequest() != null) { + builder.withPerformQueryPersonRequest(primary.isPerformQueryPersonRequest()); } - if(primary.isPerformQueryPersonRequest() != null) { - builder.withPerformQueryPersonRequest(primary.isPerformQueryPersonRequest()); + if (primary.getMSGClient() != null) { + builder.withMSGClient(merge(primary.getMSGClient(), fallback.getMSGClient())); + } + + if (primary.getTNVZClient() != null) { + builder.withMSGClient(merge(primary.getTNVZClient(), fallback.getTNVZClient())); } return builder.build(); + } + + private ClientType merge(ClientType primary, ClientType fallback) { + var builder = clientTypeBuilder(fallback); + + if (primary.getURL() != null) { + builder.withURL(primary.getURL()); + } + + if (primary.getSSL() != null) { + builder.withSSL(merge(primary.getSSL(), fallback.getSSL())); + } + return builder.build(); } - private ServerType merge(ServerType primary, ServerType fallback) { + private SSLType merge(SSLType primary, SSLType fallback) { + var builder = SSLTypeBuilder(fallback); - if (fallback == null) { - return primary; + if (primary.getKeyStore() != null) { + builder.withKeyStore(merge(primary.getKeyStore(), fallback.getKeyStore())); } - var builder = serverTypeBuilder(fallback); + if (primary.getTrustStore() != null) { + builder.withKeyStore(merge(primary.getTrustStore(), fallback.getTrustStore())); + } - if (primary.getX509() != null) builder.withX509 (primary.getX509() ); - if (primary.getZUSEUrlID() != null) builder.withZUSEUrlID(primary.getZUSEUrlID()); + if (primary.isLaxHostNameVerification() != null) { + builder.withLaxHostNameVerification(primary.isLaxHostNameVerification()); + } + if (primary.isTrustAll() != null) { + builder.withLaxHostNameVerification(primary.isTrustAll()); + } return builder.build(); } + private KeyStoreType merge(KeyStoreType primary, KeyStoreType fallback) { + + if (primary.getFileName() != null && primary.getFileType() != null && primary.getPassword() != null) + return primary; + + return fallback; + + } + /** * Check if all mandatory fields are set. * @@ -80,11 +188,42 @@ public class ConfigUtil { * @return true if all mandatory fields are set */ public boolean isComplete(@Nullable ConfigType profile) { - //TODO: add check fo x509 certificate return profile != null && profile.isPerformQueryPersonRequest() != null - && profile.getServer() != null - && profile.getServer().getZUSEUrlID() != null; + && isTVNZClientConfigured(profile.getTNVZClient(), profile.isPerformQueryPersonRequest()) + && isMSGClientConfigured(profile.getMSGClient()); + } + + private boolean isTVNZClientConfigured(ClientType tnvzClient, Boolean isPerformQueryPersonRequest) { + return (tnvzClient != null + && tnvzClient.getURL() != null + && isSSLConfigured(tnvzClient)) + || isPerformQueryPersonRequest == false; } + private boolean isMSGClientConfigured(ClientType msgClient) { + return msgClient != null + && msgClient.getURL() != null + && isSSLConfigured(msgClient); + } + + private boolean isSSLConfigured(ClientType params) { + return (params.getURL().startsWith("https") + && params.getSSL() != null + && params.getSSL().isTrustAll() != null + && params.getSSL().isLaxHostNameVerification() != null + && isKeyStoreConfigured(params.getSSL().getKeyStore()) + && isKeyStoreConfigured(params.getSSL().getTrustStore())) + || !params.getURL().startsWith("https"); + } + + private boolean isKeyStoreConfigured(KeyStoreType keyStore) { + return (keyStore != null + && keyStore.getPassword() != null + && keyStore.getFileType() != null + && keyStore.getFileName() != null) + || keyStore == null; + } + + } -- cgit v1.2.3