From 1940392a7dabd31a68d97155f58406cf71e5be36 Mon Sep 17 00:00:00 2001 From: Piotr Borelowski Date: Wed, 3 Jun 2020 17:01:27 +0200 Subject: [PATCH] Add a certificate in communication with VNFM Issue-ID: SO-2979 Signed-off-by: Piotr Borelowski Change-Id: I7fa13c9371b7789950af315b7772a0ee409cc34b --- adapters/etsi-sol002-adapter/pom.xml | 12 +++++ .../configuration/ApplicationConfiguration.java | 56 +++++++++++++++++++++ .../vevnfm/configuration/ConfigProperties.java | 29 +++++++++++ .../so/adapters/vevnfm/service/StartupService.java | 2 - .../src/main/resources/application.yaml | 14 ++++-- .../src/main/resources/certs/org.onap.so.trust.jks | Bin 0 -> 1413 bytes .../src/main/resources/certs/ve-vnfm-adapter.p12 | Bin 0 -> 4079 bytes 7 files changed, 107 insertions(+), 6 deletions(-) create mode 100644 adapters/etsi-sol002-adapter/src/main/resources/certs/org.onap.so.trust.jks create mode 100644 adapters/etsi-sol002-adapter/src/main/resources/certs/ve-vnfm-adapter.p12 diff --git a/adapters/etsi-sol002-adapter/pom.xml b/adapters/etsi-sol002-adapter/pom.xml index 81e35d896d..5dee8fe8e6 100644 --- a/adapters/etsi-sol002-adapter/pom.xml +++ b/adapters/etsi-sol002-adapter/pom.xml @@ -82,6 +82,18 @@ + + + ${basedir}/src/main/resources + + certs/* + + + + ${basedir}/src/main/resources/certs + false + + diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/configuration/ApplicationConfiguration.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/configuration/ApplicationConfiguration.java index 411572ff5b..38f7a0cd3f 100644 --- a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/configuration/ApplicationConfiguration.java +++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/configuration/ApplicationConfiguration.java @@ -20,17 +20,44 @@ package org.onap.so.adapters.vevnfm.configuration; +import java.io.IOException; +import java.security.*; +import java.security.cert.CertificateException; +import javax.net.ssl.SSLContext; +import org.apache.http.client.HttpClient; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.ssl.SSLContextBuilder; import org.onap.so.adapters.vevnfm.provider.AuthorizationHeadersProvider; import org.onap.so.configuration.rest.HttpHeadersProvider; import org.onap.so.rest.service.HttpRestServiceProvider; import org.onap.so.rest.service.HttpRestServiceProviderImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; +import org.springframework.http.client.BufferingClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; @Configuration public class ApplicationConfiguration { + private static final Logger logger = LoggerFactory.getLogger(ApplicationConfiguration.class); + + private final Resource clientKeyStore; + private final String clientKeyStorePassword; + private final Resource clientTrustStore; + private final String clientTrustStorePassword; + + public ApplicationConfiguration(final ConfigProperties configProperties) { + clientKeyStore = configProperties.getClientKeyStore(); + clientKeyStorePassword = configProperties.getClientKeyStorePassword(); + clientTrustStore = configProperties.getClientTrustStore(); + clientTrustStorePassword = configProperties.getClientTrustStorePassword(); + } + @Bean public AuthorizationHeadersProvider headersProvider() { return new AuthorizationHeadersProvider(); @@ -39,6 +66,35 @@ public class ApplicationConfiguration { @Bean public HttpRestServiceProvider restProvider(final RestTemplate restTemplate, final HttpHeadersProvider headersProvider) { + modify(restTemplate); return new HttpRestServiceProviderImpl(restTemplate, headersProvider); } + + private void modify(final RestTemplate restTemplate) { + + if (clientKeyStore == null || clientTrustStore == null) { + return; + } + + try { + final KeyStore keystore = KeyStore.getInstance("PKCS12"); + keystore.load(clientKeyStore.getInputStream(), clientKeyStorePassword.toCharArray()); + + final SSLContext sslContext = new SSLContextBuilder() + .loadTrustMaterial(clientTrustStore.getURL(), clientTrustStorePassword.toCharArray()) + .loadKeyMaterial(keystore, clientKeyStorePassword.toCharArray()).build(); + + logger.info("Setting truststore: {}", clientTrustStore.getURL()); + + final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext); + final HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).build(); + final HttpComponentsClientHttpRequestFactory factory = + new HttpComponentsClientHttpRequestFactory(httpClient); + + restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(factory)); + } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | CertificateException + | IOException | UnrecoverableKeyException e) { + logger.error("Error reading truststore, TLS connection to VNFM will fail.", e); + } + } } diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/configuration/ConfigProperties.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/configuration/ConfigProperties.java index d4ca5af0f2..a8a436ddc6 100644 --- a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/configuration/ConfigProperties.java +++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/configuration/ConfigProperties.java @@ -23,6 +23,7 @@ package org.onap.so.adapters.vevnfm.configuration; import org.onap.so.adapters.vevnfm.constant.NotificationVnfFilterType; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; @Configuration public class ConfigProperties { @@ -72,6 +73,18 @@ public class ConfigProperties { @Value("${spring.security.usercredentials[0].openpass}") private String springSecurityOpenpass; + @Value("${client.key-store:#{null}}") + private Resource clientKeyStore; + + @Value("${client.key-store-password:#{null}}") + private String clientKeyStorePassword; + + @Value("${client.trust-store:#{null}}") + private Resource clientTrustStore; + + @Value("${client.trust-store-password:#{null}}") + private String clientTrustStorePassword; + public String getVevnfmadapterVnfFilterJson() { return vevnfmadapterVnfFilterJson; } @@ -131,4 +144,20 @@ public class ConfigProperties { public String getSpringSecurityOpenpass() { return springSecurityOpenpass; } + + public Resource getClientKeyStore() { + return clientKeyStore; + } + + public String getClientKeyStorePassword() { + return clientKeyStorePassword; + } + + public Resource getClientTrustStore() { + return clientTrustStore; + } + + public String getClientTrustStorePassword() { + return clientTrustStorePassword; + } } diff --git a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/StartupService.java b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/StartupService.java index c128275e43..eba1d087c6 100644 --- a/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/StartupService.java +++ b/adapters/etsi-sol002-adapter/src/main/java/org/onap/so/adapters/vevnfm/service/StartupService.java @@ -28,7 +28,6 @@ import org.onap.so.adapters.vevnfm.configuration.ConfigProperties; import org.onap.so.adapters.vevnfm.exception.VeVnfmException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.EnableRetry; import org.springframework.retry.annotation.Recover; @@ -44,7 +43,6 @@ public class StartupService { private final String vnfmDefaultEndpoint; private final AaiConnection aaiConnection; - @Autowired public StartupService(final ConfigProperties configProperties, final AaiConnection aaiConnection) { this.vnfmDefaultEndpoint = configProperties.getVnfmDefaultEndpoint(); this.aaiConnection = aaiConnection; diff --git a/adapters/etsi-sol002-adapter/src/main/resources/application.yaml b/adapters/etsi-sol002-adapter/src/main/resources/application.yaml index c69c95187a..f5b6bc3158 100644 --- a/adapters/etsi-sol002-adapter/src/main/resources/application.yaml +++ b/adapters/etsi-sol002-adapter/src/main/resources/application.yaml @@ -19,17 +19,23 @@ server: vevnfmadapter: vnf-filter-json: '{notificationTypes:[VnfLcmOperationOccurrenceNotification],operationStates:[COMPLETED]}' - endpoint: http://so-ve-vnfm-adapter.onap:9098 + endpoint: http://so-ve-vnfm-adapter:9098 + +client: + key-store: classpath:ve-vnfm-adapter.p12 + key-store-password: 'ywsqCy:EEo#j}HJHM7z^Rk[L' + trust-store: classpath:org.onap.so.trust.jks + trust-store-password: ',sx#.C*W)]wVgJC6ccFHI#:H' mso: key: 07a7159d3bf51a0e53be7a8f89699be7 aai: - endpoint: https://aai.onap:30233 + endpoint: https://aai:30233 auth: 75C4483F9C05E2C33A8602635FA532397EC44AB667A2B64DED4FEE08DD932F2E3C1FEE vnfm: - default-endpoint: https://so-vnfm-simulator.onap:9093 + default-endpoint: https://so-vnfm-simulator:9093 subscription: /vnflcm/v1/subscriptions notification: /lcm/v1/vnf/instances/notifications @@ -37,7 +43,7 @@ notification: vnf-filter-type: NONE dmaap: - endpoint: http://message-router.onap:30227 + endpoint: http://message-router:30227 topic: /events/unauthenticated.DCAE_CL_OUTPUT closed-loop: control: diff --git a/adapters/etsi-sol002-adapter/src/main/resources/certs/org.onap.so.trust.jks b/adapters/etsi-sol002-adapter/src/main/resources/certs/org.onap.so.trust.jks new file mode 100644 index 0000000000000000000000000000000000000000..1f0d8a550a92bc44003e36b849884d5d8e013dc9 GIT binary patch literal 1413 zcmb7DYdF&j9RBa7<#DuzKJP^cnMcyF$&LM-5dstSt6 z9DB|uRR}~G0e~hrB&ebQqr#O{5YBEkHg-5wPX2| zKEwX!$fvP`O*!q?AI)?zl zq7E_=!b*KtGvB7d+XD2G$I7w_q6vq67DWRp+SS<89o=YAr)$#9*fn>obUHm`srkO` zwPOkH743qkP!(XS83Z3F_y*rFFy3q#8(*CrPY$h6O zro693AK+!7#;q`&xXt%QI_Z(_pJNqY4|xULIiUuHK>$eES&$CutVd7>2}i@Xx>4~< zj%yHZ3>jz)e$BVf(`I{#ml)Pu-tHki>qo%BxHtG zaXiyeQBW6pN-`Dn(%nfiIh5k7o z?ty7}k%QZa2fcK@GB2L&HtOPj%YIr3FAlvjvHeO!^6i4Vw)Ck}thU}LvDQcvM;-c~;@w15NnG3zCn40IjByPCi z;f|<8BdSAfOS|LI!4Q4OyWU2-ksPEfJnG%|_{_ti?tlr;CNaYL8$#;Jo+l?4SIXbYwp6+=jXLG!Z^grD2l(i SNV>823N+-{-VIXs7n8-fK)}{gY-v8LTYj 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