MerlinKeystore.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */

  20. package org.openspcoop2.security.keystore;

  21. import java.io.Serializable;
  22. import java.security.Key;
  23. import java.security.KeyStore;
  24. import java.security.cert.Certificate;
  25. import java.util.Properties;

  26. import org.openspcoop2.security.SecurityException;
  27. import org.openspcoop2.utils.certificate.byok.BYOKRequestParams;
  28. import org.openspcoop2.utils.certificate.hsm.HSMManager;

  29. /**
  30.  * MerlinKeystore
  31.  *
  32.  * @author Andrea Poli (apoli@link.it)
  33.  * @author $Author$
  34.  * @version $Rev$, $Date$
  35.  */
  36. public class MerlinKeystore implements Serializable {

  37.     /**
  38.      *
  39.      */
  40.     private static final long serialVersionUID = 1L;
  41.    
  42.     private transient org.openspcoop2.utils.certificate.KeyStore ks = null;
  43.    
  44.     private byte[] ksBytes;
  45.     private String tipoStore = null;
  46.     private String pathStore = null;
  47.     private String passwordStore = null;
  48.     private String passwordPrivateKey = null;
  49.    
  50.     private boolean hsm;
  51.    
  52.     @Override
  53.     public String toString() {
  54.         StringBuilder bf = new StringBuilder();
  55.         bf.append("KeyStore (").append(this.tipoStore).append(") ").append(this.pathStore);
  56.         return bf.toString();
  57.     }
  58.    
  59.     public MerlinKeystore(String propertyFilePath) throws SecurityException{
  60.         this.initMerlinKeystoreEngine(propertyFilePath, null, false,
  61.                 null);
  62.     }
  63.     public MerlinKeystore(String propertyFilePath,
  64.             BYOKRequestParams requestParams) throws SecurityException{
  65.         this.initMerlinKeystoreEngine(propertyFilePath, null, false,
  66.                 requestParams);
  67.     }
  68.     public MerlinKeystore(String propertyFilePath,String passwordPrivateKey) throws SecurityException{
  69.         this.initMerlinKeystoreEngine(propertyFilePath, passwordPrivateKey, true,
  70.                 null);
  71.     }
  72.     public MerlinKeystore(String propertyFilePath,String passwordPrivateKey,
  73.             BYOKRequestParams requestParams) throws SecurityException{
  74.         this.initMerlinKeystoreEngine(propertyFilePath, passwordPrivateKey, true,
  75.                 requestParams);
  76.     }
  77.     private void initMerlinKeystoreEngine(String propertyFilePath,String passwordPrivateKey, boolean privatePasswordRequired,
  78.             BYOKRequestParams requestParams) throws SecurityException{
  79.        
  80.         Properties propStore = StoreUtils.readProperties("PropertyFilePath", propertyFilePath);
  81.         this.initMerlinKeystoreEngine(propStore,passwordPrivateKey, privatePasswordRequired,
  82.                 requestParams);
  83.                
  84.     }
  85.    
  86.     public MerlinKeystore(Properties propStore) throws SecurityException{
  87.         this.initMerlinKeystoreEngine(propStore,null, false,
  88.                 null);
  89.     }
  90.     public MerlinKeystore(Properties propStore,
  91.             BYOKRequestParams requestParams) throws SecurityException{
  92.         this.initMerlinKeystoreEngine(propStore,null, false,
  93.                 requestParams);
  94.     }
  95.     public MerlinKeystore(Properties propStore,String passwordPrivateKey) throws SecurityException{
  96.         this.initMerlinKeystoreEngine(propStore,passwordPrivateKey, true,
  97.                 null);
  98.     }
  99.     public MerlinKeystore(Properties propStore,String passwordPrivateKey,
  100.             BYOKRequestParams requestParams) throws SecurityException{
  101.         this.initMerlinKeystoreEngine(propStore,passwordPrivateKey, true,
  102.                 requestParams);
  103.     }
  104.     private void initMerlinKeystoreEngine(Properties propStore,String passwordPrivateKey, boolean privatePasswordRequired,
  105.             BYOKRequestParams requestParams) throws SecurityException{
  106.        
  107.         try{
  108.             if(propStore==null){
  109.                 throw new SecurityException("Properties per lo Store non indicato");
  110.             }
  111.            
  112.             this.tipoStore = propStore.getProperty(KeystoreConstants.PROPERTY_KEYSTORE_TYPE);
  113.             if(this.tipoStore!=null){
  114.                 this.tipoStore = this.tipoStore.trim();
  115.             }else{
  116.                 this.tipoStore = KeyStore.getDefaultType();
  117.             }
  118.            
  119.             this.pathStore = propStore.getProperty(KeystoreConstants.PROPERTY_KEYSTORE_PATH);
  120.            
  121.             this.passwordStore = propStore.getProperty(KeystoreConstants.PROPERTY_KEYSTORE_PASSWORD);
  122.                        
  123.             init(passwordPrivateKey, privatePasswordRequired,
  124.                     requestParams);
  125.            
  126.         }catch(Exception e){
  127.             throw new SecurityException(e.getMessage(),e);
  128.         }
  129.        
  130.     }
  131.        
  132.     public MerlinKeystore(String pathStore,String tipoStore,String passwordStore) throws SecurityException{
  133.         initMerlinKeystoreEngine(pathStore,tipoStore,passwordStore,null, false,
  134.                 null);
  135.     }
  136.     public MerlinKeystore(String pathStore,String tipoStore,String passwordStore,
  137.             BYOKRequestParams requestParams) throws SecurityException{
  138.         initMerlinKeystoreEngine(pathStore,tipoStore,passwordStore,null, false,
  139.                 requestParams);
  140.     }
  141.     public MerlinKeystore(String pathStore,String tipoStore,String passwordStore,String passwordPrivateKey) throws SecurityException{
  142.         initMerlinKeystoreEngine(pathStore,tipoStore,passwordStore,passwordPrivateKey, true,
  143.                 null);
  144.     }
  145.     public MerlinKeystore(String pathStore,String tipoStore,String passwordStore,String passwordPrivateKey,
  146.             BYOKRequestParams requestParams) throws SecurityException{
  147.         initMerlinKeystoreEngine(pathStore,tipoStore,passwordStore,passwordPrivateKey, true,
  148.                 requestParams);
  149.     }
  150.     public void initMerlinKeystoreEngine(String pathStore,String tipoStore,String passwordStore,String passwordPrivateKey, boolean privatePasswordRequired,
  151.             BYOKRequestParams requestParams) throws SecurityException{
  152.            
  153.         this.pathStore = pathStore;
  154.         this.tipoStore = tipoStore;
  155.         this.passwordStore = passwordStore;
  156.        
  157.         init(passwordPrivateKey, privatePasswordRequired,
  158.                 requestParams);
  159.        
  160.     }
  161.    
  162.     public MerlinKeystore(byte[]bytesKeystore,String tipoStore,String passwordStore) throws SecurityException{
  163.         initMerlinKeystoreEngine(bytesKeystore,tipoStore,passwordStore,null, false,
  164.                 null);
  165.     }
  166.     public MerlinKeystore(byte[]bytesKeystore,String tipoStore,String passwordStore,
  167.             BYOKRequestParams requestParams) throws SecurityException{
  168.         initMerlinKeystoreEngine(bytesKeystore,tipoStore,passwordStore,null, false,
  169.                 requestParams);
  170.     }
  171.     public MerlinKeystore(byte[]bytesKeystore,String tipoStore,String passwordStore,String passwordPrivateKey) throws SecurityException{
  172.         initMerlinKeystoreEngine(bytesKeystore,tipoStore,passwordStore,passwordPrivateKey, true,
  173.                 null);
  174.     }
  175.     public MerlinKeystore(byte[]bytesKeystore,String tipoStore,String passwordStore,String passwordPrivateKey,
  176.             BYOKRequestParams requestParams) throws SecurityException{
  177.         initMerlinKeystoreEngine(bytesKeystore,tipoStore,passwordStore,passwordPrivateKey, true,
  178.                 requestParams);
  179.     }
  180.     public void initMerlinKeystoreEngine(byte[]bytesKeystore,String tipoStore,String passwordStore,String passwordPrivateKey, boolean privatePasswordRequired,
  181.             BYOKRequestParams requestParams) throws SecurityException{
  182.            
  183.         this.ksBytes = bytesKeystore;
  184.         this.tipoStore = tipoStore;
  185.         this.passwordStore = passwordStore;
  186.        
  187.         init(passwordPrivateKey, privatePasswordRequired,
  188.                 requestParams);
  189.        
  190.     }
  191.    
  192.     private void init(String passwordPrivateKey, boolean privatePasswordRequired,
  193.             BYOKRequestParams requestParams) throws SecurityException{
  194.         try{
  195.             if(this.tipoStore==null){
  196.                 throw new SecurityException("Tipo dello Store non indicato");
  197.             }
  198.             if(this.passwordStore==null){
  199.                 throw new SecurityException("Password dello Store non indicata");
  200.             }
  201.            
  202.             HSMManager hsmManager = HSMManager.getInstance();
  203.             if(hsmManager!=null) {
  204.                 this.hsm = hsmManager.existsKeystoreType(this.tipoStore);
  205.             }
  206.            
  207.             if(!this.hsm) {
  208.                 initKsBytes(requestParams);
  209.             }
  210.            
  211.             this.initKS();
  212.            
  213.             if(passwordPrivateKey==null && privatePasswordRequired){
  214.                 if(this.pathStore!=null) {
  215.                     throw new SecurityException("Password chiave privata non indicata per lo Store ["+this.pathStore+"] ");
  216.                 }
  217.                 else {
  218.                     throw new SecurityException("Password chiave privata non indicata per lo Store ");
  219.                 }
  220.             }
  221.             this.passwordPrivateKey = passwordPrivateKey;
  222.            
  223.         }catch(Exception e){
  224.             throw new SecurityException(e.getMessage(),e);
  225.         }
  226.     }
  227.    
  228.     private void initKsBytes(BYOKRequestParams requestParams) throws SecurityException {
  229.        
  230.         if(this.ksBytes==null && this.pathStore==null){
  231.             throw new SecurityException("Path per lo Store non indicato");
  232.         }

  233.         if(this.ksBytes==null) {
  234.             this.ksBytes = StoreUtils.readContent("Path", this.pathStore);
  235.         }
  236.        
  237.         if(requestParams!=null) {
  238.             this.ksBytes = StoreUtils.unwrapBYOK(this.ksBytes, requestParams);
  239.         }
  240.     }
  241.    
  242.     public boolean isHsm() {
  243.         return this.hsm;
  244.     }

  245.     private void checkInit() throws SecurityException{
  246.         if(this.ks==null) {
  247.             this.initKS();
  248.         }
  249.     }
  250.     private synchronized void initKS() throws SecurityException{
  251.         if(this.ks==null) {
  252.             try{
  253.                 if(this.hsm) {
  254.                     this.ks = HSMManager.getInstance().getKeystore(this.tipoStore);
  255.                 }
  256.                 else {
  257.                                        
  258.                     this.ks = new org.openspcoop2.utils.certificate.KeyStore(this.ksBytes, this.tipoStore, this.passwordStore);
  259.                    
  260.                     // non utilizzabile in hsm, si ottiene errore: java.lang.UnsupportedOperationException: trusted certificates may only be set by token initialization application
  261.                     // at jdk.crypto.cryptoki/sun.security.pkcs11.P11KeyStore.engineSetEntry(P11KeyStore.java:1022)
  262.                     FixTrustAnchorsNotEmpty.addCertificate(this.ks.getKeystore());
  263.                 }
  264.             }
  265.             catch(Exception e){
  266.                 throw new SecurityException(e.getMessage(),e);
  267.             }
  268.         }
  269.     }
  270.    
  271.    
  272.     public Key getKey(String alias) throws SecurityException {
  273.         return this.getKey(alias, this.passwordPrivateKey);
  274.     }
  275.     public Key getKey(String alias, String password) throws SecurityException {
  276.         if(alias==null) {
  277.             throw new SecurityException("Alias della chiave non fornita");
  278.         }
  279.         if(password==null) {
  280.             throw new SecurityException("Password della chiave non fornita");
  281.         }
  282.         this.checkInit(); // per ripristino da Serializable
  283.         try {
  284.             return this.ks.getPrivateKey(alias, password);
  285.         }catch(Exception e){
  286.             throw new SecurityException(e.getMessage(),e);
  287.         }
  288.     }
  289.    
  290.     public Certificate getCertificate(String alias) throws SecurityException {
  291.         if(alias==null) {
  292.             throw new SecurityException("Alias non fornito");
  293.         }
  294.         this.checkInit(); // per ripristino da Serializable
  295.         try{
  296.             return this.ks.getCertificate(alias);
  297.         }catch(Exception e){
  298.             throw new SecurityException(e.getMessage(),e);
  299.         }
  300.     }

  301.     public org.openspcoop2.utils.certificate.KeyStore getKeyStore() throws SecurityException {
  302.         this.checkInit(); // per ripristino da Serializable
  303.         try{
  304.             return this.ks;
  305.         }catch(Exception e){
  306.             throw new SecurityException(e.getMessage(),e);
  307.         }
  308.     }

  309. }