Update FProxy to separate truststore and keystore 26/72226/3
authorMichael Arrastia <MArrasti@amdocs.com>
Thu, 8 Nov 2018 16:57:56 +0000 (16:57 +0000)
committerMichael Arrastia <MArrasti@amdocs.com>
Fri, 9 Nov 2018 13:49:40 +0000 (13:49 +0000)
* Create default truststore, fproxy_truststore.
* Require TRUST_STORE_PASSWORD system parameter on application start.
* Harden parameter checks in FProxyApplication PostConstruct.
* Rationalise properties in RestTemplateConfig.
* Update unit tests to handle trust store.
* Correct spring dependency in pom.

Change-Id: I0254e5d27ff76bbd7a44b961169d7fe47761d3f9
Issue-ID: AAF-614
Signed-off-by: Michael Arrastia <MArrasti@amdocs.com>
.gitignore
sidecar/fproxy/config/auth/fproxy_truststore [new file with mode: 0644]
sidecar/fproxy/pom.xml
sidecar/fproxy/src/main/bin/start.sh
sidecar/fproxy/src/main/java/org/onap/aaf/cadi/sidecar/fproxy/FProxyApplication.java
sidecar/fproxy/src/main/java/org/onap/aaf/cadi/sidecar/fproxy/RestTemplateConfig.java
sidecar/fproxy/src/main/resources/application.properties
sidecar/fproxy/src/test/java/org/onap/aaf/cadi/sidecar/fproxy/test/FProxyIT.java
sidecar/fproxy/src/test/java/org/onap/aaf/cadi/sidecar/fproxy/test/FProxyServiceTest.java

index f3bad09..6f0e6fd 100644 (file)
@@ -1,5 +1,21 @@
-/.classpath
-/.settings/
-/target/
-/.project
-/logs/
+# Application
+logs/
+
+# Maven
+target/
+
+# Eclipse
+.classpath
+.factorypath
+.project
+.settings/
+
+# IntelliJ
+.idea/
+*.iml
+
+# Visual Studio Code
+.vscode
+
+# Misc
+.checkstyle
diff --git a/sidecar/fproxy/config/auth/fproxy_truststore b/sidecar/fproxy/config/auth/fproxy_truststore
new file mode 100644 (file)
index 0000000..9eec841
Binary files /dev/null and b/sidecar/fproxy/config/auth/fproxy_truststore differ
index e79bd3e..68e6a86 100644 (file)
@@ -1,21 +1,21 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!--* ============LICENSE_START==================================================== 
-    * =========================================================================== 
-    * org.onap.aaf 
-    * 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==================================================== 
+<!--* ============LICENSE_START====================================================
+    * ===========================================================================
+    * org.onap.aaf
+    * 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====================================================
     * -->
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <name>Sidecar fproxy</name>
        <description>ONAP AAF Forward Proxy Microservice For Pluggable Security</description>
 
+       <dependencyManagement>
+               <dependencies>
+                       <dependency>
+                               <!-- Import dependency management from Spring Boot -->
+                               <groupId>org.springframework.boot</groupId>
+                               <artifactId>spring-boot-dependencies</artifactId>
+                               <version>${spring.boot.version}</version>
+                               <type>pom</type>
+                               <scope>import</scope>
+                       </dependency>
+               </dependencies>
+       </dependencyManagement>
+
        <dependencies>
                <dependency>
-                       <!-- Import dependency management from Spring Boot -->
-                       <groupId>org.springframework.boot</groupId>
-                       <artifactId>spring-boot-dependencies</artifactId>
-                       <version>${spring.boot.version}</version>
-                       <type>pom</type>
-                       <scope>import</scope>
+                       <groupId>org.apache.httpcomponents</groupId>
+                       <artifactId>httpclient</artifactId>
                </dependency>
-               
-               <dependency>
-                   <groupId>org.apache.httpcomponents</groupId>
-                   <artifactId>httpclient</artifactId>
-               </dependency>
-               
+
                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-jetty</artifactId>
index 53662b6..624f784 100644 (file)
@@ -26,7 +26,14 @@ if [ -z "${KEY_STORE_PASSWORD}" ]; then
        exit 1
 fi
 
