CRLParams.java

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

  21. import java.security.cert.CertStore;
  22. import java.security.cert.X509Certificate;
  23. import java.util.ArrayList;
  24. import java.util.HashMap;
  25. import java.util.List;
  26. import java.util.Map;

  27. import org.openspcoop2.utils.LoggerBuffer;
  28. import org.openspcoop2.utils.UtilsException;
  29. import org.openspcoop2.utils.UtilsMultiException;
  30. import org.openspcoop2.utils.certificate.ArchiveLoader;
  31. import org.openspcoop2.utils.certificate.AuthorityInformationAccess;
  32. import org.openspcoop2.utils.certificate.CRLCertstore;
  33. import org.openspcoop2.utils.certificate.CRLDistributionPoint;
  34. import org.openspcoop2.utils.certificate.CRLDistributionPoints;
  35. import org.openspcoop2.utils.certificate.Certificate;
  36. import org.openspcoop2.utils.certificate.CertificateInfo;
  37. import org.openspcoop2.utils.certificate.KeyStore;
  38. import org.openspcoop2.utils.certificate.KeystoreType;
  39. import org.openspcoop2.utils.transport.TransportUtils;

  40. /**
  41.  * OCSPRequestParams
  42.  *
  43.  * @author Poli Andrea (apoli@link.it)
  44.  * @author $Author$
  45.  * @version $Rev$, $Date$
  46.  */
  47. public class CRLParams {

  48.     private KeyStore crlTrustStore;
  49.     private CertStore crlCertstore;
  50.        
  51.     public KeyStore getCrlTrustStore() {
  52.         return this.crlTrustStore;
  53.     }
  54.     public void setCrlTrustStore(KeyStore crlTrustStore) {
  55.         this.crlTrustStore = crlTrustStore;
  56.     }
  57.     public CertStore getCrlCertstore() {
  58.         return this.crlCertstore;
  59.     }
  60.     public void setCrlCertstore(CertStore crlCertstore) {
  61.         this.crlCertstore = crlCertstore;
  62.     }
  63.    
  64.     public static CRLParams build(LoggerBuffer log, X509Certificate certificate, String crlInputConfig, KeyStore trustStore, OCSPConfig config, IOCSPResourceReader reader) throws UtilsException {
  65.         CertificateInfo cer = new CertificateInfo(certificate, "ocspVerifica");
  66.         return build(log, cer, crlInputConfig, trustStore, config, reader);
  67.     }
  68.     public static CRLParams build(LoggerBuffer log, CertificateInfo certificate, String crlInputConfig, KeyStore trustStore, OCSPConfig config, IOCSPResourceReader reader) throws UtilsException {
  69.    
  70.         if(config==null) {
  71.             throw new UtilsException("Param config is null");
  72.         }
  73.         if(certificate==null) {
  74.             throw new UtilsException("Param certificate is null");
  75.         }
  76.        
  77.        
  78.         // comprendo path CRL
  79.         List<String> crlPaths = new ArrayList<>();
  80.         Map<String, byte[]> localResources = new HashMap<>();
  81.        
  82.         if(config.getCrlSource()!=null && !config.getCrlSource().isEmpty()) {
  83.            
  84.             List<Throwable> listExceptions = new ArrayList<>();
  85.                        
  86.             for (CertificateSource s : config.getCrlSource()) {
  87.                 if(CertificateSource.CONFIG.equals(s)) {
  88.                     if(crlInputConfig!=null) {
  89.                         // รจ possibile fornire un'unica indicazione di una risorsa remota o in alternativa N file crl
  90.                         if(TransportUtils.isRemoteResource(crlInputConfig)){
  91.                             readCrlPath(crlInputConfig.trim(),
  92.                                     crlPaths, localResources,
  93.                                     listExceptions,
  94.                                     reader,
  95.                                     log);
  96.                         }
  97.                         else {
  98.                             List<String> l = CRLCertstore.readCrlPaths(crlInputConfig);
  99.                             if(l!=null && !l.isEmpty()) {
  100.                                 for (String crlPath : l) {
  101.                                     String p = crlPath.trim();
  102.                                     if(!crlPaths.contains(p)) {
  103.                                         crlPaths.add(p);
  104.                                         log.debug("OCSP-CRL: add config path '"+p+"'");
  105.                                     }
  106.                                 }
  107.                             }
  108.                         }
  109.                     }
  110.                     if(!crlPaths.isEmpty()) {
  111.                         break;
  112.                     }
  113.                 }
  114.                 else if(CertificateSource.ALTERNATIVE_CONFIG.equals(s)) {
  115.                     List<String> l = null;
  116.                     if(config.getCrlAlternative()!=null) {
  117.                         l = config.getCrlAlternative();
  118.                     }
  119.                     if(l!=null && !l.isEmpty()) {
  120.                         for (String crlPath : l) {
  121.                             String p = crlPath.trim();
  122.                             if(!crlPaths.contains(p)) {
  123.                                 crlPaths.add(p);
  124.                                 log.debug("OCSP-CRL: add alternative config path '"+p+"'");
  125.                             }
  126.                         }
  127.                     }
  128.                     if(!crlPaths.isEmpty()) {
  129.                         break;
  130.                     }
  131.                 }
  132.                 else if(CertificateSource.AUTHORITY_INFORMATION_ACCESS.equals(s)) {
  133.                     try {
  134.                         CRLDistributionPoints crls = certificate.getCRLDistributionPoints();
  135.                         if(crls!=null) {
  136.                             List<CRLDistributionPoint> crlsList = crls.getCRLDistributionPoints();
  137.                             if(crlsList!=null && !crlsList.isEmpty()) {
  138.                                 for (CRLDistributionPoint crlDP : crlsList) {
  139.                                     List<String> l = crlDP.getDistributionPointNames();
  140.                                     if(l!=null) {
  141.                                         for (String crlPath : l) {
  142.                                             readCrlPath(crlPath,
  143.                                                     crlPaths, localResources,
  144.                                                     listExceptions,
  145.                                                     reader,
  146.                                                     log);
  147.                                         }
  148.                                     }
  149.                                 }
  150.                             }
  151.                         }                      
  152.                     }catch(Exception t) {
  153.                         throw new UtilsException(t.getMessage(),t);
  154.                     }
  155.                     if(!crlPaths.isEmpty()) {
  156.                         break;
  157.                     }
  158.                 }
  159.             }
  160.            
  161.             if(crlPaths.isEmpty()) {
  162.                 boolean reject = false;
  163.                 boolean isCA = false;
  164.                 try {
  165.                     isCA = certificate.isCA();
  166.                 }catch(Exception t) {
  167.                     throw new UtilsException(t.getMessage(),t);
  168.                 }
  169.                 if(isCA) {
  170.                     reject = config.isRejectsCAWithoutCRL();
  171.                 }
  172.                 else {
  173.                     reject = config.isRejectsCertificateWithoutCRL();
  174.                 }
  175.                 if(reject) {
  176.                     if(!listExceptions.isEmpty()) {
  177.                         if(listExceptions.size()==1) {
  178.                             Throwable t = listExceptions.get(0);
  179.                             if(t!=null) {
  180.                                 throw new UtilsException("Crl retrieve failed; "+t.getMessage(),t);
  181.                             }
  182.                         }
  183.                         UtilsMultiException multi = new UtilsMultiException("Crl retrieve failed", listExceptions.toArray(new Throwable[1]));
  184.                         throw new UtilsException("Crl retrieve failed;\n"+multi.getMultiMessage(),multi);
  185.                     }
  186.                     else {
  187.                         throw new UtilsException("Crl retrieve failed");
  188.                     }
  189.                 }
  190.             }
  191.            
  192.         }
  193.        
  194.         KeyStore crlTrustStore = null;
  195.         if(!crlPaths.isEmpty() &&
  196.             // comprendo issuer del certificato da validare
  197.             config.getCrlTrustStoreSource()!=null && !config.getCrlTrustStoreSource().isEmpty()) {
  198.             for (CertificateSource s : config.getCrlTrustStoreSource()) {
  199.                 if(CertificateSource.CONFIG.equals(s)) {
  200.                     if(trustStore!=null) {
  201.                         try {
  202.                             if(crlTrustStore==null) {
  203.                                 java.security.KeyStore ks = java.security.KeyStore.getInstance(KeystoreType.JKS.getNome());
  204.                                 ks.load(null, null);
  205.                                 crlTrustStore = new KeyStore(ks);
  206.                             }
  207.                         }catch(Exception t) {
  208.                             String msgError = "OCSP-CRL [crlssuer: CONFIG] retrieve failed: "+t.getMessage();
  209.                             log.debug(msgError,t);
  210.                         }
  211.                         if(crlTrustStore!=null) {
  212.                             crlTrustStore.putAllCertificate(trustStore, false);
  213.                         }
  214.                         log.debug("OCSP-CRL: add certificate in truststore config");
  215.                     }
  216.                 }
  217.                 else if(CertificateSource.ALTERNATIVE_CONFIG.equals(s)) {
  218.                     KeyStore alternativeTrustStore = null;
  219.                     if(config.getAlternativeTrustStoreCRLPath()!=null) {
  220.                         alternativeTrustStore = reader.getCrlAlternativeTrustStore();
  221.                     }
  222.                     if(alternativeTrustStore!=null) {
  223.                         try {
  224.                             if(crlTrustStore==null) {
  225.                                 java.security.KeyStore ks = java.security.KeyStore.getInstance(KeystoreType.JKS.getNome());
  226.                                 ks.load(null, null);
  227.                                 crlTrustStore = new KeyStore(ks);
  228.                             }
  229.                         }catch(Exception t) {
  230.                             String msgError = "OCSP-CRL [crlssuer: ALTERNATIVE_CONFIG] retrieve failed: "+t.getMessage();
  231.                             log.debug(msgError,t);
  232.                         }
  233.                         if(crlTrustStore!=null) {
  234.                             crlTrustStore.putAllCertificate(alternativeTrustStore, false);
  235.                         }
  236.                         log.debug("OCSP-CRL: add certificate in alternative truststore config");
  237.                     }
  238.                 }
  239.                 else if(CertificateSource.AUTHORITY_INFORMATION_ACCESS.equals(s)) {
  240.                     try {
  241.                         CRLDistributionPoints crls = certificate.getCRLDistributionPoints();
  242.                         if(crls!=null) {
  243.                             List<CRLDistributionPoint> crlsList = crls.getCRLDistributionPoints();
  244.                             int indexCrl = 0;
  245.                             if(crlsList!=null && !crlsList.isEmpty()) {
  246.                                 for (CRLDistributionPoint crlDP : crlsList) {
  247.                                     List<String> l = crlDP.getCRLIssuers();
  248.                                     if(l!=null) {
  249.                                         for (String crlPath : l) {
  250.                                             if(!crlPaths.contains(crlPath)) {
  251.                                                 try {
  252.                                                     Map<String, byte[]> map = new HashMap<>();
  253.                                                     reader.readExternalResource(crlPath, map);
  254.                                                     byte [] issuer = null;
  255.                                                     if(!map.isEmpty()) {
  256.                                                         issuer = map.get(crlPath);
  257.                                                     }
  258.                                                     if(issuer==null || issuer.length<=0) {
  259.                                                         throw new UtilsException("empty resource");
  260.                                                     }
  261.                                                     Certificate cer = ArchiveLoader.load(issuer);
  262.                                                     if(cer!=null && cer.getCertificate()!=null) {
  263.                                                         if(crlTrustStore==null) {
  264.                                                             java.security.KeyStore ks = java.security.KeyStore.getInstance(KeystoreType.JKS.getNome());
  265.                                                             ks.load(null, null);
  266.                                                             crlTrustStore = new KeyStore(ks);
  267.                                                         }
  268.                                                         crlTrustStore.putCertificate("crlIssuerCert-"+indexCrl, cer.getCertificate().getCertificate(), false);
  269.                                                         indexCrl++;
  270.                                                         log.debug("OCSP-CRL: add certificate retrieved from '"+crlPath+"'");
  271.                                                     }
  272.                                                 }catch(Exception t) {
  273.                                                     String msgError = "OCSP-CRL [crlssuer: "+crlPath+"] retrieve failed: "+t.getMessage();
  274.                                                     log.debug(msgError,t);
  275.                                                 }
  276.                                             }
  277.                                         }
  278.                                     }
  279.                                 }
  280.                             }
  281.                         }                      
  282.                     }catch(Exception t) {
  283.                         throw new UtilsException(t.getMessage(),t);
  284.                     }
  285.                     try {
  286.                         AuthorityInformationAccess aia = certificate.getAuthorityInformationAccess();
  287.                         if(aia!=null) {
  288.                             List<String> issuer = aia.getCAIssuers();
  289.                             int indexAia = 0;
  290.                             if(issuer!=null && !issuer.isEmpty()) {
  291.                                 for (String urlIssuer : issuer) {
  292.                                     Map<String, byte[]> map = new HashMap<>();
  293.                                     reader.readExternalResource(urlIssuer, map);
  294.                                     if(!map.isEmpty()) {
  295.                                         byte [] issCert = map.get(urlIssuer);
  296.                                         if(issCert!=null) {
  297.                                             Certificate cer = ArchiveLoader.load(issCert);
  298.                                             if(cer!=null && cer.getCertificate()!=null) {
  299.                                                 if(crlTrustStore==null) {
  300.                                                     java.security.KeyStore ks = java.security.KeyStore.getInstance(KeystoreType.JKS.getNome());
  301.                                                     ks.load(null, null);
  302.                                                     crlTrustStore = new KeyStore(ks);
  303.                                                 }
  304.                                                 crlTrustStore.putCertificate("aiaIssuerCert-"+indexAia, cer.getCertificate().getCertificate(), false);
  305.                                                 indexAia++;
  306.                                                 log.debug("OCSP-CRL-AIA: add certificate retrieved from '"+urlIssuer+"'");
  307.                                             }
  308.                                         }
  309.                                     }
  310.                                 }
  311.                             }
  312.                         }
  313.                     }catch(Exception t) {
  314.                         throw new UtilsException(t.getMessage(),t);
  315.                     }
  316.                 }
  317.             }
  318.            
  319.         }
  320.        
  321.         CRLParams params = new CRLParams();
  322.         if(!crlPaths.isEmpty()) {
  323.             params.crlCertstore = reader.readCRL(crlPaths, localResources).getCertStore();
  324.            
  325. /**         boolean newTrustStore = false;
  326. //          if(crlTrustStore==null) {
  327. //              try {
  328. //                  java.security.KeyStore ks = java.security.KeyStore.getInstance(KeystoreType.JKS.getNome());
  329. //                  ks.load(null, null);
  330. //                  crlTrustStore = new KeyStore(ks);
  331. //                  newTrustStore = true;
  332. //              }catch(Throwable t) {
  333. //                  throw new UtilsException(t.getMessage(),t);
  334. //              }
  335. //          }
  336. //          
  337. //          try {
  338. //              if(certificate.isCA()) {
  339. //                  if(newTrustStore || (!params.crlTrustStore.existsCertificateBySubject(certificate.getCertificate().getSubjectX500Principal()))) {
  340. //                      crlTrustStore.putCertificate("ca", certificate.getCertificate(), false);
  341. //                  }
  342. //              }
  343. //          }catch(Throwable t) {
  344. //              throw new UtilsException(t.getMessage(),t);
  345. //          }*/
  346.            
  347.             params.crlTrustStore = crlTrustStore;
  348.         }
  349.        
  350.         return params;
  351.        
  352.     }
  353.    
  354.     private static void readCrlPath(String crlPath,
  355.             List<String> crlPaths,Map<String, byte[]> localResources,
  356.             List<Throwable> listExceptions,
  357.             IOCSPResourceReader reader,
  358.             LoggerBuffer log) {
  359.         if(!crlPaths.contains(crlPath)) {
  360.             try {
  361.                 Map<String, byte[]> map = new HashMap<>();
  362.                 reader.readExternalResource(crlPath, map);
  363.                 byte [] crl = null;
  364.                 if(!map.isEmpty()) {
  365.                     crl = map.get(crlPath);
  366.                 }
  367.                 if(crl==null || crl.length<=0) {
  368.                     throw new UtilsException("empty resource");
  369.                 }
  370.                 localResources.put(crlPath, crl);
  371.                 crlPaths.add(crlPath);
  372.                 log.debug("OCSP-CRL: add external resource '"+crlPath+"'");
  373.             }catch(Exception t) {
  374.                 String msgError = "[crl: "+crlPath+"] retrieve failed: "+t.getMessage();
  375.                 log.debug("OCSP-CRL "+msgError,t);
  376.                 listExceptions.add(new Exception(msgError,t));
  377.             }
  378.         }
  379.     }
  380. }