MultiKeystore.java
/*
* GovWay - A customizable API Gateway
* https://govway.org
*
* Copyright (c) 2005-2024 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.security.keystore;
import java.io.Serializable;
import java.security.Key;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.openspcoop2.security.SecurityException;
import org.openspcoop2.utils.LoggerWrapperFactory;
import org.openspcoop2.utils.certificate.KeyStore;
import org.openspcoop2.utils.certificate.byok.BYOKRequestParams;
/**
* MultiKeystore
*
* @author Andrea Poli (apoli@link.it)
* @author $Author$
* @version $Rev$, $Date$
*/
public class MultiKeystore implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private static final String ALIASES = "aliases";
private static final String KEYSTORE_TYPE = ".keystore.type";
private static final String KEYSTORE_PATH = ".keystore.path";
private static final String KEYSTORE_PASSWORD = ".keystore.password";
private static final String KEY_ALIAS = ".key.alias";
private static final String KEY_PASSWORD = ".key.password";
private static final String KEY_VALUE = ".key.value";
private static final String KEY_ALGORITHM = ".key.algorithm";
private List<String> aliasesList = new ArrayList<>();
private Map<String, Serializable> keystores = new HashMap<>();
private Map<String, String> mappingAliasToKeystorePath = new HashMap<>();
private Map<String, String> mappingAliasToKeystorePassword = new HashMap<>();
private Map<String, String> mappingAliasToKeystoreType = new HashMap<>();
private Map<String, String> mappingAliasToKeyAlias = new HashMap<>();
private Map<String, String> mappingAliasToKeyPassword = new HashMap<>();
@Override
public String toString() {
StringBuilder bf = new StringBuilder();
bf.append("MultiKeystore ").append(this.aliasesList);
return bf.toString();
}
public MultiKeystore(String propertyFilePath) throws SecurityException{
this(propertyFilePath, null);
}
public MultiKeystore(String propertyFilePath, BYOKRequestParams requestParams) throws SecurityException{
try{
Properties multiProperties = StoreUtils.readProperties("MultiProperties", propertyFilePath);
String keyAliases = getProperty(multiProperties, MultiKeystore.ALIASES);
String [] tmp = keyAliases.split(",");
for (int i = 0; i < tmp.length; i++) {
if(!this.aliasesList.contains(tmp[i].trim()))
this.aliasesList.add(tmp[i].trim());
}
for (String alias : this.aliasesList) {
String keyAlias = getSafeKeyAlias(alias, multiProperties);
String keyPassword = getProperty(multiProperties, alias+MultiKeystore.KEY_PASSWORD);
String keyValue = multiProperties.getProperty(alias+MultiKeystore.KEY_VALUE);
if(keyValue!=null){
// Configurazione con keyValue fornita direttamente
String keyAlgorithm = getProperty(multiProperties, alias+MultiKeystore.KEY_ALGORITHM);
addSymmetricKeystore(alias, keyAlias, keyValue, keyAlgorithm, requestParams);
}
else{
// Configurazione con MerlinKeystore
String keystoreType = getProperty(multiProperties, alias+MultiKeystore.KEYSTORE_TYPE);
String keystorePath = getProperty(multiProperties, alias+MultiKeystore.KEYSTORE_PATH);
String keystorePassword = getProperty(multiProperties, alias+MultiKeystore.KEYSTORE_PASSWORD);
addMerlinKeystore(alias, keyAlias, keystoreType, keystorePath, keystorePassword, keyPassword, requestParams);
}
this.mappingAliasToKeyAlias.put(alias, keyAlias);
this.mappingAliasToKeyPassword.put(alias, keyPassword);
}
}catch(Exception e){
throw new SecurityException(e.getMessage(),e);
}
}
private String getSafeKeyAlias(String alias, Properties multiProperties) {
String keyAlias = null;
try{
keyAlias = getProperty(multiProperties, alias+MultiKeystore.KEY_ALIAS);
}catch(Exception e){
keyAlias = alias;
}
return keyAlias;
}
private void addSymmetricKeystore(String alias, String keyAlias, String keyValue, String keyAlgorithm, BYOKRequestParams requestParams) {
try {
this.keystores.put(alias, new SymmetricKeystore(keyAlias, keyValue, keyAlgorithm, requestParams));
}catch(Exception e) {
String idKeystore = "!!! Errore durante il caricamento del SymmetricKeystore !!! [keyAlias:"+keyAlias+"] ";
LoggerWrapperFactory.getLogger(MultiKeystore.class).error(idKeystore+e.getMessage(),e);
}
}
private void addMerlinKeystore(String alias, String keyAlias, String keystoreType, String keystorePath, String keystorePassword, String keyPassword, BYOKRequestParams requestParams) {
try {
this.keystores.put(alias, new MerlinKeystore(keystorePath, keystoreType, keystorePassword, keyPassword, requestParams));
this.mappingAliasToKeystoreType.put(alias, keystoreType);
this.mappingAliasToKeystorePath.put(alias, keystorePath);
this.mappingAliasToKeystorePassword.put(alias, keystorePassword);
}catch(Exception e) {
String idKeystore = "!!! Errore durante il caricamento del MerlinKeystore !!! [keyAlias:"+keyAlias+"] ";
LoggerWrapperFactory.getLogger(MultiKeystore.class).error(idKeystore+e.getMessage(),e);
}
}
private String getProperty(Properties multiProperties,String property)throws SecurityException{
if(!multiProperties.containsKey(property)){
throw new SecurityException("Proprieta' ["+property+"] non trovata nel MultiProperties file");
}
else{
return multiProperties.getProperty(property).trim();
}
}
private String getErrorAlias(String alias) {
return "Alias["+alias+"] non trovato nella configurazione MultiKeystore";
}
public Key getKey(String alias) throws SecurityException {
try{
if(!this.aliasesList.contains(alias)){
throw new SecurityException(getErrorAlias(alias));
}
Object keystore = this.keystores.get(alias);
if(keystore==null) {
throw new SecurityException("Non esiste un keystore per l'alias["+alias+"]; verificare che non sia avvenuti errori durante l'inizializzazione (MultiKeystore)");
}
if(keystore instanceof MerlinKeystore){
return ((MerlinKeystore)keystore).getKey(this.mappingAliasToKeyAlias.get(alias));
}
else if(keystore instanceof SymmetricKeystore){
return ((SymmetricKeystore)keystore).getKey();
}
else{
throw new SecurityException("Tipo di Keystore non supportato: "+keystore.getClass().getName());
}
}catch(Exception e){
throw new SecurityException(e.getMessage(),e);
}
}
public boolean existsAlias(String alias){
return this.aliasesList.contains(alias);
}
public KeyStore getKeyStore(String alias) throws SecurityException {
try{
if(!this.aliasesList.contains(alias)){
throw new SecurityException(getErrorAlias(alias));
}
Object keystore = this.keystores.get(alias);
if(keystore==null) {
throw new SecurityException("Non esiste un keystore per l'alias["+alias+"]; verificare che non sia avvenuti errori durante l'inizializzazione (MultiKeystore)");
}
if(keystore instanceof MerlinKeystore){
return ((MerlinKeystore)keystore).getKeyStore();
}
else if(keystore instanceof SymmetricKeystore){
return ((SymmetricKeystore)keystore).getKeyStore();
}
else{
throw new SecurityException("Tipo di Keystore non supportato: "+keystore.getClass().getName());
}
}catch(Exception e){
throw new SecurityException(e.getMessage(),e);
}
}
public String getKeyAlias(String alias) throws SecurityException {
try{
if(!this.aliasesList.contains(alias)){
throw new SecurityException(getErrorAlias(alias));
}
return this.mappingAliasToKeyAlias.get(alias);
}catch(Exception e){
throw new SecurityException(e.getMessage(),e);
}
}
public String getKeyPassword(String alias) throws SecurityException {
try{
if(!this.aliasesList.contains(alias)){
throw new SecurityException(getErrorAlias(alias));
}
return this.mappingAliasToKeyPassword.get(alias);
}catch(Exception e){
throw new SecurityException(e.getMessage(),e);
}
}
public String getKeystorePath(String alias) throws SecurityException {
try{
if(!this.aliasesList.contains(alias)){
throw new SecurityException(getErrorAlias(alias));
}
return this.mappingAliasToKeystorePath.get(alias);
}catch(Exception e){
throw new SecurityException(e.getMessage(),e);
}
}
public String getKeystorePassword(String alias) throws SecurityException {
try{
if(!this.aliasesList.contains(alias)){
throw new SecurityException(getErrorAlias(alias));
}
return this.mappingAliasToKeystorePassword.get(alias);
}catch(Exception e){
throw new SecurityException(e.getMessage(),e);
}
}
public String getKeystoreType(String alias) throws SecurityException {
try{
if(!this.aliasesList.contains(alias)){
throw new SecurityException(getErrorAlias(alias));
}
return this.mappingAliasToKeystoreType.get(alias);
}catch(Exception e){
throw new SecurityException(e.getMessage(),e);
}
}
public String getInternalConfigAlias(String keyAlias) throws SecurityException {
try{
if(!this.mappingAliasToKeyAlias.containsValue(keyAlias)){
throw new SecurityException(getErrorAlias(keyAlias));
}
for (Map.Entry<String,String> entry : this.mappingAliasToKeyAlias.entrySet()) {
if(entry.getValue().equals(keyAlias)) {
return entry.getKey();
}
}
throw new SecurityException(getErrorAlias(keyAlias));
}catch(Exception e){
throw new SecurityException(e.getMessage(),e);
}
}
}