Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public class Constants {
public static final String CIPHER_TEXT_PROPERTY_FILE = "cipher-text.properties";
public static final String CIPHER_TOOL_PROPERTY_FILE = "cipher-tool.properties";
public static final String SECRET_PROPERTY_FILE = "secret-conf.properties";
public static final String DEFAULT_JSON_FILE = "default.json";
public static final String DEFAULT_JSON_DIR_PATH = "default.json.dir.path";
public static final String DEPLOYMENT_TOML_FILE = "deployment.toml";
public static final String DEPLOYMENT_CONFIG_FILE_PATH = "deployment.config.file.path";
public static final String CARBON_CONFIG_DIR_PATH = "carbon.config.dir.path";
Expand All @@ -52,6 +54,18 @@ public class Constants {
public static final String KEY_TYPE_PROPERTY = "primary.key.type";
public static final String KEY_ALIAS_PROPERTY = "primary.key.alias";

public static final String PRIMARY_KEYSTORE_PROPERTY_MAP_NAME = "keystore.primary";
public static final String INTERNAL_KEYSTORE_PROPERTY_MAP_NAME = "keystore.internal";
public static final String KEYSTORE_PRIMARY_FILE_NAME = "keystore.primary.file_name";
public static final String KEYSTORE_PRIMARY_TYPE = "keystore.primary.type";
public static final String KEYSTORE_PRIMARY_ALIAS = "keystore.primary.alias";
public static final String KEYSTORE_INTERNAL_TYPE = "keystore.internal.type";
public static final String KEYSTORE_INTERNAL_ALIAS = "keystore.internal.alias";

public static final String KEY_FILE_NAME = "file_name";
public static final String KEY_TYPE = "type";
public static final String KEY_ALIAS = "alias";

public static final String SECRET_PROPERTY_MAP_NAME = "secrets";
public static final String SECRETS_SECTION = "[secrets]";
public static final String SECTION_PREFIX = "[";
Expand Down
202 changes: 176 additions & 26 deletions components/ciphertool/src/main/java/org/wso2/ciphertool/utils/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package org.wso2.ciphertool.utils;

import com.google.gson.Gson;
import net.consensys.cava.toml.Toml;
import net.consensys.cava.toml.TomlParseResult;
import net.consensys.cava.toml.TomlTable;
Expand All @@ -33,10 +34,13 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
Expand Down Expand Up @@ -175,6 +179,44 @@ public static void writeToPropertyFile(Properties properties, String filePath) {
}
}

/**
* Retrieve the value for the given configuration from the following order of files.
* 1. deployment.toml
* 2. default.json
* 3. carbon.xml
*
* @param config Configuration value.
* @param key Key of the configuration value in default.json.
* @param defaultMap Map that contains values from default.json.
* @param element Element.
* @param xPath Xpath.
* @return Configuration value.
*/
public static String getValueFromConfigs(String config, String key, Map<String, Object> defaultMap,
Element element, String xPath) {

String value = config;
try {
// If the value is empty in deployment.toml, read from default.json.
if (StringUtils.isBlank(value)) {
value = defaultMap.get(key).toString();
}
// If the value is given as a reference, read from default.json.
if (value.startsWith("$ref")) {
// Read the value between the curly braces as the reference.
// e.g. $ref{<reference>} -> <reference>
String reference = value.substring(value.indexOf('{') + 1, value.indexOf('}'));
return defaultMap.get(reference).toString();
}
return value;
// Throw NullPointerException if the value is not available in default.json.
} catch (NullPointerException e) {
// Read from carbon.xml if default.json is not available.
System.err.println("Invalid value " + key + " " + e);
return Utils.getValueFromXPath(element, xPath);
}
}

/**
* retrieve the value for the given xpath from the file
*
Expand Down Expand Up @@ -263,29 +305,43 @@ public static void setSystemProperties() {

if (Files.exists(path)) {
//WSO2 Environment
Map<String, String> internalKeystoreMap = Utils.getKeystoreFromConfiguration(getDeploymentFilePath(),
Constants.INTERNAL_KEYSTORE_PROPERTY_MAP_NAME);
Map<String, String> primaryKeystoreMap = Utils.getKeystoreFromConfiguration(getDeploymentFilePath(),
Constants.PRIMARY_KEYSTORE_PROPERTY_MAP_NAME);
Map<String, Object> defaultConfigMap = Utils.getJSONConfiguration(getDefaultJSONFilePath());
try {
DocumentBuilder docBuilder = getSecuredDocumentBuilder(false);
Document document = docBuilder.parse(path.toAbsolutePath().toString());

keyStoreFile = Utils.getValueFromXPath(document.getDocumentElement(),
Constants.InternalKeyStore.KEY_LOCATION_XPATH);
keyStoreFile = internalKeystoreMap.get(Constants.KEY_FILE_NAME);
//Use InternalKeyStore if it exists, else use the Primary keystore
if (keyStoreFile != null) {
keyType = Utils.getValueFromXPath(document.getDocumentElement(),
Constants.InternalKeyStore.KEY_TYPE_XPATH);
keyAlias = Utils.getValueFromXPath(document.getDocumentElement(),
Constants.InternalKeyStore.KEY_ALIAS_XPATH);
if (StringUtils.isNotBlank(keyStoreFile)) {
keyType = Utils.getValueFromConfigs(
internalKeystoreMap.get(Constants.KEY_TYPE),
Constants.KEYSTORE_INTERNAL_TYPE, defaultConfigMap,
document.getDocumentElement(), Constants.InternalKeyStore.KEY_TYPE_XPATH);
keyAlias = Utils.getValueFromConfigs(
internalKeystoreMap.get(Constants.KEY_ALIAS),
Constants.KEYSTORE_INTERNAL_ALIAS, defaultConfigMap,
document.getDocumentElement(), Constants.InternalKeyStore.KEY_ALIAS_XPATH);
primaryKeyStore = false;
} else {
keyStoreFile = Utils.getValueFromXPath(document.getDocumentElement(),
Constants.PrimaryKeyStore.KEY_LOCATION_XPATH);
keyType = Utils.getValueFromXPath(document.getDocumentElement(),
Constants.PrimaryKeyStore.KEY_TYPE_XPATH);
keyAlias = Utils.getValueFromXPath(document.getDocumentElement(),
Constants.PrimaryKeyStore.KEY_ALIAS_XPATH);
keyStoreFile = Utils.getValueFromConfigs(
primaryKeystoreMap.get(Constants.KEY_FILE_NAME),
Constants.KEYSTORE_PRIMARY_FILE_NAME, defaultConfigMap,
document.getDocumentElement(), Constants.PrimaryKeyStore.KEY_LOCATION_XPATH);
keyType = Utils.getValueFromConfigs(
primaryKeystoreMap.get(Constants.KEY_TYPE),
Constants.KEYSTORE_PRIMARY_TYPE, defaultConfigMap,
document.getDocumentElement(), Constants.PrimaryKeyStore.KEY_TYPE_XPATH);
keyAlias = Utils.getValueFromConfigs(
primaryKeystoreMap.get(Constants.KEY_ALIAS),
Constants.KEYSTORE_PRIMARY_ALIAS, defaultConfigMap,
document.getDocumentElement(), Constants.PrimaryKeyStore.KEY_ALIAS_XPATH);
}

keyStoreFile = resolveKeyStorePath(keyStoreFile, homeFolder);
keyStoreFile = resolveKeyStorePath(keyStoreFile, homeFolder, defaultConfigMap);
System.setProperty(Constants.KEY_LOCATION_PROPERTY, keyStoreFile);
String keyStoreName = ((Utils.isPrimaryKeyStore()) ? Constants.PRIMARY : Constants.INTERNAL);

Expand Down Expand Up @@ -380,22 +436,47 @@ public static boolean isPrimaryKeyStore() {
}

/**
* Resolve absolute path of the keystore
* Resolve path of the keystore.
*
* @param keyStorePath path of the keystore
* @param homeFolder path of the IS_HOME
* @param defaultMap map that contains values from default.json
* @return resolved path of the keystore
*/
public static String resolveKeyStorePath(String keyStorePath, String homeFolder) {
// Check whether it's a relative path and is inside {carbon.home}.
if (keyStorePath.contains("}")) {
keyStorePath = getAbsolutePathWithCarbonHome(keyStorePath, homeFolder);
} else if (!keyStorePath.startsWith(homeFolder)) {
if (keyStorePath.contains(Constants.REPOSITORY_DIR + "/" + Constants.RESOURCES_DIR + "/" + Constants.SECURITY_DIR)) {
keyStorePath = Paths.get(homeFolder, keyStorePath).toString();
} else {
keyStorePath = Paths.get(homeFolder, Constants.REPOSITORY_DIR,
Constants.RESOURCES_DIR, Constants.SECURITY_DIR, keyStorePath).toString();
public static String resolveKeyStorePath(String keyStorePath, String homeFolder,
Map<String, Object> defaultMap) {

String path = keyStorePath;
try {
if (StringUtils.isBlank(path)) {
throw new CipherToolException("KeyStore file path cannot be empty");
}
// If the value is given as a reference, read from default.json.
if (path.startsWith("$ref")) {
// Read the value between the curly braces as the reference.
// e.g. $ref{<reference>} -> <reference>
String reference = path.substring(path.indexOf('{') + 1, path.indexOf('}'));
path = defaultMap.get(reference).toString();
}
// Check whether it's a relative path and is inside {carbon.home}.
if (path.contains("}")) {
path = getAbsolutePathWithCarbonHome(path, homeFolder);
// Check whether it only contains the file name (when retrieved from toml).
} else if (!path.startsWith(homeFolder)) {
if (path.contains(Constants.REPOSITORY_DIR + "/" + Constants.RESOURCES_DIR + "/" +
Constants.SECURITY_DIR)) {
path = Paths.get(homeFolder, path).toString();
} else {
path = Paths.get(homeFolder, Constants.REPOSITORY_DIR,
Constants.RESOURCES_DIR, Constants.SECURITY_DIR, path).toString();
}
}
return path;
} catch (InvalidPathException e) {
throw new CipherToolException("Error while resolving the keystore path: " + path, e);
}
return keyStorePath;
}

private static String getAbsolutePathWithCarbonHome(String keyStorePath, String homeFolder) {
// Append carbon.home location to the relative path.
return homeFolder + keyStorePath.substring((keyStorePath.indexOf('}')) + 1);
Expand Down Expand Up @@ -480,6 +561,75 @@ public static Map<String, String> getSecreteFromConfiguration(String configFileP
return context;
}

/**
* Read toml file and return a map of keystore data.
*
* @param configFilePath File path to deployment toml.
* @param keystoreName Name of the keystore.
* @return Map of keystore data.
*/
public static Map<String, String> getKeystoreFromConfiguration(String configFilePath, String keystoreName) {

Map<String, String> context = new LinkedHashMap<>();
try {
TomlParseResult result = Toml.parse(Paths.get(configFilePath));
if (result.hasErrors()) {
throw new CipherToolException("Error while parsing TOML config file");
}
TomlTable table = result.getTable(keystoreName);
if (table != null) {
table.dottedKeySet().forEach(key -> context.put(key, table.getString(key)));
}
// Returns an empty map if the deployment toml is not found.
} catch (IOException e) {
System.err.println("Error parsing file " + configFilePath + e.toString());
}
return context;
}

/**
* Read from default.json file and return a map of data.
*
* @return Map of data.
*/
public static Map<String, Object> getJSONConfiguration(Path jsonFilePath) {

Gson gson = new Gson();
Map<String, Object> map = new HashMap<>();

if (jsonFilePath != null) {
try (Reader reader = Files.newBufferedReader(jsonFilePath)) {
map = gson.fromJson(reader, Map.class);
// Returns an empty map if the default json file is not found.
} catch (IOException e) {
System.err.println("Error parsing file " + jsonFilePath + " " + e);
}
}
return map;
}
Comment thread
KalinduGandara marked this conversation as resolved.

/**
* Get default.json file path.
*
* @return Default JSON file path.
*/
public static Path getDefaultJSONFilePath() {

String defaultJsonDirPath = System.getProperty(Constants.DEFAULT_JSON_DIR_PATH);
if (StringUtils.isEmpty(defaultJsonDirPath)) {
String homeFolder = System.getProperty(Constants.CARBON_HOME);
Path filePath = null;
try {
filePath = Paths.get(homeFolder, Constants.REPOSITORY_DIR,
Constants.RESOURCES_DIR, Constants.CONF_DIR, Constants.DEFAULT_JSON_FILE);
} catch (InvalidPathException e) {
System.err.println("Error while resolving the default.json file path" + e.toString());
}
return filePath;
}
return Paths.get(defaultJsonDirPath, Constants.DEFAULT_JSON_FILE);
}

private static String resolveVariable(String text) {
String sysRefs = StringUtils.substringBetween(text, SYS_PROPERTY_PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX);
String envRefs = StringUtils.substringBetween(text, ENV_VAR_PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX);
Expand Down