diff options
author | Michal Jagiello <michal.jagiello@t-mobile.pl> | 2020-05-28 10:49:20 +0000 |
---|---|---|
committer | Michal Jagiello <michal.jagiello@t-mobile.pl> | 2020-07-13 10:06:02 +0000 |
commit | 8ac3e42050884ef8d5e9bcf8a7083b01350a134a (patch) | |
tree | 7e4bf71411e3344ce26a606456723b2a4fc1ea01 /common | |
parent | c919ee261f665b824e716e77b5cc358ec15e44a9 (diff) |
CDS client gRPC SSL/TLS support
Issue-ID: SO-3003
Change-Id: Id9150c7da5c29fc0854ebaf13d845adf89fc60ff
Signed-off-by: Michal Jagiello <michal.jagiello@t-mobile.pl>
Diffstat (limited to 'common')
7 files changed, 103 insertions, 35 deletions
diff --git a/common/pom.xml b/common/pom.xml index 08dfc4d905..6b54ad0e43 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -1,4 +1,4 @@ -<?xml version="1.0"?> +<?xml version="1.0" ?> <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"> <modelVersion>4.0.0</modelVersion> @@ -354,4 +354,4 @@ </plugin> </plugins> </build> -</project> +</project>
\ No newline at end of file diff --git a/common/src/main/java/org/onap/so/client/KeyStoreLoader.java b/common/src/main/java/org/onap/so/client/KeyStoreLoader.java new file mode 100644 index 0000000000..8279be8635 --- /dev/null +++ b/common/src/main/java/org/onap/so/client/KeyStoreLoader.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2020 Deutsche Telekom. + * ================================================================================ + * 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.so.client; + +import java.io.FileInputStream; +import java.nio.file.Paths; +import java.security.KeyStore; + +public abstract class KeyStoreLoader { + + static final String SSL_KEY_STORE_KEY = "javax.net.ssl.keyStore"; + + static public KeyStore getKeyStore() { + KeyStore ks = null; + final char[] password = getSSlKeyStorePassword().toCharArray(); + try (FileInputStream fis = + new FileInputStream(Paths.get(System.getProperty(SSL_KEY_STORE_KEY)).normalize().toString())) { + ks = KeyStore.getInstance(KeyStore.getDefaultType()); + ks.load(fis, password); + } catch (final Exception e) { + return null; + } + + return ks; + } + + static public String getSSlKeyStorePassword() { + return System.getProperty("javax.net.ssl.keyStorePassword"); + } +} diff --git a/common/src/main/java/org/onap/so/client/RestClientSSL.java b/common/src/main/java/org/onap/so/client/RestClientSSL.java index f5737b862c..1e8953892e 100644 --- a/common/src/main/java/org/onap/so/client/RestClientSSL.java +++ b/common/src/main/java/org/onap/so/client/RestClientSSL.java @@ -20,9 +20,7 @@ package org.onap.so.client; -import java.io.FileInputStream; import java.net.URI; -import java.nio.file.Paths; import java.security.KeyStore; import java.security.NoSuchAlgorithmException; import java.util.Optional; @@ -33,10 +31,8 @@ import javax.ws.rs.client.ClientBuilder; public abstract class RestClientSSL extends RestClient { private static final String TRUE = "true"; - private static final String SSL_KEY_STORE_KEY = "javax.net.ssl.keyStore"; private static final String MSO_LOAD_SSL_CLIENT_KEYSTORE_KEY = "mso.load.ssl.client.keystore"; - protected RestClientSSL(RestProperties props, Optional<URI> path) { super(props, path); } @@ -52,9 +48,9 @@ public abstract class RestClientSSL extends RestClient { try { String loadSSLKeyStore = System.getProperty(RestClientSSL.MSO_LOAD_SSL_CLIENT_KEYSTORE_KEY); if (loadSSLKeyStore != null && loadSSLKeyStore.equalsIgnoreCase(TRUE)) { - KeyStore ks = getKeyStore(); + KeyStore ks = KeyStoreLoader.getKeyStore(); if (ks != null) { - client = ClientBuilder.newBuilder().keyStore(ks, getSSlKeyStorePassword()).build(); + client = ClientBuilder.newBuilder().keyStore(ks, KeyStoreLoader.getSSlKeyStorePassword()).build(); logger.info("RestClientSSL not using default SSL context - setting keystore here."); return client; } @@ -67,23 +63,4 @@ public abstract class RestClientSSL extends RestClient { } return client; } - - private KeyStore getKeyStore() { - KeyStore ks = null; - char[] password = getSSlKeyStorePassword().toCharArray(); - try (FileInputStream fis = new FileInputStream( - Paths.get(System.getProperty(RestClientSSL.SSL_KEY_STORE_KEY)).normalize().toString())) { - ks = KeyStore.getInstance(KeyStore.getDefaultType()); - - ks.load(fis, password); - } catch (Exception e) { - return null; - } - - return ks; - } - - private String getSSlKeyStorePassword() { - return System.getProperty("javax.net.ssl.keyStorePassword"); - } } diff --git a/common/src/main/java/org/onap/so/client/cds/CDSProcessingClient.java b/common/src/main/java/org/onap/so/client/cds/CDSProcessingClient.java index 7ef158996d..fa309b54fe 100644 --- a/common/src/main/java/org/onap/so/client/cds/CDSProcessingClient.java +++ b/common/src/main/java/org/onap/so/client/cds/CDSProcessingClient.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP - SO * ================================================================================ - * Copyright (C) 2017 - 2019 Bell Canada. + * Copyright (C) 2017 - 2019 Bell Canada, Deutsche Telekom. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,9 +23,16 @@ package org.onap.so.client.cds; import io.grpc.ManagedChannel; import io.grpc.internal.DnsNameResolverProvider; import io.grpc.internal.PickFirstLoadBalancerProvider; +import io.grpc.netty.GrpcSslContexts; import io.grpc.netty.NettyChannelBuilder; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; import java.util.concurrent.CountDownLatch; +import javax.net.ssl.SSLException; +import javax.net.ssl.TrustManagerFactory; import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceInput; +import org.onap.so.client.KeyStoreLoader; import org.onap.so.client.PreconditionFailedException; import org.onap.so.client.RestPropertiesLoader; import org.slf4j.Logger; @@ -73,10 +80,36 @@ public class CDSProcessingClient implements AutoCloseable { throw new PreconditionFailedException( "No RestProperty.CDSProperties implementation found on classpath, can't create client."); } - this.channel = NettyChannelBuilder.forAddress(props.getHost(), props.getPort()) + NettyChannelBuilder builder = NettyChannelBuilder.forAddress(props.getHost(), props.getPort()) .nameResolverFactory(new DnsNameResolverProvider()) - .loadBalancerFactory(new PickFirstLoadBalancerProvider()) - .intercept(new BasicAuthClientInterceptor(props)).usePlaintext().build(); + .loadBalancerFactory(new PickFirstLoadBalancerProvider()); + if (props.getUseSSL()) { + log.info("Configure SSL connection"); + KeyStore ks = KeyStoreLoader.getKeyStore(); + if (ks == null) { + log.error("Can't load KeyStore"); + throw new RuntimeException("Can't load KeyStore to create secure channel"); + } + try { + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(ks); + builder.sslContext(GrpcSslContexts.forClient().trustManager(tmf).build()); + } catch (NoSuchAlgorithmException e) { + log.error("Can't get default TrustManager algorithm"); + throw new RuntimeException(e); + } catch (KeyStoreException e) { + log.error("TrustManagerFactory initialization failed"); + throw new RuntimeException(e); + } catch (SSLException e) { + log.error("SslContext build error"); + throw new RuntimeException(e); + } + } + if (props.getUseBasicAuth()) { + log.info("Configure Basic authentication"); + builder.intercept(new BasicAuthClientInterceptor(props)).usePlaintext(); + } + this.channel = builder.build(); this.handler = new CDSProcessingHandler(listener); log.info("CDSProcessingClient started"); } diff --git a/common/src/main/java/org/onap/so/client/cds/CDSProperties.java b/common/src/main/java/org/onap/so/client/cds/CDSProperties.java index 37a5c0bc18..db566fa3de 100644 --- a/common/src/main/java/org/onap/so/client/cds/CDSProperties.java +++ b/common/src/main/java/org/onap/so/client/cds/CDSProperties.java @@ -22,7 +22,6 @@ package org.onap.so.client.cds; import org.onap.so.client.RestProperties; - public interface CDSProperties extends RestProperties { String getHost(); @@ -32,4 +31,8 @@ public interface CDSProperties extends RestProperties { String getBasicAuth(); int getTimeout(); + + boolean getUseSSL(); + + boolean getUseBasicAuth(); } diff --git a/common/src/test/java/org/onap/so/client/cds/CDSProcessingClientTest.java b/common/src/test/java/org/onap/so/client/cds/CDSProcessingClientTest.java index 18ec9efa50..5792c28f5f 100644 --- a/common/src/test/java/org/onap/so/client/cds/CDSProcessingClientTest.java +++ b/common/src/test/java/org/onap/so/client/cds/CDSProcessingClientTest.java @@ -20,7 +20,6 @@ package org.onap.so.client.cds; - import static org.junit.Assert.*; import static org.mockito.Mockito.*; import io.grpc.inprocess.InProcessChannelBuilder; @@ -58,7 +57,6 @@ public class CDSProcessingClientTest { private CDSProcessingHandler handler; private CDSProcessingClient client; - private final MutableHandlerRegistry serviceRegistry = new MutableHandlerRegistry(); private final List<String> messagesDelivered = new ArrayList<>(); private final CountDownLatch allRequestsDelivered = new CountDownLatch(1); @@ -115,7 +113,6 @@ public class CDSProcessingClientTest { new CDSProcessingClient(listener); } - @Test public void testSendMessageFail() throws Exception { diff --git a/common/src/test/java/org/onap/so/client/cds/TestCDSPropertiesImpl.java b/common/src/test/java/org/onap/so/client/cds/TestCDSPropertiesImpl.java index 2834d37f1f..41238e539e 100644 --- a/common/src/test/java/org/onap/so/client/cds/TestCDSPropertiesImpl.java +++ b/common/src/test/java/org/onap/so/client/cds/TestCDSPropertiesImpl.java @@ -72,4 +72,14 @@ public class TestCDSPropertiesImpl implements CDSProperties { public int getTimeout() { return 60; } + + @Override + public boolean getUseSSL() { + return false; + } + + @Override + public boolean getUseBasicAuth() { + return true; + } } |