+if [ -z "${TRUST_STORE_PASSWORD}" ]; then
+       echo "TRUST_STORE_PASSWORD must be set in order to start up process"
+       exit 1
+fi
+
 PROPS="-DKEY_STORE_PASSWORD=${KEY_STORE_PASSWORD}"
+PROPS="$PROPS -DTRUST_STORE_PASSWORD=${TRUST_STORE_PASSWORD}"
+
 JVM_MAX_HEAP=${MAX_HEAP:-1024}
 
 exec java -Xmx${JVM_MAX_HEAP}m ${PROPS} -jar ${BASEDIR}/fproxy-exec.jar
index 7e3ffe4..9ca301a 100644 (file)
@@ -20,6 +20,7 @@
 package org.onap.aaf.cadi.sidecar.fproxy;
 
 import java.util.HashMap;
+import java.util.Optional;
 import javax.annotation.PostConstruct;
 import org.eclipse.jetty.util.security.Password;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -35,40 +36,40 @@ public class FProxyApplication extends SpringBootServletInitializer {
 
     @Autowired
     private Environment env;
-    
+
+    @FunctionalInterface
+    public interface AppProperty {
+        String getProperty(String p);
+    }
+
     /**
-     * Spring Boot Initialization.
-     * 
+     * Spring Boot initialization.
+     *
      * @param args main args
      */
     public static void main(String[] args) {
-        String keyStorePassword = System.getProperty("KEY_STORE_PASSWORD");
-        if (keyStorePassword == null || keyStorePassword.isEmpty()) {
-            throw new IllegalArgumentException("Env property KEY_STORE_PASSWORD not set");
-        }
+        AppProperty appProp = (String propertyName) -> Optional.ofNullable(System.getProperty(propertyName))
+                .orElseThrow(() -> new IllegalArgumentException("Env property " + propertyName + " not set"));
+
         HashMap<String, Object> props = new HashMap<>();
-        props.put("server.ssl.key-store-password", Password.deobfuscate(keyStorePassword));
+        props.put("server.ssl.key-store-password", Password.deobfuscate(appProp.getProperty("KEY_STORE_PASSWORD")));
+        props.put("server.ssl.trust-store-password", Password.deobfuscate(appProp.getProperty("TRUST_STORE_PASSWORD")));
         new FProxyApplication().configure(new SpringApplicationBuilder(FProxyApplication.class).properties(props))
                 .run(args);
     }
-    
+
     /**
-     * Set required trust store system properties using values from application.properties
+     * Set required trust and key store system properties using values from application.properties
      */
     @PostConstruct
     public void setSystemProperties() {
-        String keyStorePath = env.getProperty("server.ssl.key-store");
-        if (keyStorePath != null) {
-            String keyStorePassword = env.getProperty("server.ssl.key-store-password");
+        AppProperty appProp = (String propertyName) -> Optional.ofNullable(env.getProperty(propertyName))
+                .orElseThrow(() -> new IllegalArgumentException("Env property " + propertyName + " not set"));
 
-            if (keyStorePassword != null) {
-                System.setProperty("javax.net.ssl.keyStore", keyStorePath);
-                System.setProperty("javax.net.ssl.keyStorePassword", keyStorePassword);
-                System.setProperty("javax.net.ssl.trustStore", keyStorePath);
-                System.setProperty("javax.net.ssl.trustStorePassword", keyStorePassword);
-            } else {
-                throw new IllegalArgumentException("Env property server.ssl.key-store-password not set");
-            }
-        }
+        System.setProperty("javax.net.ssl.keyStore", appProp.getProperty("server.ssl.key-store"));
+        System.setProperty("javax.net.ssl.keyStorePassword", appProp.getProperty("server.ssl.key-store-password"));
+        System.setProperty("javax.net.ssl.trustStore", appProp.getProperty("server.ssl.trust-store"));
+        System.setProperty("javax.net.ssl.trustStorePassword", appProp.getProperty("server.ssl.trust-store-password"));
     }
+
 }
