KeyStore.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.utils.certificate;

  21. import java.io.File;
  22. import java.security.Key;
  23. import java.security.PrivateKey;
  24. import java.security.PublicKey;
  25. import java.security.cert.Certificate;
  26. import java.security.cert.X509Certificate;
  27. import java.util.Enumeration;
  28. import java.util.HashMap;
  29. import java.util.Map;

  30. import javax.crypto.SecretKey;
  31. import javax.security.auth.x500.X500Principal;

  32. import org.apache.cxf.common.util.Base64UrlUtility;
  33. import org.apache.cxf.rt.security.crypto.MessageDigestUtils;
  34. import org.openspcoop2.utils.UtilsException;
  35. import org.openspcoop2.utils.resources.FileSystemUtilities;

  36. /**
  37.  * Keystore
  38.  *
  39.  * @author Poli Andrea (apoli@link.it)
  40.  * @author $Author$
  41.  * @version $Rev$, $Date$
  42.  */
  43. public class KeyStore {
  44.    
  45.     private java.security.KeyStore keystoreArchive;
  46.     private boolean keystoreHsm;
  47.    
  48.     public KeyStore(String keystorePath,String passwordKeystore) throws UtilsException{
  49.         this(keystorePath,KeystoreType.JKS.getNome(),passwordKeystore);
  50.     }
  51.     public KeyStore(String keystorePath,String tipoKeystore, String passwordKeystore) throws UtilsException{
  52.         this(new File(keystorePath),tipoKeystore,passwordKeystore);
  53.     }
  54.     public KeyStore(File keystorePath,String passwordKeystore) throws UtilsException{
  55.         this(keystorePath,KeystoreType.JKS.getNome(),passwordKeystore);
  56.     }
  57.     public KeyStore(File keystorePath,String tipoKeystore, String passwordKeystore) throws UtilsException{
  58.        
  59.         if(!keystorePath.exists()){
  60.             throw new UtilsException("Keystore ["+keystorePath+"] not exists");
  61.         }
  62.         if(!keystorePath.canRead()){
  63.             throw new UtilsException("Keystore ["+keystorePath+"] cannot read");
  64.         }
  65.        
  66.         byte [] keystore = null;
  67.         try {
  68.             keystore = FileSystemUtilities.readBytesFromFile(keystorePath);
  69.         }catch(Exception e){
  70.             throw new UtilsException(e.getMessage(),e);
  71.         }
  72.        
  73.         this.keystoreArchive = KeystoreUtils.readKeystore(keystore, tipoKeystore, passwordKeystore);
  74.     }
  75.    
  76.     public KeyStore(byte[] keystore,String passwordKeystore) throws UtilsException{
  77.         this(keystore,KeystoreType.JKS.getNome(),passwordKeystore);
  78.     }
  79.     public KeyStore(byte[] keystore,String tipoKeystore, String passwordKeystore) throws UtilsException{
  80.        
  81.         if(keystore==null){
  82.             throw new UtilsException("Keystore undefined");
  83.         }
  84.        
  85.         this.keystoreArchive = KeystoreUtils.readKeystore(keystore, tipoKeystore, passwordKeystore);
  86.        
  87.     }
  88.    
  89.    
  90.     public KeyStore(java.security.KeyStore keystore) {
  91.         this(keystore, false);
  92.     }
  93.     public KeyStore(java.security.KeyStore keystore, boolean keystoreHsm) {
  94.         this.keystoreArchive = keystore;
  95.         this.keystoreHsm = keystoreHsm;
  96.     }
  97.    
  98.     private Map<String, Key> keys = new HashMap<>(); // effettuo il cache delle chiavi essendo costoso accederci tutte le volte
  99.     private synchronized void initKey(String alias, String password) throws UtilsException {
  100.         if(!this.keys.containsKey(alias)) {
  101.             try{
  102.                 /** System.out.println("******** AGGIUNGO CHIAVE '"+alias+"' IN CACHE!!!!!!!!"); */
  103.                 Key key = null;
  104.                 if(password!=null) {
  105.                     key = this.keystoreArchive.getKey(alias, password.toCharArray());
  106.                 }
  107.                 else {
  108.                     key = this.keystoreArchive.getKey(alias, "".toCharArray());
  109.                 }
  110.                 if(key==null) {
  111.                     throw new UtilsException("Not found");
  112.                 }
  113.                 this.keys.put(alias, key);
  114.             }catch(Exception e){
  115.                 throw new UtilsException(e.getMessage(),e);
  116.             }
  117.         }
  118.     }
  119.    
  120.     public PrivateKey getPrivateKey(String alias,String passwordPrivateKey) throws UtilsException{
  121.         try{
  122.             if(!this.keys.containsKey(alias)) {
  123.                 initKey(alias, passwordPrivateKey);
  124.             }
  125. /**         else {
  126. //              System.out.println("GET KEY '"+alias+"' FROM CACHE");
  127. //          } */
  128.             return (PrivateKey) this.keys.get(alias);
  129.         }catch(Exception e){
  130.             throw new UtilsException(e.getMessage(),e);
  131.         }  
  132.     }
  133.     public SecretKey getSecretKey(String alias,String passwordPrivateKey) throws UtilsException{
  134.         try{
  135.             if(!this.keys.containsKey(alias)) {
  136.                 initKey(alias, passwordPrivateKey);
  137.             }
  138.             return (SecretKey) this.keys.get(alias);
  139.         }catch(Exception e){
  140.             throw new UtilsException(e.getMessage(),e);
  141.         }  
  142.     }

  143.     public Certificate getCertificate() throws UtilsException{
  144.         try{
  145.             Enumeration<String> aliases = this.keystoreArchive.aliases();
  146.             Certificate cer = null;
  147.             while (aliases.hasMoreElements()) {
  148.                 String alias = aliases.nextElement();
  149.                 if(cer!=null){
  150.                     throw new UtilsException("More than one certificate, use alias");
  151.                 }
  152.                 cer = this.keystoreArchive.getCertificate(alias);
  153.             }
  154.             return cer;
  155.         }catch(Exception e){
  156.             throw new UtilsException(e.getMessage(),e);
  157.         }  
  158.     }
  159.     public Certificate getCertificate(String alias) throws UtilsException{
  160.         try{
  161.             return this.keystoreArchive.getCertificate(alias);
  162.         }catch(Exception e){
  163.             throw new UtilsException(e.getMessage(),e);
  164.         }  
  165.     }
  166.     public Certificate[] getCertificateChain(String alias) throws UtilsException{
  167.         try{
  168.             return this.keystoreArchive.getCertificateChain(alias);
  169.         }catch(Exception e){
  170.             throw new UtilsException(e.getMessage(),e);
  171.         }  
  172.     }
  173.    
  174.     public Certificate getCertificateByDigestMD5UrlEncoded(String digest) throws UtilsException{
  175.         return getCertificateByDigestUrlEncoded(digest, MessageDigestUtils.ALGO_MD5);
  176.     }
  177.     public Certificate getCertificateByDigestSHA1UrlEncoded(String digest) throws UtilsException{
  178.         return getCertificateByDigestUrlEncoded(digest, MessageDigestUtils.ALGO_SHA_1);
  179.     }
  180.     public Certificate getCertificateByDigestSHA256UrlEncoded(String digest) throws UtilsException{
  181.         return getCertificateByDigestUrlEncoded(digest, MessageDigestUtils.ALGO_SHA_256);
  182.     }
  183.     public Certificate getCertificateByDigestUrlEncoded(String digest, String digestAlgo) throws UtilsException{
  184.         try{
  185.             Enumeration<String> aliases = this.keystoreArchive.aliases();
  186.             while (aliases.hasMoreElements()) {
  187.                 String alias = aliases.nextElement();
  188.                 Certificate cer = this.keystoreArchive.getCertificate(alias);
  189.                 String digestCer = this.buildDigestUrlEncoded(cer, digestAlgo);
  190.                 if(digestCer.equals(digest)) {
  191.                     return cer;
  192.                 }
  193.             }
  194.             return null;
  195.         }catch(Exception e){
  196.             throw new UtilsException(e.getMessage(),e);
  197.         }  
  198.     }
  199.    
  200.     public Certificate getCertificateBySubject(X500Principal principal) throws UtilsException{
  201.         try{
  202.             if(principal==null) {
  203.                 return null;
  204.             }
  205.             Enumeration<String> aliases = this.keystoreArchive.aliases();
  206.             while (aliases.hasMoreElements()) {
  207.                 String alias = aliases.nextElement();
  208.                 Certificate cer = this.keystoreArchive.getCertificate(alias);
  209.                 if(cer instanceof X509Certificate) {
  210.                     X509Certificate x509 = (X509Certificate) cer;
  211.                     X500Principal subject = x509.getSubjectX500Principal();
  212.                     if(principal.equals(subject)) {
  213.                         return cer;
  214.                     }
  215.                 }
  216.             }
  217.             return null;
  218.         }catch(Exception e){
  219.             throw new UtilsException(e.getMessage(),e);
  220.         }  
  221.     }
  222.     public boolean existsCertificateBySubject(X500Principal principal) throws UtilsException{
  223.         try{
  224.             return this.getCertificateBySubject(principal)!=null;
  225.         }catch(Exception e){
  226.             throw new UtilsException(e.getMessage(),e);
  227.         }  
  228.     }
  229.    
  230.     public Certificate getCertificateByPublicKey(PublicKey publicKey) throws UtilsException{
  231.         try{
  232.             if(publicKey==null) {
  233.                 return null;
  234.             }
  235.             Enumeration<String> aliases = this.keystoreArchive.aliases();
  236.             while (aliases.hasMoreElements()) {
  237.                 String alias = aliases.nextElement();
  238.                 Certificate cer = this.keystoreArchive.getCertificate(alias);
  239.                 PublicKey pk = cer.getPublicKey();
  240.                 if(pk!=null && pk.equals(publicKey)) {
  241.                     return cer;
  242.                 }
  243.             }
  244.             return null;
  245.         }catch(Exception e){
  246.             throw new UtilsException(e.getMessage(),e);
  247.         }  
  248.     }
  249.     public boolean existsCertificateByPublicKey(PublicKey publicKey) throws UtilsException{
  250.         try{
  251.             return this.getCertificateByPublicKey(publicKey)!=null;
  252.         }catch(Exception e){
  253.             throw new UtilsException(e.getMessage(),e);
  254.         }  
  255.     }
  256.    
  257.     public String getDigestMD5UrlEncoded(String alias) throws UtilsException{
  258.         return this.getDigestUrlEncoded(alias, MessageDigestUtils.ALGO_MD5);
  259.     }
  260.     public String getDigestSHA1UrlEncoded(String alias) throws UtilsException{
  261.         return this.getDigestUrlEncoded(alias, MessageDigestUtils.ALGO_SHA_1);
  262.     }
  263.     public String getDigestSHA256UrlEncoded(String alias) throws UtilsException{
  264.         return this.getDigestUrlEncoded(alias, MessageDigestUtils.ALGO_SHA_256);
  265.     }
  266.     public String getDigestUrlEncoded(String alias, String digestAlgo) throws UtilsException{
  267.         try{
  268.             Certificate cer = getCertificate(alias);
  269.             if(cer==null) {
  270.                 throw new UtilsException("Certificate '"+alias+"' not exists");
  271.             }
  272.             return this.buildDigestUrlEncoded(cer, digestAlgo);
  273.         }catch(Exception e){
  274.             throw new UtilsException(e.getMessage(),e);
  275.         }  
  276.     }
  277.     private String buildDigestUrlEncoded(Certificate cer, String digestAlgo) throws UtilsException{
  278.         try{
  279.             byte[] digestB = MessageDigestUtils.createDigest(cer.getEncoded(), digestAlgo);
  280.             return Base64UrlUtility.encode(digestB);
  281.         }catch(Exception e){
  282.             throw new UtilsException(e.getMessage(),e);
  283.         }
  284.     }
  285.    
  286.     public boolean existsAlias(String alias) throws UtilsException{
  287.         try{
  288.             return this.keystoreArchive.containsAlias(alias);
  289.         }catch(Exception e){
  290.             throw new UtilsException(e.getMessage(),e);
  291.         }  
  292.     }
  293.     public Enumeration<String> aliases() throws UtilsException{
  294.         try{
  295.             return this.keystoreArchive.aliases();
  296.         }catch(Exception e){
  297.             throw new UtilsException(e.getMessage(),e);
  298.         }
  299.     }
  300.     public PublicKey getPublicKey() throws UtilsException{
  301.         return this.getCertificate().getPublicKey();
  302.     }
  303.     public PublicKey getPublicKey(String alias) throws UtilsException{
  304.         return this.getCertificate(alias).getPublicKey();
  305.     }
  306.    
  307.     public java.security.KeyStore getKeystore() {
  308.         return this.keystoreArchive;
  309.     }
  310.     public boolean isKeystoreHsm() {
  311.         return this.keystoreHsm;
  312.     }
  313.     public String getKeystoreType() {
  314.         if(this.keystoreArchive==null) {
  315.             return null;
  316.         }
  317.         return this.keystoreArchive.getType();
  318.     }
  319.     public java.security.Provider getKeystoreProvider() {
  320.         return this.keystoreArchive.getProvider();
  321.     }
  322.    
  323.     public void putCertificate(String alias, Certificate cert, boolean overwriteIfExists) throws UtilsException {
  324.         if(this.existsAlias(alias)) {
  325.             if(overwriteIfExists) {
  326.                 try {
  327.                     this.keystoreArchive.deleteEntry(alias);
  328.                 }catch(Exception t) {
  329.                     throw new UtilsException(t.getMessage(),t);
  330.                 }
  331.             }
  332.             else {
  333.                 return;
  334.             }
  335.         }
  336.         try {
  337.             this.keystoreArchive.setCertificateEntry(alias, cert);
  338.         }catch(Exception t) {
  339.             throw new UtilsException(t.getMessage(),t);
  340.         }
  341.     }
  342.     public void putAllCertificate(KeyStore keystore, boolean overwriteIfExists) throws UtilsException {
  343.         if(keystore!=null) {
  344.             Enumeration<String> aliases = keystore.aliases();
  345.             if(aliases!=null) {
  346.                 while (aliases.hasMoreElements()) {
  347.                     String alias = aliases.nextElement();
  348.                     Certificate cert = keystore.getCertificate(alias);
  349.                     putCertificate(alias, cert, overwriteIfExists);
  350.                 }
  351.             }
  352.         }
  353.     }
  354.    
  355. }