From 536db7b811eba341aef48a745b495da068d170eb Mon Sep 17 00:00:00 2001 From: sebdet Date: Tue, 15 Sep 2020 11:53:27 +0200 Subject: Fix the ssl config Fix SSL config so that clamp can access external files from the application.properties spring definition Issue-ID: CLAMP-884 Signed-off-by: sebdet Change-Id: Ic4483d56c86f52249b09b386cdbe505f2f2f2a66 Signed-off-by: sebdet --- src/main/java/org/onap/clamp/clds/Application.java | 7 +- .../onap/clamp/clds/config/CamelConfiguration.java | 8 +- .../java/org/onap/clamp/clds/config/SslConfig.java | 41 +++++----- .../onap/clamp/clds/filter/ClampCadiFilter.java | 7 +- .../org/onap/clamp/clds/util/ClampVersioning.java | 2 +- .../java/org/onap/clamp/clds/util/CryptoUtils.java | 2 +- .../org/onap/clamp/clds/util/ResourceFileUtil.java | 65 ---------------- .../onap/clamp/clds/util/ResourceFileUtils.java | 89 ++++++++++++++++++++++ .../OperationalPolicyRepresentationBuilder.java | 4 +- src/main/java/org/onap/clamp/util/PassDecoder.java | 21 ++--- src/main/resources/application.properties | 1 + 11 files changed, 131 insertions(+), 116 deletions(-) delete mode 100644 src/main/java/org/onap/clamp/clds/util/ResourceFileUtil.java create mode 100644 src/main/java/org/onap/clamp/clds/util/ResourceFileUtils.java (limited to 'src/main') diff --git a/src/main/java/org/onap/clamp/clds/Application.java b/src/main/java/org/onap/clamp/clds/Application.java index 84232999e..c2a1ab908 100644 --- a/src/main/java/org/onap/clamp/clds/Application.java +++ b/src/main/java/org/onap/clamp/clds/Application.java @@ -39,14 +39,13 @@ import java.util.Enumeration; import org.apache.catalina.connector.Connector; import org.onap.clamp.clds.util.ClampVersioning; -import org.onap.clamp.clds.util.ResourceFileUtil; +import org.onap.clamp.clds.util.ResourceFileUtils; import org.onap.clamp.util.PassDecoder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; @@ -111,7 +110,7 @@ public class Application extends SpringBootServletInitializer { */ @Bean public ServletRegistrationBean camelServletRegistrationBean() throws IOException { - eelfLogger.info(ResourceFileUtil.getResourceAsString("boot-message.txt") + "(v" + eelfLogger.info(ResourceFileUtils.getResourceAsString("boot-message.txt") + "(v" + ClampVersioning.getCldsVersionFromProps() + ")" + System.getProperty("line.separator") + getSslExpirationDate()); ServletRegistrationBean registration = new ServletRegistrationBean(new ClampServlet(), "/restservices/clds/*"); @@ -161,7 +160,7 @@ public class Application extends SpringBootServletInitializer { String password = PassDecoder.decode(env.getProperty("server.ssl.key-store-password"), env.getProperty("clamp.config.keyFile")); String keyStore = env.getProperty("server.ssl.key-store"); - InputStream is = ResourceFileUtil.getResourceAsStream(keyStore.replaceAll("classpath:", "")); + InputStream is = ResourceFileUtils.getResourceAsStream(keyStore.replaceAll("classpath:", "")); keystore.load(is, password.toCharArray()); Enumeration aliases = keystore.aliases(); diff --git a/src/main/java/org/onap/clamp/clds/config/CamelConfiguration.java b/src/main/java/org/onap/clamp/clds/config/CamelConfiguration.java index 949ff1eb4..7bf45e498 100644 --- a/src/main/java/org/onap/clamp/clds/config/CamelConfiguration.java +++ b/src/main/java/org/onap/clamp/clds/config/CamelConfiguration.java @@ -48,6 +48,7 @@ import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.conn.BasicHttpClientConnectionManager; import org.onap.clamp.clds.util.ClampVersioning; +import org.onap.clamp.clds.util.ResourceFileUtils; import org.onap.clamp.util.PassDecoder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; @@ -65,7 +66,7 @@ public class CamelConfiguration extends RouteBuilder { private void configureDefaultSslProperties() throws IOException { if (env.getProperty("server.ssl.trust-store") != null) { URL storeResource = Thread.currentThread().getContextClassLoader() - .getResource(env.getProperty("server.ssl.trust-store").replaceAll("classpath:", "")); + .getResource(env.getProperty("server.ssl.trust-store").replaceFirst("classpath:", "")); System.setProperty("javax.net.ssl.trustStore", storeResource.getPath()); String keyFile = env.getProperty("clamp.config.keyFile"); String trustStorePass = PassDecoder.decode(env.getProperty("server.ssl.trust-store-password"), @@ -74,7 +75,7 @@ public class CamelConfiguration extends RouteBuilder { System.setProperty("javax.net.ssl.trustStoreType", "jks"); System.setProperty("ssl.TrustManagerFactory.algorithm", "PKIX"); storeResource = Thread.currentThread().getContextClassLoader() - .getResource(env.getProperty("server.ssl.key-store").replaceAll("classpath:", "")); + .getResource(env.getProperty("server.ssl.key-store").replaceFirst("classpath:", "")); System.setProperty("javax.net.ssl.keyStore", storeResource.getPath()); String keyStorePass = PassDecoder.decode(env.getProperty("server.ssl.key-store-password"), @@ -91,8 +92,7 @@ public class CamelConfiguration extends RouteBuilder { String keyFile = env.getProperty("clamp.config.keyFile"); String password = PassDecoder.decode(env.getProperty("server.ssl.trust-store-password"), keyFile); truststore.load( - Thread.currentThread().getContextClassLoader() - .getResourceAsStream(env.getProperty("server.ssl.trust-store").replaceAll("classpath:", "")), + ResourceFileUtils.getResourceAsStream(env.getProperty("server.ssl.trust-store")), password.toCharArray()); TrustManagerFactory trustFactory = TrustManagerFactory.getInstance("PKIX"); diff --git a/src/main/java/org/onap/clamp/clds/config/SslConfig.java b/src/main/java/org/onap/clamp/clds/config/SslConfig.java index 7c7433e96..16af44695 100644 --- a/src/main/java/org/onap/clamp/clds/config/SslConfig.java +++ b/src/main/java/org/onap/clamp/clds/config/SslConfig.java @@ -30,7 +30,7 @@ import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; -import org.onap.clamp.clds.util.ResourceFileUtil; +import org.onap.clamp.clds.util.ResourceFileUtils; import org.onap.clamp.util.PassDecoder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.web.ServerProperties; @@ -52,45 +52,42 @@ public class SslConfig { @Bean WebServerFactoryCustomizer tomcatCustomizer(ServerProperties serverProperties, - ResourceLoader resourceLoader) { + ResourceLoader resourceLoader) { return (tomcat) -> tomcat.setSslStoreProvider(new SslStoreProvider() { @Override - public KeyStore getKeyStore() throws KeyStoreException, + public KeyStore getKeyStore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { KeyStore keystore = KeyStore.getInstance(env.getProperty("server.ssl.key-store-type")); - String password = PassDecoder.decode(env.getProperty("server.ssl.key-store-password"), - env.getProperty("clamp.config.keyFile")); - String keyStore = env.getProperty("server.ssl.key-store"); - InputStream is = ResourceFileUtil.getResourceAsStream(keyStore.replaceAll("classpath:", "")); - keystore.load(is, password.toCharArray()); + String password = PassDecoder.decode(env.getProperty("server.ssl.key-store-password"), + env.getProperty("clamp.config.keyFile")); + keystore.load(ResourceFileUtils.getResourceAsStream(env.getProperty("server.ssl.key-store")), + password.toCharArray()); return keystore; } @Override - public KeyStore getTrustStore() throws KeyStoreException, + public KeyStore getTrustStore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { - KeyStore truststore = KeyStore.getInstance("JKS"); - String password = PassDecoder.decode(env.getProperty("server.ssl.trust-store-password"), - env.getProperty("clamp.config.keyFile")); - truststore.load( - Thread.currentThread().getContextClassLoader() - .getResourceAsStream(env.getProperty("server.ssl.trust-store") - .replaceAll("classpath:", "")), - password.toCharArray()); - return truststore; + KeyStore truststore = KeyStore.getInstance("JKS"); + String password = PassDecoder.decode(env.getProperty("server.ssl.trust-store-password"), + env.getProperty("clamp.config.keyFile")); + truststore.load( + ResourceFileUtils.getResourceAsStream(env.getProperty("server.ssl.trust-store")), + password.toCharArray()); + return truststore; } }); } @Bean WebServerFactoryCustomizer tomcatSslCustomizer(ServerProperties serverProperties, - ResourceLoader resourceLoader) { + ResourceLoader resourceLoader) { return (tomcat) -> tomcat.setSsl(new Ssl() { @Override public String getKeyPassword() { - String password = PassDecoder.decode(env.getProperty("server.ssl.key-password"), - env.getProperty("clamp.config.keyFile")); - return password; + String password = PassDecoder.decode(env.getProperty("server.ssl.key-password"), + env.getProperty("clamp.config.keyFile")); + return password; } }); } diff --git a/src/main/java/org/onap/clamp/clds/filter/ClampCadiFilter.java b/src/main/java/org/onap/clamp/clds/filter/ClampCadiFilter.java index 3bbb8a0bc..f68990a81 100644 --- a/src/main/java/org/onap/clamp/clds/filter/ClampCadiFilter.java +++ b/src/main/java/org/onap/clamp/clds/filter/ClampCadiFilter.java @@ -46,7 +46,7 @@ import javax.servlet.http.HttpServletRequest; import org.onap.aaf.cadi.config.Config; import org.onap.aaf.cadi.filter.CadiFilter; -import org.onap.clamp.clds.util.ResourceFileUtil; +import org.onap.clamp.clds.util.ResourceFileUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationContext; @@ -102,6 +102,9 @@ public class ClampCadiFilter extends CadiFilter { @Value("${clamp.config.cadi.cadiX509Issuers:#{null}}") private String cadiX509Issuers; + @Value("${clamp.config.caCerts:#{null}}") + private String caCertsPath; + private void checkIfNullProperty(String key, String value) { /* * When value is null, so not defined in application.properties set nothing in @@ -153,7 +156,7 @@ public class ClampCadiFilter extends CadiFilter { URLDecoder.decode(certHeader, StandardCharsets.UTF_8.toString()).getBytes())); X509Certificate caCert = (X509Certificate) certificateFactory .generateCertificate(new ByteArrayInputStream( - ResourceFileUtil.getResourceAsString("clds/aaf/ssl/ca-certs.pem").getBytes())); + ResourceFileUtils.getResourceAsString(this.caCertsPath).getBytes())); X509Certificate[] certifArray = ((X509Certificate[]) request .getAttribute("javax.servlet.request.X509Certificate")); diff --git a/src/main/java/org/onap/clamp/clds/util/ClampVersioning.java b/src/main/java/org/onap/clamp/clds/util/ClampVersioning.java index fd7a9a0fc..ec0162cb1 100644 --- a/src/main/java/org/onap/clamp/clds/util/ClampVersioning.java +++ b/src/main/java/org/onap/clamp/clds/util/ClampVersioning.java @@ -51,7 +51,7 @@ public class ClampVersioning { public static String getCldsVersionFromProps() { String cldsVersion = ""; Properties props = new Properties(); - try (InputStream resourceStream = ResourceFileUtil.getResourceAsStream(RESOURCE_NAME)) { + try (InputStream resourceStream = ResourceFileUtils.getResourceAsStream(RESOURCE_NAME)) { props.load(resourceStream); cldsVersion = props.getProperty(CLDS_VERSION_PROPERTY); } catch (Exception ex) { diff --git a/src/main/java/org/onap/clamp/clds/util/CryptoUtils.java b/src/main/java/org/onap/clamp/clds/util/CryptoUtils.java index 7d37cca60..1ddf3a90a 100644 --- a/src/main/java/org/onap/clamp/clds/util/CryptoUtils.java +++ b/src/main/java/org/onap/clamp/clds/util/CryptoUtils.java @@ -157,7 +157,7 @@ public final class CryptoUtils { if (encryptionKey != null && encryptionKey.trim().length() > 0) { return getSecretKeySpec(encryptionKey); } else { - props.load(ResourceFileUtil.getResourceAsStream(propertiesFileName)); + props.load(ResourceFileUtils.getResourceAsStream(propertiesFileName)); return getSecretKeySpec(props.getProperty(KEY_PARAM)); } } catch (IOException | DecoderException e) { diff --git a/src/main/java/org/onap/clamp/clds/util/ResourceFileUtil.java b/src/main/java/org/onap/clamp/clds/util/ResourceFileUtil.java deleted file mode 100644 index 5deee4679..000000000 --- a/src/main/java/org/onap/clamp/clds/util/ResourceFileUtil.java +++ /dev/null @@ -1,65 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP CLAMP - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights - * reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END============================================ - * =================================================================== - * - */ - -package org.onap.clamp.clds.util; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Scanner; - -/** - * Utility methods supporting resources accesses. - */ -public final class ResourceFileUtil { - - /** - * Private constructor to avoid creating instances of util class. - */ - private ResourceFileUtil() { - } - - /** - * Return resource as a Stream. - * - * @return resource - resource as stream - */ - public static InputStream getResourceAsStream(String name) { - InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(name); - if (is == null) { - throw new IllegalArgumentException("Unable to find resource: " + name); - } - return is; - } - - /** - * Return resource as a String. - */ - public static String getResourceAsString(String name) throws IOException { - try (InputStream is = getResourceAsStream(name)) { - try (Scanner scanner = new Scanner(is)) { - Scanner delimitedScanner = scanner.useDelimiter("\\A"); - return delimitedScanner.hasNext() ? delimitedScanner.next() : ""; - } - } - } -} diff --git a/src/main/java/org/onap/clamp/clds/util/ResourceFileUtils.java b/src/main/java/org/onap/clamp/clds/util/ResourceFileUtils.java new file mode 100644 index 000000000..f858ed2b8 --- /dev/null +++ b/src/main/java/org/onap/clamp/clds/util/ResourceFileUtils.java @@ -0,0 +1,89 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + * =================================================================== + * + */ + +package org.onap.clamp.clds.util; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Scanner; + +/** + * Utility methods supporting resources accesses. + */ +public final class ResourceFileUtils { + + /** + * getResourceAsStram supports the "file:" prefix as they use URL. + * So here we want to eliminate classpath: prefix, so that this class can get + * files from jar resource or file system. + */ + + private static final String CLASSPATH_PREFIX = "classpath:"; + + /** + * Private constructor to avoid creating instances of util class. + */ + private ResourceFileUtils() { + } + + /** + * Method to access a file from the jar resource folder or file system. + * Give the prefix "classpath:" so that it accesses the jar resource folder (default case) + * or the prefix "file:" so that it accesses the file system. + * + * @param fileName The path of the resource (no prefix it will be a classpath access, + * "classpath:/myfilename" or "file:/myfilename") + * @return The file as inputStream + */ + public static InputStream getResourceAsStream(String fileName) { + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream( + fileName.startsWith(CLASSPATH_PREFIX) ? fileName.replaceFirst(CLASSPATH_PREFIX, "") : fileName); + if (is == null) { + throw new IllegalArgumentException("Unable to find resource: " + fileName); + } + return is; + } + + /** + * Method to access a resource file as a string. + * Give the prefix "classpath:" so that it accesses the jar resource folder (default case) + * or the prefix "file:" so that it accesses the file system. + * + * @param fileName The path of the resource (no prefix it will be a classpath access, + * "classpath:/myfilename" or "file:/myfilename") + * @return The file as String + * @throws IOException In case of failure to find the file. + */ + public static String getResourceAsString(String fileName) throws IOException { + try (InputStream is = getResourceAsStream(fileName)) { + return streamToString(is); + } + } + + private static String streamToString(InputStream inputStream) { + try (Scanner scanner = new Scanner(inputStream)) { + Scanner delimitedScanner = scanner.useDelimiter("\\A"); + return delimitedScanner.hasNext() ? delimitedScanner.next() : ""; + } + } +} \ No newline at end of file diff --git a/src/main/java/org/onap/clamp/policy/operational/OperationalPolicyRepresentationBuilder.java b/src/main/java/org/onap/clamp/policy/operational/OperationalPolicyRepresentationBuilder.java index c0e1c019e..0381f0a2a 100644 --- a/src/main/java/org/onap/clamp/policy/operational/OperationalPolicyRepresentationBuilder.java +++ b/src/main/java/org/onap/clamp/policy/operational/OperationalPolicyRepresentationBuilder.java @@ -36,7 +36,7 @@ import java.util.Map.Entry; import java.util.Set; import org.onap.clamp.clds.util.JsonUtils; -import org.onap.clamp.clds.util.ResourceFileUtil; +import org.onap.clamp.clds.util.ResourceFileUtils; import org.onap.clamp.loop.service.Service; public class OperationalPolicyRepresentationBuilder { @@ -74,7 +74,7 @@ public class OperationalPolicyRepresentationBuilder { JsonObject jsonSchema = null; try { jsonSchema = JsonUtils.GSON.fromJson( - ResourceFileUtil + ResourceFileUtils .getResourceAsString("clds/json-schema/operational_policies/operational_policy.json"), JsonObject.class); jsonSchema.get(PROPERTIES).getAsJsonObject() diff --git a/src/main/java/org/onap/clamp/util/PassDecoder.java b/src/main/java/org/onap/clamp/util/PassDecoder.java index 029f55d69..5d261c023 100644 --- a/src/main/java/org/onap/clamp/util/PassDecoder.java +++ b/src/main/java/org/onap/clamp/util/PassDecoder.java @@ -31,7 +31,7 @@ import java.io.IOException; import java.io.InputStream; import org.onap.aaf.cadi.Symm; -import org.onap.clamp.clds.util.ResourceFileUtil; +import org.onap.clamp.clds.util.ResourceFileUtils; /** * PassDecoder for decrypting the truststore and keystore password. @@ -44,12 +44,12 @@ public class PassDecoder { /** * Decode the password. - * + * * @param encryptedPass The encrypted password - * @param keyFile The key file name in String + * @param keyFileName The key file name in String */ - public static String decode(String encryptedPass, String keyFile) { - if (null == keyFile) { + public static String decode(String encryptedPass, String keyFileName) { + if (null == keyFileName) { logger.debug("Key file is not defined, thus password will not be decrypted"); return encryptedPass; } @@ -58,16 +58,7 @@ public class PassDecoder { return null; } try { - InputStream is; - if (keyFile.contains("classpath:")) { - is = ResourceFileUtil.getResourceAsStream(keyFile.replaceAll("classpath:", "")); - } else { - File key = new File(keyFile); - is = new FileInputStream(key); - } - Symm symm = Symm.obtain(is); - - return symm.depass(encryptedPass); + return Symm.obtain(ResourceFileUtils.getResourceAsStream(keyFileName)).depass(encryptedPass); } catch (IOException e) { logger.error("Exception occurred during the key decryption", e); return null; diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index c5bab26c4..4ab551ea3 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -63,6 +63,7 @@ server.ssl.key-alias=clamp@clamp.onap.org # The key file used to decode the key store and trust store password # If not defined, the key store and trust store password will not be decrypted clamp.config.keyFile=classpath:/clds/aaf/org.onap.clamp.keyfile +clamp.config.caCerts=classpath:/clds/aaf/ssl/ca-certs.pem ## Config part for Client certificates server.ssl.client-auth=want -- cgit 1.2.3-korg