SSLUtilities.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.transport.http;

  21. import java.io.ByteArrayInputStream;
  22. import java.io.File;
  23. import java.io.FileInputStream;
  24. import java.io.InputStream;
  25. import java.io.StringWriter;
  26. import java.lang.reflect.Method;
  27. import java.security.Key;
  28. import java.security.KeyStore;
  29. import java.security.Provider;
  30. import java.security.Provider.Service;
  31. import java.security.Security;
  32. import java.security.cert.CertStore;
  33. import java.security.cert.Certificate;
  34. import java.security.cert.CertificateFactory;
  35. import java.security.cert.CollectionCertStoreParameters;
  36. import java.security.cert.PKIXBuilderParameters;
  37. import java.security.cert.X509CRL;
  38. import java.security.cert.X509CertSelector;
  39. import java.util.ArrayList;
  40. import java.util.Enumeration;
  41. import java.util.List;

  42. import javax.net.ssl.CertPathTrustManagerParameters;
  43. import javax.net.ssl.HostnameVerifier;
  44. import javax.net.ssl.KeyManager;
  45. import javax.net.ssl.KeyManagerFactory;
  46. import javax.net.ssl.SSLContext;
  47. import javax.net.ssl.SSLSocket;
  48. import javax.net.ssl.SSLSocketFactory;
  49. import javax.net.ssl.TrustManager;
  50. import javax.net.ssl.TrustManagerFactory;
  51. import javax.net.ssl.X509KeyManager;
  52. import javax.net.ssl.X509TrustManager;
  53. import javax.servlet.http.HttpServletRequest;

  54. import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
  55. import org.openspcoop2.utils.Utilities;
  56. import org.openspcoop2.utils.UtilsException;
  57. import org.openspcoop2.utils.certificate.KeystoreType;
  58. import org.openspcoop2.utils.certificate.KeystoreUtils;
  59. import org.openspcoop2.utils.certificate.hsm.HSMManager;
  60. import org.openspcoop2.utils.date.DateManager;
  61. import org.openspcoop2.utils.random.RandomGenerator;
  62. import org.openspcoop2.utils.resources.Loader;
  63. import org.slf4j.Logger;

  64. /**
  65.  * SSLUtilities
  66.  *
  67.  * @author Poli Andrea (apoli@link.it)
  68.  * @author $Author$
  69.  * @version $Rev$, $Date$
  70.  */
  71. public class SSLUtilities {
  72.    
  73.     private SSLUtilities() {}
  74.    
  75.    
  76.     private static String jvmHttpsClientCertificateConfigurated = null;
  77.     private static synchronized void initJvmHttpsClientCertificateConfigurated() {
  78.         if(jvmHttpsClientCertificateConfigurated==null) {
  79.             jvmHttpsClientCertificateConfigurated = System.getProperty("javax.net.ssl.keyStore");
  80.         }
  81.     }
  82.     public static boolean isJvmHttpsClientCertificateConfigurated() {
  83.         if(jvmHttpsClientCertificateConfigurated==null) {
  84.             initJvmHttpsClientCertificateConfigurated();
  85.         }
  86.         return jvmHttpsClientCertificateConfigurated!=null;
  87.     }
  88.     public static String getJvmHttpsClientCertificateConfigurated() {
  89.         if(jvmHttpsClientCertificateConfigurated==null) {
  90.             initJvmHttpsClientCertificateConfigurated();
  91.         }
  92.         return jvmHttpsClientCertificateConfigurated;
  93.     }
  94.    
  95.    
  96.     public static List<String> getSSLEnabledProtocols(String sslType) throws UtilsException{
  97.         try{
  98.             List<String> p = new ArrayList<>();
  99.             SSLContext context = SSLContext.getInstance(sslType);
  100.             context.init(null,null,null);
  101.             SSLSocket socket = null;
  102.             try {
  103.                 socket = (SSLSocket)context.getSocketFactory().createSocket();
  104.                 String[] protocols = socket.getEnabledProtocols();
  105.                 for (int i = 0; i < protocols.length; i++) {
  106.                     p.add(protocols[i]);
  107.                 }
  108.             }finally {
  109.                 try {
  110.                     if(socket!=null) {
  111.                         socket.close();
  112.                     }
  113.                 }catch(Throwable t) {
  114.                     // ignore
  115.                 }
  116.             }
  117.             return p;
  118.         }catch(Exception e){
  119.             throw new UtilsException(e.getMessage(), e);
  120.         }
  121.     }
  122.     public static List<String> getSSLSupportedProtocols() throws UtilsException{
  123.         try{
  124.             List<String> p = new ArrayList<>();
  125.             SSLContext defaultContext = SSLContext.getDefault();
  126.             SSLSocket socket = null;
  127.             try {
  128.                 socket = (SSLSocket)defaultContext.getSocketFactory().createSocket();
  129.                 String[] protocols = socket.getSupportedProtocols();
  130.                 for (int i = 0; i < protocols.length; i++) {
  131.                     p.add(protocols[i]);
  132.                 }
  133.             }finally {
  134.                 try {
  135.                     if(socket!=null) {
  136.                         socket.close();
  137.                     }
  138.                 }catch(Throwable t) {
  139.                     // ignore
  140.                 }
  141.             }
  142.             return p;
  143.         }catch(Exception e){
  144.             throw new UtilsException(e.getMessage(), e);
  145.         }
  146.     }
  147.     public static String getSafeDefaultProtocol(){
  148.         try{
  149.             return getDefaultProtocol();
  150.         }catch(Exception e){
  151.             return SSLConstants.PROTOCOL_TLS;
  152.         }
  153.     }
  154.     public static String getDefaultProtocol() throws UtilsException{
  155.         // Ritorno l'ultima versione disponibile
  156.         List<String> p = getSSLSupportedProtocols();
  157.         if(p.contains(SSLConstants.PROTOCOL_TLS_V1_3)){
  158.             return SSLConstants.PROTOCOL_TLS_V1_3;
  159.         }
  160.         else if(p.contains(SSLConstants.PROTOCOL_TLS_V1_2)){
  161.             return SSLConstants.PROTOCOL_TLS_V1_2;
  162.         }
  163.         else if(p.contains(SSLConstants.PROTOCOL_TLS_V1_1)){
  164.             return SSLConstants.PROTOCOL_TLS_V1_1;
  165.         }
  166.         else if(p.contains(SSLConstants.PROTOCOL_TLS_V1)){
  167.             return SSLConstants.PROTOCOL_TLS_V1;
  168.         }
  169.         else if(p.contains(SSLConstants.PROTOCOL_TLS)){
  170.             return SSLConstants.PROTOCOL_TLS;
  171.         }
  172.         else if(p.contains(SSLConstants.PROTOCOL_SSL_V3)){
  173.             return SSLConstants.PROTOCOL_SSL_V3;
  174.         }
  175.         else if(p.contains(SSLConstants.PROTOCOL_SSL)){
  176.             return SSLConstants.PROTOCOL_SSL;
  177.         }
  178.         else if(p.contains(SSLConstants.PROTOCOL_SSL_V2_HELLO)){
  179.             return SSLConstants.PROTOCOL_SSL_V2_HELLO;
  180.         }
  181.         else{
  182.             return p.get(0);
  183.         }
  184.     }
  185.     public static List<String> getAllSslProtocol() {
  186.         // ritorno in ordine dal più recente al meno recento, più altri eventuali protocolli.
  187.         List<String> p = new ArrayList<>();
  188.         p.add(SSLConstants.PROTOCOL_TLS_V1_2);
  189.         p.add(SSLConstants.PROTOCOL_TLS_V1_1);
  190.         p.add(SSLConstants.PROTOCOL_TLS_V1);
  191.         p.add(SSLConstants.PROTOCOL_TLS); // per retrocompatibilità
  192.         p.add(SSLConstants.PROTOCOL_SSL_V3);
  193.         p.add(SSLConstants.PROTOCOL_SSL); // per retrocompatibilità
  194.         p.add(SSLConstants.PROTOCOL_SSL_V2_HELLO);
  195.        
  196.         try{
  197.             List<String> pTmp = getSSLSupportedProtocols();
  198.             for (String s : pTmp) {
  199.                 if(p.contains(s)==false){
  200.                     p.add(s);
  201.                 }
  202.             }
  203.         }catch(Exception e){
  204.             // non dovrebbe mai accadere una eccezione
  205.             e.printStackTrace(System.err);
  206.         }
  207.            
  208.         return  p;
  209.     }
  210.    
  211.     public static List<String> getSSLEnabledCipherSuites(String sslType) throws UtilsException{
  212.         try{
  213.             List<String> l = new ArrayList<>();
  214.             SSLContext context = SSLContext.getInstance(sslType);
  215.             context.init(null,null,null);
  216.             SSLSocket socket = null;
  217.             try {
  218.                 socket = (SSLSocket)context.getSocketFactory().createSocket();
  219.                 String[] cs = socket.getEnabledCipherSuites();
  220.                 for (int i = 0; i < cs.length; i++) {
  221.                     l.add(cs[i]);
  222.                 }
  223.             }finally {
  224.                 try {
  225.                     if(socket!=null) {
  226.                         socket.close();
  227.                     }
  228.                 }catch(Throwable t) {
  229.                     // ignore
  230.                 }
  231.             }
  232.             return l;
  233.         }catch(Exception e){
  234.             throw new UtilsException(e.getMessage(), e);
  235.         }
  236.     }
  237.     public static List<String> getSSLSupportedCipherSuites() throws UtilsException{
  238.         try{
  239.             List<String> l = new ArrayList<>();
  240.             SSLContext defaultContext = SSLContext.getDefault();
  241.             SSLSocket socket = null;
  242.             try {
  243.                 socket = (SSLSocket)defaultContext.getSocketFactory().createSocket();
  244.                 String[] cs = socket.getSupportedCipherSuites();
  245.                 for (int i = 0; i < cs.length; i++) {
  246.                     l.add(cs[i]);
  247.                 }
  248.             }finally {
  249.                 try {
  250.                     if(socket!=null) {
  251.                         socket.close();
  252.                     }
  253.                 }catch(Throwable t) {
  254.                     // ignore
  255.                 }
  256.             }
  257.             return l;
  258.         }catch(Exception e){
  259.             throw new UtilsException(e.getMessage(), e);
  260.         }
  261.     }
  262.        
  263.    
  264.     public static List<Provider> getSSLProviders() throws UtilsException{
  265.         try{
  266.             List<Provider> p = new ArrayList<>();
  267.             for (Provider provider : Security.getProviders()){
  268.                 p.add(provider);
  269.             }
  270.             return p;
  271.         }catch(Exception e){
  272.             throw new UtilsException(e.getMessage(), e);
  273.         }
  274.     }
  275.     public static List<String> getSSLProvidersName() throws UtilsException{
  276.         try{
  277.             List<String> p = new ArrayList<>();
  278.             for (Provider provider : Security.getProviders()){
  279.                 p.add(provider.getName());
  280.             }
  281.             return p;
  282.         }catch(Exception e){
  283.             throw new UtilsException(e.getMessage(), e);
  284.         }
  285.     }
  286.     public static List<String> getServiceTypes(Provider provider) throws UtilsException{
  287.         try{
  288.             List<String> p = new ArrayList<>();
  289.             for (Service service : provider.getServices()){
  290.                 if(!p.contains(service.getType())){
  291.                     p.add(service.getType());
  292.                 }
  293.             }
  294.             return p;
  295.         }catch(Exception e){
  296.             throw new UtilsException(e.getMessage(), e);
  297.         }
  298.     }
  299.     public static List<String> getServiceTypeAlgorithms(Provider provider,String serviceType) throws UtilsException{
  300.         try{
  301.             List<String> p = new ArrayList<>();
  302.             for (Service service : provider.getServices()){
  303.                 if(serviceType.equals(service.getType())){
  304.                     p.add(service.getAlgorithm());
  305.                 }
  306.             }
  307.             return p;
  308.         }catch(Exception e){
  309.             throw new UtilsException(e.getMessage(), e);
  310.         }
  311.     }
  312.    
  313.     private static TrustManager[] trustAllCertsManager;
  314.     private static synchronized void initTrustAllCertsManager() {
  315.         if(trustAllCertsManager==null) {
  316.             // Create a trust manager that does not validate certificate chains
  317.             trustAllCertsManager = new TrustManager[]{
  318.                 new SSLTrustAllManager()
  319.             };
  320.         }
  321.     }
  322.     public static TrustManager[] getTrustAllCertsManager() {
  323.         if(trustAllCertsManager==null) {
  324.             initTrustAllCertsManager();
  325.         }
  326.         return trustAllCertsManager;
  327.     }
  328.    
  329.     public static SSLContext generateSSLContext(SSLConfig sslConfig, StringBuilder bfLog) throws UtilsException{
  330.         return generateSSLContext(sslConfig, null, null, bfLog);
  331.     }
  332.     public static SSLContext generateSSLContext(SSLConfig sslConfig, IOCSPValidator ocspValidator, IBYOKUnwrapManager byok, StringBuilder bfLog) throws UtilsException{

  333.         // Gestione https
  334.         SSLContext sslContext = null;
  335.        
  336.         bfLog.append("Creo contesto SSL...\n");
  337.         KeyManager[] km = null;
  338.         TrustManager[] tm = null;

  339.         InputStream finKeyStore = null;
  340.         InputStream finTrustStore = null;
  341.         try{
  342.                    
  343.             // Autenticazione CLIENT
  344.             if(sslConfig.getKeyStore()!=null || sslConfig.getKeyStoreLocation()!=null){
  345.                 bfLog.append("Gestione keystore...\n");
  346.                 bfLog.append("\tKeystore type["+sslConfig.getKeyStoreType()+"]\n");
  347.                 bfLog.append("\tKeystore location["+sslConfig.getKeyStoreLocation()+"]\n");
  348.                 /**bfLog.append("\tKeystore password["+sslConfig.getKeyStorePassword()+"]\n");*/
  349.                 bfLog.append("\tKeystore byok policy["+sslConfig.getKeyStoreBYOKPolicy()+"]\n");
  350.                 bfLog.append("\tKeystore keyManagementAlgorithm["+sslConfig.getKeyManagementAlgorithm()+"]\n");
  351.                 /**bfLog.append("\tKeystore keyPassword["+sslConfig.getKeyPassword()+"]\n");*/
  352.                 String location = null;
  353.                 try {
  354.                     location = sslConfig.getKeyStoreLocation(); // per debug
  355.                
  356.                     boolean hsmKeystore = false;
  357.                     HSMManager hsmManager = HSMManager.getInstance();
  358.                     if(hsmManager!=null) {
  359.                         if(sslConfig.getKeyStore()!=null) {
  360.                             hsmKeystore = sslConfig.isKeyStoreHsm();
  361.                         }
  362.                         else {
  363.                             if(sslConfig.getKeyStoreType()!=null && hsmManager.existsKeystoreType(sslConfig.getKeyStoreType())) {
  364.                                 hsmKeystore = true;
  365.                             }
  366.                         }
  367.                     }
  368.                     bfLog.append("\tKeystore HSM["+hsmManager+"]\n");
  369.                    
  370.                     KeyStore keystore = null;
  371.                     KeyStore keystoreParam = null;
  372.                     @SuppressWarnings("unused")
  373.                     Provider keystoreProvider = null;
  374.                     if(sslConfig.getKeyStore()!=null) {
  375.                         keystoreParam = sslConfig.getKeyStore();
  376.                         if(hsmKeystore) {
  377.                             keystoreProvider = keystoreParam.getProvider();
  378.                         }
  379.                     }
  380.                     else {
  381.                         if(hsmKeystore) {
  382.                             org.openspcoop2.utils.certificate.KeyStore ks = hsmManager.getKeystore(sslConfig.getKeyStoreType());
  383.                             if(ks==null) {
  384.                                 throw new UtilsException("Keystore not found");
  385.                             }
  386.                             keystoreParam = ks.getKeystore();
  387.                             keystoreProvider = keystoreParam.getProvider();
  388.                         }
  389.                         else {
  390.                             File file = new File(location);
  391.                             if(file.exists()) {
  392.                                 finKeyStore = new FileInputStream(file);
  393.                             }
  394.                             else {
  395.                                 finKeyStore = SSLUtilities.class.getResourceAsStream(location);
  396.                             }
  397.                             if(finKeyStore == null) {
  398.                                 throw new UtilsException("Keystore not found");
  399.                             }
  400.                             if(byok!=null) {
  401.                                 byte [] keystoreEncBytes = Utilities.getAsByteArray(finKeyStore);
  402.                                 byte [] keystorePlainBytes = byok.unwrap(keystoreEncBytes);
  403.                                 keystoreParam = KeystoreUtils.readKeystore(keystorePlainBytes, sslConfig.getKeyStoreType(), sslConfig.getKeyStorePassword());
  404.                             }
  405.                             else {
  406.                                 keystoreParam = KeystoreUtils.readKeystore(finKeyStore, sslConfig.getKeyStoreType(), sslConfig.getKeyStorePassword());
  407.                             }
  408.                         }
  409.                     }
  410.                    
  411.                     boolean oldMethodKeyAlias = false; // Questo metodo non funzionava con PKCS11
  412.                     if(oldMethodKeyAlias && sslConfig.getKeyAlias()!=null) {
  413.                         Key key = keystoreParam.getKey(sslConfig.getKeyAlias(), sslConfig.getKeyPassword().toCharArray());
  414.                         if(key==null) {
  415.                             throw new UtilsException("Key with alias '"+sslConfig.getKeyAlias()+"' not found");
  416.                         }
  417.                         if(hsmKeystore) {
  418.                             // uso un JKS come tmp
  419.                             keystore = KeyStore.getInstance(KeystoreType.JKS.getNome());
  420.                         }
  421.                         else {
  422.                             keystore = KeyStore.getInstance(sslConfig.getKeyStoreType());
  423.                         }
  424.                         keystore.load(null); // inizializza il keystore
  425.                         keystore.setKeyEntry(sslConfig.getKeyAlias(), key,
  426.                                 sslConfig.getKeyPassword()!=null ? sslConfig.getKeyPassword().toCharArray() : "".toCharArray(),
  427.                                 keystoreParam.getCertificateChain(sslConfig.getKeyAlias()));
  428.                     }
  429.                     else {
  430.                         keystore = keystoreParam;
  431.                     }
  432.                    
  433.                     KeyManagerFactory keyManagerFactory = null;
  434.                     // NO: no such algorithm: SunX509 for provider SunPKCS11-xxx
  435.                     /**if(keystoreProvider!=null) {
  436.                     //  keyManagerFactory = KeyManagerFactory.getInstance(sslConfig.getKeyManagementAlgorithm(), keystoreProvider);
  437.                     //}
  438.                     //else {*/
  439.                     keyManagerFactory = KeyManagerFactory.getInstance(sslConfig.getKeyManagementAlgorithm());
  440.                    
  441.                     keyManagerFactory.init(keystore, sslConfig.getKeyPassword()!=null ? sslConfig.getKeyPassword().toCharArray() : "".toCharArray());
  442.                     km = keyManagerFactory.getKeyManagers();
  443.                     if(!oldMethodKeyAlias && sslConfig.getKeyAlias()!=null &&
  444.                         km!=null && km.length>0 && km[0]!=null && km[0] instanceof X509KeyManager) {
  445.                            
  446.                         String alias = sslConfig.getKeyAlias();
  447.                        
  448.                         // Fix case insensitive
  449.                         Enumeration<String> enAliases = keystore.aliases();
  450.                         if(enAliases!=null) {
  451.                             while (enAliases.hasMoreElements()) {
  452.                                 String a = enAliases.nextElement();
  453.                                 if(a.equalsIgnoreCase(alias)) {
  454.                                     alias = a; // uso quello presente nel keystore
  455.                                     break;
  456.                                 }
  457.                             }
  458.                         }
  459.                        
  460.                         X509KeyManager wrapperX509KeyManager = new SSLX509ManagerForcedClientAlias(alias, (X509KeyManager)km[0] );
  461.                         km[0] = wrapperX509KeyManager;
  462.                     }
  463.                     bfLog.append("Gestione keystore effettuata\n");
  464.                 }catch(Throwable e) {
  465.                     if(location!=null) {
  466.                         throw new UtilsException("["+location+"] "+e.getMessage(),e);
  467.                     }
  468.                     else {
  469.                         throw new UtilsException(e.getMessage(),e);
  470.                     }
  471.                 }
  472.             }
  473.    
  474.    
  475.             // Autenticazione SERVER
  476.             KeyStore truststoreParam = null;
  477.             if(sslConfig.isTrustAllCerts()) {
  478.                 bfLog.append("Gestione trust all certs...\n");
  479.                 tm = getTrustAllCertsManager();
  480.                 bfLog.append("Gestione trust all certs effettuata\n");
  481.             }
  482.             else if(sslConfig.getTrustStore()!=null || sslConfig.getTrustStoreLocation()!=null){
  483.                 bfLog.append("Gestione truststore...\n");
  484.                 bfLog.append("\tTruststore type["+sslConfig.getTrustStoreType()+"]\n");
  485.                 bfLog.append("\tTruststore location["+sslConfig.getTrustStoreLocation()+"]\n");
  486.                 /**bfLog.append("\tTruststore password["+sslConfig.getTrustStorePassword()+"]\n");*/
  487.                 bfLog.append("\tTruststore trustManagementAlgorithm["+sslConfig.getTrustManagementAlgorithm()+"]\n");
  488.                 String location = null;
  489.                 try {
  490.                     location = sslConfig.getTrustStoreLocation(); // per debug
  491.                    
  492.                     boolean hsmTruststore = false;
  493.                     HSMManager hsmManager = HSMManager.getInstance();
  494.                     if(hsmManager!=null) {
  495.                         if(sslConfig.getTrustStore()!=null) {
  496.                             hsmTruststore = sslConfig.isTrustStoreHsm();
  497.                         }
  498.                         else {
  499.                             if(sslConfig.getTrustStoreType()!=null && hsmManager.existsKeystoreType(sslConfig.getTrustStoreType())) {
  500.                                 hsmTruststore = true;
  501.                             }
  502.                         }
  503.                     }
  504.                     bfLog.append("\tTruststore HSM["+hsmTruststore+"]\n");
  505.                    
  506.                     @SuppressWarnings("unused")
  507.                     Provider truststoreProvider = null;
  508.                     if(sslConfig.getTrustStore()!=null) {
  509.                         truststoreParam = sslConfig.getTrustStore();
  510.                         if(hsmTruststore) {
  511.                             truststoreProvider = truststoreParam.getProvider();
  512.                         }
  513.                     }
  514.                     else {
  515.                         if(hsmTruststore) {
  516.                             org.openspcoop2.utils.certificate.KeyStore ks = hsmManager.getKeystore(sslConfig.getTrustStoreType());
  517.                             if(ks==null) {
  518.                                 throw new UtilsException("Truststore not found");
  519.                             }
  520.                             truststoreParam = ks.getKeystore();
  521.                             truststoreProvider = truststoreParam.getProvider();
  522.                         }
  523.                         else {
  524.                             File file = new File(location);
  525.                             if(file.exists()) {
  526.                                 finTrustStore = new FileInputStream(file);
  527.                             }
  528.                             else {
  529.                                 finTrustStore = SSLUtilities.class.getResourceAsStream(location);
  530.                             }
  531.                             if(finTrustStore == null) {
  532.                                 throw new UtilsException("Truststore not found");
  533.                             }      
  534.                             truststoreParam = KeystoreUtils.readKeystore(finTrustStore, sslConfig.getTrustStoreType(), sslConfig.getTrustStorePassword());
  535.                         }
  536.                     }
  537.                    
  538.                     TrustManagerFactory trustManagerFactory = null;
  539.                     // NO: no such algorithm: PKIX for provider SunPKCS11-xxx
  540.                     /**if(truststoreProvider!=null) {
  541.                     //  trustManagerFactory = TrustManagerFactory.getInstance(sslConfig.getTrustManagementAlgorithm(), truststoreProvider);
  542.                     //}
  543.                     //else {*/
  544.                     trustManagerFactory = TrustManagerFactory.getInstance(sslConfig.getTrustManagementAlgorithm());
  545.                    
  546.                     String trustManagementAlgo = sslConfig.getTrustManagementAlgorithm();
  547.                     if(trustManagementAlgo!=null) {
  548.                         trustManagementAlgo = trustManagementAlgo.trim();
  549.                     }
  550.                     if("PKIX".equalsIgnoreCase(trustManagementAlgo)) {
  551.                    
  552.                          // create the parameters for the validator
  553.                         if(sslConfig.getTrustStoreCRLs()!=null) {
  554.                             bfLog.append("\tTruststore CRLs\n");
  555.                         }
  556.                         else if(sslConfig.getTrustStoreCRLsLocation()!=null) {
  557.                             bfLog.append("\tTruststore CRLs["+sslConfig.getTrustStoreCRLsLocation()+"]\n");
  558.                         }
  559.                        
  560.                         Provider sigProvider = null;
  561.                         CertPathTrustManagerParameters params = buildCertPathTrustManagerParameters(truststoreParam, sslConfig.getTrustStoreCRLs(), sslConfig.getTrustStoreCRLsLocation(), sigProvider);
  562.                         trustManagerFactory.init(params);
  563.                        
  564.                     }
  565.                     else {
  566.                    
  567.                         trustManagerFactory.init(truststoreParam);
  568.                        
  569.                     }
  570.                     tm = trustManagerFactory.getTrustManagers();
  571.                     bfLog.append("Gestione truststore effettuata\n");
  572.                 }catch(Throwable e) {
  573.                     if(location!=null) {
  574.                         throw new UtilsException("["+location+"] "+e.getMessage(),e);
  575.                     }
  576.                     else {
  577.                         throw new UtilsException(e.getMessage(),e);
  578.                     }
  579.                 }
  580.             }
  581.            
  582.             if(ocspValidator!=null) {
  583.                 if(ocspValidator.getTrustStore()==null && truststoreParam!=null) {
  584.                     ocspValidator.setTrustStore(new org.openspcoop2.utils.certificate.KeyStore(truststoreParam));
  585.                 }
  586.                 tm = OCSPTrustManager.wrap(tm, ocspValidator);
  587.                 ocspValidator.setOCSPTrustManager(OCSPTrustManager.read(tm));
  588.             }
  589.    
  590.             // Creo contesto SSL
  591.             bfLog.append("Init SSLContext type["+sslConfig.getSslType()+"] ...\n");
  592.             sslContext = SSLContext.getInstance(sslConfig.getSslType());
  593.             if(sslConfig.isSecureRandom()) {
  594.                 RandomGenerator randomGenerator = null;
  595.                 if(sslConfig.getSecureRandomAlgorithm()!=null && !"".equals(sslConfig.getSecureRandomAlgorithm())) {
  596.                     bfLog.append("Creazione Secure Random con algoritmo '"+sslConfig.getSecureRandomAlgorithm()+"' ...\n");
  597.                     randomGenerator = new RandomGenerator(true, sslConfig.getSecureRandomAlgorithm());
  598.                     bfLog.append("Creazione Secure Random con algoritmo '"+sslConfig.getSecureRandomAlgorithm()+"' effettuata\n");
  599.                 }
  600.                 else {
  601.                     bfLog.append("Creazione Secure Random ...\n");
  602.                     randomGenerator = new RandomGenerator(true);
  603.                     bfLog.append("Creazione Secure Random effettuata\n");
  604.                 }
  605.                 java.security.SecureRandom secureRandom = (java.security.SecureRandom) randomGenerator.getRandomEngine();
  606.                 bfLog.append("Inizializzazione SSLContext con Secure Random ...\n");
  607.                 sslContext.init(km, tm, secureRandom);
  608.             }
  609.             else {
  610.                 sslContext.init(km, tm, null);
  611.             }
  612.            
  613.            
  614.             if(sslContext.getClientSessionContext()!=null) {
  615.                 bfLog.append("ClientSessionContext size:").
  616.                     append(sslContext.getClientSessionContext().getSessionCacheSize()).
  617.                     append(" timeout:").
  618.                     append(sslContext.getClientSessionContext().getSessionTimeout()).append("\n");
  619.             }
  620.             if(sslContext.getServerSessionContext()!=null) {
  621.                 bfLog.append("ServerSessionContext size:").
  622.                     append(sslContext.getServerSessionContext().getSessionCacheSize()).
  623.                     append(" timeout:").
  624.                     append(sslContext.getServerSessionContext().getSessionTimeout()).append("\n");
  625.             }
  626.            
  627.             bfLog.append("Init SSLContext type["+sslConfig.getSslType()+"] effettuato\n");
  628.            
  629.             return sslContext;
  630.            
  631.         }catch(Exception e){
  632.             throw new UtilsException(e.getMessage(), e);
  633.         }
  634.         finally{
  635.             try{
  636.                 if(finKeyStore!=null){
  637.                     finKeyStore.close();
  638.                 }
  639.             }catch(Exception e){
  640.                 // close
  641.             }
  642.             try{
  643.                 if(finTrustStore!=null){
  644.                     finTrustStore.close();
  645.                 }
  646.             }catch(Exception e){
  647.                 // close
  648.             }
  649.         }
  650.     }
  651.    
  652.     public static CertPathTrustManagerParameters buildCertPathTrustManagerParameters(KeyStore truststoreParam,
  653.             CertStore crlStore, String crlLocation, Provider provider) throws Exception {
  654.        
  655.          // create the parameters for the validator
  656.        
  657.         // Ricreo il truststore altrimenti i certificati presenti come coppia (chiave privata e pubblica non sono trusted)
  658.         KeyStore truststore = KeyStore.getInstance(KeyStore.getDefaultType()); // JKS
  659.         truststore.load(null); // inizializza il truststore
  660.         Enumeration<String> aliases = truststoreParam.aliases();
  661.         while (aliases.hasMoreElements()) {
  662.             String alias = aliases.nextElement();
  663.             /** System.out.println("ALIAS: '"+alias+"'"); */
  664.             truststore.setCertificateEntry(alias, truststoreParam.getCertificate(alias));
  665.         }
  666.        
  667.         PKIXBuilderParameters pkixParams = new PKIXBuilderParameters(truststore, new X509CertSelector());
  668.         pkixParams.setRevocationEnabled(false);
  669.         pkixParams.setDate(DateManager.getDate());
  670.        
  671.         /**
  672.         java.security.cert.PKIXRevocationChecker revocationChecker =
  673.                 (java.security.cert.PKIXRevocationChecker) java.security.cert.CertPathBuilder.getInstance(trustManagementAlgo).getRevocationChecker();
  674.         pkixParams.addCertPathChecker(revocationChecker);
  675.         revocationChecker.setOcspResponder(uriResponse);
  676.         */
  677.                        
  678.         if(crlStore!=null || crlLocation!=null) {
  679.             CertStore crlsCertstore = null;
  680.             if(crlStore!=null) {
  681.                 crlsCertstore = crlStore;
  682.             }else {
  683.                 crlsCertstore = buildCRLCertStoreEngine(crlLocation);
  684.             }
  685.             pkixParams.addCertStore(crlsCertstore);
  686.             pkixParams.setRevocationEnabled(true);
  687.         }
  688.        
  689.         if(provider!=null) {
  690.             pkixParams.setSigProvider(provider.getName());
  691.         }
  692.        
  693.         return new CertPathTrustManagerParameters(pkixParams);
  694.        
  695.     }
  696.    
  697.     private static CertStore buildCRLCertStoreEngine(String crlsPath) throws Exception {
  698.         List<byte[]> crlBytes = new ArrayList<>();
  699.         List<String> crlPathsList = new ArrayList<>();
  700.         if(crlsPath.contains(",")) {
  701.             String [] tmp = crlsPath.split(",");
  702.             for (String crlPath : tmp) {
  703.                 crlPathsList.add(crlPath.trim());
  704.             }
  705.         }
  706.         else {
  707.             crlPathsList.add(crlsPath.trim());
  708.         }
  709.         for (String crlPath : crlPathsList) {
  710.             InputStream isStore = null;
  711.             try{
  712.                 File fStore = new File(crlPath);
  713.                 if(fStore.exists()){
  714.                     isStore = new FileInputStream(fStore);
  715.                 }else{
  716.                     isStore = SSLUtilities.class.getResourceAsStream(crlPath);
  717.                 }
  718.                 if(isStore==null){
  719.                     throw new UtilsException("CRL ["+crlPath+"] not found");
  720.                 }
  721.                 crlBytes.add(Utilities.getAsByteArray(isStore));
  722.             }finally{
  723.                 try{
  724.                     if(isStore!=null){
  725.                         isStore.close();
  726.                     }
  727.                 }catch(Exception eClose){
  728.                     // close
  729.                 }
  730.             }
  731.         }
  732.         List<X509CRL> caCrls = new ArrayList<>();
  733.         CertificateFactory certFactory = org.openspcoop2.utils.certificate.CertificateFactory.getCertificateFactory();
  734.         for (int i = 0; i < crlBytes.size(); i++) {
  735.             byte [] crl = crlBytes.get(i);
  736.             try(ByteArrayInputStream bin = new ByteArrayInputStream(crl)){
  737.                 X509CRL caCrl = (X509CRL) certFactory.generateCRL(bin);
  738.                 caCrls.add(caCrl);
  739.             }
  740.             catch(Exception e){
  741.                 throw new SecurityException("Error loading CRL '"+crlPathsList.get(i)+"': "+e.getMessage(),e);
  742.             }
  743.         }
  744.         try {
  745.             CollectionCertStoreParameters certStoreParams =
  746.                         new CollectionCertStoreParameters(caCrls);
  747.             return CertStore.getInstance("Collection", certStoreParams);
  748.         }catch(Exception e){
  749.             throw new SecurityException("Build CertStore failed: "+e.getMessage(),e);
  750.         }
  751.     }

  752.    
  753.     public static HostnameVerifier generateHostnameVerifier(SSLConfig sslConfig, StringBuilder bfLog, Logger log, Loader loader) throws UtilsException{
  754.         try{
  755.             if(sslConfig.isHostnameVerifier()){
  756.                 if(sslConfig.getClassNameHostnameVerifier()!=null){
  757.                     bfLog.append("HostNamve verifier enabled ["+sslConfig.getClassNameHostnameVerifier()+"]\n");
  758.                     return (HostnameVerifier) loader.newInstance(sslConfig.getClassNameHostnameVerifier());
  759.                 }else{
  760.                     bfLog.append("HostName verifier enabled\n");
  761.                     return null;
  762.                 }
  763.             }else{
  764.                 bfLog.append("HostName verifier disabled\n");
  765.                 SSLHostNameVerifierDisabled disabilitato = new SSLHostNameVerifierDisabled(log);
  766.                 return disabilitato;
  767.             }
  768.         }catch(Exception e){
  769.             throw new UtilsException(e.getMessage(), e);
  770.         }
  771.        
  772.     }
  773.    
  774.    
  775.     public static void setSSLContextIntoJavaProperties(SSLConfig sslConfig, StringBuilder bfLog) throws UtilsException{

  776.         bfLog.append("Creo contesto SSL...\n");

  777.         try{
  778.        
  779.             // Autenticazione CLIENT
  780.             if(sslConfig.getKeyStoreLocation()!=null){
  781.                 bfLog.append("Gestione keystore...\n");
  782.                
  783.                 System.setProperty("javax.net.ssl.keyStore", sslConfig.getKeyStoreLocation());
  784.                 if(sslConfig.getKeyStoreType()!=null){
  785.                     System.setProperty("javax.net.ssl.keyStoreType", sslConfig.getKeyStoreType());
  786.                 }
  787.                 if(sslConfig.getKeyStorePassword()!=null){
  788.                     System.setProperty("javax.net.ssl.keyStorePassword", sslConfig.getKeyStorePassword());
  789.                 }
  790.                 if(sslConfig.getKeyPassword()!=null){
  791.                     System.setProperty("javax.net.ssl.keyStorePassword", sslConfig.getKeyStorePassword());
  792.                     if(sslConfig.getKeyStorePassword()!=null){
  793.                         if(!sslConfig.getKeyPassword().equals(sslConfig.getKeyStorePassword())){
  794.                             throw new UtilsException("Keystore and key password in java must be equals");
  795.                         }
  796.                     }
  797.                 }
  798.                
  799.                 bfLog.append("Gestione keystore effettuata\n");
  800.             }
  801.    
  802.    
  803.             // Autenticazione SERVER
  804.             if(sslConfig.getTrustStoreLocation()!=null){
  805.                 bfLog.append("Gestione truststore...\n");
  806.                
  807.                 System.setProperty("javax.net.ssl.trustStore", sslConfig.getTrustStoreLocation());
  808.                 if(sslConfig.getKeyStoreType()!=null){
  809.                     System.setProperty("javax.net.ssl.trustStoreType", sslConfig.getTrustStoreType());
  810.                 }
  811.                 if(sslConfig.getKeyStorePassword()!=null){
  812.                     System.setProperty("javax.net.ssl.trustStorePassword", sslConfig.getTrustStorePassword());
  813.                 }
  814.                
  815.                 bfLog.append("Gestione truststore effettuata\n");
  816.             }
  817.            
  818.         }catch(Exception e){
  819.             throw new UtilsException(e.getMessage(), e);
  820.         }

  821.     }
  822.    
  823.     public static String readPeerCertificates(String host, int port) throws UtilsException{
  824.         try {
  825.            
  826.             SSLContext sslContext = SSLContext.getInstance(SSLUtilities.getDefaultProtocol());
  827.             KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
  828.             TrustManagerFactory tmf =
  829.                     TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
  830.             tmf.init(ks);
  831.             X509TrustManager defaultTrustManager = (X509TrustManager)tmf.getTrustManagers()[0];
  832.             SSLSavingTrustManager   tm = new SSLSavingTrustManager(defaultTrustManager);
  833.             sslContext.init(null, new TrustManager[] {tm}, null);
  834.            
  835.             SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
  836.            
  837.             SSLSocket sslSocket = null;
  838.             try {
  839.                 sslSocket = (SSLSocket) sslSocketFactory.createSocket(host, port);
  840.                 sslSocket.setSoTimeout(10000);
  841.                 sslSocket.setWantClientAuth(false);
  842.                 try {
  843.                     sslSocket.startHandshake();
  844.                 }catch(Throwable t) {
  845.                     // ignore
  846.                 }
  847.             }finally {
  848.                 try {
  849.                     if(sslSocket!=null) {
  850.                         sslSocket.close();
  851.                     }
  852.                 }catch(Throwable t) {
  853.                     // ignore
  854.                 }
  855.             }
  856.             Certificate [] certs = tm.getPeerCertificates();
  857.             if(certs == null || certs.length<=0) {
  858.                 throw new UtilsException("Peer Certificates not found");
  859.             }
  860.             StringBuilder sb = new StringBuilder();
  861.             for (Certificate certificate : certs) {

  862.                 StringWriter sw = new StringWriter();
  863.                 JcaPEMWriter pemWriter = new JcaPEMWriter(sw);
  864.                 pemWriter.writeObject(certificate);
  865.                 pemWriter.close();
  866.                 sw.close();
  867.                 sb.append(sw.toString());

  868.             }
  869.            
  870.             return sb.toString();
  871.            
  872.         }catch(Exception e){
  873.             throw new UtilsException(e.getMessage(), e);
  874.         }
  875.     }
  876.    
  877.     public static java.security.cert.X509Certificate[] readCertificatesFromUndertowServlet(HttpServletRequest req) {
  878.         return readCertificatesFromUndertowServlet(req, null);
  879.     }
  880.     public static java.security.cert.X509Certificate[] readCertificatesFromUndertowServlet(HttpServletRequest reqParam, Logger log) {
  881.         try {
  882.             HttpServletRequest req = reqParam;
  883.             if(reqParam instanceof WrappedHttpServletRequest) {
  884.                 req = ((WrappedHttpServletRequest)reqParam).httpServletRequest;
  885.             }
  886.            
  887.             String undertow = "io.undertow.servlet.spec.HttpServletRequestImpl";
  888.             String actual = req.getClass().getName() + "";
  889.             boolean isUndertow = undertow.equals(actual);
  890.            
  891.             if(isUndertow) {
  892.                
  893.                 // io/undertow/server/HttpServerExchange.java
  894.                 Method mExchange = req.getClass().getMethod("getExchange");
  895.                 if(mExchange!=null) {
  896.                     Object exchange = mExchange.invoke(req);
  897.                     if(exchange!=null) {
  898.                         /**System.out.println("Exchange ["+exchange.getClass().getName()+"]");*/
  899.                        
  900.                         // io/undertow/server/ServerConnection.java
  901.                         Method mConnection = exchange.getClass().getMethod("getConnection");
  902.                         if(mConnection!=null) {
  903.                             Object connection = mConnection.invoke(exchange);
  904.                             if(connection!=null) {
  905.                                 /**System.out.println("Connection ["+connection.getClass().getName()+"]");*/
  906.                                
  907.                                 // io/undertow/server/SSLSessionInfo.java
  908.                                 Method mSSLSessionInfo = connection.getClass().getMethod("getSslSessionInfo");
  909.                                 if(mSSLSessionInfo!=null) {
  910.                                     Object sslSessionInfo = mSSLSessionInfo.invoke(connection);
  911.                                     if(sslSessionInfo!=null) {
  912.                                         /**System.out.println("sslSessionInfo ["+sslSessionInfo.getClass().getName()+"]");*/
  913.                                        
  914.                                         Method mPeerCertificates = sslSessionInfo.getClass().getMethod("getPeerCertificates");
  915.                                         if(mPeerCertificates!=null) {
  916.                                             try {
  917.                                                 Object peerCertificates = mPeerCertificates.invoke(sslSessionInfo);
  918.                                                 if(peerCertificates instanceof java.security.cert.X509Certificate[]) {
  919.                                                     return (java.security.cert.X509Certificate[]) peerCertificates;
  920.                                                 }
  921.                                             }catch(Throwable t) {
  922.                                                 // a volte lancia eccezione null ....
  923.                                                 if(Utilities.existsInnerException(t, "io.undertow.server.RenegotiationRequiredException")) {
  924.                                                     return null; // certificati non sono disponibili a causa di una rinegoziazione
  925.                                                 }
  926.                                                 else {
  927.                                                     if(log!=null) {
  928.                                                         log.error("readCertificatesFromUndertowServlet 'get peer certificates' failed: "+t.getMessage(),t);
  929.                                                     }
  930.                                                 }
  931.                                             }
  932.                                         }
  933.                                     }
  934.                                 }
  935.                             }
  936.                         }
  937.                     }
  938.                 }
  939.             }
  940.         }catch(Throwable t) {
  941.             if(log!=null) {
  942.                 log.error("readCertificatesFromUndertowServlet failed: "+t.getMessage(),t);
  943.             }
  944.         }
  945.         return null;
  946.     }
  947. }