HSMManager.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.utils.certificate.hsm;
- import java.io.File;
- import java.io.FileInputStream;
- import java.util.ArrayList;
- import java.util.Enumeration;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Properties;
- import org.openspcoop2.utils.UtilsException;
- import org.openspcoop2.utils.certificate.KeyStore;
- import org.openspcoop2.utils.properties.PropertiesReader;
- import org.slf4j.Logger;
- /**
- * HSMManager
- *
- * @author Poli Andrea (apoli@link.it)
- * @author $Author$
- * @version $Rev$, $Date$
- */
- public class HSMManager {
- private static HSMManager staticInstance;
- public static synchronized void init(File f, boolean throwNotExists, Logger log, boolean accessKeystore) throws UtilsException {
- if(staticInstance==null) {
- staticInstance = new HSMManager(f, throwNotExists, log, accessKeystore);
- }
- }
- public static HSMManager getInstance() {
- // spotbugs warning 'SING_SINGLETON_GETTER_NOT_SYNCHRONIZED': l'istanza viene creata allo startup
- if (staticInstance == null) {
- synchronized (HSMManager.class) {
- if (staticInstance == null) {
- return null;
- }
- }
- }
- return staticInstance;
- }
-
- /*
- * Consente di inizializzare una serie di keystore hardware
- *
- * La configurazione di ogni keystore deve essere definita nel file hsm.properties fornito come argomento dove la sintassi utilizzabile è la seguente
- *
- * hsm.<idKeystore>.provider: [required su nodo run] classe del provider che deve essere stata registrata in JVM/conf/security/java.security o andrà aggiunta dinamicamente tramite opzione successiva
- * hsm.<idKeystore>.provider.add: [optional, default false] indica se il provider fornito deve essere aggiunto (se non già presente)
- * hsm.<idKeystore>.provider.configFile: [optional] se fornito verrà utilizzato per configurare il provider tramite l'istruzione 'configure(configFile)'
- * hsm.<idKeystore>.provider.config: [optional] se fornito verrà utilizzato per configurare il provider tramite l'istruzione 'configure(config)'
- * hsm.<idKeystore>.pin: [required su nodo run] pin per accedere al keystore
- * hsm.<idKeystore>.keystoreType.label: [required su nodo run] label associata al keystore e visualizzata nelle console
- * hsm.<idKeystore>.keystoreType: [required su nodo run] tipo associato al keystore ed utilizzato per istanziarlo tramite l'istruzione 'KeyStore.getInstance(keystoreType, provider)'
- * hsm.<idKeystore>.usableAsTrustStore: [optional, default false] indica se il keystore è utilizzabile anche come truststore di certificati
- * hsm.<idKeystore>.usableAsSecretKeyStore: [optional, default false] indica se il keystore è utilizzabile anche come repository di chiavi segrete
- *
- * Un disponibile in HSM.example
- *
- **/
-
- private HashMap<String, HSMKeystore> hsmKeystoreMapIDtoConfig = new HashMap<>();
-
- private HashMap<String, String> hsmKeystoreMapKeystoreTypeLabelToID = new HashMap<>();
-
- private HSMManager(File f, boolean throwNotExists, Logger log, boolean accessKeystore) throws UtilsException {
- String prefixFile = "File '"+f.getAbsolutePath()+"'";
- if(!f.exists()) {
- if(throwNotExists) {
- throw new UtilsException(prefixFile+" not exists");
- }
- }
- else {
- if(!f.canRead()) {
- throw new UtilsException(prefixFile+" cannot read");
- }
- Properties p = new Properties();
- try {
- try(FileInputStream fin = new FileInputStream(f)){
- p.load(fin);
- }
- }catch(Exception t) {
- throw new UtilsException(prefixFile+"; initialize error: "+t.getMessage(),t);
- }
- init(p, log, accessKeystore);
- }
- }
- /**private HSMManager(Properties p, Logger log, boolean accessKeystore) throws UtilsException {
- init(p, log, accessKeystore);
- }*/
- private void init(Properties p, Logger log, boolean accessKeystore) throws UtilsException {
-
- List<String> idKeystore = new ArrayList<>();
-
- if(p!=null && !p.isEmpty()) {
- init(p, idKeystore);
- }
-
- if(!idKeystore.isEmpty()) {
- for (String idK : idKeystore) {
- init(p, log, accessKeystore, idK);
- }
- }
- else {
- log.warn("La configurazione fornita per HSM non contiene alcun keystore");
- }
- }
- private void init(Properties p, List<String> idKeystore) {
- Enumeration<?> enKeys = p.keys();
- while (enKeys.hasMoreElements()) {
- Object object = enKeys.nextElement();
- if(object instanceof String) {
- String key = (String) object;
- init(key, idKeystore);
- }
- }
- }
- private void init(String key, List<String> idKeystore) {
- if(key.startsWith(HSMCostanti.PROPERTY_PREFIX) && key.length()>(HSMCostanti.PROPERTY_PREFIX.length())) {
- String tmp = key.substring(HSMCostanti.PROPERTY_PREFIX.length());
- if(tmp!=null && tmp.contains(".")) {
- int indeoOf = tmp.indexOf(".");
- if(indeoOf>0) {
- String idK = tmp.substring(0,indeoOf);
- if(!idKeystore.contains(idK)) {
- idKeystore.add(idK);
- }
- }
- }
- }
- }
- private void init(Properties p, Logger log, boolean accessKeystore, String idK) throws UtilsException {
- String prefix = HSMCostanti.PROPERTY_PREFIX + idK + ".";
- PropertiesReader pReader = new PropertiesReader(p, true);
- Properties pKeystore = pReader.readProperties_convertEnvProperties(prefix);
- HSMKeystore hsmKeystore = new HSMKeystore(idK, pKeystore, log, accessKeystore);
-
- boolean alreadyExists = false;
- for (String type : this.hsmKeystoreMapKeystoreTypeLabelToID.keySet()) {
- if(hsmKeystore.getKeystoreTypeLabel().equalsIgnoreCase(type)) {
- alreadyExists = true;
- }
- }
- if(alreadyExists) {
- throw new UtilsException("Same keystore type label found for keystore '"+this.hsmKeystoreMapKeystoreTypeLabelToID.get(hsmKeystore.getKeystoreTypeLabel())+"' e '"+idK+"'");
- }
- this.hsmKeystoreMapKeystoreTypeLabelToID.put(hsmKeystore.getKeystoreTypeLabel(), idK);
-
- this.hsmKeystoreMapIDtoConfig.put(idK, hsmKeystore);
- String d = "HSMKeystore "+idK+" registrato (keystoreType:"+hsmKeystore.getKeystoreTypeLabel()+")";
- log.info(d);
- }
-
- public void providerInit(Logger log, boolean uniqueProviderInstance) throws UtilsException {
- if(this.hsmKeystoreMapIDtoConfig!=null && !this.hsmKeystoreMapIDtoConfig.isEmpty()) {
- for (Map.Entry<String,HSMKeystore> entry : this.hsmKeystoreMapIDtoConfig.entrySet()) {
- String idK = entry.getKey();
- HSMKeystore hsmKeystore = this.hsmKeystoreMapIDtoConfig.get(idK);
- hsmKeystore.init(log, uniqueProviderInstance);
- }
- }
- }
-
- private HSMKeystore getHSMKeystore(String keystoreTypeLabel) throws UtilsException {
- if(!this.hsmKeystoreMapKeystoreTypeLabelToID.containsKey(keystoreTypeLabel)) {
- throw new UtilsException("Keystore type '"+keystoreTypeLabel+"' unknown");
- }
- String idK = this.hsmKeystoreMapKeystoreTypeLabelToID.get(keystoreTypeLabel);
- if(!this.hsmKeystoreMapIDtoConfig.containsKey(idK)) {
- throw new UtilsException("Keystore config for type '"+keystoreTypeLabel+"' unknown ? (id:"+idK+")");
- }
- return this.hsmKeystoreMapIDtoConfig.get(idK);
- }
-
- public KeyStore getKeystore(String keystoreTypeLabel) throws UtilsException {
- HSMKeystore hsmKeystore = getHSMKeystore(keystoreTypeLabel);
- return hsmKeystore.getInstance();
- }
-
- public boolean isUsableAsTrustStore(String keystoreTypeLabel) throws UtilsException {
- HSMKeystore hsmKeystore = getHSMKeystore(keystoreTypeLabel);
- return hsmKeystore.isUsableAsTrustStore();
- }
-
- public boolean isUsableAsSecretKeyStore(String keystoreTypeLabel) throws UtilsException {
- HSMKeystore hsmKeystore = getHSMKeystore(keystoreTypeLabel);
- return hsmKeystore.isUsableAsSecretKeyStore();
- }
-
- public List<String> getKeystoreTypes() {
- List<String> l = new ArrayList<>();
- if(!this.hsmKeystoreMapKeystoreTypeLabelToID.isEmpty()) {
- for (String type : this.hsmKeystoreMapKeystoreTypeLabelToID.keySet()) {
- l.add(type);
- }
- }
- return l;
- }
-
- public boolean existsKeystoreType(String keystoreTypeLabel) {
- if(keystoreTypeLabel==null) {
- return false;
- }
- for (String type : this.hsmKeystoreMapKeystoreTypeLabelToID.keySet()) {
- if(keystoreTypeLabel.equalsIgnoreCase(type)) {
- return true;
- }
- }
- return false;
- }
- }