From e2e71040679fc6f305f9cdbe0d9d38c701934dcd Mon Sep 17 00:00:00 2001 From: sebdet Date: Mon, 19 Apr 2021 14:46:45 +0200 Subject: Fix Sonar Crypto issues Fix this problem by removing the CryptoUtils that could be replaced by AAF cadi call (this was already in place in the code). The OOM sdc controller password will have to be modified as well. Issue-ID: POLICY-3201 Issue-ID: POLICY-3200 Change-Id: I6dfd9abb691afb3548d4e68c8759351ad02a30da Signed-off-by: sebdet --- .../org/onap/policy/clamp/clds/Application.java | 2 +- .../config/sdc/SdcControllersConfiguration.java | 27 ++-- .../sdc/SdcSingleControllerConfiguration.java | 54 +++---- .../onap/policy/clamp/clds/util/CryptoUtils.java | 168 --------------------- .../policy/clamp/clds/util/ResourceFileUtils.java | 8 +- .../org/onap/policy/clamp/util/PassDecoder.java | 10 +- 6 files changed, 46 insertions(+), 223 deletions(-) delete mode 100644 src/main/java/org/onap/policy/clamp/clds/util/CryptoUtils.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/onap/policy/clamp/clds/Application.java b/src/main/java/org/onap/policy/clamp/clds/Application.java index a242086da..ba300ac09 100644 --- a/src/main/java/org/onap/policy/clamp/clds/Application.java +++ b/src/main/java/org/onap/policy/clamp/clds/Application.java @@ -96,7 +96,7 @@ public class Application extends SpringBootServletInitializer { private String keyStoreType; - @Value("${clamp.config.keyFile:#{null}}") + @Value("${clamp.config.keyFile:classpath:/clds/aaf/org.onap.clamp.keyfile}") private String keyFile; @Autowired diff --git a/src/main/java/org/onap/policy/clamp/clds/config/sdc/SdcControllersConfiguration.java b/src/main/java/org/onap/policy/clamp/clds/config/sdc/SdcControllersConfiguration.java index 4748edf6d..d0b116f71 100644 --- a/src/main/java/org/onap/policy/clamp/clds/config/sdc/SdcControllersConfiguration.java +++ b/src/main/java/org/onap/policy/clamp/clds/config/sdc/SdcControllersConfiguration.java @@ -1,8 +1,8 @@ /*- * ============LICENSE_START======================================================= - * ONAP CLAMP + * ONAP POLICY-CLAMP * ================================================================================ - * Copyright (C) 2018 AT&T Intellectual Property. All rights + * Copyright (C) 2018, 2021 AT&T Intellectual Property. All rights * reserved. * ================================================================================ * Modifications Copyright (c) 2019 Samsung @@ -20,13 +20,14 @@ * limitations under the License. * ============LICENSE_END============================================ * =================================================================== - * + * */ package org.onap.policy.clamp.clds.config.sdc; import com.google.gson.JsonObject; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.HashMap; @@ -49,10 +50,14 @@ public class SdcControllersConfiguration { private static final String CONTROLLER_SUBTREE_KEY = "sdc-connections"; @Autowired protected ApplicationContext appContext; + + @Value("${clamp.config.keyFile:classpath:/clds/aaf/org.onap.clamp.keyfile}") + private String keyFile; + /** * The file name that will be loaded by Spring. */ - @Value("${clamp.config.files.sdcController:'classpath:/clds/sdc-controllers-config.json'}") + @Value("${clamp.config.files.sdcController:classpath:/clds/sdc-controllers-config.json}") protected String sdcControllerFile; /** * The root of the JSON. @@ -66,11 +71,10 @@ public class SdcControllersConfiguration { */ @PostConstruct public void loadConfiguration() throws IOException { - Resource resource = appContext.getResource(sdcControllerFile); - // Try to load json tree - jsonRootNode = JsonUtils.GSON.fromJson(new InputStreamReader( - resource.getInputStream(), StandardCharsets.UTF_8), - JsonObject.class); + try (InputStreamReader controllerFile = new InputStreamReader( + appContext.getResource(sdcControllerFile).getInputStream(), StandardCharsets.UTF_8)) { + jsonRootNode = JsonUtils.GSON.fromJson(controllerFile, JsonObject.class); + } } public SdcSingleControllerConfiguration getSdcSingleControllerConfiguration(String controllerName) { @@ -86,8 +90,9 @@ public class SdcControllersConfiguration { Map result = new HashMap<>(); if (jsonRootNode.get(CONTROLLER_SUBTREE_KEY) != null) { jsonRootNode.get(CONTROLLER_SUBTREE_KEY).getAsJsonObject().entrySet().forEach( - entry -> result.put(entry.getKey(), - new SdcSingleControllerConfiguration(entry.getValue().getAsJsonObject(), entry.getKey()))); + entry -> result.put(entry.getKey(), + new SdcSingleControllerConfiguration(entry.getValue().getAsJsonObject(), entry.getKey(), + keyFile))); } else { throw new SdcParametersException( CONTROLLER_SUBTREE_KEY + " key not found in the file: " + sdcControllerFile); diff --git a/src/main/java/org/onap/policy/clamp/clds/config/sdc/SdcSingleControllerConfiguration.java b/src/main/java/org/onap/policy/clamp/clds/config/sdc/SdcSingleControllerConfiguration.java index 0bbbf19dc..67060d776 100644 --- a/src/main/java/org/onap/policy/clamp/clds/config/sdc/SdcSingleControllerConfiguration.java +++ b/src/main/java/org/onap/policy/clamp/clds/config/sdc/SdcSingleControllerConfiguration.java @@ -1,8 +1,8 @@ /*- * ============LICENSE_START======================================================= - * ONAP CLAMP + * ONAP POLICY-CLAMP * ================================================================================ - * Copyright (C) 2018 AT&T Intellectual Property. All rights + * Copyright (C) 2018, 2021 AT&T Intellectual Property. All rights * reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,22 +18,17 @@ * limitations under the License. * ============LICENSE_END============================================ * =================================================================== - * + * */ package org.onap.policy.clamp.clds.config.sdc; -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; import com.google.gson.JsonObject; -import java.security.GeneralSecurityException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; -import org.apache.commons.codec.DecoderException; import org.onap.policy.clamp.clds.exception.sdc.controller.SdcParametersException; -import org.onap.policy.clamp.clds.util.CryptoUtils; +import org.onap.policy.clamp.util.PassDecoder; import org.onap.sdc.api.consumer.IConfiguration; /** @@ -41,8 +36,8 @@ import org.onap.sdc.api.consumer.IConfiguration; */ public class SdcSingleControllerConfiguration implements IConfiguration { - private static final EELFLogger logger = EELFManager.getInstance() - .getLogger(SdcSingleControllerConfiguration.class); + private final String keyFile; + /** * The sdc Controller name corresponding. */ @@ -78,23 +73,20 @@ public class SdcSingleControllerConfiguration implements IConfiguration { public static final String OTHER = "OTHER"; public static final String TOSCA_CSAR = "TOSCA_CSAR"; public static final String VF_MODULES_METADATA = "VF_MODULES_METADATA"; - private static final String[] SUPPORTED_ARTIFACT_TYPES = { - TOSCA_CSAR, VF_MODULES_METADATA - }; - public static final List SUPPORTED_ARTIFACT_TYPES_LIST = Collections - .unmodifiableList(Arrays.asList(SUPPORTED_ARTIFACT_TYPES)); + private static final String[] SUPPORTED_ARTIFACT_TYPES = {TOSCA_CSAR, VF_MODULES_METADATA}; + public static final List SUPPORTED_ARTIFACT_TYPES_LIST = List.of(SUPPORTED_ARTIFACT_TYPES); /** * This constructor builds a SdcSingleControllerConfiguration from the * corresponding json. - * - * @param jsonNode - * The JSON node - * @param controllerName - * The controller name that must appear in the JSON + * + * @param jsonNode The JSON node + * @param controllerName The controller name that must appear in the JSON + * @param keyFileLocation The location of the file to decode the password using CADI */ - public SdcSingleControllerConfiguration(JsonObject jsonNode, String controllerName) { + public SdcSingleControllerConfiguration(JsonObject jsonNode, String controllerName, String keyFileLocation) { jsonRootNode = jsonNode; + keyFile = keyFileLocation; setSdcControllerName(controllerName); testAllRequiredParameters(); } @@ -130,10 +122,10 @@ public class SdcSingleControllerConfiguration implements IConfiguration { } } - private String getEncryptedStringConfig(String key) throws GeneralSecurityException, DecoderException { + private String getEncryptedStringConfig(String key) { if (jsonRootNode != null && jsonRootNode.get(key) != null) { return jsonRootNode.get(key).getAsString().isEmpty() ? null - : CryptoUtils.decrypt(jsonRootNode.get(key).getAsString()); + : PassDecoder.decode(jsonRootNode.get(key).getAsString(), keyFile); } return null; } @@ -164,12 +156,7 @@ public class SdcSingleControllerConfiguration implements IConfiguration { @Override public String getPassword() { - try { - return getEncryptedStringConfig(SDC_KEY_ATTRIBUTE_NAME); - } catch (GeneralSecurityException | DecoderException e) { - logger.error("Unable to decrypt the SDC password", e); - return null; - } + return getEncryptedStringConfig(SDC_KEY_ATTRIBUTE_NAME); } @Override @@ -211,12 +198,7 @@ public class SdcSingleControllerConfiguration implements IConfiguration { @Override public String getKeyStorePassword() { - try { - return getEncryptedStringConfig(KEY_STORE_KEY); - } catch (GeneralSecurityException | DecoderException e) { - logger.error("Unable to decrypt the SDC password", e); - return null; - } + return getEncryptedStringConfig(KEY_STORE_KEY); } @Override diff --git a/src/main/java/org/onap/policy/clamp/clds/util/CryptoUtils.java b/src/main/java/org/onap/policy/clamp/clds/util/CryptoUtils.java deleted file mode 100644 index 01dd48763..000000000 --- a/src/main/java/org/onap/policy/clamp/clds/util/CryptoUtils.java +++ /dev/null @@ -1,168 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP CLAMP - * ================================================================================ - * Copyright (C) 2017-2018 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============================================ - * =================================================================== - * - */ - -package org.onap.policy.clamp.clds.util; - -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; -import com.google.common.base.Charsets; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.security.GeneralSecurityException; -import java.security.SecureRandom; -import java.util.Properties; -import javax.crypto.Cipher; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; -import org.apache.commons.codec.DecoderException; -import org.apache.commons.codec.binary.Hex; -import org.apache.commons.lang3.ArrayUtils; - -/** - * CryptoUtils for encrypting/decrypting string based on a Key defined in - * application.properties (Spring config file). - */ -public final class CryptoUtils { - - /** - * Used to log CryptoUtils class. - */ - private static final EELFLogger logger = EELFManager.getInstance().getLogger(CryptoUtils.class); - // Openssl commands: - // Encrypt: echo -n "123456" | openssl aes-128-cbc -e -K - // -iv <16 Bytes iv (HEX), be careful it's 32 Hex Chars> | xxd -u -g100 - // Final result is to put in properties file is: IV + Outcome of openssl - // command - // ************************************************************ - // Decrypt: echo -n 'Encrypted string' | xxd -r -ps | openssl aes-128-cbc -d - // -K - // -iv <16 Bytes IV extracted from Encrypted String, be - // careful it's 32 Hex Chars> - /** - * Definition of encryption algorithm. - */ - private static final String ALGORITHM = "AES"; - - /** - * AES Encryption Key environment variable for external configuration. - */ - private static final String AES_ENCRYPTION_KEY = "AES_ENCRYPTION_KEY"; - - /** - * Detailed definition of encryption algorithm. - */ - private static final String ALGORITHM_DETAILS = ALGORITHM + "/CBC/PKCS5PADDING"; - private static final int IV_BLOCK_SIZE_IN_BITS = 128; - /** - * An Initial Vector of 16 Bytes, so 32 Hexadecimal Chars. - */ - private static final int IV_BLOCK_SIZE_IN_BYTES = IV_BLOCK_SIZE_IN_BITS / 8; - /** - * Key to read in the key.properties file. - */ - private static final String KEY_PARAM = "org.onap.policy.clamp.encryption.aes.key"; - private static final String PROPERTIES_FILE_NAME = "clds/key.properties"; - /** - * The SecretKeySpec created from the Base 64 String key. - */ - private static final SecretKeySpec SECRET_KEY_SPEC = readSecretKeySpec(PROPERTIES_FILE_NAME); - - /** - * Private constructor to avoid creating instances of util class. - */ - private CryptoUtils() { - } - - /** - * Encrypt a value based on the Clamp Encryption Key. - * - * @param value The value to encrypt - * @return The encrypted string - * @throws GeneralSecurityException In case of issue with the encryption - * @throws UnsupportedEncodingException In case of issue with the charset - * conversion - */ - public static String encrypt(String value) throws GeneralSecurityException { - Cipher cipher = Cipher.getInstance(ALGORITHM_DETAILS, "SunJCE"); - byte[] iv = new byte[IV_BLOCK_SIZE_IN_BYTES]; - SecureRandom.getInstance("SHA1PRNG").nextBytes(iv); - IvParameterSpec ivspec = new IvParameterSpec(iv); - cipher.init(Cipher.ENCRYPT_MODE, SECRET_KEY_SPEC, ivspec); - return Hex.encodeHexString(ArrayUtils.addAll(iv, cipher.doFinal(value.getBytes(Charsets.UTF_8)))); - } - - /** - * Decrypt a value based on the Clamp Encryption Key. - * - * @param message The encrypted string that must be decrypted using the Clamp - * Encryption Key - * @return The String decrypted - * @throws GeneralSecurityException In case of issue with the encryption - * @throws DecoderException In case of issue to decode the HexString - */ - public static String decrypt(String message) throws GeneralSecurityException, DecoderException { - byte[] encryptedMessage = Hex.decodeHex(message.toCharArray()); - Cipher cipher = Cipher.getInstance(ALGORITHM_DETAILS, "SunJCE"); - IvParameterSpec ivspec = new IvParameterSpec(ArrayUtils.subarray(encryptedMessage, 0, IV_BLOCK_SIZE_IN_BYTES)); - byte[] realData = ArrayUtils.subarray(encryptedMessage, IV_BLOCK_SIZE_IN_BYTES, encryptedMessage.length); - cipher.init(Cipher.DECRYPT_MODE, SECRET_KEY_SPEC, ivspec); - byte[] decrypted = cipher.doFinal(realData); - return new String(decrypted); - } - - /** - * Method used to generate the SecretKeySpec from a Base64 String. - * - * @param keyString The key as a string in Base 64 - * @return The SecretKeySpec created - * @throws DecoderException In case of issues with the decoding of Base64 - */ - private static SecretKeySpec getSecretKeySpec(String keyString) throws DecoderException { - byte[] key = Hex.decodeHex(keyString.toCharArray()); - return new SecretKeySpec(key, ALGORITHM); - } - - /** - * Reads SecretKeySpec from file specified by propertiesFileName. - * - * @param propertiesFileName File name with properties - * @return SecretKeySpec secret key spec read from propertiesFileName - */ - private static SecretKeySpec readSecretKeySpec(String propertiesFileName) { - Properties props = new Properties(); - try { - // Workaround fix to make encryption key configurable - // System environment variable takes precedence for over clds/key.properties - String encryptionKey = System.getenv(AES_ENCRYPTION_KEY); - if (encryptionKey != null && encryptionKey.trim().length() > 0) { - return getSecretKeySpec(encryptionKey); - } else { - props.load(ResourceFileUtils.getResourceAsStream(propertiesFileName)); - return getSecretKeySpec(props.getProperty(KEY_PARAM)); - } - } catch (IOException | DecoderException e) { - logger.error("Exception occurred during the key reading", e); - return null; - } - } -} diff --git a/src/main/java/org/onap/policy/clamp/clds/util/ResourceFileUtils.java b/src/main/java/org/onap/policy/clamp/clds/util/ResourceFileUtils.java index cd4700277..d6184c656 100644 --- a/src/main/java/org/onap/policy/clamp/clds/util/ResourceFileUtils.java +++ b/src/main/java/org/onap/policy/clamp/clds/util/ResourceFileUtils.java @@ -1,8 +1,8 @@ /*- * ============LICENSE_START======================================================= - * ONAP CLAMP + * ONAP POLICY-CLAMP * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights + * Copyright (C) 2017, 2021 AT&T Intellectual Property. All rights * reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -56,8 +56,8 @@ public final class ResourceFileUtils { * @return The file as inputStream */ public static InputStream getResourceAsStream(String fileName) { - InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream( - fileName.startsWith(CLASSPATH_PREFIX) ? fileName.replaceFirst(CLASSPATH_PREFIX, "") : fileName); + InputStream is = Thread.currentThread().getContextClassLoader() + .getResourceAsStream(fileName.replaceFirst("^" + CLASSPATH_PREFIX, "")); if (is == null) { throw new IllegalArgumentException("Unable to find resource: " + fileName); } diff --git a/src/main/java/org/onap/policy/clamp/util/PassDecoder.java b/src/main/java/org/onap/policy/clamp/util/PassDecoder.java index f4b8ed4dc..b8e90e3d0 100644 --- a/src/main/java/org/onap/policy/clamp/util/PassDecoder.java +++ b/src/main/java/org/onap/policy/clamp/util/PassDecoder.java @@ -1,8 +1,8 @@ /*- * ============LICENSE_START======================================================= - * ONAP CLAMP + * ONAP POLICY-CLAMP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights + * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights * reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -32,6 +32,10 @@ import org.onap.policy.clamp.clds.util.ResourceFileUtils; * PassDecoder for decrypting the truststore and keystore password. */ public class PassDecoder { + + private PassDecoder() { + } + /** * Used to log PassDecoder class. */ @@ -41,7 +45,7 @@ public class PassDecoder { * Decode the password. * * @param encryptedPass The encrypted password - * @param keyFileName The key file name in String + * @param keyFileName The key file name in String */ public static String decode(String encryptedPass, String keyFileName) { if (null == keyFileName) { -- cgit 1.2.3-korg