From 37cacbd89a7129e5736916627b25d0ecf0364947 Mon Sep 17 00:00:00 2001 From: MichaelMorris Date: Fri, 2 Aug 2019 23:20:31 +0000 Subject: [PATCH] VNFM adapter support two way TLS Change-Id: Icdb57587c9070bcce405eeaea4275fea0af0533a Issue-ID: SO-2190 Signed-off-by: MichaelMorris --- .../mso-vnfm-etsi-adapter/Readme.txt | 128 +++++++++++++++++++++ .../vnfmadapter/WebSecurityConfigImpl.java | 14 ++- .../vnfmadapter/extclients/vnfm/VnfmHelper.java | 2 + .../vnfm/VnfmServiceProviderConfiguration.java | 39 ++++--- .../rest/VnfmAdapterControllerTest.java | 2 +- bpmn/mso-infrastructure-bpmn/pom.xml | 18 +++ .../src/main/resources/org.onap.so.p12 | Bin 0 -> 4095 bytes .../src/main/resources/org.onap.so.trust.jks | Bin 0 -> 1413 bytes .../VnfmAdapterCreateVnfTaskConfiguration.java | 60 ++++++++++ .../svnfm/simulator/config/ApplicationConfig.java | 8 +- .../simulator/services/OperationProgressor.java | 35 +++++- 11 files changed, 281 insertions(+), 25 deletions(-) create mode 100644 adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/Readme.txt create mode 100644 bpmn/mso-infrastructure-bpmn/src/main/resources/org.onap.so.p12 create mode 100644 bpmn/mso-infrastructure-bpmn/src/main/resources/org.onap.so.trust.jks diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/Readme.txt b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/Readme.txt new file mode 100644 index 0000000000..66876311db --- /dev/null +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/Readme.txt @@ -0,0 +1,128 @@ +The following describes how to configure authentication for the VNFM adapter. + + +========================================== +To confgure TLS +========================================== + +--------------- +VNFM Adapter +--------------- +The following parameters can be set to configure the certificate for the VNFM adapter +server: + ssl: + key-alias: so@so.onap.org + key--store-password: 'I,re7WWEJR$e]x370wRgx?qE' + key-store: classpath:org.onap.so.p12 + key-store-type: PKCS12 +The values shown above relate to the certificate included in the VNFM adapter jar which has been generated from AAF. If a different certificate is to be used then these values should be changed accordingly. + +The following paramters can be set to configure the trust store for the VNFM adapter: +http: + client: + ssl: + trust-store: org.onap.so.trust.jks + trust-store-password: NyRD](z:EJJNIt?},QgM3o7H +The values shown above relate to the trust store included in the VNFM adapter jar which has been generated from AAI. If a different trust store is to be used then these values should be changed accordingly. + +Ensure the value for the below parameter uses https instead of http +vnfmadapter: + endpoint: http://so-vnfm-adapter.onap:9092 + +--------------- +bpmn-infra +--------------- +For bpmn-infra, ensure the value for the below parameter uses https instead of http +so: + vnfm: + adapter: + url: https://so-vnfm-adapter.onap:9092/so/vnfm-adapter/v1/ + + +========================================== +To use two way TLS +========================================== + +Ensure the value for username and password are empty in the AAI entry for the VNFM (The VNFM adapter will use oauth instead of two way TLS if the username/password is set). +Ensure TLS has been configuered as detailed above. + +--------------- +VNFM adapter +--------------- +Set the following parameter for the VNFM adapter: +server: + ssl: + client-auth: need + +--------------- +bpmn-infra: +--------------- +Set the following paramters for bpmn-infra: +rest: + http: + client: + configuration: + ssl: + keyStore: classpath:org.onap.so.p12 + keyStorePassword: 'RLe5ExMWW;Kd6GTSt0WQz;.Y' + trustStore: classpath:org.onap.so.trust.jks + trustStorePassword: '6V%8oSU$,%WbYp3IUe;^mWt4' +Ensure the value for the below parameter uses https instead of http +so: + vnfm: + adapter: + url: https://so-vnfm-adapter.onap:9092/so/vnfm-adapter/v1/ + +--------------- +VNFM simulator: +--------------- +Set the following parameters for the VNFM simulator (if used): +server: + ssl: + client-auth: need + request: + grant: + auth: twowaytls + +========================================== +To use oauth token base authentication +========================================== + +--------------- +VNFM adapter: +--------------- +Ensure the value for username and password set set in the AAI entry for the VNFM. The VNFM adapter will use this username/password as the client credentials in the request for a token for the VNFM. The token endpoint +for the VNFM will by default will be derived from the service url for the VNFM in AAI as follows: /oauth/token, e.g. if the service url is https://so-vnfm-simulator.onap/vnflcm/v1 then the token url will +be taken to be https://so-vnfm-simulator.onap/oauth/token. This can be overriden using the following parameter for the VNFM adapter: +vnfmadapter: + temp: + vnfm: + oauth: + endpoint: + +The VNFM adapter exposes a token point at url: https://:/oauth/token e.g. https://so-vnfm-adapter.onap:9092/oauth/token. The VNFM can request a token from this endpoint for use in grant requests and notifications +to the VNFM adapter. The username/password to be used in the token request are passed to the VNFM in a subscription request. The username/password sent by the VNFM adpater in the subscription request can be configuered using the +following parameter: +vnfmadapter: + auth: +where is ':' encoded using org.onap.so.utils.CryptoUtils with the key set by the paramter: +mso: + key: +The default username:password is vnfm-adapter:123456 when vnfm-adapter.auth is not set. + +--------------- +VNFM simulator: +--------------- +Set the following parameters for the simulator: +spring: + profiles: + active: oauth-authentication +server: + request: + grant: + auth: oauth + +========================================== +To use basic auth for notifications +========================================== +The same username/password is used as for oauth token requests as describe above and passed to the VNFM in the subscription request. \ No newline at end of file diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/WebSecurityConfigImpl.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/WebSecurityConfigImpl.java index 2b33e8b11d..f45d5a0219 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/WebSecurityConfigImpl.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/WebSecurityConfigImpl.java @@ -22,6 +22,7 @@ package org.onap.so.adapters.vnfmadapter; import org.onap.so.security.MSOSpringFirewall; import org.onap.so.security.WebSecurityConfig; +import org.springframework.beans.factory.annotation.Value; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; @@ -34,11 +35,18 @@ import org.springframework.util.StringUtils; @EnableWebSecurity public class WebSecurityConfigImpl extends WebSecurityConfig { + @Value("${server.ssl.client-auth:none}") + private String clientAuth; + @Override protected void configure(final HttpSecurity http) throws Exception { - http.csrf().disable().authorizeRequests().antMatchers("/manage/health", "/manage/info").permitAll() - .antMatchers("/**").hasAnyRole(StringUtils.collectionToDelimitedString(getRoles(), ",")).and() - .httpBasic(); + if (clientAuth.equalsIgnoreCase("need")) { + http.csrf().disable().authorizeRequests().anyRequest().permitAll(); + } else { + http.csrf().disable().authorizeRequests().antMatchers("/manage/health", "/manage/info").permitAll() + .antMatchers("/**").hasAnyRole(StringUtils.collectionToDelimitedString(getRoles(), ",")).and() + .httpBasic(); + } } @Override diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmHelper.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmHelper.java index b4355efc20..7c22020287 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmHelper.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmHelper.java @@ -212,6 +212,8 @@ public class VnfmHelper { basicAuthParams.setPassword(decrypedAuth[1]); authentication.addAuthTypeItem(AuthTypeEnum.BASIC); authentication.paramsBasic(basicAuthParams); + + authentication.addAuthTypeItem(AuthTypeEnum.TLS_CERT); return authentication; } diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmServiceProviderConfiguration.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmServiceProviderConfiguration.java index a604f9a6b9..93312cfa64 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmServiceProviderConfiguration.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/vnfm/VnfmServiceProviderConfiguration.java @@ -24,11 +24,12 @@ import static org.onap.so.client.RestTemplateConfig.CONFIGURABLE_REST_TEMPLATE; import com.google.gson.Gson; import java.io.IOException; import java.security.KeyManagementException; +import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.util.Iterator; -import java.util.ListIterator; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -42,7 +43,6 @@ import org.onap.aai.domain.yang.EsrSystemInfo; import org.onap.aai.domain.yang.EsrVnfm; import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.JSON; import org.onap.so.configuration.rest.BasicHttpHeadersProvider; -import org.onap.so.logging.jaxrs.filter.SpringClientFilter; import org.onap.so.rest.service.HttpRestServiceProvider; import org.onap.so.rest.service.HttpRestServiceProviderImpl; import org.slf4j.Logger; @@ -52,7 +52,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; -import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.http.client.BufferingClientHttpRequestFactory; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.GsonHttpMessageConverter; @@ -73,7 +73,12 @@ public class VnfmServiceProviderConfiguration { @Value("${http.client.ssl.trust-store:#{null}}") private Resource trustStore; @Value("${http.client.ssl.trust-store-password:#{null}}") - private String trustPassword; + private String trustStorePassword; + + @Value("${server.ssl.key-store:#{null}}") + private Resource keyStoreResource; + @Value("${server.ssl.key--store-password:#{null}}") + private String keyStorePassword; /** * This property is only intended to be temporary until the AAI schema is updated to support setting the endpoint @@ -98,7 +103,6 @@ public class VnfmServiceProviderConfiguration { if (trustStore != null) { setTrustStore(restTemplate); } - removeSpringClientFilter(restTemplate); return new HttpRestServiceProviderImpl(restTemplate, new BasicHttpHeadersProvider()); } @@ -141,27 +145,26 @@ public class VnfmServiceProviderConfiguration { private void setTrustStore(final RestTemplate restTemplate) { SSLContext sslContext; try { - sslContext = - new SSLContextBuilder().loadTrustMaterial(trustStore.getURL(), trustPassword.toCharArray()).build(); + if (keyStoreResource != null) { + KeyStore keystore = KeyStore.getInstance("pkcs12"); + keystore.load(keyStoreResource.getInputStream(), keyStorePassword.toCharArray()); + sslContext = + new SSLContextBuilder().loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray()) + .loadKeyMaterial(keystore, keyStorePassword.toCharArray()).build(); + } else { + sslContext = new SSLContextBuilder() + .loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray()).build(); + } logger.info("Setting truststore: {}", trustStore.getURL()); final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext); final HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).build(); final HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); - restTemplate.setRequestFactory(factory); + restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(factory)); } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | CertificateException - | IOException exception) { + | IOException | UnrecoverableKeyException exception) { logger.error("Error reading truststore, TLS connection to VNFM will fail.", exception); } } - private void removeSpringClientFilter(final RestTemplate restTemplate) { - ListIterator interceptorIterator = restTemplate.getInterceptors().listIterator(); - while (interceptorIterator.hasNext()) { - if (interceptorIterator.next() instanceof SpringClientFilter) { - interceptorIterator.remove(); - } - } - } - } diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/test/java/org/onap/so/adapters/vnfmadapter/rest/VnfmAdapterControllerTest.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/test/java/org/onap/so/adapters/vnfmadapter/rest/VnfmAdapterControllerTest.java index 6cdabb9374..fe55907420 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/test/java/org/onap/so/adapters/vnfmadapter/rest/VnfmAdapterControllerTest.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/test/java/org/onap/so/adapters/vnfmadapter/rest/VnfmAdapterControllerTest.java @@ -133,7 +133,7 @@ public class VnfmAdapterControllerTest { setUpVimInMockAai(); final String expectedsubscriptionRequest = - "{\"filter\":{\"vnfInstanceSubscriptionFilter\":{\"vnfInstanceIds\":[\"vnfId\"]},\"notificationTypes\":[\"VnfLcmOperationOccurrenceNotification\"]},\"callbackUri\":\"https://so-vnfm-adapter.onap:30406/so/vnfm-adapter/v1/lcn/VnfLcmOperationOccurrenceNotification\",\"authentication\":{\"authType\":[\"OAUTH2_CLIENT_CREDENTIALS\", \"BASIC\"],\"paramsOauth2ClientCredentials\":{\"clientId\":\"vnfm\",\"clientPassword\":\"password1$\",\"tokenEndpoint\":\"https://so-vnfm-adapter.onap:30406/oauth/token\"},\"paramsBasic\":{\"userName\":\"vnfm\",\"password\":\"password1$\"}}}"; + "{\"filter\":{\"vnfInstanceSubscriptionFilter\":{\"vnfInstanceIds\":[\"vnfId\"]},\"notificationTypes\":[\"VnfLcmOperationOccurrenceNotification\"]},\"callbackUri\":\"https://so-vnfm-adapter.onap:30406/so/vnfm-adapter/v1/lcn/VnfLcmOperationOccurrenceNotification\",\"authentication\":{\"authType\":[\"OAUTH2_CLIENT_CREDENTIALS\", \"BASIC\", \"TLS_CERT\"],\"paramsOauth2ClientCredentials\":{\"clientId\":\"vnfm\",\"clientPassword\":\"password1$\",\"tokenEndpoint\":\"https://so-vnfm-adapter.onap:30406/oauth/token\"},\"paramsBasic\":{\"userName\":\"vnfm\",\"password\":\"password1$\"}}}"; final InlineResponse2001 subscriptionResponse = new InlineResponse2001(); final InlineResponse201 createResponse = createCreateResponse(); diff --git a/bpmn/mso-infrastructure-bpmn/pom.xml b/bpmn/mso-infrastructure-bpmn/pom.xml index ea1a205317..25913eabba 100644 --- a/bpmn/mso-infrastructure-bpmn/pom.xml +++ b/bpmn/mso-infrastructure-bpmn/pom.xml @@ -134,6 +134,24 @@ + + + src/main/resources + true + + **/*.p12 + **/*.jks + + + + src/main/resources + false + + **/*.p12 + **/*.jks + + + diff --git a/bpmn/mso-infrastructure-bpmn/src/main/resources/org.onap.so.p12 b/bpmn/mso-infrastructure-bpmn/src/main/resources/org.onap.so.p12 new file mode 100644 index 0000000000000000000000000000000000000000..79631bf344f4bd98d341431bde7c03ffb276aead GIT binary patch literal 4095 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 literal 0 HcmV?d00001 diff --git a/bpmn/mso-infrastructure-bpmn/src/main/resources/org.onap.so.trust.jks b/bpmn/mso-infrastructure-bpmn/src/main/resources/org.onap.so.trust.jks new file mode 100644 index 0000000000000000000000000000000000000000..6f8168d89638401de4b77dba7cf562dce531a4c4 GIT binary patch literal 1413 zcmb7DYdF&j9NtyOWm{6STteim9qK=8HAQ10$0ekhP^`j|NFBL9W2Y@dZn>4YAHs^o zTw=pg?rU<=$%DMXEXUoDY3CU(Sc$^FHtUd!OI)`|!SsS;Z^}1cIy&_&chc zrTYelo}~x-0_#$+n-EbBf_v^E0_GqPoC2`mhXEGUxEKlnLmqN`HoaOg6#b99WWdOWkFCNfCW*3upnSihk1p)dVM_| z6SCt`CgY(_UXVS;-M~xxl;F!sY*hod$(~A4M6Xzpo+r2ZFbZeUP^((!Jh1JA%ACer z?!0PmBKG`>33sm3i7RSpVT7rVc{mLw7- zeTM?hQBGqAnsSBLA5Z(I$#9ec|7;UaY04i5_s{SQ+fYtEE!+gnj5L>89(HCwPsABh zMjc`#hL`%SX1z;;wFT;@jFx2=#1L(K7rOh^bgHqZMV;vGcDLl4acdsf@u`f^rRE2= z*N!E6R0;*rDc3tQ*HHcf`AgRk{tf-gM^qjd`Xs=wL0Zzk2(zIyl)j|a; z|C5%hI9N$K4$0k`JoaIzcc?d)$d8k2&^{pxq=cF{)jLR<5gpN0gR8C!ec9kJNb-RR z(S0f8a5P=58u1%H+X{1@X*oJ?O!EvY94}54Hrjb<0+OuKx8mMH{5?jW$4*{+Fe6GYO}a z`o0!@ke7`bv&6LHH{Ty_r$>2wj#GX!=p9&oLLCAHgTQ5H0Xm?&9zk6s3=P}rP9-ck z&Pd((osqXYvG|zzceB3&dK+s)7zRMc|F;3PVbB1B*I;k}x()zxLqKf^u=Rp)evILI zE7oHO29fo87`2f_&UIw1K)Qv<^mtGArXYn~9dRNt#E`I8vYa;z&5KaFxT>x~MrLXk zComnmeZ`qtwB!qU{46$Qk9SV{+^WLZpjAJFA)F%@xL$fXY_@dyeQj6CY(Ljg9FY6r zK9HUtHL#6z$XoX-^Ww=);|}h(oM(4o#bH+_wqJ=%xl?e@mR|P7p>LqB!^gI&q|jR< ztAAHb{97w=mzk_S>=L`7wV9;<_=YUai2cenRh=AJTvV|nc^(-veW51}Q}cqC%#9E{ z+7X>(Om(Pj5jq|n2sHpN_B7fJ=OSehNgs(1wO|cS*s=Sw#Ig9LXU_2w?#!`qknX*bg{yu|(-;OzXK3UgZJuit zmjCfYoOJT?gGy%~BWcpk*4rznJKem=ah;qQv!5~=D8WY*uH@$1?P!CpYZDjT{7(k5 ztt3-q=C?B`G>a`CFtG|po`lafJf2=g6ze=3i@Az=i{2jlhCBc4#d#gga1LKy86*?! SL@6=_Huy#0?VdkvG5-M7Gh(R# literal 0 HcmV?d00001 diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/vnfm/tasks/VnfmAdapterCreateVnfTaskConfiguration.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/vnfm/tasks/VnfmAdapterCreateVnfTaskConfiguration.java index f5bae2c82a..c3c0047fff 100644 --- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/vnfm/tasks/VnfmAdapterCreateVnfTaskConfiguration.java +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/vnfm/tasks/VnfmAdapterCreateVnfTaskConfiguration.java @@ -21,14 +21,32 @@ package org.onap.so.bpmn.infrastructure.adapter.vnfm.tasks; import static org.onap.so.client.RestTemplateConfig.CONFIGURABLE_REST_TEMPLATE; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +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.configuration.rest.BasicHttpHeadersProvider; 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.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; 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; /** @@ -40,13 +58,55 @@ import org.springframework.web.client.RestTemplate; @Configuration public class VnfmAdapterCreateVnfTaskConfiguration { + private static final Logger logger = LoggerFactory.getLogger(VnfmAdapterCreateVnfTaskConfiguration.class); + + @Value("${rest.http.client.configuration.ssl.trustStore:#{null}}") + private Resource trustStore; + + @Value("${rest.http.client.configuration.ssl.trustStorePassword:#{null}}") + private String trustStorePassword; + + @Value("${rest.http.client.configuration.ssl.keyStore:#{null}}") + private Resource keyStoreResource; + + @Value("${rest.http.client.configuration.ssl.keyStorePassword:#{null}}") + private String keyStorePassword; + @Bean public HttpRestServiceProvider databaseHttpRestServiceProvider( @Qualifier(CONFIGURABLE_REST_TEMPLATE) @Autowired final RestTemplate restTemplate, @Autowired final VnfmBasicHttpConfigProvider etsiVnfmAdapter) { + if (trustStore != null) { + setTrustStore(restTemplate); + } return getHttpRestServiceProvider(restTemplate, new BasicHttpHeadersProvider(etsiVnfmAdapter.getAuth())); } + private void setTrustStore(final RestTemplate restTemplate) { + SSLContext sslContext; + try { + if (keyStoreResource != null) { + KeyStore keystore = KeyStore.getInstance("pkcs12"); + keystore.load(keyStoreResource.getInputStream(), keyStorePassword.toCharArray()); + sslContext = + new SSLContextBuilder().loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray()) + .loadKeyMaterial(keystore, keyStorePassword.toCharArray()).build(); + } else { + sslContext = new SSLContextBuilder() + .loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray()).build(); + } + logger.info("Setting truststore: {}", trustStore.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 exception) { + logger.error("Error reading truststore, TLS connection to VNFM will fail.", exception); + } + } + private HttpRestServiceProvider getHttpRestServiceProvider(final RestTemplate restTemplate, final HttpHeadersProvider httpHeadersProvider) { return new HttpRestServiceProviderImpl(restTemplate, httpHeadersProvider); diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/config/ApplicationConfig.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/config/ApplicationConfig.java index 32c05ebca8..a1abb05f07 100644 --- a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/config/ApplicationConfig.java +++ b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/config/ApplicationConfig.java @@ -1,6 +1,5 @@ package org.onap.svnfm.simulator.config; -import java.net.InetAddress; import java.util.Arrays; import org.onap.svnfm.simulator.constants.Constant; import org.springframework.beans.factory.annotation.Autowired; @@ -23,6 +22,9 @@ public class ApplicationConfig implements ApplicationRunner { @Value("${server.dns.name:so-vnfm-simulator.onap}") private String serverDnsName; + @Value("${server.request.grant.auth:oauth}") + private String grantAuth; + @Autowired private Environment environment; @@ -37,6 +39,10 @@ public class ApplicationConfig implements ApplicationRunner { return baseUrl; } + public String getGrantAuth() { + return grantAuth; + } + @Bean public CacheManager cacheManager() { final Cache inlineResponse201 = new ConcurrentMapCache(Constant.IN_LINE_RESPONSE_201_CACHE); diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/OperationProgressor.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/OperationProgressor.java index eed62780c0..6e9478bdeb 100644 --- a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/OperationProgressor.java +++ b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/OperationProgressor.java @@ -8,10 +8,17 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.nio.charset.StandardCharsets; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.List; import java.util.UUID; import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; import javax.ws.rs.core.MediaType; import org.apache.commons.codec.binary.Base64; import org.modelmapper.ModelMapper; @@ -44,12 +51,16 @@ import org.onap.svnfm.simulator.repository.VnfOperationRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; public abstract class OperationProgressor implements Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(OperationProgressor.class); private static final String CERTIFICATE_TO_TRUST = "so-vnfm-adapter.crt.pem"; + private Resource keyStoreResource = new ClassPathResource("so-vnfm-simulator.p12"); + private String keyStorePassword = "7Em3&j4.19xYiMelhD5?xbQ."; + protected final VnfOperation operation; protected final SvnfmService svnfmService; private final VnfOperationRepository vnfOperationRepository; @@ -73,12 +84,14 @@ public abstract class OperationProgressor implements Runnable { String callBackUrl = subscriptionService.getSubscriptions().iterator().next().getCallbackUri(); callBackUrl = callBackUrl.substring(0, callBackUrl.indexOf("/lcn/")); apiClient.setBasePath(callBackUrl); + apiClient.setKeyManagers(getKeyManagers()); apiClient.setSslCaCert(getCertificateToTrust()); notificationClient = new DefaultApi(apiClient); final org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.ApiClient grantApiClient = new org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.ApiClient(); grantApiClient.setBasePath(callBackUrl); + grantApiClient.setKeyManagers(getKeyManagers()); grantApiClient.setSslCaCert(getCertificateToTrust()); grantClient = new org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.api.DefaultApi(grantApiClient); } @@ -92,6 +105,22 @@ public abstract class OperationProgressor implements Runnable { } } + private KeyManager[] getKeyManagers() { + KeyStore keystore; + try { + keystore = KeyStore.getInstance("pkcs12"); + keystore.load(keyStoreResource.getInputStream(), keyStorePassword.toCharArray()); + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); + keyManagerFactory.init(keystore, keyStorePassword.toCharArray()); + return keyManagerFactory.getKeyManagers(); + } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException + | UnrecoverableKeyException exception) { + LOGGER.error("Error reading certificate, https calls using two way TLS to VNFM adapter will fail", + exception); + return new KeyManager[0]; + } + } + @Override public void run() { try { @@ -247,8 +276,10 @@ public abstract class OperationProgressor implements Runnable { final SubscriptionsAuthenticationParamsOauth2ClientCredentials subscriptionAuthentication = subscriptionService.getSubscriptions().iterator().next().getAuthentication() .getParamsOauth2ClientCredentials(); - final String authHeader = - "Bearer " + getToken(notificationClient.getApiClient(), subscriptionAuthentication); + + final String authHeader = applicationConfig.getGrantAuth().equals("oauth") + ? "Bearer " + getToken(notificationClient.getApiClient(), subscriptionAuthentication) + : null; final ApiResponse response = grantClient.grantsPostWithHttpInfo(grantRequest, MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, authHeader); -- 2.16.6