index 23f3471..33ecb7e 100644 (file)
@@ -45,11 +45,11 @@ public class RestTemplateConfig {
     @Value("${server.ssl.client-cert-password}")
     private String clientCertPassword;
 
-    @Value("${server.ssl.key-store}")
-    private String keystorePath;
+    @Value("${server.ssl.trust-store}")
+    private String trustStorePath;
 
-    @Value("${server.ssl.key-store-password}")
-    private String keystorePassword;
+    @Value("${server.ssl.trust-store-password}")
+    private String trustStorePassword;
 
     @Profile("secure")
     @Bean
@@ -66,11 +66,11 @@ public class RestTemplateConfig {
     }
 
     private HttpClientBuilder getClientBuilder() throws GeneralSecurityException, IOException {
+        char[] clientPassword = Password.deobfuscate(clientCertPassword).toCharArray();
 
         SSLContext sslContext = SSLContextBuilder.create()
-                .loadKeyMaterial(ResourceUtils.getFile(clientCertPath), Password.deobfuscate(clientCertPassword).toCharArray(),
-                        keystorePassword.toCharArray())
-                .loadTrustMaterial(ResourceUtils.getFile(keystorePath), keystorePassword.toCharArray()).build();
+                .loadKeyMaterial(ResourceUtils.getFile(clientCertPath), clientPassword, clientPassword)
+                .loadTrustMaterial(ResourceUtils.getFile(trustStorePath), trustStorePassword.toCharArray()).build();
 
         return HttpClients.custom().setSSLContext(sslContext);
     }
index 2fb9396..47717b7 100644 (file)
@@ -2,6 +2,8 @@ CONFIG_HOME=config
 
 server.port=10680
 server.ssl.key-store=${CONFIG_HOME}/auth/tomcat_keystore
+server.ssl.trust-store=${CONFIG_HOME}/auth/fproxy_truststore
+
 server.ssl.client-cert=${CONFIG_HOME}/auth/client-cert.p12
 server.ssl.client-cert-password=OBF:1y0q1uvc1uum1uvg1pil1pjl1uuq1uvk1uuu1y10
 server.ssl.client-auth=want
@@ -10,4 +12,4 @@ server.servlet.context-path=/
 
 logging.config=${CONFIG_HOME}/logback-spring.xml
 
-spring.profiles.active=secure
\ No newline at end of file
+spring.profiles.active=secure
index 308eb26..dae0e55 100644 (file)
 package org.onap.aaf.cadi.sidecar.fproxy.test;
 
 import static org.assertj.core.api.Assertions.assertThat;
-
 import org.eclipse.jetty.util.security.Password;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.onap.aaf.cadi.sidecar.fproxy.service.ForwardingProxyService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.test.context.TestPropertySource;
 import org.springframework.test.context.junit4.SpringRunner;
 
 @RunWith(SpringRunner.class)
-@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+@SpringBootTest
+@TestPropertySource(properties = {"TRUST_STORE_PASSWORD=OBF:1y0q1uvc1uum1uvg1pil1pjl1uuq1uvk1uuu1y10",
+        "KEY_STORE_PASSWORD=OBF:1y0q1uvc1uum1uvg1pil1pjl1uuq1uvk1uuu1y10"})
 public class FProxyIT {
 
     static {
         System.setProperty("server.ssl.key-store-password",
                 Password.deobfuscate("OBF:1y0q1uvc1uum1uvg1pil1pjl1uuq1uvk1uuu1y10"));
+        System.setProperty("server.ssl.trust-store-password",
+                Password.deobfuscate("OBF:1y0q1uvc1uum1uvg1pil1pjl1uuq1uvk1uuu1y10"));
     }
 
     @Autowired
index 8943a09..651fa06 100644 (file)
@@ -26,7 +26,6 @@ import static org.springframework.test.web.client.match.MockRestRequestMatchers.
 import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
 import javax.servlet.http.Cookie;
 import org.eclipse.jetty.util.security.Password;
 import org.junit.Before;
@@ -54,6 +53,8 @@ public class FProxyServiceTest {
     static {
         System.setProperty("server.ssl.key-store-password",
                 Password.deobfuscate("OBF:1y0q1uvc1uum1uvg1pil1pjl1uuq1uvk1uuu1y10"));
+        System.setProperty("server.ssl.trust-store-password",
+                Password.deobfuscate("OBF:1y0q1uvc1uum1uvg1pil1pjl1uuq1uvk1uuu1y10"));
     }
 
     @Value("${transactionid.header.name}")