Fix the ssl config
[clamp.git] / src / main / java / org / onap / clamp / clds / util / CryptoUtils.java
index 4243996..1ddf3a9 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP CLAMP
  * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights
  *                             reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,7 +18,7 @@
  * limitations under the License.
  * ============LICENSE_END============================================
  * ===================================================================
- * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * 
  */
 
 package org.onap.clamp.clds.util;
@@ -44,26 +44,39 @@ import org.apache.commons.lang3.ArrayUtils;
  */
 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 <Private Hex key>
-    // -iv <16 Hex Bytes iv> | xxd -u -g100
+    // -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
-    // <Private Hex Key> -iv <16 Bytes IV extracted from Encrypted String>
+    // <Private Hex Key> -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 BLOCK_SIZE_IN_BITS = 128;
-    private static final int BLOCK_SIZE_IN_BYTES = BLOCK_SIZE_IN_BITS / 8;
+    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.
      */
@@ -82,17 +95,17 @@ public final class 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
+     * @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, UnsupportedEncodingException {
+    public static String encrypt(String value) throws GeneralSecurityException {
         Cipher cipher = Cipher.getInstance(ALGORITHM_DETAILS, "SunJCE");
-        SecureRandom randomNumber = SecureRandom.getInstance("SHA1PRNG");
-        byte[] iv = new byte[BLOCK_SIZE_IN_BYTES];
-        randomNumber.nextBytes(iv);
+        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))));
@@ -100,17 +113,18 @@ public final class CryptoUtils {
 
     /**
      * Decrypt a value based on the Clamp Encryption Key.
-     *
-     * @param message The encrypted string that must be decrypted using 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
+     * @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, BLOCK_SIZE_IN_BYTES));
-        byte[] realData = ArrayUtils.subarray(encryptedMessage, BLOCK_SIZE_IN_BYTES, encryptedMessage.length);
+        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);
@@ -118,7 +132,7 @@ public final class CryptoUtils {
 
     /**
      * 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
@@ -129,7 +143,7 @@ public final class CryptoUtils {
     }
 
     /**
-     * Reads SecretKeySpec from file specified by propertiesFileName
+     * Reads SecretKeySpec from file specified by propertiesFileName.
      *
      * @param propertiesFileName File name with properties
      * @return SecretKeySpec secret key spec read from propertiesFileName
@@ -137,8 +151,15 @@ public final class CryptoUtils {
     private static SecretKeySpec readSecretKeySpec(String propertiesFileName) {
         Properties props = new Properties();
         try {
-            props.load(ResourceFileUtil.getResourceAsStream(propertiesFileName));
-            return getSecretKeySpec(props.getProperty(KEY_PARAM));
+            // 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;