CertificateUtils.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.protocol.registry;

  21. import java.io.File;
  22. import java.io.InputStream;
  23. import java.security.PrivateKey;
  24. import java.security.cert.X509Certificate;
  25. import java.text.SimpleDateFormat;
  26. import java.util.ArrayList;
  27. import java.util.Enumeration;
  28. import java.util.List;

  29. import javax.crypto.SecretKey;

  30. import org.apache.commons.lang.StringUtils;
  31. import org.openspcoop2.core.constants.CostantiLabel;
  32. import org.openspcoop2.core.constants.StatoCheck;
  33. import org.openspcoop2.utils.LoggerBuffer;
  34. import org.openspcoop2.utils.Utilities;
  35. import org.openspcoop2.utils.UtilsException;
  36. import org.openspcoop2.utils.certificate.ArchiveLoader;
  37. import org.openspcoop2.utils.certificate.CRLCertstore;
  38. import org.openspcoop2.utils.certificate.Certificate;
  39. import org.openspcoop2.utils.certificate.CertificateInfo;
  40. import org.openspcoop2.utils.certificate.JWKSet;
  41. import org.openspcoop2.utils.certificate.KeyUtils;
  42. import org.openspcoop2.utils.certificate.KeystoreParams;
  43. import org.openspcoop2.utils.certificate.KeystoreType;
  44. import org.openspcoop2.utils.certificate.hsm.HSMManager;
  45. import org.openspcoop2.utils.certificate.hsm.HSMUtils;
  46. import org.openspcoop2.utils.certificate.ocsp.IOCSPResourceReader;
  47. import org.openspcoop2.utils.certificate.ocsp.OCSPResourceReader;
  48. import org.openspcoop2.utils.certificate.ocsp.OCSPValidatorImpl;
  49. import org.openspcoop2.utils.date.DateManager;
  50. import org.openspcoop2.utils.resources.Charset;
  51. import org.openspcoop2.utils.resources.FileSystemUtilities;
  52. import org.openspcoop2.utils.transport.http.IBYOKUnwrapManager;
  53. import org.openspcoop2.utils.transport.http.IOCSPValidator;
  54. import org.slf4j.Logger;

  55. /**
  56.  *  CertificateUtils
  57.  *
  58.  * @author Poli Andrea (apoli@link.it)
  59.  * @author $Author$
  60.  * @version $Rev$, $Date$
  61.  */
  62. public class CertificateUtils {
  63.    
  64.     private CertificateUtils() {}

  65.     private static final String FORMAT_DATE_CERTIFICATE = "dd/MM/yyyy HH:mm";
  66.    
  67.     public static String toString(Certificate certificate, String separator, String newLine) throws UtilsException {
  68.         StringBuilder sb = new StringBuilder();
  69.        
  70.         SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_DATE_CERTIFICATE);
  71.        
  72.         String certificatoSubject = certificate.getCertificate().getSubject().getNameNormalized();
  73.         boolean certificatoSelfSigned = certificate.getCertificate().isSelfSigned();
  74.         String certificatoIssuer = null;
  75.         if(!certificatoSelfSigned) {
  76.             certificatoIssuer = certificate.getCertificate().getIssuer().getNameNormalized();
  77.         }
  78.         sb.append(CostantiLabel.CERTIFICATE_SUBJECT).append(separator).append(certificatoSubject);
  79.         if(certificatoSelfSigned) {
  80.             sb.append(newLine).append(CostantiLabel.CERTIFICATE_SELF_SIGNED);
  81.         }
  82.         else {
  83.             sb.append(newLine).append(CostantiLabel.CERTIFICATE_ISSUER).append(separator).append(certificatoIssuer);
  84.         }
  85.        
  86.         String notBefore = null;
  87.         if(certificate.getCertificate().getNotBefore()!=null) {
  88.             notBefore = sdf.format(certificate.getCertificate().getNotBefore());
  89.         }
  90.         String notAfter = null;
  91.         if(certificate.getCertificate().getNotAfter()!=null) {
  92.             notAfter = sdf.format(certificate.getCertificate().getNotAfter());
  93.         }
  94.         if(notBefore!=null) {
  95.             sb.append(newLine).append(CostantiLabel.CERTIFICATE_NOT_BEFORE).append(separator).append(notBefore);
  96.         }
  97.         if(notAfter!=null) {
  98.             sb.append(newLine).append(CostantiLabel.CERTIFICATE_NOT_AFTER).append(separator).append(notAfter);
  99.         }
  100.        
  101.         /** String serialNumber = certificate.getCertificate().getSerialNumber() + ""; */
  102.         String serialNumberHex = certificate.getCertificate().getSerialNumberHex() + "";
  103.         /** sb.append(newLine).append(CostantiLabel.CERTIFICATE_SERIAL_NUMBER).append(separator).append(serialNumber);
  104.         //sb.append(newLine).append(CostantiLabel.CERTIFICATE_SERIAL_NUMBER_HEX).append(separator).append(serialNumberHex); */
  105.         sb.append(newLine).append(CostantiLabel.CERTIFICATE_SERIAL_NUMBER).append(separator).append(serialNumberHex);
  106.        
  107.         /** String certificatoType = certificate.getCertificate().getType();
  108.         //String certificatoVersion = certificate.getCertificate().getVersion() + ""; */
  109.        
  110.         return sb.toString();
  111.     }
  112.    
  113.     public static String toStringKeyStore(KeystoreParams params,
  114.             String separator, String newLine) {
  115.         return toStringEngine(true, params.getKeyAlias(),
  116.                 null, params.getByokPolicy(),
  117.                 params.getPath(), params.getType(),
  118.                 separator, newLine);
  119.     }
  120.     public static String toStringKeyStore(String storePath, String storeType,
  121.             String byokPolicy,
  122.             String keyAlias,
  123.             String separator, String newLine) {
  124.         return toStringEngine(true, keyAlias,
  125.                 null, byokPolicy,
  126.                 storePath, storeType,
  127.                 separator, newLine);
  128.     }
  129.     public static String toStringTrustStore(KeystoreParams params,
  130.             String separator, String newLine) {
  131.         return toStringEngine(false, params.getKeyAlias(),
  132.                 params.getCrls(), params.getOcspPolicy(),
  133.                 params.getPath(), params.getType(),
  134.                 separator, newLine);
  135.     }
  136.     public static String toStringTrustStore(String storePath, String storeType,
  137.             String trustCRL, String ocspPolicy,
  138.             String separator, String newLine) {
  139.         return toStringTrustStore(storePath, storeType,
  140.                 trustCRL, ocspPolicy,
  141.                 null,
  142.                 separator, newLine);
  143.     }
  144.     public static String toStringTrustStore(String storePath, String storeType,
  145.             String trustCRL, String ocspPolicy,
  146.             String certAlias,
  147.             String separator, String newLine) {
  148.         return toStringEngine(false, certAlias,
  149.                 trustCRL, ocspPolicy,
  150.                 storePath, storeType,
  151.                 separator, newLine);
  152.     }
  153.     private static String toStringEngine(boolean keystore, String keyAlias,
  154.             String trustCRL, String policy, // policy è ocspPolicy in truststore e byokPolicy in keystore; nel caso di keystore crl è inutilizzato
  155.             String storePath, String storeType,
  156.             String separator, String newLine) {
  157.        
  158.         StringBuilder sb = new StringBuilder();
  159.        
  160.         sb.append(keystore? CostantiLabel.KEYSTORE : CostantiLabel.TRUSTSTORE);
  161.         sb.append(separator);
  162.         boolean hsm = HSMUtils.isKeystoreHSM(separator);
  163.         String location = storePath;
  164.         if(hsm) {
  165.             location = CostantiLabel.STORE_HSM;
  166.         }
  167.         sb.append("(").append(storeType).append(") ").append(location);
  168.        
  169.         if(!keystore && trustCRL!=null) {
  170.             sb.append(newLine);
  171.             sb.append(CostantiLabel.CRLS);
  172.             sb.append(separator);
  173.             sb.append(trustCRL);
  174.         }
  175.        
  176.         if(policy!=null) {
  177.             sb.append(newLine);
  178.             sb.append(keystore ? CostantiLabel.BYOK_POLICY : CostantiLabel.OCSP_POLICY);
  179.             sb.append(separator);
  180.             sb.append(policy);
  181.         }
  182.        
  183.         if(keyAlias!=null) {
  184.             sb.append(newLine);
  185.             if(keystore) {
  186.                 sb.append(CostantiLabel.KEY_ALIAS);
  187.             }
  188.             else {
  189.                 sb.append(CostantiLabel.CERTIFICATE_ALIAS);
  190.             }
  191.             sb.append(separator);
  192.             sb.append(keyAlias);
  193.         }
  194.        
  195.         return sb.toString();
  196.     }
  197.    
  198.    
  199.     public static KeystoreParams readKeyStoreParamsJVM() {
  200.        
  201.         KeystoreParams params = null;
  202.        
  203.         String keyStoreLocation = System.getProperty("javax.net.ssl.keyStore");
  204.         String keyStoreType = System.getProperty("javax.net.ssl.keyStoreType");
  205.         String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword");
  206.        
  207.         if(keyStoreLocation!=null || keyStoreType!=null) {
  208.             if(keyStoreLocation==null) {
  209.                 keyStoreLocation = "NONE";
  210.             }
  211.             if(keyStoreType==null) {
  212.                 keyStoreType = KeystoreType.JKS.getNome();
  213.             }
  214.             params = new KeystoreParams();
  215.             params.setPath(keyStoreLocation);
  216.             params.setType(keyStoreType);
  217.             params.setPassword(keyStorePassword);
  218.             params.setKeyPassword(keyStorePassword); // uguale in java
  219.         }
  220.    
  221.         return params;
  222.     }
  223.    
  224.     public static KeystoreParams readTrustStoreParamsJVM() {
  225.        
  226.         KeystoreParams params = null;
  227.        
  228.         String trustStoreLocation = System.getProperty("javax.net.ssl.trustStore");
  229.         String trustStoreType = System.getProperty("javax.net.ssl.trustStoreType");
  230.         String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword");
  231.        
  232.         if(trustStoreLocation!=null) {
  233.             if(trustStoreType==null) {
  234.                 trustStoreType = KeystoreType.JKS.getNome();
  235.             }
  236.             params = new KeystoreParams();
  237.             params.setPath(trustStoreLocation);
  238.             params.setType(trustStoreType);
  239.             params.setPassword(trustStorePassword);
  240.         }
  241.    
  242.         return params;
  243.     }
  244.    
  245.     private static final String NOT_EXISTS_STRING = " not exists";
  246.     private static final String CANNOT_READ_STRING = " cannot read";
  247.     private static final String READING_PREFIX_STRING = "Reading ";
  248.     private static final String SERIAL_NUMBER_STRING = " serialNumber:";
  249.     private static String getSuffixCertificateNotValid(Exception t) {
  250.         return " non risulta valido: "+t.getMessage();
  251.     }
  252.     private static String getSuffixFailed(Exception t) {
  253.         return " failed: "+t.getMessage();
  254.     }
  255.    
  256.     public static CertificateCheck checkCertificateClient(List<byte[]>certs, List<Boolean> strictValidation, int sogliaWarningGiorni,
  257.             boolean addCertificateDetails, String separator, String newLine,
  258.             Logger log) throws UtilsException{
  259.        
  260.         SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_DATE_CERTIFICATE);
  261.        
  262.         if(certs==null || certs.isEmpty()) {
  263.             throw new UtilsException("Nessun certificato individuato");
  264.         }
  265.         if(strictValidation==null || strictValidation.isEmpty()) {
  266.             throw new UtilsException("Nessuna informazione sul tipo di validazione fornita");
  267.         }
  268.         if(strictValidation.size()!=certs.size()) {
  269.             throw new UtilsException("Rilevata inconsistenza tra le informazioni fornite sul tipo di validazione e i certificati");
  270.         }
  271.        
  272.         CertificateCheck esito = new CertificateCheck();
  273.                
  274.         boolean error = false;
  275.         boolean warning = false;
  276.         boolean almostOneValid = false;
  277.         for (int i = 0; i < certs.size(); i++) {
  278.             boolean principale = (i==0);
  279.             Certificate certificate = null;
  280.             String identitaCertificato = "Certificato "+ (principale ? "principale" : "n."+(i+1));
  281.             String credenziale = "Certificato";
  282.             if(principale && certs.size()>1) {
  283.                 credenziale = credenziale + " principale";
  284.             }
  285.             try {
  286.                 byte [] bytesCert = certs.get(i);
  287.                 boolean strictValidationCert = strictValidation.get(i);
  288.                 certificate = ArchiveLoader.load(bytesCert);
  289.                
  290.                 String hex = certificate.getCertificate().getSerialNumberHex();
  291.                 String certificateDetails = null;
  292.                 if(addCertificateDetails) {
  293.                     certificateDetails = CertificateUtils.toString(certificate, separator, newLine);
  294.                 }
  295.                 else {
  296.                     credenziale = credenziale+ " (CN:"+certificate.getCertificate().getSubject().getCN()+SERIAL_NUMBER_STRING+hex+")";
  297.                 }
  298.                 boolean check = true;
  299.                 try {
  300.                     certificate.getCertificate().checkValid();
  301.                 }catch(Exception t) {
  302.                     check = false;
  303.                     if(strictValidationCert) {
  304.                         String msgErrore = credenziale+" non valido: "+t.getMessage();
  305.                         error = true;
  306.                         esito.addError(identitaCertificato, msgErrore, certificateDetails);
  307.                         continue;
  308.                     }
  309.                     else {
  310.                         String msgErrore = credenziale+" utilizzato per attivare la validazione tramite Subject e Issuer non risulta valido: "+t.getMessage();
  311.                         warning = true;
  312.                         esito.addWarning(identitaCertificato, msgErrore, certificateDetails);
  313.                     }
  314.                 }
  315.                                    
  316.                 if(check && certificate.getCertificateChain()!=null && !certificate.getCertificateChain().isEmpty()) {
  317.                     for (CertificateInfo caChain : certificate.getCertificateChain()) {
  318.                         String hexCaChain = caChain.getSerialNumberHex();
  319.                         String credenzialeCaChain = "(CN:"+caChain.getSubject().getCN()+SERIAL_NUMBER_STRING+hexCaChain+")";
  320.                         try {
  321.                             caChain.checkValid();
  322.                         }catch(Exception t) {
  323.                             check = false;
  324.                             String msgErrore = (credenziale+"; un certificato della catena "+credenzialeCaChain+getSuffixCertificateNotValid(t));
  325.                             if(strictValidationCert) {
  326.                                 error = true;
  327.                                 esito.addError(identitaCertificato, msgErrore, certificateDetails);
  328.                                 continue;
  329.                             }
  330.                             else {
  331.                                 warning = true;
  332.                                 esito.addWarning(identitaCertificato, msgErrore, certificateDetails);
  333.                             }
  334.                         }
  335.                     }
  336.                 }
  337.                
  338.                 if(check && sogliaWarningGiorni>0 &&
  339.                     certificate.getCertificate().getNotAfter()!=null) {
  340.                     long expire = certificate.getCertificate().getNotAfter().getTime();
  341.                     long now = DateManager.getTimeMillis();
  342.                     long diff = expire - now;
  343.                     long soglia = (1000l*60l*60l*24l) * ((long)sogliaWarningGiorni);
  344.                     /**System.out.println("=======================");
  345.                     //System.out.println("SUBJECT ["+certificate.getCertificate().getCertificate().getSubjectDN().getName()+"]");
  346.                     //System.out.println("NOT AFTER ["+certificate.getCertificate().getNotAfter()+"]");
  347.                     //System.out.println("SOGLIA ["+sogliaWarningGiorni+"]");
  348.                     //System.out.println("DEXP ["+expire+"]");
  349.                     //System.out.println("DNOW ["+now+"]");
  350.                     //System.out.println("DIFF ["+diff+"]");
  351.                     //System.out.println("SOGLIATR ["+soglia+"]");*/
  352.                     if(diff<soglia) {
  353.                         String msgErrore = credenziale+" prossima alla scadenza ("+sogliaWarningGiorni+" giorni): "+sdf.format(certificate.getCertificate().getNotAfter());
  354.                         warning = true;
  355.                         esito.addWarning(identitaCertificato, msgErrore, certificateDetails);
  356.                     }
  357.                 }
  358.                
  359.             }catch(Exception t) {
  360.                 // non dovrebbe succedere
  361.                 String msgError = "L'analisi del certificato ha prodotto un errore non atteso: "+t.getMessage();
  362.                 esito.addError(identitaCertificato, msgError, null);
  363.                 log.error(msgError, t);
  364.                 error = true;
  365.                 continue;
  366.             }
  367.                
  368.             almostOneValid = true;
  369.         }
  370.        
  371.        
  372.         if(almostOneValid) {
  373.             if(error || warning) {
  374.                 esito.setStatoCheck(StatoCheck.WARN);
  375.             }
  376.             else {
  377.                 esito.setStatoCheck(StatoCheck.OK);
  378.             }
  379.         }
  380.         else {
  381.             esito.setStatoCheck(StatoCheck.ERROR);
  382.         }
  383.         return esito;

  384.     }
  385.    
  386.     public static CertificateCheck checkTrustStore(String trustStore, boolean classpathSupported, String type, String password, String trustStoreCrls, String ocspPolicy,
  387.             int sogliaWarningGiorni,
  388.             boolean addCertificateDetails, String separator, String newLine,
  389.             Logger log) throws UtilsException{
  390.         return checkTrustStore(trustStore, classpathSupported, type, password, trustStoreCrls, ocspPolicy, null,
  391.                 sogliaWarningGiorni,
  392.                 addCertificateDetails, separator, newLine,
  393.                 log);
  394.     }
  395.     public static CertificateCheck checkTrustStore(String trustStore, boolean classpathSupported, String type, String password, String trustStoreCrls,String ocspPolicy,String certAlias,
  396.             int sogliaWarningGiorni,
  397.             boolean addCertificateDetails, String separator, String newLine,
  398.             Logger log) throws UtilsException{
  399.        
  400.         boolean hsm = HSMUtils.isKeystoreHSM(type);
  401.         byte [] keystoreBytes = null;
  402.         if(!hsm) {
  403.             File f = new File(trustStore);
  404.             boolean exists = f.exists();
  405.             boolean inClasspath = false;
  406.             if(!exists && classpathSupported) {
  407.                 String uri = trustStore;
  408.                 if(!trustStore.startsWith("/")) {
  409.                     uri = "/" + uri;    
  410.                 }
  411.                 try {
  412.                     try( InputStream is = CertificateUtils.class.getResourceAsStream(uri); ){
  413.                         exists = (is!=null);
  414.                         if(exists) {
  415.                             inClasspath = true;
  416.                             keystoreBytes = Utilities.getAsByteArray(is);
  417.                         }
  418.                     }
  419.                 }catch(Exception e) {
  420.                     throw new UtilsException(e.getMessage(),e);
  421.                 }
  422.             }
  423.             if(!exists || (!inClasspath && !f.canRead())) {
  424.                
  425.                 String storeDetails = null;
  426.                 if(addCertificateDetails) {
  427.                     storeDetails = toStringTrustStore(trustStore, type, trustStoreCrls, ocspPolicy, certAlias, separator, newLine);
  428.                 }
  429.                 String errorDetails = CostantiLabel.TRUSTSTORE;
  430.                 if(!addCertificateDetails) {
  431.                     errorDetails = errorDetails + " '"+
  432.                             //f.getAbsolutePath()+  // nel caso di path relativo viene visualizzato un PATH basato sul bin di wildfly ed e' forviante
  433.                             trustStore+
  434.                             "'";
  435.                 }
  436.                 errorDetails = errorDetails + (!exists ? NOT_EXISTS_STRING : CANNOT_READ_STRING);
  437.                
  438.                 CertificateCheck esito = new CertificateCheck();
  439.                 esito.setStatoCheck(StatoCheck.ERROR);
  440.                 esito.addError(trustStore, errorDetails, storeDetails);
  441.                 return esito;
  442.             }
  443.             if(!inClasspath) {
  444.                 try {
  445.                     keystoreBytes = FileSystemUtilities.readBytesFromFile(f);
  446.                 }catch(Exception e) {
  447.                     throw new UtilsException(e.getMessage(),e);
  448.                 }
  449.             }
  450.         }
  451.         return checkStore(false, certAlias, null,
  452.                 trustStoreCrls, ocspPolicy, null,
  453.                 trustStore, keystoreBytes, type, password,
  454.                 sogliaWarningGiorni,
  455.                 addCertificateDetails, separator, newLine,
  456.                 log);
  457.     }
  458.     public static CertificateCheck checkTrustStore(String trustStorePath, byte[] trustStore, String type, String password, String trustStoreCrls, String ocspPolicy,
  459.             int sogliaWarningGiorni,
  460.             boolean addCertificateDetails, String separator, String newLine,
  461.             Logger log) throws UtilsException{
  462.         return checkStore(false, null, null,
  463.                 trustStoreCrls, ocspPolicy, null,
  464.                 trustStorePath!=null ? trustStorePath : CostantiLabel.STORE_CARICATO_BASEDATI, trustStore, type, password,
  465.                 sogliaWarningGiorni,
  466.                 addCertificateDetails, separator, newLine,
  467.                 log);
  468.     }
  469.     public static CertificateCheck checkTrustStore(String trustStorePath, byte[] trustStore, String type, String password, String trustStoreCrls, String ocspPolicy,
  470.             String alias,
  471.             int sogliaWarningGiorni,
  472.             boolean addCertificateDetails, String separator, String newLine,
  473.             Logger log) throws UtilsException{
  474.         return checkStore(false, alias, null,
  475.                 trustStoreCrls, ocspPolicy, null,
  476.                 trustStorePath!=null ? trustStorePath : CostantiLabel.STORE_CARICATO_BASEDATI, trustStore, type, password,
  477.                 sogliaWarningGiorni,
  478.                 addCertificateDetails, separator, newLine,
  479.                 log);
  480.     }
  481.     public static CertificateCheck checkKeyStore(String keyStore, boolean classpathSupported, String type, String password, IBYOKUnwrapManager byokUnwrapManager,
  482.             String aliasKey, String passwordKey,
  483.             int sogliaWarningGiorni,
  484.             boolean addCertificateDetails, String separator, String newLine,
  485.             Logger log) throws UtilsException{
  486.         boolean hsm = HSMUtils.isKeystoreHSM(type);
  487.         byte [] keystoreBytes = null;
  488.         if(!hsm) {
  489.             File f = new File(keyStore);
  490.             boolean exists = f.exists();
  491.             boolean inClasspath = false;
  492.             if(!exists && classpathSupported) {
  493.                 String uri = keyStore;
  494.                 if(!keyStore.startsWith("/")) {
  495.                     uri = "/" + uri;    
  496.                 }
  497.                 try {
  498.                     try( InputStream is = CertificateUtils.class.getResourceAsStream(uri); ){
  499.                         exists = (is!=null);
  500.                         if(exists) {
  501.                             inClasspath = true;
  502.                             keystoreBytes = Utilities.getAsByteArray(is);
  503.                         }
  504.                     }
  505.                 }catch(Exception e) {
  506.                     throw new UtilsException(e.getMessage(),e);
  507.                 }
  508.             }
  509.             if(!exists || (!inClasspath && !f.canRead())) {
  510.                
  511.                 String storeDetails = null;
  512.                 if(addCertificateDetails) {
  513.                     storeDetails = toStringKeyStore(keyStore, type, (byokUnwrapManager!=null ? byokUnwrapManager.getPolicy() : null), aliasKey, separator, newLine);
  514.                 }
  515.                 String errorDetails = CostantiLabel.KEYSTORE;
  516.                 if(!addCertificateDetails) {
  517.                     errorDetails = errorDetails + " '"+
  518.                             //f.getAbsolutePath()+  // nel caso di path relativo viene visualizzato un PATH basato sul bin di wildfly ed e' forviante
  519.                             keyStore+
  520.                             "'";
  521.                 }
  522.                 errorDetails = errorDetails + (!exists ? NOT_EXISTS_STRING : CANNOT_READ_STRING);
  523.                
  524.                 CertificateCheck esito = new CertificateCheck();
  525.                 esito.setStatoCheck(StatoCheck.ERROR);
  526.                 esito.addError(keyStore, errorDetails, storeDetails);
  527.                 return esito;
  528.             }
  529.             if(!inClasspath) {
  530.                 try {
  531.                     keystoreBytes = FileSystemUtilities.readBytesFromFile(f);
  532.                 }catch(Exception e) {
  533.                     throw new UtilsException(e.getMessage(),e);
  534.                 }
  535.             }
  536.         }
  537.         return checkStore(true, aliasKey, passwordKey,
  538.                 null, null, byokUnwrapManager,
  539.                 keyStore, keystoreBytes, type, password,
  540.                 sogliaWarningGiorni,
  541.                 addCertificateDetails, separator, newLine,
  542.                 log);
  543.     }
  544.     public static CertificateCheck checkKeyStore(String keyStorePath, byte[] keyStore, String type, String password, IBYOKUnwrapManager byokUnwrapManager,
  545.             String aliasKey, String passwordKey,
  546.             int sogliaWarningGiorni,
  547.             boolean addCertificateDetails, String separator, String newLine,
  548.             Logger log) throws UtilsException{
  549.         return checkStore(true, aliasKey, passwordKey,
  550.                 null, null, byokUnwrapManager,
  551.                 keyStorePath!=null ? keyStorePath : CostantiLabel.STORE_CARICATO_BASEDATI, keyStore, type, password,
  552.                 sogliaWarningGiorni,
  553.                 addCertificateDetails, separator, newLine,
  554.                 log);
  555.     }
  556.     private static CertificateCheck checkStore(boolean keystore, String aliasKey, String passwordKey,
  557.             String trustStoreCrls, String ocspPolicy, IBYOKUnwrapManager byokUnwrapManager,
  558.             String storePath, byte[] storeBytes, String type, String password,
  559.             int sogliaWarningGiorni,
  560.             boolean addCertificateDetails, String separator, String newLine,
  561.             Logger log) throws UtilsException{
  562.        
  563.         SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_DATE_CERTIFICATE);
  564.        
  565.         String storeDetails = "";
  566.         if(addCertificateDetails) {
  567.             if(keystore) {
  568.                 storeDetails = toStringKeyStore(storePath, type, (byokUnwrapManager!=null ? byokUnwrapManager.getPolicy() : null), aliasKey, separator, newLine);
  569.             }
  570.             else {
  571.                 storeDetails = toStringTrustStore(storePath, type, trustStoreCrls, ocspPolicy, aliasKey, separator, newLine);
  572.             }
  573.         }
  574.                
  575.         org.openspcoop2.utils.certificate.KeyStore store = null;
  576.         try {
  577.             if(HSMUtils.isKeystoreHSM(type)) {
  578.                 store = HSMManager.getInstance().getKeystore(type);
  579.             }
  580.             else {
  581.                 if(keystore && byokUnwrapManager!=null) {
  582.                     storeBytes = byokUnwrapManager.unwrap(storeBytes);
  583.                 }
  584.                 store = new org.openspcoop2.utils.certificate.KeyStore(storeBytes, type, password);
  585.             }
  586.         }catch(Exception t) {
  587.             CertificateCheck esito = new CertificateCheck();
  588.             esito.setStatoCheck(StatoCheck.ERROR);
  589.             esito.addError(storePath, "Non è possibile accedere al "+(keystore ? CostantiLabel.KEYSTORE : CostantiLabel.TRUSTSTORE)+": "+t.getMessage(), storeDetails);
  590.             return esito;
  591.         }
  592.        
  593.         IOCSPValidator ocspValidator = null;
  594.         CRLCertstore crls = null;      
  595.         if(!keystore && (
  596.                 (trustStoreCrls!=null && StringUtils.isNotEmpty(trustStoreCrls))
  597.                 ||
  598.                 (ocspPolicy!=null && StringUtils.isNotEmpty(ocspPolicy))
  599.                 )
  600.             ) {
  601.            
  602.             boolean crlByOcsp = false;
  603.             if(ocspPolicy!=null && StringUtils.isNotEmpty(ocspPolicy)) {
  604.                 LoggerBuffer lb = new LoggerBuffer();
  605.                 lb.setLogDebug(log);
  606.                 lb.setLogError(log);
  607.                 IOCSPResourceReader ocspResourceReader = new OCSPResourceReader();
  608.                 ocspValidator = new OCSPValidatorImpl(lb, store, trustStoreCrls, ocspPolicy, ocspResourceReader);
  609.                 if(ocspValidator!=null) {
  610.                     OCSPValidatorImpl gOcspValidator = (OCSPValidatorImpl) ocspValidator;
  611.                     if(gOcspValidator.getOcspConfig()!=null) {
  612.                         crlByOcsp = gOcspValidator.getOcspConfig().isCrl();
  613.                     }
  614.                 }
  615.             }
  616.            
  617.             List<String> crlList = null;
  618.             if(trustStoreCrls!=null && StringUtils.isNotEmpty(trustStoreCrls)) {
  619.                 crlList = CRLCertstore.readCrlPaths(trustStoreCrls);
  620.             }
  621.             if(crlList!=null && !crlList.isEmpty()) {
  622.                 for (String path : crlList) {
  623.                     File f = new File(path);
  624.                     if(!f.exists() || !f.canRead()) {
  625.                        
  626.                         /** String identita = CostantiLabel.CRL+" '"+path+"'"; */
  627.                         String identita = CostantiLabel.CRL;
  628.                         if(addCertificateDetails) {
  629.                             identita = CostantiLabel.CRL+" '"+path+"'";
  630.                         }
  631.                         String errorDetails = identita;
  632.                         if(!addCertificateDetails) {
  633.                             errorDetails = errorDetails + " '"+
  634.                                     //f.getAbsolutePath()+  // nel caso di path relativo viene visualizzato un PATH basato sul bin di wildfly ed e' forviante
  635.                                     path+
  636.                                     "'";
  637.                         }
  638.                         errorDetails = errorDetails + (!f.exists() ? NOT_EXISTS_STRING : CANNOT_READ_STRING);
  639.                        
  640.                         CertificateCheck esito = new CertificateCheck();
  641.                         esito.setStatoCheck(StatoCheck.ERROR);
  642.                         esito.addError(identita, errorDetails, storeDetails);
  643.                         return esito;
  644.                     }                  
  645.                 }
  646.                
  647.                 if(!crlByOcsp) {
  648.                     crls = new CRLCertstore(trustStoreCrls);
  649.                 }
  650.             }
  651.         }
  652.        
  653.         CertificateCheck esito = new CertificateCheck();
  654.         boolean error = false;
  655.         boolean warning = false;
  656.        
  657.         List<String> aliasesForCheck = null;
  658.        
  659.         if(keystore) {
  660.            
  661.             List<String> alias = new ArrayList<>();
  662.             if(aliasKey!=null) {
  663.                 alias.add(aliasKey);
  664.             }
  665.             else {
  666.                 try {
  667.                     Enumeration<String> aliases = store.aliases();
  668.                     while (aliases.hasMoreElements()) {
  669.                         String aliasCheck = aliases.nextElement();
  670.                         if(store.getKeystore().isKeyEntry(aliasCheck)) {
  671.                             alias.add(aliasCheck);
  672.                         }
  673.                     }
  674.                 }catch(Exception e) {
  675.                     throw new UtilsException(e.getMessage(),e);
  676.                 }
  677.             }
  678.             if(alias.isEmpty()) {
  679.                 esito = new CertificateCheck();
  680.                 esito.setStatoCheck(StatoCheck.ERROR);
  681.                 esito.addError(storePath, "Nel "+CostantiLabel.KEYSTORE+" non sono presenti chiavi private", storeDetails);
  682.                 return esito;
  683.             }
  684.            
  685.             aliasesForCheck = alias;
  686.            
  687.         }
  688.         else {
  689.            
  690.             List<String> alias = new ArrayList<>();
  691.             if(aliasKey!=null) {
  692.                 alias.add(aliasKey);
  693.             }
  694.             else {
  695.                 Enumeration<String> aliases = store.aliases();
  696.                 while (aliases.hasMoreElements()) {
  697.                     String aliasCheck = aliases.nextElement();
  698.                     alias.add(aliasCheck);
  699.                 }
  700.             }
  701.            
  702.             if(alias.isEmpty()) {
  703.                 esito = new CertificateCheck();
  704.                 esito.setStatoCheck(StatoCheck.ERROR);
  705.                 esito.addError(storePath, "Nel "+CostantiLabel.TRUSTSTORE+" non sono presenti certificati", storeDetails);
  706.                 return esito;
  707.             }
  708.            
  709.             aliasesForCheck = alias;
  710.         }
  711.        
  712.         List<Certificate> listCertificate = new ArrayList<>();
  713.         if(aliasesForCheck!=null && !aliasesForCheck.isEmpty()) {
  714.             for (String aliasVerify : aliasesForCheck) {
  715.                
  716.                 boolean secret = KeystoreType.JCEKS.getNome().equalsIgnoreCase(store.getKeystoreType());
  717.                
  718.                 java.security.cert.X509Certificate cert = (java.security.cert.X509Certificate) store.getCertificate(aliasVerify);
  719.                 SecretKey secretKey = null;
  720.                 if(cert==null && secret && store.existsAlias(aliasKey)) {
  721.                     // provo a vedere se si tratta di una chiave segreta
  722.                     String errorKey = null;
  723.                     try {
  724.                         secretKey = store.getSecretKey(aliasVerify, passwordKey);
  725.                     }catch(Exception e) {
  726.                         errorKey = e.getMessage();
  727.                     }
  728.                     if(secretKey==null) {
  729.                         esito = new CertificateCheck();
  730.                         esito.setStatoCheck(StatoCheck.ERROR);
  731.                         esito.addError(storePath, "Nel "+
  732.                                 CostantiLabel.KEYSTORE+
  733.                                 " la chiave segreta "+
  734.                                 " con alias '"+aliasVerify+"' non è accessibile"+
  735.                                 (errorKey!=null ? ": "+errorKey : ""), storeDetails);
  736.                         return esito;
  737.                     }
  738.                 }
  739.                 if(cert==null && secretKey==null) {
  740.                     esito = new CertificateCheck();
  741.                     esito.setStatoCheck(StatoCheck.ERROR);
  742.                     esito.addError(storePath, "Nel "+
  743.                             (keystore ? CostantiLabel.KEYSTORE : CostantiLabel.TRUSTSTORE)+
  744.                             " non è presente "+
  745.                             (keystore ? "una coppia di chiavi" : "un certificato")+
  746.                             " con alias '"+aliasVerify+"'", storeDetails);
  747.                     return esito;
  748.                 }
  749.                
  750.                 if(keystore && secretKey==null) {
  751.                     PrivateKey privateKey = null;
  752.                     String errorKey = null;
  753.                     try {
  754.                         privateKey = store.getPrivateKey(aliasVerify, passwordKey);
  755.                     }catch(Exception e) {
  756.                         errorKey = e.getMessage();
  757.                     }
  758.                     if(privateKey==null) {
  759.                         esito = new CertificateCheck();
  760.                         esito.setStatoCheck(StatoCheck.ERROR);
  761.                         esito.addError(storePath, "Nel "+
  762.                                 CostantiLabel.KEYSTORE+
  763.                                 " la chiave "+
  764.                                 " con alias '"+aliasVerify+"' non è accessibile"+
  765.                                 (errorKey!=null ? ": "+errorKey : ""), storeDetails);
  766.                         return esito;
  767.                     }
  768.                 }
  769.                
  770.                 if(secretKey==null) {
  771.                     java.security.cert.Certificate[] baseCertChain = store.getCertificateChain(aliasVerify);
  772.                     List<java.security.cert.X509Certificate> certChain = null;
  773.                     if(baseCertChain!=null && baseCertChain.length>0) {
  774.                         for (int i = 0; i < baseCertChain.length; i++) {
  775.                             java.security.cert.Certificate check = baseCertChain[i];
  776.                             if(check instanceof X509Certificate) {
  777.                                 if(certChain==null) {
  778.                                     certChain = new ArrayList<>();
  779.                                 }
  780.                                 certChain.add((X509Certificate) check);
  781.                             }
  782.                         }
  783.                     }
  784.                                    
  785.                     Certificate certificate = new Certificate(aliasVerify,
  786.                             cert,
  787.                             certChain );
  788.                     listCertificate.add(certificate);
  789.                 }
  790.             }
  791.         }
  792.                
  793.         if(listCertificate!=null && !listCertificate.isEmpty()) {
  794.             for (Certificate certificate : listCertificate) {  
  795.                
  796.                 String aliasVerify = certificate.getCertificate().getName();
  797.                 String identita = "Certificato '"+aliasVerify+"'";
  798.                
  799.                 String aliasDetails = "";
  800.                 if(!storeDetails.contains(CostantiLabel.KEY_ALIAS+separator+aliasVerify)) {
  801.                     aliasDetails = (addCertificateDetails ? newLine : "") +
  802.                             CostantiLabel.ALIAS+separator+aliasVerify;
  803.                 }
  804.                 String certificateDetails = CertificateUtils.toString(certificate, separator, newLine);
  805.                 certificateDetails = storeDetails +
  806.                         aliasDetails +
  807.                         newLine +
  808.                         certificateDetails;
  809.                 boolean check = true;
  810.                 try {
  811.                     if(keystore || crls==null) {
  812.                         certificate.getCertificate().checkValid();
  813.                     }
  814.                     else {
  815.                         certificate.getCertificate().checkValid(crls.getCertStore(), store);
  816.                     }
  817.                     if(ocspValidator!=null) {
  818.                         ocspValidator.valid(certificate.getCertificate().getCertificate());
  819.                     }
  820.                 }catch(Exception t) {
  821.                     String msgErrore = "Certificato non valido: "+t.getMessage();
  822.                     error = true;
  823.                     esito.addError(identita, msgErrore, certificateDetails);
  824.                     /** check = false; */
  825.                     continue;
  826.                 }
  827.                                    
  828.                 if(check && certificate.getCertificateChain()!=null && !certificate.getCertificateChain().isEmpty()) {
  829.                     for (CertificateInfo caChain : certificate.getCertificateChain()) {
  830.                         String hexCaChain = caChain.getSerialNumberHex();
  831.                         String credenzialeCaChain = "(CN:"+caChain.getSubject().getCN()+SERIAL_NUMBER_STRING+hexCaChain+")";
  832.                         try {
  833.                             if(keystore || crls==null) {
  834.                                 caChain.checkValid();
  835.                             }
  836.                             else {
  837.                                 caChain.checkValid(crls.getCertStore(), store);
  838.                             }
  839.                             // La validazione della catena viene effettuata direttamente dal ocsp validator se previsto dalla policy
  840. /**                         if(ocspValidator!=null) {
  841. //                              ocspValidator.valid(certificate.getCertificate().getCertificate());
  842. //                          }*/
  843.                         }catch(Exception t) {
  844.                             check = false;
  845.                             String msgErrore = ("Un certificato della catena "+credenzialeCaChain+getSuffixCertificateNotValid(t));
  846.                             error = true;
  847.                             esito.addError(identita, msgErrore, certificateDetails);
  848.                         }
  849.                     }
  850.                 }
  851.                
  852.                 if(check && sogliaWarningGiorni>0 &&
  853.                     certificate.getCertificate().getNotAfter()!=null) {
  854.                     long expire = certificate.getCertificate().getNotAfter().getTime();
  855.                     long now = DateManager.getTimeMillis();
  856.                     long diff = expire - now;
  857.                     long soglia = (1000l*60l*60l*24l) * (sogliaWarningGiorni);
  858.                     /**System.out.println("=======================");
  859.                     //System.out.println("SUBJECT ["+certificate.getCertificate().getCertificate().getSubjectDN().getName()+"]");
  860.                     //System.out.println("NOT AFTER ["+certificate.getCertificate().getNotAfter()+"]");
  861.                     //System.out.println("SOGLIA ["+sogliaWarningGiorni+"]");
  862.                     //System.out.println("DEXP ["+expire+"]");
  863.                     //System.out.println("DNOW ["+now+"]");
  864.                     //System.out.println("DIFF ["+diff+"]");
  865.                     //System.out.println("SOGLIATR ["+soglia+"]");*/
  866.                     if(diff<soglia) {
  867.                         String msgErrore = "Certificato prossima alla scadenza ("+sogliaWarningGiorni+" giorni): "+sdf.format(certificate.getCertificate().getNotAfter());
  868.                         warning = true;
  869.                         esito.addWarning(identita, msgErrore, certificateDetails);
  870.                     }
  871.                 }
  872.                
  873.             }
  874.         }
  875.                
  876.         if(error) {
  877.             esito.setStatoCheck(StatoCheck.ERROR);
  878.         }
  879.         else if(warning) {
  880.             esito.setStatoCheck(StatoCheck.WARN);
  881.         }
  882.         else {
  883.             esito.setStatoCheck(StatoCheck.OK);
  884.         }
  885.         return esito;

  886.     }
  887.    
  888.    
  889.     public static CertificateCheck checkSingleCertificate(String storeDetails, byte[] bytesCert,
  890.             int sogliaWarningGiorni,
  891.             String separator, String newLine) throws UtilsException{
  892.        
  893.         SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_DATE_CERTIFICATE);
  894.        
  895.        
  896.         CertificateCheck esito = new CertificateCheck();
  897.         boolean error = false;
  898.         boolean warning = false;
  899.        
  900.         Certificate certificate = ArchiveLoader.load(bytesCert);        
  901.        
  902.         String identita = "Certificato";
  903.        
  904.         String certificateDetails = storeDetails +
  905.                 newLine +
  906.                 CertificateUtils.toString(certificate, separator, newLine);
  907.         boolean check = true;
  908.         try {
  909.             certificate.getCertificate().checkValid();
  910.         }catch(Exception t) {
  911.             check = false;
  912.             String msgErrore = "Certificato non valido: "+t.getMessage();
  913.             error = true;
  914.             esito.addError(identita, msgErrore, certificateDetails);
  915.         }
  916.                            
  917.         if(check && certificate.getCertificateChain()!=null && !certificate.getCertificateChain().isEmpty()) {
  918.             for (CertificateInfo caChain : certificate.getCertificateChain()) {
  919.                 String hexCaChain = caChain.getSerialNumberHex();
  920.                 String credenzialeCaChain = "(CN:"+caChain.getSubject().getCN()+SERIAL_NUMBER_STRING+hexCaChain+")";
  921.                 try {
  922.                     caChain.checkValid();
  923.                 }catch(Exception t) {
  924.                     check = false;
  925.                     String msgErrore = ("Un certificato della catena "+credenzialeCaChain+getSuffixCertificateNotValid(t));
  926.                     error = true;
  927.                     esito.addError(identita, msgErrore, certificateDetails);
  928.                 }
  929.             }
  930.         }
  931.        
  932.         if(check && sogliaWarningGiorni>0 &&
  933.             certificate.getCertificate().getNotAfter()!=null) {
  934.             long expire = certificate.getCertificate().getNotAfter().getTime();
  935.             long now = DateManager.getTimeMillis();
  936.             long diff = expire - now;
  937.             long soglia = (1000l*60l*60l*24l) * (sogliaWarningGiorni);
  938.             /**System.out.println("=======================");
  939.             //System.out.println("SUBJECT ["+certificate.getCertificate().getCertificate().getSubjectDN().getName()+"]");
  940.             //System.out.println("NOT AFTER ["+certificate.getCertificate().getNotAfter()+"]");
  941.             //System.out.println("SOGLIA ["+sogliaWarningGiorni+"]");
  942.             //System.out.println("DEXP ["+expire+"]");
  943.             //System.out.println("DNOW ["+now+"]");
  944.             //System.out.println("DIFF ["+diff+"]");
  945.             //System.out.println("SOGLIATR ["+soglia+"]");*/
  946.             if(diff<soglia) {
  947.                 String msgErrore = "Certificato prossima alla scadenza ("+sogliaWarningGiorni+" giorni): "+sdf.format(certificate.getCertificate().getNotAfter());
  948.                 warning = true;
  949.                 esito.addWarning(identita, msgErrore, certificateDetails);
  950.             }
  951.         }
  952.            
  953.         if(error) {
  954.             esito.setStatoCheck(StatoCheck.ERROR);
  955.         }
  956.         else if(warning) {
  957.             esito.setStatoCheck(StatoCheck.WARN);
  958.         }
  959.         else {
  960.             esito.setStatoCheck(StatoCheck.OK);
  961.         }
  962.         return esito;

  963.     }
  964.    
  965.    
  966.    
  967.     public static CertificateCheck checkKeyPair(String privateKeyPath, byte[] privateKey,
  968.             String publicKeyPath, byte[] publicKey, String passwordKey, String algorithm, IBYOKUnwrapManager byokUnwrapManager,
  969.             boolean addCertificateDetails, String separator, String newLine) throws UtilsException{
  970.        
  971.         String storeDetails = null;
  972.         if(addCertificateDetails) {
  973.             storeDetails = toStringKeyPair(privateKeyPath, publicKeyPath,
  974.                     (byokUnwrapManager!=null ? byokUnwrapManager.getPolicy() : null),
  975.                     separator, newLine);
  976.         }
  977.        
  978.         return checkKeyPairEngine(true,
  979.                 storeDetails, privateKey, publicKey, passwordKey, algorithm, byokUnwrapManager,
  980.                 addCertificateDetails);
  981.     }
  982.     public static CertificateCheck checkKeyPair(boolean classpathSupported, String privateKey, String publicKey, String passwordKey, String algorithm, IBYOKUnwrapManager byokUnwrapManager,
  983.             boolean addCertificateDetails, String separator, String newLine) throws UtilsException{
  984.         return checkKeyPairEngine(true,
  985.                 classpathSupported, privateKey, publicKey, passwordKey, algorithm, byokUnwrapManager,
  986.                 addCertificateDetails, separator, newLine);
  987.     }
  988.     public static String toStringKeyPair(KeystoreParams params,
  989.             String separator, String newLine) {
  990.         return toStringKeyPair(params.getPath(), params.getKeyPairPublicKeyPath(), params.getByokPolicy(),
  991.                 separator, newLine);
  992.     }
  993.     private static String toStringKeyPair(String privateKey, String publicKey, String byokPolicy,
  994.             String separator, String newLine) {
  995.        
  996.         StringBuilder sb = new StringBuilder();
  997.        
  998.         sb.append(CostantiLabel.KEY_PAIR);
  999.         sb.append(separator);
  1000.         sb.append("private:");
  1001.         sb.append(privateKey);
  1002.         sb.append(" ");
  1003.         sb.append("public:");
  1004.         sb.append(publicKey);
  1005.        
  1006.         if(byokPolicy!=null) {
  1007.             sb.append(newLine);
  1008.             sb.append(CostantiLabel.BYOK_POLICY);
  1009.             sb.append(separator);
  1010.             sb.append(byokPolicy);
  1011.         }
  1012.        
  1013.         return sb.toString();
  1014.     }
  1015.    
  1016.     public static CertificateCheck checkPublicKey(String publicKeyPath, byte[] publicKey, String algorithm,
  1017.             boolean addCertificateDetails, String separator, String newLine) throws UtilsException{
  1018.        
  1019.         String storeDetails = null;
  1020.         if(addCertificateDetails) {
  1021.             storeDetails = toStringPublicKey(publicKeyPath, separator, newLine);
  1022.         }
  1023.        
  1024.         return checkKeyPairEngine(false,
  1025.                 storeDetails, null, publicKey, null, algorithm, null,
  1026.                 addCertificateDetails);
  1027.     }
  1028.     public static CertificateCheck checkPublicKey(boolean classpathSupported, String publicKey, String algorithm,
  1029.             boolean addCertificateDetails, String separator, String newLine) throws UtilsException{
  1030.         return checkKeyPairEngine(false,
  1031.                 classpathSupported, null, publicKey, null, algorithm, null,
  1032.                 addCertificateDetails, separator, newLine);
  1033.     }  
  1034.     public static String toStringPublicKey(KeystoreParams params,
  1035.             String separator, String newLine) {
  1036.         return toStringPublicKey(params.getPath(),
  1037.                 separator, newLine);
  1038.     }
  1039.     private static String toStringPublicKey(String publicKey,
  1040.             String separator, String newLine) {
  1041.        
  1042.         if(newLine!=null) {
  1043.             // nop
  1044.         }
  1045.        
  1046.         StringBuilder sb = new StringBuilder();
  1047.        
  1048.         sb.append(CostantiLabel.PUBLIC_KEY);
  1049.         sb.append(separator);
  1050.         sb.append(publicKey);
  1051.        
  1052.         return sb.toString();
  1053.     }
  1054.    
  1055.    
  1056.    
  1057.    
  1058.     private static CertificateCheck checkKeyPairEngine(boolean isKeyPair,
  1059.             boolean classpathSupported, String privateKey, String publicKey, String passwordKey, String algorithm, IBYOKUnwrapManager byokUnwrapManager,
  1060.             boolean addCertificateDetails, String separator, String newLine) throws UtilsException{
  1061.        
  1062.         String storeDetails = null;
  1063.         if(addCertificateDetails) {
  1064.             if(isKeyPair) {
  1065.                 storeDetails = toStringKeyPair(privateKey, publicKey,
  1066.                         (byokUnwrapManager!=null ? byokUnwrapManager.getPolicy() : null),
  1067.                         separator, newLine);
  1068.             }
  1069.             else {
  1070.                 storeDetails = toStringPublicKey(publicKey, separator, newLine);
  1071.             }
  1072.         }
  1073.        
  1074.        
  1075.         // PRIVATE KEY
  1076.        
  1077.         byte[] privateKeyBytes = null;
  1078.         if(isKeyPair) {
  1079.             File f = new File(privateKey);
  1080.             boolean exists = f.exists();
  1081.             boolean inClasspath = false;
  1082.             if(!exists && classpathSupported) {
  1083.                 String uri = privateKey;
  1084.                 if(!privateKey.startsWith("/")) {
  1085.                     uri = "/" + uri;    
  1086.                 }
  1087.                 try {
  1088.                     try( InputStream is = CertificateUtils.class.getResourceAsStream(uri); ){
  1089.                         exists = (is!=null);
  1090.                         if(exists) {
  1091.                             inClasspath = true;
  1092.                             privateKeyBytes = Utilities.getAsByteArray(is);
  1093.                         }
  1094.                     }
  1095.                 }catch(Exception e) {
  1096.                     throw new UtilsException(e.getMessage(),e);
  1097.                 }
  1098.             }
  1099.             if(!exists || (!inClasspath && !f.canRead())) {
  1100.                
  1101.                 String errorDetails = CostantiLabel.PRIVATE_KEY;
  1102.                 if(!addCertificateDetails) {
  1103.                     errorDetails = errorDetails + " '"+
  1104.                             //f.getAbsolutePath()+  // nel caso di path relativo viene visualizzato un PATH basato sul bin di wildfly ed e' forviante
  1105.                             privateKey+
  1106.                             "'";
  1107.                 }
  1108.                 errorDetails = errorDetails + (!exists ? NOT_EXISTS_STRING : CANNOT_READ_STRING);
  1109.                
  1110.                 CertificateCheck esito = new CertificateCheck();
  1111.                 esito.setStatoCheck(StatoCheck.ERROR);
  1112.                 esito.addError(privateKey, errorDetails, storeDetails);
  1113.                 return esito;
  1114.             }
  1115.             if(!inClasspath) {
  1116.                 try {
  1117.                     privateKeyBytes = FileSystemUtilities.readBytesFromFile(f);
  1118.                 }catch(Exception e) {
  1119.                     throw new UtilsException(e.getMessage(),e);
  1120.                 }
  1121.             }
  1122.         }
  1123.        
  1124.         // PUBLIC KEY
  1125.        
  1126.         byte[] publicKeyBytes = null;
  1127.         File f = new File(publicKey);
  1128.         boolean exists = f.exists();
  1129.         boolean inClasspath = false;
  1130.         if(!exists && classpathSupported) {
  1131.             String uri = publicKey;
  1132.             if(!publicKey.startsWith("/")) {
  1133.                 uri = "/" + uri;    
  1134.             }
  1135.             try {
  1136.                 try( InputStream is = CertificateUtils.class.getResourceAsStream(uri); ){
  1137.                     exists = (is!=null);
  1138.                     if(exists) {
  1139.                         inClasspath = true;
  1140.                         publicKeyBytes = Utilities.getAsByteArray(is);
  1141.                     }
  1142.                 }
  1143.             }catch(Exception e) {
  1144.                 throw new UtilsException(e.getMessage(),e);
  1145.             }
  1146.         }
  1147.                
  1148.         if(!exists || (!inClasspath && !f.canRead())) {
  1149.            
  1150.             String errorDetails = CostantiLabel.PUBLIC_KEY;
  1151.             if(!addCertificateDetails) {
  1152.                 errorDetails = errorDetails + " '"+
  1153.                         //f.getAbsolutePath()+  // nel caso di path relativo viene visualizzato un PATH basato sul bin di wildfly ed e' forviante
  1154.                         publicKey+
  1155.                         "'";
  1156.             }
  1157.             errorDetails = errorDetails + (!exists ? NOT_EXISTS_STRING : CANNOT_READ_STRING);
  1158.            
  1159.             CertificateCheck esito = new CertificateCheck();
  1160.             esito.setStatoCheck(StatoCheck.ERROR);
  1161.             esito.addError(publicKey, errorDetails, storeDetails);
  1162.             return esito;
  1163.         }
  1164.         if(!inClasspath) {
  1165.             try {
  1166.                 publicKeyBytes = FileSystemUtilities.readBytesFromFile(f);
  1167.             }catch(Exception e) {
  1168.                 throw new UtilsException(e.getMessage(),e);
  1169.             }
  1170.         }
  1171.        
  1172.         return checkKeyPairEngine(isKeyPair,
  1173.                 storeDetails, privateKeyBytes, publicKeyBytes, passwordKey, algorithm, byokUnwrapManager,
  1174.                 addCertificateDetails);
  1175.     }
  1176.     private static CertificateCheck checkKeyPairEngine(boolean isKeyPair,
  1177.             String storeDetails, byte[] privateKey, byte[] publicKey, String passwordKey, String algorithm, IBYOKUnwrapManager byokUnwrapManager,
  1178.             boolean addCertificateDetails) throws UtilsException{
  1179.                
  1180.         KeyUtils keyUtils = null;
  1181.         try {
  1182.             keyUtils = KeyUtils.getInstance(algorithm);
  1183.         }catch(Exception t) {
  1184.             String errorDetails = "KeyAlgorithm";
  1185.             if(!addCertificateDetails) {
  1186.                 errorDetails = errorDetails + " '"+
  1187.                         //f.getAbsolutePath()+  // nel caso di path relativo viene visualizzato un PATH basato sul bin di wildfly ed e' forviante
  1188.                         algorithm+
  1189.                         "'";
  1190.             }
  1191.             errorDetails = errorDetails + " unknown: "+t.getMessage();
  1192.            
  1193.             CertificateCheck esito = new CertificateCheck();
  1194.             esito.setStatoCheck(StatoCheck.ERROR);
  1195.             esito.addError(algorithm, errorDetails, storeDetails);
  1196.             return esito;
  1197.         }
  1198.        
  1199.         if(isKeyPair) {
  1200.             try {
  1201.                 if(byokUnwrapManager!=null) {
  1202.                     privateKey = byokUnwrapManager.unwrap(privateKey);
  1203.                 }
  1204.                 if(passwordKey!=null) {
  1205.                     keyUtils.getPrivateKey(privateKey, passwordKey);
  1206.                 }
  1207.                 else {
  1208.                     keyUtils.getPrivateKey(privateKey);
  1209.                 }
  1210.             }catch(Exception t) {
  1211.                 String errorDetails = READING_PREFIX_STRING+ CostantiLabel.PRIVATE_KEY+getSuffixFailed(t);
  1212.                 CertificateCheck esito = new CertificateCheck();
  1213.                 esito.setStatoCheck(StatoCheck.ERROR);
  1214.                 esito.addError(CostantiLabel.PRIVATE_KEY, errorDetails, storeDetails);
  1215.                 return esito;
  1216.             }
  1217.         }
  1218.        
  1219.         try {
  1220.             keyUtils.getPublicKey(publicKey);
  1221.         }catch(Exception t) {
  1222.             String errorDetails = READING_PREFIX_STRING+ CostantiLabel.PUBLIC_KEY+getSuffixFailed(t);
  1223.             CertificateCheck esito = new CertificateCheck();
  1224.             esito.setStatoCheck(StatoCheck.ERROR);
  1225.             esito.addError(CostantiLabel.PUBLIC_KEY, errorDetails, storeDetails);
  1226.             return esito;
  1227.         }
  1228.        
  1229.         CertificateCheck esito = new CertificateCheck();
  1230.         esito.setStatoCheck(StatoCheck.OK);
  1231.         return esito;
  1232.     }
  1233.    
  1234.    
  1235.    
  1236.    
  1237.    
  1238.     public static CertificateCheck checkKeystoreJWKs(boolean classpathSupported, String jwksPath, String keyAlias, IBYOKUnwrapManager byokUnwrapManager,
  1239.             boolean addCertificateDetails, String separator, String newLine) throws UtilsException{
  1240.         return checkJWKsEngine(true,
  1241.                 classpathSupported, jwksPath, keyAlias,
  1242.                 byokUnwrapManager,
  1243.                 addCertificateDetails, separator, newLine);
  1244.     }
  1245.     public static CertificateCheck checkKeystoreJWKs(String jwksPath, String jwks, String keyAlias, IBYOKUnwrapManager byokUnwrapManager,
  1246.             boolean addCertificateDetails, String separator, String newLine) throws UtilsException{
  1247.        
  1248.         String storeDetails = null;
  1249.         if(addCertificateDetails) {
  1250.             storeDetails = toStringJWKs(true, jwksPath, keyAlias,
  1251.                     (byokUnwrapManager!=null ? byokUnwrapManager.getPolicy() : null),
  1252.                     separator, newLine);
  1253.         }
  1254.        
  1255.         return checkJWKsEngine(false,
  1256.                 storeDetails, jwks, keyAlias, byokUnwrapManager);
  1257.     }
  1258.     public static CertificateCheck checkTruststoreJWKs(boolean classpathSupported, String jwksPath, String keyAlias,
  1259.             boolean addCertificateDetails, String separator, String newLine) throws UtilsException{
  1260.         return checkJWKsEngine(false,
  1261.                 classpathSupported, jwksPath, keyAlias, null,
  1262.                 addCertificateDetails, separator, newLine);
  1263.     }
  1264.     public static CertificateCheck checkTruststoreJWKs(String jwksPath, String jwks, String keyAlias,
  1265.             boolean addCertificateDetails, String separator, String newLine) throws UtilsException{
  1266.        
  1267.         String storeDetails = null;
  1268.         if(addCertificateDetails) {
  1269.             storeDetails = toStringJWKs(false, jwksPath, keyAlias,
  1270.                     null,
  1271.                     separator, newLine);
  1272.         }
  1273.        
  1274.         return checkJWKsEngine(false,
  1275.                 storeDetails, jwks, keyAlias, null);
  1276.     }
  1277.     private static CertificateCheck checkJWKsEngine(boolean keystore,
  1278.             boolean classpathSupported, String jwksPath, String keyAlias, IBYOKUnwrapManager byokUnwrapManager,
  1279.             boolean addCertificateDetails, String separator, String newLine) throws UtilsException{
  1280.        
  1281.         String storeDetails = null;
  1282.         if(addCertificateDetails) {
  1283.             storeDetails = toStringJWKs(keystore, jwksPath, keyAlias,
  1284.                     (byokUnwrapManager!=null ? byokUnwrapManager.getPolicy() : null),
  1285.                     separator, newLine);
  1286.         }
  1287.                
  1288.         String jwks = null;
  1289.         File f = new File(jwksPath);
  1290.         boolean exists = f.exists();
  1291.         boolean inClasspath = false;
  1292.         if(!exists && classpathSupported) {
  1293.             String uri = jwksPath;
  1294.             if(!jwksPath.startsWith("/")) {
  1295.                 uri = "/" + uri;    
  1296.             }
  1297.             try {
  1298.                 try( InputStream is = CertificateUtils.class.getResourceAsStream(uri); ){
  1299.                     exists = (is!=null);
  1300.                     if(exists) {
  1301.                         inClasspath = true;
  1302.                         jwks = Utilities.getAsString(is, Charset.UTF_8.getValue());
  1303.                     }
  1304.                 }
  1305.             }catch(Exception e) {
  1306.                 throw new UtilsException(e.getMessage(),e);
  1307.             }
  1308.         }
  1309.                
  1310.         if(!exists || (!inClasspath && !f.canRead())) {
  1311.            
  1312.             String errorDetails = keystore ? CostantiLabel.KEYSTORE : CostantiLabel.TRUSTSTORE;
  1313.             if(!addCertificateDetails) {
  1314.                 errorDetails = errorDetails + " '"+
  1315.                         //f.getAbsolutePath()+  // nel caso di path relativo viene visualizzato un PATH basato sul bin di wildfly ed e' forviante
  1316.                         jwksPath+
  1317.                         "'";
  1318.             }
  1319.             errorDetails = errorDetails + (!exists ? NOT_EXISTS_STRING : CANNOT_READ_STRING);
  1320.            
  1321.             CertificateCheck esito = new CertificateCheck();
  1322.             esito.setStatoCheck(StatoCheck.ERROR);
  1323.             esito.addError(jwksPath, errorDetails, storeDetails);
  1324.             return esito;
  1325.         }
  1326.         if(!inClasspath) {
  1327.             try {
  1328.                 jwks = FileSystemUtilities.readFile(f);
  1329.             }catch(Exception e) {
  1330.                 throw new UtilsException(e.getMessage(),e);
  1331.             }
  1332.         }
  1333.        
  1334.         return checkJWKsEngine(keystore,
  1335.                 storeDetails, jwks, keyAlias, byokUnwrapManager);
  1336.     }
  1337.     private static CertificateCheck checkJWKsEngine(boolean keystore,
  1338.             String storeDetails,
  1339.             String jwks, String keyAlias, IBYOKUnwrapManager byokUnwrapManager) throws UtilsException{
  1340.                
  1341.         com.nimbusds.jose.jwk.JWKSet set = null;
  1342.         try {
  1343.             if(keystore && byokUnwrapManager!=null) {
  1344.                 jwks = new String(byokUnwrapManager.unwrap(jwks.getBytes()));
  1345.             }
  1346.             JWKSet jwkset = new JWKSet(jwks);
  1347.             set = jwkset.getJWKSet();
  1348.         }catch(Exception t) {
  1349.             String errorDetails = READING_PREFIX_STRING+ (keystore ? CostantiLabel.KEYSTORE : CostantiLabel.TRUSTSTORE) +getSuffixFailed(t);
  1350.             CertificateCheck esito = new CertificateCheck();
  1351.             esito.setStatoCheck(StatoCheck.ERROR);
  1352.             esito.addError(keystore ? CostantiLabel.KEYSTORE : CostantiLabel.TRUSTSTORE, errorDetails, storeDetails);
  1353.             return esito;
  1354.         }
  1355.        
  1356.         CertificateCheck checkAlias = checkJWKsEngineKeyAlias(keyAlias, set, keystore, storeDetails);
  1357.         if(checkAlias!=null) {
  1358.             return checkAlias;
  1359.         }
  1360.        
  1361.         CertificateCheck esito = new CertificateCheck();
  1362.         esito.setStatoCheck(StatoCheck.OK);
  1363.         return esito;
  1364.     }
  1365.     private static CertificateCheck checkJWKsEngineKeyAlias(String keyAlias, com.nimbusds.jose.jwk.JWKSet set, boolean keystore, String storeDetails) {
  1366.         if(keyAlias!=null && StringUtils.isNotEmpty(keyAlias) && !"*".equals(keyAlias)) {
  1367.             try {
  1368.                 com.nimbusds.jose.jwk.JWK jwk = set.getKeyByKeyId(keyAlias);
  1369.                 if(jwk==null) {
  1370.                     throw new UtilsException("kid not exists");
  1371.                 }
  1372.             }catch(Exception t) {
  1373.                 String errorDetails = (keystore ? CostantiLabel.KEY_ALIAS : CostantiLabel.CERTIFICATE_ALIAS) +" unknown: "+t.getMessage();
  1374.                 CertificateCheck esito = new CertificateCheck();
  1375.                 esito.setStatoCheck(StatoCheck.ERROR);
  1376.                 esito.addError(keystore ? CostantiLabel.KEYSTORE : CostantiLabel.TRUSTSTORE, errorDetails, storeDetails);
  1377.                 return esito;
  1378.             }
  1379.         }
  1380.         return null;
  1381.     }
  1382.     public static String toStringKeystoreJWKs(KeystoreParams params,
  1383.             String separator, String newLine) {
  1384.         return toStringJWKs(true, params.getPath(), params.getKeyAlias(), params.getByokPolicy(),
  1385.                 separator, newLine);
  1386.     }
  1387.     public static String toStringTruststoreJWKs(KeystoreParams params,
  1388.             String separator, String newLine) {
  1389.         return toStringJWKs(false, params.getPath(), params.getKeyAlias(), null,
  1390.                 separator, newLine);
  1391.     }
  1392.     private static String toStringJWKs(boolean keystore, String jwksPath, String keyAlias, String byokPolicy,
  1393.             String separator, String newLine) {
  1394.        
  1395.         StringBuilder sb = new StringBuilder();
  1396.        
  1397.         sb.append(keystore? CostantiLabel.KEYSTORE : CostantiLabel.TRUSTSTORE);
  1398.         sb.append(separator);
  1399.         sb.append(CostantiLabel.JWKS);
  1400.         sb.append(" ");
  1401.         sb.append(jwksPath);
  1402.        
  1403.         if(keyAlias!=null) {
  1404.             sb.append(newLine);
  1405.             if(keystore) {
  1406.                 sb.append(CostantiLabel.KEY_ALIAS);
  1407.             }
  1408.             else {
  1409.                 sb.append(CostantiLabel.CERTIFICATE_ALIAS);
  1410.             }
  1411.             sb.append(separator);
  1412.             sb.append(keyAlias);
  1413.         }
  1414.        
  1415.         if(byokPolicy!=null) {
  1416.             sb.append(newLine);
  1417.             sb.append(CostantiLabel.BYOK_POLICY);
  1418.             sb.append(separator);
  1419.             sb.append(byokPolicy);
  1420.         }
  1421.        
  1422.         return sb.toString();
  1423.     }
  1424. }