BYOKMapProperties.java
- /*
- * GovWay - A customizable API Gateway
- * https://govway.org
- *
- * Copyright (c) 2005-2025 Link.it srl (https://link.it).
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 3, as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- package org.openspcoop2.pdd.core.byok;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Properties;
- import org.apache.commons.lang.StringUtils;
- import org.openspcoop2.utils.UtilsException;
- import org.openspcoop2.utils.UtilsRuntimeException;
- import org.openspcoop2.utils.certificate.byok.BYOKInstance;
- import org.openspcoop2.utils.certificate.byok.BYOKManager;
- import org.openspcoop2.utils.certificate.byok.BYOKMode;
- import org.openspcoop2.utils.certificate.byok.BYOKRequestParams;
- import org.openspcoop2.utils.properties.MapProperties;
- import org.slf4j.Logger;
- /**
- * BYOKMapProperties
- *
- * @author Poli Andrea (apoli@link.it)
- * @author $Author$
- * @version $Rev$, $Date$
- */
- public class BYOKMapProperties extends MapProperties {
- public static final String FILE_NAME = "govway.secrets.properties";
-
- private static final String PROP_KMS_PREFIX = "kms.";
- private static final String ENV_KMS_PREFIX = MapProperties.ENV_PREFIX+PROP_KMS_PREFIX;
- private static final String JAVA_KMS_PREFIX = MapProperties.JAVA_PREFIX+PROP_KMS_PREFIX;
-
- private static final String PROP_KSM_PREFIX_DEPRECATED = "ksm.";
- private static final String ENV_KSM_PREFIX_DEPRECATED = MapProperties.ENV_PREFIX+PROP_KSM_PREFIX_DEPRECATED;
- private static final String JAVA_KSM_PREFIX_DEPRECATED = MapProperties.JAVA_PREFIX+PROP_KSM_PREFIX_DEPRECATED;
-
- private static final String PROP_SECURITY_PREFIX = "security.";
- private static final String ENV_SECURITY_PREFIX = MapProperties.ENV_PREFIX+PROP_SECURITY_PREFIX;
- private static final String JAVA_SECURITY_PREFIX = MapProperties.JAVA_PREFIX+PROP_SECURITY_PREFIX;
-
- // default true
- private static final String PROP_WRAPPED_PREFIX = "wrapped.";
- private static final String ENV_WRAPPED_PREFIX = MapProperties.ENV_PREFIX+PROP_WRAPPED_PREFIX;
- private static final String JAVA_WRAPPED_PREFIX = MapProperties.JAVA_PREFIX+PROP_WRAPPED_PREFIX;
-
- // default false
- private static final String PROP_UNWRAP_AFTER_GOVWAY_STARTUP_PREFIX = "govway-run-only.unwrap-after-startup.";
- private static final String ENV_UNWRAP_AFTER_GOVWAY_STARTUP_PREFIX = MapProperties.ENV_PREFIX+PROP_UNWRAP_AFTER_GOVWAY_STARTUP_PREFIX;
- private static final String JAVA_UNWRAP_AFTER_GOVWAY_STARTUP_PREFIX = MapProperties.JAVA_PREFIX+PROP_UNWRAP_AFTER_GOVWAY_STARTUP_PREFIX;
-
- private static final String UNWRAP_DEFAULT_MODE = "unwrap.default.mode";
- private static final String UNWRAP_DEFAULT_ID = "unwrap.default.id";
- private static final String UNWRAP_MODE_SECURITY = "security";
- private static final String UNWRAP_MODE_KMS = "kms";
- private static final String UNWRAP_MODE_KSM_DEPRECATED = "ksm";
-
- // kms.<id>.param.<paramName>=<paramValue>
- private static final String KMS_PREFIX = "kms.";
- private static final String KMS_PARAM_PREFIX = ".param.";
- private static String getKmsParamPrefixPropertyName(String kmsId) {
- return KMS_PREFIX+kmsId+KMS_PARAM_PREFIX;
- }
-
- private static final String KSM_PREFIX_DEPRECATED = "ksm.";
- private static final String KSM_PARAM_PREFIX_DEPRECATED = ".param.";
- private static String getKsmParamPrefixPropertyNameDeprecated(String ksmId) {
- return KSM_PREFIX_DEPRECATED+ksmId+KSM_PARAM_PREFIX_DEPRECATED;
- }
-
- private static final String ERROR_SUFFIX_UNKNOW = "' unknown";
-
- private static final String ERROR_DEFAULT_MODE_NOT_FOUND = ") an unwrap mode has not been defined (security/kms); specifying the mode is mandatory if a default unwrap mode is not defined.";
-
- private String defaultUnwrapId = null;
- private Boolean defaultUnwrapModeSecurity = null;
-
- private boolean useSecurityEngine = false;
- private String securityPolicy;
- private String securityRemotePolicy;
-
- private Map<String, DriverBYOK> mapDriverSecurity = new HashMap<>();
-
- private Map<String, Map<String, String>> mapKmsInput = new HashMap<>();
-
- private Map<String, Object> dynamicMap = null;
- private boolean checkJmxPrefixOperazioneNonRiuscita = false;
-
- private boolean existsUnwrapPropertiesAfterGovWayStartup = false;
- public boolean isExistsUnwrapPropertiesAfterGovWayStartup() {
- return this.existsUnwrapPropertiesAfterGovWayStartup;
- }
- private boolean isGovWayStarted = false; // usato per caricare variabili che devono essere trattate solo sui nodi run
- public boolean isGovWayStarted() {
- return this.isGovWayStarted;
- }
- public void setGovWayStarted(boolean isGovWayStarted) {
- this.isGovWayStarted = isGovWayStarted;
- }
- /** Copia Statica */
- private static BYOKMapProperties secretsProperties = null;
-
- /**private BYOKMapProperties(Logger log, boolean throwNotFound,
- boolean useSecurityEngine,
- Map<String, Object> dynamicMapParam, boolean checkJmxPrefixOperazioneNonRiuscita) throws UtilsException {
- super(log, FILE_NAME, throwNotFound);
- init(useSecurityEngine,
- dynamicMapParam, checkJmxPrefixOperazioneNonRiuscita);
- }*/
- private BYOKMapProperties(Logger log, String fileName, boolean throwNotFound,
- boolean useSecurityEngine,
- Map<String, Object> dynamicMapParam, boolean checkJmxPrefixOperazioneNonRiuscita) throws UtilsException {
- super(log, fileName, throwNotFound);
- init(useSecurityEngine,
- dynamicMapParam, checkJmxPrefixOperazioneNonRiuscita);
- }
- private void init(boolean useSecurityEngine,
- Map<String, Object> dynamicMapParam, boolean checkJmxPrefixOperazioneNonRiuscita) {
- String securityPolicyB = BYOKManager.getSecurityEngineGovWayPolicy();
- String securityRemotePolicyB = BYOKManager.getSecurityRemoteEngineGovWayPolicy();
- if(securityPolicyB!=null && StringUtils.isNotEmpty(securityPolicyB)) {
- this.securityPolicy = securityPolicyB;
- }
- if(securityRemotePolicyB!=null && StringUtils.isNotEmpty(securityRemotePolicyB)) {
- this.securityRemotePolicy = securityRemotePolicyB;
- }
- this.useSecurityEngine = useSecurityEngine;
- this.dynamicMap = dynamicMapParam;
- this.checkJmxPrefixOperazioneNonRiuscita = checkJmxPrefixOperazioneNonRiuscita;
- }
-
- /**
- * Il Metodo si occupa di inizializzare il propertiesReader
- *
- *
- */
- public static boolean initialize(Logger log, String fileName, boolean throwNotFound,
- boolean useSecurityEngine,
- Map<String, Object> dynamicMapParam, boolean checkJmxPrefixOperazioneNonRiuscita){
- try {
- BYOKMapProperties.secretsProperties = new BYOKMapProperties(log, fileName, throwNotFound,
- useSecurityEngine,
- dynamicMapParam, checkJmxPrefixOperazioneNonRiuscita);
- return true;
- }
- catch(Exception e) {
- return false;
- }
- }
-
- /**
- * Ritorna l'istanza di questa classe
- *
- * @return Istanza di BYOKMapProperties
- *
- */
- public static BYOKMapProperties getInstance(){
- // spotbugs warning 'SING_SINGLETON_GETTER_NOT_SYNCHRONIZED': l'istanza viene creata allo startup
- if (BYOKMapProperties.secretsProperties == null) {
- synchronized (BYOKMapProperties.class) {
- if (BYOKMapProperties.secretsProperties == null) {
- return null;
- }
- }
- }
- return BYOKMapProperties.secretsProperties;
- }
- @Override
- public void loadPropertyInEnvironment(String key) throws UtilsException {
-
- this.loadDefaultUnwrap();
-
- if(key.startsWith(ENV_PREFIX) && key.length()>ENV_PREFIX.length() &&
- !key.startsWith(ENV_KSM_PREFIX_DEPRECATED) &&
- !key.startsWith(ENV_KMS_PREFIX) &&
- !key.startsWith(ENV_SECURITY_PREFIX) &&
- !key.startsWith(ENV_WRAPPED_PREFIX) &&
- !key.startsWith(ENV_UNWRAP_AFTER_GOVWAY_STARTUP_PREFIX)) {
- loadEnvPropertyInEnvironment(key);
- }
- else if(key.startsWith(JAVA_PREFIX) && key.length()>JAVA_PREFIX.length() &&
- !key.startsWith(JAVA_KSM_PREFIX_DEPRECATED) &&
- !key.startsWith(JAVA_KMS_PREFIX) &&
- !key.startsWith(JAVA_SECURITY_PREFIX) &&
- !key.startsWith(JAVA_WRAPPED_PREFIX) &&
- !key.startsWith(JAVA_UNWRAP_AFTER_GOVWAY_STARTUP_PREFIX)) {
- loadJavaPropertyInEnvironment(key);
- }
- }
- public void loadEnvPropertyInEnvironment(String key) throws UtilsException {
- String envKey = key.substring(ENV_PREFIX.length());
- String value = this.reader.getValue_convertEnvProperties(key);
-
- if(this.isUnwrapAfterGovWayStartup(false,envKey)){
- this.existsUnwrapPropertiesAfterGovWayStartup = true;
- if(!this.isGovWayStarted) {
- return; // verrĂ effettuato l'unwrap dopo che GovWay ha completato lo startup
- }
- }
-
- if(this.isWrapped(false,envKey)) {
- processWrappedValue(key, envKey, value,
- false); // envProperty
- }
- else {
- setEnvProperty(envKey, value);
- }
- }
- public void loadJavaPropertyInEnvironment(String key) throws UtilsException {
- String envKey = key.substring(JAVA_PREFIX.length());
- String value = this.reader.getValue_convertEnvProperties(key);
-
- if(this.isUnwrapAfterGovWayStartup(true,envKey)) {
- this.existsUnwrapPropertiesAfterGovWayStartup = true;
- if(!this.isGovWayStarted) {
- return; // verrĂ effettuato l'unwrap dopo che GovWay ha completato lo startup
- }
- }
-
- if(this.isWrapped(true,envKey)) {
- processWrappedValue(key, envKey, value,
- true); // envProperty
- }
- else {
- setJavaProperty(envKey, value);
- }
- }
- private void processWrappedValue(String key, String envKey, String value, boolean javaProperty) throws UtilsException {
- String plainValue = null;
- String securityId = this.getUnwrapId(javaProperty, envKey);
- try {
- if(this.isWrappedBySecurity(javaProperty, envKey)) {
- String p = this.securityRemotePolicy!=null ? this.securityRemotePolicy : this.securityPolicy;
- if(!this.useSecurityEngine && securityId!=null && securityId.equals(p)) {
- // securityNonInizializzato, skip
- return;
- }
- plainValue = getDriverBYOK(securityId).unwrapAsString(value, securityId, true);
- }
- else {
- plainValue = unwrapByKmsId(value, securityId);
- }
- }catch(Exception e) {
- throw new UtilsException("["+key+"] "+e.getMessage(),e);
- }
- if(plainValue==null) {
- throw new UtilsException("("+key+") unwrapped value null");
- }
- else {
- if(javaProperty) {
- setJavaProperty(envKey, plainValue);
- }
- else{
- setEnvProperty(envKey, plainValue);
- }
- }
- }
-
- private void loadDefaultUnwrap() throws UtilsException {
- String tmp = this.reader.getValue_convertEnvProperties(UNWRAP_DEFAULT_ID);
- if(tmp!=null) {
- this.defaultUnwrapId = tmp.trim();
- if(StringUtils.isEmpty(this.defaultUnwrapId)) {
- this.defaultUnwrapId = null;
- }
- }
-
- if(this.defaultUnwrapId!=null) {
- tmp = this.reader.getValue_convertEnvProperties(UNWRAP_DEFAULT_MODE);
- if(tmp!=null && StringUtils.isNotEmpty(tmp.trim())) {
- if(UNWRAP_MODE_SECURITY.equals(tmp.trim())) {
- this.defaultUnwrapModeSecurity = true;
- }
- else if(UNWRAP_MODE_KMS.equals(tmp.trim()) || UNWRAP_MODE_KSM_DEPRECATED.equals(tmp.trim())) {
- this.defaultUnwrapModeSecurity = false;
- }
- else {
- throw new UtilsException(UNWRAP_DEFAULT_MODE +" '"+tmp.trim()+ERROR_SUFFIX_UNKNOW);
- }
- }
- else {
- this.defaultUnwrapModeSecurity = true; // default by security id
- }
- }
- }
-
- private boolean isWrapped(boolean javaProperty, String key) throws UtilsException {
- if(this.reader==null) {
- return false; // non inizializzato
- }
- String prefix = javaProperty ? JAVA_WRAPPED_PREFIX : ENV_WRAPPED_PREFIX;
- String tmp = this.reader.getValue_convertEnvProperties(prefix+key);
- if(tmp!=null && StringUtils.isNotEmpty(tmp.trim())) {
- if("true".equals(tmp.trim())) {
- return true;
- }
- else if("false".equals(tmp.trim())) {
- return false;
- }
- else {
- throw new UtilsException(prefix+key+" with value '"+tmp.trim()+ERROR_SUFFIX_UNKNOW);
- }
- }
- else {
- return true; // default
- }
- }
-
- private boolean isUnwrapAfterGovWayStartup(boolean javaProperty, String key) throws UtilsException {
- if(this.reader==null) {
- return false; // non inizializzato
- }
- String prefix = javaProperty ? JAVA_UNWRAP_AFTER_GOVWAY_STARTUP_PREFIX : ENV_UNWRAP_AFTER_GOVWAY_STARTUP_PREFIX;
- String tmp = this.reader.getValue_convertEnvProperties(prefix+key);
- if(tmp!=null && StringUtils.isNotEmpty(tmp.trim())) {
- if("true".equals(tmp.trim())) {
- return true;
- }
- else if("false".equals(tmp.trim())) {
- return false;
- }
- else {
- throw new UtilsException(prefix+key+" with value '"+tmp.trim()+ERROR_SUFFIX_UNKNOW);
- }
- }
- else {
- return false; // default
- }
- }
-
- @Override
- protected boolean obfuscate(boolean java, String key) {
- try {
- return isWrapped(java, key);
- }catch(Exception e) {
- return true;
- }
- }
-
- private boolean isWrappedBySecurity(boolean javaProperty, String key) throws UtilsException {
- if(this.reader==null) {
- return false; // non inizializzato
- }
- String pSecurityName = javaProperty ? JAVA_SECURITY_PREFIX : ENV_SECURITY_PREFIX;
- String tmp = this.reader.getValue_convertEnvProperties(pSecurityName+key);
- if(tmp!=null && StringUtils.isNotEmpty(tmp.trim())) {
- return true;
- }
- else {
- return isWrappedBySecurityKms(javaProperty, key);
- }
- }
- private boolean isWrappedBySecurityKms(boolean javaProperty, String key) throws UtilsException {
- String pKmsName = javaProperty ? JAVA_KMS_PREFIX : ENV_KMS_PREFIX;
- String tmp = this.reader.getValue_convertEnvProperties(pKmsName+key);
- if(tmp!=null && StringUtils.isNotEmpty(tmp.trim())) {
- return false;
- }
- else {
- pKmsName = javaProperty ? JAVA_KSM_PREFIX_DEPRECATED : ENV_KSM_PREFIX_DEPRECATED;
- tmp = this.reader.getValue_convertEnvProperties(pKmsName+key);
- if(tmp!=null && StringUtils.isNotEmpty(tmp.trim())) {
- return false;
- }
- }
-
- if(this.defaultUnwrapModeSecurity!=null) {
- return this.defaultUnwrapModeSecurity.booleanValue();
- }
- else {
- String prefix = javaProperty ? JAVA_PREFIX : ENV_PREFIX;
- throw new UtilsException("("+prefix+key+ERROR_DEFAULT_MODE_NOT_FOUND);
- }
- }
-
- private String getUnwrapId(boolean javaProperty, String key) throws UtilsException {
- if(this.reader==null) {
- return null; // non inizializzato
- }
- String pSecurityName = javaProperty ? JAVA_SECURITY_PREFIX : ENV_SECURITY_PREFIX;
- String tmp = this.reader.getValue_convertEnvProperties(pSecurityName+key);
- if(tmp!=null && StringUtils.isNotEmpty(tmp.trim())) {
- return tmp.trim();
- }
- else {
- return getUnwrapIdByKms(javaProperty, key);
- }
- }
- private String getUnwrapIdByKms(boolean javaProperty, String key) throws UtilsException {
- String pKmsName = javaProperty ? JAVA_KMS_PREFIX : ENV_KMS_PREFIX;
- String tmp = this.reader.getValue_convertEnvProperties(pKmsName+key);
- if(tmp!=null && StringUtils.isNotEmpty(tmp.trim())) {
- return tmp.trim();
- }
- else {
- pKmsName = javaProperty ? JAVA_KSM_PREFIX_DEPRECATED : ENV_KSM_PREFIX_DEPRECATED;
- tmp = this.reader.getValue_convertEnvProperties(pKmsName+key);
- if(tmp!=null && StringUtils.isNotEmpty(tmp.trim())) {
- return tmp.trim();
- }
- }
-
- if(this.defaultUnwrapId!=null) {
- return this.defaultUnwrapId;
- }
- else {
- String prefix = javaProperty ? JAVA_PREFIX : ENV_PREFIX;
- throw new UtilsException("("+prefix+key+ERROR_DEFAULT_MODE_NOT_FOUND);
- }
- }
-
- private DriverBYOK getDriverBYOK(String securityId) {
- if(!this.mapDriverSecurity.containsKey(securityId)) {
- initDriverBYOK(securityId);
- }
- return this.mapDriverSecurity.get(securityId);
- }
- private synchronized void initDriverBYOK(String securityId) {
- this.mapDriverSecurity.computeIfAbsent(securityId, k -> new DriverBYOK(this.log, this.securityPolicy, this.securityRemotePolicy,
- newDynamicMap(), this.checkJmxPrefixOperazioneNonRiuscita));
- }
- private Map<String, Object> newDynamicMap(){
- if(this.dynamicMap==null) {
- initDynamicMap();
- }
- // cro una nuova mappa per non sovrascrivere le varie variabili di input
- Map<String, Object> map = new HashMap<>();
- if(this.dynamicMap!=null && !this.dynamicMap.isEmpty()) {
- map.putAll(this.dynamicMap);
- }
- return map;
- }
- private synchronized void initDynamicMap() {
- if(this.dynamicMap==null) {
- this.dynamicMap = DriverBYOK.buildDynamicMap(this.log);
- }
- }
-
- private Map<String, String> readKmsInputMap(String kmsId) throws UtilsException{
- Map<String, String> map = new HashMap<>();
- Properties p = this.reader.readProperties_convertEnvProperties(getKmsParamPrefixPropertyName(kmsId));
- if(p==null || p.isEmpty()) {
- p = this.reader.readProperties_convertEnvProperties(getKsmParamPrefixPropertyNameDeprecated(kmsId));
- }
- if(p!=null && !p.isEmpty()) {
- for (Map.Entry<Object,Object> entry : p.entrySet()) {
- if(entry.getKey() instanceof String && entry.getValue() instanceof String) {
- map.put((String)entry.getKey(), (String)entry.getValue());
- }
- }
- }
- return map;
- }
- private Map<String, String> getKmsInputMap(String kmsId) {
- if(!this.mapKmsInput.containsKey(kmsId)) {
- initKmsInputMap(kmsId);
- }
- return this.mapKmsInput.get(kmsId);
- }
- private synchronized void initKmsInputMap(String kmsId) {
- this.mapKmsInput.computeIfAbsent(kmsId, k -> {
- try {
- return readKmsInputMap(kmsId);
- } catch (UtilsException e) {
- throw new UtilsRuntimeException(e.getMessage(),e);
- }
- });
- }
-
- private String unwrapByKmsId(String value, String kmsId) throws UtilsException {
-
- Map<String, String> inputMap = getKmsInputMap(kmsId);
- BYOKRequestParams params = DriverBYOK.getBYOKRequestParamsByKmsId(kmsId, inputMap, newDynamicMap());
- if(!BYOKMode.UNWRAP.equals(params.getConfig().getMode())) {
- throw new UtilsException("Kms '"+kmsId+"' unusable in unwrap operation");
- }
- BYOKInstance instance = BYOKInstance.newInstance(this.log, params, value.getBytes());
- byte[] unwrappedValue = DriverBYOK.processInstance(instance, this.checkJmxPrefixOperazioneNonRiuscita);
- return new String(unwrappedValue);
- }
- }