From e8c3685742892482c0a5492e16d61e1f417119d2 Mon Sep 17 00:00:00 2001 From: Abhishek Bajaj Date: Thu, 11 Mar 2021 18:34:35 +0530 Subject: security blocker in restconf collector Issue-ID: DCAEGEN2-2518 Signed-off-by: Abhishek Bajaj Change-Id: Id216e79c2bb616372f08201cf9e08f3caf003006 --- Changelog.md | 5 +- .../java/org/onap/dcae/common/RestapiCallNode.java | 86 ++++++++++++++++--- .../dcae/controller/PersistentEventConnection.java | 96 +++++++++++++++++----- version.properties | 2 +- 4 files changed, 155 insertions(+), 34 deletions(-) diff --git a/Changelog.md b/Changelog.md index ce33bf0..b2adf82 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [1.2.5] - 12/03/2021 +### Fixed +- [DCAEGEN2-2518](https://jira.onap.org/browse/DCAEGEN2-2518) - Fix the security blocker in restconf collector + ## [1.2.4] - 19/02/2021 ### Fixed - [DCAEGEN2-2641](https://jira.onap.org/browse/DCAEGEN2-2641) - Fix the RESTConf sonar report issue @@ -13,5 +17,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - [DCAEGEN2-2592](https://jira.onap.org/browse/DCAEGEN2-2592) - Honolulu Vulnerability updates - ## [1.2.2] - 15/12/2020 diff --git a/src/main/java/org/onap/dcae/common/RestapiCallNode.java b/src/main/java/org/onap/dcae/common/RestapiCallNode.java index 387fa98..4152db9 100755 --- a/src/main/java/org/onap/dcae/common/RestapiCallNode.java +++ b/src/main/java/org/onap/dcae/common/RestapiCallNode.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * org.onap.dcaegen2.collectors.restconf * ================================================================================ - * Copyright (C) 2018-2019 Huawei. All rights reserved. + * Copyright (C) 2018-2021 Huawei. 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. @@ -43,6 +43,7 @@ import java.net.SocketException; import java.nio.file.Files; import java.nio.file.Paths; import java.security.KeyStore; +import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.*; @@ -325,14 +326,21 @@ public class RestapiCallNode { ssl = createSSLContext(p); } if (ssl != null) { - HostnameVerifier hostnameVerifier = (hostname, session) -> true; - + // HostnameVerifier hostnameVerifier = (hostname, session) -> true; + HostnameVerifier hostnameVerifier = new HostnameVerifier() { + @Override + public boolean verify(String hostname,SSLSession session) { + HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier(); + return hv.verify(hostname, session); + } + }; + config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(hostnameVerifier, ssl)); } } else { - /* Create a trust manager that does not validate certificate chains */ + /* Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; @@ -344,20 +352,70 @@ public class RestapiCallNode { } }; - /* Install the all-trusting trust manager */ + Install the all-trusting trust manager SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); - /* Create all-trusting host name verifier */ + Create all-trusting host name verifier HostnameVerifier allHostsValid = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }; - /* Install the all-trusting host verifier*/ - HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); + Install the all-trusting host verifier + HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);*/ + + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + + //Using null here initialises the tmf with default trust store + tmf.init((KeyStore)null); + + //Get hold of default trust manager + X509TrustManager x509Tm = null; + for(TrustManager tm: tmf.getTrustManagers()) + { + if(tm instanceof X509TrustManager) { + x509Tm = (X509TrustManager) tm; + break; + } + } + + //Wrap it in your own class + final X509TrustManager finalTm = x509Tm; + X509TrustManager customTm = new X509TrustManager() { + + @Override + public X509Certificate[] getAcceptedIssuers() { + return finalTm.getAcceptedIssuers(); + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + finalTm.checkServerTrusted(chain, authType); + + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + finalTm.checkClientTrusted(chain, authType); + + }}; + + SSLContext sc = SSLContext.getInstance("TLS"); + sc.init(null,new TrustManager[]{customTm},new java.security.SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); + + HostnameVerifier hostnameverifier = new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier(); + return hv.verify(hostname, session); + + }}; + + HttpsURLConnection.setDefaultHostnameVerifier(hostnameverifier); } logProperties(config.getProperties()); @@ -448,8 +506,16 @@ public class RestapiCallNode { System.setProperty("javax.net.ssl.trustStore", p.trustStoreFileName); System.setProperty("javax.net.ssl.trustStorePassword", p.trustStorePassword); - HttpsURLConnection.setDefaultHostnameVerifier((string, ssls) -> true); - + // HttpsURLConnection.setDefaultHostnameVerifier((string, ssls) -> true); + HostnameVerifier hostnameVerifier = new HostnameVerifier() { + @Override + public boolean verify(String hostname,SSLSession session) { + HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier(); + return hv.verify(hostname, session); + } + }; + HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier); + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); KeyStore ks = KeyStore.getInstance("PKCS12"); char[] pwd = p.keyStorePassword.toCharArray(); diff --git a/src/main/java/org/onap/dcae/controller/PersistentEventConnection.java b/src/main/java/org/onap/dcae/controller/PersistentEventConnection.java index 7434fc2..3b16360 100644 --- a/src/main/java/org/onap/dcae/controller/PersistentEventConnection.java +++ b/src/main/java/org/onap/dcae/controller/PersistentEventConnection.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * org.onap.dcaegen2.collectors.restconf * ================================================================================ - * Copyright (C) 2018-2019 Huawei. All rights reserved. + * Copyright (C) 2018-2021 Huawei. 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. @@ -31,14 +31,19 @@ import org.onap.dcae.common.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.HttpHeaders; import java.security.KeyManagementException; +import java.security.KeyStore; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; @@ -260,7 +265,7 @@ public class PersistentEventConnection implements Runnable { log.info("SSE received url " + event_sseventsUrl); } - private EventSource OpenSseConnection() { + private EventSource OpenSseConnection() throws Exception { Parameters p = null; try { @@ -293,30 +298,77 @@ public class PersistentEventConnection implements Runnable { userName + ":" + password).getBytes()); } - private Client ignoreSslClient() { - SSLContext sslcontext = null; + private Client ignoreSslClient() throws Exception { + /* + * SSLContext sslcontext = null; + * + * try { sslcontext = SSLContext.getInstance("TLS"); sslcontext.init(null, new + * TrustManager[]{new X509TrustManager() { + * + * @Override public void checkClientTrusted(X509Certificate[] arg0, String arg1) + * throws CertificateException { } + * + * @Override public void checkServerTrusted(X509Certificate[] arg0, String arg1) + * throws CertificateException { } + * + * @Override public X509Certificate[] getAcceptedIssuers() { return new + * X509Certificate[0]; } }}, new java.security.SecureRandom()); } catch + * (NoSuchAlgorithmException | KeyManagementException e) { throw new + * IllegalStateException(e); } + * + * return + * ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier((s1, s2) + * -> true).build(); + */ + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + + //Using null here initialises the tmf with default trust store + tmf.init((KeyStore)null); + + //Get hold of default trust manager + X509TrustManager x509Tm = null; + for(TrustManager tm: tmf.getTrustManagers()) + { + if(tm instanceof X509TrustManager) { + x509Tm = (X509TrustManager) tm; + break; + } + } + + //Wrap it in your own class + final X509TrustManager finalTm = x509Tm; + X509TrustManager customTm = new X509TrustManager() { + + @Override + public X509Certificate[] getAcceptedIssuers() { + return finalTm.getAcceptedIssuers(); + } - try { - sslcontext = SSLContext.getInstance("TLS"); - sslcontext.init(null, new TrustManager[]{new X509TrustManager() { - @Override - public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { - } + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + finalTm.checkServerTrusted(chain, authType); - @Override - public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { - } + } - @Override - public X509Certificate[] getAcceptedIssuers() { - return new X509Certificate[0]; - } - }}, new java.security.SecureRandom()); - } catch (NoSuchAlgorithmException | KeyManagementException e) { - throw new IllegalStateException(e); - } + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + finalTm.checkClientTrusted(chain, authType); + + }}; + + SSLContext sc = SSLContext.getInstance("TLS"); + sc.init(null,new TrustManager[]{customTm},new java.security.SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); - return ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier((s1, s2) -> true).build(); + HostnameVerifier hostnameverifier = new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier(); + return hv.verify(hostname, session); + + }}; + + return ClientBuilder.newBuilder().sslContext(sc).hostnameVerifier(hostnameverifier).build(); } public String getEventRuleId() { diff --git a/version.properties b/version.properties index 1b6b05f..4fd02cd 100644 --- a/version.properties +++ b/version.properties @@ -1,6 +1,6 @@ major=1 minor=2 -patch=4 +patch=5 base_version=${major}.${minor}.${patch} release_version=${base_version} snapshot_version=${base_version}-SNAPSHOT -- cgit 1.2.3-korg